67611: Import new external entity and add to selection + message changes/refactoring

This commit is contained in:
Kristof De Langhe
2019-12-06 16:52:30 +01:00
parent 3a7fa8dbaf
commit 1402dd9129
8 changed files with 116 additions and 40 deletions

View File

@@ -1546,7 +1546,19 @@
"submission.sections.describe.relationship-lookup.external-source.added": "Successfully added local entry to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-button-title": "Import remote entry",
"submission.sections.describe.relationship-lookup.external-source.import-button-title.Author": "Import remote author",
"submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal": "Import remote journal",
"submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Issue": "Import remote journal issue",
"submission.sections.describe.relationship-lookup.external-source.import-button-title.Journal Volume": "Import remote journal volume",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Author.title": "Import Remote Author",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Author.added.local-entity": "Successfully added local author to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Author.added.new-entity": "Successfully imported and added external author to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.authority": "Authority",
@@ -1570,9 +1582,25 @@
"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.Journal.title": "Import Remote Journal",
"submission.sections.describe.relationship-lookup.external-source.import-modal.title": "Import Remote Entry",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.local-entity": "Successfully added local journal to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal.added.new-entity": "Successfully imported and added external journal to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.title": "Import Remote Journal Issue",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.local-entity": "Successfully added local journal issue to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Issue.added.new-entity": "Successfully imported and added external journal issue to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.title": "Import Remote Journal Volume",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.local-entity": "Successfully added local journal volume to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.Journal Volume.added.new-entity": "Successfully imported and added external journal volume to the selection",
"submission.sections.describe.relationship-lookup.external-source.import-modal.select": "Select a local match:",
"submission.sections.describe.relationship-lookup.search-tab.deselect-all": "Deselect all",

View File

@@ -254,7 +254,7 @@ export class ItemDataService extends DataService<Item> {
* @param externalSourceEntry
* @param collectionId
*/
public importExternalSourceEntry(externalSourceEntry: ExternalSourceEntry, collectionId: string): Observable<RestResponse> {
public importExternalSourceEntry(externalSourceEntry: ExternalSourceEntry, collectionId: string): Observable<RemoteData<Item>> {
const options: HttpOptions = Object.create({});
let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'text/uri-list');
@@ -273,7 +273,13 @@ export class ItemDataService extends DataService<Item> {
return this.requestService.getByUUID(requestId).pipe(
find((request: RequestEntry) => request.completed),
map((request: RequestEntry) => request.response)
getResponseFromEntry(),
map((response: any) => {
if (isNotEmpty(response.resourceSelfLinks)) {
return response.resourceSelfLinks[0];
}
}),
switchMap((selfLink: string) => this.findByHref(selfLink))
);
}

View File

@@ -15,6 +15,7 @@ import { getAllSucceededRemoteData, getRemoteDataPayload } from '../shared/opera
import { Injectable } from '@angular/core';
import { ExternalSource } from '../shared/external-source.model';
import { ExternalSourceEntry } from '../shared/external-source-entry.model';
import { RequestService } from './request.service';
/**
* A service for retrieving local and external entries information during a relation lookup
@@ -35,7 +36,8 @@ export class LookupRelationService {
});
constructor(protected externalSourceService: ExternalSourceService,
protected searchService: SearchService) {
protected searchService: SearchService,
protected requestService: RequestService) {
}
/**
@@ -91,4 +93,11 @@ export class LookupRelationService {
startWith(0)
);
}
/**
* Remove cached requests from local results
*/
removeLocalResultsCache() {
this.searchService.getEndpoint().subscribe((href) => this.requestService.removeByHrefSubstring(href));
}
}

View File

@@ -25,14 +25,14 @@
[title]="'submission.sections.describe.relationship-lookup.search-tab.tab-title.' + source.id | translate : {count: (totalExternal$ | async)[idx]}">
<ng-template ngbTabContent>
<ds-dynamic-lookup-relation-external-source-tab
[label]="label"
[listId]="listId"
[item]="item"
[collection]="collection"
[relationship]="relationshipOptions"
[context]="context"
[externalSource]="source"
(selectObject)="select($event)"
(deselectObject)="deselect($event)"
(importedObject)="imported($event)"
class="d-block pt-3">
</ds-dynamic-lookup-relation-external-source-tab>
</ng-template>

View File

@@ -179,6 +179,15 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
)
}
/**
* Called when an external object has been imported, resets the total values and adds the object to the selected list
* @param object
*/
imported(object) {
this.setTotals();
this.select(object);
}
/**
* Calculate and set the total entries available for each tab
*/

