Skip to content

Commit b1bf764

Browse files
author
Jens Vannerum
committed
140390: Don't show replace button in initial submission, use /edititems endpoint
1 parent 432fbf2 commit b1bf764

5 files changed

Lines changed: 49 additions & 25 deletions

File tree

src/app/submission/sections/upload/file/replace/submission-section-upload-file-replace/submission-section-upload-file-replace.component.html

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ <h4 class="modal-title">{{
66
fileSize: fileSizeBytes | dsFileSize
77
}
88
}}</h4>
9-
<button type="button" class="btn-close" (click)="closeModal()" aria-label="Close">
10-
</button>
9+
<button type="button" class="btn-close" (click)="closeModal()" aria-label="Close"></button>
1110
</div>
1211
<div class="modal-body">
1312
<p>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.btn-close:focus {
2+
box-shadow: none;
3+
opacity: 0.75;
4+
}

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

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ describe('SubmissionSectionUploadFileReplaceComponent', () => {
4646
const locationObject = jasmine.createSpyObj('location', ['back']);
4747
const bitstreamUuid = 'test-bitstream-uuid-123';
4848
const fileIndex = '0';
49-
const submissionId = '0';
49+
const submissionId = 'test-submission-id';
50+
const editItemsLinkName = 'edititems';
5051

5152
const mockSections = { upload: [{ uuid: bitstreamUuid }] };
5253
const mockWorkspaceItem = { sections: mockSections, errors: [] };
@@ -90,14 +91,15 @@ describe('SubmissionSectionUploadFileReplaceComponent', () => {
9091
notificationsService = TestBed.inject(NotificationsService) as unknown as NotificationsServiceStub;
9192
sectionsService = TestBed.inject(SectionsService) as unknown as SectionsServiceStub;
9293
submissionService = TestBed.inject(SubmissionService) as unknown as SubmissionServiceStub;
94+
submissionService.getSubmissionObjectLinkName.and.returnValue(editItemsLinkName);
9395
fixture.detectChanges();
9496
uploadComponent = fixture.debugElement.query(By.directive(TestUploaderComponent)).context;
9597
});
9698

9799
describe('on init', () => {
98-
it('should build the upload URL pointing to the bitstream content endpoint', () => {
99-
// URL must be: {halBase}/bitstreams/{bitstreamUuid}/content?replaceName=true
100-
const expectedUrl = `${bitstreamReplaceUrl}/bitstreams/${bitstreamUuid}/content?replaceName=true`;
100+
it('should build the upload URL pointing to the edititems endpoint with replaceFile param', () => {
101+
// URL must be: {halBase}/{editItemsLinkName}/{submissionId}?replaceFile={bitstreamUuid}&replaceName=true
102+
const expectedUrl = `${bitstreamReplaceUrl}/${editItemsLinkName}/${submissionId}?replaceFile=${bitstreamUuid}&replaceName=true`;
101103
expect(uploadComponent.uploadFilesOptions.url).toBe(expectedUrl);
102104
});
103105
});

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

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { AuthService } from '@dspace/core/auth/auth.service';
99
import { NotificationsService } from '@dspace/core/notification-system/notifications.service';
1010
import { HALEndpointService } from '@dspace/core/shared/hal-endpoint.service';
1111
import { normalizeSectionData } from '@dspace/core/submission/submission-response-parsing.service';
12+
import { SubmissionScopeType } from '@dspace/core/submission/submission-scope-type';
1213
import {
1314
hasValue,
1415
isNotEmpty,
@@ -46,14 +47,17 @@ import { SectionsService } from '../../../../sections.service';
4647
],
4748
})
4849
/**
49-
* Modal component used inside the submission/edit-item upload section to replace the content of
50-
* an existing Bitstream without changing its metadata or its position in the bundle.
50+
* Modal component used inside the edit-item upload section to replace the content of an existing
51+
* Bitstream without changing its metadata or its position in the bundle.
5152
*
52-
* The component is opened by {@link SectionUploadFileComponent} when the user clicks the
53-
* "Replace" button next to a listed file. It issues a `PUT` request to
54-
* `bitstreams/{uuid}/content`, the same endpoint used by {@link ReplaceBitstreamPageComponent}
55-
* from the Bitstream admin tab, with an optional `replaceName` query parameter that controls
56-
* whether the stored file name is updated to match the newly uploaded file.
53+
* The component is opened by {@link SectionUploadFileComponent} when the user clicks the "Replace"
54+
* button next to a listed file. It issues a `POST` multipart request to the `edititems` endpoint
55+
* (e.g. `edititems/{submissionId}?replaceFile={bitstreamUuid}&replaceName={bool}`), which is the
56+
* same endpoint used for new file uploads in the edit-item UI. The `replaceFile` parameter tells
57+
* the backend to replace the identified Bitstream rather than creating a new one.
58+
*
59+
* The replace button is intentionally hidden for fresh workspace/workflow item submissions — it is
60+
* only shown when the submission scope is {@link SubmissionScopeType.EditItem}.
5761
*/
5862
export class SubmissionSectionUploadFileReplaceComponent implements OnInit, OnDestroy {
5963

@@ -91,13 +95,13 @@ export class SubmissionSectionUploadFileReplaceComponent implements OnInit, OnDe
9195
* @type {UploaderOptions}
9296
*/
9397
protected uploadFilesOptions: UploaderOptions = Object.assign(new UploaderOptions(), {
94-
// URL needs to contain something to not produce any errors. This will be replaced once a bundle has been selected.
95-
url: 'placeholder', /* TODO Change upload URL */
98+
// URL needs to contain something to not produce any errors. This will be replaced once ready.
99+
url: 'placeholder',
96100
authToken: null,
97101
disableMultipart: false,
98102
itemAlias: null,
99103
autoUpload: false,
100-
method: RestRequestMethod.PUT,
104+
method: RestRequestMethod.POST,
101105
});
102106

103107
/**
@@ -198,24 +202,32 @@ export class SubmissionSectionUploadFileReplaceComponent implements OnInit, OnDe
198202
}
199203

200204
/**
201-
* Set the upload URL to the bitstream content endpoint for this specific bitstream.
202-
* Uses PUT to replace the existing file content, matching the behaviour of ReplaceBitstreamPageComponent.
205+
* Set the upload URL to the edititems endpoint for this submission, which mirrors the endpoint
206+
* used for new file uploads in the edit-item UI. A `replaceFile` UUID parameter instructs the
207+
* backend to replace the identified existing Bitstream rather than creating a new one.
203208
*/
204209
private setUploadUrl() {
205210
this.subs.push(
206-
this.halService.getEndpoint('bitstreams').pipe(
211+
this.halService.getEndpoint(this.submissionService.getSubmissionObjectLinkName()).pipe(
207212
filter((href: string) => isNotEmpty(href)),
208213
distinctUntilChanged())
209214
.subscribe((endpointURL) => {
210215
this.uploadFilesOptions.authToken = this.authService.buildAuthHeader();
211-
this.uploadFilesUrlNoParam = `${endpointURL}/${this.bitstreamUuid}`;
216+
this.uploadFilesUrlNoParam = `${endpointURL}/${this.submissionId}`;
212217
this.setUploadUrlParameters();
213218
}),
214219
);
215220
}
216221

222+
/**
223+
* Applies the `replaceFile` and `replaceName` query parameters to the upload URL and optionally
224+
* syncs the new URL into the underlying file-upload library so that a file already in the queue
225+
* picks up the latest value before the upload starts.
226+
*
227+
* @param uploader - Optional {@link UploaderComponent} whose internal options should also be updated.
228+
*/
217229
protected setUploadUrlParameters(uploader?: UploaderComponent) {
218-
this.uploadFilesOptions.url = `${this.uploadFilesUrlNoParam}/content?replaceName=${this.shouldReplaceName}`;
230+
this.uploadFilesOptions.url = `${this.uploadFilesUrlNoParam}?replaceFile=${this.bitstreamUuid}&replaceName=${this.shouldReplaceName}`;
219231
if (hasValue(uploader?.uploader?.options)) {
220232
uploader.uploader.options.url = this.uploadFilesOptions.url;
221233
}

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { Bitstream } from '@dspace/core/shared/bitstream.model';
1717
import { HALEndpointService } from '@dspace/core/shared/hal-endpoint.service';
1818
import { WorkspaceitemSectionUploadFileObject } from '@dspace/core/submission/models/workspaceitem-section-upload-file.model';
1919
import { SubmissionJsonPatchOperationsService } from '@dspace/core/submission/submission-json-patch-operations.service';
20+
import { SubmissionScopeType } from '@dspace/core/submission/submission-scope-type';
2021
import {
2122
hasValue,
2223
isNotUndefined,
@@ -252,10 +253,16 @@ export class SubmissionSectionUploadFileComponent implements OnChanges, OnInit,
252253
this.subscriptions.push(
253254
this.uploadService.getFileData(this.submissionId, this.sectionId, this.fileId).pipe(
254255
filter(isNotUndefined),
255-
switchMap((fileData) => this.halService.getEndpoint('bitstreams').pipe(
256-
map(endpoint => `${endpoint}/${fileData.uuid}`),
257-
switchMap(bitstreamUrl => this.authorizationService.isAuthorized(FeatureID.CanReplaceBitstreamSubmitter, bitstreamUrl)),
258-
)),
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+
}),
259266
).subscribe((canReplace) => this.showReplaceButton$.next(canReplace)),
260267
);
261268
}

0 commit comments

Comments
 (0)