From 21df5421fbead06afaecc0e11189e3ce6746e128 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Wed, 10 Mar 2021 14:13:39 +0100 Subject: [PATCH] Field rule context. (#668) --- .../pages/content/content-page.component.ts | 9 +++++---- .../references/content-creator.component.ts | 2 +- .../shared/state/contents.forms-helpers.ts | 4 ++-- .../app/shared/state/contents.forms.spec.ts | 19 +++++++++++++++++++ frontend/app/shared/state/contents.forms.ts | 10 ++++++++-- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/frontend/app/features/content/pages/content/content-page.component.ts b/frontend/app/features/content/pages/content/content-page.component.ts index dc76791fd..4bfc34236 100644 --- a/frontend/app/features/content/pages/content/content-page.component.ts +++ b/frontend/app/features/content/pages/content/content-page.component.ts @@ -88,7 +88,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD .subscribe(schema => { this.schema = schema; - this.contentForm = new EditContentForm(this.languages, this.schema, this.formContext.user); + this.contentForm = new EditContentForm(this.languages, this.schema, this.formContext); })); this.own( @@ -96,9 +96,10 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD .subscribe(content => { const isNewContent = isOtherContent(content, this.content); - this.content = content; + this.formContext['initialContent'] = content; - this.formContext['initialContent'] = this.content; + this.content = content; + this.contentForm.setContext(this.formContext); this.autoSaveKey = { schemaId: this.schema.id, @@ -251,7 +252,7 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD this.contentsState.loadVersion(content, version) .subscribe(dto => { if (compare) { - this.contentFormCompare = new EditContentForm(this.languages, this.schema, this.formContext.user); + this.contentFormCompare = new EditContentForm(this.languages, this.schema, this.formContext); this.contentFormCompare.load(dto.payload); this.contentFormCompare.setEnabled(false); diff --git a/frontend/app/features/content/shared/references/content-creator.component.ts b/frontend/app/features/content/shared/references/content-creator.component.ts index e0c3d10df..a7d0a2344 100644 --- a/frontend/app/features/content/shared/references/content-creator.component.ts +++ b/frontend/app/features/content/shared/references/content-creator.component.ts @@ -66,7 +66,7 @@ export class ContentCreatorComponent extends ResourceOwner implements OnInit { this.schema = schema; this.contentsState.schema = schema; - this.contentForm = new EditContentForm(this.languages, this.schema, this.formContext.user); + this.contentForm = new EditContentForm(this.languages, this.schema, { user: this.formContext.user }); this.changeDetector.markForCheck(); } diff --git a/frontend/app/shared/state/contents.forms-helpers.ts b/frontend/app/shared/state/contents.forms-helpers.ts index 809844185..8e0b8b12a 100644 --- a/frontend/app/shared/state/contents.forms-helpers.ts +++ b/frontend/app/shared/state/contents.forms-helpers.ts @@ -89,7 +89,7 @@ export class CompiledRule { private readonly rule: FieldRule ) { try { - this.function = new Function(`return function(user, data, itemData) { return ${rule.condition} }`)(); + this.function = new Function(`return function(user, ctx, data, itemData) { return ${rule.condition} }`)(); } catch { this.function = () => false; } @@ -97,7 +97,7 @@ export class CompiledRule { public eval(context: RuleContext) { try { - return this.function(context.user, context.data, context.itemData); + return this.function(context.user, context, context.data, context.itemData); } catch { return false; } diff --git a/frontend/app/shared/state/contents.forms.spec.ts b/frontend/app/shared/state/contents.forms.spec.ts index ac451f247..ca39467e5 100644 --- a/frontend/app/shared/state/contents.forms.spec.ts +++ b/frontend/app/shared/state/contents.forms.spec.ts @@ -276,6 +276,25 @@ describe('ContentForm', () => { expectForm(contentForm.form, 'field3.de', { invalid: false }); }); + it('should require field based on context condition', () => { + const contentForm = createForm([ + createField({ id: 1, properties: createProperties('Number'), partitioning: 'invariant' }), + createField({ id: 2, properties: createProperties('Number'), partitioning: 'invariant' }) + ], [{ + field: 'field1', action: 'Require', condition: 'ctx.value < 100' + }]); + + contentForm.setContext({ value: 50 }); + + const field1 = contentForm.get('field1')!.get('iv'); + + expect(field1!.form.valid).toBeFalsy(); + + contentForm.setContext({ value: 120 }); + + expect(field1!.form.valid).toBeTruthy(); + }); + it('should require field based on condition', () => { const contentForm = createForm([ createField({ id: 1, properties: createProperties('Number'), partitioning: 'invariant' }), diff --git a/frontend/app/shared/state/contents.forms.ts b/frontend/app/shared/state/contents.forms.ts index 32dcca927..5ffded248 100644 --- a/frontend/app/shared/state/contents.forms.ts +++ b/frontend/app/shared/state/contents.forms.ts @@ -92,7 +92,7 @@ export class EditContentForm extends Form { } constructor(languages: ReadonlyArray, schema: SchemaDetailsDto, - private readonly user: any = {}, debounce = 100 + private context: any, debounce = 100 ) { super(new FormGroup({})); @@ -184,6 +184,12 @@ export class EditContentForm extends Form { this.updateState(this.value); } + public setContext(context?: any) { + this.context = context; + + this.updateState(this.value); + } + public submitCompleted(options?: { newValue?: any, noReset?: boolean }) { super.submitCompleted(options); @@ -191,7 +197,7 @@ export class EditContentForm extends Form { } private updateState(data: any) { - const context = { user: this.user, data }; + const context = { ...this.context || {}, data }; for (const field of Object.values(this.fields)) { field.updateState(context, { isDisabled: this.form.disabled });