From eadbcdbe14108b6c47f9e623e8b99c10d03ff5bd Mon Sep 17 00:00:00 2001 From: Andreas Awouters Date: Wed, 11 Sep 2024 16:25:42 +0200 Subject: [PATCH] 118219: Store result of drag & dropping bitstream --- .../item-bitstreams.component.ts | 15 +++-- .../item-edit-bitstream-bundle.component.ts | 60 ++++++++++++++++--- 2 files changed, 62 insertions(+), 13 deletions(-) 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 9f27cf11b3..e7c846b5da 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 @@ -1,6 +1,6 @@ import { ChangeDetectorRef, Component, NgZone, OnDestroy } from '@angular/core'; import { AbstractItemUpdateComponent } from '../abstract-item-update/abstract-item-update.component'; -import { filter, map, switchMap, take } from 'rxjs/operators'; +import { map, switchMap, take } from 'rxjs/operators'; import { Observable, Subscription, zip as observableZip } from 'rxjs'; import { ItemDataService } from '../../../core/data/item-data.service'; import { ObjectUpdatesService } from '../../../core/data/object-updates/object-updates.service'; @@ -11,7 +11,11 @@ import { BitstreamDataService } from '../../../core/data/bitstream-data.service' import { hasValue } from '../../../shared/empty.util'; import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; -import { getFirstSucceededRemoteData, getRemoteDataPayload } from '../../../core/shared/operators'; +import { + getFirstSucceededRemoteData, + getRemoteDataPayload, + getFirstCompletedRemoteData +} from '../../../core/shared/operators'; import { RemoteData } from '../../../core/data/remote-data'; import { PaginatedList } from '../../../core/data/paginated-list.model'; import { Bundle } from '../../../core/shared/bundle.model'; @@ -127,12 +131,13 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme from: `/_links/bitstreams/${event.fromIndex}/href`, path: `/_links/bitstreams/${event.toIndex}/href` } as Operation; - this.bundleService.patch(bundle, [moveOperation]).pipe(take(1)).subscribe((response: RemoteData) => { + this.bundleService.patch(bundle, [moveOperation]).pipe( + getFirstCompletedRemoteData(), + ).subscribe((response: RemoteData) => { this.zone.run(() => { this.itemBitstreamsService.displayNotifications('item.edit.bitstreams.notifications.move', [response]); // Remove all cached requests from this bundle and call the event's callback when the requests are cleared - this.requestService.removeByHrefSubstring(bundle.self).pipe( - filter((isCached) => isCached), + this.requestService.setStaleByHrefSubstring(bundle.self).pipe( take(1) ).subscribe(() => event.finish()); }); diff --git a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts index c0c4e30231..0293a1daea 100644 --- a/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts +++ b/src/app/item-page/edit-item-page/item-bitstreams/item-edit-bitstream-bundle/item-edit-bitstream-bundle.component.ts @@ -28,7 +28,8 @@ import { PaginationService } from '../../../../core/pagination/pagination.servic import { PaginationComponent } from '../../../../shared/pagination/pagination.component'; import { RequestService } from '../../../../core/data/request.service'; import { ItemBitstreamsService } from '../item-bitstreams.service'; -import { CdkDragDrop } from '@angular/cdk/drag-drop'; +import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop'; +import { hasValue } from '../../../../shared/empty.util'; /** * Interface storing all the information necessary to create a row in the bitstream edit table @@ -135,7 +136,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The data to show in the table */ - tableEntries$: Observable; + tableEntries$: BehaviorSubject = new BehaviorSubject(null); /** * The initial page options to use for fetching the bitstreams @@ -165,7 +166,7 @@ export class ItemEditBitstreamBundleComponent implements OnInit { /** * The updates to the current bitstreams */ - updates$: Observable; + updates$: BehaviorSubject = new BehaviorSubject(null); constructor( @@ -229,17 +230,17 @@ export class ItemEditBitstreamBundleComponent implements OnInit { this.objectUpdatesService.initialize(this.bundleUrl, bitstreams, new Date()); }); - this.updates$ = this.bitstreamsRD$.pipe( + this.bitstreamsRD$.pipe( getAllSucceededRemoteData(), paginatedListToArray(), switchMap((bitstreams) => this.objectUpdatesService.getFieldUpdatesExclusive(this.bundleUrl, bitstreams)) - ); + ).subscribe((updates) => this.updates$.next(updates)); - this.tableEntries$ = this.bitstreamsRD$.pipe( + this.bitstreamsRD$.pipe( getAllSucceededRemoteData(), paginatedListToArray(), map((bitstreams) => this.itemBitstreamsService.mapBitstreamsToTableEntries(bitstreams)), - ); + ).subscribe((tableEntries) => this.tableEntries$.next(tableEntries)); } /** @@ -288,7 +289,50 @@ export class ItemEditBitstreamBundleComponent implements OnInit { } drop(event: CdkDragDrop) { - console.log('dropEvent:', event); + const dragIndex = event.previousIndex; + let dropIndex = event.currentIndex; + const dragPage = this.currentPaginationOptions$.value.currentPage - 1; + let dropPage = this.currentPaginationOptions$.value.currentPage - 1; + + // Check if the user is hovering over any of the pagination's pages at the time of dropping the object + const droppedOnElement = document.elementFromPoint(event.dropPoint.x, event.dropPoint.y); + if (hasValue(droppedOnElement) && hasValue(droppedOnElement.textContent) && droppedOnElement.classList.contains('page-link')) { + // The user is hovering over a page, fetch the page's number from the element + const droppedPage = Number(droppedOnElement.textContent); + if (hasValue(droppedPage) && !Number.isNaN(droppedPage)) { + dropPage = droppedPage - 1; + dropIndex = 0; + } + } + + const isNewPage = dragPage !== dropPage; + // Move the object in the custom order array if the drop happened within the same page + // This allows us to instantly display a change in the order, instead of waiting for the REST API's response first + if (!isNewPage && dragIndex !== dropIndex) { + const currentEntries = [...this.tableEntries$.value]; + moveItemInArray(currentEntries, dragIndex, dropIndex); + this.tableEntries$.next(currentEntries); + } + + const pageSize = this.currentPaginationOptions$.value.pageSize; + const redirectPage = dropPage + 1; + const fromIndex = (dragPage * pageSize) + dragIndex; + const toIndex = (dropPage * pageSize) + dropIndex; + // Send out a drop event (and navigate to the new page) when the "from" and "to" indexes are different from each other + if (fromIndex !== toIndex) { + // if (isNewPage) { + // this.loading$.next(true); + // } + this.dropObject.emit(Object.assign({ + fromIndex, + toIndex, + finish: () => { + if (isNewPage) { + this.paginationComponent.doPageChange(redirectPage); + } + } + })); + } } }