67611: Refactored import button to separate component within object-collection + moved calling of import modal to external-source tab

This commit is contained in:
Kristof De Langhe
2019-12-05 14:06:29 +01:00
parent 6ada3fae5b
commit 7a904f9bf7
13 changed files with 223 additions and 46 deletions

View File

@@ -1,11 +1,4 @@
<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>

View File

@@ -6,10 +6,6 @@ import { Context } from '../../../../../core/shared/context.model';
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({
@@ -23,29 +19,7 @@ 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;
}
}
}

View File

@@ -14,8 +14,9 @@
[config]="initialPagination"
[hideGear]="true"
[context]="context"
(deselectObject)="deselectObject.emit($event)"
(selectObject)="selectObject.emit($event)">
[importable]="true"
[importConfig]="importConfig"
(importObject)="import($event)">
</ds-viewable-collection>
<ds-loading *ngIf="!entriesRD || !entriesRD?.payload || entriesRD?.isLoading"
message="{{'loading.search-results' | translate}}"></ds-loading>

View File

@@ -1,4 +1,4 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angular/core';
import { SEARCH_CONFIG_SERVICE } from '../../../../../../+my-dspace-page/my-dspace-page.component';
import { SearchConfigurationService } from '../../../../../../core/shared/search/search-configuration.service';
import { Router } from '@angular/router';
@@ -15,6 +15,11 @@ import { ListableObject } from '../../../../../object-collection/shared/listable
import { fadeIn, fadeInOut } from '../../../../../animations/fade';
import { PaginationComponentOptions } from '../../../../../pagination/pagination-component-options.model';
import { RelationshipOptions } from '../../../models/relationship-options.model';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ExternalSourceEntryImportModalComponent } from './external-source-entry-import-modal/external-source-entry-import-modal.component';
import { Subscription } from 'rxjs/internal/Subscription';
import { hasValue } from '../../../../../empty.util';
import { SelectableListService } from '../../../../../object-list/selectable-list/selectable-list.service';
@Component({
selector: 'ds-dynamic-lookup-relation-external-source-tab',
@@ -32,7 +37,7 @@ import { RelationshipOptions } from '../../../models/relationship-options.model'
]
})
export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit {
export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit, OnDestroy {
@Input() label: string;
@Input() listId: string;
@Input() relationship: RelationshipOptions;
@@ -56,9 +61,28 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
*/
entriesRD$: Observable<RemoteData<PaginatedList<ExternalSourceEntry>>>;
/**
* Config to use for the import buttons
*/
importConfig = {
buttonLabel: 'submission.sections.describe.relationship-lookup.external-source.import-button-title'
};
/**
* The modal for importing the entry
*/
modalRef: NgbModalRef;
/**
* Subscription to the modal's importedObject event-emitter
*/
importObjectSub: Subscription;
constructor(private router: Router,
public searchConfigService: SearchConfigurationService,
private externalSourceService: ExternalSourceService) {
private externalSourceService: ExternalSourceService,
private modalService: NgbModal,
private selectableListService: SelectableListService) {
}
ngOnInit(): void {
@@ -67,4 +91,28 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
this.externalSourceService.getExternalSourceEntries(this.externalSource.id, searchOptions))
)
}
/**
* Start the import of an entry by opening up an import modal window
* @param entry The entry to import
*/
import(entry) {
this.modalRef = this.modalService.open(ExternalSourceEntryImportModalComponent, {
size: 'lg',
container: 'ds-dynamic-lookup-relation-modal'
});
const modalComp = this.modalRef.componentInstance;
modalComp.externalSourceEntry = entry;
modalComp.relationship = this.relationship;
this.importObjectSub = modalComp.importedObject.subscribe((object) => {
this.selectableListService.selectSingle(this.listId, object);
this.selectObject.emit(object);
});
}
ngOnDestroy(): void {
if (hasValue(this.importObjectSub)) {
this.importObjectSub.unsubscribe();
}
}
}

View File

@@ -26,7 +26,7 @@
[selectionConfig]="{ repeatable: false, listId: entityListId }"
[linkType]="linkTypes.ExternalLink"
[context]="context"
(deselectObject)="deselectEntity($event)"
(deselectObject)="deselectEntity()"
(selectObject)="selectEntity($event)">
</ds-search-results>
<div class="form-check">

View File

