diff --git a/src/demo/app/app.component.css b/src/demo/app/app.component.css index 7bde748..f5aa842 100644 --- a/src/demo/app/app.component.css +++ b/src/demo/app/app.component.css @@ -189,3 +189,24 @@ textarea:input:focus { .dnd-target-feedback .connection { animation: flash-stroke-width 2s linear infinite; } + +.properties-group-container .property-row { + display: block; +} + +.df-property-row { + width: 100%; + display:inline-table; +} + +.df-property-label-cell { + width: 50%; +} + +.df-property-container { + width: 100% +} + +.df-property-control { + width: 100%; +} diff --git a/src/demo/app/editor.ts b/src/demo/app/editor.ts index 878ed7b..f6d3668 100644 --- a/src/demo/app/editor.ts +++ b/src/demo/app/editor.ts @@ -59,7 +59,7 @@ export class Editor implements Flo.Editor { // }, Flo.PropertiesForm.InputType.TEXT)); // bsModalRef.content.addControlModels(models); // }); - bsModalRef.content.propertiesGroupModel = new Properties.PropertiesGroupModel(cell); + bsModalRef.content.propertiesGroupModel = new SamplePropertiesGroupModel(cell); } validatePort(context : Flo.EditorContext, view : dia.ElementView, magnet : SVGElement) { @@ -553,3 +553,38 @@ export class Editor implements Flo.Editor { } } + +class SamplePropertiesGroupModel extends Properties.PropertiesGroupModel { + protected createControlModel(property : Properties.Property) : Properties.ControlModel { + let inputType = Properties.InputType.TEXT; + switch (property.metadata.type) { + case 'number': + inputType = Properties.InputType.NUMBER; + break; + case 'url': + inputType = Properties.InputType.URL; + break; + case 'password': + inputType = Properties.InputType.PASSWORD; + break; + case 'boolean': + inputType = Properties.InputType.CHECKBOX; + break; + case 'number': + inputType = Properties.InputType.EMAIL; + break; + case 'enum': + if (Array.isArray(property.metadata.options)) { + return new Properties.SelectControlModel(property, Properties.InputType.SELECT, (> property.metadata.options).map(o => { + return { + name: o, + value: o === property.defaultValue ? undefined : o + } + })); + } + default: + break; + } + return new Properties.GenericControlModel(property, inputType); + } +} diff --git a/src/demo/app/metamodel.ts b/src/demo/app/metamodel.ts index 89cb6f5..a678d6b 100644 --- a/src/demo/app/metamodel.ts +++ b/src/demo/app/metamodel.ts @@ -5,12 +5,17 @@ import { convertTextToGraph } from './text-to-graph'; const metamodelData: Array = [{ name: 'http', group: 'source', description: 'Receive HTTP input', properties: [ - {id: 'port', name: 'port', defaultValue: '80', description: 'Port on which to listen'} + {id: 'port', name: 'port', defaultValue: '80', description: 'Port on which to listen', type: 'number'} ], }, { name: 'rabbit', group: 'source', description: 'Receives messages from RabbitMQ', properties: [ - {id: 'queue', name: 'queue', description: 'the queue(s) from which messages will be received'} + {id: 'queue', name: 'queue', description: 'the queue(s) from which messages will be received'}, + {id: 'time-unit', name: 'time-unit', description: 'Time unit for heart beat messages', type: 'enum', options: ['HOURS', 'MINUTES', 'SECONDS', 'MILIOSECONDS'], defaultValue: 'SECONDS'}, + {id: 'heart-beat', name: 'heart-beat', description: 'Heart beat on/off', type: 'boolean', defaultValue: false}, + {id: 'interval', name: 'interval', description: 'Time period being consecutive heart beat messages', type: 'number', defaultValue: 20}, + {id: 'url', name: 'url', description: 'Service URL', type: 'url'}, + {id: 'password', name: 'password', description: 'Password to login to service', type: 'password'} ], }, { name: 'filewatch', group: 'source', description: 'Produce messages from the content of files created in a directory', @@ -67,7 +72,7 @@ const metamodelData: Array = [{ name: 'ftp', group: 'sink', description: 'Send messages over FTP', properties: [ {id: 'host', name: 'host', description: 'the host name for the FTP server'}, - {id: 'port', name: 'port', description: 'The port for the FTP server'}, + {id: 'port', name: 'port', description: 'The port for the FTP server', type: 'number'}, {id: 'remoteDir', name: 'remoteDir', description: 'The remote directory on the server'}, ], }]; diff --git a/src/lib/src/properties/df.property.component.html b/src/lib/src/properties/df.property.component.html index 00736f5..adc884e 100644 --- a/src/lib/src/properties/df.property.component.html +++ b/src/lib/src/properties/df.property.component.html @@ -1,21 +1,42 @@ -
+ - + + + -
+ +
- + - + -
+ - -

{{model.description}}

-

{{e.message}}

+ -
+ + + + + +
+ + +

{{model.description}}

+

{{e.message}}

+ + + diff --git a/src/lib/src/properties/properties.group.component.html b/src/lib/src/properties/properties.group.component.html index c8a0171..4ed9674 100644 --- a/src/lib/src/properties/properties.group.component.html +++ b/src/lib/src/properties/properties.group.component.html @@ -1,5 +1,3 @@
-
- -
+
diff --git a/src/lib/src/shared/flo.properties.ts b/src/lib/src/shared/flo.properties.ts index a97e66a..4eb6ef2 100644 --- a/src/lib/src/shared/flo.properties.ts +++ b/src/lib/src/shared/flo.properties.ts @@ -10,6 +10,7 @@ export namespace Properties { NUMBER, SELECT, CHECKBOX, + PASSWORD, EMAIL, URL, CODE @@ -22,6 +23,12 @@ export namespace Properties { description? : string; defaultValue? : any; value? : any; + readonly metadata : Flo.PropertyMetadata; + } + + export interface SelectOption { + name: string; + value: any; } export interface ErrorData { @@ -86,6 +93,12 @@ export namespace Properties { } + export class SelectControlModel extends GenericControlModel { + constructor(_property : Property, type : InputType, public options : Array) { + super(_property, type); + } + } + export class PropertiesGroupModel { protected cell : dia.Cell; @@ -133,7 +146,8 @@ export namespace Properties { defaultValue: metadata.defaultValue, attr: `props/${metadata.name}`, value: this.cell.attr(`props/${metadata.name}`), - description: metadata.description + description: metadata.description, + metadata: metadata } }