mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
[CST-4499] Version history - Changes to version history table
This commit is contained in:
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -19,26 +19,72 @@
|
|||||||
<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).
|
||||||
<div class="left-column">
|
Conditionals inside *ngVar are needed in order to avoid useless calls. -->
|
||||||
<a [routerLink]="getVersionRoute(version.id)">{{version.version}}</a>
|
<ng-container *ngVar="((hasDraftVersion$ | async) ? getWorkspaceId(version?.item) : undefined) as workspaceId$">
|
||||||
<span *ngIf="version?.id === itemVersion?.id">*</span>
|
<ng-container *ngVar=" ((workspaceId$ | async) ? undefined : getWorkflowId(version?.item)) as workflowId$">
|
||||||
</div>
|
|
||||||
<div class="right-column">
|
<div class="left-column">
|
||||||
<ng-container *ngVar="getDraftId(version?.item) as draftId$">
|
|
||||||
<button class="btn btn-outline-primary btn-sm version-row-element-edit" *ngIf="draftId$ | async"
|
<span *ngIf="(workspaceId$ | async) || (workflowId$ | async); then versionNumberWithoutLink else versionNumberWithLink"></span>
|
||||||
(click)="editWorkspaceItem(draftId$)">
|
<ng-template #versionNumberWithLink>
|
||||||
<i class="fas fa-pencil-alt fa-fw"></i> {{ "item.version.history.table.workspaceItem" | translate }}
|
<a [routerLink]="getVersionRoute(version.id)">{{version.version}}</a>
|
||||||
</button>
|
</ng-template>
|
||||||
</ng-container>
|
<ng-template #versionNumberWithoutLink>
|
||||||
</div>
|
{{version.version}}
|
||||||
</div>
|
</ng-template>
|
||||||
|
<span *ngIf="version?.id === itemVersion?.id">*</span>
|
||||||
|
|
||||||
|
<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"
|
||||||
|
*ngIf="workspaceId$ | async"
|
||||||
|
(click)="editWorkspaceItem(workspaceId$)"
|
||||||
|
title="{{'item.version.history.table.action.editWorkspaceItem' | translate }}">
|
||||||
|
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
<!--CREATE-->
|
||||||
|
<ng-container *ngIf="canCreateVersion$ | async">
|
||||||
|
<button class="btn btn-outline-primary btn-sm version-row-element-create"
|
||||||
|
[disabled]="isAnyBeingEdited() || (hasDraftVersion$ | async)"
|
||||||
|
(click)="createNewVersion(version)"
|
||||||
|
title="{{createVersionTitle$ | async | translate }}">
|
||||||
|
<i class="fas fa-code-branch fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
<!--DELETE-->
|
||||||
|
<ng-container *ngIf="canDeleteVersion$(version) | async">
|
||||||
|
<button class="btn btn-sm version-row-element-delete"
|
||||||
|
[ngClass]="isAnyBeingEdited() ? 'btn-outline-primary' : 'btn-outline-danger'"
|
||||||
|
[disabled]="isAnyBeingEdited()"
|
||||||
|
(click)="deleteVersion(version, version.id==itemVersion.id)"
|
||||||
|
title="{{'item.version.history.table.action.deleteVersion' | translate}}">
|
||||||
|
<i class="fas fa-trash fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ng-container>
|
||||||
|
</ng-container>
|
||||||
</td>
|
</td>
|
||||||
<td *ngIf="(hasEpersons$ | async)" class="version-row-element-editor">
|
<td *ngIf="(hasEpersons$ | async)" class="version-row-element-editor">
|
||||||
<span *ngVar="(version?.eperson | async)?.payload as eperson">
|
<span *ngVar="(version?.eperson | async)?.payload as eperson">
|
||||||
@@ -49,14 +95,25 @@
|
|||||||
{{version?.created | date : 'yyyy-MM-dd HH:mm:ss'}}
|
{{version?.created | date : 'yyyy-MM-dd HH:mm:ss'}}
|
||||||
</td>
|
</td>
|
||||||
<td class="version-row-element-summary">
|
<td class="version-row-element-summary">
|
||||||
<ng-container *ngIf="isThisBeingEdited(version); then editSummary else showSummary"></ng-container>
|
<div class="float-left">
|
||||||
<ng-template #showSummary>{{version?.summary}}</ng-template>
|
<ng-container *ngIf="isThisBeingEdited(version); then editSummary else showSummary"></ng-container>
|
||||||
<ng-template #editSummary>
|
<ng-template #showSummary>{{version?.summary}}</ng-template>
|
||||||
<input class="form-control" type="text" [(ngModel)]="versionBeingEditedSummary" (keyup.enter)="onSummarySubmit()"/>
|
<ng-template #editSummary>
|
||||||
</ng-template>
|
<input class="form-control" type="text" [(ngModel)]="versionBeingEditedSummary"
|
||||||
</td>
|
(keyup.enter)="onSummarySubmit()"/>
|
||||||
<td class="version-row-element-actions" *ngIf="displayActions">
|
</ng-template>
|
||||||
<div class="btn-group edit-field">
|
</div>
|
||||||
|
|
||||||
|
<div class="float-right btn-group edit-field" *ngIf="displayActions">
|
||||||
|
<!--DISCARD EDIT -->
|
||||||
|
<ng-container *ngIf="(canEditVersion$(version) | async) && isThisBeingEdited(version)">
|
||||||
|
<button class="btn btn-sm"
|
||||||
|
[ngClass]="isThisBeingEdited(version) ? 'btn-outline-warning' : 'btn-outline-primary'"
|
||||||
|
(click)="disableSummaryEditing()"
|
||||||
|
title="{{'item.version.history.table.action.discardSummary' | translate}}">
|
||||||
|
<i class="fas fa-undo-alt fa-fw"></i>
|
||||||
|
</button>
|
||||||
|
</ng-container>
|
||||||
<!--EDIT / SAVE-->
|
<!--EDIT / SAVE-->
|
||||||
<ng-container *ngIf="canEditVersion$(version) | async">
|
<ng-container *ngIf="canEditVersion$(version) | async">
|
||||||
<button class="btn btn-outline-primary btn-sm version-row-element-edit"
|
<button class="btn btn-outline-primary btn-sm version-row-element-edit"
|
||||||
@@ -73,36 +130,9 @@
|
|||||||
<i class="fas fa-check fa-fw"></i>
|
<i class="fas fa-check fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<!--CREATE-->
|
|
||||||
<ng-container *ngIf="canCreateVersion$ | async">
|
|
||||||
<button class="btn btn-outline-primary btn-sm version-row-element-create"
|
|
||||||
[disabled]="isAnyBeingEdited() || (hasDraftVersion$ | async)"
|
|
||||||
(click)="createNewVersion(version)"
|
|
||||||
title="{{createVersionTitle$ | async | translate }}">
|
|
||||||
<i class="fas fa-code-branch fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
|
||||||
<!--DELETE-->
|
|
||||||
<ng-container *ngIf="canDeleteVersion$(version) | async">
|
|
||||||
<button class="btn btn-sm version-row-element-delete"
|
|
||||||
[ngClass]="isAnyBeingEdited() ? 'btn-outline-primary' : 'btn-outline-danger'"
|
|
||||||
[disabled]="isAnyBeingEdited()"
|
|
||||||
(click)="deleteVersion(version, version.id==itemVersion.id)"
|
|
||||||
title="{{'item.version.history.table.action.deleteVersion' | translate}}">
|
|
||||||
<i class="fas fa-trash fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
|
||||||
<!--DISCARD EDIT -->
|
|
||||||
<ng-container *ngIf="canEditVersion$(version) | async">
|
|
||||||
<button class="btn btn-sm"
|
|
||||||
[ngClass]="isThisBeingEdited(version) ? 'btn-outline-warning' : 'btn-outline-primary'"
|
|
||||||
[disabled]="!isAnyBeingEdited()"
|
|
||||||
(click)="disableSummaryEditing()"
|
|
||||||
title="{{'item.version.history.table.action.discardSummary' | translate}}">
|
|
||||||
<i class="fas fa-undo-alt fa-fw"></i>
|
|
||||||
</button>
|
|
||||||
</ng-container>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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",
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user