mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
73014: MetadataPatchOperationService create patch in two steps to fix remove operation issue
This commit is contained in:
@@ -11,7 +11,6 @@ import { NgModel } from '@angular/forms';
|
|||||||
import { MetadatumViewModel } from '../../../../core/shared/metadata.models';
|
import { MetadatumViewModel } from '../../../../core/shared/metadata.models';
|
||||||
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
import { MetadataField } from '../../../../core/metadata/metadata-field.model';
|
||||||
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
import { InputSuggestion } from '../../../../shared/input-suggestions/input-suggestions.model';
|
||||||
import { METADATA_PATCH_OPERATION_SERVICE_TOKEN } from '../../../../core/data/object-updates/patch-operation-service/metadata-patch-operation.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
// tslint:disable-next-line:component-selector
|
// tslint:disable-next-line:component-selector
|
||||||
@@ -76,7 +75,7 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
* Sends a new change update for this field to the object updates service
|
* Sends a new change update for this field to the object updates service
|
||||||
*/
|
*/
|
||||||
update(ngModel?: NgModel) {
|
update(ngModel?: NgModel) {
|
||||||
this.objectUpdatesService.saveChangeFieldUpdate(this.url, cloneDeep(this.metadata), METADATA_PATCH_OPERATION_SERVICE_TOKEN);
|
this.objectUpdatesService.saveChangeFieldUpdate(this.url, cloneDeep(this.metadata));
|
||||||
if (hasValue(ngModel)) {
|
if (hasValue(ngModel)) {
|
||||||
this.checkValidity(ngModel);
|
this.checkValidity(ngModel);
|
||||||
}
|
}
|
||||||
@@ -104,7 +103,7 @@ export class EditInPlaceFieldComponent implements OnInit, OnChanges {
|
|||||||
* Sends a new remove update for this field to the object updates service
|
* Sends a new remove update for this field to the object updates service
|
||||||
*/
|
*/
|
||||||
remove() {
|
remove() {
|
||||||
this.objectUpdatesService.saveRemoveFieldUpdate(this.url, cloneDeep(this.metadata), METADATA_PATCH_OPERATION_SERVICE_TOKEN);
|
this.objectUpdatesService.saveRemoveFieldUpdate(this.url, cloneDeep(this.metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -94,14 +94,14 @@ export class ItemMetadataComponent extends AbstractItemUpdateComponent {
|
|||||||
* @param metadata The metadata to add, if no parameter is supplied, create a new Metadatum
|
* @param metadata The metadata to add, if no parameter is supplied, create a new Metadatum
|
||||||
*/
|
*/
|
||||||
add(metadata: MetadatumViewModel = new MetadatumViewModel()) {
|
add(metadata: MetadatumViewModel = new MetadatumViewModel()) {
|
||||||
this.objectUpdatesService.saveAddFieldUpdate(this.url, metadata, METADATA_PATCH_OPERATION_SERVICE_TOKEN);
|
this.objectUpdatesService.saveAddFieldUpdate(this.url, metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends all initial values of this item to the object updates service
|
* Sends all initial values of this item to the object updates service
|
||||||
*/
|
*/
|
||||||
public initializeOriginalFields() {
|
public initializeOriginalFields() {
|
||||||
this.objectUpdatesService.initialize(this.url, this.item.metadataAsList, this.item.lastModified);
|
this.objectUpdatesService.initialize(this.url, this.item.metadataAsList, this.item.lastModified, METADATA_PATCH_OPERATION_SERVICE_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -40,7 +40,8 @@ export class InitializeFieldsAction implements Action {
|
|||||||
payload: {
|
payload: {
|
||||||
url: string,
|
url: string,
|
||||||
fields: Identifiable[],
|
fields: Identifiable[],
|
||||||
lastModified: Date
|
lastModified: Date,
|
||||||
|
patchOperationServiceToken?: InjectionToken<PatchOperationService>
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,16 +51,15 @@ export class InitializeFieldsAction implements Action {
|
|||||||
* the unique url of the page for which the fields are being initialized
|
* the unique url of the page for which the fields are being initialized
|
||||||
* @param fields The identifiable fields of which the updates are kept track of
|
* @param fields The identifiable fields of which the updates are kept track of
|
||||||
* @param lastModified The last modified date of the object that belongs to the page
|
* @param lastModified The last modified date of the object that belongs to the page
|
||||||
* @param order A custom order to keep track of objects moving around
|
* @param patchOperationServiceToken An InjectionToken referring to the {@link PatchOperationService} used for creating a patch
|
||||||
* @param pageSize The page size used to fill empty pages for the custom order
|
|
||||||
* @param page The first page to populate in the custom order
|
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(
|
||||||
url: string,
|
url: string,
|
||||||
fields: Identifiable[],
|
fields: Identifiable[],
|
||||||
lastModified: Date
|
lastModified: Date,
|
||||||
|
patchOperationServiceToken?: InjectionToken<PatchOperationService>
|
||||||
) {
|
) {
|
||||||
this.payload = { url, fields, lastModified };
|
this.payload = { url, fields, lastModified, patchOperationServiceToken };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +72,6 @@ export class AddFieldUpdateAction implements Action {
|
|||||||
url: string,
|
url: string,
|
||||||
field: Identifiable,
|
field: Identifiable,
|
||||||
changeType: FieldChangeType,
|
changeType: FieldChangeType,
|
||||||
patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,9 +85,8 @@ export class AddFieldUpdateAction implements Action {
|
|||||||
constructor(
|
constructor(
|
||||||
url: string,
|
url: string,
|
||||||
field: Identifiable,
|
field: Identifiable,
|
||||||
changeType: FieldChangeType,
|
changeType: FieldChangeType) {
|
||||||
patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>) {
|
this.payload = { url, field, changeType };
|
||||||
this.payload = { url, field, changeType, patchOperationServiceToken };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,7 +51,6 @@ export interface Identifiable {
|
|||||||
export interface FieldUpdate {
|
export interface FieldUpdate {
|
||||||
field: Identifiable,
|
field: Identifiable,
|
||||||
changeType: FieldChangeType,
|
changeType: FieldChangeType,
|
||||||
patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,6 +91,7 @@ export interface ObjectUpdatesEntry {
|
|||||||
fieldUpdates: FieldUpdates;
|
fieldUpdates: FieldUpdates;
|
||||||
virtualMetadataSources: VirtualMetadataSources;
|
virtualMetadataSources: VirtualMetadataSources;
|
||||||
lastModified: Date;
|
lastModified: Date;
|
||||||
|
patchOperationServiceToken?: InjectionToken<PatchOperationService>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -166,6 +166,7 @@ function initializeFieldsUpdate(state: any, action: InitializeFieldsAction) {
|
|||||||
const url: string = action.payload.url;
|
const url: string = action.payload.url;
|
||||||
const fields: Identifiable[] = action.payload.fields;
|
const fields: Identifiable[] = action.payload.fields;
|
||||||
const lastModifiedServer: Date = action.payload.lastModified;
|
const lastModifiedServer: Date = action.payload.lastModified;
|
||||||
|
const patchOperationServiceToken: InjectionToken<PatchOperationService> = action.payload.patchOperationServiceToken;
|
||||||
const fieldStates = createInitialFieldStates(fields);
|
const fieldStates = createInitialFieldStates(fields);
|
||||||
const newPageState = Object.assign(
|
const newPageState = Object.assign(
|
||||||
{},
|
{},
|
||||||
@@ -173,7 +174,8 @@ function initializeFieldsUpdate(state: any, action: InitializeFieldsAction) {
|
|||||||
{ fieldStates: fieldStates },
|
{ fieldStates: fieldStates },
|
||||||
{ fieldUpdates: {} },
|
{ fieldUpdates: {} },
|
||||||
{ virtualMetadataSources: {} },
|
{ virtualMetadataSources: {} },
|
||||||
{ lastModified: lastModifiedServer }
|
{ lastModified: lastModifiedServer },
|
||||||
|
{ patchOperationServiceToken }
|
||||||
);
|
);
|
||||||
return Object.assign({}, state, { [url]: newPageState });
|
return Object.assign({}, state, { [url]: newPageState });
|
||||||
}
|
}
|
||||||
@@ -187,7 +189,6 @@ function addFieldUpdate(state: any, action: AddFieldUpdateAction) {
|
|||||||
const url: string = action.payload.url;
|
const url: string = action.payload.url;
|
||||||
const field: Identifiable = action.payload.field;
|
const field: Identifiable = action.payload.field;
|
||||||
const changeType: FieldChangeType = action.payload.changeType;
|
const changeType: FieldChangeType = action.payload.changeType;
|
||||||
const patchOperationServiceToken: InjectionToken<PatchOperationService<Identifiable>> = action.payload.patchOperationServiceToken;
|
|
||||||
const pageState: ObjectUpdatesEntry = state[url] || {};
|
const pageState: ObjectUpdatesEntry = state[url] || {};
|
||||||
|
|
||||||
let states = pageState.fieldStates;
|
let states = pageState.fieldStates;
|
||||||
@@ -198,7 +199,7 @@ function addFieldUpdate(state: any, action: AddFieldUpdateAction) {
|
|||||||
let fieldUpdate: any = pageState.fieldUpdates[field.uuid] || {};
|
let fieldUpdate: any = pageState.fieldUpdates[field.uuid] || {};
|
||||||
const newChangeType = determineChangeType(fieldUpdate.changeType, changeType);
|
const newChangeType = determineChangeType(fieldUpdate.changeType, changeType);
|
||||||
|
|
||||||
fieldUpdate = Object.assign({}, { field, changeType: newChangeType, patchOperationServiceToken });
|
fieldUpdate = Object.assign({}, { field, changeType: newChangeType });
|
||||||
|
|
||||||
const fieldUpdates = Object.assign({}, pageState.fieldUpdates, { [field.uuid]: fieldUpdate });
|
const fieldUpdates = Object.assign({}, pageState.fieldUpdates, { [field.uuid]: fieldUpdate });
|
||||||
|
|
||||||
|
@@ -59,9 +59,10 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are being mapped
|
* @param url The page's URL for which the changes are being mapped
|
||||||
* @param fields The initial fields for the page's object
|
* @param fields The initial fields for the page's object
|
||||||
* @param lastModified The date the object was last modified
|
* @param lastModified The date the object was last modified
|
||||||
|
* @param patchOperationServiceToken An InjectionToken referring to the {@link PatchOperationService} used for creating a patch
|
||||||
*/
|
*/
|
||||||
initialize(url, fields: Identifiable[], lastModified: Date): void {
|
initialize(url, fields: Identifiable[], lastModified: Date, patchOperationServiceToken?: InjectionToken<PatchOperationService>): void {
|
||||||
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified));
|
this.store.dispatch(new InitializeFieldsAction(url, fields, lastModified, patchOperationServiceToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,8 +71,8 @@ export class ObjectUpdatesService {
|
|||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
* @param changeType The last type of change applied to this field
|
* @param changeType The last type of change applied to this field
|
||||||
*/
|
*/
|
||||||
private saveFieldUpdate(url: string, field: Identifiable, changeType: FieldChangeType, patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>) {
|
private saveFieldUpdate(url: string, field: Identifiable, changeType: FieldChangeType) {
|
||||||
this.store.dispatch(new AddFieldUpdateAction(url, field, changeType, patchOperationServiceToken))
|
this.store.dispatch(new AddFieldUpdateAction(url, field, changeType))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -188,8 +189,8 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
*/
|
*/
|
||||||
saveAddFieldUpdate(url: string, field: Identifiable, patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>) {
|
saveAddFieldUpdate(url: string, field: Identifiable) {
|
||||||
this.saveFieldUpdate(url, field, FieldChangeType.ADD, patchOperationServiceToken);
|
this.saveFieldUpdate(url, field, FieldChangeType.ADD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -197,8 +198,8 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
*/
|
*/
|
||||||
saveRemoveFieldUpdate(url: string, field: Identifiable, patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>) {
|
saveRemoveFieldUpdate(url: string, field: Identifiable) {
|
||||||
this.saveFieldUpdate(url, field, FieldChangeType.REMOVE, patchOperationServiceToken);
|
this.saveFieldUpdate(url, field, FieldChangeType.REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,8 +207,8 @@ export class ObjectUpdatesService {
|
|||||||
* @param url The page's URL for which the changes are saved
|
* @param url The page's URL for which the changes are saved
|
||||||
* @param field An updated field for the page's object
|
* @param field An updated field for the page's object
|
||||||
*/
|
*/
|
||||||
saveChangeFieldUpdate(url: string, field: Identifiable, patchOperationServiceToken?: InjectionToken<PatchOperationService<Identifiable>>) {
|
saveChangeFieldUpdate(url: string, field: Identifiable) {
|
||||||
this.saveFieldUpdate(url, field, FieldChangeType.UPDATE, patchOperationServiceToken);
|
this.saveFieldUpdate(url, field, FieldChangeType.UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -345,18 +346,17 @@ export class ObjectUpdatesService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a patch from the current object-updates state
|
* Create a patch from the current object-updates state
|
||||||
|
* The {@link ObjectUpdatesEntry} should contain a patchOperationServiceToken, in order to define how a patch should
|
||||||
|
* be created. If it doesn't, an empty patch will be returned.
|
||||||
* @param url The URL of the page for which the patch should be created
|
* @param url The URL of the page for which the patch should be created
|
||||||
*/
|
*/
|
||||||
createPatch(url: string): Observable<Operation[]> {
|
createPatch(url: string): Observable<Operation[]> {
|
||||||
return this.getObjectEntry(url).pipe(
|
return this.getObjectEntry(url).pipe(
|
||||||
map((entry) => {
|
map((entry) => {
|
||||||
const patch = [];
|
let patch = [];
|
||||||
Object.keys(entry.fieldUpdates).forEach((uuid) => {
|
if (hasValue(entry.patchOperationServiceToken)) {
|
||||||
const update = entry.fieldUpdates[uuid];
|
patch = this.injector.get(entry.patchOperationServiceToken).fieldUpdatesToPatchOperations(entry.fieldUpdates);
|
||||||
if (hasValue(update.patchOperationServiceToken)) {
|
|
||||||
patch.push(this.injector.get(update.patchOperationServiceToken).fieldUpdateToPatchOperation(update));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
return patch;
|
return patch;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
import { Operation } from 'fast-json-patch';
|
||||||
|
import { hasValue } from '../../../../shared/empty.util';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper object for metadata patch Operations
|
||||||
|
* It contains the operation type, metadata field, metadata place and patch value, as well as a method to transform it
|
||||||
|
* into a fast-json-patch Operation.
|
||||||
|
*/
|
||||||
|
export class MetadataPatchOperation {
|
||||||
|
op: string;
|
||||||
|
field: string;
|
||||||
|
place: number;
|
||||||
|
value: any;
|
||||||
|
|
||||||
|
constructor(op: string, field: string, place?: number, value?: any) {
|
||||||
|
this.op = op;
|
||||||
|
this.field = field;
|
||||||
|
this.place = place;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform the MetadataPatchOperation into a fast-json-patch Operation by constructing its path and other properties
|
||||||
|
* using the information provided.
|
||||||
|
*/
|
||||||
|
toOperation(): Operation {
|
||||||
|
let path = `/metadata/${this.field}`;
|
||||||
|
if (hasValue(this.place)) {
|
||||||
|
path += `/${this.place}`;
|
||||||
|
}
|
||||||
|
return { op: this.op as any, path, value: this.value };
|
||||||
|
}
|
||||||
|
}
|
@@ -1,29 +1,103 @@
|
|||||||
import { PatchOperationService } from './patch-operation.service';
|
import { PatchOperationService } from './patch-operation.service';
|
||||||
import { MetadataValue, MetadatumViewModel } from '../../../shared/metadata.models';
|
import { MetadatumViewModel } from '../../../shared/metadata.models';
|
||||||
import { FieldUpdate } from '../object-updates.reducer';
|
import { FieldUpdates } from '../object-updates.reducer';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
import { FieldChangeType } from '../object-updates.actions';
|
import { FieldChangeType } from '../object-updates.actions';
|
||||||
import { InjectionToken } from '@angular/core';
|
import { InjectionToken } from '@angular/core';
|
||||||
|
import { MetadataPatchOperation } from './metadata-patch-operation.model';
|
||||||
|
import { hasValue } from '../../../../shared/empty.util';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Token to use for injecting this service anywhere you want
|
||||||
|
* This token can used to store in the object-updates store
|
||||||
|
*/
|
||||||
export const METADATA_PATCH_OPERATION_SERVICE_TOKEN = new InjectionToken<MetadataPatchOperationService>('MetadataPatchOperationService', {
|
export const METADATA_PATCH_OPERATION_SERVICE_TOKEN = new InjectionToken<MetadataPatchOperationService>('MetadataPatchOperationService', {
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
factory: () => new MetadataPatchOperationService(),
|
factory: () => new MetadataPatchOperationService(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export class MetadataPatchOperationService implements PatchOperationService<MetadatumViewModel> {
|
/**
|
||||||
fieldUpdateToPatchOperation(fieldUpdate: FieldUpdate): Operation {
|
* Service transforming {@link FieldUpdates} into {@link Operation}s for metadata values
|
||||||
const metadatum = fieldUpdate.field as MetadatumViewModel;
|
* This expects the fields within every {@link FieldUpdate} to be {@link MetadatumViewModel}s
|
||||||
const path = `/metadata/${metadatum.key}`;
|
*/
|
||||||
|
export class MetadataPatchOperationService implements PatchOperationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a {@link FieldUpdates} object into an array of fast-json-patch Operations for metadata values
|
||||||
|
* This method first creates an array of {@link MetadataPatchOperation} wrapper operations, which are then
|
||||||
|
* iterated over to create the actual patch operations. While iterating, it has the ability to check for previous
|
||||||
|
* operations that would modify the operation's position and act accordingly.
|
||||||
|
* @param fieldUpdates
|
||||||
|
*/
|
||||||
|
fieldUpdatesToPatchOperations(fieldUpdates: FieldUpdates): Operation[] {
|
||||||
|
const metadataPatch = this.fieldUpdatesToMetadataPatchOperations(fieldUpdates);
|
||||||
|
|
||||||
|
// This map stores what metadata fields had a value deleted at which places
|
||||||
|
// This is used to modify the place of operations to match previous operations
|
||||||
|
const metadataRemoveMap = new Map<string, number[]>();
|
||||||
|
const patch = [];
|
||||||
|
metadataPatch.forEach((operation) => {
|
||||||
|
// If this operation is removing or editing an existing value, first check the map for previous operations
|
||||||
|
// If the map contains remove operations before this operation's place, lower the place by 1 for each
|
||||||
|
if ((operation.op === 'remove' || operation.op === 'replace') && hasValue(operation.place)) {
|
||||||
|
if (metadataRemoveMap.has(operation.field)) {
|
||||||
|
metadataRemoveMap.get(operation.field).forEach((index) => {
|
||||||
|
if (index < operation.place) {
|
||||||
|
operation.place--;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this is a remove operation, add its (updated) place to the map, so we can adjust following operations accordingly
|
||||||
|
if (operation.op === 'remove' && hasValue(operation.place)) {
|
||||||
|
if (!metadataRemoveMap.has(operation.field)) {
|
||||||
|
metadataRemoveMap.set(operation.field, []);
|
||||||
|
}
|
||||||
|
metadataRemoveMap.get(operation.field).push(operation.place);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform the updated operation into a fast-json-patch Operation and add it to the patch
|
||||||
|
patch.push(operation.toOperation());
|
||||||
|
});
|
||||||
|
|
||||||
|
return patch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform a {@link FieldUpdates} object into an array of {@link MetadataPatchOperation} wrapper objects
|
||||||
|
* These wrapper objects contain detailed information about the patch operation that needs to be creates for each update
|
||||||
|
* This information can then be modified before creating the actual patch
|
||||||
|
* @param fieldUpdates
|
||||||
|
*/
|
||||||
|
fieldUpdatesToMetadataPatchOperations(fieldUpdates: FieldUpdates): MetadataPatchOperation[] {
|
||||||
|
const metadataPatch = [];
|
||||||
|
|
||||||
|
Object.keys(fieldUpdates).forEach((uuid) => {
|
||||||
|
const update = fieldUpdates[uuid];
|
||||||
|
const metadatum = update.field as MetadatumViewModel;
|
||||||
const val = {
|
const val = {
|
||||||
value: metadatum.value,
|
value: metadatum.value,
|
||||||
language: metadatum.language
|
language: metadatum.language
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fieldUpdate.changeType) {
|
let operation: MetadataPatchOperation;
|
||||||
case FieldChangeType.ADD: return { op: 'add', path, value: [ val ] };
|
switch (update.changeType) {
|
||||||
case FieldChangeType.REMOVE: return { op: 'remove', path: `${path}/${metadatum.place}` };
|
case FieldChangeType.ADD:
|
||||||
case FieldChangeType.UPDATE: return { op: 'replace', path: `${path}/${metadatum.place}`, value: val };
|
operation = new MetadataPatchOperation('add', metadatum.key, undefined, [ val ]);
|
||||||
default: return undefined;
|
break;
|
||||||
|
case FieldChangeType.REMOVE:
|
||||||
|
operation = new MetadataPatchOperation('remove', metadatum.key, metadatum.place);
|
||||||
|
break;
|
||||||
|
case FieldChangeType.UPDATE:
|
||||||
|
operation = new MetadataPatchOperation('replace', metadatum.key, metadatum.place, val);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
metadataPatch.push(operation);
|
||||||
|
});
|
||||||
|
|
||||||
|
return metadataPatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,15 @@
|
|||||||
import { FieldUpdate, Identifiable } from '../object-updates.reducer';
|
import { FieldUpdates } from '../object-updates.reducer';
|
||||||
import { Operation } from 'fast-json-patch';
|
import { Operation } from 'fast-json-patch';
|
||||||
|
|
||||||
export interface PatchOperationService<T extends Identifiable> {
|
/**
|
||||||
fieldUpdateToPatchOperation(fieldUpdate: FieldUpdate): Operation;
|
* Interface for a service dealing with the transformations of patch operations from the object-updates store
|
||||||
|
* The implementations of this service know how to deal with the fields of a FieldUpdate and how to transform them
|
||||||
|
* into patch Operations.
|
||||||
|
*/
|
||||||
|
export interface PatchOperationService {
|
||||||
|
/**
|
||||||
|
* Transform a {@link FieldUpdates} object into an array of fast-json-patch Operations
|
||||||
|
* @param fieldUpdates
|
||||||
|
*/
|
||||||
|
fieldUpdatesToPatchOperations(fieldUpdates: FieldUpdates): Operation[];
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user