Skip to content

Commit 2e52386

Browse files
authored
Merge pull request DSpace#5137 from dspace-unimr/feature/add-dataset-entity-type
Support for dataset entities
2 parents 178ae2a + cc4bf75 commit 2e52386

10 files changed

Lines changed: 866 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<ng-container *ngVar="(bitstreamsRD$ | async) as bitstreamsRD">
2+
<div class="file-section my-3 justify-content-center">
3+
<div class="w-100 file-section-header mb-3">
4+
<h3 [innerText]="label | translate"></h3>
5+
</div>
6+
<div class="file-section-table">
7+
<div class="row heading mx-0">
8+
<div class="col-6">
9+
<h4 [innerText]="'file.section.name' | translate"></h4>
10+
</div>
11+
<div class="col-3">
12+
<h4 [innerText]="'file.section.type' | translate"></h4>
13+
</div>
14+
<div class="col-2">
15+
<h4 [innerText]="'file.section.size' | translate"></h4>
16+
</div>
17+
<div class="col-1">
18+
</div>
19+
</div>
20+
<div class="mx-1">
21+
@if (bitstreamsRD?.payload?.totalElements > 0) {
22+
<ds-pagination
23+
[paginationOptions]="pageConfig"
24+
[collectionSize]="bitstreamsRD?.payload?.totalElements"
25+
[hideGear]="true"
26+
[hidePagerWhenSinglePage]="true"
27+
[retainScrollPosition]="true">
28+
<div class="entries">
29+
@for (file of bitstreamsRD?.payload?.page; track file) {
30+
<div class="row file-section-entry mx-0">
31+
<div class="col-6">
32+
<span [innerHTML]="dsoNameService.getName(file)"></span>
33+
</div>
34+
<div class="col-3">
35+
<span>{{ (bitstreamFormatDataService.findByBitstream(file) | async).payload?.shortDescription }}</span>
36+
</div>
37+
<div class="col-2">
38+
<span> {{ (file?.sizeBytes) | dsFileSize }}</span>
39+
</div>
40+
<div class="col-1 text-center">
41+
<ds-file-download-link [bitstream]="file" [item]="item">
42+
<i class="fa fa-download"></i>
43+
</ds-file-download-link>
44+
</div>
45+
</div>
46+
}
47+
</div>
48+
</ds-pagination>
49+
}
50+
</div>
51+
</div>
52+
</div>
53+
</ng-container>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
@import '../../../../../styles/variables.scss';
2+
3+
.file-section {
4+
padding: 1rem;
5+
background-color: var(--bs-gray-200);
6+
7+
.file-section-header {
8+
border-bottom: 4px solid var(--bs-primary);
9+
}
10+
11+
.file-section-table {
12+
.row {
13+
padding: 0.4em 0.75em;
14+
}
15+
.entries {
16+
.file-section-entry {
17+
background-color: var(--bs-300);
18+
&:nth-child(2n + 1) {
19+
background-color: var(--bs-gray-100);
20+
}
21+
}
22+
}
23+
.heading {
24+
border-bottom: 1px solid var(--bs-gray-900);
25+
background-color: var(--bs-gray-400);
26+
font-size: 1.25em;
27+
}
28+
}
29+
}
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { NO_ERRORS_SCHEMA } from '@angular/core';
2+
import {
3+
ComponentFixture,
4+
TestBed,
5+
waitForAsync,
6+
} from '@angular/core/testing';
7+
import { By } from '@angular/platform-browser';
8+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
9+
import { ActivatedRoute } from '@angular/router';
10+
import { APP_CONFIG } from '@dspace/config/app-config.interface';
11+
import { BitstreamDataService } from '@dspace/core/data/bitstream-data.service';
12+
import { BitstreamFormatDataService } from '@dspace/core/data/bitstream-format-data.service';
13+
import { LocaleService } from '@dspace/core/locale/locale.service';
14+
import { NotificationsService } from '@dspace/core/notification-system/notifications.service';
15+
import { PaginationService } from '@dspace/core/pagination/pagination.service';
16+
import { Bitstream } from '@dspace/core/shared/bitstream.model';
17+
import { BitstreamFormat } from '@dspace/core/shared/bitstream-format.model';
18+
import { Item } from '@dspace/core/shared/item.model';
19+
import { ActivatedRouteStub } from '@dspace/core/testing/active-router.stub';
20+
import { NotificationsServiceStub } from '@dspace/core/testing/notifications-service.stub';
21+
import { PaginationServiceStub } from '@dspace/core/testing/pagination-service.stub';
22+
import { TranslateLoaderMock } from '@dspace/core/testing/translate-loader.mock';
23+
import { createPaginatedList } from '@dspace/core/testing/utils.test';
24+
import { createSuccessfulRemoteDataObject$ } from '@dspace/core/utilities/remote-data.utils';
25+
import { XSRFService } from '@dspace/core/xsrf/xsrf.service';
26+
import { provideMockStore } from '@ngrx/store/testing';
27+
import {
28+
TranslateLoader,
29+
TranslateModule,
30+
} from '@ngx-translate/core';
31+
import { of } from 'rxjs';
32+
33+
import { environment } from '../../../../../environments/environment';
34+
import { ThemedFileDownloadLinkComponent } from '../../../../shared/file-download-link/themed-file-download-link.component';
35+
import { PaginationComponent } from '../../../../shared/pagination/pagination.component';
36+
import { SearchConfigurationService } from '../../../../shared/search/search-configuration.service';
37+
import { getMockThemeService } from '../../../../shared/theme-support/test/theme-service.mock';
38+
import { ThemeService } from '../../../../shared/theme-support/theme.service';
39+
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
40+
import { VarDirective } from '../../../../shared/utils/var.directive';
41+
import { ExtendedFileSectionComponent } from './extended-file-section.component';
42+
43+
describe('ExtendedFileSectionComponent', () => {
44+
let component: ExtendedFileSectionComponent;
45+
let fixture: ComponentFixture<ExtendedFileSectionComponent>;
46+
let localeService: any;
47+
const languageList = ['en;q=1', 'de;q=0.8'];
48+
const mockLocaleService = jasmine.createSpyObj('LocaleService', {
49+
getCurrentLanguageCode: jasmine.createSpy('getCurrentLanguageCode'),
50+
getLanguageCodeList: of(languageList),
51+
});
52+
53+
const paginationServiceStub = new PaginationServiceStub();
54+
55+
const mockItem = Object.assign(new Item(), {
56+
id: 'test-item-id',
57+
uuid: 'test-item-id',
58+
_links: {
59+
self: { href: 'test-item-selflink' },
60+
},
61+
});
62+
63+
const mockBitstream = Object.assign(new Bitstream(), {
64+
id: 'test-bitstream-id',
65+
uuid: 'test-bitstream-id',
66+
name: 'test-bitstream.pdf',
67+
sizeBytes: 1024,
68+
_links: {
69+
self: { href: 'test-bitstream-selflink' },
70+
},
71+
});
72+
73+
const mockBitstreamFormat = Object.assign(new BitstreamFormat(), {
74+
resourceType: 'testResourceType',
75+
shortDescription: 'testShortDescription',
76+
description: 'testDescription',
77+
mimetype: 'test/mimeType',
78+
});
79+
80+
const paginatedList = createPaginatedList([mockBitstream]);
81+
82+
paginatedList.pageInfo.elementsPerPage = environment.item.bitstream.pageSize;
83+
84+
const bitstreamDataService = jasmine.createSpyObj('bitstreamDataService', {
85+
findAllByItemAndBundleName: createSuccessfulRemoteDataObject$(paginatedList),
86+
});
87+
88+
const bitstreamFormatDataService = jasmine.createSpyObj('bitstreamFormatDataService', {
89+
findByBitstream: createSuccessfulRemoteDataObject$(mockBitstreamFormat),
90+
});
91+
92+
beforeEach(waitForAsync(() => {
93+
94+
TestBed.configureTestingModule({
95+
imports: [
96+
TranslateModule.forRoot({
97+
loader: {
98+
provide: TranslateLoader,
99+
useClass: TranslateLoaderMock,
100+
},
101+
}),
102+
BrowserAnimationsModule,
103+
ExtendedFileSectionComponent,
104+
VarDirective,
105+
FileSizePipe,
106+
],
107+
providers: [
108+
provideMockStore(),
109+
{ provide: XSRFService, useValue: {} },
110+
{ provide: BitstreamDataService, useValue: bitstreamDataService },
111+
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
112+
{ provide: BitstreamFormatDataService, useValue: bitstreamFormatDataService },
113+
{ provide: ThemeService, useValue: getMockThemeService() },
114+
{ provide: SearchConfigurationService, useValue: jasmine.createSpyObj(['getCurrentConfiguration']) },
115+
{ provide: PaginationService, useValue: paginationServiceStub },
116+
{ provide: ActivatedRoute, useValue: new ActivatedRouteStub() },
117+
{ provide: LocaleService, useValue: mockLocaleService },
118+
{ provide: APP_CONFIG, useValue: environment },
119+
],
120+
schemas: [NO_ERRORS_SCHEMA],
121+
}).overrideComponent(ExtendedFileSectionComponent, {
122+
remove: {
123+
imports: [
124+
PaginationComponent,
125+
ThemedFileDownloadLinkComponent,
126+
],
127+
},
128+
}).compileComponents();
129+
}));
130+
131+
beforeEach(waitForAsync(() => {
132+
localeService = TestBed.inject(LocaleService);
133+
localeService.getCurrentLanguageCode.and.returnValue(of('en'));
134+
fixture = TestBed.createComponent(ExtendedFileSectionComponent);
135+
component = fixture.componentInstance;
136+
component.item = mockItem;
137+
fixture.detectChanges();
138+
}));
139+
140+
it('should create', () => {
141+
expect(component).toBeTruthy();
142+
});
143+
144+
it('should set pageSize from appConfig', () => {
145+
expect(component.pageSize).toEqual(environment.item.bitstream.pageSize);
146+
});
147+
148+
describe('when the extended file section gets loaded with bitstreams available', () => {
149+
it('should contain a list with bitstream', () => {
150+
const fileSection = fixture.debugElement.queryAll(By.css('.file-section-entry'));
151+
expect(fileSection.length).toEqual(1);
152+
});
153+
});
154+
});
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { AsyncPipe } from '@angular/common';
2+
import {
3+
Component,
4+
Inject,
5+
Input,
6+
OnInit,
7+
} from '@angular/core';
8+
import {
9+
APP_CONFIG,
10+
AppConfig,
11+
} from '@dspace/config/app-config.interface';
12+
import { DSONameService } from '@dspace/core/breadcrumbs/dso-name.service';
13+
import { BitstreamDataService } from '@dspace/core/data/bitstream-data.service';
14+
import { BitstreamFormatDataService } from '@dspace/core/data/bitstream-format-data.service';
15+
import { PaginatedList } from '@dspace/core/data/paginated-list.model';
16+
import { RemoteData } from '@dspace/core/data/remote-data';
17+
import { PaginationService } from '@dspace/core/pagination/pagination.service';
18+
import { PaginationComponentOptions } from '@dspace/core/pagination/pagination-component-options.model';
19+
import { Bitstream } from '@dspace/core/shared/bitstream.model';
20+
import { followLink } from '@dspace/core/shared/follow-link-config.model';
21+
import { Item } from '@dspace/core/shared/item.model';
22+
import { TranslateModule } from '@ngx-translate/core';
23+
import {
24+
from,
25+
Observable,
26+
} from 'rxjs';
27+
import { switchMap } from 'rxjs/operators';
28+
29+
import { ThemedFileDownloadLinkComponent } from '../../../../shared/file-download-link/themed-file-download-link.component';
30+
import { PaginationComponent } from '../../../../shared/pagination/pagination.component';
31+
import { FileSizePipe } from '../../../../shared/utils/file-size-pipe';
32+
import { VarDirective } from '../../../../shared/utils/var.directive';
33+
34+
@Component({
35+
selector: 'ds-extended-file-section',
36+
imports: [
37+
AsyncPipe,
38+
FileSizePipe,
39+
PaginationComponent,
40+
ThemedFileDownloadLinkComponent,
41+
TranslateModule,
42+
VarDirective,
43+
],
44+
templateUrl: './extended-file-section.component.html',
45+
styleUrl: './extended-file-section.component.scss',
46+
})
47+
export class ExtendedFileSectionComponent implements OnInit {
48+
49+
@Input() item: Item;
50+
51+
@Input() bundleName = 'ORIGINAL';
52+
53+
@Input() label = 'item.page.extended-file-section';
54+
55+
bitstreamsRD$: Observable<RemoteData<PaginatedList<Bitstream>>>;
56+
57+
pageSize = this.appConfig.item.bitstream.pageSize;
58+
59+
60+
/**
61+
* The current pagination configuration for the page
62+
*/
63+
pageConfig: PaginationComponentOptions = Object.assign(new PaginationComponentOptions(), {
64+
id: 'efs',
65+
currentPage: 1,
66+
pageSize: this.appConfig.item.bitstream.pageSize,
67+
});
68+
69+
70+
constructor(
71+
protected bitstreamDataService: BitstreamDataService,
72+
protected bitstreamFormatDataService: BitstreamFormatDataService,
73+
public dsoNameService: DSONameService,
74+
@Inject(APP_CONFIG) protected appConfig: AppConfig,
75+
private paginationService: PaginationService,
76+
) {
77+
this.bitstreamsRD$ = from([]);
78+
}
79+
80+
ngOnInit(): void {
81+
this.bitstreamsRD$ = this.paginationService.getCurrentPagination(this.pageConfig.id, this.pageConfig).pipe(
82+
switchMap((options: PaginationComponentOptions) => {
83+
return this.bitstreamDataService.findAllByItemAndBundleName(
84+
this.item,
85+
this.bundleName,
86+
{ elementsPerPage: options.pageSize, currentPage: options.currentPage },
87+
true,
88+
true,
89+
followLink('format'),
90+
followLink('accessStatus'),
91+
);
92+
}),
93+
);
94+
}
95+
96+
97+
}

0 commit comments

Comments
 (0)