[CST-4499] Version history - Changes to version history table

This commit is contained in:
Davide Negretti
2021-10-15 19:13:15 +02:00
parent 850970e204
commit e4d468b17c
10 changed files with 189 additions and 68 deletions

View File

@@ -59,6 +59,7 @@ export class ItemDataService extends DataService<Item> {
* Get the endpoint for browsing items * Get the endpoint for browsing items
* (When options.sort.field is empty, the default field to browse by will be 'dc.date.issued') * (When options.sort.field is empty, the default field to browse by will be 'dc.date.issued')
* @param {FindListOptions} options * @param {FindListOptions} options
* @param linkPath
* @returns {Observable<string>} * @returns {Observable<string>}
*/ */
public getBrowseEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> { public getBrowseEndpoint(options: FindListOptions = {}, linkPath: string = this.linkPath): Observable<string> {
@@ -287,4 +288,13 @@ export class ItemDataService extends DataService<Item> {
switchMap((url: string) => this.halService.getEndpoint('bitstreams', `${url}/${itemId}`)) switchMap((url: string) => this.halService.getEndpoint('bitstreams', `${url}/${itemId}`))
); );
} }
/**
* Invalidate the cache of the item
* @param itemUUID
*/
invalidateItemCache(itemUUID: string) {
this.requestService.setStaleByHrefSubstring('item/' + itemUUID);
}
} }

View File

