From 3983f9b5cdef2ce3f262c1e3c77c7f957d26ada0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Kilchenmann?= Date: Mon, 23 May 2022 16:24:13 +0200 Subject: [PATCH] feat(resource): open annotation (region) the correct way (DEV-785) (#749) --- .../still-image/still-image.component.ts | 10 +- .../resource/resource.component.html | 1 + .../workspace/resource/resource.component.ts | 110 +++++++++++------- 3 files changed, 76 insertions(+), 45 deletions(-) diff --git a/src/app/workspace/resource/representation/still-image/still-image.component.ts b/src/app/workspace/resource/representation/still-image/still-image.component.ts index d063270e05..b1d0c1b101 100644 --- a/src/app/workspace/resource/representation/still-image/still-image.component.ts +++ b/src/app/workspace/resource/representation/still-image/still-image.component.ts @@ -192,16 +192,16 @@ export class StillImageComponent implements OnChanges, OnDestroy, AfterViewInit if (changes['images']) { this._openImages(); this._unhighlightAllRegions(); - // tODO: check if this is necessary or could be handled below + // --> TODO: check if this is necessary or could be handled below // (remove the 'else' before the 'if', so changes['activateRegion'] is always checked for) } - if (this.activateRegion !== undefined) { - this._highlightRegion(this.activateRegion); - } if (this.currentTab === 'annotations') { this.renderRegions(); } + if (this.activateRegion !== undefined) { + this._highlightRegion(this.activateRegion); + } if (changes['activateRegion']) { this._unhighlightAllRegions(); } @@ -642,6 +642,8 @@ export class StillImageComponent implements OnChanges, OnDestroy, AfterViewInit this._viewer.navigator.element.style.display = 'none'; // disable the region draw mode this.regionDrawMode = false; + // stop loading tiles + this._viewer.removeAllHandlers('open'); } else { // enable mouse navigation incl. zoom this._viewer.setMouseNavEnabled(true); diff --git a/src/app/workspace/resource/resource.component.html b/src/app/workspace/resource/resource.component.html index e73266d51c..c6c2c7435e 100644 --- a/src/app/workspace/resource/resource.component.html +++ b/src/app/workspace/resource/resource.component.html @@ -14,6 +14,7 @@ [project]="resource.res.attachedToProject" [currentTab]="selectedTabLabel" [parentResource]="resource.res" + [activateRegion]="selectedRegion" (loaded)="representationLoaded($event)" (goToPage)="compoundNavigation($event)" (regionClicked)="openRegion($event)" diff --git a/src/app/workspace/resource/resource.component.ts b/src/app/workspace/resource/resource.component.ts index 615f75279b..c7e2d34a5e 100644 --- a/src/app/workspace/resource/resource.component.ts +++ b/src/app/workspace/resource/resource.component.ts @@ -18,10 +18,14 @@ import { ReadArchiveFileValue, ReadAudioFileValue, ReadDocumentFileValue, + ReadLinkValue, ReadMovingImageFileValue, ReadResource, ReadResourceSequence, ReadStillImageFileValue, + ResourceClassAndPropertyDefinitions, + ResourceClassDefinition, + ResourceClassDefinitionWithPropertyDefinition, SystemPropertyDefinition } from '@dasch-swiss/dsp-js'; import { Subscription } from 'rxjs'; @@ -76,6 +80,8 @@ export class ResourceComponent implements OnInit, OnChanges, OnDestroy { iiifUrl: string; + resourceIsAnnotation: 'region' | 'sequence'; + // list of representations to be displayed // --> TODO: will be expanded with | MovingImageRepresentation[] | AudioRepresentation[] etc. representationsToDisplay: FileRepresentation[] = []; @@ -243,56 +249,78 @@ export class ResourceComponent implements OnInit, OnChanges, OnDestroy { const res = new DspResource(response); this.resource = res; - if (response.isDeleted) { - // deleted resource; no further infos needed + // --> TODO: here we have to add also sequenceOf similar to regionOf (DEV-744) + if (this.resource.res.outgoingReferences.length && this.resource.res.entityInfo.classes[Constants.Region] && this.resource.res.id === this.resourceIri) { + // the main resource (resourceIri) is a region; + // display the corresponding still-image resource instance + // find the iri of the parent resource; still-image in case of region, moving-image or audio in case of sequence + const annotationOfIri = (this.resource.res.properties[Constants.IsRegionOfValue] as ReadLinkValue[])[0].linkedResourceIri; - } else { - // if there is no incomingResource and the resource has a still image property, assign the iiiUrl to be passed as an input to the still-image component - if (!this.incomingResource && this.resource.res.properties[Constants.HasStillImageFileValue]) { - this.iiifUrl = (this.resource.res.properties[Constants.HasStillImageFileValue][0] as ReadStillImageFileValue).fileUrl; - } + // get the parent resource to display + this.getResource(annotationOfIri); - this.selectedTabLabel = this.resource.res.entityInfo?.classes[this.resource.res.type].label; + // open annotation`s tab and highlight region + this.selectedTabLabel = 'annotations'; + this.openRegion(iri); - // get information about the logged-in user, if one is logged-in - if (this._session.getSession()) { - this.session = this._session.getSession(); - // is the logged-in user project member? - // --> TODO: as soon as we know how to handle the permissions, set this value the correct way - this.editPermissions = true; - // is the logged-in user system admin or project admin? - this.adminPermissions = this.session.user.sysAdmin ? this.session.user.sysAdmin : this.session.user.projectAdmin.some(e => e === res.res.attachedToProject); - } + this.selectedRegion = iri; + // define resource as annotation of type region + this.resourceIsAnnotation = (this.resource.res.entityInfo.classes[Constants.Region] ? 'region' : 'sequence'); - this.representationsToDisplay = this.collectRepresentationsAndAnnotations(this.resource); + } else { - if (!this.representationsToDisplay.length && !this.compoundPosition) { - // the resource could be a compound object - this._incomingService.getStillImageRepresentationsForCompoundResource(this.resource.res.id, 0, true).subscribe( - (countQuery: CountQueryResponse) => { + if (response.isDeleted) { + // deleted resource; no further infos needed + // --> TODO: as soon as we know how to display deleted/archived resources, we can handle it here. - if (countQuery.numberOfResults > 0) { - this.compoundPosition = new DspCompoundPosition(countQuery.numberOfResults); - this.compoundNavigation(1); - } else { - // not a compound object + } else { + // if there is no incomingResource and the resource has a still image property, assign the iiiUrl to be passed as an input to the still-image component + if (!this.incomingResource && this.resource.res.properties[Constants.HasStillImageFileValue]) { + this.iiifUrl = (this.resource.res.properties[Constants.HasStillImageFileValue][0] as ReadStillImageFileValue).fileUrl; + } + + this.selectedTabLabel = this.resource.res.entityInfo?.classes[this.resource.res.type].label; + + // get information about the logged-in user, if one is logged-in + if (this._session.getSession()) { + this.session = this._session.getSession(); + // is the logged-in user project member? + // --> TODO: as soon as we know how to handle the permissions, set this value the correct way + this.editPermissions = true; + // is the logged-in user system admin or project admin? + this.adminPermissions = this.session.user.sysAdmin ? this.session.user.sysAdmin : this.session.user.projectAdmin.some(e => e === res.res.attachedToProject); + } + + this.representationsToDisplay = this.collectRepresentationsAndAnnotations(this.resource); + + if (!this.representationsToDisplay.length && !this.compoundPosition) { + // the resource could be a compound object + this._incomingService.getStillImageRepresentationsForCompoundResource(this.resource.res.id, 0, true).subscribe( + (countQuery: CountQueryResponse) => { + + if (countQuery.numberOfResults > 0) { + this.compoundPosition = new DspCompoundPosition(countQuery.numberOfResults); + this.compoundNavigation(1); + } else { + // not a compound object + this.loading = false; + } + }, + (error: ApiResponseError) => { this.loading = false; + this._errorHandler.showMessage(error); } - }, - (error: ApiResponseError) => { - this.loading = false; - this._errorHandler.showMessage(error); - } - ); - } else { - this.requestIncomingResources(this.resource); - } + ); + } else { + this.requestIncomingResources(this.resource); + } - // gather resource property information - res.resProps = this.initProps(response); + // gather resource property information + res.resProps = this.initProps(response); - // gather system property information - res.systemProps = this.resource.res.entityInfo.getPropertyDefinitionsByType(SystemPropertyDefinition); + // gather system property information + res.systemProps = this.resource.res.entityInfo.getPropertyDefinitionsByType(SystemPropertyDefinition); + } } }, (error: ApiResponseError) => { @@ -444,7 +472,7 @@ export class ResourceComponent implements OnInit, OnChanges, OnDestroy { // developer feature: this keeps the annotations tab open, if you add "/annotations" to the end of the URL // e.g. http://0.0.0.0:4200/resource/[project-shortcode]/[resource-iri]/annotations - if (this.valueUuid === 'annotations') { + if (this.valueUuid === 'annotations' || this.selectedRegion === this.resourceIri) { this.selectedTab = (this.incomingResource ? 2 : 1); this.selectedTabLabel = 'annotations'; }