@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, EventEmitter, 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';
@@ -14,6 +14,8 @@ import { PaginatedSearchOptions } from '../../../../../../search/paginated-searc
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';
import { ListableObject } from '../../../../../../object-collection/shared/listable-object.model';
import { take } from 'rxjs/operators';
/**
* The possible types of import for the external entry
@@ -87,6 +89,21 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
*/
selectedImportType = ImportType.None;
/**
* The selected local entity
*/
selectedEntity: ListableObject;
/**
* The selected local authority
*/
selectedAuthority: ListableObject;
/**
* An object has been imported, send it to the parent component
*/
importedObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
constructor(public modal: NgbActiveModal,
public lookupRelationService: LookupRelationService,
private selectService: SelectableListService) {
@@ -109,14 +126,64 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
* Perform the import of the external entry
*/
import() {
console.log('TODO: Import');
switch (this.selectedImportType) {
case ImportType.LocalEntity : {
this.importLocalEntity();
break;
}
case ImportType.NewEntity : {
this.importNewEntity();
break;
}
case ImportType.LocalAuthority : {
this.importLocalAuthority();
break;
}
case ImportType.NewAuthority : {
this.importNewAuthority();
break;
}
}
this.selectedImportType = ImportType.None;
this.deselectAllLists();
this.close();
}
/**
* Import the selected local entity
*/
importLocalEntity() {
if (this.selectedEntity !== undefined) {
this.importedObject.emit(this.selectedEntity);
}
}
/**
* Create and import a new entity from the external entry
*/
importNewEntity() {
this.importedObject.emit(this.externalSourceEntry);
}
/**
* Import the selected local authority
*/
importLocalAuthority() {
// TODO: Implement ability to import local authorities
}
/**
* Create and import a new authority from the external entry
*/
importNewAuthority() {
// TODO: Implement ability to import new authorities
}
/**
* Deselected a local entity
* @param event
*/
deselectEntity(event) {
deselectEntity() {
this.selectedEntity = undefined;
if (this.selectedImportType === ImportType.LocalEntity) {
this.selectedImportType = ImportType.None;
}
@@ -124,9 +191,10 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
/**
* Selected a local entity
* @param event
* @param entity
*/
selectEntity(event) {
selectEntity(entity) {
this.selectedEntity = entity;
this.selectedImportType = ImportType.LocalEntity;
}
@@ -142,6 +210,25 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
}
}
/**
* Deselected a local authority
*/
deselectAuthority() {
this.selectedAuthority = undefined;
if (this.selectedImportType === ImportType.LocalAuthority) {
this.selectedImportType = ImportType.None;
}
}
/**
* Selected a local authority
* @param authority
*/
selectAuthority(authority) {
this.selectedAuthority = authority;
this.selectedImportType = ImportType.LocalAuthority;
}
/**
* Selected/deselected the new authority option
*/

View File

@@ -15,6 +15,9 @@
(sortFieldChange)="onSortFieldChange($event)"
[selectable]="selectable"
[selectionConfig]="selectionConfig"
[importable]="importable"
[importConfig]="importConfig"
(importObject)="importObject.emit($event)"
*ngIf="(currentMode$ | async) === viewModeEnum.ListElement">
</ds-object-list>

View File

@@ -53,6 +53,21 @@ export class ObjectCollectionComponent implements OnInit {
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
@Output() selectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* Whether or not to add an import button to the object elements
*/
@Input() importable = false;
/**
* The config to use for the import button
*/
@Input() importConfig: { buttonLabel: string };
/**
* Send an import event to the parent component
*/
@Output() importObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* The link type of the rendered list elements
*/

View File

@@ -0,0 +1,7 @@
<div class="d-inline-block mr-2">
<button (click)="importObject.emit(object)"
class="btn btn-outline-primary btn-sm float-left"
title="{{importConfig?.buttonLabel | translate}}">
<i class="fas fa-cloud-download-alt fa-fw"></i>
</button>
</div>

View File

@@ -0,0 +1,26 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { ListableObject } from '../listable-object.model';
@Component({
selector: 'ds-importable-list-item-control',
templateUrl: './importable-list-item-control.component.html'
})
/**
* Component adding an import button to a list item
*/
export class ImportableListItemControlComponent {
/**
* The item or metadata to determine the component for
*/
@Input() object: ListableObject;
/**
* Extra configuration for the import button
*/
@Input() importConfig: { buttonLabel: string };
/**
* Output the object to import
*/
@Output() importObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
}

View File

@@ -20,6 +20,11 @@
(deselectObject)="deselectObject.emit($event)"
(selectObject)="selectObject.emit($event)"></ds-selectable-list-item-control>
</span>
<span *ngIf="importable">
<ds-importable-list-item-control [object]="object"
[importConfig]="importConfig"
(importObject)="importObject.emit($event)"></ds-importable-list-item-control>
</span>
<ds-listable-object-component-loader [object]="object" [viewMode]="viewMode" [index]="i" [context]="context" [linkType]="linkType"
[listID]="selectionConfig?.listId"></ds-listable-object-component-loader>
</li>

View File

@@ -79,6 +79,16 @@ export class ObjectListComponent {
*/
@Input() hidePaginationDetail = false;
/**
* Whether or not to add an import button to the object
*/
@Input() importable = false;
/**
* Config used for the import button
*/
@Input() importConfig: { importLabel: string };
/**
* The current listable objects
*/
@@ -137,6 +147,12 @@ export class ObjectListComponent {
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
@Output() selectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* Send an import event to the parent component
*/
@Output() importObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* An event fired when the sort field is changed.
* Event's payload equals to the newly selected sort field.

View File

@@ -176,6 +176,7 @@ import { MetadataRepresentationListComponent } from '../+item-page/simple/metada
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';
import { ImportableListItemControlComponent } from './object-collection/shared/importable-list-item-control/importable-list-item-control.component';
const MODULES = [
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
@@ -333,7 +334,8 @@ const COMPONENTS = [
CollectionSelectComponent,
MetadataRepresentationLoaderComponent,
SelectableListItemControlComponent,
ExternalSourceEntryImportModalComponent
ExternalSourceEntryImportModalComponent,
ImportableListItemControlComponent
];
const ENTRY_COMPONENTS = [