Skip to content

Commit bb5aa68

Browse files
committed
feat(submission): add configurable metadatafield visibility in external import preview #5151
1 parent 3d3615a commit bb5aa68

8 files changed

Lines changed: 140 additions & 3 deletions

config/config.example.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,16 @@ submission:
253253
# The configured icon will be displayed next to the authority value in submission and on item page or search results.
254254
- source: orcid
255255
- path: assets/images/orcid.logo.icon.svg
256+
# Settings for import item from an external source
257+
importExternal:
258+
# Toggle visibility of metadata field names in the external import preview modal.
259+
# Possible values:
260+
# - 'disable': show only the translated label
261+
# - 'tooltip': (default) also show an info icon with the field name as tooltip
262+
# - 'labeled': also show the field name in parentheses
263+
# - 'full': show both the 'labeled' and 'tooltip' modes
264+
viewMode: default
265+
256266
# Fallback language in which the UI will be rendered if the user's browser language is not an active language
257267
fallbackLanguage: en
258268

src/app/submission/import-external/import-external-preview/submission-import-external-preview.component.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ <h2>{{'submission.import-external.preview.title.' + labelPrefix | translate}}</h
1818
</div>
1919
@for (metadata of metadataList; track metadata) {
2020
<div class="row">
21-
<p class="col-md-12">
22-
<strong class="">{{'item.preview.' + metadata.key | translate}}</strong><br>
21+
<p id="{{metadata.key}}" class="col-md-12">
22+
<strong class="">{{'item.preview.' + metadata.key | translate}}</strong>
23+
@if ([MetadataFieldViewMode.Labeled, MetadataFieldViewMode.Full].includes(viewMode)) {
24+
<span class="text-muted ps-2">({{metadata.key}})</span>
25+
}
26+
@if ([MetadataFieldViewMode.Tooltip, MetadataFieldViewMode.Full].includes(viewMode)) {
27+
<i class="fas fa-info-circle text-primary ps-2" [ngbTooltip]="metadata.key"></i>
28+
}
29+
<br>
2330
@for (metadatum of metadata.values; track metadatum) {
2431
<span>{{metadatum.value}}</span><br>
2532
}

src/app/submission/import-external/import-external-preview/submission-import-external-preview.component.spec.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import {
88
TestBed,
99
waitForAsync,
1010
} from '@angular/core/testing';
11+
import { By } from '@angular/platform-browser';
1112
import { Router } from '@angular/router';
13+
import { APP_CONFIG } from '@dspace/config/app-config.interface';
14+
import { ImportExternalMetadataViewMode } from '@dspace/config/import-external-metadata-view.mode';
1215
import { NotificationsService } from '@dspace/core/notification-system/notifications.service';
1316
import { ExternalSourceEntry } from '@dspace/core/shared/external-source-entry.model';
1417
import { Metadata } from '@dspace/core/shared/metadata.utils';
@@ -25,6 +28,7 @@ import { getTestScheduler } from 'jasmine-marbles';
2528
import { of } from 'rxjs';
2629
import { TestScheduler } from 'rxjs/testing';
2730

31+
import { environment } from '../../../../environments/environment.test';
2832
import { CollectionListEntry } from '../../../shared/collection-dropdown/collection-dropdown.component';
2933
import { SubmissionService } from '../../submission.service';
3034
import { SubmissionImportExternalCollectionComponent } from '../import-external-collection/submission-import-external-collection.component';
@@ -68,6 +72,7 @@ describe('SubmissionImportExternalPreviewComponent test suite', () => {
6872
{ provide: NotificationsService, useValue: new NotificationsServiceStub() },
6973
{ provide: NgbModal, useValue: ngbModal },
7074
{ provide: NgbActiveModal, useValue: ngbActiveModal },
75+
{ provide: APP_CONFIG, useValue: environment },
7176
SubmissionImportExternalPreviewComponent,
7277
],
7378
schemas: [NO_ERRORS_SCHEMA],
@@ -118,6 +123,7 @@ describe('SubmissionImportExternalPreviewComponent test suite', () => {
118123
fixture.detectChanges();
119124

120125
expect(comp.metadataList).toEqual(expected);
126+
expect(comp.viewMode).toEqual(environment.submission.importExternal.viewMode);
121127
});
122128

123129
it('Should close the modal calling \'activeModal.dismiss\'', () => {
@@ -165,6 +171,61 @@ describe('SubmissionImportExternalPreviewComponent test suite', () => {
165171
done();
166172
});
167173
});
174+
175+
describe('Metadatafield View Modes UI rendering', () => {
176+
beforeEach(() => {
177+
fixture = TestBed.createComponent(SubmissionImportExternalPreviewComponent);
178+
comp = fixture.componentInstance;
179+
comp.externalSourceEntry = externalEntry;
180+
fixture.detectChanges();
181+
});
182+
183+
it('should display tooltip only in Tooltip mode', () => {
184+
comp.viewMode = ImportExternalMetadataViewMode.Tooltip;
185+
fixture.detectChanges();
186+
187+
const tooltipIcon = fixture.debugElement.query(By.css('.fa-info-circle'));
188+
const labelText = fixture.debugElement.query(By.css('span.text-muted'));
189+
190+
expect(tooltipIcon).toBeTruthy();
191+
expect(labelText).toBeNull();
192+
});
193+
194+
it('should display label only in Labeled mode', () => {
195+
comp.viewMode = ImportExternalMetadataViewMode.Labeled;
196+
fixture.detectChanges();
197+
198+
const tooltipIcon = fixture.debugElement.query(By.css('.fa-info-circle'));
199+
const labelText = fixture.debugElement.query(By.css('span.text-muted'));
200+
201+
expect(tooltipIcon).toBeNull();
202+
expect(labelText).toBeTruthy();
203+
expect(labelText.nativeElement.textContent).toContain('(dc.identifier.uri)');
204+
});
205+
206+
it('should display both in Full mode', () => {
207+
comp.viewMode = ImportExternalMetadataViewMode.Full;
208+
fixture.detectChanges();
209+
210+
const tooltipIcon = fixture.debugElement.query(By.css('.fa-info-circle'));
211+
const labelText = fixture.debugElement.query(By.css('span.text-muted'));
212+
213+
expect(tooltipIcon).toBeTruthy();
214+
expect(labelText).toBeTruthy();
215+
expect(labelText.nativeElement.textContent).toContain('(dc.identifier.uri)');
216+
});
217+
218+
it('should display neither in Disable mode', () => {
219+
comp.viewMode = ImportExternalMetadataViewMode.Disable;
220+
fixture.detectChanges();
221+
222+
const tooltipIcon = fixture.debugElement.query(By.css('.fa-info-circle'));
223+
const labelText = fixture.debugElement.query(By.css('span.text-muted'));
224+
225+
expect(tooltipIcon).toBeNull();
226+
expect(labelText).toBeNull();
227+
});
228+
});
168229
});
169230

