Skip to content

Commit 0f77ec9

Browse files
author
Jens Vannerum
committed
140390: DO show replace button for new versions but not for (unversioned) new submission + cleanup code for nested subscriptions
1 parent b1bf764 commit 0f77ec9

1 file changed

Lines changed: 58 additions & 10 deletions

File tree

src/app/submission/sections/upload/file/section-upload-file.component.ts

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ import { FeatureID } from '@dspace/core/data/feature-authorization/feature-id';
1414
import { JsonPatchOperationPathCombiner } from '@dspace/core/json-patch/builder/json-patch-operation-path-combiner';
1515
import { JsonPatchOperationsBuilder } from '@dspace/core/json-patch/builder/json-patch-operations-builder';
1616
import { Bitstream } from '@dspace/core/shared/bitstream.model';
17+
import { followLink } from '@dspace/core/shared/follow-link-config.model';
1718
import { HALEndpointService } from '@dspace/core/shared/hal-endpoint.service';
19+
import { Item } from '@dspace/core/shared/item.model';
20+
import {
21+
getAllSucceededRemoteData,
22+
getRemoteDataPayload,
23+
} from '@dspace/core/shared/operators';
1824
import { WorkspaceitemSectionUploadFileObject } from '@dspace/core/submission/models/workspaceitem-section-upload-file.model';
1925
import { SubmissionJsonPatchOperationsService } from '@dspace/core/submission/submission-json-patch-operations.service';
2026
import { SubmissionScopeType } from '@dspace/core/submission/submission-scope-type';
@@ -31,6 +37,7 @@ import { TranslateModule } from '@ngx-translate/core';
3137
import {
3238
BehaviorSubject,
3339
Observable,
40+
of,
3441
Subscription,
3542
} from 'rxjs';
3643
import {
@@ -39,6 +46,7 @@ import {
3946
switchMap,
4047
} from 'rxjs/operators';
4148

49+
import { LinkService } from '../../../../core/cache/builders/link.service';
4250
import { BtnDisabledDirective } from '../../../../shared/btn-disabled.directive';
4351
import { ThemedFileDownloadLinkComponent } from '../../../../shared/file-download-link/themed-file-download-link.component';
4452
import { FormService } from '../../../../shared/form/form.service';
@@ -210,6 +218,7 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
210218
* @param {SectionUploadService} uploadService
211219
* @param {AuthorizationDataService} authorizationService
212220
* @param {HALEndpointService} halService
221+
* @param {LinkService} linkService
213222
*/
214223
constructor(
215224
private formService: FormService,
@@ -220,6 +229,7 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
220229
private uploadService: SectionUploadService,
221230
private authorizationService: AuthorizationDataService,
222231
private halService: HALEndpointService,
232+
private linkService: LinkService,
223233
) {
224234
this.readMode = true;
225235
}
@@ -253,20 +263,58 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
253263
this.subscriptions.push(
254264
this.uploadService.getFileData(this.submissionId, this.sectionId, this.fileId).pipe(
255265
filter(isNotUndefined),
256-
switchMap((fileData) => {
257-
// Replace is only meaningful for archived items being edited, not for fresh submissions.
258-
if (this.submissionService.getSubmissionScope() !== SubmissionScopeType.EditItem) {
259-
return [false];
260-
}
261-
return this.halService.getEndpoint('bitstreams').pipe(
262-
map(endpoint => `${endpoint}/${fileData.uuid}`),
263-
switchMap(bitstreamUrl => this.authorizationService.isAuthorized(FeatureID.CanReplaceBitstreamSubmitter, bitstreamUrl)),
264-
);
265-
}),
266+
switchMap((fileData) => this.canShowReplaceButton(fileData.uuid)),
266267
).subscribe((canReplace) => this.showReplaceButton$.next(canReplace)),
267268
);
268269
}
269270

271+
/**
272+
* Returns an Observable that emits whether the replace button should be shown for the given
273+
* bitstream. WorkflowItems never show the button; WorkspaceItems only show it when the
274+
* submission is a new version of an existing item; Archived items rely solely on backend
275+
* authorization.
276+
*/
277+
private canShowReplaceButton(bitstreamUuid: string): Observable<boolean> {
278+
const scope = this.submissionService.getSubmissionScope();
279+
if (scope === SubmissionScopeType.WorkflowItem) {
280+
return of(false);
281+
}
282+
return this.isVersionedSubmission(scope).pipe(
283+
switchMap((isVersioned) => isVersioned ? this.isAuthorizedToReplace(bitstreamUuid) : of(false)),
284+
);
285+
}
286+
287+
/**
288+
* Returns `true` when the current submission is a new-version workspace item (i.e. its item
289+
* already belongs to a version history), or unconditionally `true` for EditItem scope where
290+
* versioning does not apply.
291+
*/
292+
private isVersionedSubmission(scope: SubmissionScopeType): Observable<boolean> {
293+
if (scope !== SubmissionScopeType.WorkspaceItem) {
294+
return of(true);
295+
}
296+
return this.submissionService.retrieveSubmission(this.submissionId).pipe(
297+
getAllSucceededRemoteData(),
298+
getRemoteDataPayload(),
299+
map((submissionObject) => Object.assign(new Item(), submissionObject.item)),
300+
map((item: Item) => this.linkService.resolveLink(item, followLink('version'))),
301+
switchMap((item: Item) => item.version),
302+
getAllSucceededRemoteData(),
303+
getRemoteDataPayload(),
304+
map((version) => hasValue(version)),
305+
);
306+
}
307+
308+
/**
309+
* Returns whether the current user is authorized to replace the given bitstream.
310+
*/
311+
private isAuthorizedToReplace(bitstreamUuid: string): Observable<boolean> {
312+
return this.halService.getEndpoint('bitstreams').pipe(
313+
map((endpoint) => `${endpoint}/${bitstreamUuid}`),
314+
switchMap((bitstreamUrl) => this.authorizationService.isAuthorized(FeatureID.CanReplaceBitstreamSubmitter, bitstreamUrl)),
315+
);
316+
}
317+
270318
/**
271319
* Show confirmation dialog for delete
272320
*/

0 commit comments

Comments
 (0)