mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-18 15:33:04 +00:00
[TLC-249] Register DOI operation and button in item status page
This commit is contained in:
@@ -3,14 +3,23 @@ import { fadeIn, fadeInOut } from '../../../shared/animations/fade';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ItemOperation } from '../item-operation/itemOperation.model';
|
||||
import { distinctUntilChanged, first, map, mergeMap, toArray } from 'rxjs/operators';
|
||||
import { BehaviorSubject, Observable, from as observableFrom } from 'rxjs';
|
||||
import {distinctUntilChanged, first, map, mergeMap, startWith, switchMap, toArray} from 'rxjs/operators';
|
||||
import {BehaviorSubject, Observable, from as observableFrom, Subscription, combineLatest, of} from 'rxjs';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { getItemEditRoute, getItemPageRoute } from '../../item-page-routing-paths';
|
||||
import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { FeatureID } from '../../../core/data/feature-authorization/feature-id';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { getAllSucceededRemoteDataPayload } from '../../../core/shared/operators';
|
||||
import {
|
||||
getAllSucceededRemoteDataPayload,
|
||||
getFirstCompletedRemoteData, getFirstSucceededRemoteData,
|
||||
getFirstSucceededRemoteDataPayload
|
||||
} from '../../../core/shared/operators';
|
||||
import {IdentifierDataService} from '../../../core/data/identifier-data.service';
|
||||
import {IdentifierData} from '../../../shared/object-list/identifier-data/identifier-data.model';
|
||||
import {Identifier} from '../../../shared/object-list/identifier-data/identifier.model';
|
||||
import {ConfigurationProperty} from '../../../core/shared/configuration-property.model';
|
||||
import {ConfigurationDataService} from '../../../core/data/configuration-data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-status',
|
||||
@@ -51,15 +60,32 @@ export class ItemStatusComponent implements OnInit {
|
||||
*/
|
||||
actionsKeys;
|
||||
|
||||
/**
|
||||
* Identifiers (handles, DOIs)
|
||||
*/
|
||||
identifiers$: Observable<Identifier[]>;
|
||||
|
||||
/**
|
||||
* Configuration and state variables regarding DOIs
|
||||
*/
|
||||
|
||||
public subs: Subscription[] = [];
|
||||
|
||||
/**
|
||||
* Route to the item's page
|
||||
*/
|
||||
itemPageRoute$: Observable<string>;
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private authorizationService: AuthorizationDataService) {
|
||||
private authorizationService: AuthorizationDataService,
|
||||
private identifierDataService: IdentifierDataService,
|
||||
private configurationService: ConfigurationDataService,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise component
|
||||
*/
|
||||
ngOnInit(): void {
|
||||
this.itemRD$ = this.route.parent.data.pipe(map((data) => data.dso));
|
||||
this.itemRD$.pipe(
|
||||
@@ -72,6 +98,35 @@ export class ItemStatusComponent implements OnInit {
|
||||
lastModified: item.lastModified
|
||||
});
|
||||
this.statusDataKeys = Object.keys(this.statusData);
|
||||
|
||||
// Observable for item identifiers (retrieved from embedded link)
|
||||
this.identifiers$ = this.identifierDataService.getIdentifierDataFor(item).pipe(
|
||||
map((identifierRD) => {
|
||||
if (identifierRD.statusCode !== 401 && hasValue(identifierRD.payload)) {
|
||||
return identifierRD.payload.identifiers;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
// Observable for configuration determining whether the Register DOI feature is enabled
|
||||
let registerConfigEnabled$: Observable<boolean> = this.configurationService.findByPropertyName('identifiers.item-status.register').pipe(
|
||||
map((enabled: RemoteData<ConfigurationProperty>) => {
|
||||
let show: boolean = false;
|
||||
if (enabled.hasSucceeded) {
|
||||
if (enabled.payload !== undefined && enabled.payload !== null) {
|
||||
if (enabled.payload.values !== undefined) {
|
||||
enabled.payload.values.forEach((value) => {
|
||||
show = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return show;
|
||||
})
|
||||
);
|
||||
|
||||
/*
|
||||
The key is used to build messages
|
||||
i18n example: 'item.edit.tabs.status.buttons.<key>.label'
|
||||
@@ -92,27 +147,66 @@ export class ItemStatusComponent implements OnInit {
|
||||
}
|
||||
operations.push(new ItemOperation('delete', this.getCurrentUrl(item) + '/delete', FeatureID.CanDelete, true));
|
||||
operations.push(new ItemOperation('move', this.getCurrentUrl(item) + '/move', FeatureID.CanMove, true));
|
||||
|
||||
this.operations$.next(operations);
|
||||
|
||||
observableFrom(operations).pipe(
|
||||
mergeMap((operation) => {
|
||||
if (hasValue(operation.featureID)) {
|
||||
return this.authorizationService.isAuthorized(operation.featureID, item.self).pipe(
|
||||
distinctUntilChanged(),
|
||||
map((authorized) => new ItemOperation(operation.operationKey, operation.operationUrl, operation.featureID, !authorized, authorized))
|
||||
);
|
||||
} else {
|
||||
return [operation];
|
||||
// Observable that reads identifiers and their status and, and config properties, and decides
|
||||
// if we're allowed to show a Register DOI feature
|
||||
let showRegister$: Observable<boolean> = combineLatest([this.identifiers$, registerConfigEnabled$]).pipe(
|
||||
distinctUntilChanged(),
|
||||
map(([identifiers, enabled]) => {
|
||||
let no_doi: boolean = true;
|
||||
let pending: boolean = false;
|
||||
if (identifiers !== undefined && identifiers !== null) {
|
||||
identifiers.forEach((identifier: Identifier) => {
|
||||
if (hasValue(identifier) && identifier.identifierType == 'doi') {
|
||||
// The item has some kind of DOI
|
||||
no_doi = false;
|
||||
if (identifier.identifierStatus == '10' || identifier.identifierStatus == '11'
|
||||
|| identifier.identifierStatus == null) {
|
||||
// The item's DOI is pending, minted or null.
|
||||
// It isn't registered, reserved, queued for registration or reservation or update, deleted
|
||||
// or queued for deletion.
|
||||
pending = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}),
|
||||
toArray()
|
||||
).subscribe((ops) => this.operations$.next(ops));
|
||||
// If there is no DOI, or a pending/minted/null DOI, and the config is enabled, return true
|
||||
return ((pending || no_doi) && enabled);
|
||||
})
|
||||
)
|
||||
|
||||
// Subscribe to changes from the showRegister check and rebuild operations list accordingly
|
||||
this.subs.push(showRegister$.subscribe((show) => {
|
||||
// Copy the static array first so we don't keep appending to it
|
||||
let tmp_operations = [...operations];
|
||||
if (show) {
|
||||
// Push the new Register DOI item operation
|
||||
tmp_operations.push(new ItemOperation('registerDOI', this.getCurrentUrl(item) + '/registerdoi', FeatureID.CanRegisterDOI));
|
||||
}
|
||||
// Check authorisations and merge into new operations list
|
||||
observableFrom(tmp_operations).pipe(
|
||||
mergeMap((operation) => {
|
||||
if (hasValue(operation.featureID)) {
|
||||
return this.authorizationService.isAuthorized(operation.featureID, item.self).pipe(
|
||||
distinctUntilChanged(),
|
||||
map((authorized) => new ItemOperation(operation.operationKey, operation.operationUrl, operation.featureID, !authorized, authorized))
|
||||
);
|
||||
} else {
|
||||
return [operation];
|
||||
}
|
||||
}),
|
||||
toArray()
|
||||
).subscribe((ops) => this.operations$.next(ops));
|
||||
}));
|
||||
|
||||
});
|
||||
|
||||
this.itemPageRoute$ = this.itemRD$.pipe(
|
||||
getAllSucceededRemoteDataPayload(),
|
||||
map((item) => getItemPageRoute(item))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,4 +221,10 @@ export class ItemStatusComponent implements OnInit {
|
||||
return hasValue(operation) ? operation.operationKey : undefined;
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subs
|
||||
.filter((subscription) => hasValue(subscription))
|
||||
.forEach((subscription) => subscription.unsubscribe());
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user