"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/app/shared/item/item-versions/item-versions.component.ts" between
dspace-angular-dspace-7.0.tar.gz and dspace-angular-dspace-7.1.tar.gz

About: dspace-angular is the Angular-based frontend of DSpace, a digital repository system to capture, store, index, preserve and redistribute an organization’s research material in digital formats.

item-versions.component.ts  (dspace-angular-dspace-7.0):item-versions.component.ts  (dspace-angular-dspace-7.1)
import { Component, Input, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { Item } from '../../../core/shared/item.model'; import { Item } from '../../../core/shared/item.model';
import { Version } from '../../../core/shared/version.model'; import { Version } from '../../../core/shared/version.model';
import { RemoteData } from '../../../core/data/remote-data'; import { RemoteData } from '../../../core/data/remote-data';
import { BehaviorSubject, combineLatest as observableCombineLatest, Observable } import {
from 'rxjs'; BehaviorSubject,
combineLatest,
combineLatest as observableCombineLatest,
Observable,
of,
Subscription,
} from 'rxjs';
import { VersionHistory } from '../../../core/shared/version-history.model'; import { VersionHistory } from '../../../core/shared/version-history.model';
import { import {
getAllSucceededRemoteData, getAllSucceededRemoteData,
getAllSucceededRemoteDataPayload, getAllSucceededRemoteDataPayload,
getFirstCompletedRemoteData,
getFirstSucceededRemoteData,
getFirstSucceededRemoteDataPayload,
getRemoteDataPayload getRemoteDataPayload
} from '../../../core/shared/operators'; } from '../../../core/shared/operators';
import { map, startWith, switchMap } from 'rxjs/operators'; import { map, mergeMap, startWith, switchMap, take, tap } from 'rxjs/operators';
import { PaginatedList } from '../../../core/data/paginated-list.model'; import { PaginatedList } from '../../../core/data/paginated-list.model';
import { PaginationComponentOptions } from '../../pagination/pagination-componen t-options.model'; import { PaginationComponentOptions } from '../../pagination/pagination-componen t-options.model';
import { VersionHistoryDataService } from '../../../core/data/version-history-da ta.service'; import { VersionHistoryDataService } from '../../../core/data/version-history-da ta.service';
import { PaginatedSearchOptions } from '../../search/paginated-search-options.mo del'; import { PaginatedSearchOptions } from '../../search/paginated-search-options.mo del';
import { AlertType } from '../../alert/aletr-type'; import { AlertType } from '../../alert/aletr-type';
import { followLink } from '../../utils/follow-link-config.model'; import { followLink } from '../../utils/follow-link-config.model';
import { hasValue, hasValueOperator } from '../../empty.util'; import { hasValue, hasValueOperator } from '../../empty.util';
import { PaginationService } from '../../../core/pagination/pagination.service'; import { PaginationService } from '../../../core/pagination/pagination.service';
import { getItemPageRoute } from '../../../item-page/item-page-routing-paths'; import {
getItemEditVersionhistoryRoute,
getItemPageRoute,
getItemVersionRoute
} from '../../../item-page/item-page-routing-paths';
import { FormBuilder } from '@angular/forms';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ItemVersionsSummaryModalComponent } from './item-versions-summary-modal
/item-versions-summary-modal.component';
import { NotificationsService } from '../../notifications/notifications.service'
;
import { TranslateService } from '@ngx-translate/core';
import { ItemVersionsDeleteModalComponent } from './item-versions-delete-modal/i
tem-versions-delete-modal.component';
import { VersionDataService } from '../../../core/data/version-data.service';
import { ItemDataService } from '../../../core/data/item-data.service';
import { Router } from '@angular/router';
import { AuthorizationDataService } from '../../../core/data/feature-authorizati
on/authorization-data.service';
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
import { ItemVersionsSharedService } from './item-versions-shared.service';
import { WorkspaceItem } from '../../../core/submission/models/workspaceitem.mod
el';
import { WorkspaceitemDataService } from '../../../core/submission/workspaceitem
-data.service';
import { WorkflowItemDataService } from '../../../core/submission/workflowitem-d
ata.service';
@Component({ @Component({
selector: 'ds-item-versions', selector: 'ds-item-versions',
templateUrl: './item-versions.component.html' templateUrl: './item-versions.component.html',
styleUrls: ['./item-versions.component.scss']
}) })
/** /**
* Component listing all available versions of the history the provided item is a part of * Component listing all available versions of the history the provided item is a part of
*/ */
export class ItemVersionsComponent implements OnInit { export class ItemVersionsComponent implements OnInit {
/** /**
* The item to display a version history for * The item to display a version history for
*/ */
@Input() item: Item; @Input() item: Item;
/** /**
* An option to display the list of versions, even when there aren't any. * An option to display the list of versions, even when there aren't any.
* Instead of the table, an alert will be displayed, notifying the user there are no other versions present * Instead of the table, an alert will be displayed, notifying the user there are no other versions present
* for the current item. * for the current item.
*/ */
@Input() displayWhenEmpty = false; @Input() displayWhenEmpty = false;
/** /**
* Whether or not to display the title * Whether or not to display the title
*/ */
@Input() displayTitle = true; @Input() displayTitle = true;
/** /**
* Whether or not to display the action buttons (delete/create/edit version)
*/
@Input() displayActions: boolean;
/**
* Array of active subscriptions
*/
subs: Subscription[] = [];
/**
* The AlertType enumeration * The AlertType enumeration
* @type {AlertType} * @type {AlertType}
*/ */
AlertTypeEnum = AlertType; AlertTypeEnum = AlertType;
/** /**
* The item's version * The item's version
*/ */
versionRD$: Observable<RemoteData<Version>>; versionRD$: Observable<RemoteData<Version>>;
/** /**
* The item's full version history * The item's full version history (remote data)
*/ */
versionHistoryRD$: Observable<RemoteData<VersionHistory>>; versionHistoryRD$: Observable<RemoteData<VersionHistory>>;
/** /**
* The item's full version history
*/
versionHistory$: Observable<VersionHistory>;
/**
* The version history's list of versions * The version history's list of versions
*/ */
versionsRD$: Observable<RemoteData<PaginatedList<Version>>>; versionsRD$: BehaviorSubject<RemoteData<PaginatedList<Version>>> = new Behavio rSubject<RemoteData<PaginatedList<Version>>>(null);
/** /**
* Verify if the list of versions has at least one e-person to display * Verify if the list of versions has at least one e-person to display
* Used to hide the "Editor" column when no e-persons are present to display * Used to hide the "Editor" column when no e-persons are present to display
*/ */
hasEpersons$: Observable<boolean>; hasEpersons$: Observable<boolean>;
/** /**
* Verify if there is an inprogress submission in the version history
* Used to disable the "Create version" button
*/
hasDraftVersion$: Observable<boolean>;
/**
* The amount of versions to display per page * The amount of versions to display per page
*/ */
pageSize = 10; pageSize = 10;
/** /**
* The page options to use for fetching the versions * The page options to use for fetching the versions
* Start at page 1 and always use the set page size * Start at page 1 and always use the set page size
*/ */
options = Object.assign(new PaginationComponentOptions(),{ options = Object.assign(new PaginationComponentOptions(), {
id: 'ivo', id: 'ivo',
currentPage: 1, currentPage: 1,
pageSize: this.pageSize pageSize: this.pageSize
}); });
/** /**
* The current page being displayed
*/
currentPage$ = new BehaviorSubject<number>(1);
/**
* The routes to the versions their item pages * The routes to the versions their item pages
* Key: Item ID * Key: Item ID
* Value: Route to item page * Value: Route to item page
*/ */
itemPageRoutes$: Observable<{ itemPageRoutes$: Observable<{
[itemId: string]: string [itemId: string]: string
}>; }>;
/**
* The number of the version whose summary is currently being edited
*/
versionBeingEditedNumber: number;
/**
* The id of the version whose summary is currently being edited
*/
versionBeingEditedId: string;
/**
* The summary currently being edited
*/
versionBeingEditedSummary: string;
canCreateVersion$: Observable<boolean>;
createVersionTitle$: Observable<string>;
constructor(private versionHistoryService: VersionHistoryDataService, constructor(private versionHistoryService: VersionHistoryDataService,
private paginationService: PaginationService private versionService: VersionDataService,
) { private itemService: ItemDataService,
private paginationService: PaginationService,
private formBuilder: FormBuilder,
private modalService: NgbModal,
private notificationsService: NotificationsService,
private translateService: TranslateService,
private router: Router,
private itemVersionShared: ItemVersionsSharedService,
private authorizationService: AuthorizationDataService,
private workspaceItemDataService: WorkspaceitemDataService,
private workflowItemDataService: WorkflowItemDataService,
) {
}
/**
* True when a version is being edited
* (used to disable buttons for other versions)
*/
isAnyBeingEdited(): boolean {
return this.versionBeingEditedNumber != null;
}
/**
* True if the specified version is being edited
* (used to show input field and to change buttons for specified version)
*/
isThisBeingEdited(version: Version): boolean {
return version?.version === this.versionBeingEditedNumber;
}
/**
* Enables editing for the specified version
*/
enableVersionEditing(version: Version): void {
this.versionBeingEditedSummary = version?.summary;
this.versionBeingEditedNumber = version?.version;
this.versionBeingEditedId = version?.id;
}
/**
* Disables editing for the specified version and discards all pending changes
*/
disableVersionEditing(): void {
this.versionBeingEditedSummary = undefined;
this.versionBeingEditedNumber = undefined;
this.versionBeingEditedId = undefined;
}
/**
* Get the route to the specified version
* @param versionId the ID of the version for which the route will be retrieve
d
*/
getVersionRoute(versionId: string) {
return getItemVersionRoute(versionId);
}
/**
* Applies changes to version currently being edited
*/
onSummarySubmit() {
const successMessageKey = 'item.version.edit.notification.success';
const failureMessageKey = 'item.version.edit.notification.failure';
this.versionService.findById(this.versionBeingEditedId).pipe(
getFirstSucceededRemoteData(),
switchMap((findRes: RemoteData<Version>) => {
const payload = findRes.payload;
const summary = {summary: this.versionBeingEditedSummary,};
const updatedVersion = Object.assign({}, payload, summary);
return this.versionService.update(updatedVersion).pipe(getFirstCompleted
RemoteData<Version>());
}),
).subscribe((updatedVersionRD: RemoteData<Version>) => {
if (updatedVersionRD.hasSucceeded) {
this.notificationsService.success(null, this.translateService.get(succ
essMessageKey, {'version': this.versionBeingEditedNumber}));
this.getAllVersions(this.versionHistory$);
} else {
this.notificationsService.warning(null, this.translateService.get(fail
ureMessageKey, {'version': this.versionBeingEditedNumber}));
}
this.disableVersionEditing();
}
);
}
/**
* Delete the item and get the result of the operation
* @param item
*/
deleteItemAndGetResult$(item: Item): Observable<boolean> {
return this.itemService.delete(item.id).pipe(
getFirstCompletedRemoteData(),
map((deleteItemRes) => deleteItemRes.hasSucceeded),
take(1),
);
}
/**
* Deletes the specified version, notify the success/failure and redirect to l
atest version
* @param version the version to be deleted
* @param redirectToLatest force the redirect to the latest version in the his
tory
*/
deleteVersion(version: Version, redirectToLatest: boolean): void {
const successMessageKey = 'item.version.delete.notification.success';
const failureMessageKey = 'item.version.delete.notification.failure';
const versionNumber = version.version;
const versionItem$ = version.item;
// Open modal
const activeModal = this.modalService.open(ItemVersionsDeleteModalComponent)
;
activeModal.componentInstance.versionNumber = version.version;
activeModal.componentInstance.firstVersion = false;
// On modal submit/dismiss
activeModal.result.then(() => {
versionItem$.pipe(
getFirstSucceededRemoteDataPayload<Item>(),
// Retrieve version history and invalidate cache
mergeMap((item: Item) => combineLatest([
of(item),
this.versionHistoryService.getVersionHistoryFromVersion$(version).pipe
(
tap((versionHistory: VersionHistory) => {
this.versionHistoryService.invalidateVersionHistoryCache(versionHi
story.id);
})
)
])),
// Delete item
mergeMap(([item, versionHistory]: [Item, VersionHistory]) => combineLate
st([
this.deleteItemAndGetResult$(item),
of(versionHistory)
])),
// Retrieve new latest version
mergeMap(([deleteItemResult, versionHistory]: [boolean, VersionHistory])
=> combineLatest([
of(deleteItemResult),
this.versionHistoryService.getLatestVersionItemFromHistory$(versionHis
tory).pipe(
tap(() => {
this.getAllVersions(of(versionHistory));
}),
)
])),
).subscribe(([deleteHasSucceeded, newLatestVersionItem]: [boolean, Item])
=> {
// Notify operation result and redirect to latest item
if (deleteHasSucceeded) {
this.notificationsService.success(null, this.translateService.get(succ
essMessageKey, {'version': versionNumber}));
} else {
this.notificationsService.error(null, this.translateService.get(failur
eMessageKey, {'version': versionNumber}));
}
if (redirectToLatest) {
const path = getItemEditVersionhistoryRoute(newLatestVersionItem);
this.router.navigateByUrl(path);
}
});
});
}
/**
* Creates a new version starting from the specified one
* @param version the version from which a new one will be created
*/
createNewVersion(version: Version) {
const versionNumber = version.version;
// Open modal and set current version number
const activeModal = this.modalService.open(ItemVersionsSummaryModalComponent
);
activeModal.componentInstance.versionNumber = versionNumber;
// On createVersionEvent emitted create new version and notify
activeModal.componentInstance.createVersionEvent.pipe(
mergeMap((summary: string) => combineLatest([
of(summary),
version.item.pipe(getFirstSucceededRemoteDataPayload())
])),
mergeMap(([summary, item]: [string, Item]) => this.versionHistoryService.c
reateVersion(item._links.self.href, summary)),
// show success/failure notification
tap((newVersionRD: RemoteData<Version>) => {
this.itemVersionShared.notifyCreateNewVersion(newVersionRD);
if (newVersionRD.hasSucceeded) {
const versionHistory$ = this.versionService.getHistoryFromVersion(vers
ion).pipe(
tap((versionHistory: VersionHistory) => {
this.itemService.invalidateItemCache(this.item.uuid);
this.versionHistoryService.invalidateVersionHistoryCache(versionHi
story.id);
}),
);
this.getAllVersions(versionHistory$);
}
}),
// get workspace item
getFirstSucceededRemoteDataPayload<Version>(),
switchMap((newVersion: Version) => this.itemService.findByHref(newVersion.
_links.item.href)),
getFirstSucceededRemoteDataPayload<Item>(),
switchMap((newVersionItem: Item) => this.workspaceItemDataService.findByIt
em(newVersionItem.uuid, true, false)),
getFirstSucceededRemoteDataPayload<WorkspaceItem>(),
).subscribe((wsItem) => {
const wsiId = wsItem.id;
const route = 'workspaceitems/' + wsiId + '/edit';
this.router.navigateByUrl(route);
});
}
/**
* Check is the current user can edit the version summary
* @param version
*/
canEditVersion$(version: Version): Observable<boolean> {
return this.authorizationService.isAuthorized(FeatureID.CanEditVersion, vers
ion.self);
}
/**
* Check if the current user can delete the version
* @param version
*/
canDeleteVersion$(version: Version): Observable<boolean> {
return this.authorizationService.isAuthorized(FeatureID.CanDeleteVersion, ve
rsion.self);
}
/**
* Get all versions for the given version history and store them in versionRD$
* @param versionHistory$
*/
getAllVersions(versionHistory$: Observable<VersionHistory>): void {
const currentPagination = this.paginationService.getCurrentPagination(this.o
ptions.id, this.options);
observableCombineLatest([versionHistory$, currentPagination]).pipe(
switchMap(([versionHistory, options]: [VersionHistory, PaginationComponent
Options]) => {
return this.versionHistoryService.getVersions(versionHistory.id,
new PaginatedSearchOptions({pagination: Object.assign({}, options, {cu
rrentPage: options.currentPage})}),
false, true, followLink('item'), followLink('eperson'));
}),
getFirstCompletedRemoteData(),
).subscribe((res: RemoteData<PaginatedList<Version>>) => {
this.versionsRD$.next(res);
});
}
/**
* Updates the page
*/
onPageChange() {
this.getAllVersions(this.versionHistory$);
}
/**
* 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<string> {
return versionItem.pipe(
getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid),
switchMap((itemUuid: string) => this.workspaceItemDataService.findByItem(i
temUuid, true)),
getFirstCompletedRemoteData<WorkspaceItem>(),
map((res: RemoteData<WorkspaceItem>) => 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<string> {
return versionItem.pipe(
getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid),
switchMap((itemUuid: string) => this.workflowItemDataService.findByItem(it
emUuid, true)),
getFirstCompletedRemoteData<WorkspaceItem>(),
map((res: RemoteData<WorkspaceItem>) => res?.payload?.id ),
);
}
/**
* redirect to the edit page of the workspace item
* @param id$ the id of the workspace item
*/
editWorkspaceItem(id$: Observable<string>) {
id$.subscribe((id) => {
this.router.navigateByUrl('workspaceitems/' + id + '/edit');
});
} }
/** /**
* Initialize all observables * Initialize all observables
*/ */
ngOnInit(): void { ngOnInit(): void {
if (hasValue(this.item.version)) { if (hasValue(this.item.version)) {
this.versionRD$ = this.item.version; this.versionRD$ = this.item.version;
this.versionHistoryRD$ = this.versionRD$.pipe( this.versionHistoryRD$ = this.versionRD$.pipe(
getAllSucceededRemoteData(), getAllSucceededRemoteData(),
getRemoteDataPayload(), getRemoteDataPayload(),
hasValueOperator(), hasValueOperator(),
switchMap((version: Version) => version.versionhistory) switchMap((version: Version) => version.versionhistory),
); );
const versionHistory$ = this.versionHistoryRD$.pipe( this.versionHistory$ = this.versionHistoryRD$.pipe(
getAllSucceededRemoteData(), getFirstSucceededRemoteDataPayload(),
getRemoteDataPayload(),
hasValueOperator(), hasValueOperator(),
); );
const currentPagination = this.paginationService.getCurrentPagination(this
.options.id, this.options); this.canCreateVersion$ = this.authorizationService.isAuthorized(FeatureID.
this.versionsRD$ = observableCombineLatest(versionHistory$, currentPaginat CanCreateVersion, this.item.self);
ion).pipe(
switchMap(([versionHistory, options]: [VersionHistory, PaginationCompone // If there is a draft item in the version history the 'Create version' bu
ntOptions]) => tton is disabled and a different tooltip message is shown
this.versionHistoryService.getVersions(versionHistory.id, this.hasDraftVersion$ = this.versionHistoryRD$.pipe(
new PaginatedSearchOptions({pagination: Object.assign({}, options, { getFirstSucceededRemoteDataPayload(),
currentPage: options.currentPage })}), map((res) => Boolean(res?.draftVersion)),
true, true, followLink('item'), followLink('eperson')))
); );
this.createVersionTitle$ = this.hasDraftVersion$.pipe(
take(1),
switchMap((res) => of(res ? 'item.version.history.table.action.hasDraft'
: 'item.version.history.table.action.newVersion'))
);
this.getAllVersions(this.versionHistory$);
this.hasEpersons$ = this.versionsRD$.pipe( this.hasEpersons$ = this.versionsRD$.pipe(
getAllSucceededRemoteData(), getAllSucceededRemoteData(),
getRemoteDataPayload(), getRemoteDataPayload(),
hasValueOperator(), hasValueOperator(),
map((versions: PaginatedList<Version>) => versions.page.filter((version: Version) => version.eperson !== undefined).length > 0), map((versions: PaginatedList<Version>) => versions.page.filter((version: Version) => version.eperson !== undefined).length > 0),
startWith(false) startWith(false)
); );
this.itemPageRoutes$ = this.versionsRD$.pipe( this.itemPageRoutes$ = this.versionsRD$.pipe(
getAllSucceededRemoteDataPayload(), getAllSucceededRemoteDataPayload(),
switchMap((versions) => observableCombineLatest(...versions.page.map((ve rsion) => version.item.pipe(getAllSucceededRemoteDataPayload())))), switchMap((versions) => observableCombineLatest(...versions.page.map((ve rsion) => version.item.pipe(getAllSucceededRemoteDataPayload())))),
map((versions) => { map((versions) => {
const itemPageRoutes = {}; const itemPageRoutes = {};
versions.forEach((item) => itemPageRoutes[item.uuid] = getItemPageRout e(item)); versions.forEach((item) => itemPageRoutes[item.uuid] = getItemPageRout e(item));
return itemPageRoutes; return itemPageRoutes;
}) })
); );
} }
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.cleanupSubscribes();
this.paginationService.clearPagination(this.options.id); this.paginationService.clearPagination(this.options.id);
} }
/**
* Unsub all subscriptions
*/
cleanupSubscribes() {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe())
;
}
} }
 End of changes. 22 change blocks. 
29 lines changed or deleted 418 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)