@@ -11,7 +11,7 @@ import { NotificationsService } from '../../shared/notifications/notifications.s
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { DefaultChangeAnalyzer } from './default-change-analyzer.service'; import { DefaultChangeAnalyzer } from './default-change-analyzer.service';
import { FindListOptions } from './request.models'; import { FindListOptions } from './request.models';
import { Observable, of } from 'rxjs'; import { EMPTY, Observable } from 'rxjs';
import { dataService } from '../cache/builders/build-decorators'; import { dataService } from '../cache/builders/build-decorators';
import { VERSION } from '../shared/version.resource-type'; import { VERSION } from '../shared/version.resource-type';
import { VersionHistory } from '../shared/version-history.model'; import { VersionHistory } from '../shared/version-history.model';
@@ -55,7 +55,7 @@ export class VersionDataService extends DataService<Version> {
getFirstSucceededRemoteDataPayload(), getFirstSucceededRemoteDataPayload(),
switchMap((res) => res.versionhistory), switchMap((res) => res.versionhistory),
getFirstSucceededRemoteDataPayload(), getFirstSucceededRemoteDataPayload(),
) : of(null); ) : EMPTY;
} }
/** /**

View File

@@ -196,6 +196,10 @@ export class VersionHistoryDataService extends DataService<VersionHistory> {
); );
} }
/**
* Get the item of the latest version from any version in the version history
* @param version
*/
getVersionHistoryFromVersion$(version: Version): Observable<VersionHistory> { getVersionHistoryFromVersion$(version: Version): Observable<VersionHistory> {
return this.versionDataService.getHistoryIdFromVersion$(version).pipe( return this.versionDataService.getHistoryIdFromVersion$(version).pipe(
take(1), take(1),
@@ -204,6 +208,10 @@ export class VersionHistoryDataService extends DataService<VersionHistory> {
); );
} }
/**
* Invalidate the cache of the version history
* @param versionHistoryID
*/
invalidateVersionHistoryCache(versionHistoryID: string) { invalidateVersionHistoryCache(versionHistoryID: string) {
this.requestService.setStaleByHrefSubstring('versioning/versionhistories/' + versionHistoryID); this.requestService.setStaleByHrefSubstring('versioning/versionhistories/' + versionHistoryID);
} }

View File

@@ -9,7 +9,7 @@ import { DataService } from '../data/data.service';
import { RequestService } from '../data/request.service'; import { RequestService } from '../data/request.service';
import { WorkflowItem } from './models/workflowitem.model'; import { WorkflowItem } from './models/workflowitem.model';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DeleteByIDRequest } from '../data/request.models'; import { DeleteByIDRequest, FindListOptions } from '../data/request.models';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { ObjectCacheService } from '../cache/object-cache.service'; import { ObjectCacheService } from '../cache/object-cache.service';
import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service'; import { DSOChangeAnalyzer } from '../data/dso-change-analyzer.service';
@@ -19,6 +19,9 @@ import { hasValue } from '../../shared/empty.util';
import { RemoteData } from '../data/remote-data'; import { RemoteData } from '../data/remote-data';
import { NoContent } from '../shared/NoContent.model'; import { NoContent } from '../shared/NoContent.model';
import { getFirstCompletedRemoteData } from '../shared/operators'; import { getFirstCompletedRemoteData } from '../shared/operators';
import { FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { WorkspaceItem } from './models/workspaceitem.model';
import { RequestParam } from '../cache/models/request-param.model';
/** /**
* A service that provides methods to make REST requests with workflow items endpoint. * A service that provides methods to make REST requests with workflow items endpoint.
@@ -27,6 +30,7 @@ import { getFirstCompletedRemoteData } from '../shared/operators';
@dataService(WorkflowItem.type) @dataService(WorkflowItem.type)
export class WorkflowItemDataService extends DataService<WorkflowItem> { export class WorkflowItemDataService extends DataService<WorkflowItem> {
protected linkPath = 'workflowitems'; protected linkPath = 'workflowitems';
protected searchByItemLinkPath = 'item';
protected responseMsToLive = 10 * 1000; protected responseMsToLive = 10 * 1000;
constructor( constructor(
@@ -86,4 +90,23 @@ export class WorkflowItemDataService extends DataService<WorkflowItem> {
return this.rdbService.buildFromRequestUUID(requestId); return this.rdbService.buildFromRequestUUID(requestId);
} }
/**
* Return the WorkflowItem object found through the UUID of an item
*
* @param uuid The uuid of the item
* @param useCachedVersionIfAvailable If this is true, the request will only be sent if there's
* no valid cached version. Defaults to true
* @param reRequestOnStale Whether or not the request should automatically be re-
* requested after the response becomes stale
* @param options The {@link FindListOptions} object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
public findByItem(uuid: string, useCachedVersionIfAvailable = false, reRequestOnStale = true, options: FindListOptions = {}, ...linksToFollow: FollowLinkConfig<WorkspaceItem>[]): Observable<RemoteData<WorkspaceItem>> {
const findListOptions = new FindListOptions();
findListOptions.searchParams = [new RequestParam('uuid', encodeURIComponent(uuid))];
const href$ = this.getSearchByHref(this.searchByItemLinkPath, findListOptions, ...linksToFollow);
return this.findByHref(href$, useCachedVersionIfAvailable, reRequestOnStale, ...linksToFollow);
}
} }

View File

@@ -31,7 +31,7 @@ export class VersionedItemComponent extends ItemComponent {
private versionService: VersionDataService, private versionService: VersionDataService,
private itemVersionShared: ItemVersionsSharedService, private itemVersionShared: ItemVersionsSharedService,
private router: Router, private router: Router,
private workspaceitemDataService: WorkspaceitemDataService, private workspaceItemDataService: WorkspaceitemDataService,
private searchService: SearchService, private searchService: SearchService,
private itemService: ItemDataService, private itemService: ItemDataService,
) { ) {
@@ -62,11 +62,11 @@ export class VersionedItemComponent extends ItemComponent {
getFirstCompletedRemoteData(), getFirstCompletedRemoteData(),
// show success/failure notification // show success/failure notification
tap((res: RemoteData<Version>) => { this.itemVersionShared.notifyCreateNewVersion(res); }), tap((res: RemoteData<Version>) => { this.itemVersionShared.notifyCreateNewVersion(res); }),
getFirstSucceededRemoteDataPayload<Version>(),
// get workspace item // get workspace item
getFirstSucceededRemoteDataPayload<Version>(),
switchMap((newVersion: Version) => this.itemService.findByHref(newVersion._links.item.href)), switchMap((newVersion: Version) => this.itemService.findByHref(newVersion._links.item.href)),
getFirstSucceededRemoteDataPayload<Item>(), getFirstSucceededRemoteDataPayload<Item>(),
switchMap((newVersionItem: Item) => this.workspaceitemDataService.findByItem(newVersionItem.uuid, true, false)), switchMap((newVersionItem: Item) => this.workspaceItemDataService.findByItem(newVersionItem.uuid, true, false)),
getFirstSucceededRemoteDataPayload<WorkspaceItem>(), getFirstSucceededRemoteDataPayload<WorkspaceItem>(),
).subscribe((wsItem) => { ).subscribe((wsItem) => {
const wsiId = wsItem.id; const wsiId = wsItem.id;

View File

@@ -7,6 +7,8 @@ import { AuthService } from '../../../core/auth/auth.service';
import { NotificationsService } from '../../notifications/notifications.service'; import { NotificationsService } from '../../notifications/notifications.service';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { VersionHistoryDataService } from '../../../core/data/version-history-data.service'; import { VersionHistoryDataService } from '../../../core/data/version-history-data.service';
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
describe('ItemVersionsSharedService', () => { describe('ItemVersionsSharedService', () => {
let service: ItemVersionsSharedService; let service: ItemVersionsSharedService;
@@ -20,6 +22,8 @@ describe('ItemVersionsSharedService', () => {
{ provide: AuthService, useValue: {} }, { provide: AuthService, useValue: {} },
{ provide: NotificationsService, useValue: {} }, { provide: NotificationsService, useValue: {} },
{ provide: TranslateService, useValue: {} }, { provide: TranslateService, useValue: {} },
{ provide: WorkspaceitemDataService, useValue: {} },
{ provide: WorkflowItemDataService, useValue: {} },
], ],
}); });
service = TestBed.inject(ItemVersionsSharedService); service = TestBed.inject(ItemVersionsSharedService);

View File

@@ -19,60 +19,47 @@
<th scope="col" *ngIf="(hasEpersons$ | async)">{{"item.version.history.table.editor" | translate}}</th> <th scope="col" *ngIf="(hasEpersons$ | async)">{{"item.version.history.table.editor" | translate}}</th>
<th scope="col">{{"item.version.history.table.date" | translate}}</th> <th scope="col">{{"item.version.history.table.date" | translate}}</th>
<th scope="col">{{"item.version.history.table.summary" | translate}}</th> <th scope="col">{{"item.version.history.table.summary" | translate}}</th>
<th scope="col" *ngIf="displayActions">{{"item.version.history.table.actions" | translate}}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr *ngFor="let version of versions?.page" [id]="'version-row-' + version.id"> <tr *ngFor="let version of versions?.page" [id]="'version-row-' + version.id">
<td class="version-row-element-version"> <td class="version-row-element-version">
<div> <!-- Get the ID of the workspace/workflow item (`undefined` if they don't exist).
Conditionals inside *ngVar are needed in order to avoid useless calls. -->
<ng-container *ngVar="((hasDraftVersion$ | async) ? getWorkspaceId(version?.item) : undefined) as workspaceId$">
<ng-container *ngVar=" ((workspaceId$ | async) ? undefined : getWorkflowId(version?.item)) as workflowId$">
<div class="left-column"> <div class="left-column">
<span *ngIf="(workspaceId$ | async) || (workflowId$ | async); then versionNumberWithoutLink else versionNumberWithLink"></span>
<ng-template #versionNumberWithLink>
<a [routerLink]="getVersionRoute(version.id)">{{version.version}}</a> <a [routerLink]="getVersionRoute(version.id)">{{version.version}}</a>
<span *ngIf="version?.id === itemVersion?.id">*</span>
</div>
<div class="right-column">
<ng-container *ngVar="getDraftId(version?.item) as draftId$">
<button class="btn btn-outline-primary btn-sm version-row-element-edit" *ngIf="draftId$ | async"
(click)="editWorkspaceItem(draftId$)">
<i class="fas fa-pencil-alt fa-fw"></i> {{ "item.version.history.table.workspaceItem" | translate }}
</button>
</ng-container>
</div>
</div>
</td>
<td *ngIf="(hasEpersons$ | async)" class="version-row-element-editor">
<span *ngVar="(version?.eperson | async)?.payload as eperson">
<a *ngIf="eperson" [href]="'mailto:' + eperson?.email">{{eperson?.name}}</a>
</span>
</td>
<td class="version-row-element-date">
{{version?.created | date : 'yyyy-MM-dd HH:mm:ss'}}
</td>
<td class="version-row-element-summary">
<ng-container *ngIf="isThisBeingEdited(version); then editSummary else showSummary"></ng-container>
<ng-template #showSummary>{{version?.summary}}</ng-template>
<ng-template #editSummary>
<input class="form-control" type="text" [(ngModel)]="versionBeingEditedSummary" (keyup.enter)="onSummarySubmit()"/>
</ng-template> </ng-template>
</td> <ng-template #versionNumberWithoutLink>
<td class="version-row-element-actions" *ngIf="displayActions"> {{version.version}}
<div class="btn-group edit-field"> </ng-template>
<!--EDIT / SAVE--> <span *ngIf="version?.id === itemVersion?.id">*</span>
<ng-container *ngIf="canEditVersion$(version) | async">
<span *ngIf="workspaceId$ | async" class="text-light badge badge-primary ml-3">
{{ "item.version.history.table.workspaceItem" | translate }}
</span>
<span *ngIf="workflowId$ | async" class="text-light badge badge-info ml-3">
{{ "item.version.history.table.workflowItem" | translate }}
</span>
</div>
<div class="right-column">
<div class="btn-group edit-field" *ngIf="displayActions">
<!--EDIT WORKSPACE ITEM-->
<button class="btn btn-outline-primary btn-sm version-row-element-edit" <button class="btn btn-outline-primary btn-sm version-row-element-edit"
*ngIf="!isThisBeingEdited(version)" *ngIf="workspaceId$ | async"
[disabled]="isAnyBeingEdited()" (click)="editWorkspaceItem(workspaceId$)"
(click)="enableVersionEditing(version)" title="{{'item.version.history.table.action.editWorkspaceItem' | translate }}">
title="{{'item.version.history.table.action.editSummary' | translate}}"> <i class="fas fa-pencil-alt fa-fw"></i>
<i class="fas fa-edit fa-fw"></i>
</button> </button>
<button class="btn btn-outline-success btn-sm"
*ngIf="isThisBeingEdited(version)"
(click)="onSummarySubmit()"
title="{{'item.version.history.table.action.saveSummary' | translate}}">
<i class="fas fa-check fa-fw"></i>
</button>
</ng-container>
<!--CREATE--> <!--CREATE-->
<ng-container *ngIf="canCreateVersion$ | async"> <ng-container *ngIf="canCreateVersion$ | async">
<button class="btn btn-outline-primary btn-sm version-row-element-create" <button class="btn btn-outline-primary btn-sm version-row-element-create"
@@ -92,17 +79,60 @@
<i class="fas fa-trash fa-fw"></i> <i class="fas fa-trash fa-fw"></i>
</button> </button>
</ng-container> </ng-container>
</div>
</div>
</ng-container>
</ng-container>
</td>
<td *ngIf="(hasEpersons$ | async)" class="version-row-element-editor">
<span *ngVar="(version?.eperson | async)?.payload as eperson">
<a *ngIf="eperson" [href]="'mailto:' + eperson?.email">{{eperson?.name}}</a>
</span>
</td>
<td class="version-row-element-date">
{{version?.created | date : 'yyyy-MM-dd HH:mm:ss'}}
</td>
<td class="version-row-element-summary">
<div class="float-left">
<ng-container *ngIf="isThisBeingEdited(version); then editSummary else showSummary"></ng-container>
<ng-template #showSummary>{{version?.summary}}</ng-template>
<ng-template #editSummary>
<input class="form-control" type="text" [(ngModel)]="versionBeingEditedSummary"
(keyup.enter)="onSummarySubmit()"/>
</ng-template>
</div>
<div class="float-right btn-group edit-field" *ngIf="displayActions">
<!--DISCARD EDIT --> <!--DISCARD EDIT -->
<ng-container *ngIf="canEditVersion$(version) | async"> <ng-container *ngIf="(canEditVersion$(version) | async) && isThisBeingEdited(version)">
<button class="btn btn-sm" <button class="btn btn-sm"
[ngClass]="isThisBeingEdited(version) ? 'btn-outline-warning' : 'btn-outline-primary'" [ngClass]="isThisBeingEdited(version) ? 'btn-outline-warning' : 'btn-outline-primary'"
[disabled]="!isAnyBeingEdited()"
(click)="disableSummaryEditing()" (click)="disableSummaryEditing()"
title="{{'item.version.history.table.action.discardSummary' | translate}}"> title="{{'item.version.history.table.action.discardSummary' | translate}}">
<i class="fas fa-undo-alt fa-fw"></i> <i class="fas fa-undo-alt fa-fw"></i>
</button> </button>
</ng-container> </ng-container>
<!--EDIT / SAVE-->
<ng-container *ngIf="canEditVersion$(version) | async">
<button class="btn btn-outline-primary btn-sm version-row-element-edit"
*ngIf="!isThisBeingEdited(version)"
[disabled]="isAnyBeingEdited()"
(click)="enableVersionEditing(version)"
title="{{'item.version.history.table.action.editSummary' | translate}}">
<i class="fas fa-edit fa-fw"></i>
</button>
<button class="btn btn-outline-success btn-sm"
*ngIf="isThisBeingEdited(version)"
(click)="onSummarySubmit()"
title="{{'item.version.history.table.action.saveSummary' | translate}}">
<i class="fas fa-check fa-fw"></i>
</button>
</ng-container>
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@@ -22,6 +22,8 @@ import { NotificationsService } from '../../notifications/notifications.service'
import { NotificationsServiceStub } from '../../testing/notifications-service.stub'; import { NotificationsServiceStub } from '../../testing/notifications-service.stub';
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
describe('ItemVersionsComponent', () => { describe('ItemVersionsComponent', () => {
let component: ItemVersionsComponent; let component: ItemVersionsComponent;
@@ -29,9 +31,12 @@ describe('ItemVersionsComponent', () => {
let authenticationService: AuthService; let authenticationService: AuthService;
let authorizationService: AuthorizationDataService; let authorizationService: AuthorizationDataService;
let versionHistoryService: VersionHistoryDataService; let versionHistoryService: VersionHistoryDataService;
let workspaceItemDataService: WorkspaceitemDataService;
let workflowItemDataService: WorkflowItemDataService;
const versionHistory = Object.assign(new VersionHistory(), { const versionHistory = Object.assign(new VersionHistory(), {
id: '1' id: '1',
draftVersion: false,
}); });
const version1 = Object.assign(new Version(), { const version1 = Object.assign(new Version(), {
@@ -86,7 +91,7 @@ describe('ItemVersionsComponent', () => {
version2.item = createSuccessfulRemoteDataObject$(item2); version2.item = createSuccessfulRemoteDataObject$(item2);
const versionHistoryServiceSpy = jasmine.createSpyObj('versionHistoryService', { const versionHistoryServiceSpy = jasmine.createSpyObj('versionHistoryService', {
getVersions: createSuccessfulRemoteDataObject$(createPaginatedList(versions)) getVersions: createSuccessfulRemoteDataObject$(createPaginatedList(versions)),
}); });
const authenticationServiceSpy = jasmine.createSpyObj('authenticationService', { const authenticationServiceSpy = jasmine.createSpyObj('authenticationService', {
isAuthenticated: observableOf(true), isAuthenticated: observableOf(true),
@@ -94,6 +99,12 @@ describe('ItemVersionsComponent', () => {
} }
); );
const authorizationServiceSpy = jasmine.createSpyObj('authorizationService', ['isAuthorized']); const authorizationServiceSpy = jasmine.createSpyObj('authorizationService', ['isAuthorized']);
const workspaceItemDataServiceSpy = jasmine.createSpyObj('workspaceItemDataService', {
findByItem: of(undefined),
});
const workflowItemDataServiceSpy = jasmine.createSpyObj('workflowItemDataService', {
findByItem: of(undefined),
});
beforeEach(waitForAsync(() => { beforeEach(waitForAsync(() => {
@@ -110,6 +121,8 @@ describe('ItemVersionsComponent', () => {
{provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy}, {provide: VersionHistoryDataService, useValue: versionHistoryServiceSpy},
{provide: ItemDataService, useValue: {}}, {provide: ItemDataService, useValue: {}},
{provide: VersionDataService, useValue: {}}, {provide: VersionDataService, useValue: {}},
{provide: WorkspaceitemDataService, useValue: workspaceItemDataServiceSpy},
{provide: WorkflowItemDataService, useValue: workflowItemDataServiceSpy},
], ],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}).compileComponents(); }).compileComponents();
@@ -117,6 +130,8 @@ describe('ItemVersionsComponent', () => {
versionHistoryService = TestBed.inject(VersionHistoryDataService); versionHistoryService = TestBed.inject(VersionHistoryDataService);
authenticationService = TestBed.inject(AuthService); authenticationService = TestBed.inject(AuthService);
authorizationService = TestBed.inject(AuthorizationDataService); authorizationService = TestBed.inject(AuthorizationDataService);
workspaceItemDataService = TestBed.inject(WorkspaceitemDataService);
workflowItemDataService = TestBed.inject(WorkflowItemDataService);
})); }));

View File

@@ -8,7 +8,7 @@ import {
combineLatest as observableCombineLatest, combineLatest as observableCombineLatest,
Observable, Observable,
of, of,
Subscription Subscription,
} from 'rxjs'; } from 'rxjs';
import { VersionHistory } from '../../../core/shared/version-history.model'; import { VersionHistory } from '../../../core/shared/version-history.model';
import { import {
@@ -47,6 +47,7 @@ import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { ItemVersionsSharedService } from './item-versions-shared.service'; import { ItemVersionsSharedService } from './item-versions-shared.service';
import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model'; import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.model';
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service'; import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem-data.service';
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-data.service';
@Component({ @Component({
selector: 'ds-item-versions', selector: 'ds-item-versions',
@@ -173,6 +174,7 @@ export class ItemVersionsComponent implements OnInit {
private itemVersionShared: ItemVersionsSharedService, private itemVersionShared: ItemVersionsSharedService,
private authorizationService: AuthorizationDataService, private authorizationService: AuthorizationDataService,
private workspaceItemDataService: WorkspaceitemDataService, private workspaceItemDataService: WorkspaceitemDataService,
private workflowItemDataService: WorkflowItemDataService,
) { ) {
} }
@@ -333,19 +335,31 @@ export class ItemVersionsComponent implements OnInit {
of(summary), of(summary),
version.item.pipe(getFirstSucceededRemoteDataPayload()) version.item.pipe(getFirstSucceededRemoteDataPayload())
])), ])),
mergeMap(([summary, item]: [string, Item]) => this.itemVersionShared.createNewVersionAndNotify(item, summary)), mergeMap(([summary, item]: [string, Item]) => this.versionHistoryService.createVersion(item._links.self.href, summary)),
map((newVersionRD: RemoteData<Version>) => { // show success/failure notification
tap((newVersionRD: RemoteData<Version>) => {
this.itemVersionShared.notifyCreateNewVersion(newVersionRD);
if (newVersionRD.hasSucceeded) { if (newVersionRD.hasSucceeded) {
const versionHistory$ = this.versionService.getHistoryFromVersion$(version).pipe( const versionHistory$ = this.versionService.getHistoryFromVersion$(version).pipe(
tap((res: VersionHistory) => { tap((versionHistory: VersionHistory) => {
this.versionHistoryService.invalidateVersionHistoryCache(res.id); this.itemService.invalidateItemCache(this.item.uuid);
this.versionHistoryService.invalidateVersionHistoryCache(versionHistory.id);
}), }),
); );
this.getAllVersions(versionHistory$); this.getAllVersions(versionHistory$);
} }
}), }),
take(1), // get workspace item
).subscribe(); getFirstSucceededRemoteDataPayload<Version>(),
switchMap((newVersion: Version) => this.itemService.findByHref(newVersion._links.item.href)),
getFirstSucceededRemoteDataPayload<Item>(),
switchMap((newVersionItem: Item) => this.workspaceItemDataService.findByItem(newVersionItem.uuid, true, false)),
getFirstSucceededRemoteDataPayload<WorkspaceItem>(),
).subscribe((wsItem) => {
const wsiId = wsItem.id;
const route = 'workspaceitems/' + wsiId + '/edit';
this.router.navigateByUrl(route);
});
} }
/** /**
@@ -386,7 +400,7 @@ export class ItemVersionsComponent implements OnInit {
* Get the ID of the workspace item, if present, otherwise return undefined * Get the ID of the workspace item, if present, otherwise return undefined
* @param versionItem the item for which retrieve the workspace item id * @param versionItem the item for which retrieve the workspace item id
*/ */
getDraftId(versionItem): Observable<string> { getWorkspaceId(versionItem): Observable<string> {
return versionItem.pipe( return versionItem.pipe(
getFirstSucceededRemoteDataPayload(), getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid), map((item: Item) => item.uuid),
@@ -396,6 +410,20 @@ export class ItemVersionsComponent implements OnInit {
); );
} }
/**
* 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<string> {
return versionItem.pipe(
getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid),
switchMap((itemUuid: string) => this.workflowItemDataService.findByItem(itemUuid, true)),
getFirstCompletedRemoteData<WorkspaceItem>(),
map((res: RemoteData<WorkspaceItem>) => res?.payload?.id ),
);
}
/** /**
* redirect to the edit page of the workspace item * redirect to the edit page of the workspace item
* @param id$ the id of the workspace item * @param id$ the id of the workspace item

View File

@@ -1983,8 +1983,11 @@
"item.version.history.table.workspaceItem": "Workspace item", "item.version.history.table.workspaceItem": "Workspace item",
"item.version.history.table.workflowItem": "Workflow item",
"item.version.history.table.actions": "Action", "item.version.history.table.actions": "Action",
"item.version.history.table.action.editWorkspaceItem": "Edit workspace item",
"item.version.history.table.action.editSummary": "Edit summary", "item.version.history.table.action.editSummary": "Edit summary",