diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html
index 7789b682783..88525eb18bf 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.html
@@ -27,7 +27,7 @@
-
0" class="mt-4 table-border scrollable-table">
+
0" class="mt-4 table-border scrollable-table" [ngClass]="{'disabled-overlay': (isProcessingMoveRequest | async)}">
+
+
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss
index 985516ab121..7fd1f4b31e7 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.scss
@@ -43,3 +43,13 @@
.scrollable-table {
overflow-x: auto;
}
+
+.disabled-overlay {
+ opacity: 0.6;
+}
+
+.loading-overlay {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+}
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts
index 6ee5dcb545f..72f85675c93 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.component.ts
@@ -59,6 +59,11 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
*/
itemUpdateSubscription: Subscription;
+ /**
+ * An observable which emits a boolean which represents whether the service is currently handling a 'move' request
+ */
+ isProcessingMoveRequest: Observable;
+
constructor(
public itemService: ItemDataService,
public objectUpdatesService: ObjectUpdatesService,
@@ -84,6 +89,7 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
*/
postItemInit(): void {
const bundlesOptions = this.itemBitstreamsService.getInitialBundlesPaginationOptions();
+ this.isProcessingMoveRequest = this.itemBitstreamsService.getPerformingMoveRequest$();
this.bundles$ = this.itemService.getBundles(this.item.id, new PaginatedSearchOptions({pagination: bundlesOptions})).pipe(
getFirstSucceededRemoteData(),
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts
index f2af25f22f7..a0277ef064b 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.spec.ts
@@ -573,8 +573,6 @@ describe('ItemBitstreamsService', () => {
const to = 7;
const callback = createSpy('callbackFunction');
- console.log('bundle:', bundle);
-
it('should correctly create the Move request', () => {
const expectedOperation: MoveOperation = {
op: 'move',
@@ -601,6 +599,22 @@ describe('ItemBitstreamsService', () => {
service.performBitstreamMoveRequest(bundle, from, to, callback);
expect(callback).toHaveBeenCalled();
});
+
+ it('should emit at the start and end of the request', fakeAsync(() => {
+ const emittedActions = [];
+
+ service.getPerformingMoveRequest$().subscribe(selected => emittedActions.push(selected));
+
+ expect(emittedActions.length).toBe(1);
+ expect(emittedActions[0]).toBeFalse();
+
+ service.performBitstreamMoveRequest(bundle, from, to, callback);
+ tick();
+
+ expect(emittedActions.length).toBe(3);
+ expect(emittedActions[1]).toBeTrue();
+ expect(emittedActions[2]).toBeFalse();
+ }));
});
describe('displayNotifications', () => {
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts
index 7aac79fe695..f60693f7263 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.stub.ts
@@ -30,6 +30,10 @@ export class ItemBitstreamsServiceStub {
performBitstreamMoveRequest = jasmine.createSpy('performBitstreamMoveRequest');
+ getPerformingMoveRequest = jasmine.createSpy('getPerformingMoveRequest').and.returnValue(false);
+
+ getPerformingMoveRequest$ = jasmine.createSpy('getPerformingMoveRequest$').and.returnValue(of(false));
+
getInitialBundlesPaginationOptions = jasmine.createSpy('getInitialBundlesPaginationOptions').and
.returnValue(new PaginationComponentOptions());
diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts
index 2329107c29d..9bbf3804873 100644
--- a/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts
+++ b/src/app/item-page/edit-item-page/item-bitstreams/item-bitstreams.service.ts
@@ -119,7 +119,7 @@ export class ItemBitstreamsService {
*/
protected selectionAction$: BehaviorSubject = new BehaviorSubject(null);
- protected isPerformingMoveRequest = false;
+ protected isPerformingMoveRequest: BehaviorSubject = new BehaviorSubject(false);
constructor(
protected notificationsService: NotificationsService,
@@ -221,7 +221,7 @@ export class ItemBitstreamsService {
cancelSelection() {
const selected = this.getSelectedBitstream();
- if (hasNoValue(selected) || this.isPerformingMoveRequest) {
+ if (hasNoValue(selected) || this.getPerformingMoveRequest()) {
return;
}
@@ -247,7 +247,7 @@ export class ItemBitstreamsService {
moveSelectedBitstreamUp() {
const selected = this.getSelectedBitstream();
- if (hasNoValue(selected) || this.isPerformingMoveRequest) {
+ if (hasNoValue(selected) || this.getPerformingMoveRequest()) {
return;
}
@@ -272,7 +272,7 @@ export class ItemBitstreamsService {
moveSelectedBitstreamDown() {
const selected = this.getSelectedBitstream();
- if (hasNoValue(selected) || this.isPerformingMoveRequest) {
+ if (hasNoValue(selected) || this.getPerformingMoveRequest()) {
return;
}
@@ -299,7 +299,7 @@ export class ItemBitstreamsService {
* @param finish Optional: Function to execute once the response has been received
*/
performBitstreamMoveRequest(bundle: Bundle, fromIndex: number, toIndex: number, finish?: () => void) {
- if (this.isPerformingMoveRequest) {
+ if (this.getPerformingMoveRequest()) {
console.warn('Attempted to perform move request while previous request has not completed yet');
return;
}
@@ -310,18 +310,34 @@ export class ItemBitstreamsService {
path: `/_links/bitstreams/${toIndex}/href`,
};
- this.isPerformingMoveRequest = true;
+ this.announceLoading();
+ this.isPerformingMoveRequest.next(true);
this.bundleService.patch(bundle, [moveOperation]).pipe(
getFirstCompletedRemoteData(),
tap((response: RemoteData) => this.displayFailedResponseNotifications(MOVE_KEY, [response])),
switchMap(() => this.requestService.setStaleByHrefSubstring(bundle.self)),
take(1),
).subscribe(() => {
- this.isPerformingMoveRequest = false;
+ console.log('got here!');
+ this.isPerformingMoveRequest.next(false);
finish?.();
});
}
+ /**
+ * Whether the service currently is processing a 'move' request
+ */
+ getPerformingMoveRequest(): boolean {
+ return this.isPerformingMoveRequest.value;
+ }
+
+ /**
+ * Returns an observable which emits when the service starts, or ends, processing a 'move' request
+ */
+ getPerformingMoveRequest$(): Observable {
+ return this.isPerformingMoveRequest;
+ }
+
/**
* Returns the pagination options to use when fetching the bundles
*/
@@ -526,4 +542,12 @@ export class ItemBitstreamsService {
{ bitstream: bitstreamName });
this.liveRegionService.addMessage(message);
}
+
+ /**
+ * Adds a message to the live region mentioning that the
+ */
+ announceLoading() {
+ const message = this.translateService.instant('item.edit.bitstreams.edit.live.loading');
+ this.liveRegionService.addMessage(message);
+ }
}
diff --git a/src/assets/i18n/en.json5 b/src/assets/i18n/en.json5
index 519189ed691..9007982a728 100644
--- a/src/assets/i18n/en.json5
+++ b/src/assets/i18n/en.json5
@@ -1954,6 +1954,8 @@
"item.edit.bitstreams.edit.live.clear": "{{ bitstream }} is no longer selected.",
+ "item.edit.bitstreams.edit.live.loading": "Waiting for move to complete.",
+
"item.edit.bitstreams.edit.live.select": "{{ bitstream }} is selected.",
"item.edit.bitstreams.edit.live.move": "{{ bitstream }} is now in position {{ toIndex }}.",