diff --git a/src/activities/Elsa.Activities.Entity/Activities/EntityChanged/EntityChanged.cs b/src/activities/Elsa.Activities.Entity/Activities/EntityChanged/EntityChanged.cs index 5ec548a5a..a0d9a1d67 100644 --- a/src/activities/Elsa.Activities.Entity/Activities/EntityChanged/EntityChanged.cs +++ b/src/activities/Elsa.Activities.Entity/Activities/EntityChanged/EntityChanged.cs @@ -19,7 +19,7 @@ namespace Elsa.Activities.Entity public string? EntityName { get; set; } [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "The Entity Changed Action to observe. Matches any action if no value is specified.", Options = new[] { "Added", "Updated", "Deleted" } )] diff --git a/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs b/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs index 6e9eada78..219fe009c 100644 --- a/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs +++ b/src/activities/Elsa.Activities.Http/Activities/SendHttpRequest/SendHttpRequest.cs @@ -47,7 +47,7 @@ namespace Elsa.Activities.Http /// The HTTP method to use. /// [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "The HTTP method to use when making the request.", Options = new[] { "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD" } )] @@ -63,7 +63,7 @@ namespace Elsa.Activities.Http /// The Content Type header to send along with the request body. /// [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "The content type to send with the request.", Options = new[] { "text/plain", "text/html", "application/json", "application/xml" } )] diff --git a/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs b/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs index fd4cf722e..5098daab3 100644 --- a/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs +++ b/src/activities/Elsa.Activities.Http/Activities/WriteHttpResponse/WriteHttpResponse.cs @@ -14,7 +14,7 @@ namespace Elsa.Activities.Http { [Action( Category = "HTTP", - DisplayName = "Write HTTP Response", + DisplayName = "HTTP Response", Description = "Write an HTTP response.", Outcomes = new[] { OutcomeNames.Done } )] @@ -34,7 +34,7 @@ namespace Elsa.Activities.Http /// The HTTP status code to return. /// [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "The HTTP status code to write.", Options = new[] { HttpStatusCode.OK, HttpStatusCode.Created, HttpStatusCode.Accepted, HttpStatusCode.NoContent, HttpStatusCode.Redirect, HttpStatusCode.BadRequest, HttpStatusCode.NotFound, HttpStatusCode.Conflict } )] @@ -50,7 +50,7 @@ namespace Elsa.Activities.Http /// The Content-Type header to send along with the response. /// [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "The HTTP content type header to write.", Options = new[]{ "text/plain", "text/html", "application/json", "application/xml" } )] diff --git a/src/core/Elsa.Abstractions/Design/ActivityPropertyUIHints.cs b/src/core/Elsa.Abstractions/Design/ActivityPropertyUIHints.cs index 5fcd2d444..c9c8cf053 100644 --- a/src/core/Elsa.Abstractions/Design/ActivityPropertyUIHints.cs +++ b/src/core/Elsa.Abstractions/Design/ActivityPropertyUIHints.cs @@ -7,7 +7,7 @@ namespace Elsa.Design public const string Checkbox = "checkbox"; public const string CheckList = "check-list"; public const string RadioList = "radio-list"; - public const string DropdownList = "dropdown-list"; + public const string Dropdown = "dropdown"; /// /// A list that allows the user to enter zero or more values. diff --git a/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs b/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs index 44f0b57da..ce81a78d3 100644 --- a/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs +++ b/src/core/Elsa.Core/Activities/ControlFlow/Join/Join.cs @@ -37,7 +37,7 @@ namespace Elsa.Activities.ControlFlow } [ActivityProperty( - UIHint = ActivityPropertyUIHints.DropdownList, + UIHint = ActivityPropertyUIHints.Dropdown, Hint = "WaitAll: wait for all incoming activities to have executed. WaitAny: continue execution as soon as any of the incoming activity has executed.", Options = new[] { "WaitAll", "WaitAny" } )] diff --git a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs index 08f55c389..09a07238f 100644 --- a/src/core/Elsa.Core/Metadata/ActivityDescriber.cs +++ b/src/core/Elsa.Core/Metadata/ActivityDescriber.cs @@ -79,7 +79,7 @@ namespace Elsa.Metadata return ActivityPropertyUIHints.SingleLine; if (typeof(IEnumerable).IsAssignableFrom(type)) - return ActivityPropertyUIHints.DropdownList; + return ActivityPropertyUIHints.Dropdown; return ActivityPropertyUIHints.SingleLine; } diff --git a/src/designer/elsa-workflows-studio/src/components.d.ts b/src/designer/elsa-workflows-studio/src/components.d.ts index 2d5a9dfad..bfd4ba96a 100644 --- a/src/designer/elsa-workflows-studio/src/components.d.ts +++ b/src/designer/elsa-workflows-studio/src/components.d.ts @@ -27,6 +27,10 @@ export namespace Components { "activityModel": ActivityModel; "icon": string; } + interface ElsaDropdownProperty { + "propertyDescriptor": ActivityPropertyDescriptor; + "propertyModel": ActivityDefinitionProperty; + } interface ElsaModalDialog { "hide": (animate: boolean) => Promise; "show": (animate: boolean) => Promise; @@ -95,6 +99,12 @@ declare global { prototype: HTMLElsaDesignerTreeActivityElement; new (): HTMLElsaDesignerTreeActivityElement; }; + interface HTMLElsaDropdownPropertyElement extends Components.ElsaDropdownProperty, HTMLStencilElement { + } + var HTMLElsaDropdownPropertyElement: { + prototype: HTMLElsaDropdownPropertyElement; + new (): HTMLElsaDropdownPropertyElement; + }; interface HTMLElsaModalDialogElement extends Components.ElsaModalDialog, HTMLStencilElement { } var HTMLElsaModalDialogElement: { @@ -138,6 +148,7 @@ declare global { "elsa-checkbox-property": HTMLElsaCheckboxPropertyElement; "elsa-designer-tree": HTMLElsaDesignerTreeElement; "elsa-designer-tree-activity": HTMLElsaDesignerTreeActivityElement; + "elsa-dropdown-property": HTMLElsaDropdownPropertyElement; "elsa-modal-dialog": HTMLElsaModalDialogElement; "elsa-monaco": HTMLElsaMonacoElement; "elsa-text-property": HTMLElsaTextPropertyElement; @@ -169,6 +180,10 @@ declare namespace LocalJSX { "onEdit-activity"?: (event: CustomEvent) => void; "onRemove-activity"?: (event: CustomEvent) => void; } + interface ElsaDropdownProperty { + "propertyDescriptor"?: ActivityPropertyDescriptor; + "propertyModel"?: ActivityDefinitionProperty; + } interface ElsaModalDialog { } interface ElsaMonaco { @@ -203,6 +218,7 @@ declare namespace LocalJSX { "elsa-checkbox-property": ElsaCheckboxProperty; "elsa-designer-tree": ElsaDesignerTree; "elsa-designer-tree-activity": ElsaDesignerTreeActivity; + "elsa-dropdown-property": ElsaDropdownProperty; "elsa-modal-dialog": ElsaModalDialog; "elsa-monaco": ElsaMonaco; "elsa-text-property": ElsaTextProperty; @@ -221,6 +237,7 @@ declare module "@stencil/core" { "elsa-checkbox-property": LocalJSX.ElsaCheckboxProperty & JSXBase.HTMLAttributes; "elsa-designer-tree": LocalJSX.ElsaDesignerTree & JSXBase.HTMLAttributes; "elsa-designer-tree-activity": LocalJSX.ElsaDesignerTreeActivity & JSXBase.HTMLAttributes; + "elsa-dropdown-property": LocalJSX.ElsaDropdownProperty & JSXBase.HTMLAttributes; "elsa-modal-dialog": LocalJSX.ElsaModalDialog & JSXBase.HTMLAttributes; "elsa-monaco": LocalJSX.ElsaMonaco & JSXBase.HTMLAttributes; "elsa-text-property": LocalJSX.ElsaTextProperty & JSXBase.HTMLAttributes; diff --git a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-check-list-property/elsa-check-list-property.tsx b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-check-list-property/elsa-check-list-property.tsx index 7620e9497..28574d5fd 100644 --- a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-check-list-property/elsa-check-list-property.tsx +++ b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-check-list-property/elsa-check-list-property.tsx @@ -57,7 +57,7 @@ export class ElsaCheckListProperty {
this.onCheckChanged(e)} class="focus:ring-blue-500 h-4 w-4 text-blue-600 border-gray-300 rounded"/>
-
+
diff --git a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.css b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.css new file mode 100644 index 000000000..5d4e87f30 --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.css @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.tsx b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.tsx new file mode 100644 index 000000000..5504eeb98 --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-dropdown-property/elsa-dropdown-property.tsx @@ -0,0 +1,48 @@ +import {Component, h, Prop, State} from '@stencil/core'; +import {ActivityDefinitionProperty, ActivityPropertyDescriptor} from "../../../../models"; + +@Component({ + tag: 'elsa-dropdown-property', + styleUrl: 'elsa-dropdown-property.css', + shadow: false, +}) +export class ElsaDropdownProperty { + + @Prop() propertyDescriptor: ActivityPropertyDescriptor; + @Prop() propertyModel: ActivityDefinitionProperty; + @State() currentValue?: string; + + async componentWillLoad() { + this.currentValue = this.propertyModel.expression || ''; + } + + onChanged(e: Event) { + const select = (e.target as HTMLSelectElement); + this.currentValue = select.value; + } + + render() { + const propertyDescriptor = this.propertyDescriptor; + const propertyName = propertyDescriptor.name; + const fieldId = propertyName; + const fieldName = propertyName; + const fieldLabel = propertyDescriptor.label || propertyName; + const fieldHint = propertyDescriptor.hint; + const options = propertyDescriptor.options as Array; + const value = this.currentValue; + + return ( +
+ + + + + {fieldHint ?

{fieldHint}

: undefined} +
+ ) + } +} diff --git a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-text-property/elsa-text-property.tsx b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-text-property/elsa-text-property.tsx index 9e9a579a4..e4381ab6f 100644 --- a/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-text-property/elsa-text-property.tsx +++ b/src/designer/elsa-workflows-studio/src/components/editors/properties/elsa-text-property/elsa-text-property.tsx @@ -73,55 +73,51 @@ export class ElsaTextProperty { const property = this.propertyModel; const value = this.currentValue; - return ( -
- -
-
- - -
-
-
- this.onMonacoValueChanged(e.detail)} - ref={el => this.monacoEditor = el}/> -
- {fieldHint ?

{fieldHint}

: undefined} - - - ) +
+ this.onMonacoValueChanged(e.detail)} + ref={el => this.monacoEditor = el}/> +
+ {fieldHint ?

{fieldHint}

: undefined} + + + } } diff --git a/src/designer/elsa-workflows-studio/src/property-display-drivers/dropdown-driver.tsx b/src/designer/elsa-workflows-studio/src/property-display-drivers/dropdown-driver.tsx new file mode 100644 index 000000000..31d30d528 --- /dev/null +++ b/src/designer/elsa-workflows-studio/src/property-display-drivers/dropdown-driver.tsx @@ -0,0 +1,23 @@ +import {PropertyDisplayDriver} from "../services/property-display-driver"; +import {ActivityModel, ActivityPropertyDescriptor} from "../models"; +import {h} from "@stencil/core"; +import {getProperty, setActivityModelProperty} from "../utils/utils"; + +export class DropdownDriver implements PropertyDisplayDriver { + + display(activity: ActivityModel, property: ActivityPropertyDescriptor) { + const key = `${activity.activityId}:${property.name}`; + const prop = getProperty(activity.properties, property.name); + + return ( +
+ +
+ ) + } + + update(activity: ActivityModel, property: ActivityPropertyDescriptor, form: FormData) { + const value = form.get(property.name) as string; + setActivityModelProperty(activity, property.name, value, 'Literal'); + } +} diff --git a/src/designer/elsa-workflows-studio/src/property-display-drivers/index.ts b/src/designer/elsa-workflows-studio/src/property-display-drivers/index.ts index 272002b8b..d29f1fff3 100644 --- a/src/designer/elsa-workflows-studio/src/property-display-drivers/index.ts +++ b/src/designer/elsa-workflows-studio/src/property-display-drivers/index.ts @@ -3,3 +3,4 @@ export * from './single-line-driver'; export * from './multiline-driver'; export * from './check-list-driver'; export * from './checkbox-driver'; +export * from './dropdown-driver'; diff --git a/src/designer/elsa-workflows-studio/src/services/property-display-manager.ts b/src/designer/elsa-workflows-studio/src/services/property-display-manager.ts index e63fead0d..b6679e7f7 100644 --- a/src/designer/elsa-workflows-studio/src/services/property-display-manager.ts +++ b/src/designer/elsa-workflows-studio/src/services/property-display-manager.ts @@ -1,6 +1,6 @@ import {ActivityModel, ActivityPropertyDescriptor} from "../models/"; import {PropertyDisplayDriver} from "./property-display-driver"; -import {CheckBoxDriver, CheckListDriver, MultilineDriver, NullPropertyDriver, SingleLineDriver} from "../property-display-drivers"; +import {CheckBoxDriver, CheckListDriver, DropdownDriver, MultilineDriver, NullPropertyDriver, SingleLineDriver} from "../property-display-drivers"; import {Map} from '../utils/utils'; export type PropertyDisplayDriverMap = Map<() => PropertyDisplayDriver>; @@ -14,7 +14,8 @@ export class PropertyDisplayManager { 'single-line': () => new SingleLineDriver(), 'multi-line': () => new MultilineDriver(), 'check-list': () => new CheckListDriver(), - 'checkbox': () => new CheckBoxDriver() + 'checkbox': () => new CheckBoxDriver(), + 'dropdown': () => new DropdownDriver() }; }