From 71ffeac80eb55423d0fe1f0b6a700d35b7d1e4b4 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Mon, 18 Apr 2022 13:18:40 +0530 Subject: [PATCH 01/10] [CST-5676] Bitstream edit page is broken if no policies are set --- .../edit-bitstream-page.component.ts | 17 +++++++++++++++++ .../resource-policies.component.html | 6 +++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index 9a59df4b95..2042efbd52 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -387,6 +387,16 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { */ protected subs: Subscription[] = []; + /** + * Set to blank to detect changes in format. + */ + bitstreamFormat = {}; + + /** + * Set to true to detect changes in bundle. + */ + bitstreamBundle = {}; + constructor(private route: ActivatedRoute, private router: Router, @@ -685,6 +695,13 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { const regexExcludeBundles = /OTHERCONTENT|THUMBNAIL|LICENSE/; const regexIIIFItem = /true|yes/i; + this.bitstream.format.subscribe(res => { + this.bitstreamFormat = res; + }); + this.bitstream.bundle.subscribe(res => { + this.bitstreamBundle = res; + }); + const isImage$ = this.bitstream.format.pipe( getFirstSucceededRemoteData(), map((format: RemoteData) => format.payload.mimetype.includes('image/'))); diff --git a/src/app/shared/resource-policies/resource-policies.component.html b/src/app/shared/resource-policies/resource-policies.component.html index b06946ad25..4667e22217 100644 --- a/src/app/shared/resource-policies/resource-policies.component.html +++ b/src/app/shared/resource-policies/resource-policies.component.html @@ -1,4 +1,4 @@ -
+
@@ -29,7 +29,7 @@ - + - +
{{'resource-policies.table.headers.edit' | translate}}
From 4fe82112d6649e0e725be4b514683ced71a1b595 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Mon, 18 Apr 2022 13:39:36 +0530 Subject: [PATCH 02/10] [CST-5676] Bitstream edit page is broken if no policies are set --- .../edit-bitstream-page.component.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index 2042efbd52..a2b8f7c9d3 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -706,11 +706,20 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { getFirstSucceededRemoteData(), map((format: RemoteData) => format.payload.mimetype.includes('image/'))); + let isImageBitstream = false; + isImage$.subscribe(res => { + isImageBitstream = res; + }); + const isIIIFBundle$ = this.bitstream.bundle.pipe( getFirstSucceededRemoteData(), map((bundle: RemoteData) => this.dsoNameService.getName(bundle.payload).match(regexExcludeBundles) == null)); + let isIIIFBundleBitstream = false; + isIIIFBundle$.subscribe(res => { + isIIIFBundleBitstream = res; + }); const isEnabled$ = this.bitstream.bundle.pipe( getFirstSucceededRemoteData(), map((bundle: RemoteData) => bundle.payload.item.pipe( @@ -720,6 +729,11 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { item.payload.firstMetadataValue('dspace.iiif.enabled').match(regexIIIFItem) !== null) )))); + let isEnabledBitstream: Observable; + isEnabled$.subscribe(res => { + isEnabledBitstream = res; + }); + const iiifSub = combineLatest( isImage$, isIIIFBundle$, From 6480b75aed6df0aef1ef02773af0299c38b91e61 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Mon, 18 Apr 2022 16:27:36 +0530 Subject: [PATCH 03/10] [CST-5676] Bitstream edit page is broken if no policies are set --- .../edit-bitstream-page.component.ts | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts index a2b8f7c9d3..9a59df4b95 100644 --- a/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts +++ b/src/app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component.ts @@ -387,16 +387,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { */ protected subs: Subscription[] = []; - /** - * Set to blank to detect changes in format. - */ - bitstreamFormat = {}; - - /** - * Set to true to detect changes in bundle. - */ - bitstreamBundle = {}; - constructor(private route: ActivatedRoute, private router: Router, @@ -695,31 +685,15 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { const regexExcludeBundles = /OTHERCONTENT|THUMBNAIL|LICENSE/; const regexIIIFItem = /true|yes/i; - this.bitstream.format.subscribe(res => { - this.bitstreamFormat = res; - }); - this.bitstream.bundle.subscribe(res => { - this.bitstreamBundle = res; - }); - const isImage$ = this.bitstream.format.pipe( getFirstSucceededRemoteData(), map((format: RemoteData) => format.payload.mimetype.includes('image/'))); - let isImageBitstream = false; - isImage$.subscribe(res => { - isImageBitstream = res; - }); - const isIIIFBundle$ = this.bitstream.bundle.pipe( getFirstSucceededRemoteData(), map((bundle: RemoteData) => this.dsoNameService.getName(bundle.payload).match(regexExcludeBundles) == null)); - let isIIIFBundleBitstream = false; - isIIIFBundle$.subscribe(res => { - isIIIFBundleBitstream = res; - }); const isEnabled$ = this.bitstream.bundle.pipe( getFirstSucceededRemoteData(), map((bundle: RemoteData) => bundle.payload.item.pipe( @@ -729,11 +703,6 @@ export class EditBitstreamPageComponent implements OnInit, OnDestroy { item.payload.firstMetadataValue('dspace.iiif.enabled').match(regexIIIFItem) !== null) )))); - let isEnabledBitstream: Observable; - isEnabled$.subscribe(res => { - isEnabledBitstream = res; - }); - const iiifSub = combineLatest( isImage$, isIIIFBundle$, From 01f3cbcaea3685d4cd50d167adaedf13219b26c2 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Wed, 20 Apr 2022 15:44:01 +0530 Subject: [PATCH 04/10] [CST-5676] Breadcrumbs changes --- .../bitstream-page-routing.module.ts | 23 ++++++++++----- .../bitstream-page/bitstream-page.resolver.ts | 13 +++++++++ .../bitstream-breadcrumb.resolver.ts | 28 +++++++++++++++++++ src/app/core/shared/bitstream.model.ts | 8 ++++-- 4 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts diff --git a/src/app/bitstream-page/bitstream-page-routing.module.ts b/src/app/bitstream-page/bitstream-page-routing.module.ts index 27b9db9a05..5da9135846 100644 --- a/src/app/bitstream-page/bitstream-page-routing.module.ts +++ b/src/app/bitstream-page/bitstream-page-routing.module.ts @@ -10,6 +10,7 @@ import { ResourcePolicyResolver } from '../shared/resource-policies/resolvers/re import { ResourcePolicyEditComponent } from '../shared/resource-policies/edit/resource-policy-edit.component'; import { BitstreamAuthorizationsComponent } from './bitstream-authorizations/bitstream-authorizations.component'; import { LegacyBitstreamUrlResolver } from './legacy-bitstream-url.resolver'; +import { BitstreamBreadcrumbResolver } from '../core/breadcrumbs/bitstream-breadcrumb.resolver'; const EDIT_BITSTREAM_PATH = ':id/edit'; const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; @@ -25,7 +26,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: 'handle/:prefix/:suffix/:filename', component: BitstreamDownloadPageComponent, resolve: { - bitstream: LegacyBitstreamUrlResolver + bitstream: LegacyBitstreamUrlResolver, + breadcrumb: BitstreamBreadcrumbResolver }, }, { @@ -33,7 +35,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: ':prefix/:suffix/:sequence_id/:filename', component: BitstreamDownloadPageComponent, resolve: { - bitstream: LegacyBitstreamUrlResolver + bitstream: LegacyBitstreamUrlResolver, + breadcrumb: BitstreamBreadcrumbResolver }, }, { @@ -41,14 +44,16 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: ':id/download', component: BitstreamDownloadPageComponent, resolve: { - bitstream: BitstreamPageResolver + bitstream: BitstreamPageResolver, + breadcrumb: BitstreamBreadcrumbResolver }, }, { path: EDIT_BITSTREAM_PATH, component: EditBitstreamPageComponent, resolve: { - bitstream: BitstreamPageResolver + bitstream: BitstreamPageResolver, + breadcrumb: BitstreamBreadcrumbResolver }, canActivate: [AuthenticatedGuard] }, @@ -59,7 +64,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; { path: 'create', resolve: { - resourcePolicyTarget: ResourcePolicyTargetResolver + resourcePolicyTarget: ResourcePolicyTargetResolver, + breadcrumb: BitstreamBreadcrumbResolver }, component: ResourcePolicyCreateComponent, data: { title: 'resource-policies.create.page.title', showBreadcrumbs: true } @@ -67,7 +73,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; { path: 'edit', resolve: { - resourcePolicy: ResourcePolicyResolver + resourcePolicy: ResourcePolicyResolver, + breadcrumb: BitstreamBreadcrumbResolver }, component: ResourcePolicyEditComponent, data: { title: 'resource-policies.edit.page.title', showBreadcrumbs: true } @@ -75,7 +82,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; { path: '', resolve: { - bitstream: BitstreamPageResolver + bitstream: BitstreamPageResolver, + breadcrumb: BitstreamBreadcrumbResolver }, component: BitstreamAuthorizationsComponent, data: { title: 'bitstream.edit.authorizations.title', showBreadcrumbs: true } @@ -86,6 +94,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; ], providers: [ BitstreamPageResolver, + BitstreamBreadcrumbResolver ] }) export class BitstreamPageRoutingModule { diff --git a/src/app/bitstream-page/bitstream-page.resolver.ts b/src/app/bitstream-page/bitstream-page.resolver.ts index fd9d5b351b..7da80cff5f 100644 --- a/src/app/bitstream-page/bitstream-page.resolver.ts +++ b/src/app/bitstream-page/bitstream-page.resolver.ts @@ -7,6 +7,19 @@ import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { followLink, FollowLinkConfig } from '../shared/utils/follow-link-config.model'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; +/** + * The self links defined in this list are expected to be requested somewhere in the near future + * Requesting them as embeds will limit the number of requests + */ + export const BITSTREAM_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ + followLink('format', {}, + followLink('parentCommunity', {}, + followLink('parentCommunity')) + ), + followLink('bundle'), + followLink('thumbnail') +]; + /** * This class represents a resolver that requests a specific bitstream before the route is activated */ diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts new file mode 100644 index 0000000000..00be49166c --- /dev/null +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; +import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { Bitstream } from '../shared/bitstream.model'; +import { BitstreamDataService } from '../data/bitstream-data.service'; +import { BITSTREAM_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; + +/** + * The class that resolves the BreadcrumbConfig object for an Item + */ +@Injectable({ + providedIn: 'root' +}) +export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { + constructor(protected breadcrumbService: DSOBreadcrumbsService, protected dataService: BitstreamDataService) { + super(breadcrumbService, dataService); + } + + /** + * Method that returns the follow links to already resolve + * The self links defined in this list are expected to be requested somewhere in the near future + * Requesting them as embeds will limit the number of requests + */ + get followLinks(): FollowLinkConfig[] { + return BITSTREAM_PAGE_LINKS_TO_FOLLOW; + } +} diff --git a/src/app/core/shared/bitstream.model.ts b/src/app/core/shared/bitstream.model.ts index baf2f82635..c855325d2d 100644 --- a/src/app/core/shared/bitstream.model.ts +++ b/src/app/core/shared/bitstream.model.ts @@ -7,13 +7,13 @@ import { BITSTREAM_FORMAT } from './bitstream-format.resource-type'; import { BITSTREAM } from './bitstream.resource-type'; import { DSpaceObject } from './dspace-object.model'; import { HALLink } from './hal-link.model'; -import { HALResource } from './hal-resource.model'; import {BUNDLE} from './bundle.resource-type'; import {Bundle} from './bundle.model'; +import { ChildHALResource } from './child-hal-resource.model'; @typedObject @inheritSerialization(DSpaceObject) -export class Bitstream extends DSpaceObject implements HALResource { +export class Bitstream extends DSpaceObject implements ChildHALResource { static type = BITSTREAM; /** @@ -66,4 +66,8 @@ export class Bitstream extends DSpaceObject implements HALResource { */ @link(BUNDLE) bundle?: Observable>; + + getParentLinkKey(): keyof this['_links'] { + return 'format'; + } } From ffe5922990bf67a8c762dff01219c933dcd3394d Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 21 Apr 2022 12:50:18 +0530 Subject: [PATCH 05/10] [CST-5676] resolver overwrite --- .../bitstream-breadcrumb.resolver.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts index 00be49166c..de8da19a41 100644 --- a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -1,10 +1,16 @@ import { Injectable } from '@angular/core'; import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; -import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Bitstream } from '../shared/bitstream.model'; import { BitstreamDataService } from '../data/bitstream-data.service'; import { BITSTREAM_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; +import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs'; +import { BreadcrumbConfig } from 'src/app/breadcrumbs/breadcrumb/breadcrumb-config.model'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../shared/operators'; +import { map } from 'rxjs/operators'; +import { hasValue } from 'src/app/shared/empty.util'; +import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; /** * The class that resolves the BreadcrumbConfig object for an Item @@ -17,6 +23,29 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver> { + const uuid = route.params.id; + return this.dataService.findById(uuid, true, false, ...this.followLinks).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + map((object: Bitstream) => { + if (hasValue(object)) { + const fullPath = state.url; + const url = fullPath.substr(0, fullPath.indexOf(uuid)) + uuid; + return {provider: this.breadcrumbService, key: object, url: url}; + } else { + return undefined; + } + }) + ); + } + /** * Method that returns the follow links to already resolve * The self links defined in this list are expected to be requested somewhere in the near future From 78a3a93f24fa750ecc9d355b1573dec841002516 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh <“sufiyan.shaikh@4science.com”> Date: Tue, 26 Apr 2022 17:11:50 +0530 Subject: [PATCH 06/10] [CST-5676] Resolve --- .../bitstream-page/bitstream-page.resolver.ts | 9 ++++++ .../bitstream-breadcrumb.resolver.ts | 31 +++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/app/bitstream-page/bitstream-page.resolver.ts b/src/app/bitstream-page/bitstream-page.resolver.ts index 7da80cff5f..5f41cafdeb 100644 --- a/src/app/bitstream-page/bitstream-page.resolver.ts +++ b/src/app/bitstream-page/bitstream-page.resolver.ts @@ -6,6 +6,7 @@ import { Bitstream } from '../core/shared/bitstream.model'; import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { followLink, FollowLinkConfig } from '../shared/utils/follow-link-config.model'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; +import { Bundle } from '../core/shared/bundle.model'; /** * The self links defined in this list are expected to be requested somewhere in the near future @@ -20,6 +21,14 @@ import { getFirstCompletedRemoteData } from '../core/shared/operators'; followLink('thumbnail') ]; +export const BUNDLE_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ + followLink('bitstreams', {}, + followLink('parentCommunity', {}, + followLink('parentCommunity')) + ), + followLink('primaryBitstream') +]; + /** * This class represents a resolver that requests a specific bitstream before the route is activated */ diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts index de8da19a41..8d658f7d6e 100644 --- a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -3,14 +3,19 @@ import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Bitstream } from '../shared/bitstream.model'; import { BitstreamDataService } from '../data/bitstream-data.service'; -import { BITSTREAM_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; +import { BITSTREAM_PAGE_LINKS_TO_FOLLOW, BUNDLE_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { Observable } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { BreadcrumbConfig } from 'src/app/breadcrumbs/breadcrumb/breadcrumb-config.model'; import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../shared/operators'; import { map } from 'rxjs/operators'; import { hasValue } from 'src/app/shared/empty.util'; import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; +import { BundleDataService } from '../data/bundle-data.service'; +import { Bundle } from '../shared/bundle.model'; +import { ItemDataService } from '../data/item-data.service'; +import { Item } from '../shared/item.model'; +import { ITEM_PAGE_LINKS_TO_FOLLOW } from 'src/app/item-page/item.resolver'; /** * The class that resolves the BreadcrumbConfig object for an Item @@ -19,7 +24,7 @@ import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; providedIn: 'root' }) export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { - constructor(protected breadcrumbService: DSOBreadcrumbsService, protected dataService: BitstreamDataService) { + constructor(protected breadcrumbService: DSOBreadcrumbsService, protected dataService: BitstreamDataService, protected itemService: ItemDataService) { super(breadcrumbService, dataService); } @@ -36,9 +41,19 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { if (hasValue(object)) { - const fullPath = state.url; - const url = fullPath.substr(0, fullPath.indexOf(uuid)) + uuid; - return {provider: this.breadcrumbService, key: object, url: url}; + object.bundle.pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload() + ).subscribe(res => { + this.itemService.findById(res.uuid, true, false, ...this.bfollowLinks).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload() + ).subscribe(bres => { + console.log(bres); + }); + const url = res._links.item.href; + return {provider: this.breadcrumbService, key: of(res), url: url}; + }); } else { return undefined; } @@ -54,4 +69,8 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver[] { return BITSTREAM_PAGE_LINKS_TO_FOLLOW; } + + get bfollowLinks(): FollowLinkConfig[] { + return ITEM_PAGE_LINKS_TO_FOLLOW; + } } From b83e87dd4ee5dce2c55b404f2dcb651f4f3fef31 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 28 Apr 2022 10:38:45 +0530 Subject: [PATCH 07/10] [CST-5676] Bitstream Breadcrumb Resolver --- .../bitstream-breadcrumb.resolver.ts | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts index 8d658f7d6e..67c8c092c3 100644 --- a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; -import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; +import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Bitstream } from '../shared/bitstream.model'; import { BitstreamDataService } from '../data/bitstream-data.service'; import { BITSTREAM_PAGE_LINKS_TO_FOLLOW, BUNDLE_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; @@ -23,9 +23,13 @@ import { ITEM_PAGE_LINKS_TO_FOLLOW } from 'src/app/item-page/item.resolver'; @Injectable({ providedIn: 'root' }) -export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { - constructor(protected breadcrumbService: DSOBreadcrumbsService, protected dataService: BitstreamDataService, protected itemService: ItemDataService) { - super(breadcrumbService, dataService); +export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { + constructor( + protected breadcrumbService: DSOBreadcrumbsService, + protected dataService: BitstreamDataService, + protected itemService: ItemDataService + ) { + super(breadcrumbService, itemService); } /** @@ -34,7 +38,7 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver> { + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> { const uuid = route.params.id; return this.dataService.findById(uuid, true, false, ...this.followLinks).pipe( getFirstCompletedRemoteData(), @@ -45,12 +49,6 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { - this.itemService.findById(res.uuid, true, false, ...this.bfollowLinks).pipe( - getFirstCompletedRemoteData(), - getRemoteDataPayload() - ).subscribe(bres => { - console.log(bres); - }); const url = res._links.item.href; return {provider: this.breadcrumbService, key: of(res), url: url}; }); @@ -67,7 +65,7 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver[] { - return BITSTREAM_PAGE_LINKS_TO_FOLLOW; + return [followLink('bundle', followLink('item'))]; } get bfollowLinks(): FollowLinkConfig[] { From b8904f5fe1de67d989a192de11b91956fc2bb645 Mon Sep 17 00:00:00 2001 From: Sufiyan Shaikh Date: Thu, 28 Apr 2022 16:35:42 +0530 Subject: [PATCH 08/10] [CST-5676] Resolver Changes Item Undefined --- .../bitstream-breadcrumb.resolver.ts | 56 ++++++++++++------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts index 67c8c092c3..ef23a2819b 100644 --- a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -8,7 +8,7 @@ import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { Observable, of } from 'rxjs'; import { BreadcrumbConfig } from 'src/app/breadcrumbs/breadcrumb/breadcrumb-config.model'; import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../shared/operators'; -import { map } from 'rxjs/operators'; +import { map, switchMap } from 'rxjs/operators'; import { hasValue } from 'src/app/shared/empty.util'; import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; import { BundleDataService } from '../data/bundle-data.service'; @@ -16,6 +16,7 @@ import { Bundle } from '../shared/bundle.model'; import { ItemDataService } from '../data/item-data.service'; import { Item } from '../shared/item.model'; import { ITEM_PAGE_LINKS_TO_FOLLOW } from 'src/app/item-page/item.resolver'; +import { DSpaceObject } from '../shared/dspace-object.model'; /** * The class that resolves the BreadcrumbConfig object for an Item @@ -26,10 +27,10 @@ import { ITEM_PAGE_LINKS_TO_FOLLOW } from 'src/app/item-page/item.resolver'; export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { constructor( protected breadcrumbService: DSOBreadcrumbsService, - protected dataService: BitstreamDataService, - protected itemService: ItemDataService + protected bitstreamService: BitstreamDataService, + protected dataService: ItemDataService ) { - super(breadcrumbService, itemService); + super(breadcrumbService, dataService); } /** @@ -40,20 +41,37 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { */ resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> { const uuid = route.params.id; - return this.dataService.findById(uuid, true, false, ...this.followLinks).pipe( + return this.bitstreamService.findById(uuid, true, false, ...this.bfollowLinks).pipe( getFirstCompletedRemoteData(), getRemoteDataPayload(), - map((object: Bitstream) => { - if (hasValue(object)) { - object.bundle.pipe( + switchMap((bitstream: Bitstream) => { + if (hasValue(bitstream)) { + return bitstream.bundle.pipe( getFirstCompletedRemoteData(), - getRemoteDataPayload() - ).subscribe(res => { - const url = res._links.item.href; - return {provider: this.breadcrumbService, key: of(res), url: url}; - }); + getRemoteDataPayload(), + switchMap((bundle: Bundle) => { + if (hasValue(bundle)) { + return bundle.item.pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + map((item: Item) => { + if (hasValue(item)) { + console.log(item); + const fullPath = state.url; + const url = fullPath.substr(0, fullPath.indexOf(uuid)) + uuid; + return {provider: this.breadcrumbService, key: item, url: url}; + } else { + return undefined; + } + }) + ); + } else { + return of(undefined); + } + }) + ); } else { - return undefined; + return of(undefined); } }) ); @@ -64,11 +82,11 @@ export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { * The self links defined in this list are expected to be requested somewhere in the near future * Requesting them as embeds will limit the number of requests */ - get followLinks(): FollowLinkConfig[] { - return [followLink('bundle', followLink('item'))]; - } - - get bfollowLinks(): FollowLinkConfig[] { + get followLinks(): FollowLinkConfig[] { return ITEM_PAGE_LINKS_TO_FOLLOW; } + + get bfollowLinks(): FollowLinkConfig[] { + return [followLink('bundle', followLink('item'))]; + } } From 393a4a3d4075764c1362a25856b4aba2b78d69d1 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 28 Apr 2022 15:41:25 +0200 Subject: [PATCH 09/10] [CST-5676] Implemented bitstream-breadcrumbs.service --- .../bitstream-page-routing.module.ts | 27 +++--- .../bitstream-page/bitstream-page.resolver.ts | 2 +- .../bitstream-breadcrumb.resolver.ts | 77 ++--------------- .../bitstream-breadcrumbs.service.ts | 85 +++++++++++++++++++ .../breadcrumbs/dso-breadcrumbs.service.ts | 4 +- 5 files changed, 109 insertions(+), 86 deletions(-) create mode 100644 src/app/core/breadcrumbs/bitstream-breadcrumbs.service.ts diff --git a/src/app/bitstream-page/bitstream-page-routing.module.ts b/src/app/bitstream-page/bitstream-page-routing.module.ts index 5da9135846..0bdda29ddf 100644 --- a/src/app/bitstream-page/bitstream-page-routing.module.ts +++ b/src/app/bitstream-page/bitstream-page-routing.module.ts @@ -11,6 +11,8 @@ import { ResourcePolicyEditComponent } from '../shared/resource-policies/edit/re import { BitstreamAuthorizationsComponent } from './bitstream-authorizations/bitstream-authorizations.component'; import { LegacyBitstreamUrlResolver } from './legacy-bitstream-url.resolver'; import { BitstreamBreadcrumbResolver } from '../core/breadcrumbs/bitstream-breadcrumb.resolver'; +import { BitstreamBreadcrumbsService } from '../core/breadcrumbs/bitstream-breadcrumbs.service'; +import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver'; const EDIT_BITSTREAM_PATH = ':id/edit'; const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; @@ -26,8 +28,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: 'handle/:prefix/:suffix/:filename', component: BitstreamDownloadPageComponent, resolve: { - bitstream: LegacyBitstreamUrlResolver, - breadcrumb: BitstreamBreadcrumbResolver + bitstream: LegacyBitstreamUrlResolver }, }, { @@ -35,8 +36,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: ':prefix/:suffix/:sequence_id/:filename', component: BitstreamDownloadPageComponent, resolve: { - bitstream: LegacyBitstreamUrlResolver, - breadcrumb: BitstreamBreadcrumbResolver + bitstream: LegacyBitstreamUrlResolver }, }, { @@ -44,8 +44,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; path: ':id/download', component: BitstreamDownloadPageComponent, resolve: { - bitstream: BitstreamPageResolver, - breadcrumb: BitstreamBreadcrumbResolver + bitstream: BitstreamPageResolver }, }, { @@ -53,7 +52,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; component: EditBitstreamPageComponent, resolve: { bitstream: BitstreamPageResolver, - breadcrumb: BitstreamBreadcrumbResolver + breadcrumb: BitstreamBreadcrumbResolver, }, canActivate: [AuthenticatedGuard] }, @@ -64,8 +63,7 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; { path: 'create', resolve: { - resourcePolicyTarget: ResourcePolicyTargetResolver, - breadcrumb: BitstreamBreadcrumbResolver + resourcePolicyTarget: ResourcePolicyTargetResolver }, component: ResourcePolicyCreateComponent, data: { title: 'resource-policies.create.page.title', showBreadcrumbs: true } @@ -73,17 +71,17 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; { path: 'edit', resolve: { - resourcePolicy: ResourcePolicyResolver, - breadcrumb: BitstreamBreadcrumbResolver + breadcrumb: I18nBreadcrumbResolver, + resourcePolicy: ResourcePolicyResolver }, component: ResourcePolicyEditComponent, - data: { title: 'resource-policies.edit.page.title', showBreadcrumbs: true } + data: { breadcrumbKey: 'item.edit', title: 'resource-policies.edit.page.title', showBreadcrumbs: true } }, { path: '', resolve: { bitstream: BitstreamPageResolver, - breadcrumb: BitstreamBreadcrumbResolver + breadcrumb: BitstreamBreadcrumbResolver, }, component: BitstreamAuthorizationsComponent, data: { title: 'bitstream.edit.authorizations.title', showBreadcrumbs: true } @@ -94,7 +92,8 @@ const EDIT_BITSTREAM_AUTHORIZATIONS_PATH = ':id/authorizations'; ], providers: [ BitstreamPageResolver, - BitstreamBreadcrumbResolver + BitstreamBreadcrumbResolver, + BitstreamBreadcrumbsService ] }) export class BitstreamPageRoutingModule { diff --git a/src/app/bitstream-page/bitstream-page.resolver.ts b/src/app/bitstream-page/bitstream-page.resolver.ts index 5f41cafdeb..4f4f16b24d 100644 --- a/src/app/bitstream-page/bitstream-page.resolver.ts +++ b/src/app/bitstream-page/bitstream-page.resolver.ts @@ -17,7 +17,7 @@ import { Bundle } from '../core/shared/bundle.model'; followLink('parentCommunity', {}, followLink('parentCommunity')) ), - followLink('bundle'), + followLink('bundle', {}, followLink('item')), followLink('thumbnail') ]; diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts index ef23a2819b..b2ddade682 100644 --- a/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts +++ b/src/app/core/breadcrumbs/bitstream-breadcrumb.resolver.ts @@ -1,22 +1,11 @@ import { Injectable } from '@angular/core'; -import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; -import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; + +import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model'; import { Bitstream } from '../shared/bitstream.model'; import { BitstreamDataService } from '../data/bitstream-data.service'; -import { BITSTREAM_PAGE_LINKS_TO_FOLLOW, BUNDLE_PAGE_LINKS_TO_FOLLOW } from 'src/app/bitstream-page/bitstream-page.resolver'; -import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { Observable, of } from 'rxjs'; -import { BreadcrumbConfig } from 'src/app/breadcrumbs/breadcrumb/breadcrumb-config.model'; -import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../shared/operators'; -import { map, switchMap } from 'rxjs/operators'; -import { hasValue } from 'src/app/shared/empty.util'; +import { BITSTREAM_PAGE_LINKS_TO_FOLLOW } from '../../bitstream-page/bitstream-page.resolver'; import { DSOBreadcrumbResolver } from './dso-breadcrumb.resolver'; -import { BundleDataService } from '../data/bundle-data.service'; -import { Bundle } from '../shared/bundle.model'; -import { ItemDataService } from '../data/item-data.service'; -import { Item } from '../shared/item.model'; -import { ITEM_PAGE_LINKS_TO_FOLLOW } from 'src/app/item-page/item.resolver'; -import { DSpaceObject } from '../shared/dspace-object.model'; +import { BitstreamBreadcrumbsService } from './bitstream-breadcrumbs.service'; /** * The class that resolves the BreadcrumbConfig object for an Item @@ -24,69 +13,19 @@ import { DSpaceObject } from '../shared/dspace-object.model'; @Injectable({ providedIn: 'root' }) -export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { +export class BitstreamBreadcrumbResolver extends DSOBreadcrumbResolver { constructor( - protected breadcrumbService: DSOBreadcrumbsService, - protected bitstreamService: BitstreamDataService, - protected dataService: ItemDataService - ) { + protected breadcrumbService: BitstreamBreadcrumbsService, protected dataService: BitstreamDataService) { super(breadcrumbService, dataService); } - /** - * Method for resolving a breadcrumb config object - * @param {ActivatedRouteSnapshot} route The current ActivatedRouteSnapshot - * @param {RouterStateSnapshot} state The current RouterStateSnapshot - * @returns BitstreamBreadcrumbConfig object - */ - resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable> { - const uuid = route.params.id; - return this.bitstreamService.findById(uuid, true, false, ...this.bfollowLinks).pipe( - getFirstCompletedRemoteData(), - getRemoteDataPayload(), - switchMap((bitstream: Bitstream) => { - if (hasValue(bitstream)) { - return bitstream.bundle.pipe( - getFirstCompletedRemoteData(), - getRemoteDataPayload(), - switchMap((bundle: Bundle) => { - if (hasValue(bundle)) { - return bundle.item.pipe( - getFirstCompletedRemoteData(), - getRemoteDataPayload(), - map((item: Item) => { - if (hasValue(item)) { - console.log(item); - const fullPath = state.url; - const url = fullPath.substr(0, fullPath.indexOf(uuid)) + uuid; - return {provider: this.breadcrumbService, key: item, url: url}; - } else { - return undefined; - } - }) - ); - } else { - return of(undefined); - } - }) - ); - } else { - return of(undefined); - } - }) - ); - } - /** * Method that returns the follow links to already resolve * The self links defined in this list are expected to be requested somewhere in the near future * Requesting them as embeds will limit the number of requests */ - get followLinks(): FollowLinkConfig[] { - return ITEM_PAGE_LINKS_TO_FOLLOW; + get followLinks(): FollowLinkConfig[] { + return BITSTREAM_PAGE_LINKS_TO_FOLLOW; } - get bfollowLinks(): FollowLinkConfig[] { - return [followLink('bundle', followLink('item'))]; - } } diff --git a/src/app/core/breadcrumbs/bitstream-breadcrumbs.service.ts b/src/app/core/breadcrumbs/bitstream-breadcrumbs.service.ts new file mode 100644 index 0000000000..333886ed3d --- /dev/null +++ b/src/app/core/breadcrumbs/bitstream-breadcrumbs.service.ts @@ -0,0 +1,85 @@ +import { Injectable } from '@angular/core'; + +import { Observable, of as observableOf } from 'rxjs'; +import { map, switchMap } from 'rxjs/operators'; + +import { Breadcrumb } from '../../breadcrumbs/breadcrumb/breadcrumb.model'; +import { DSONameService } from './dso-name.service'; +import { ChildHALResource } from '../shared/child-hal-resource.model'; +import { LinkService } from '../cache/builders/link.service'; +import { DSpaceObject } from '../shared/dspace-object.model'; +import { RemoteData } from '../data/remote-data'; +import { hasValue, isNotEmpty } from '../../shared/empty.util'; +import { getDSORoute } from '../../app-routing-paths'; +import { DSOBreadcrumbsService } from './dso-breadcrumbs.service'; +import { BitstreamDataService } from '../data/bitstream-data.service'; +import { getFirstCompletedRemoteData, getRemoteDataPayload } from '../shared/operators'; +import { Bitstream } from '../shared/bitstream.model'; +import { Bundle } from '../shared/bundle.model'; +import { Item } from '../shared/item.model'; +import { BITSTREAM_PAGE_LINKS_TO_FOLLOW } from '../../bitstream-page/bitstream-page.resolver'; + +/** + * Service to calculate DSpaceObject breadcrumbs for a single part of the route + */ +@Injectable({ + providedIn: 'root' +}) +export class BitstreamBreadcrumbsService extends DSOBreadcrumbsService { + constructor( + protected bitstreamService: BitstreamDataService, + protected linkService: LinkService, + protected dsoNameService: DSONameService + ) { + super(linkService, dsoNameService); + } + + /** + * Method to recursively calculate the breadcrumbs + * This method returns the name and url of the key and all its parent DSOs recursively, top down + * @param key The key (a DSpaceObject) used to resolve the breadcrumb + * @param url The url to use as a link for this breadcrumb + */ + getBreadcrumbs(key: ChildHALResource & DSpaceObject, url: string): Observable { + const label = this.dsoNameService.getName(key); + const crumb = new Breadcrumb(label, url); + + return this.getOwningItem(key.uuid).pipe( + switchMap((parentRD: RemoteData) => { + if (isNotEmpty(parentRD) && hasValue(parentRD.payload)) { + const parent = parentRD.payload; + return super.getBreadcrumbs(parent, getDSORoute(parent)); + } + return observableOf([]); + + }), + map((breadcrumbs: Breadcrumb[]) => [...breadcrumbs, crumb]) + ); + } + + getOwningItem(uuid: string): Observable> { + return this.bitstreamService.findById(uuid, true, true, ...BITSTREAM_PAGE_LINKS_TO_FOLLOW).pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + switchMap((bitstream: Bitstream) => { + if (hasValue(bitstream)) { + return bitstream.bundle.pipe( + getFirstCompletedRemoteData(), + getRemoteDataPayload(), + switchMap((bundle: Bundle) => { + if (hasValue(bundle)) { + return bundle.item.pipe( + getFirstCompletedRemoteData(), + ); + } else { + return observableOf(undefined); + } + }) + ); + } else { + return observableOf(undefined); + } + }) + ); + } +} diff --git a/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts index 23fff18537..a5884ca3c9 100644 --- a/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts +++ b/src/app/core/breadcrumbs/dso-breadcrumbs.service.ts @@ -20,8 +20,8 @@ import { getDSORoute } from '../../app-routing-paths'; }) export class DSOBreadcrumbsService implements BreadcrumbsProviderService { constructor( - private linkService: LinkService, - private dsoNameService: DSONameService + protected linkService: LinkService, + protected dsoNameService: DSONameService ) { } From 3d206165b20303aa56fd2eeadf44451942375d61 Mon Sep 17 00:00:00 2001 From: Giuseppe Digilio Date: Thu, 28 Apr 2022 15:53:48 +0200 Subject: [PATCH 10/10] [CST-5676] Fix bitstream's follow links --- .../bitstream-page/bitstream-page.resolver.ts | 20 ++----------------- 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/src/app/bitstream-page/bitstream-page.resolver.ts b/src/app/bitstream-page/bitstream-page.resolver.ts index 4f4f16b24d..be92041dfc 100644 --- a/src/app/bitstream-page/bitstream-page.resolver.ts +++ b/src/app/bitstream-page/bitstream-page.resolver.ts @@ -6,27 +6,14 @@ import { Bitstream } from '../core/shared/bitstream.model'; import { BitstreamDataService } from '../core/data/bitstream-data.service'; import { followLink, FollowLinkConfig } from '../shared/utils/follow-link-config.model'; import { getFirstCompletedRemoteData } from '../core/shared/operators'; -import { Bundle } from '../core/shared/bundle.model'; /** * The self links defined in this list are expected to be requested somewhere in the near future * Requesting them as embeds will limit the number of requests */ export const BITSTREAM_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ - followLink('format', {}, - followLink('parentCommunity', {}, - followLink('parentCommunity')) - ), followLink('bundle', {}, followLink('item')), - followLink('thumbnail') -]; - -export const BUNDLE_PAGE_LINKS_TO_FOLLOW: FollowLinkConfig[] = [ - followLink('bitstreams', {}, - followLink('parentCommunity', {}, - followLink('parentCommunity')) - ), - followLink('primaryBitstream') + followLink('format') ]; /** @@ -56,9 +43,6 @@ export class BitstreamPageResolver implements Resolve> { * Requesting them as embeds will limit the number of requests */ get followLinks(): FollowLinkConfig[] { - return [ - followLink('bundle', {}, followLink('item')), - followLink('format') - ]; + return BITSTREAM_PAGE_LINKS_TO_FOLLOW; } }