diff --git a/src/designer/elsa-workflows-designer/src/components.d.ts b/src/designer/elsa-workflows-designer/src/components.d.ts index bb0167777..edb6aa196 100644 --- a/src/designer/elsa-workflows-designer/src/components.d.ts +++ b/src/designer/elsa-workflows-designer/src/components.d.ts @@ -29,8 +29,6 @@ import { WorkflowDefinitionPropsUpdatedArgs, WorkflowDefinitionUpdatedArgs } fro import { PublishClickedArgs as PublishClickedArgs1 } from "./modules/workflow-definitions/components/publish-button"; export namespace Components { interface ElsaActivityDefinitionBrowser { - "hide": () => Promise; - "show": () => Promise; } interface ElsaActivityDefinitionEditor { "activityDefinition"?: ActivityDefinition; @@ -170,15 +168,16 @@ export namespace Components { "selectedLabels": Array; } interface ElsaLabelsManager { - "hide": () => Promise; - "show": () => Promise; } interface ElsaModalDialog { "actions": Array; + "content": () => any; "hide": (animate?: boolean) => Promise; "show": (animate?: boolean) => Promise; "size": string; } + interface ElsaModalDialogContainer { + } interface ElsaMonacoEditor { "editorHeight": string; "language": string; @@ -232,17 +231,13 @@ export namespace Components { "tooltipContent": any; "tooltipPosition"?: string; } - interface ElsaVariableEditorDialog { - "hide": () => Promise; - "show": () => Promise; + interface ElsaVariableEditorDialogContent { "variable": Variable; } interface ElsaVariablesEditor { "variables"?: Array; } interface ElsaWorkflowDefinitionBrowser { - "hide": () => Promise; - "show": () => Promise; } interface ElsaWorkflowDefinitionEditor { "getCanvas": () => Promise; @@ -269,8 +264,6 @@ export namespace Components { "workflowDefinition"?: WorkflowDefinition; } interface ElsaWorkflowInstanceBrowser { - "hide": () => Promise; - "show": () => Promise; } interface ElsaWorkflowInstanceProperties { "hide": () => Promise; @@ -467,6 +460,12 @@ declare global { prototype: HTMLElsaModalDialogElement; new (): HTMLElsaModalDialogElement; }; + interface HTMLElsaModalDialogContainerElement extends Components.ElsaModalDialogContainer, HTMLStencilElement { + } + var HTMLElsaModalDialogContainerElement: { + prototype: HTMLElsaModalDialogContainerElement; + new (): HTMLElsaModalDialogContainerElement; + }; interface HTMLElsaMonacoEditorElement extends Components.ElsaMonacoEditor, HTMLStencilElement { } var HTMLElsaMonacoEditorElement: { @@ -545,11 +544,11 @@ declare global { prototype: HTMLElsaTooltipElement; new (): HTMLElsaTooltipElement; }; - interface HTMLElsaVariableEditorDialogElement extends Components.ElsaVariableEditorDialog, HTMLStencilElement { + interface HTMLElsaVariableEditorDialogContentElement extends Components.ElsaVariableEditorDialogContent, HTMLStencilElement { } - var HTMLElsaVariableEditorDialogElement: { - prototype: HTMLElsaVariableEditorDialogElement; - new (): HTMLElsaVariableEditorDialogElement; + var HTMLElsaVariableEditorDialogContentElement: { + prototype: HTMLElsaVariableEditorDialogContentElement; + new (): HTMLElsaVariableEditorDialogContentElement; }; interface HTMLElsaVariablesEditorElement extends Components.ElsaVariablesEditor, HTMLStencilElement { } @@ -669,6 +668,7 @@ declare global { "elsa-label-picker": HTMLElsaLabelPickerElement; "elsa-labels-manager": HTMLElsaLabelsManagerElement; "elsa-modal-dialog": HTMLElsaModalDialogElement; + "elsa-modal-dialog-container": HTMLElsaModalDialogContainerElement; "elsa-monaco-editor": HTMLElsaMonacoEditorElement; "elsa-multi-line-input": HTMLElsaMultiLineInputElement; "elsa-multi-text-input": HTMLElsaMultiTextInputElement; @@ -682,7 +682,7 @@ declare global { "elsa-studio": HTMLElsaStudioElement; "elsa-switch-editor": HTMLElsaSwitchEditorElement; "elsa-tooltip": HTMLElsaTooltipElement; - "elsa-variable-editor-dialog": HTMLElsaVariableEditorDialogElement; + "elsa-variable-editor-dialog-content": HTMLElsaVariableEditorDialogContentElement; "elsa-variables-editor": HTMLElsaVariablesEditorElement; "elsa-workflow-definition-browser": HTMLElsaWorkflowDefinitionBrowserElement; "elsa-workflow-definition-editor": HTMLElsaWorkflowDefinitionEditorElement; @@ -838,11 +838,14 @@ declare namespace LocalJSX { } interface ElsaModalDialog { "actions"?: Array; + "content"?: () => any; "onActionInvoked"?: (event: CustomEvent) => void; "onHidden"?: (event: CustomEvent) => void; "onShown"?: (event: CustomEvent) => void; "size"?: string; } + interface ElsaModalDialogContainer { + } interface ElsaMonacoEditor { "editorHeight"?: string; "language"?: string; @@ -898,7 +901,7 @@ declare namespace LocalJSX { "tooltipContent"?: any; "tooltipPosition"?: string; } - interface ElsaVariableEditorDialog { + interface ElsaVariableEditorDialogContent { "onVariableChanged"?: (event: CustomEvent) => void; "variable"?: Variable; } @@ -989,6 +992,7 @@ declare namespace LocalJSX { "elsa-label-picker": ElsaLabelPicker; "elsa-labels-manager": ElsaLabelsManager; "elsa-modal-dialog": ElsaModalDialog; + "elsa-modal-dialog-container": ElsaModalDialogContainer; "elsa-monaco-editor": ElsaMonacoEditor; "elsa-multi-line-input": ElsaMultiLineInput; "elsa-multi-text-input": ElsaMultiTextInput; @@ -1002,7 +1006,7 @@ declare namespace LocalJSX { "elsa-studio": ElsaStudio; "elsa-switch-editor": ElsaSwitchEditor; "elsa-tooltip": ElsaTooltip; - "elsa-variable-editor-dialog": ElsaVariableEditorDialog; + "elsa-variable-editor-dialog-content": ElsaVariableEditorDialogContent; "elsa-variables-editor": ElsaVariablesEditor; "elsa-workflow-definition-browser": ElsaWorkflowDefinitionBrowser; "elsa-workflow-definition-editor": ElsaWorkflowDefinitionEditor; @@ -1051,6 +1055,7 @@ declare module "@stencil/core" { "elsa-label-picker": LocalJSX.ElsaLabelPicker & JSXBase.HTMLAttributes; "elsa-labels-manager": LocalJSX.ElsaLabelsManager & JSXBase.HTMLAttributes; "elsa-modal-dialog": LocalJSX.ElsaModalDialog & JSXBase.HTMLAttributes; + "elsa-modal-dialog-container": LocalJSX.ElsaModalDialogContainer & JSXBase.HTMLAttributes; "elsa-monaco-editor": LocalJSX.ElsaMonacoEditor & JSXBase.HTMLAttributes; "elsa-multi-line-input": LocalJSX.ElsaMultiLineInput & JSXBase.HTMLAttributes; "elsa-multi-text-input": LocalJSX.ElsaMultiTextInput & JSXBase.HTMLAttributes; @@ -1064,7 +1069,7 @@ declare module "@stencil/core" { "elsa-studio": LocalJSX.ElsaStudio & JSXBase.HTMLAttributes; "elsa-switch-editor": LocalJSX.ElsaSwitchEditor & JSXBase.HTMLAttributes; "elsa-tooltip": LocalJSX.ElsaTooltip & JSXBase.HTMLAttributes; - "elsa-variable-editor-dialog": LocalJSX.ElsaVariableEditorDialog & JSXBase.HTMLAttributes; + "elsa-variable-editor-dialog-content": LocalJSX.ElsaVariableEditorDialogContent & JSXBase.HTMLAttributes; "elsa-variables-editor": LocalJSX.ElsaVariablesEditor & JSXBase.HTMLAttributes; "elsa-workflow-definition-browser": LocalJSX.ElsaWorkflowDefinitionBrowser & JSXBase.HTMLAttributes; "elsa-workflow-definition-editor": LocalJSX.ElsaWorkflowDefinitionEditor & JSXBase.HTMLAttributes; diff --git a/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog-content.tsx b/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog-content.tsx new file mode 100644 index 000000000..458cafd01 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog-content.tsx @@ -0,0 +1,77 @@ +import {Component, h, Prop, Event, EventEmitter, Method} from "@stencil/core"; +import {DefaultActions, StorageDriverDescriptor, Variable} from "../../../models"; +import {FormEntry} from "../../shared/forms/form-entry"; +import {isNullOrWhitespace} from "../../../utils"; +import descriptorsStore from '../../../data/descriptors-store'; + +@Component({ + tag: 'elsa-variable-editor-dialog-content', + shadow: false +}) +export class VariableEditorDialogContent { + @Prop() variable: Variable; + @Event() variableChanged: EventEmitter; + + render() { + const variable: Variable = this.variable ?? {name: '', type: 'Object'}; + const variableType = variable.type; + const availableTypes: Array = ['Object', 'String', 'Boolean', 'Int32', 'Int64', 'Single', 'Double']; // TODO: Fetch these from backend. + const storageDrivers: Array = [{id: null, displayName: '-'}, ...descriptorsStore.storageDrivers]; + + return ( +
+
this.onSubmit(e)} method="post"> +
+

Edit Variable

+
+ + + + + + + + + + + + + + + + + +
+
+
+
+ ); + } + + private onSubmit = async (e: Event) => { + e.preventDefault(); + const formData = new FormData(e.target as HTMLFormElement); + const name = formData.get('variableName') as string; + const value = formData.get('variableValue') as string; + const type = formData.get('variableType') as string; + const driverId = formData.get('variableStorageDriverId') as string; + const variable = this.variable; + + variable.name = name; + variable.type = type; + variable.value = value; + variable.storageDriverId = isNullOrWhitespace(driverId) ? null : driverId; + + this.variableChanged.emit(variable); + }; + +} diff --git a/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog.tsx b/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog.tsx deleted file mode 100644 index e40ae639f..000000000 --- a/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variable-editor-dialog.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import {Component, h, Prop, Event, EventEmitter, Method} from "@stencil/core"; -import {DefaultActions, StorageDriverDescriptor, Variable} from "../../../models"; -import {FormEntry} from "../../shared/forms/form-entry"; -import {isNullOrWhitespace} from "../../../utils"; -import descriptorsStore from '../../../data/descriptors-store'; - -@Component({ - tag: 'elsa-variable-editor-dialog', - shadow: false -}) -export class VariableEditorDialog { - private modalDialog: HTMLElsaModalDialogElement; - - @Prop() variable: Variable; - @Event() variableChanged: EventEmitter; - - @Method() - public async show() { - await this.modalDialog.show(); - } - - @Method() - public async hide() { - await this.modalDialog.hide(); - } - - render() { - const variable: Variable = this.variable ?? {name: '', type: 'Object'}; - const variableType = variable.type; - const cancelAction = DefaultActions.Cancel(); - const saveAction = DefaultActions.Save(); - const actions = [cancelAction, saveAction]; - const availableTypes: Array = ['Object', 'String', 'Boolean', 'Int32', 'Int64', 'Single', 'Double']; // TODO: Fetch these from backend. - const storageDrivers: Array = [{ id: null, displayName: '-' }, ...descriptorsStore.storageDrivers]; - - return ( -
-
this.onSubmit(e)} method="post"> - (this.modalDialog = el)} actions={actions}> -
-

Edit Variable

-
- - - - - - - - - - - - - - - - - - -
-
-
-
-
- ); - } - - private onSubmit = async (e: Event) => { - e.preventDefault(); - const formData = new FormData(e.target as HTMLFormElement); - const name = formData.get('variableName') as string; - const value = formData.get('variableValue') as string; - const type = formData.get('variableType') as string; - const driverId = formData.get('variableStorageDriverId') as string; - const variable = this.variable; - - variable.name = name; - variable.type = type; - variable.value = value; - variable.storageDriverId = isNullOrWhitespace(driverId) ? null : driverId; - - this.variableChanged.emit(variable); - await this.hide(); - }; - -} diff --git a/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variables-editor.tsx b/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variables-editor.tsx index c60aff0bb..765d69a68 100644 --- a/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variables-editor.tsx +++ b/src/designer/elsa-workflows-designer/src/components/designer/variables-editor/variables-editor.tsx @@ -1,15 +1,22 @@ import {Component, h, Prop, State, Event, EventEmitter, Watch} from "@stencil/core"; import {DeleteIcon, EditIcon} from "../../icons/tooling"; import {StorageDriverDescriptor, Variable} from "../../../models"; -import {isNullOrWhitespace} from "../../../utils"; import descriptorsStore from "../../../data/descriptors-store"; +import {ModalDialogInstance, ModalDialogService} from "../../shared/modal-dialog"; +import {Container} from "typedi"; @Component({ tag: 'elsa-variables-editor', shadow: false }) export class VariablesEditor { - private variableEditorDialog: HTMLElsaVariableEditorDialogElement; + private readonly modalDialogService: ModalDialogService; + private modalDialogInstance: ModalDialogInstance; + + constructor() { + this.modalDialogService = Container.get(ModalDialogService); + } + @Prop() variables?: Array; @Event() variablesChanged: EventEmitter>; @State() variablesState: Array = []; @@ -68,7 +75,6 @@ export class VariablesEditor { - this.variableEditorDialog = el} onVariableChanged={e => this.onVariableChanged(e)}/> ); } @@ -94,14 +100,13 @@ export class VariablesEditor { private onAddVariableClick = async () => { const newVariableName = this.generateNewVariableName(); - this.variableEditorDialog.variable = {name: newVariableName, type: 'Object', value: null}; - await this.variableEditorDialog.show(); + const variable = {name: newVariableName, type: 'Object', value: null}; + this.modalDialogInstance = this.modalDialogService.show(() => ) }; private onEditClick = async (e: Event, variable: Variable) => { e.preventDefault(); - this.variableEditorDialog.variable = variable; - await this.variableEditorDialog.show(); + this.modalDialogInstance = this.modalDialogService.show(() => ); }; private onDeleteClick = (e: Event, variable: Variable) => { diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/index.ts b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/index.ts new file mode 100644 index 000000000..ebdb4a1e5 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/index.ts @@ -0,0 +1,4 @@ +export * from './modal-dialog'; +export * from './modal-dialog-container'; +export * from './models'; +export * from './services'; diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog-container.tsx b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog-container.tsx new file mode 100644 index 000000000..befb0944e --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog-container.tsx @@ -0,0 +1,26 @@ +import {Component, Host, h} from '@stencil/core'; +import state from './state'; +import {ModalDialogInstance} from "./models"; + +@Component({ + tag: 'elsa-modal-dialog-container', + shadow: false, +}) +export class ModalDialogContainer { + + private onInstanceHidden = (instance: ModalDialogInstance) => { + let instances: Array = state.instances; + instances = instances.filter(x => x != instance); + state.instances = instances; + } + + render() { + const instances: Array = state.instances; + + return ( + + {instances.map(instance => this.onInstanceHidden(instance)}/>)} + + ); + } +} diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog.tsx b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog.tsx index cf89d57ef..6d2ae5cea 100644 --- a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog.tsx +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/modal-dialog.tsx @@ -6,19 +6,17 @@ import {ActionDefinition, ActionInvokedArgs, ActionType} from '../../../models'; tag: 'elsa-modal-dialog', shadow: false, }) -export class ElsaModalDialog { - @Prop() public actions: Array = []; - @Prop() public size: string = 'sm:w-full sm:max-w-6xl'; - @Event() public shown: EventEmitter; - @Event() public hidden: EventEmitter; - @Event() public actionInvoked: EventEmitter; - @State() private isVisible: boolean; +export class ModalDialog { private overlay: HTMLElement private modal: HTMLElement - render() { - return this.renderModal(); - } + @Prop() actions: Array = []; + @Prop() size: string = 'sm:w-full sm:max-w-6xl'; + @Prop() content: () => any = () =>
; + @Event() shown: EventEmitter; + @Event() hidden: EventEmitter; + @Event() actionInvoked: EventEmitter; + @State() private isVisible: boolean = true; @Method() async show(animate: boolean = true) { @@ -65,7 +63,14 @@ export class ElsaModalDialog { } } - renderModal() { + componentDidRender() { + if(this.isVisible) { + enter(this.overlay); + enter(this.modal).then(this.shown.emit); + } + } + + render() { const actions = this.actions; return ( @@ -92,7 +97,7 @@ export class ElsaModalDialog { class={`hidden inline-block sm:align-top bg-white rounded-lg text-left overflow-visible shadow-xl transform transition-all sm:my-8 sm:align-top ${this.size}`} role="dialog" aria-modal="true" aria-labelledby="modal-headline">
diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/models.ts b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/models.ts new file mode 100644 index 000000000..45bbb6572 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/models.ts @@ -0,0 +1,6 @@ +import {ActionDefinition} from "../../../models"; + +export interface ModalDialogInstance { + content: () => any; + actions: Array; +} diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/services.ts b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/services.ts new file mode 100644 index 000000000..2f12a08b1 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/services.ts @@ -0,0 +1,26 @@ +import 'reflect-metadata'; +import {Service} from "typedi"; +import state from "./state"; +import {ModalDialogInstance} from "./models"; + +@Service() +export class ModalDialogService { + + show(content: () => any): ModalDialogInstance { + const newInstance: ModalDialogInstance = { + content: content, + actions: [] + }; + + let instances: Array = state.instances; + instances = [...instances, newInstance]; + state.instances = instances; + return newInstance; + } + + hide(instance: ModalDialogInstance) { + let instances: Array = state.instances; + instances = instances.filter(x => x != instance); + state.instances = instances; + } +} diff --git a/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/state.ts b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/state.ts new file mode 100644 index 000000000..7d5ea4296 --- /dev/null +++ b/src/designer/elsa-workflows-designer/src/components/shared/modal-dialog/state.ts @@ -0,0 +1,7 @@ +import { createStore } from '@stencil/store'; + +const { state, onChange } = createStore({ + instances: [] +}); + +export default state; diff --git a/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar-menu/workflow-toolbar-menu.tsx b/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar-menu/workflow-toolbar-menu.tsx index 442094fe4..a4b04e649 100644 --- a/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar-menu/workflow-toolbar-menu.tsx +++ b/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar-menu/workflow-toolbar-menu.tsx @@ -11,11 +11,8 @@ import toolbarButtonMenuItemStore from "../../../data/toolbar-button-menu-item-s }) export class WorkflowToolbarMenu { private readonly eventBus: EventBus; - //private readonly model: ToolbarMenu; private menu: HTMLElement; private element: HTMLElement; - private workflowDefinitionBrowser: HTMLElsaWorkflowDefinitionBrowserElement; - private workflowInstanceBrowser: HTMLElsaWorkflowInstanceBrowserElement; constructor() { this.eventBus = Container.get(EventBus); @@ -60,7 +57,6 @@ export class WorkflowToolbarMenu { Settings
- this.workflowInstanceBrowser = el}/> ); } @@ -73,10 +69,6 @@ export class WorkflowToolbarMenu { this.closeMenu(); } - private onWorkflowInstancesClick = async () => { - await this.workflowInstanceBrowser.show(); - }; - private onMenuItemClick = async (e: MouseEvent, menuItem: ToolbarMenuItem) => { e.preventDefault(); await menuItem.onClick(); diff --git a/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar/workflow-toolbar.tsx b/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar/workflow-toolbar.tsx index 5d5ad356e..8e0cbd61f 100644 --- a/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar/workflow-toolbar.tsx +++ b/src/designer/elsa-workflows-designer/src/components/toolbar/workflow-toolbar/workflow-toolbar.tsx @@ -24,7 +24,7 @@ export class WorkflowToolbar {