forked from hazza/dspace-angular
[CST-4591] Use search collection dropdown when importing from external source with lookup modal
This commit is contained in:
@@ -1,10 +1,15 @@
|
||||
import { autoserialize, deserialize } from 'cerialize';
|
||||
import { typedObject } from '../cache/builders/build-decorators';
|
||||
import { link, typedObject } from '../cache/builders/build-decorators';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { excludeFromEquals } from '../utilities/equals.decorators';
|
||||
import { EXTERNAL_SOURCE } from './external-source.resource-type';
|
||||
import { HALLink } from './hal-link.model';
|
||||
import { ResourceType } from './resource-type';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { PaginatedList } from '../data/paginated-list.model';
|
||||
import { Observable } from 'rxjs/internal/Observable';
|
||||
import { ITEM_TYPE } from './item-relationships/item-type.resource-type';
|
||||
import { ItemType } from './item-relationships/item-type.model';
|
||||
|
||||
/**
|
||||
* Model class for an external source
|
||||
@@ -38,6 +43,13 @@ export class ExternalSource extends CacheableObject {
|
||||
@autoserialize
|
||||
hierarchical: boolean;
|
||||
|
||||
/**
|
||||
* The list of entity types that are compatible with this external source
|
||||
* Will be undefined unless the entityTypes {@link HALLink} has been resolved.
|
||||
*/
|
||||
@link(ITEM_TYPE, true)
|
||||
entityTypes?: Observable<RemoteData<PaginatedList<ItemType>>>;
|
||||
|
||||
/**
|
||||
* The {@link HALLink}s for this ExternalSource
|
||||
*/
|
||||
@@ -45,5 +57,6 @@ export class ExternalSource extends CacheableObject {
|
||||
_links: {
|
||||
self: HALLink;
|
||||
entries: HALLink;
|
||||
entityTypes: HALLink;
|
||||
};
|
||||
}
|
||||
|
@@ -12,7 +12,9 @@ import { RelationshipOptions } from '../../models/relationship-options.model';
|
||||
import { SearchResult } from '../../../../search/search-result.model';
|
||||
import { Item } from '../../../../../core/shared/item.model';
|
||||
import {
|
||||
AddRelationshipAction, RemoveRelationshipAction, UpdateRelationshipNameVariantAction,
|
||||
AddRelationshipAction,
|
||||
RemoveRelationshipAction,
|
||||
UpdateRelationshipNameVariantAction,
|
||||
} from './relationship.actions';
|
||||
import { RelationshipService } from '../../../../../core/data/relationship.service';
|
||||
import { RelationshipTypeService } from '../../../../../core/data/relationship-type.service';
|
||||
@@ -25,6 +27,7 @@ import { ExternalSourceService } from '../../../../../core/data/external-source.
|
||||
import { Router } from '@angular/router';
|
||||
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
|
||||
import { getAllSucceededRemoteDataPayload } from '../../../../../core/shared/operators';
|
||||
import { followLink } from '../../../../utils/follow-link-config.model';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-dynamic-lookup-relation-modal',
|
||||
@@ -146,7 +149,14 @@ export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy
|
||||
|
||||
if (isNotEmpty(this.relationshipOptions.externalSources)) {
|
||||
this.externalSourcesRD$ = this.rdbService.aggregate(
|
||||
this.relationshipOptions.externalSources.map((source) => this.externalSourceService.findById(source))
|
||||
this.relationshipOptions.externalSources.map((source) => {
|
||||
return this.externalSourceService.findById(
|
||||
source,
|
||||
true,
|
||||
true,
|
||||
followLink('entityTypes')
|
||||
);
|
||||
})
|
||||
).pipe(
|
||||
getAllSucceededRemoteDataPayload()
|
||||
);
|
||||
|
@@ -26,6 +26,7 @@ import { ExternalSourceEntryImportModalComponent } from './external-source-entry
|
||||
import { createPaginatedList } from '../../../../../testing/utils.test';
|
||||
import { PaginationService } from '../../../../../../core/pagination/pagination.service';
|
||||
import { PaginationServiceStub } from '../../../../../testing/pagination-service.stub';
|
||||
import { ItemType } from '../../../../../../core/shared/item-relationships/item-type.model';
|
||||
|
||||
describe('DsDynamicLookupRelationExternalSourceTabComponent', () => {
|
||||
let component: DsDynamicLookupRelationExternalSourceTabComponent;
|
||||
@@ -35,10 +36,12 @@ describe('DsDynamicLookupRelationExternalSourceTabComponent', () => {
|
||||
let selectableListService;
|
||||
let modalService;
|
||||
|
||||
const itemType = Object.assign(new ItemType(), { label: 'Person' });
|
||||
const externalSource = {
|
||||
id: 'orcidV2',
|
||||
name: 'orcidV2',
|
||||
hierarchical: false
|
||||
hierarchical: false,
|
||||
entityTypes: createSuccessfulRemoteDataObject$(createPaginatedList([itemType]))
|
||||
} as ExternalSource;
|
||||
const externalEntries = [
|
||||
Object.assign({
|
||||
|
@@ -7,7 +7,7 @@ import { RemoteData } from '../../../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../../../core/data/paginated-list.model';
|
||||
import { ExternalSourceEntry } from '../../../../../../core/shared/external-source-entry.model';
|
||||
import { ExternalSource } from '../../../../../../core/shared/external-source.model';
|
||||
import { startWith, switchMap } from 'rxjs/operators';
|
||||
import { map, startWith, switchMap } from 'rxjs/operators';
|
||||
import { PaginatedSearchOptions } from '../../../../../search/paginated-search-options.model';
|
||||
import { Context } from '../../../../../../core/shared/context.model';
|
||||
import { ListableObject } from '../../../../../object-collection/shared/listable-object.model';
|
||||
@@ -22,6 +22,8 @@ import { Item } from '../../../../../../core/shared/item.model';
|
||||
import { Collection } from '../../../../../../core/shared/collection.model';
|
||||
import { PaginationService } from '../../../../../../core/pagination/pagination.service';
|
||||
import { Observable, Subscription } from 'rxjs';
|
||||
import { ItemType } from '../../../../../../core/shared/item-relationships/item-type.model';
|
||||
import { getFirstCompletedRemoteData } from '../../../../../../core/shared/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-dynamic-lookup-relation-external-source-tab',
|
||||
@@ -116,6 +118,11 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
|
||||
*/
|
||||
importObjectSub: Subscription;
|
||||
|
||||
/**
|
||||
* The entity types compatible with the given external source
|
||||
*/
|
||||
relatedEntityType: ItemType;
|
||||
|
||||
constructor(private router: Router,
|
||||
public searchConfigService: SearchConfigurationService,
|
||||
private externalSourceService: ExternalSourceService,
|
||||
@@ -129,6 +136,15 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
|
||||
* Get the entries for the selected external source
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.externalSource.entityTypes.pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((entityTypesRD: RemoteData<PaginatedList<ItemType>>) => {
|
||||
return (entityTypesRD.hasSucceeded && entityTypesRD.payload.totalElements > 0) ? entityTypesRD.payload.page[0] : null;
|
||||
})
|
||||
).subscribe((entityType: ItemType) => {
|
||||
this.relatedEntityType = entityType;
|
||||
});
|
||||
|
||||
this.resetRoute();
|
||||
this.entriesRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
|
||||
switchMap((searchOptions: PaginatedSearchOptions) =>
|
||||
@@ -155,6 +171,7 @@ export class DsDynamicLookupRelationExternalSourceTabComponent implements OnInit
|
||||
modalComp.collection = this.collection;
|
||||
modalComp.relationship = this.relationship;
|
||||
modalComp.label = this.label;
|
||||
modalComp.relatedEntityType = this.relatedEntityType;
|
||||
this.importObjectSub = modalComp.importedObject.subscribe((object) => {
|
||||
this.selectableListService.selectSingle(this.listId, object);
|
||||
this.importedObject.emit(object);
|
||||
|
@@ -17,13 +17,6 @@
|
||||
<div id="external-source-entry-entities" class="mb-3">
|
||||
<h5 class="font-weight-bold">{{ (labelPrefix + 'entities' | translate) }}</h5>
|
||||
|
||||
<div id="external-source-entry-collection" class="mb-3">
|
||||
<div class="form-group">
|
||||
<label for="collection">{{ (labelPrefix + 'collection' | translate) }}</label>
|
||||
<input type="text" class="form-control" id="collection" placeholder="Enter collection ID" [(ngModel)]="collectionId">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ds-search-results *ngIf="(localEntitiesRD$ | async)?.payload?.page?.length > 0"
|
||||
[searchResults]="(localEntitiesRD$ | async)"
|
||||
[sortConfig]="this.lookupRelationService.searchConfig?.sort"
|
||||
|
@@ -86,7 +86,6 @@ describe('DsDynamicLookupRelationExternalSourceTabComponent', () => {
|
||||
component.externalSourceEntry = entry;
|
||||
component.label = label;
|
||||
component.relationship = relationship;
|
||||
component.collection = submissionCollection;
|
||||
component.item = submissionItem;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { Component, EventEmitter, OnInit } from '@angular/core';
|
||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { NgbActiveModal, NgbModal, NgbModalRef } 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';
|
||||
@@ -15,14 +15,16 @@ import { CollectionElementLinkType } from '../../../../../../object-collection/c
|
||||
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 { Collection } from '../../../../../../../core/shared/collection.model';
|
||||
import { ItemDataService } from '../../../../../../../core/data/item-data.service';
|
||||
import { PaginationComponentOptions } from '../../../../../../pagination/pagination-component-options.model';
|
||||
import { getRemoteDataPayload, getFirstSucceededRemoteData } from '../../../../../../../core/shared/operators';
|
||||
import { take } from 'rxjs/operators';
|
||||
import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../../../../../core/shared/operators';
|
||||
import { mergeMap, 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';
|
||||
import { ItemType } from '../../../../../../../core/shared/item-relationships/item-type.model';
|
||||
import { SubmissionImportExternalCollectionComponent } from '../../../../../../../submission/import-external/import-external-collection/submission-import-external-collection.component';
|
||||
import { CollectionListEntry } from '../../../../../../collection-dropdown/collection-dropdown.component';
|
||||
|
||||
/**
|
||||
* The possible types of import for the external entry
|
||||
@@ -67,16 +69,6 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
|
||||
*/
|
||||
item: Item;
|
||||
|
||||
/**
|
||||
* The collection the user is submitting in
|
||||
*/
|
||||
collection: Collection;
|
||||
|
||||
/**
|
||||
* The ID of the collection to import entries to
|
||||
*/
|
||||
collectionId: string;
|
||||
|
||||
/**
|
||||
* The current relationship-options used for filtering results
|
||||
*/
|
||||
@@ -147,8 +139,19 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
|
||||
*/
|
||||
authorityEnabled = false;
|
||||
|
||||
/**
|
||||
* The entity types compatible with the given external source
|
||||
*/
|
||||
relatedEntityType: ItemType;
|
||||
|
||||
/**
|
||||
* The modal for the collection selection
|
||||
*/
|
||||
modalRef: NgbModalRef;
|
||||
|
||||
constructor(public modal: NgbActiveModal,
|
||||
public lookupRelationService: LookupRelationService,
|
||||
private modalService: NgbModal,
|
||||
private selectService: SelectableListService,
|
||||
private itemService: ItemDataService,
|
||||
private notificationsService: NotificationsService,
|
||||
@@ -160,7 +163,6 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
|
||||
const pagination = Object.assign(new PaginationComponentOptions(), { id: 'external-entry-import', pageSize: 5 });
|
||||
this.searchOptions = Object.assign(new PaginatedSearchOptions({ query: this.externalSourceEntry.value, pagination: pagination }));
|
||||
this.localEntitiesRD$ = this.lookupRelationService.getLocalResults(this.relationship, this.searchOptions);
|
||||
this.collectionId = this.collection.id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,10 +213,19 @@ export class ExternalSourceEntryImportModalComponent implements OnInit {
|
||||
* Create and import a new entity from the external entry
|
||||
*/
|
||||
importNewEntity() {
|
||||
this.itemService.importExternalSourceEntry(this.externalSourceEntry, this.collectionId).pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
this.modalRef = this.modalService.open(SubmissionImportExternalCollectionComponent, {
|
||||
size: 'lg',
|
||||
});
|
||||
this.modalRef.componentInstance.entityType = this.relatedEntityType.label;
|
||||
|
||||
this.modalRef.componentInstance.selectedEvent.pipe(
|
||||
mergeMap((collectionListEntry: CollectionListEntry) => {
|
||||
return this.itemService.importExternalSourceEntry(this.externalSourceEntry, collectionListEntry.collection.id).pipe(
|
||||
getFirstSucceededRemoteData(),
|
||||
getRemoteDataPayload(),
|
||||
take(1)
|
||||
);
|
||||
})
|
||||
).subscribe((item: Item) => {
|
||||
this.lookupRelationService.removeLocalResultsCache();
|
||||
const searchResult = Object.assign(new ItemSearchResult(), {
|
||||
|
@@ -11,6 +11,9 @@ export const externalSourceOrcid: ExternalSource = {
|
||||
entries: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/orcid/entries'
|
||||
},
|
||||
entityTypes: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/my_staff_db/entityTypes'
|
||||
},
|
||||
self: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/orcid'
|
||||
}
|
||||
@@ -26,6 +29,9 @@ export const externalSourceCiencia: ExternalSource = {
|
||||
entries: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/ciencia/entries'
|
||||
},
|
||||
entityTypes: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/my_staff_db/entityTypes'
|
||||
},
|
||||
self: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/ciencia'
|
||||
}
|
||||
@@ -41,6 +47,9 @@ export const externalSourceMyStaffDb: ExternalSource = {
|
||||
entries: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/my_staff_db/entries'
|
||||
},
|
||||
entityTypes: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/my_staff_db/entityTypes'
|
||||
},
|
||||
self: {
|
||||
href: 'https://dspace7.4science.cloud/server/api/integration/externalsources/my_staff_db'
|
||||
}
|
||||
|
@@ -1193,6 +1193,8 @@
|
||||
|
||||
"dso-selector.placeholder": "Search for a {{ type }}",
|
||||
|
||||
"dso-selector.select.collection.head": "Select a collection",
|
||||
|
||||
|
||||
|
||||
"confirmation-modal.export-metadata.header": "Export metadata for {{ dsoName }}",
|
||||
@@ -3730,6 +3732,7 @@
|
||||
"vocabulary-treeview.tree.description.srsc": "Research Subject Categories",
|
||||
|
||||
|
||||
"unset.listelement.badge": "Untyped",
|
||||
|
||||
"uploader.browse": "browse",
|
||||
|
||||
|
Reference in New Issue
Block a user