170231
// declare a test component

src/app/submission/import-external/import-external-preview/submission-import-external-preview.component.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
21
import {
32
Component,
3+
Inject,
44
Input,
55
OnInit,
66
} from '@angular/core';
77
import { Router } from '@angular/router';
8+
import {
9+
APP_CONFIG,
10+
AppConfig,
11+
} from '@dspace/config/app-config.interface';
12+
import { ImportExternalMetadataViewMode } from '@dspace/config/import-external-metadata-view.mode';
813
import { NotificationsService } from '@dspace/core/notification-system/notifications.service';
914
import { ExternalSourceEntry } from '@dspace/core/shared/external-source-entry.model';
1015
import { MetadataValue } from '@dspace/core/shared/metadata.models';
@@ -14,6 +19,7 @@ import {
1419
NgbActiveModal,
1520
NgbModal,
1621
NgbModalRef,
22+
NgbTooltipModule,
1723
} from '@ng-bootstrap/ng-bootstrap';
1824
import { TranslateModule } from '@ngx-translate/core';
1925
import { mergeMap } from 'rxjs/operators';
@@ -30,6 +36,7 @@ import { SubmissionImportExternalCollectionComponent } from '../import-external-
3036
styleUrls: ['./submission-import-external-preview.component.scss'],
3137
templateUrl: './submission-import-external-preview.component.html',
3238
imports: [
39+
NgbTooltipModule,
3340
TranslateModule,
3441
],
3542
})
@@ -51,26 +58,40 @@ export class SubmissionImportExternalPreviewComponent implements OnInit {
5158
*/
5259
modalRef: NgbModalRef;
5360

61+
/**
62+
* The view mode for the metadatafield names
63+
*/
64+
public viewMode: ImportExternalMetadataViewMode;
65+
66+
/**
67+
* The available view modes
68+
*/
69+
public MetadataFieldViewMode = ImportExternalMetadataViewMode;
70+
5471
/**
5572
* Initialize the component variables.
5673
* @param {NgbActiveModal} activeModal
5774
* @param {SubmissionService} submissionService
5875
* @param {NgbModal} modalService
5976
* @param {Router} router
6077
* @param {NotificationsService} notificationService
78+
* @param {AppConfig} appConfig
6179
*/
6280
constructor(
6381
private activeModal: NgbActiveModal,
6482
private submissionService: SubmissionService,
6583
private modalService: NgbModal,
6684
private router: Router,
6785
private notificationService: NotificationsService,
86+
@Inject(APP_CONFIG) protected appConfig: AppConfig,
6887
) { }
6988

7089
/**
7190
* Metadata initialization for HTML display.
7291
*/
7392
ngOnInit(): void {
93+
this.viewMode = this.appConfig.submission.importExternal.viewMode
94+
?? this.MetadataFieldViewMode.Default;
7495
this.metadataList = [];
7596
const metadataKeys = Object.keys(this.externalSourceEntry.metadata);
7697
metadataKeys.forEach((key) => {

src/config/default-app-config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ImportExternalMetadataViewMode } from '@dspace/config/import-external-metadata-view.mode';
12
import { LayoutConfig } from '@dspace/config/layout-config.interfaces';
23
import { SearchResultConfig } from '@dspace/config/search-result-config.interface';
34

@@ -293,6 +294,10 @@ export class DefaultAppConfig implements AppConfig {
293294
// Icons that should remain visible even when no authority value is present for the metadata field
294295
iconsVisibleWithNoAuthority: ['fas fa-user'],
295296
},
297+
importExternal: {
298+
// Visibility of metadatafield names in preview item from an external source
299+
viewMode: ImportExternalMetadataViewMode.Default,
300+
},
296301
};
297302

298303
// Fallback language in which the UI will be rendered if the user's browser language is not an active language
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Represents the view modes for metadatafield names in the external import preview modal.
3+
*/
4+
export enum ImportExternalMetadataViewMode {
5+
/**
6+
* Hide metadatafield names (show only labels).
7+
*/
8+
Disable = 'disable',
9+
/**
10+
* Show tooltip with field name.
11+
*/
12+
Tooltip = 'tooltip',
13+
/**
14+
* Show field name in parentheses.
15+
*/
16+
Labeled = 'labeled',
17+
/**
18+
* Show both labeled and tooltip modes.
19+
*/
20+
Full = 'full',
21+
22+
Default = Tooltip,
23+
}

src/config/submission-config.interface.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ImportExternalMetadataViewMode } from '@dspace/config/import-external-metadata-view.mode';
2+
13
import { Config } from './config.interface';
24

35
interface AutosaveConfig extends Config {
@@ -43,4 +45,7 @@ export interface SubmissionConfig extends Config {
4345
duplicateDetection: DuplicateDetectionConfig;
4446
typeBind: TypeBindConfig;
4547
icons: IconsConfig;
48+
importExternal: {
49+
viewMode: ImportExternalMetadataViewMode;
50+
};
4651
}

src/environments/environment.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// This configuration is only used for unit tests, end-to-end tests use environment.production.ts
22
import { AdvancedAttachmentElementType } from '@dspace/config/advanced-attachment-rendering.config';
3+
import { ImportExternalMetadataViewMode } from '@dspace/config/import-external-metadata-view.mode';
34
import { NotificationAnimationsType } from '@dspace/config/notifications-config.interfaces';
45
import { RestRequestMethod } from '@dspace/config/rest-request-method';
56
import { BuildConfig } from 'src/config/build-config.interface';
@@ -197,6 +198,10 @@ export const environment: BuildConfig = {
197198
],
198199
},
199200
},
201+
importExternal: {
202+
// Visibility of metadatafield names in preview item from an external source
203+
viewMode: ImportExternalMetadataViewMode.Default,
204+
},
200205
},
201206

202207
// NOTE: will log all redux actions and transfers in console

0 commit comments

Comments
 (0)