From 58830d9f8d7f49b7498dd10a09197a8adcf86ae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Ma=C5=BE=C3=A1ri?= Date: Wed, 4 Dec 2024 07:29:13 +0100 Subject: [PATCH 1/5] [NAB-368] - Component parameters - add interface definitions for field list - add new component definitions - add default component properties --- .../field-list/field-list.component.ts | 17 ++++-- .../field-list/field-list.service.ts | 61 +++++++++++++++---- .../form-builder/gridster/gridster.service.ts | 2 +- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/app/form-builder/field-list/field-list.component.ts b/src/app/form-builder/field-list/field-list.component.ts index 3c19f36..9cdcf66 100644 --- a/src/app/form-builder/field-list/field-list.component.ts +++ b/src/app/form-builder/field-list/field-list.component.ts @@ -3,8 +3,8 @@ import {MatDialog} from '@angular/material/dialog'; import {ModelService} from '../../modeler/services/model/model.service'; import {GridsterService} from '../gridster/gridster.service'; import {Router} from '@angular/router'; -import {FieldListService} from './field-list.service'; -import {DataType, DataVariable} from '@netgrif/petriflow'; +import {ComponentDef, FieldListService} from './field-list.service'; +import {DataType, DataVariable, Property} from '@netgrif/petriflow'; import {timer} from 'rxjs'; import {MatExpansionPanel} from '@angular/material/expansion'; import {MatSnackBar} from '@angular/material/snack-bar'; @@ -104,10 +104,10 @@ export class FieldListComponent implements OnInit, AfterViewInit { if (datafield.component?.name) { const meta = this.fieldListService.fieldListArray.find(type => type.type === datafield.type).components.find(c => c?.name === datafield.component.name); if (meta?.rows) { - $event.dataTransfer.setData('rows', meta.rows); + $event.dataTransfer.setData('rows', `${meta.rows}`); } if (meta?.cols) { - $event.dataTransfer.setData('cols', meta.cols); + $event.dataTransfer.setData('cols', `${meta.cols}`); } } this.dragStartHandler($event, true); @@ -141,13 +141,18 @@ export class FieldListComponent implements OnInit, AfterViewInit { this.addDataRef(field, meta); } - private addDataRef(data: DataVariable, meta: any) { - this.gridsterService.addDataRef(data, meta.rows, meta.cols, meta.name, { + private addDataRef(data: DataVariable, meta: ComponentDef) { + const dataRef = this.gridsterService.addDataRef(data, meta.rows, meta.cols, meta.name, { x: 0, y: 0, rows: meta.rows, cols: meta.cols } as GridsterItem); + if (meta.name && meta.properties) { + for (const property of meta.properties) { + dataRef.component.properties.push(new Property(property.name, property.defaultValue)); + } + } this.gridsterService.options.api.optionsChanged(); } diff --git a/src/app/form-builder/field-list/field-list.service.ts b/src/app/form-builder/field-list/field-list.service.ts index 478d8c6..f4ad72c 100644 --- a/src/app/form-builder/field-list/field-list.service.ts +++ b/src/app/form-builder/field-list/field-list.service.ts @@ -1,8 +1,26 @@ import {Injectable} from '@angular/core'; import {Subject} from 'rxjs'; -import {DataType} from '@netgrif/petriflow'; +import {DataType, Property} from '@netgrif/petriflow'; import {GridsterDataField} from '../gridster/classes/gridster-data-field'; +export interface PropertyDef { + name: string; + defaultValue: any; +} + +export interface ComponentDef { + title: string; + name?: string; + rows?: number; + cols?: number; + properties?: Array; +} + +export interface DataRefDef { + type: DataType; + components: Array; +} + @Injectable({ providedIn: 'root' }) @@ -11,7 +29,7 @@ export class FieldListService { static DEFAULT_FIELD_COLS = 2; static DEFAULT_FIELD_ROWS = 1; - fieldListArray: any = [ + fieldListArray: Array = [ { type: DataType.TEXT, components: [ @@ -19,14 +37,31 @@ export class FieldListService { {title: 'Area', name: 'textarea', rows: 2, cols: 4}, {title: 'Markdown Editor', name: 'richtextarea', rows: 2, cols: 4}, {title: 'HTML Editor', name: 'htmltextarea', rows: 2, cols: 4}, - {title: 'Password', name: 'password'} + {title: 'Password', name: 'password'}, + {title: 'Signature', name: 'signature'} ] }, { type: DataType.NUMBER, components: [ {title: 'Simple'}, - {title: 'Currency', name: 'currency'} + {title: 'Decimal', name: 'decimal'}, + { + title: 'Currency', name: 'currency', properties: [ + { + name: 'code', + defaultValue: 'EUR' + }, + { + name: 'fractionSize', + defaultValue: 2 + }, + { + name: 'locale', + defaultValue: 'sk' + }, + ] + } ] }, { @@ -44,7 +79,8 @@ export class FieldListService { {title: 'Stepper', name: 'stepper'}, {title: 'Autocomplete', name: 'autocomplete'}, {title: 'Dynamic Autocomplete', name: 'autocomplete_dynamic'}, - {title: 'Icon', name: 'icon'} + {title: 'Icon', name: 'icon'}, + {title: 'Case ref', name: 'caseref'} ] }, { @@ -59,7 +95,8 @@ export class FieldListService { components: [ {title: 'Select'}, {title: 'List', name: 'list'}, - {title: 'Autocomplete', name: 'autocomplete'} + {title: 'Autocomplete', name: 'autocomplete'}, + {title: 'Case ref', name: 'caseref'} ] }, { @@ -120,7 +157,8 @@ export class FieldListService { { type: DataType.FILTER, components: [ - {title: 'Simple'} + {title: 'Simple'}, + {title: 'Tab view', name: 'filter-tab-view'} ] }, { @@ -133,7 +171,8 @@ export class FieldListService { { type: DataType.TASK_REF, components: [ - {title: 'Simple', cols: 4} + {title: 'Simple', cols: 4}, + {title: 'Dashboard', name: 'dashboard', cols: 4} ] }, { @@ -143,7 +182,7 @@ export class FieldListService { ] }, { - type: 'stringCollection', + type: 'stringCollection' as DataType, components: [ {title: 'Simple'} ] @@ -156,12 +195,12 @@ export class FieldListService { this.draggedObjectsStream = new Subject(); } - public getComponentMeta(type: DataType, componentName: string) { + public getComponentMeta(type: DataType, componentName: string): ComponentDef { const meta = { rows: FieldListService.DEFAULT_FIELD_ROWS, cols: FieldListService.DEFAULT_FIELD_COLS, name: componentName - }; + } as ComponentDef; if (type === undefined || componentName === undefined) { return meta; } diff --git a/src/app/form-builder/gridster/gridster.service.ts b/src/app/form-builder/gridster/gridster.service.ts index c45ac97..9ba7323 100644 --- a/src/app/form-builder/gridster/gridster.service.ts +++ b/src/app/form-builder/gridster/gridster.service.ts @@ -196,7 +196,7 @@ export class GridsterService { return dataVariable; } - public addDataRef(dataVariable: DataVariable, componentRows: number, componentCols: number, componentName: string, item: GridsterItem) { + public addDataRef(dataVariable: DataVariable, componentRows: number, componentCols: number, componentName: string, item: GridsterItem): DataRef { const dataRef = new DataRef(dataVariable.id); dataRef.layout.x = item.x; dataRef.layout.y = item.y; From d18b24bd86e91e335d2b1048dea429c04d13b317 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Ma=C5=BE=C3=A1ri?= Date: Mon, 9 Dec 2024 08:03:22 +0100 Subject: [PATCH 2/5] [NAB-368] - Component parameters - change input in data view to autocomplete, prepare for component refactor --- .../data-detail/data-detail.component.html | 9 +++++++-- .../data-detail/data-detail.component.ts | 16 +++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/app/modeler/data-mode/data-detail/data-detail.component.html b/src/app/modeler/data-mode/data-detail/data-detail.component.html index faffabd..35286e6 100644 --- a/src/app/modeler/data-mode/data-detail/data-detail.component.html +++ b/src/app/modeler/data-mode/data-detail/data-detail.component.html @@ -98,8 +98,13 @@ Component Name - + + + + {{componentDef.title}} + +
diff --git a/src/app/modeler/data-mode/data-detail/data-detail.component.ts b/src/app/modeler/data-mode/data-detail/data-detail.component.ts index 792aaa3..52c8726 100644 --- a/src/app/modeler/data-mode/data-detail/data-detail.component.ts +++ b/src/app/modeler/data-mode/data-detail/data-detail.component.ts @@ -3,7 +3,9 @@ import {DataMasterDetailService} from '../data-master-detail.service'; import { Component as PetriflowComponent, DataType, - DataVariable, Expression, I18nString, + DataVariable, + Expression, + I18nString, I18nWithDynamic, Option, Property, @@ -23,6 +25,7 @@ import {HistoryService} from '../../services/history/history.service'; import {Observable} from 'rxjs'; import {map, startWith, tap} from 'rxjs/operators'; import {ModelerUtils} from '../../modeler-utils'; +import {ComponentDef, DataRefDef, FieldListService} from '../../../form-builder/field-list/field-list.service'; export interface TypeArray { viewValue: string; @@ -43,6 +46,7 @@ export class DataDetailComponent implements OnDestroy { counterEnumMap = 0; formControlRef: FormControl; + componentNameFormCtrl: FormControl; transitionOptions: Array; filteredOptions: Observable>; typeArray: Array = [ @@ -71,6 +75,7 @@ export class DataDetailComponent implements OnDestroy { public constructor( private _masterService: DataMasterDetailService, private _modelService: ModelService, + private _fieldListService: FieldListService, private dialog: MatDialog, private _router: Router, private _actionMode: ActionsModeService, @@ -78,6 +83,7 @@ export class DataDetailComponent implements OnDestroy { private _historyService: HistoryService ) { this.formControlRef = new FormControl(); + this.componentNameFormCtrl = new FormControl(); this.transitionOptions = this.createTransOptions(); this._masterService.getSelected$().subscribe(obj => { if (this.historyDataSave?.save) { @@ -364,4 +370,12 @@ export class DataDetailComponent implements OnDestroy { trackByFn(index: any, item: any) { return index; } + + get filteredComponents(): Array { + const componentDefs: DataRefDef = this._fieldListService.fieldListArray.find(type => type.type === this.item.type); + if (!componentDefs) { + return []; + } + return componentDefs.components.filter(def => def.name !== undefined && def.title.toLowerCase().includes(this.item.component.name)); + } } From e9793d9f8b8348239e77089d1b12859b1bbe94f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juraj=20Ma=C5=BE=C3=A1ri?= Date: Mon, 16 Dec 2024 09:16:28 +0100 Subject: [PATCH 3/5] [NAB-368] - Component parameters - update components in edit panel to autocomplete (WIP) --- .../edit-panel/edit-panel.component.html | 17 ++++++++++++++--- .../edit-panel/edit-panel.component.ts | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/app/form-builder/edit-panel/edit-panel.component.html b/src/app/form-builder/edit-panel/edit-panel.component.html index c589897..017a689 100644 --- a/src/app/form-builder/edit-panel/edit-panel.component.html +++ b/src/app/form-builder/edit-panel/edit-panel.component.html @@ -210,7 +210,13 @@

Component Name - + + + + {{componentDef.title}} + +
@@ -283,8 +289,13 @@

Component Name - + + + + {{componentDef.title}} + +
diff --git a/src/app/form-builder/edit-panel/edit-panel.component.ts b/src/app/form-builder/edit-panel/edit-panel.component.ts index 6feece4..d83c383 100644 --- a/src/app/form-builder/edit-panel/edit-panel.component.ts +++ b/src/app/form-builder/edit-panel/edit-panel.component.ts @@ -35,6 +35,7 @@ import {DATE_FORMAT, DATE_TIME_FORMAT, EnumerationFieldValue} from '@netgrif/com import {Router} from '@angular/router'; import {ActionsModeService} from '../../modeler/actions-mode/actions-mode.service'; import {ActionsMasterDetailService} from '../../modeler/actions-mode/actions-master-detail.setvice'; +import {ComponentDef, DataRefDef, FieldListService} from '../field-list/field-list.service'; @Component({ selector: 'nab-edit-panel', @@ -72,15 +73,18 @@ export class EditPanelComponent implements OnInit, AfterViewInit { filteredOptions: Observable>; formControlRef: FormControl; transitionOptions: Array; - behaviorOptions; + componentNameFormCtrl: FormControl; + dataRefComponentNameFormCtrl: FormControl; + constructor(public gridsterService: GridsterService, public modelService: ModelService, private dialog: MatDialog, private transitionService: SelectedTransitionService, private _router: Router, private _actionMode: ActionsModeService, + private _fieldListService: FieldListService, private _actionsMasterDetail: ActionsMasterDetailService) { // this.transitionOptions = []; this.formControlRef = new FormControl(); @@ -92,6 +96,8 @@ export class EditPanelComponent implements OnInit, AfterViewInit { } ngOnInit() { + this.componentNameFormCtrl = new FormControl(); + this.dataRefComponentNameFormCtrl = new FormControl(); this.transId = this.transitionService.id; if (this.transId === null) { this.numOfCols = ModelerConfig.LAYOUT_DEFAULT_COLS; @@ -515,4 +521,12 @@ export class EditPanelComponent implements OnInit, AfterViewInit { numberOfActions(): number { return this.modelService.numberOfTransitionActions(this.transition); } + + filteredComponents(component: PetriflowComponent): Array { + const componentDefs: DataRefDef = this._fieldListService.fieldListArray.find(type => type.type === this.dataVariable.type); + if (!componentDefs) { + return []; + } + return componentDefs.components.filter(def => def.name !== undefined && def.title.toLowerCase().includes(component.name)); + } } From 60a15d25d3d0b34c31a39b585906b0928bdc5a1c Mon Sep 17 00:00:00 2001 From: Jozef Daxner Date: Tue, 1 Apr 2025 15:42:02 +0200 Subject: [PATCH 4/5] [NAB-368] Component parameters - add known engine properties to components - add button to copy dataRef component into dataField component in form builder and via versa --- package.json | 4 +- .../edit-panel/edit-panel.component.html | 32 ++- .../edit-panel/edit-panel.component.ts | 57 +++- .../field-list/field-list.service.ts | 251 +++++++++++++++++- .../data-detail/data-detail.component.html | 7 +- .../data-detail/data-detail.component.ts | 39 ++- 6 files changed, 359 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index b602f56..a50c9e0 100644 --- a/package.json +++ b/package.json @@ -58,9 +58,9 @@ "@mdi/font": "^7.4.47", "@netgrif/components": "7.0.0-beta.1", "@netgrif/components-core": "7.0.0-beta.1", - "@netgrif/petri.svg": "1.1.0", + "@netgrif/petri.svg": "1.1.1", "@netgrif/petriflow": "2.2.0", - "@netgrif/petriflow.svg": "1.1.0", + "@netgrif/petriflow.svg": "1.1.1", "@ngbracket/ngx-layout": "^17.0.1", "@ngx-translate/core": "~15.0.0", "@ngx-translate/http-loader": "~8.0.0", diff --git a/src/app/form-builder/edit-panel/edit-panel.component.html b/src/app/form-builder/edit-panel/edit-panel.component.html index 017a689..4acde5d 100644 --- a/src/app/form-builder/edit-panel/edit-panel.component.html +++ b/src/app/form-builder/edit-panel/edit-panel.component.html @@ -53,7 +53,7 @@
Delegate event

Id: {{ dataVariable.id }} - @@ -78,7 +78,7 @@

-
+
Title @@ -212,7 +212,7 @@

Component Name - + {{componentDef.title}} @@ -222,8 +222,13 @@

- + + + {{propertyDef.name}} + + add Add property +
@@ -291,7 +301,7 @@

Component Name - + {{componentDef.title}} @@ -301,8 +311,13 @@

- + + + {{propertyDef.name}} + + add Add property +
diff --git a/src/app/form-builder/edit-panel/edit-panel.component.ts b/src/app/form-builder/edit-panel/edit-panel.component.ts index d83c383..004dd14 100644 --- a/src/app/form-builder/edit-panel/edit-panel.component.ts +++ b/src/app/form-builder/edit-panel/edit-panel.component.ts @@ -35,7 +35,8 @@ import {DATE_FORMAT, DATE_TIME_FORMAT, EnumerationFieldValue} from '@netgrif/com import {Router} from '@angular/router'; import {ActionsModeService} from '../../modeler/actions-mode/actions-mode.service'; import {ActionsMasterDetailService} from '../../modeler/actions-mode/actions-master-detail.setvice'; -import {ComponentDef, DataRefDef, FieldListService} from '../field-list/field-list.service'; +import {ComponentDef, DataRefDef, FieldListService, PropertyDef} from '../field-list/field-list.service'; +import {MatAutocompleteSelectedEvent} from '@angular/material/autocomplete'; @Component({ selector: 'nab-edit-panel', @@ -414,8 +415,13 @@ export class EditPanelComponent implements OnInit, AfterViewInit { return false; } - setPropertyKey($event, index: number, component: PetriflowComponent) { - component.properties[index].key = $event.target.value; + public setPropertyKey($event, index: number, component: PetriflowComponent): void { + if ($event instanceof MatAutocompleteSelectedEvent) { + component.properties[index].key = $event.option.value; + this.setPropertyDefaultValue($event, index, component); + } else { + component.properties[index].key = $event.target.value; + } } setPropertyValue($event, index: number, component: PetriflowComponent) { @@ -446,18 +452,26 @@ export class EditPanelComponent implements OnInit, AfterViewInit { } } - setComponent($event) { + public setComponent($event): void { if (!this.gridsterService.selectedDataField.dataVariable.component) { this.gridsterService.selectedDataField.dataVariable.component = new PetriflowComponent(''); } - this.gridsterService.selectedDataField.dataVariable.component.name = $event.target.value; + if ($event instanceof MatAutocompleteSelectedEvent) { + this.gridsterService.selectedDataField.dataVariable.component.name = $event.option.value; + } else { + this.gridsterService.selectedDataField.dataVariable.component.name = $event.target.value; + } } - setDataRefComponent($event) { + public setDataRefComponent($event): void { if (!this.gridsterService.selectedDataField.dataRef.component) { this.gridsterService.selectedDataField.dataRef.component = new PetriflowComponent(''); } - this.gridsterService.selectedDataField.dataRef.component.name = $event.target.value; + if ($event instanceof MatAutocompleteSelectedEvent) { + this.gridsterService.selectedDataField.dataRef.component.name = $event.option.value; + } else { + this.gridsterService.selectedDataField.dataRef.component.name = $event.target.value; + } } taskRefTitle(option: EnumerationFieldValue) { @@ -529,4 +543,33 @@ export class EditPanelComponent implements OnInit, AfterViewInit { } return componentDefs.components.filter(def => def.name !== undefined && def.title.toLowerCase().includes(component.name)); } + + public filteredProperties(component: PetriflowComponent, propertyName: string): Array { + const componentDefs: DataRefDef = this._fieldListService.fieldListArray.find(type => type.type === this.dataVariable.type); + if (!componentDefs) { + return []; + } + const propertyDefs: ComponentDef = componentDefs.components.find(compDef => { + return (!component.name && !compDef.name) || (!!component.name && !!compDef.name && component.name === compDef.name); + }); + if (!propertyDefs || !propertyDefs.properties) { + return []; + } + const existingProperties = component.properties.map(compProperty => compProperty.key); + return propertyDefs.properties.filter(propDef => propDef.name.includes(propertyName) && !existingProperties.includes(propDef.name)); + } + + public setPropertyDefaultValue($event: MatAutocompleteSelectedEvent, index: number, component: PetriflowComponent): void { + component.properties[index].value = this._fieldListService.fieldListArray + .find(type => type.type === this.dataVariable.type)?.components + .find(compDef => (!component.name && !compDef.name) || (!!component.name && !!compDef.name && component.name === compDef.name))?.properties + .find(propDef => propDef.name === $event.option.value).defaultValue; + } + + public cloneProperty(source: DataRef | DataVariable, target: DataRef | DataVariable, property: string): void { + if (!(property in source)) { + return; + } + target[property] = source[property].clone(); + } } diff --git a/src/app/form-builder/field-list/field-list.service.ts b/src/app/form-builder/field-list/field-list.service.ts index f4ad72c..8294c9d 100644 --- a/src/app/form-builder/field-list/field-list.service.ts +++ b/src/app/form-builder/field-list/field-list.service.ts @@ -19,6 +19,7 @@ export interface ComponentDef { export interface DataRefDef { type: DataType; components: Array; + properties?: Array; } @Injectable({ @@ -45,16 +46,31 @@ export class FieldListService { type: DataType.NUMBER, components: [ {title: 'Simple'}, - {title: 'Decimal', name: 'decimal'}, { - title: 'Currency', name: 'currency', properties: [ + title: 'Decimal', + name: 'decimal', + properties: [ + { + name: 'digitsInfo', + defaultValue: '1.0-3' + }, + { + name: 'locale', + defaultValue: 'sk' + }, + ] + }, + { + title: 'Currency', + name: 'currency', + properties: [ { name: 'code', defaultValue: 'EUR' }, { name: 'fractionSize', - defaultValue: 2 + defaultValue: '2' }, { name: 'locale', @@ -76,11 +92,75 @@ export class FieldListService { components: [ {title: 'Select'}, {title: 'List', name: 'list'}, - {title: 'Stepper', name: 'stepper'}, - {title: 'Autocomplete', name: 'autocomplete'}, + { + title: 'Stepper', + name: 'stepper', + properties: [ + { + name: 'arrowStepper', + defaultValue: 'true' + } + ] + }, + { + title: 'Autocomplete', + name: 'autocomplete', + properties: [ + { + name: 'filter', + defaultValue: 'prefix' + } + ] + }, {title: 'Dynamic Autocomplete', name: 'autocomplete_dynamic'}, - {title: 'Icon', name: 'icon'}, - {title: 'Case ref', name: 'caseref'} + { + title: 'Icon', + name: 'icon', + properties: [ + { + name: 'horizontal', + defaultValue: 'true' + }, + { + name: 'arrow', + defaultValue: 'true' + }, + { + name: 'divider', + defaultValue: 'true' + } + ] + }, + { + title: 'Case ref', + name: 'caseref', + properties: [ + { + name: 'filter', + defaultValue: 'true' + }, + { + name: 'filterQuery', + defaultValue: '' + }, + { + name: 'headers', + defaultValue: 'meta-visualID,meta-mongoID,meta-title,meta-author,meta-creationDate' + }, + { + name: 'createCase', + defaultValue: 'true' + }, + { + name: 'search', + defaultValue: 'true' + }, + { + name: 'filter', + defaultValue: 'true' + }, + ] + } ] }, { @@ -95,8 +175,46 @@ export class FieldListService { components: [ {title: 'Select'}, {title: 'List', name: 'list'}, - {title: 'Autocomplete', name: 'autocomplete'}, - {title: 'Case ref', name: 'caseref'} + { + title: 'Autocomplete', + name: 'autocomplete', + properties: [ + { + name: 'filter', + defaultValue: 'prefix' + } + ] + }, + { + title: 'Case ref', + name: 'caseref', + properties: [ + { + name: 'filter', + defaultValue: 'true' + }, + { + name: 'filterQuery', + defaultValue: '' + }, + { + name: 'headers', + defaultValue: 'meta-visualID,meta-mongoID,meta-title,meta-author,meta-creationDate' + }, + { + name: 'createCase', + defaultValue: 'true' + }, + { + name: 'search', + defaultValue: 'true' + }, + { + name: 'filter', + defaultValue: 'true' + }, + ] + } ] }, { @@ -115,6 +233,24 @@ export class FieldListService { {title: 'Icon', name: 'icon'}, {title: 'FAB', name: 'fab'}, {title: 'MiniFAB', name: 'minifab'} + ], + properties: [ + { + name: 'dialogText', + defaultValue: '' + }, + { + name: 'dialogTitle', + defaultValue: '' + }, + { + name: 'align', + defaultValue: '' + }, + { + name: 'stretch', + defaultValue: 'true' + } ] }, { @@ -133,7 +269,28 @@ export class FieldListService { type: DataType.FILE, components: [ {title: 'Simple'}, - {title: 'Preview', name: 'preview'} + { + title: 'Preview', + name: 'preview', + properties: [ + { + name: 'borderWidth', + defaultValue: '0' + }, + { + name: 'borderStyle', + defaultValue: 'none' + }, + { + name: 'borderColor', + defaultValue: 'black' + }, + { + name: 'borderEnabled', + defaultValue: 'true' + } + ] + } ] }, { @@ -164,8 +321,42 @@ export class FieldListService { { type: DataType.I18N, components: [ - {title: 'Simple'}, - {title: 'Divider', name: 'divider', cols: 4} + { + title: 'Simple', + properties: [ + { + name: 'plainText', + defaultValue: 'true' + }, + { + name: 'boldText', + defaultValue: 'true' + }, + { + name: 'textColor', + defaultValue: 'black' + }, + { + name: 'fontSize', + defaultValue: '12px' + } + ] + }, + { + title: 'Divider', + name: 'divider', + cols: 4, + properties: [ + { + name: 'dividerColor', + defaultValue: 'black' + }, + { + name: 'fontSize', + defaultValue: '12px' + } + ] + } ] }, { @@ -179,12 +370,48 @@ export class FieldListService { type: DataType.CASE_REF, components: [ {title: 'Simple'} + ], + properties: [ + { + name: 'filter', + defaultValue: 'true' + }, + { + name: 'filterQuery', + defaultValue: '' + }, + { + name: 'headers', + defaultValue: 'meta-visualID,meta-mongoID,meta-title,meta-author,meta-creationDate' + }, + { + name: 'createCase', + defaultValue: 'true' + }, + { + name: 'search', + defaultValue: 'true' + }, + { + name: 'filter', + defaultValue: 'true' + }, ] }, { type: 'stringCollection' as DataType, components: [ {title: 'Simple'} + ], + properties: [ + { + name: 'semicolon', + defaultValue: 'true' + }, + { + name: 'comma', + defaultValue: 'true' + } ] } ]; diff --git a/src/app/modeler/data-mode/data-detail/data-detail.component.html b/src/app/modeler/data-mode/data-detail/data-detail.component.html index 35286e6..fc14c23 100644 --- a/src/app/modeler/data-mode/data-detail/data-detail.component.html +++ b/src/app/modeler/data-mode/data-detail/data-detail.component.html @@ -116,7 +116,12 @@ Key + [value]="property.key" [matAutocomplete]="propertyAutocomplete"> + + + {{propertyDef.name}} + + Value diff --git a/src/app/modeler/data-mode/data-detail/data-detail.component.ts b/src/app/modeler/data-mode/data-detail/data-detail.component.ts index 52c8726..d25e3c2 100644 --- a/src/app/modeler/data-mode/data-detail/data-detail.component.ts +++ b/src/app/modeler/data-mode/data-detail/data-detail.component.ts @@ -25,7 +25,13 @@ import {HistoryService} from '../../services/history/history.service'; import {Observable} from 'rxjs'; import {map, startWith, tap} from 'rxjs/operators'; import {ModelerUtils} from '../../modeler-utils'; -import {ComponentDef, DataRefDef, FieldListService} from '../../../form-builder/field-list/field-list.service'; +import { + ComponentDef, + DataRefDef, + FieldListService, + PropertyDef +} from '../../../form-builder/field-list/field-list.service'; +import {MatAutocompleteSelectedEvent} from '@angular/material/autocomplete'; export interface TypeArray { viewValue: string; @@ -149,7 +155,7 @@ export class DataDetailComponent implements OnDestroy { }); } - setValue($event, variable: string, index?: number): void { + public setValue($event, variable: string, index?: number): void { switch (variable) { case 'id': { this.item.id = $event.target.value; @@ -226,7 +232,12 @@ export class DataDetailComponent implements OnDestroy { break; } case 'property_key': { - this.item.component.properties[index].key = $event.target.value as string; + if ($event instanceof MatAutocompleteSelectedEvent) { + this.item.component.properties[index].key = $event.option.value as string; + this.setPropertyDefaultValue($event, index, this.item); + } else { + this.item.component.properties[index].key = $event.target.value as string; + } break; } case 'property_value': { @@ -378,4 +389,26 @@ export class DataDetailComponent implements OnDestroy { } return componentDefs.components.filter(def => def.name !== undefined && def.title.toLowerCase().includes(this.item.component.name)); } + + public filteredProperties(dataVariable: DataVariable, propertyName: string): Array { + const componentDefs: DataRefDef = this._fieldListService.fieldListArray.find(type => type.type === dataVariable.type); + if (!componentDefs) { + return []; + } + const propertyDefs: ComponentDef = componentDefs.components.find(compDef => { + return (!dataVariable.component.name && !compDef.name) || (!!dataVariable.component.name && !!compDef.name && dataVariable.component.name === compDef.name); + }); + if (!propertyDefs || !propertyDefs.properties) { + return []; + } + const existingProperties = dataVariable.component.properties.map(compProperty => compProperty.key); + return propertyDefs.properties.filter(propDef => propDef.name.includes(propertyName) && !existingProperties.includes(propDef.name)); + } + + public setPropertyDefaultValue($event: MatAutocompleteSelectedEvent, index: number, dataVariable: DataVariable): void { + dataVariable.component.properties[index].value = this._fieldListService.fieldListArray + .find(type => type.type === dataVariable.type)?.components + .find(compDef => (!dataVariable.component.name && !compDef.name) || (!!dataVariable.component.name && !!compDef.name && dataVariable.component.name === compDef.name))?.properties + .find(propDef => propDef.name === $event.option.value).defaultValue; + } } From c9b7fa28de18af20c4574c43649c0bb3652da308 Mon Sep 17 00:00:00 2001 From: Jozef Daxner Date: Tue, 8 Apr 2025 14:09:56 +0200 Subject: [PATCH 5/5] [NAB-368] Component parameters - prefill known component properties with default values in form builder (click + drag&drop) - update fields with placeholder (caseRef/taskRef...) in form builder - fix i18n text field default properties in form builder --- .../field-list/field-list.component.ts | 6 +++ .../field-list/field-list.service.ts | 42 +++++++++++++++---- .../gridster-data-field.component.html | 10 ++--- .../gridster-data-field.component.ts | 5 ++- .../form-builder/gridster/gridster.service.ts | 14 +++++-- 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/src/app/form-builder/field-list/field-list.component.ts b/src/app/form-builder/field-list/field-list.component.ts index 9cdcf66..7003f31 100644 --- a/src/app/form-builder/field-list/field-list.component.ts +++ b/src/app/form-builder/field-list/field-list.component.ts @@ -95,6 +95,9 @@ export class FieldListComponent implements OnInit, AfterViewInit { if (meta.cols) { $event.dataTransfer.setData('cols', meta.cols); } + if (meta.properties) { + $event.dataTransfer.setData('properties', JSON.stringify(meta.properties)); + } this.dragStartHandler($event, false); } @@ -109,6 +112,9 @@ export class FieldListComponent implements OnInit, AfterViewInit { if (meta?.cols) { $event.dataTransfer.setData('cols', `${meta.cols}`); } + if (meta?.properties) { + $event.dataTransfer.setData('properties', JSON.stringify(meta.properties)); + } } this.dragStartHandler($event, true); } diff --git a/src/app/form-builder/field-list/field-list.service.ts b/src/app/form-builder/field-list/field-list.service.ts index 8294c9d..0d464e3 100644 --- a/src/app/form-builder/field-list/field-list.service.ts +++ b/src/app/form-builder/field-list/field-list.service.ts @@ -1,6 +1,6 @@ import {Injectable} from '@angular/core'; import {Subject} from 'rxjs'; -import {DataType, Property} from '@netgrif/petriflow'; +import {DataType, DataVariable, Property} from '@netgrif/petriflow'; import {GridsterDataField} from '../gridster/classes/gridster-data-field'; export interface PropertyDef { @@ -14,12 +14,14 @@ export interface ComponentDef { rows?: number; cols?: number; properties?: Array; + showPlaceholder?: boolean; } export interface DataRefDef { type: DataType; components: Array; properties?: Array; + showPlaceholder?: boolean; } @Injectable({ @@ -134,6 +136,7 @@ export class FieldListService { { title: 'Case ref', name: 'caseref', + showPlaceholder: true, properties: [ { name: 'filter', @@ -141,7 +144,7 @@ export class FieldListService { }, { name: 'filterQuery', - defaultValue: '' + defaultValue: '{}' }, { name: 'headers', @@ -188,6 +191,7 @@ export class FieldListService { { title: 'Case ref', name: 'caseref', + showPlaceholder: true, properties: [ { name: 'filter', @@ -195,7 +199,7 @@ export class FieldListService { }, { name: 'filterQuery', - defaultValue: '' + defaultValue: '{}' }, { name: 'headers', @@ -313,6 +317,7 @@ export class FieldListService { }, { type: DataType.FILTER, + showPlaceholder: true, components: [ {title: 'Simple'}, {title: 'Tab view', name: 'filter-tab-view'} @@ -322,7 +327,8 @@ export class FieldListService { type: DataType.I18N, components: [ { - title: 'Simple', + title: 'Text', + name: 'text', properties: [ { name: 'plainText', @@ -338,7 +344,7 @@ export class FieldListService { }, { name: 'fontSize', - defaultValue: '12px' + defaultValue: '12' } ] }, @@ -353,7 +359,7 @@ export class FieldListService { }, { name: 'fontSize', - defaultValue: '12px' + defaultValue: '12' } ] } @@ -361,6 +367,7 @@ export class FieldListService { }, { type: DataType.TASK_REF, + showPlaceholder: true, components: [ {title: 'Simple', cols: 4}, {title: 'Dashboard', name: 'dashboard', cols: 4} @@ -368,6 +375,7 @@ export class FieldListService { }, { type: DataType.CASE_REF, + showPlaceholder: true, components: [ {title: 'Simple'} ], @@ -378,7 +386,7 @@ export class FieldListService { }, { name: 'filterQuery', - defaultValue: '' + defaultValue: '{}' }, { name: 'headers', @@ -447,4 +455,24 @@ export class FieldListService { } return meta; } + + public isPlaceholderField(dataField: GridsterDataField): boolean { + if (!dataField.dataVariable.type) { + return true; + } + const component = !!dataField.dataRef.component ? dataField.dataRef.component : dataField.dataVariable.component; + const dataDef = this.fieldListArray.find(it => it.type === dataField.dataVariable.type); + const simpleComponent = dataDef.components.find(it => !it.name); + if (!component || !component.name) { + if (!!simpleComponent && 'showPlaceholder' in simpleComponent) { + return simpleComponent.showPlaceholder; + } + return !!dataDef.showPlaceholder; + } + const compDef = dataDef.components.find(it => it.name === component.name); + if (!compDef || !('showPlaceholder' in compDef)) { + return !!dataDef.showPlaceholder; + } + return !!compDef.showPlaceholder; + } } diff --git a/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.html b/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.html index e371860..bfa711b 100644 --- a/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.html +++ b/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.html @@ -1,11 +1,9 @@
- Placeholder for {{dataField.dataVariable.type}} with id '{{dataField.dataVariable?.id}}' + Placeholder for {{dataField.dataVariable.type}} with id '{{dataField.dataVariable?.id}}' - +
diff --git a/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.ts b/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.ts index 5d5d497..c8c1dfe 100644 --- a/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.ts +++ b/src/app/form-builder/gridster/gridster-datafield/gridster-data-field.component.ts @@ -6,6 +6,7 @@ import {GridsterFieldToEngineFieldService} from '../../../modeler/gridster-field import {Subscription} from 'rxjs'; import moment from 'moment'; import {DataField, EnumerationField, MultichoiceField} from '@netgrif/components-core'; +import {FieldListService} from '../../field-list/field-list.service'; @Component({ selector: 'nab-gridster-datafield', @@ -20,7 +21,9 @@ export class GridsterDataFieldComponent implements OnInit, OnDestroy { engineField: DataField; private _gridsterSubscription: Subscription; - constructor(private _gridsterService: GridsterService, private _transformService: GridsterFieldToEngineFieldService) { + constructor(private _gridsterService: GridsterService, + private _transformService: GridsterFieldToEngineFieldService, + public fieldListService: FieldListService) { } ngOnDestroy(): void { diff --git a/src/app/form-builder/gridster/gridster.service.ts b/src/app/form-builder/gridster/gridster.service.ts index 9ba7323..5406d3a 100644 --- a/src/app/form-builder/gridster/gridster.service.ts +++ b/src/app/form-builder/gridster/gridster.service.ts @@ -18,7 +18,7 @@ import { DataType, DataVariable, Expression, I18nWithDynamic, - LayoutType, + LayoutType, Property, Template, Transition, TransitionLayout @@ -26,7 +26,7 @@ import { import {BehaviorSubject, ReplaySubject, Subject} from 'rxjs'; import {DataFieldUtils} from '../data-field-utils'; import {SelectedTransitionService} from '../../modeler/selected-transition.service'; -import {FieldListService} from '../field-list/field-list.service'; +import {ComponentDef, FieldListService, PropertyDef} from '../field-list/field-list.service'; import {ModelerConfig} from '../../modeler/modeler-config'; import {debounceTime} from 'rxjs/operators'; @@ -241,12 +241,20 @@ export class GridsterService { } private addNewDataRef(data: DataVariable, event: DragEvent, item: GridsterItem): DataRef { - return this.addDataRef( + const newDataRef = this.addDataRef( data, +event.dataTransfer.getData('rows'), +event.dataTransfer.getData('cols'), event.dataTransfer.getData('ref_component'), item); + const properties: Array = JSON.parse(event.dataTransfer.getData('properties')); + if (!!properties) { + for (const property of properties) { + newDataRef.component.properties.push(new Property(property.name, property.defaultValue)); + } + } + this.options.api.optionsChanged(); + return newDataRef; } private createId(type: string) {