From 13b0367631f72a50cc5a36547ceae674b86ca23f Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 08:19:28 +0200
Subject: [PATCH 08/27] Added keyboard event handling (enter)
---
.../clarin-item-versions-field.component.html | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
index a0cbda9c088..8401a12c96d 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
@@ -5,6 +5,7 @@
Date: Thu, 25 Sep 2025 08:32:37 +0200
Subject: [PATCH 09/27] Edit of manual Observable creation
---
.../clarin-item-versions-field.component.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 381e55a8173..14f20839c81 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -2,7 +2,7 @@ import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Item } from '../../../../core/shared/item.model';
import { Version } from '../../../../core/shared/version.model';
import { RemoteData } from '../../../../core/data/remote-data';
-import { combineLatest, Observable, Subscription } from 'rxjs';
+import { combineLatest, Observable, of, Subscription } from 'rxjs';
import { VersionHistory } from '../../../../core/shared/version-history.model';
import {
getAllSucceededRemoteData,
@@ -220,7 +220,7 @@ export class ClarinItemVersionsFieldComponent implements OnDestroy, OnInit {
);
} else {
// No version history available
- this.showMetadataValue = new Observable(observer => observer.next(false));
+ this.showMetadataValue = of(false);
}
}
From 523ca912e4c846c330347b6e88caf50d95b69cb1 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:14:32 +0200
Subject: [PATCH 10/27] clarin-item-versions-field extends item-versions to
avoid duplicate code
---
.../clarin-item-versions-field.component.ts | 227 +++---------------
.../versions/item-versions.component.ts | 38 +--
2 files changed, 47 insertions(+), 218 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 14f20839c81..23c9e8f53a3 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -1,118 +1,53 @@
-import { Component, Input, OnDestroy, OnInit } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
-import { Version } from '../../../../core/shared/version.model';
-import { RemoteData } from '../../../../core/data/remote-data';
-import { combineLatest, Observable, of, Subscription } from 'rxjs';
-import { VersionHistory } from '../../../../core/shared/version-history.model';
-import {
- getAllSucceededRemoteData,
- getFirstCompletedRemoteData,
- getFirstSucceededRemoteDataPayload,
- getRemoteDataPayload
-} from '../../../../core/shared/operators';
-import { map, switchMap } from 'rxjs/operators';
-import { PaginatedList } from '../../../../core/data/paginated-list.model';
-import { PaginationComponentOptions } from '../../../../shared/pagination/pagination-component-options.model';
-import { VersionHistoryDataService } from '../../../../core/data/version-history-data.service';
-import { PaginatedSearchOptions } from '../../../../shared/search/models/paginated-search-options.model';
-import { followLink } from '../../../../shared/utils/follow-link-config.model';
-import { hasValue, hasValueOperator } from '../../../../shared/empty.util';
-import { PaginationService } from '../../../../core/pagination/pagination.service';
-import { getItemVersionRoute } from '../../../item-page-routing-paths';
-import { WorkspaceItem } from '../../../../core/submission/models/workspaceitem.model';
-import { WorkspaceitemDataService } from '../../../../core/submission/workspaceitem-data.service';
-import { WorkflowItemDataService } from '../../../../core/submission/workflowitem-data.service';
interface VersionsDTO {
totalElements: number;
- versionDTOs: VersionDTO[];
-}
-
-interface VersionDTO {
- version: Version;
+ versionDTOs: any[];
}
+/**
+ * Clarin-specific field component for User/Anonymous view of item version history that extends ItemVersionsComponent
+ */
@Component({
selector: 'ds-clarin-item-versions-field',
templateUrl: './clarin-item-versions-field.component.html',
styleUrls: ['./clarin-item-versions-field.component.scss']
})
-
-/**
- * Component for displaying item versions as a field in the clarin item page
- */
-export class ClarinItemVersionsFieldComponent implements OnDestroy, OnInit {
-
- /**
- * The item to display version history for
- */
- @Input() item: Item;
-
- /**
- * Fontawesome v5. icon name with default settings.
- */
- @Input() iconName: string;
-
- /**
- * Array of active subscriptions
- */
- subs: Subscription[] = [];
-
- /**
- * The item's version
- */
- versionRD$: Observable
>;
-
- /**
- * The item's full version history (remote data)
- */
- versionHistoryRD$: Observable>;
-
- /**
- * The item's full version history
- */
- versionHistory$: Observable;
-
- /**
- * The version history information that is used to render the HTML
- */
- versionsDTO$: Observable;
-
- /**
- * Verify if there is an inprogress submission in the version history
- */
- hasDraftVersion$: Observable;
+export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent implements OnInit {
/**
- * The amount of versions to display per page
+ * Icon name for the clarin field
*/
- pageSize = 10;
+ @Input() iconName?: string;
/**
- * The page options to use for fetching the versions
- * Start at page 1 and always use the set page size
- */
- options = Object.assign(new PaginationComponentOptions(), {
- id: 'clarin-ivo',
- currentPage: 1,
- pageSize: this.pageSize
- });
-
- /**
- * Toggle state for version history
+ * Toggle state for version history display
*/
showVersionHistory = false;
/**
- * Observable to check if component should be displayed
+ * Observable to check if metadata field should be shown - clarin-specific implementation
+ * Returns true if there are multiple versions to display
*/
showMetadataValue: Observable;
- constructor(private versionHistoryService: VersionHistoryDataService,
- private paginationService: PaginationService,
- private workspaceItemDataService: WorkspaceitemDataService,
- private workflowItemDataService: WorkflowItemDataService
- ) {
+ ngOnInit(): void {
+ // Call parent's ngOnInit first to set up all the observables
+ super.ngOnInit();
+
+ // Set up clarin-specific showMetadataValue logic
+ if (this.versionsDTO$) {
+ this.showMetadataValue = this.versionsDTO$.pipe(
+ map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
+ );
+ } else {
+ // Fallback: always show if user is admin
+ this.showMetadataValue = this.isAdmin$;
+ }
}
/**
@@ -122,117 +57,11 @@ export class ClarinItemVersionsFieldComponent implements OnDestroy, OnInit {
this.showVersionHistory = !this.showVersionHistory;
}
- /**
- * Get the route to the specified version
- * @param versionId the ID of the version for which the route will be retrieved
- */
- getVersionRoute(versionId: string) {
- return getItemVersionRoute(versionId);
- }
-
- /**
- * Get all versions for the given version history and store them in versionsDTO$
- * @param versionHistory$
- */
- getAllVersions(versionHistory$: Observable): void {
- const currentPagination = this.paginationService.getCurrentPagination(this.options.id, this.options);
- this.versionsDTO$ = combineLatest([versionHistory$, currentPagination]).pipe(
- switchMap(([versionHistory, options]: [VersionHistory, PaginationComponentOptions]) => {
- return this.versionHistoryService.getVersions(versionHistory.id,
- new PaginatedSearchOptions({pagination: Object.assign({}, options, {currentPage: options.currentPage})}),
- false, true, followLink('item'));
- }),
- getFirstCompletedRemoteData(),
- getRemoteDataPayload(),
- map((versions: PaginatedList) => ({
- totalElements: versions.totalElements,
- versionDTOs: (versions?.page ?? []).reverse().map((version: Version) => ({
- version: version,
- })),
- })),
- );
- }
-
- /**
- * Get the ID of the workspace item, if present, otherwise return undefined
- * @param versionItem the item for which retrieve the workspace item id
- */
- getWorkspaceId(versionItem: Observable>): Observable {
- return versionItem.pipe(
- getFirstSucceededRemoteDataPayload(),
- map((item: Item) => item.uuid),
- switchMap((itemUuid: string) => this.workspaceItemDataService.findByItem(itemUuid, true)),
- getFirstCompletedRemoteData(),
- map((res: RemoteData) => res?.payload?.id ),
- );
- }
-
- /**
- * Get the ID of the workflow item, if present, otherwise return undefined
- * @param versionItem the item for which retrieve the workspace item id
- */
- getWorkflowId(versionItem: Observable>): Observable {
- return versionItem.pipe(
- getFirstSucceededRemoteDataPayload(),
- map((item: Item) => item.uuid),
- switchMap((itemUuid: string) => this.workflowItemDataService.findByItem(itemUuid, true)),
- getFirstCompletedRemoteData(),
- map((res: RemoteData) => res?.payload?.id ),
- );
- }
-
/**
* Get the display name for a version item
* @param versionItem the item to get the name for
*/
getVersionItemDisplayName(versionItem: Item): string {
- return versionItem.firstMetadataValue('dc.title') || versionItem.name || 'Untitled';
- }
-
- /**
- * Initialize all observables
- */
- ngOnInit(): void {
- if (hasValue(this.item?.version)) {
- this.versionRD$ = this.item.version;
- this.versionHistoryRD$ = this.versionRD$.pipe(
- getAllSucceededRemoteData(),
- getRemoteDataPayload(),
- hasValueOperator(),
- switchMap((version: Version) => version.versionhistory),
- );
- this.versionHistory$ = this.versionHistoryRD$.pipe(
- getFirstSucceededRemoteDataPayload(),
- hasValueOperator(),
- );
-
- // If there is a draft item in the version history
- this.hasDraftVersion$ = this.versionHistoryRD$.pipe(
- getFirstSucceededRemoteDataPayload(),
- map((res) => Boolean(res?.draftVersion)),
- );
-
- this.getAllVersions(this.versionHistory$);
-
- // Determine if component should be displayed (when there are multiple versions)
- this.showMetadataValue = this.versionsDTO$.pipe(
- map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
- );
- } else {
- // No version history available
- this.showMetadataValue = of(false);
- }
- }
-
- /**
- * Unsub all subscriptions
- */
- cleanupSubscribes() {
- this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
- }
-
- ngOnDestroy(): void {
- this.cleanupSubscribes();
- this.paginationService.clearPagination(this.options.id);
+ return versionItem?.firstMetadataValue('dc.title') || versionItem?.name || 'Untitled';
}
}
diff --git a/src/app/item-page/versions/item-versions.component.ts b/src/app/item-page/versions/item-versions.component.ts
index afbff77706f..66e6cfafa3e 100644
--- a/src/app/item-page/versions/item-versions.component.ts
+++ b/src/app/item-page/versions/item-versions.component.ts
@@ -202,25 +202,25 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
* Loading of the name from the items handles for the items which are stored in the metadata dc.relation.replaces` and
* `dc.relation.isreplacedby`
* Names are stored in this dict to avoid endless calling rest API to get the name of the Item.
- * @private
- */
- private nameCache: { [handle: string]: string } = {};
-
- constructor(private versionHistoryService: VersionHistoryDataService,
- private versionService: VersionDataService,
- private itemService: ItemDataService,
- private paginationService: PaginationService,
- private formBuilder: UntypedFormBuilder,
- private modalService: NgbModal,
- private notificationsService: NotificationsService,
- private translateService: TranslateService,
- private router: Router,
- private itemVersionShared: ItemVersionsSharedService,
- private authorizationService: AuthorizationDataService,
- private workspaceItemDataService: WorkspaceitemDataService,
- private workflowItemDataService: WorkflowItemDataService,
- private configurationService: ConfigurationDataService,
- private dsoNameService: DSONameService
+ * @protected
+ */
+ protected nameCache: { [handle: string]: string } = {};
+
+ constructor(protected versionHistoryService: VersionHistoryDataService,
+ protected versionService: VersionDataService,
+ protected itemService: ItemDataService,
+ protected paginationService: PaginationService,
+ protected formBuilder: UntypedFormBuilder,
+ protected modalService: NgbModal,
+ protected notificationsService: NotificationsService,
+ protected translateService: TranslateService,
+ protected router: Router,
+ protected itemVersionShared: ItemVersionsSharedService,
+ protected authorizationService: AuthorizationDataService,
+ protected workspaceItemDataService: WorkspaceitemDataService,
+ protected workflowItemDataService: WorkflowItemDataService,
+ protected configurationService: ConfigurationDataService,
+ protected dsoNameService: DSONameService
) {
}
From b93139fe2c53878ceea660861f31b9a0b885cf66 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:18:59 +0200
Subject: [PATCH 11/27] reverted new admin view of item-versions history to
usual look
---
.../versions/item-versions.component.html | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/src/app/item-page/versions/item-versions.component.html b/src/app/item-page/versions/item-versions.component.html
index 377b3ffd13e..97cd1977ab8 100644
--- a/src/app/item-page/versions/item-versions.component.html
+++ b/src/app/item-page/versions/item-versions.component.html
@@ -16,6 +16,9 @@ {{ "item.version.history.head" | translate }
| {{ "item.version.history.table.version" | translate }} |
+ {{ "item.version.history.table.editor" | translate }} |
+ {{ "item.version.history.table.date" | translate }} |
+ {{ "item.version.history.table.summary" | translate }} |
@@ -92,6 +95,52 @@ {{ "item.version.history.head" | translate }
+ |
+ {{ versionDTO.version.submitterName }}
+ |
+
+ {{ versionDTO.version.created | date : 'yyyy-MM-dd HH:mm:ss' }}
+ |
+
+
+
+ {{ versionDTO.version.summary }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
From ba781a51d365bd4eb6c0f6d3d30b4551ca360aca Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 14:37:04 +0200
Subject: [PATCH 12/27] Usage of more common way for checking if is Admin
---
.../versions/item-versions.component.ts | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/src/app/item-page/versions/item-versions.component.ts b/src/app/item-page/versions/item-versions.component.ts
index 66e6cfafa3e..7679f966983 100644
--- a/src/app/item-page/versions/item-versions.component.ts
+++ b/src/app/item-page/versions/item-versions.component.ts
@@ -447,22 +447,6 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
}
- /**
- * Check if the current user is an admin (collection admin, community admin, or site admin)
- * @returns Observable true if user has admin privileges
- */
- isAdmin(): Observable {
- return combineLatest([
- this.authorizationService.isAuthorized(FeatureID.IsCollectionAdmin),
- this.authorizationService.isAuthorized(FeatureID.IsCommunityAdmin),
- this.authorizationService.isAuthorized(FeatureID.AdministratorOf),
- ]).pipe(
- map(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin]) => {
- return isCollectionAdmin || isCommunityAdmin || isSiteAdmin;
- })
- );
- }
-
/**
* Check if the current user can delete the version
* @param version
@@ -561,7 +545,7 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
this.canCreateVersion$ = this.authorizationService.isAuthorized(FeatureID.CanCreateVersion, this.item.self);
// Initialize admin check for component visibility
- this.isAdmin$ = this.isAdmin();
+ this.isAdmin$ = this.authorizationService.isAuthorized(FeatureID.AdministratorOf);
// If there is a draft item in the version history the 'Create version' button is disabled and a different tooltip message is shown
this.hasDraftVersion$ = this.versionHistoryRD$.pipe(
From a4acf790da36593675308685cfb41187be44d671 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 15:20:19 +0200
Subject: [PATCH 13/27] removed duplicate interface
---
.../clarin-item-versions-field.component.ts | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 23c9e8f53a3..83f7eabe466 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -4,11 +4,6 @@ import { map } from 'rxjs/operators';
import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
-interface VersionsDTO {
- totalElements: number;
- versionDTOs: any[];
-}
-
/**
* Clarin-specific field component for User/Anonymous view of item version history that extends ItemVersionsComponent
*/
@@ -42,7 +37,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
// Set up clarin-specific showMetadataValue logic
if (this.versionsDTO$) {
this.showMetadataValue = this.versionsDTO$.pipe(
- map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
+ map((versionsDTO: any) => versionsDTO && versionsDTO.totalElements > 1)
);
} else {
// Fallback: always show if user is admin
From e7d02acf24a12261773204dc1a98708082ad6566 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 15:31:16 +0200
Subject: [PATCH 14/27] change to duplicate interfaces, but avoiding any type
---
.../clarin-item-versions-field.component.ts | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 83f7eabe466..94f3b0750b3 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -3,6 +3,21 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
+import { Version } from '../../../../core/shared/version.model';
+
+/**
+ * Local type definition matching the parent component's VersionsDTO structure
+ */
+interface VersionsDTO {
+ totalElements: number;
+ versionDTOs: VersionDTO[];
+}
+
+interface VersionDTO {
+ version: Version;
+ canEditVersion: Observable;
+ canDeleteVersion: Observable;
+}
/**
* Clarin-specific field component for User/Anonymous view of item version history that extends ItemVersionsComponent
@@ -37,7 +52,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
// Set up clarin-specific showMetadataValue logic
if (this.versionsDTO$) {
this.showMetadataValue = this.versionsDTO$.pipe(
- map((versionsDTO: any) => versionsDTO && versionsDTO.totalElements > 1)
+ map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
);
} else {
// Fallback: always show if user is admin
From 6a594e7481e35a1543d33df4552ac5df857b22c7 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 15:40:05 +0200
Subject: [PATCH 15/27] implementation of more effective method concating
strings
---
.../clarin-item-versions-field.component.html | 2 +-
.../clarin-item-versions-field.component.ts | 8 ++++++++
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
index 8401a12c96d..9c45c559078 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
@@ -10,7 +10,7 @@
tabindex="0"
[attr.aria-expanded]="showVersionHistory"
aria-controls="version-history-content"
- [attr.aria-label]="(showVersionHistory ? 'Collapse' : 'Expand') + ' version history'">
+ [attr.aria-label]="getToggleAriaLabel()">
{{ "item.version.history.head" | translate }}
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 94f3b0750b3..6626564bdfb 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -74,4 +74,12 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
getVersionItemDisplayName(versionItem: Item): string {
return versionItem?.firstMetadataValue('dc.title') || versionItem?.name || 'Untitled';
}
+
+ /**
+ * Get the appropriate aria-label for the toggle button
+ * @returns The aria-label text for accessibility
+ */
+ getToggleAriaLabel(): string {
+ return (this.showVersionHistory ? 'Collapse' : 'Expand') + ' version history';
+ }
}
From a0d031b2e7ac4b8d0be8c6a434ed4da0fb51a17d Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 25 Sep 2025 15:46:39 +0200
Subject: [PATCH 16/27] Added documentation for the need of protected access
modifiers
---
src/app/item-page/versions/item-versions.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/item-page/versions/item-versions.component.ts b/src/app/item-page/versions/item-versions.component.ts
index 7679f966983..903a7af459d 100644
--- a/src/app/item-page/versions/item-versions.component.ts
+++ b/src/app/item-page/versions/item-versions.component.ts
@@ -202,7 +202,7 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
* Loading of the name from the items handles for the items which are stored in the metadata dc.relation.replaces` and
* `dc.relation.isreplacedby`
* Names are stored in this dict to avoid endless calling rest API to get the name of the Item.
- * @protected
+ * @protected Accessible to extending components that may need to cache item names from handles
*/
protected nameCache: { [handle: string]: string } = {};
From 16370c8acae3a70469e78b384a3203c133e32a9c Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 07:25:48 +0200
Subject: [PATCH 17/27] Fixed documentation to valid JSDoc tag, prevention for
not initializing this.isAdmin$
---
.../clarin-item-versions-field.component.ts | 6 +++---
src/app/item-page/versions/item-versions.component.ts | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 6626564bdfb..cf4603cbe7b 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -1,5 +1,5 @@
import { Component, Input, OnInit } from '@angular/core';
-import { Observable } from 'rxjs';
+import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
@@ -55,8 +55,8 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
);
} else {
- // Fallback: always show if user is admin
- this.showMetadataValue = this.isAdmin$;
+ // Fallback: check if isAdmin$ is available, otherwise hide the component
+ this.showMetadataValue = this.isAdmin$ || of(false);
}
}
diff --git a/src/app/item-page/versions/item-versions.component.ts b/src/app/item-page/versions/item-versions.component.ts
index 903a7af459d..3c78e492904 100644
--- a/src/app/item-page/versions/item-versions.component.ts
+++ b/src/app/item-page/versions/item-versions.component.ts
@@ -202,7 +202,7 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
* Loading of the name from the items handles for the items which are stored in the metadata dc.relation.replaces` and
* `dc.relation.isreplacedby`
* Names are stored in this dict to avoid endless calling rest API to get the name of the Item.
- * @protected Accessible to extending components that may need to cache item names from handles
+ * @access protected - Accessible to extending components that may need to cache item names from handles
*/
protected nameCache: { [handle: string]: string } = {};
From 34511785bb0d06aa3415eecfcfdf4615ac2baf0c Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 07:34:12 +0200
Subject: [PATCH 18/27] Changed isAdmin warpper to section
---
.../versions/item-versions.component.html | 284 +++++++++---------
1 file changed, 142 insertions(+), 142 deletions(-)
diff --git a/src/app/item-page/versions/item-versions.component.html b/src/app/item-page/versions/item-versions.component.html
index 97cd1977ab8..34e9444ed20 100644
--- a/src/app/item-page/versions/item-versions.component.html
+++ b/src/app/item-page/versions/item-versions.component.html
@@ -1,157 +1,157 @@
-
-
-
-
{{ "item.version.history.head" | translate }}
-
- {{ "item.version.history.selected.alert" | translate : { version: itemVersion.version } }}
-
-
0"
- (paginationChange)="onPageChange()"
- [hideGear]="true"
- [hidePagerWhenSinglePage]="true"
- [paginationOptions]="options"
- [collectionSize]="versionsDTO.totalElements"
- [retainScrollPosition]="true">
-
-
-
- | {{ "item.version.history.table.version" | translate }} |
- {{ "item.version.history.table.editor" | translate }} |
- {{ "item.version.history.table.date" | translate }} |
- {{ "item.version.history.table.summary" | translate }} |
-
-
-
-
-
-
-
+
+
+
+ {{ "item.version.history.head" | translate }}
+
+ {{ "item.version.history.selected.alert" | translate : { version: itemVersion.version } }}
+
+ 0"
+ (paginationChange)="onPageChange()"
+ [hideGear]="true"
+ [hidePagerWhenSinglePage]="true"
+ [paginationOptions]="options"
+ [collectionSize]="versionsDTO.totalElements"
+ [retainScrollPosition]="true">
+
+
+
+ | {{ "item.version.history.table.version" | translate }} |
+ {{ "item.version.history.table.editor" | translate }} |
+ {{ "item.version.history.table.date" | translate }} |
+ {{ "item.version.history.table.summary" | translate }} |
+
+
+
+
+
+
+ *ngVar="((hasDraftVersion$ | async) ? getWorkspaceId(versionDTO.version.item) : undefined) as workspaceId$">
+
-
-
+
-
-
-
-
-
-
-
+
+
-
- |
-
- {{ versionDTO.version.submitterName }}
- |
-
- {{ versionDTO.version.created | date : 'yyyy-MM-dd HH:mm:ss' }}
- |
-
-
-
- {{ versionDTO.version.summary }}
-
-
-
-
+ |
+
+ {{ versionDTO.version.submitterName }}
+ |
+
+ {{ versionDTO.version.created | date : 'yyyy-MM-dd HH:mm:ss' }}
+ |
+
+
+
+ {{ versionDTO.version.summary }}
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- |
-
-
-
- * {{ "item.version.history.selected" | translate }}
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ * {{ "item.version.history.selected" | translate }}
+
+
-
-
-
-
-
-
+
+
+
+
+
From b38331f6d97ea63124b2aecabd86659649b0aa58 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 07:39:04 +0200
Subject: [PATCH 19/27] added calc() to scss
---
.../clarin-item-versions-field.component.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.scss b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.scss
index 774b489f5f7..f60052e1dc9 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.scss
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.scss
@@ -12,6 +12,6 @@
border-radius: 4px;
padding: 2%;
- max-height: var(--ds-dso-selector-list-max-height) / 2;
+ max-height: calc(var(--ds-dso-selector-list-max-height) / 2);
overflow-y: auto;
}
From 59e8ed8bdf697f64a9a27f7ac811b9e089b2cdd2 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 07:43:14 +0200
Subject: [PATCH 20/27] Fix of uninitialized isAdmin handling
---
.../clarin-item-versions-field.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index cf4603cbe7b..1ede7c390b8 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -56,7 +56,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
);
} else {
// Fallback: check if isAdmin$ is available, otherwise hide the component
- this.showMetadataValue = this.isAdmin$ || of(false);
+ this.showMetadataValue = this.isAdmin$ ? this.isAdmin$ : of(false);
}
}
From 9797d0aba2121eb686d412a6e0fef27ad233a1d1 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 08:24:47 +0200
Subject: [PATCH 21/27] Optimization of hasDraftVersion logic - exposing it as
an observable
---
.../clarin-item-versions-field.component.html | 6 ++--
.../clarin-item-versions-field.component.ts | 34 +++++++++++++++++--
2 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
index 9c45c559078..b74e862b3ab 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
@@ -27,11 +27,11 @@
-
+ Using component methods to optimize performance and avoid repeated async evaluations. -->
+ *ngVar="getVersionWorkspaceId(versionDTO.version.item) as workspaceId$">
+ *ngVar="getVersionWorkflowId(versionDTO.version.item, workspaceId$) as workflowId$">
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 1ede7c390b8..a2a8db8f845 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -1,6 +1,6 @@
import { Component, Input, OnInit } from '@angular/core';
-import { Observable, of } from 'rxjs';
-import { map } from 'rxjs/operators';
+import { Observable, of, combineLatest } from 'rxjs';
+import { map, switchMap } from 'rxjs/operators';
import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
import { Version } from '../../../../core/shared/version.model';
@@ -82,4 +82,34 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
getToggleAriaLabel(): string {
return (this.showVersionHistory ? 'Collapse' : 'Expand') + ' version history';
}
+
+ /**
+ * Get workspace ID for a version item if there's a draft version, otherwise return undefined
+ * This method optimizes the template logic by pre-computing the conditional check
+ * @param versionItem the version item's observable
+ */
+ getVersionWorkspaceId(versionItem: Observable): Observable {
+ return combineLatest([
+ this.hasDraftVersion$ || of(false),
+ of(versionItem)
+ ]).pipe(
+ switchMap(([hasDraftVersion, item]) =>
+ hasDraftVersion ? this.getWorkspaceId(item) : of(undefined)
+ )
+ );
+ }
+
+ /**
+ * Get workflow ID for a version item if workspace ID is not available
+ * This method optimizes the template logic by handling the conditional workflow ID logic
+ * @param versionItem the version item's observable
+ * @param workspaceId$ the workspace ID observable
+ */
+ getVersionWorkflowId(versionItem: Observable, workspaceId$: Observable): Observable {
+ return workspaceId$.pipe(
+ switchMap((workspaceId) =>
+ workspaceId ? of(undefined) : this.getWorkflowId(versionItem)
+ )
+ );
+ }
}
From b293024c4d34e2a9d8f9b560ffa52ca0719607ab Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 08:33:16 +0200
Subject: [PATCH 22/27] Fixed logic checking value of this.hasDraftVersion$
---
.../clarin-item-versions-field.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index a2a8db8f845..0c992560b66 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -90,7 +90,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
*/
getVersionWorkspaceId(versionItem: Observable): Observable {
return combineLatest([
- this.hasDraftVersion$ || of(false),
+ this.hasDraftVersion$ ?? of(false),
of(versionItem)
]).pipe(
switchMap(([hasDraftVersion, item]) =>
From cf44845f3f15cee31cd3e971b4848733b80e55de Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 08:55:13 +0200
Subject: [PATCH 23/27] Reverted css, removed unclear typing from new methods
---
.../clarin-item-versions-field.component.ts | 4 ++--
src/app/item-page/versions/item-versions.component.scss | 9 +++++++++
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 0c992560b66..5402c048b8f 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -88,7 +88,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
* This method optimizes the template logic by pre-computing the conditional check
* @param versionItem the version item's observable
*/
- getVersionWorkspaceId(versionItem: Observable): Observable {
+ getVersionWorkspaceId(versionItem: Observable
- ): Observable {
return combineLatest([
this.hasDraftVersion$ ?? of(false),
of(versionItem)
@@ -105,7 +105,7 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
* @param versionItem the version item's observable
* @param workspaceId$ the workspace ID observable
*/
- getVersionWorkflowId(versionItem: Observable, workspaceId$: Observable): Observable {
+ getVersionWorkflowId(versionItem: Observable
- , workspaceId$: Observable): Observable {
return workspaceId$.pipe(
switchMap((workspaceId) =>
workspaceId ? of(undefined) : this.getWorkflowId(versionItem)
diff --git a/src/app/item-page/versions/item-versions.component.scss b/src/app/item-page/versions/item-versions.component.scss
index e69de29bb2d..5594e0cafe8 100644
--- a/src/app/item-page/versions/item-versions.component.scss
+++ b/src/app/item-page/versions/item-versions.component.scss
@@ -0,0 +1,9 @@
+.left-column {
+ float: left;
+ text-align: left;
+}
+
+.right-column {
+ float: right;
+ text-align: right;
+}
From 3a47814c7a631dfee31fa9b281c022ca606d3539 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Fri, 26 Sep 2025 09:18:03 +0200
Subject: [PATCH 24/27] Fixed versionItem type handling
---
.../clarin-item-versions-field.component.ts | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 5402c048b8f..53cac862031 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -89,12 +89,9 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
* @param versionItem the version item's observable
*/
getVersionWorkspaceId(versionItem: Observable
- ): Observable {
- return combineLatest([
- this.hasDraftVersion$ ?? of(false),
- of(versionItem)
- ]).pipe(
- switchMap(([hasDraftVersion, item]) =>
- hasDraftVersion ? this.getWorkspaceId(item) : of(undefined)
+ return (this.hasDraftVersion$ ?? of(false)).pipe(
+ switchMap(hasDraftVersion =>
+ hasDraftVersion ? this.getWorkspaceId(versionItem) : of(undefined)
)
);
}
From a23f37b3d632a923d2fa288e3d10879bd5b77e49 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 6 Nov 2025 08:34:47 +0100
Subject: [PATCH 25/27] Changed expand/collapse text to translation keys
---
.../clarin-item-versions-field.component.ts | 6 +++++-
src/assets/i18n/cs.json5 | 9 +++++++++
src/assets/i18n/en.json5 | 6 ++++++
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index 53cac862031..c8a4dd6c477 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -80,7 +80,11 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
* @returns The aria-label text for accessibility
*/
getToggleAriaLabel(): string {
- return (this.showVersionHistory ? 'Collapse' : 'Expand') + ' version history';
+ const action = this.showVersionHistory
+ ? this.translateService.instant('item.version.history.collapse')
+ : this.translateService.instant('item.version.history.expand');
+ const history = this.translateService.instant('item.version.history.label');
+ return `${action} ${history}`;
}
/**
diff --git a/src/assets/i18n/cs.json5 b/src/assets/i18n/cs.json5
index f928e07d09f..a7611335547 100644
--- a/src/assets/i18n/cs.json5
+++ b/src/assets/i18n/cs.json5
@@ -3998,6 +3998,15 @@
// "item.version.history.head": "Version History",
"item.version.history.head": "Historie verzí",
+ // "item.version.history.label": "version history",
+ "item.version.history.label": "historie verzí",
+
+ // "item.version.history.expand": "Expand",
+ "item.version.history.expand": "Rozbalit",
+
+ // "item.version.history.collapse": "Collapse",
+ "item.version.history.collapse": "Sbalit",
+
// "item.version.history.return": "Back",
"item.version.history.return": "Zpět",
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index c6006102d8d..8b4a37616b6 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -2665,6 +2665,12 @@
"item.version.history.head": "Version History",
+ "item.version.history.label": "version history",
+
+ "item.version.history.expand": "Expand",
+
+ "item.version.history.collapse": "Collapse",
+
"item.version.history.return": "Back",
"item.version.history.selected": "Selected version",
From c33458f08cecaee279fb13de7c80bfd3f89f6e28 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 6 Nov 2025 08:38:39 +0100
Subject: [PATCH 26/27] fix: avoid array mutation by creating copy before
reversing version list
---
src/app/item-page/versions/item-versions.component.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/app/item-page/versions/item-versions.component.ts b/src/app/item-page/versions/item-versions.component.ts
index 3c78e492904..0d90f24d2ce 100644
--- a/src/app/item-page/versions/item-versions.component.ts
+++ b/src/app/item-page/versions/item-versions.component.ts
@@ -471,7 +471,7 @@ export class ItemVersionsComponent implements OnDestroy, OnInit {
getRemoteDataPayload(),
map((versions: PaginatedList) => ({
totalElements: versions.totalElements,
- versionDTOs: (versions?.page ?? []).reverse().map((version: Version) => ({
+ versionDTOs: [...(versions?.page ?? [])].reverse().map((version: Version) => ({
version: version,
canEditVersion: this.canEditVersion$(version),
canDeleteVersion: this.canDeleteVersion$(version),
From cfe62419a4f5da453bd999b71bc76f9cdf56ff33 Mon Sep 17 00:00:00 2001
From: Juraj Roka <95219754+jr-rk@users.noreply.github.com>
Date: Thu, 6 Nov 2025 09:30:18 +0100
Subject: [PATCH 27/27] perf: optimize version history by pre-computing
workspace/workflow IDs and using trackBy
---
.../clarin-item-versions-field.component.html | 47 ++++++----------
.../clarin-item-versions-field.component.ts | 55 +++++++++++++++++++
2 files changed, 72 insertions(+), 30 deletions(-)
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
index b74e862b3ab..5e2f6dd6b36 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.html
@@ -22,37 +22,24 @@
class="col-lg-9 collapse"
[ngClass]="{'show': showVersionHistory}"
[attr.aria-hidden]="!showVersionHistory">
-
-
-
+
* {{ "item.version.history.selected" | translate }}
diff --git a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
index c8a4dd6c477..5ed269c5988 100644
--- a/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
+++ b/src/app/item-page/simple/field-components/clarin-item-versions-field/clarin-item-versions-field.component.ts
@@ -4,6 +4,7 @@ import { map, switchMap } from 'rxjs/operators';
import { ItemVersionsComponent } from '../../../versions/item-versions.component';
import { Item } from '../../../../core/shared/item.model';
import { Version } from '../../../../core/shared/version.model';
+import { RemoteData } from '../../../../core/data/remote-data';
/**
* Local type definition matching the parent component's VersionsDTO structure
@@ -19,6 +20,16 @@ interface VersionDTO {
canDeleteVersion: Observable
;
}
+/**
+ * Enhanced VersionDTO with pre-computed workspace/workflow IDs for template optimization
+ */
+interface EnhancedVersionDTO extends VersionDTO {
+ versionItem$: Observable>;
+ workspaceId$: Observable;
+ workflowId$: Observable;
+ isCurrentVersion: boolean;
+}
+
/**
* Clarin-specific field component for User/Anonymous view of item version history that extends ItemVersionsComponent
*/
@@ -45,6 +56,11 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
*/
showMetadataValue: Observable;
+ /**
+ * Enhanced versions with pre-computed workspace/workflow IDs
+ */
+ enhancedVersions$: Observable;
+
ngOnInit(): void {
// Call parent's ngOnInit first to set up all the observables
super.ngOnInit();
@@ -54,6 +70,36 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
this.showMetadataValue = this.versionsDTO$.pipe(
map((versionsDTO: VersionsDTO) => versionsDTO && versionsDTO.totalElements > 1)
);
+
+ // Pre-compute workspace/workflow IDs to optimize template performance
+ this.enhancedVersions$ = combineLatest([
+ this.versionsDTO$,
+ this.versionRD$
+ ]).pipe(
+ map(([versionsDTO, versionRD]) => {
+ const currentVersionId = versionRD?.payload?.id;
+ return versionsDTO.versionDTOs.map(versionDTO => {
+ const versionItem$ = versionDTO.version.item;
+ const workspaceId$ = (this.hasDraftVersion$ ?? of(false)).pipe(
+ switchMap(hasDraftVersion =>
+ hasDraftVersion ? this.getWorkspaceId(versionItem$) : of(undefined)
+ )
+ );
+ const workflowId$ = workspaceId$.pipe(
+ switchMap((workspaceId) =>
+ workspaceId ? of(undefined) : this.getWorkflowId(versionItem$)
+ )
+ );
+ return {
+ ...versionDTO,
+ versionItem$,
+ workspaceId$,
+ workflowId$,
+ isCurrentVersion: versionDTO.version.id === currentVersionId
+ } as EnhancedVersionDTO;
+ });
+ })
+ );
} else {
// Fallback: check if isAdmin$ is available, otherwise hide the component
this.showMetadataValue = this.isAdmin$ ? this.isAdmin$ : of(false);
@@ -113,4 +159,13 @@ export class ClarinItemVersionsFieldComponent extends ItemVersionsComponent impl
)
);
}
+
+ /**
+ * TrackBy function for version list to optimize *ngFor performance
+ * @param index the index of the item
+ * @param versionDTO the version DTO to track
+ */
+ trackByVersionId(index: number, versionDTO: EnhancedVersionDTO): string {
+ return versionDTO.version.id;
+ }
}