diff --git a/back/app/template/models.py b/back/app/template/models.py index afedeca4..951b1e25 100644 --- a/back/app/template/models.py +++ b/back/app/template/models.py @@ -40,7 +40,8 @@ class ProvisionTemplateReference(BaseModel): "schema": "ProvisionTemplate", "displayedFields": ['title', 'body'] }, - } + }, + props={"parametrized": True} ) @@ -56,6 +57,9 @@ class ContractTemplate(CrudDocument): default=[], props={"items-per-row": "1", "numbered": True} ) - variables: List[DictionaryEntry] = Field(default=[], format="dictionary") + variables: List[DictionaryEntry] = Field( + default=[], + format="dictionary", + ) diff --git a/back/app/template/schemas.py b/back/app/template/schemas.py index b7a895c0..c6d8d9df 100644 --- a/back/app/template/schemas.py +++ b/back/app/template/schemas.py @@ -1,7 +1,7 @@ -from pydantic import BaseModel +from pydantic import BaseModel, Field from typing import List -from .models import ContractTemplate, ProvisionTemplate, PartyTemplate, ProvisionTemplateReference +from .models import ContractTemplate, ProvisionTemplate, PartyTemplate, ProvisionTemplateReference, DictionaryEntry from ..core.schemas import Writer from ..core.models import text_area @@ -17,6 +17,11 @@ class ContractTemplateCreate(Writer): class ContractTemplateUpdate(BaseModel): name: str parties: List[PartyTemplate] = [] + variables: List[DictionaryEntry] = Field( + default=[], + format="dictionary", + props={"required": False} + ) provisions: List[ProvisionTemplateReference] = [] diff --git a/front/app/src/common/crud/card/card.component.ts b/front/app/src/common/crud/card/card.component.ts index d795d275..f3964471 100644 --- a/front/app/src/common/crud/card/card.component.ts +++ b/front/app/src/common/crud/card/card.component.ts @@ -19,6 +19,7 @@ export class CardComponent implements OnInit { @Input() is_modal: Boolean = false; @Output() resourceCreated: EventEmitter = new EventEmitter(); + @Output() resourceUpdated: EventEmitter = new EventEmitter(); @Output() resourceDeleted: EventEmitter = new EventEmitter(); @@ -81,6 +82,7 @@ export class CardComponent implements OnInit { this.crudService.update(this.resource!, model).subscribe((model: any) => { this.model = model; this._modelLoading$.next(false); + this.resourceUpdated.emit(model._id) }); } } diff --git a/front/app/src/common/crud/crud-formly-jsonschema.service.ts b/front/app/src/common/crud/crud-formly-jsonschema.service.ts index 06691157..72c392cf 100644 --- a/front/app/src/common/crud/crud-formly-jsonschema.service.ts +++ b/front/app/src/common/crud/crud-formly-jsonschema.service.ts @@ -45,6 +45,8 @@ export class CrudFormlyJsonschemaOptions implements FormlyJsonschemaOptions { field.type = "date"; } else if (schema.hasOwnProperty('enum') && schema.enum.length == 1 && schema.enum[0] == schema.default ) { field.type = "hidden"; + } else if (schema.type == "array" && schema.format == "dictionary") { + field.type = "dictionary"; } if (schema.hasOwnProperty('props')) { diff --git a/front/app/src/common/crud/crud.module.ts b/front/app/src/common/crud/crud.module.ts index 946cfdcc..184b51ab 100644 --- a/front/app/src/common/crud/crud.module.ts +++ b/front/app/src/common/crud/crud.module.ts @@ -20,6 +20,8 @@ import { JsonschemasService } from "./jsonschemas.service"; import { MultiSchemaTypeComponent } from "./types/multischema.type"; import { ForeignkeyTypeComponent } from "./types/foreignkey.type"; import {HiddenTypeComponent} from "./types/hidden.type"; +import {DictionaryTypeComponent} from "./types/dictionary.type"; +import {DictionaryService} from "./types/dictionary.service"; @NgModule({ @@ -33,8 +35,15 @@ import {HiddenTypeComponent} from "./types/hidden.type"; MultiSchemaTypeComponent, ForeignkeyTypeComponent, HiddenTypeComponent, + DictionaryTypeComponent + ], + providers: [ + JsonschemasService, + ApiService, + CrudService, + CrudFormlyJsonschemaService, + DictionaryService ], - providers: [ JsonschemasService, ApiService, CrudService, CrudFormlyJsonschemaService ], imports: [ CommonModule, HttpClientModule, @@ -51,6 +60,7 @@ import {HiddenTypeComponent} from "./types/hidden.type"; { name: 'multischema', component: MultiSchemaTypeComponent }, { name: 'foreign-key', component: ForeignkeyTypeComponent }, { name: 'hidden', component: HiddenTypeComponent }, + { name: 'dictionary', component: DictionaryTypeComponent }, ] }), FormlyBootstrapModule diff --git a/front/app/src/common/crud/types/dictionary.service.ts b/front/app/src/common/crud/types/dictionary.service.ts new file mode 100644 index 00000000..5271d8f8 --- /dev/null +++ b/front/app/src/common/crud/types/dictionary.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import {Observable, Subject} from "rxjs"; + +@Injectable() +export class DictionaryService { + fieldsParameters: {[field_id: string]: string[]} = {} + parameters: string[] = [] + parameters$: Subject = new Subject() + + updateParameters(field_id: string, newParameters: string[]) { + this.fieldsParameters[field_id] = newParameters; + + this.parameters = [].concat(); + for (const field of Object.values(this.fieldsParameters)) { + this.parameters = this.parameters.concat(field); + } + this.parameters = this.parameters.filter( + (item,index) => this.parameters.indexOf(item) === index + ); + + this.parameters$.next(this.parameters) + } +} \ No newline at end of file diff --git a/front/app/src/common/crud/types/dictionary.type.ts b/front/app/src/common/crud/types/dictionary.type.ts new file mode 100644 index 00000000..d876baa9 --- /dev/null +++ b/front/app/src/common/crud/types/dictionary.type.ts @@ -0,0 +1,97 @@ +import { Component, OnInit } from '@angular/core'; +import {FieldType, FieldTypeConfig, FormlyFieldConfig, FormlyFormOptions} from '@ngx-formly/core'; +import {FormControl, FormGroup, FormArray} from "@angular/forms"; +import {DictionaryService} from "./dictionary.service"; +import {JSONSchema7} from "json-schema"; +import {FormlyJsonschema} from "@ngx-formly/core/json-schema"; + +@Component({ + selector: 'formly-dictionary-type', + template: ` +
+ + + + + + + + + + + +
+ `, +}) +export class DictionaryTypeComponent extends FieldType implements OnInit +{ + public errorMsg: string = ""; + + parameterForm: FormGroup = new FormGroup({}); + parameterList: string[] = []; + parameterModel: {[field_id: string]: string} = {}; + parameterFields: FormlyFieldConfig[] = []; + + constructor(protected service: DictionaryService, + private formlyJsonschema: FormlyJsonschema) { + super(); + } + + ngOnInit() { + for (const entry of this.formControl.value) { + this.parameterModel[entry.key] = entry.value; + } + + this.service.parameters$.subscribe((parameters) => { + this.parameterList = parameters; + for (const pname of parameters) { + if (Object.keys(this.parameterModel).indexOf(pname) == -1) { + this.parameterModel[pname] = ""; + } + } + + this.parameterFields = [this.formlyJsonschema.toFieldConfig( + this.getFormSchema(parameters) + )]; + this.parameterForm.setValue(this.parameterModel, {emitEvent: false}); + }); + + this.parameterForm.valueChanges.subscribe((values) => { + this.parameterModel = values; + + const formValue: { key :string, value: string }[] = [] + for (const [key, value] of Object.entries(this.parameterModel)) { + formValue.push({key, value}); + } + this.formControl.setValue(formValue) + }) + } + + getFormSchema(properties: string[]) { + const schema: JSONSchema7 = { + type: "object", + properties: { + }, + }; + let required: string[] = [] + for (const pname of properties) { + schema.properties![pname] = { + type: "string", + title: pname + } + if (this.field.props.required) { + required.push(pname) + } + } + schema.required = required + + return schema + } + + +} diff --git a/front/app/src/common/crud/types/foreignkey.type.ts b/front/app/src/common/crud/types/foreignkey.type.ts index 6bf9d728..53246017 100644 --- a/front/app/src/common/crud/types/foreignkey.type.ts +++ b/front/app/src/common/crud/types/foreignkey.type.ts @@ -7,6 +7,7 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { CrudService, Filters } from "../crud.service"; import { CrudFormlyJsonschemaService } from "../crud-formly-jsonschema.service"; import { FormGroup } from "@angular/forms"; +import {DictionaryService} from "./dictionary.service"; @Component({ selector: 'formly-foreignkey-type', @@ -61,13 +62,14 @@ import { FormGroup } from "@angular/forms"; [resource_id]="this.foreignModel._id" [schema]="this.foreignSchema" [is_modal]="true" - (resourceDeleted)="onResourceDeleted($event)"> + (resourceDeleted)="onResourceDeleted($event)" + (resourceUpdated)="onResourceModified($event)"> + (resourceCreated)="onResourceModified($event)">