forked from hazza/dspace-angular
65717: Move operations from custom order + sending bundle patch
This commit is contained in:
@@ -24,6 +24,9 @@ import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-o
|
||||
import { FieldUpdate, FieldUpdates } from '../../../core/data/object-updates/object-updates.reducer';
|
||||
import { Bitstream } from '../../../core/shared/bitstream.model';
|
||||
import { FieldChangeType } from '../../../core/data/object-updates/object-updates.actions';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { MoveOperation } from 'fast-json-patch/lib/core';
|
||||
import { BundleDataService } from '../../../core/data/bundle-data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-item-bitstreams',
|
||||
@@ -66,7 +69,8 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
public bitstreamService: BitstreamDataService,
|
||||
public objectCache: ObjectCacheService,
|
||||
public requestService: RequestService,
|
||||
public cdRef: ChangeDetectorRef
|
||||
public cdRef: ChangeDetectorRef,
|
||||
public bundleService: BundleDataService
|
||||
) {
|
||||
super(itemService, objectUpdatesService, router, notificationsService, translateService, EnvConfig, route);
|
||||
}
|
||||
@@ -141,6 +145,19 @@ export class ItemBitstreamsComponent extends AbstractItemUpdateComponent impleme
|
||||
this.displayNotifications(responses);
|
||||
this.reset();
|
||||
});
|
||||
|
||||
this.bundles$.pipe(take(1)).subscribe((bundles: Bundle[]) => {
|
||||
bundles.forEach((bundle: Bundle) => {
|
||||
this.objectUpdatesService.getMoveOperations(bundle.self).pipe(
|
||||
take(1),
|
||||
isNotEmptyOperator(),
|
||||
map((operations: MoveOperation[]) => [...operations.map((operation: MoveOperation) => Object.assign(operation, {
|
||||
from: `/_links/bitstreams${operation.from}/href`,
|
||||
path: `/_links/bitstreams${operation.path}/href`
|
||||
}))])
|
||||
).subscribe((operations: Operation[]) => this.bundleService.patch(bundle.self, operations));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -104,9 +104,9 @@ export class ServerSyncBufferEffects {
|
||||
map((entry: ObjectCacheEntry) => {
|
||||
if (isNotEmpty(entry.patches)) {
|
||||
const flatPatch: Operation[] = [].concat(...entry.patches.map((patch) => patch.operations));
|
||||
const metadataPatch = flatPatch.filter((op: Operation) => op.path.startsWith('/metadata'));
|
||||
if (isNotEmpty(metadataPatch)) {
|
||||
this.requestService.configure(new PatchRequest(this.requestService.generateRequestId(), href, metadataPatch));
|
||||
const objectPatch = flatPatch.filter((op: Operation) => op.path.startsWith('/metadata') || op.op === 'move');
|
||||
if (isNotEmpty(objectPatch)) {
|
||||
this.requestService.configure(new PatchRequest(this.requestService.generateRequestId(), href, objectPatch));
|
||||
}
|
||||
}
|
||||
return new ApplyPatchObjectCacheAction(href);
|
||||
|
@@ -122,6 +122,7 @@ import { BrowseDefinition } from './shared/browse-definition.model';
|
||||
import { BitstreamDataService } from './data/bitstream-data.service';
|
||||
import { MappedCollectionsReponseParsingService } from './data/mapped-collections-reponse-parsing.service';
|
||||
import { ObjectSelectService } from '../shared/object-select/object-select.service';
|
||||
import { ArrayMoveChangeAnalyzer } from './data/array-move-change-analyzer.service';
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
@@ -201,6 +202,7 @@ const PROVIDERS = [
|
||||
DSpaceObjectDataService,
|
||||
DSOChangeAnalyzer,
|
||||
DefaultChangeAnalyzer,
|
||||
ArrayMoveChangeAnalyzer,
|
||||
ObjectSelectService,
|
||||
CSSVariableService,
|
||||
MenuService,
|
||||
|
38
src/app/core/data/array-move-change-analyzer.service.ts
Normal file
38
src/app/core/data/array-move-change-analyzer.service.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { MoveOperation, Operation } from 'fast-json-patch/lib/core';
|
||||
import { compare } from 'fast-json-patch';
|
||||
import { ChangeAnalyzer } from './change-analyzer';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { NormalizedObject } from '../cache/models/normalized-object.model';
|
||||
import { moveItemInArray } from '@angular/cdk/drag-drop';
|
||||
|
||||
/**
|
||||
* A class to determine move operations between two arrays
|
||||
*/
|
||||
@Injectable()
|
||||
export class ArrayMoveChangeAnalyzer<T> {
|
||||
|
||||
/**
|
||||
* Compare two arrays detecting and returning move operations
|
||||
*
|
||||
* @param array1 The original array
|
||||
* @param array2 The custom array to compare with the original
|
||||
*/
|
||||
diff(array1: T[], array2: T[]): MoveOperation[] {
|
||||
const result = [];
|
||||
const moved = [...array1];
|
||||
array1.forEach((value: T, index: number) => {
|
||||
const otherIndex = array2.indexOf(value);
|
||||
const movedIndex = moved.indexOf(value);
|
||||
if (index !== otherIndex && movedIndex !== otherIndex) {
|
||||
moveItemInArray(moved, movedIndex, otherIndex);
|
||||
result.push(Object.assign({
|
||||
op: 'move',
|
||||
from: '/' + movedIndex,
|
||||
path: '/' + otherIndex
|
||||
}) as MoveOperation)
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -24,6 +24,9 @@ import {
|
||||
import { distinctUntilChanged, filter, map } from 'rxjs/operators';
|
||||
import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
|
||||
import { INotification } from '../../../shared/notifications/models/notification.model';
|
||||
import { Operation } from 'fast-json-patch';
|
||||
import { ArrayMoveChangeAnalyzer } from '../array-move-change-analyzer.service';
|
||||
import { MoveOperation } from 'fast-json-patch/lib/core';
|
||||
|
||||
function objectUpdatesStateSelector(): MemoizedSelector<CoreState, ObjectUpdatesState> {
|
||||
return createSelector(coreSelector, (state: CoreState) => state['cache/object-updates']);
|
||||
@@ -42,7 +45,8 @@ function filterByUrlAndUUIDFieldStateSelector(url: string, uuid: string): Memoiz
|
||||
*/
|
||||
@Injectable()
|
||||
export class ObjectUpdatesService {
|
||||
constructor(private store: Store<CoreState>) {
|
||||
constructor(private store: Store<CoreState>,
|
||||
private comparator: ArrayMoveChangeAnalyzer<string>) {
|
||||
|
||||
}
|
||||
|
||||
@@ -335,4 +339,16 @@ export class ObjectUpdatesService {
|
||||
getLastModified(url: string): Observable<Date> {
|
||||
return this.getObjectEntry(url).pipe(map((entry: ObjectUpdatesEntry) => entry.lastModified));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get move operations based on the custom order
|
||||
* @param url The page's url
|
||||
*/
|
||||
getMoveOperations(url: string): Observable<MoveOperation[]> {
|
||||
return this.getObjectEntry(url).pipe(
|
||||
map((objectEntry) => objectEntry.customOrder),
|
||||
map((customOrder) => this.comparator.diff(customOrder.initialOrder, customOrder.newOrder))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user