mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
67611: External-Source-Entry import window
This commit is contained in:
@@ -1525,6 +1525,32 @@
|
||||
|
||||
"submission.sections.describe.relationship-lookup.close": "Close",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-button-title": "Import remote entry",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new": "Import as a new local authority entry",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.cancel": "Cancel",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.entities": "Entities",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new": "Import as a new local entity",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.head.lcname": "Importing from LC Name",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.head.orcidV2": "Importing from ORCID",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaJournal": "Importing from Sherpa Journal",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.head.sherpaPublisher": "Importing from Sherpa Publisher",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.import": "Import",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.external-source.import-modal.title": "Import Remote Entry",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all",
|
||||
|
||||
"submission.sections.describe.relationship-lookup.search-tab.deselect-page": "Deselect page",
|
||||
|
@@ -25,6 +25,12 @@ export class NormalizedExternalSourceEntry extends NormalizedObject<ExternalSour
|
||||
@autoserialize
|
||||
value: string;
|
||||
|
||||
/**
|
||||
* The ID of the external source this entry originates from
|
||||
*/
|
||||
@autoserialize
|
||||
externalSource: string;
|
||||
|
||||
/**
|
||||
* Metadata of the entry
|
||||
*/
|
||||
|
@@ -24,6 +24,11 @@ export class ExternalSourceEntry extends ListableObject {
|
||||
*/
|
||||
value: string;
|
||||
|
||||
/**
|
||||
* The ID of the external source this entry originates from
|
||||
*/
|
||||
externalSource: string;
|
||||
|
||||
/**
|
||||
* Metadata of the entry
|
||||
*/
|
||||
|
@@ -1,2 +1,11 @@
|
||||
<div class="d-inline-block">
|
||||
<button (click)="import()"
|
||||
class="btn btn-outline-primary btn-sm float-left"
|
||||
title="{{'submission.sections.describe.relationship-lookup.external-source.import-button-title' | translate}}">
|
||||
<i class="fas fa-cloud-download-alt fa-fw"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="d-inline-block ml-2">
|
||||
<div>{{object.display}}</div>
|
||||
<div *ngIf="uri"><a [href]="uri.value">{{uri.value}}</a></div>
|
||||
</div>
|
||||
|
@@ -3,9 +3,13 @@ import { ExternalSourceEntry } from '../../../../../core/shared/external-source-
|
||||
import { listableObjectComponent } from '../../../../../shared/object-collection/shared/listable-object/listable-object.decorator';
|
||||
import { ViewMode } from '../../../../../core/shared/view-mode.model';
|
||||
import { Context } from '../../../../../core/shared/context.model';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, Inject, OnInit } from '@angular/core';
|
||||
import { Metadata } from '../../../../../core/shared/metadata.utils';
|
||||
import { MetadataValue } from '../../../../../core/shared/metadata.models';
|
||||
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ExternalSourceEntryImportModalComponent } from '../../../../../shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component';
|
||||
import { DsDynamicLookupRelationExternalSourceTabComponent } from '../../../../../shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component';
|
||||
import { hasValue } from '../../../../../shared/empty.util';
|
||||
|
||||
@listableObjectComponent(ExternalSourceEntry, ViewMode.ListElement, Context.SubmissionModal)
|
||||
@Component({
|
||||
@@ -19,7 +23,29 @@ export class ExternalSourceEntryListSubmissionElementComponent extends AbstractL
|
||||
*/
|
||||
uri: MetadataValue;
|
||||
|
||||
/**
|
||||
* The modal for importing the entry
|
||||
*/
|
||||
modalRef: NgbModalRef;
|
||||
|
||||
constructor(@Inject(DsDynamicLookupRelationExternalSourceTabComponent) private externalSourceTab: DsDynamicLookupRelationExternalSourceTabComponent,
|
||||
private modalService: NgbModal) {
|
||||
super();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.uri = Metadata.first(this.object.metadata, 'dc.identifier.uri');
|
||||
}
|
||||
|
||||
import(): void {
|
||||
this.modalRef = this.modalService.open(ExternalSourceEntryImportModalComponent, {
|
||||
size: 'lg',
|
||||
container: 'ds-dynamic-lookup-relation-modal'
|
||||
});
|
||||
const modalComp = this.modalRef.componentInstance;
|
||||
modalComp.externalSourceEntry = this.object;
|
||||
if (hasValue(this.externalSourceTab) && hasValue(this.externalSourceTab.relationship)) {
|
||||
modalComp.relationship = this.externalSourceTab.relationship;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
<ng-template ngbTabContent>
|
||||
<ds-dynamic-lookup-relation-external-source-tab
|
||||
[listId]="listId"
|
||||
[relationship]="relationshipOptions"
|
||||
[repeatable]="repeatable"
|
||||
[context]="context"
|
||||
[externalSource]="source"
|
||||
|
@@ -1,3 +1,11 @@
|
||||
.modal-footer {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Render child-modals slightly smaller than this modal to avoid complete overlap */
|
||||
:host {
|
||||
::ng-deep .modal-content {
|
||||
width: 90%;
|
||||
margin: 5%;
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@
|
||||
<ng-container *ngVar="(entriesRD$ | async) as entriesRD">
|
||||
<ds-viewable-collection *ngIf="entriesRD?.hasSucceeded && !entriesRD?.isLoading && entriesRD?.payload?.page?.length > 0" @fadeIn
|
||||
[objects]="entriesRD"
|
||||
[selectable]="true"
|
||||
[selectionConfig]="{ repeatable: repeatable, listId: listId }"
|
||||
[config]="initialPagination"
|
||||
[hideGear]="true"
|
||||
|
@@ -14,6 +14,7 @@ import { Context } from '../../../../../../core/shared/context.model';
|
||||
import { ListableObject } from '../../../../../object-collection/shared/listable-object.model';
|
||||
import { fadeIn, fadeInOut } from '../../../../../animations/fade';
|
||||
import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model';
|
||||
import { RelationshipOptions } from '../../../models/relationship-options.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-dynamic-lookup-relation-external-source-tab',
|
||||
@@ -34,6 +35,7 @@ import { PaginationComponentOptions } from '../../../../../pagination/pagination
|
||||
export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit {
|
||||
@Input() label: string;
|
||||
@Input() listId: string;
|
||||
@Input() relationship: RelationshipOptions;
|
||||
@Input() repeatable: boolean;
|
||||
@Input() context: Context;
|
||||
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
|
||||
|
@@ -0,0 +1,50 @@
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="modal-title">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.title') | translate }}</h4>
|
||||
<button type="button" class="close" aria-label="Close button" aria-describedby="modal-title"
|
||||
(click)="modal.dismiss()">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<h4>{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.head.' + externalSourceEntry.externalSource | translate) }}</h4>
|
||||
<div id="external-source-entry-information" class="mb-3">
|
||||
<div><span>{{externalSourceEntry.display}}</span></div>
|
||||
<div *ngIf="uri"><a href="{{uri.value}}">{{uri.value}}</a></div>
|
||||
</div>
|
||||
|
||||
<h4>{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.select' | translate) }}</h4>
|
||||
<div id="external-source-entry-entities" class="mb-2">
|
||||
<h5 class="font-weight-bold">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.entities' | translate) }}</h5>
|
||||
|
||||
<ds-search-results [searchResults]="(localEntitiesRD$ | async)"
|
||||
[sortConfig]="this.lookupRelationService.searchConfig?.sort"
|
||||
[searchConfig]="this.lookupRelationService.searchConfig"
|
||||
[selectable]="true"
|
||||
[selectionConfig]="{ repeatable: false, listId: entityListId }"
|
||||
[linkType]="linkTypes.ExternalLink"
|
||||
[context]="context"
|
||||
(deselectObject)="deselectEntity($event)"
|
||||
(selectObject)="selectEntity($event)">
|
||||
</ds-search-results>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="new-entity" id="new-entity" value="new-entity" (click)="selectNewEntity()" [checked]="selectedImportType === importType.NewEntity" />
|
||||
<label class="form-check-label" for="new-entity">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.entities.new' | translate) }}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="external-source-entry-authority">
|
||||
<h5 class="font-weight-bold">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.authority' | translate) }}</h5>
|
||||
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="new-authority" id="new-authority" value="new-authority" (click)="selectNewAuthority()" [checked]="selectedImportType === importType.NewAuthority" />
|
||||
<label class="form-check-label" for="new-authority">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.authority.new' | translate) }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div>
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="close()">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.cancel' | translate) }}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary" [disabled]="selectedImportType === importType.None" (click)="import()">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.import' | translate) }}</button>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,3 @@
|
||||
.modal-footer {
|
||||
justify-content: space-between;
|
||||
}
|
@@ -0,0 +1,162 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ExternalSourceEntry } from '../../../../../../../core/shared/external-source-entry.model';
|
||||
import { MetadataValue } from '../../../../../../../core/shared/metadata.models';
|
||||
import { Metadata } from '../../../../../../../core/shared/metadata.utils';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { RemoteData } from '../../../../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../../../../core/data/paginated-list';
|
||||
import { SearchResult } from '../../../../../../search/search-result.model';
|
||||
import { Item } from '../../../../../../../core/shared/item.model';
|
||||
import { RelationshipOptions } from '../../../../models/relationship-options.model';
|
||||
import { LookupRelationService } from '../../../../../../../core/data/lookup-relation.service';
|
||||
import { PaginatedSearchOptions } from '../../../../../../search/paginated-search-options.model';
|
||||
import { CollectionElementLinkType } from '../../../../../../object-collection/collection-element-link.type';
|
||||
import { Context } from '../../../../../../../core/shared/context.model';
|
||||
import { SelectableListService } from '../../../../../../object-list/selectable-list/selectable-list.service';
|
||||
|
||||
/**
|
||||
* The possible types of import for the external entry
|
||||
*/
|
||||
export enum ImportType {
|
||||
None = 'None',
|
||||
LocalEntity = 'LocalEntity',
|
||||
LocalAuthority = 'LocalAuthority',
|
||||
NewEntity = 'NewEntity',
|
||||
NewAuthority = 'NewAuthority'
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ds-external-source-entry-import-modal',
|
||||
styleUrls: ['./external-source-entry-import-modal.component.scss'],
|
||||
templateUrl: './external-source-entry-import-modal.component.html'
|
||||
})
|
||||
export class ExternalSourceEntryImportModalComponent implements OnInit {
|
||||
/**
|
||||
* The external source entry
|
||||
*/
|
||||
externalSourceEntry: ExternalSourceEntry;
|
||||
|
||||
/**
|
||||
* The current relationship-options used for filtering results
|
||||
*/
|
||||
relationship: RelationshipOptions;
|
||||
|
||||
/**
|
||||
* The metadata value for the entry's uri
|
||||
*/
|
||||
uri: MetadataValue;
|
||||
|
||||
/**
|
||||
* Local entities with a similar name
|
||||
*/
|
||||
localEntitiesRD$: Observable<RemoteData<PaginatedList<SearchResult<Item>>>>;
|
||||
|
||||
/**
|
||||
* Search options to use for fetching similar results
|
||||
*/
|
||||
searchOptions: PaginatedSearchOptions;
|
||||
|
||||
/**
|
||||
* The type of link to render in listable elements
|
||||
*/
|
||||
linkTypes = CollectionElementLinkType;
|
||||
|
||||
/**
|
||||
* The context we're currently in (submission)
|
||||
*/
|
||||
context = Context.SubmissionModal;
|
||||
|
||||
/**
|
||||
* List ID for selecting local entities
|
||||
*/
|
||||
entityListId = 'external-source-import-entity';
|
||||
|
||||
/**
|
||||
* List ID for selecting local authorities
|
||||
*/
|
||||
authorityListId = 'external-source-import-authority';
|
||||
|
||||
/**
|
||||
* ImportType enum
|
||||
*/
|
||||
importType = ImportType;
|
||||
|
||||
/**
|
||||
* The type of import the user currently has selected
|
||||
*/
|
||||
selectedImportType = ImportType.None;
|
||||
|
||||
constructor(public modal: NgbActiveModal,
|
||||
public lookupRelationService: LookupRelationService,
|
||||
private selectService: SelectableListService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.uri = Metadata.first(this.externalSourceEntry.metadata, 'dc.identifier.uri');
|
||||
this.searchOptions = Object.assign(new PaginatedSearchOptions({ query: this.externalSourceEntry.value }));
|
||||
this.localEntitiesRD$ = this.lookupRelationService.getLocalResults(this.relationship, this.searchOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the window
|
||||
*/
|
||||
close() {
|
||||
this.modal.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the import of the external entry
|
||||
*/
|
||||
import() {
|
||||
console.log('TODO: Import');
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselected a local entity
|
||||
* @param event
|
||||
*/
|
||||
deselectEntity(event) {
|
||||
this.selectedImportType = ImportType.None;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selected a local entity
|
||||
* @param event
|
||||
*/
|
||||
selectEntity(event) {
|
||||
this.selectedImportType = ImportType.LocalEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Selected/deselected the new entity option
|
||||
*/
|
||||
selectNewEntity() {
|
||||
if (this.selectedImportType === ImportType.NewEntity) {
|
||||
this.selectedImportType = ImportType.None;
|
||||
} else {
|
||||
this.selectedImportType = ImportType.NewEntity;
|
||||
this.deselectAllLists();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Selected/deselected the new authority option
|
||||
*/
|
||||
selectNewAuthority() {
|
||||
if (this.selectedImportType === ImportType.NewAuthority) {
|
||||
this.selectedImportType = ImportType.None;
|
||||
} else {
|
||||
this.selectedImportType = ImportType.NewAuthority;
|
||||
this.deselectAllLists();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect every element from both entity and authority lists
|
||||
*/
|
||||
deselectAllLists() {
|
||||
this.selectService.deselectAll(this.entityListId);
|
||||
this.selectService.deselectAll(this.authorityListId);
|
||||
}
|
||||
}
|
@@ -175,6 +175,7 @@ import { SidebarFilterSelectedOptionComponent } from './sidebar/filter/sidebar-f
|
||||
import { MetadataRepresentationListComponent } from '../+item-page/simple/metadata-representation-list/metadata-representation-list.component';
|
||||
import { SelectableListItemControlComponent } from './object-collection/shared/selectable-list-item-control/selectable-list-item-control.component';
|
||||
import { DsDynamicLookupRelationExternalSourceTabComponent } from './form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/dynamic-lookup-relation-external-source-tab.component';
|
||||
import { ExternalSourceEntryImportModalComponent } from './form/builder/ds-dynamic-form-ui/relation-lookup-modal/external-source-tab/external-source-entry-import-modal/external-source-entry-import-modal.component';
|
||||
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
@@ -331,7 +332,8 @@ const COMPONENTS = [
|
||||
ItemSelectComponent,
|
||||
CollectionSelectComponent,
|
||||
MetadataRepresentationLoaderComponent,
|
||||
SelectableListItemControlComponent
|
||||
SelectableListItemControlComponent,
|
||||
ExternalSourceEntryImportModalComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
@@ -393,7 +395,8 @@ const ENTRY_COMPONENTS = [
|
||||
SearchAuthorityFilterComponent,
|
||||
DsDynamicLookupRelationSearchTabComponent,
|
||||
DsDynamicLookupRelationSelectionTabComponent,
|
||||
DsDynamicLookupRelationExternalSourceTabComponent
|
||||
DsDynamicLookupRelationExternalSourceTabComponent,
|
||||
ExternalSourceEntryImportModalComponent
|
||||
];
|
||||
|
||||
const SHARED_ITEM_PAGE_COMPONENTS = [
|
||||
|
Reference in New Issue
Block a user