diff --git a/example/assets/mock-data/patches.json b/example/assets/mock-data/patches.json index 55aa4b55..ff39567a 100644 --- a/example/assets/mock-data/patches.json +++ b/example/assets/mock-data/patches.json @@ -14,6 +14,13 @@ "path": "/references/0/reference/misc/0", "value": "A Misc Thing" }, + { + "op": "add", + "path": "/references/0/reference/publication_info", + "value": { + "journal_title": "Patch Title" + } + }, { "op": "add", "path": "/references/1/reference/misc/-", @@ -26,6 +33,11 @@ "value": "New Collaboration" } }, + { + "op": "add", + "path": "/references/1/reference/texkey", + "value": "valuueee123" + }, { "op": "add", "path": "/references/-", diff --git a/src/abstract-field/abstract-field.component.ts b/src/abstract-field/abstract-field.component.ts index c393688c..0a223170 100644 --- a/src/abstract-field/abstract-field.component.ts +++ b/src/abstract-field/abstract-field.component.ts @@ -24,7 +24,7 @@ import { OnInit, OnDestroy, ChangeDetectorRef, OnChanges, SimpleChanges } from ' import { AbstractSubscriberComponent } from '../abstract-subscriber'; import { AppGlobalsService, PathUtilService, JsonStoreService, ProblemsService } from '../shared/services'; -import { ValidationProblem, PathCache, JSONSchema, JsonPatch } from '../shared/interfaces'; +import { ValidationProblem, PathCache, JSONSchema, JsonPatch, JsonPatchesByOp } from '../shared/interfaces'; /** * This is the base class for fields @@ -43,10 +43,13 @@ export abstract class AbstractFieldComponent extends AbstractSubscriberComponent pathCache: PathCache = {}; externalErrors: Array = []; schema: JSONSchema; - jsonPatches: Array = []; - // used by some components to display remove patch in a different way. + + // patches grouped by op because they different UI representation + replaceJsonPatches: Array = []; + addJsonPatches: Array = []; removeJsonPatch: JsonPatch; + constructor(public appGlobalsService: AppGlobalsService, public problemsService: ProblemsService, public pathUtilService: PathUtilService, @@ -62,17 +65,36 @@ export abstract class AbstractFieldComponent extends AbstractSubscriberComponent this.externalErrors = externalCategorizedProblemMap.errors[this.pathString] || []; this.changeDetectorRef.markForCheck(); }); + this.jsonStoreService.patchesByPath$ .map(patchesByPath => patchesByPath[this.pathString]) + .map(patches => this.groupJsonPatchesByOp(patches)) .takeUntil(this.isDestroyed) - .subscribe(patches => { - this.jsonPatches = patches || []; - this.removeJsonPatch = this.jsonPatches - .find(patch => patch.op === 'remove'); + .subscribe(patchesByOp => { + this.removeJsonPatch = patchesByOp.remove[0]; + this.addJsonPatches = patchesByOp.add; + this.replaceJsonPatches = patchesByOp.replace; this.changeDetectorRef.markForCheck(); }); } + private groupJsonPatchesByOp(patches: Array): JsonPatchesByOp { + const group: JsonPatchesByOp = { + add: [], + remove: [], + replace: [] + }; + + if (patches) { + patches.forEach((patch) => { + const opPatches = group[patch.op]; + opPatches.push(patch); + }); + } + + return group; + } + ngOnChanges(changes: SimpleChanges) { if (changes['path']) { this.pathString = this.pathUtilService.toPathString(this.path); diff --git a/src/abstract-list-field/abstract-list-field.component.ts b/src/abstract-list-field/abstract-list-field.component.ts index fcf00109..cbd846d0 100644 --- a/src/abstract-list-field/abstract-list-field.component.ts +++ b/src/abstract-list-field/abstract-list-field.component.ts @@ -66,10 +66,4 @@ export abstract class AbstractListFieldComponent extends AbstractFieldComponent getPathStringForChild(index: number): string { return `${this.pathString}${this.pathUtilService.separator}${index}`; } - - get addJsonPatches(): Array { - return this.jsonPatches - .filter(patch => patch.op === 'add'); - } - } diff --git a/src/object-field/object-field.component.html b/src/object-field/object-field.component.html index 02883e1d..0f674522 100644 --- a/src/object-field/object-field.component.html +++ b/src/object-field/object-field.component.html @@ -23,6 +23,16 @@ + + + + + + + + + + diff --git a/src/primitive-field/primitive-field.component.html b/src/primitive-field/primitive-field.component.html index dbac7fed..57bda872 100644 --- a/src/primitive-field/primitive-field.component.html +++ b/src/primitive-field/primitive-field.component.html @@ -1,4 +1,4 @@ -
+
@@ -11,7 +11,7 @@ - + + +
+ (onSelect)="onSearchableDropdownSelect($event)" [displayValueMap]="schema.enumDisplayValueMap" [tabIndex]="tabIndex" + (onBlur)="onBlur()">
- - - - + + + \ No newline at end of file diff --git a/src/primitive-field/primitive-field.component.ts b/src/primitive-field/primitive-field.component.ts index 40d3f42c..b308d644 100644 --- a/src/primitive-field/primitive-field.component.ts +++ b/src/primitive-field/primitive-field.component.ts @@ -157,7 +157,7 @@ export class PrimitiveFieldComponent extends AbstractFieldComponent implements O } get errorClass(): string { - return !this.jsonPatches[0] && this.hasErrors() ? 'error' : ''; + return !this.replaceJsonPatches[0] && this.hasErrors() ? 'error' : ''; } get isPathToAnIndex(): boolean { diff --git a/src/shared/interfaces/index.ts b/src/shared/interfaces/index.ts index 9a23af5c..bc0dda23 100644 --- a/src/shared/interfaces/index.ts +++ b/src/shared/interfaces/index.ts @@ -24,6 +24,7 @@ export { KatexData } from './katex-data'; export { JsonPatch } from './json-patch'; export { CustomFormatValidation } from './custom-format-validation'; export { JsonPatchesByPath } from './json-patches-by-path'; +export { JsonPatchesByOp } from './json-patches-by-op'; export { ViewTemplateConfig } from './view-template-config'; export { ShortcutActionFunction } from './shortcut-action-function'; export { CustomValidationMessages } from './custom-validation-messages'; diff --git a/src/shared/interfaces/json-patches-by-op.ts b/src/shared/interfaces/json-patches-by-op.ts new file mode 100644 index 00000000..d13bb7bc --- /dev/null +++ b/src/shared/interfaces/json-patches-by-op.ts @@ -0,0 +1,7 @@ +import { JsonPatch } from './json-patch'; + +export interface JsonPatchesByOp { + add: Array; + remove: Array; + replace: Array; +} diff --git a/src/shared/pipes/last-path-element.pipe.ts b/src/shared/pipes/last-path-element.pipe.ts index aa84e8a5..fe513fa3 100644 --- a/src/shared/pipes/last-path-element.pipe.ts +++ b/src/shared/pipes/last-path-element.pipe.ts @@ -35,7 +35,7 @@ export class LastPathElementPipe implements PipeTransform { constructor(private pathUtilService: PathUtilService) { } transform(path: string): string { - const elements = path.split(this.pathUtilService.separator); - return elements[elements.length - 1]; + return path + .substring(path.lastIndexOf('/') + 1); } } diff --git a/src/shared/services/json-store.service.ts b/src/shared/services/json-store.service.ts index 3891cc10..457e3656 100644 --- a/src/shared/services/json-store.service.ts +++ b/src/shared/services/json-store.service.ts @@ -225,19 +225,15 @@ export class JsonStoreService { private getComponentPathForPatch(patch: JsonPatch): string { if (patch.op === 'add') { - return this.convertElementPathToParentArrayPath(patch.path); + // add patches handled by parent component + return this.getParentPath(patch.path); } return patch.path; } - private convertElementPathToParentArrayPath(path: string): string { + private getParentPath(path: string): string { const pathArray = this.pathUtilService.toPathArray(path); - const lastPathElement = pathArray[pathArray.length - 1]; - if (lastPathElement === '-' || !isNaN(Number(lastPathElement))) { - pathArray.pop(); - return this.pathUtilService.toPathString(pathArray); - } else { - return path; - } + const parentPathArray = pathArray.slice(0, -1); + return this.pathUtilService.toPathString(parentPathArray); } }