View File

@@ -22,8 +22,6 @@ import { hasValue } from '../../../../../empty.util';
import { SelectableListService } from '../../../../../object-list/selectable-list/selectable-list.service';
import { Item } from '../../../../../../core/shared/item.model';
import { Collection } from '../../../../../../core/shared/collection.model';
import { NotificationsService } from '../../../../../notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'ds-dynamic-lookup-relation-external-source-tab',
@@ -45,6 +43,11 @@ import { TranslateService } from '@ngx-translate/core';
* Shows a list of entries matching the current search query with the option to import them into the repository
*/
export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit, OnDestroy {
/**
* The label to use for all messages (added to the end of relevant i18n keys)
*/
@Input() label: string;
/**
* The ID of the list of selected entries
*/
@@ -71,14 +74,9 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
@Input() context: Context;
/**
* Emit an event when an object has been deselected
* Emit an event when an object has been imported (or selected from similar local entries)
*/
@Output() deselectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* Emit an event when an object has been selected (or imported)
*/
@Output() selectObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
@Output() importedObject: EventEmitter<ListableObject> = new EventEmitter<ListableObject>();
/**
* The initial pagination options
@@ -101,9 +99,7 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
/**
* Config to use for the import buttons
*/
importConfig = {
buttonLabel: 'submission.sections.describe.relationship-lookup.external-source.import-button-title'
};
importConfig;
/**
* The modal for importing the entry
@@ -119,9 +115,7 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
public searchConfigService: SearchConfigurationService,
private externalSourceService: ExternalSourceService,
private modalService: NgbModal,
private selectableListService: SelectableListService,
private notificationsService: NotificationsService,
private translateService: TranslateService) {
private selectableListService: SelectableListService) {
}
/**
@@ -131,7 +125,10 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
this.entriesRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
switchMap((searchOptions: PaginatedSearchOptions) =>
this.externalSourceService.getExternalSourceEntries(this.externalSource.id, searchOptions).pipe(startWith(undefined)))
)
);
this.importConfig = {
buttonLabel: 'submission.sections.describe.relationship-lookup.external-source.import-button-title.' + this.label
};
}
/**
@@ -148,10 +145,10 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
modalComp.item = this.item;
modalComp.collection = this.collection;
modalComp.relationship = this.relationship;
modalComp.label = this.label;
this.importObjectSub = modalComp.importedObject.subscribe((object) => {
this.selectableListService.selectSingle(this.listId, object);
this.notificationsService.success(this.translateService.get('submission.sections.describe.relationship-lookup.external-source.added'));
this.selectObject.emit(object);
this.importedObject.emit(object);
});
}

View File

@@ -1,26 +1,26 @@
<div class="modal-header">
<h4 class="modal-title" id="modal-title">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.title') | translate }}</h4>
<h4 class="modal-title" id="modal-title">{{ (labelPrefix + label + '.title') | translate }}</h4>
<button type="button" class="close" aria-label="Close button" aria-describedby="modal-title"
(click)="modal.dismiss()">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<h4>{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.head.' + externalSourceEntry.externalSource | translate) }}</h4>
<h4>{{ (labelPrefix + '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>
<h4>{{ (labelPrefix + 'select' | translate) }}</h4>
<div id="external-source-entry-collection" class="mb-3">
<div class="form-group">
<label for="collection">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.collection' | translate) }}</label>
<input type="text" class="form-control" id="collection" placeholder="Enter collection ID" [value]="collectionId">
<label for="collection">{{ (labelPrefix + 'collection' | translate) }}</label>
<input type="text" class="form-control" id="collection" placeholder="Enter collection ID" [(ngModel)]="collectionId">
</div>
</div>
<div id="external-source-entry-entities" class="mb-3">
<h5 class="font-weight-bold">{{ ('submission.sections.describe.relationship-lookup.external-source.import-modal.entities' | translate) }}</h5>
<h5 class="font-weight-bold">{{ (labelPrefix + 'entities' | translate) }}</h5>
<ds-search-results *ngIf="(localEntitiesRD$ | async)?.payload?.page?.length > 0"
[searchResults]="(localEntitiesRD$ | async)"
@@ -37,23 +37,23 @@
</ds-search-results>
<div class="ml-4">
<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>
<label class="form-check-label" for="new-entity">{{ (labelPrefix + '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>
<h5 class="font-weight-bold">{{ (labelPrefix + 'authority' | translate) }}</h5>
<div class="ml-4">
<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>
<label class="form-check-label" for="new-authority">{{ (labelPrefix + '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>
<button type="button" class="btn btn-outline-secondary" (click)="close()">{{ (labelPrefix + '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>
<button type="button" class="btn btn-primary" [disabled]="selectedImportType === importType.None" (click)="import()">{{ (labelPrefix + 'import' | translate) }}</button>
</div>
</div>

View File

@@ -18,6 +18,11 @@ import { ListableObject } from '../../../../../../object-collection/shared/lista
import { Collection } from '../../../../../../../core/shared/collection.model';
import { ItemDataService } from '../../../../../../../core/data/item-data.service';
import { PaginationComponentOptions } from '../../../../../../pagination/pagination-component-options.model';
import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../../../../core/shared/operators';
import { take } from 'rxjs/operators';
import { ItemSearchResult } from '../../../../../../object-collection/shared/item-search-result.model';
import { NotificationsService } from '../../../../../../notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core';
/**
* The possible types of import for the external entry
@@ -42,6 +47,16 @@ export enum ImportType {
* The other option is to import the external entry as a new entity or authority into the repository.
*/
export class ExternalSourceEntryImportModalComponent implements OnInit {
/**
* The prefix for every i18n key within this modal
*/
labelPrefix = 'submission.sections.describe.relationship-lookup.external-source.import-modal.';
/**
* The label to use for all messages (added to the end of relevant i18n keys)
*/
label: string;
/**
* The external source entry
*/
@@ -130,7 +145,9 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
constructor(public modal: NgbActiveModal,
public lookupRelationService: LookupRelationService,
private selectService: SelectableListService,
private itemService: ItemDataService) {
private itemService: ItemDataService,
private notificationsService: NotificationsService,
private translateService: TranslateService) {
}
ngOnInit(): void {
@@ -180,6 +197,7 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
*/
importLocalEntity() {
if (this.selectedEntity !== undefined) {
this.notificationsService.success(this.translateService.get(this.labelPrefix + this.label + '.added.local-entity'));
this.importedObject.emit(this.selectedEntity);
}
}
@@ -188,8 +206,17 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
* Create and import a new entity from the external entry
*/
importNewEntity() {
this.itemService.importExternalSourceEntry(this.externalSourceEntry, this.collectionId).subscribe((response) => {
console.log(response);
this.itemService.importExternalSourceEntry(this.externalSourceEntry, this.collectionId).pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
take(1)
).subscribe((item: Item) => {
this.lookupRelationService.removeLocalResultsCache();
const searchResult = Object.assign(new ItemSearchResult(), {
indexableObject: item
});
this.notificationsService.success(this.translateService.get(this.labelPrefix + this.label + '.added.new-entity'));
this.importedObject.emit(searchResult);
});
}