Groundwork for internationalization of designer components
This commit is contained in:
parent
42d47386ed
commit
a5add7f52a
28
src/designer/elsa-workflows-studio/package-lock.json
generated
28
src/designer/elsa-workflows-studio/package-lock.json
generated
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@elsa-workflows/elsa-workflows-studio",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.4",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -27,6 +27,14 @@
|
|||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.14.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
|
||||
"integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@csstools/convert-colors": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz",
|
||||
|
|
@ -2391,6 +2399,19 @@
|
|||
"resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
|
||||
"integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg=="
|
||||
},
|
||||
"i18next": {
|
||||
"version": "20.3.3",
|
||||
"resolved": "https://registry.npmjs.org/i18next/-/i18next-20.3.3.tgz",
|
||||
"integrity": "sha512-tx9EUhHeaipvZ5pFLTaN9Xdm5Ssal774MpujaTA1Wv/ST/1My5SnoBmliY1lOpyEP5Z51Dq1gXifk/y4Yt3agQ==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.12.0"
|
||||
}
|
||||
},
|
||||
"i18next-wc": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/i18next-wc/-/i18next-wc-1.1.0.tgz",
|
||||
"integrity": "sha512-CL1KYATH6MViR4wXRxXx3rRvlHh5hHD0GTzy5DpxrDlmDmzJMjHoCqd5HCWKmdLrUkFtdTkfNT0hARpsyJ8OKA=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
|
|
@ -4083,6 +4104,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.7",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz",
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
"dagre-d3": "^0.6.4",
|
||||
"el-transition": "^0.0.7",
|
||||
"eslint": "7.29.0",
|
||||
"i18next": "^20.3.3",
|
||||
"i18next-wc": "^1.1.0",
|
||||
"js-event-bus": "^1.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
"moment": "^2.29.1",
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import { ToastNotificationOptions } from "./components/shared/elsa-toast-notific
|
|||
import { WebhookDefinition } from "./models/webhook";
|
||||
export namespace Components {
|
||||
interface ElsaActivityEditorModal {
|
||||
"culture": string;
|
||||
}
|
||||
interface ElsaActivityPickerModal {
|
||||
}
|
||||
|
|
@ -32,6 +33,7 @@ export namespace Components {
|
|||
"propertyModel": ActivityDefinitionProperty;
|
||||
}
|
||||
interface ElsaConfirmDialog {
|
||||
"culture": string;
|
||||
"hide": () => Promise<void>;
|
||||
"show": (caption: string, message: string) => Promise<boolean>;
|
||||
}
|
||||
|
|
@ -160,8 +162,10 @@ export namespace Components {
|
|||
"propertyModel": ActivityDefinitionProperty;
|
||||
}
|
||||
interface ElsaStudioHome {
|
||||
"culture": string;
|
||||
}
|
||||
interface ElsaStudioRoot {
|
||||
"culture": string;
|
||||
"monacoLibPath": string;
|
||||
"serverUrl": string;
|
||||
}
|
||||
|
|
@ -171,6 +175,7 @@ export namespace Components {
|
|||
"serverUrl": string;
|
||||
}
|
||||
interface ElsaStudioWebhookDefinitionsList {
|
||||
"culture": string;
|
||||
"history": RouterHistory;
|
||||
"serverUrl": string;
|
||||
}
|
||||
|
|
@ -179,11 +184,13 @@ export namespace Components {
|
|||
"serverUrl": string;
|
||||
}
|
||||
interface ElsaStudioWorkflowDefinitionsEdit {
|
||||
"culture": string;
|
||||
"match": MatchResults;
|
||||
"monacoLibPath": string;
|
||||
"serverUrl": string;
|
||||
}
|
||||
interface ElsaStudioWorkflowDefinitionsList {
|
||||
"culture": string;
|
||||
"history": RouterHistory;
|
||||
"serverUrl": string;
|
||||
}
|
||||
|
|
@ -229,6 +236,7 @@ export namespace Components {
|
|||
interface ElsaWorkflowDefinitionEditorNotifications {
|
||||
}
|
||||
interface ElsaWorkflowDefinitionEditorScreen {
|
||||
"culture": string;
|
||||
"exportWorkflow": () => Promise<void>;
|
||||
"getServerUrl": () => Promise<string>;
|
||||
"getWorkflowDefinitionId": () => Promise<string>;
|
||||
|
|
@ -238,6 +246,7 @@ export namespace Components {
|
|||
"workflowDefinitionId": string;
|
||||
}
|
||||
interface ElsaWorkflowDefinitionsListScreen {
|
||||
"culture": string;
|
||||
"history"?: RouterHistory;
|
||||
"serverUrl": string;
|
||||
}
|
||||
|
|
@ -264,6 +273,7 @@ export namespace Components {
|
|||
"workflowInstanceId": string;
|
||||
}
|
||||
interface ElsaWorkflowPublishButton {
|
||||
"culture": string;
|
||||
"publishing": boolean;
|
||||
"workflowDefinition": WorkflowDefinition;
|
||||
}
|
||||
|
|
@ -625,6 +635,7 @@ declare global {
|
|||
}
|
||||
declare namespace LocalJSX {
|
||||
interface ElsaActivityEditorModal {
|
||||
"culture"?: string;
|
||||
}
|
||||
interface ElsaActivityPickerModal {
|
||||
}
|
||||
|
|
@ -638,6 +649,7 @@ declare namespace LocalJSX {
|
|||
"propertyModel"?: ActivityDefinitionProperty;
|
||||
}
|
||||
interface ElsaConfirmDialog {
|
||||
"culture"?: string;
|
||||
}
|
||||
interface ElsaContextMenu {
|
||||
"history"?: RouterHistory;
|
||||
|
|
@ -772,8 +784,10 @@ declare namespace LocalJSX {
|
|||
"propertyModel"?: ActivityDefinitionProperty;
|
||||
}
|
||||
interface ElsaStudioHome {
|
||||
"culture"?: string;
|
||||
}
|
||||
interface ElsaStudioRoot {
|
||||
"culture"?: string;
|
||||
"monacoLibPath"?: string;
|
||||
"serverUrl"?: string;
|
||||
}
|
||||
|
|
@ -783,6 +797,7 @@ declare namespace LocalJSX {
|
|||
"serverUrl"?: string;
|
||||
}
|
||||
interface ElsaStudioWebhookDefinitionsList {
|
||||
"culture"?: string;
|
||||
"history"?: RouterHistory;
|
||||
"serverUrl"?: string;
|
||||
}
|
||||
|
|
@ -791,11 +806,13 @@ declare namespace LocalJSX {
|
|||
"serverUrl"?: string;
|
||||
}
|
||||
interface ElsaStudioWorkflowDefinitionsEdit {
|
||||
"culture"?: string;
|
||||
"match"?: MatchResults;
|
||||
"monacoLibPath"?: string;
|
||||
"serverUrl"?: string;
|
||||
}
|
||||
interface ElsaStudioWorkflowDefinitionsList {
|
||||
"culture"?: string;
|
||||
"history"?: RouterHistory;
|
||||
"serverUrl"?: string;
|
||||
}
|
||||
|
|
@ -836,12 +853,14 @@ declare namespace LocalJSX {
|
|||
interface ElsaWorkflowDefinitionEditorNotifications {
|
||||
}
|
||||
interface ElsaWorkflowDefinitionEditorScreen {
|
||||
"culture"?: string;
|
||||
"monacoLibPath"?: string;
|
||||
"onWorkflowSaved"?: (event: CustomEvent<WorkflowDefinition>) => void;
|
||||
"serverUrl"?: string;
|
||||
"workflowDefinitionId"?: string;
|
||||
}
|
||||
interface ElsaWorkflowDefinitionsListScreen {
|
||||
"culture"?: string;
|
||||
"history"?: RouterHistory;
|
||||
"serverUrl"?: string;
|
||||
}
|
||||
|
|
@ -865,6 +884,7 @@ declare namespace LocalJSX {
|
|||
"workflowInstanceId"?: string;
|
||||
}
|
||||
interface ElsaWorkflowPublishButton {
|
||||
"culture"?: string;
|
||||
"onExportClicked"?: (event: CustomEvent<any>) => void;
|
||||
"onImportClicked"?: (event: CustomEvent<File>) => void;
|
||||
"onPublishClicked"?: (event: CustomEvent<any>) => void;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
import {Component, h, Prop, getAssetPath} from '@stencil/core';
|
||||
import {Component, getAssetPath, h, Prop} from '@stencil/core';
|
||||
import 'i18next-wc';
|
||||
import {GetIntlMessage, IntlMessage} from "../../../i18n/intl-message";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
import {i18n} from "i18next";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-studio-home',
|
||||
|
|
@ -7,36 +12,42 @@ import {Component, h, Prop, getAssetPath} from '@stencil/core';
|
|||
})
|
||||
export class ElsaStudioHome {
|
||||
|
||||
@Prop() culture: string;
|
||||
private i18next: i18n;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
render() {
|
||||
const visualPath = getAssetPath('./assets/undraw_breaking_barriers_vnf3.svg');
|
||||
|
||||
const IntlMessage = GetIntlMessage(this.i18next);
|
||||
|
||||
return (
|
||||
<div class="elsa-relative elsa-bg-gray-800 elsa-overflow-hidden elsa-h-screen">
|
||||
<main class="elsa-mt-16 sm:elsa-mt-24">
|
||||
<div class="elsa-mx-auto elsa-max-w-7xl">
|
||||
<div class="lg:elsa-grid lg:elsa-grid-cols-12 lg:elsa-gap-8">
|
||||
<div class="elsa-px-4 sm:elsa-px-6 sm:elsa-text-center md:elsa-max-w-2xl md:elsa-mx-auto lg:elsa-col-span-6 lg:elsa-text-left lg:flex lg:elsa-items-center">
|
||||
<div>
|
||||
<h1 class="elsa-mt-4 elsa-text-4xl elsa-tracking-tight elsa-font-extrabold elsa-text-white sm:elsa-mt-5 sm:elsa-leading-none lg:elsa-mt-6 lg:elsa-text-5xl xl:elsa-text-6xl">
|
||||
<span class="md:elsa-block">Welcome to</span>
|
||||
|
||||
<span class="elsa-text-teal-400 md:elsa-block">Elsa Workflows</span> <span>2.0</span>
|
||||
</h1>
|
||||
<p class="elsa-mt-3 elsa-text-base elsa-text-gray-300 sm:elsa-mt-5 sm:elsa-text-xl lg:elsa-text-lg xl:elsa-text-xl">
|
||||
Use the dashboard app to manage all the things.
|
||||
</p>
|
||||
<main class="elsa-mt-16 sm:elsa-mt-24">
|
||||
<div class="elsa-mx-auto elsa-max-w-7xl">
|
||||
<div class="lg:elsa-grid lg:elsa-grid-cols-12 lg:elsa-gap-8">
|
||||
<div class="elsa-px-4 sm:elsa-px-6 sm:elsa-text-center md:elsa-max-w-2xl md:elsa-mx-auto lg:elsa-col-span-6 lg:elsa-text-left lg:flex lg:elsa-items-center">
|
||||
<div>
|
||||
<h1 class="elsa-mt-4 elsa-text-4xl elsa-tracking-tight elsa-font-extrabold elsa-text-white sm:elsa-mt-5 sm:elsa-leading-none lg:elsa-mt-6 lg:elsa-text-5xl xl:elsa-text-6xl">
|
||||
<span class="md:elsa-block"><IntlMessage label="Welcome" dangerous title="<span class='elsa-text-teal-400 md:elsa-block'>Elsa Workflows</span> <span>2.0</span>"/></span>
|
||||
</h1>
|
||||
<p class="elsa-mt-3 elsa-text-base elsa-text-gray-300 sm:elsa-mt-5 sm:elsa-text-xl lg:elsa-text-lg xl:elsa-text-xl">
|
||||
<IntlMessage label="Tagline"/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elsa-mt-16 sm:elsa-mt-24 lg:elsa-mt-0 lg:elsa-col-span-6">
|
||||
<div class="sm:elsa-max-w-md sm:elsa-w-full sm:elsa-mx-auto sm:elsa-rounded-lg sm:elsa-overflow-hidden">
|
||||
<div class="elsa-px-4 elsa-py-8 sm:elsa-px-10">
|
||||
<img src={visualPath} alt="" width={400} />
|
||||
<div class="elsa-mt-16 sm:elsa-mt-24 lg:elsa-mt-0 lg:elsa-col-span-6">
|
||||
<div class="sm:elsa-max-w-md sm:elsa-w-full sm:elsa-mx-auto sm:elsa-rounded-lg sm:elsa-overflow-hidden">
|
||||
<div class="elsa-px-4 elsa-py-8 sm:elsa-px-10">
|
||||
<img src={visualPath} alt="" width={400}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
'Welcome': 'Welcome to {{title}}',
|
||||
'Tagline': 'Use the dashboard app to manage all the things.'
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Welcome': 'Welkom bij {{title}}',
|
||||
'Tagline': 'Gebruik het dashboard om alles te regelen.'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
import {Component, h, Prop, getAssetPath} from '@stencil/core';
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
import {i18n} from "i18next";
|
||||
import {GetIntlMessage} from "../../../i18n/intl-message";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-studio-root',
|
||||
|
|
@ -9,10 +13,17 @@ export class ElsaStudioRoot {
|
|||
|
||||
@Prop({attribute: 'server-url', reflect: true}) serverUrl: string;
|
||||
@Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string;
|
||||
@Prop({attribute: 'culture', reflect: true}) culture: string;
|
||||
private i18next: i18n;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const serverUrl = this.serverUrl;
|
||||
const culture = this.culture;
|
||||
const monacoLibPath = this.monacoLibPath;
|
||||
const logoPath = getAssetPath('./assets/logo.png');
|
||||
|
||||
|
|
@ -20,6 +31,8 @@ export class ElsaStudioRoot {
|
|||
// const tunnelState: DashboardState = {
|
||||
// serverUrl: serverUrl,
|
||||
// };
|
||||
|
||||
const IntlMessage = GetIntlMessage(this.i18next);
|
||||
|
||||
return (
|
||||
<div class="elsa-h-screen elsa-bg-gray-100">
|
||||
|
|
@ -28,25 +41,28 @@ export class ElsaStudioRoot {
|
|||
<div class="elsa-flex elsa-items-center elsa-justify-between elsa-h-16">
|
||||
<div class="elsa-flex elsa-items-center">
|
||||
<div class="elsa-flex-shrink-0">
|
||||
<img class="elsa-h-8 elsa-w-8" src={logoPath} alt="Workflow"/>
|
||||
<stencil-route-link url="/"><img class="elsa-h-8 elsa-w-8" src={logoPath} alt="Workflow"/></stencil-route-link>
|
||||
</div>
|
||||
<div class="hidden md:elsa-block">
|
||||
<div class="elsa-ml-10 elsa-flex elsa-items-baseline elsa-space-x-4">
|
||||
<stencil-route-link url="/workflow-definitions" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">Workflow Definitions
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">
|
||||
<IntlMessage label="WorkflowDefinitions"/>
|
||||
</stencil-route-link>
|
||||
<stencil-route-link url="/workflow-instances" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">Workflow Instances
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">
|
||||
<IntlMessage label="WorkflowInstances"/>
|
||||
</stencil-route-link>
|
||||
<stencil-route-link url="/workflow-registry" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">Workflow Registry
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">
|
||||
<IntlMessage label="WorkflowRegistry"/>
|
||||
</stencil-route-link>
|
||||
|
||||
{/*<stencil-route-link url="/custom-activities" class="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium">Custom Activities</stencil-route-link>*/}
|
||||
<stencil-route-link url="/webhook-definitions" anchorClass="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium"
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">Webhook Definitions
|
||||
activeClass="elsa-text-white elsa-bg-gray-900">
|
||||
<IntlMessage label="WebhookDefinitions"/>
|
||||
</stencil-route-link>
|
||||
{/*<stencil-route-link url="/custom-activities" class="elsa-text-gray-300 hover:elsa-bg-gray-700 hover:elsa-text-white elsa-px-3 elsa-py-2 elsa-rounded-md elsa-text-sm elsa-font-medium">Custom Activities</stencil-route-link>*/}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -58,15 +74,15 @@ export class ElsaStudioRoot {
|
|||
{/*<Tunnel.Provider state={tunnelState}>*/}
|
||||
<stencil-router>
|
||||
<stencil-route-switch scrollTopOffset={0}>
|
||||
<stencil-route url="/" component="elsa-studio-home" exact={true}/>
|
||||
<stencil-route url="/workflow-registry" component="elsa-studio-workflow-registry" componentProps={{'serverUrl': serverUrl}} exact={true}/>
|
||||
<stencil-route url="/workflow-registry/:id" component="elsa-studio-workflow-blueprint-view" componentProps={{'serverUrl': serverUrl}}/>
|
||||
<stencil-route url="/workflow-definitions" component="elsa-studio-workflow-definitions-list" componentProps={{'serverUrl': serverUrl}} exact={true}/>
|
||||
<stencil-route url="/workflow-definitions/:id" component="elsa-studio-workflow-definitions-edit" componentProps={{'serverUrl': serverUrl, 'monacoLibPath': monacoLibPath}}/>
|
||||
<stencil-route url="/workflow-instances" component="elsa-studio-workflow-instances-list" componentProps={{'serverUrl': serverUrl}} exact={true}/>
|
||||
<stencil-route url="/workflow-instances/:id" component="elsa-studio-workflow-instances-view" componentProps={{'serverUrl': serverUrl}}/>
|
||||
<stencil-route url="/webhook-definitions" component="elsa-studio-webhook-definitions-list" componentProps={{'serverUrl': serverUrl}} exact={true}/>
|
||||
<stencil-route url="/webhook-definitions/:id" component="elsa-studio-webhook-definitions-edit" componentProps={{'serverUrl': serverUrl}}/>
|
||||
<stencil-route url="/" component="elsa-studio-home" exact={true} componentProps={{culture: culture}}/>
|
||||
<stencil-route url="/workflow-registry" component="elsa-studio-workflow-registry" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
|
||||
<stencil-route url="/workflow-registry/:id" component="elsa-studio-workflow-blueprint-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
|
||||
<stencil-route url="/workflow-definitions" component="elsa-studio-workflow-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
|
||||
<stencil-route url="/workflow-definitions/:id" component="elsa-studio-workflow-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture, 'monacoLibPath': monacoLibPath}}/>
|
||||
<stencil-route url="/workflow-instances" component="elsa-studio-workflow-instances-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
|
||||
<stencil-route url="/workflow-instances/:id" component="elsa-studio-workflow-instances-view" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
|
||||
<stencil-route url="/webhook-definitions" component="elsa-studio-webhook-definitions-list" componentProps={{'serverUrl': serverUrl, culture: culture}} exact={true}/>
|
||||
<stencil-route url="/webhook-definitions/:id" component="elsa-studio-webhook-definitions-edit" componentProps={{'serverUrl': serverUrl, culture: culture}}/>
|
||||
</stencil-route-switch>
|
||||
</stencil-router>
|
||||
{/*</Tunnel.Provider>*/}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
default: {
|
||||
'WorkflowDefinitions': 'Workflow Definitions',
|
||||
'WorkflowInstances': 'Workflow Instances',
|
||||
'WorkflowRegistry': 'Workflow Registry',
|
||||
'WebhookDefinitions': 'Webhook Definitions',
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
default: {
|
||||
'WorkflowDefinitions': 'Workflow Definities',
|
||||
'WorkflowInstances': 'Workflows',
|
||||
'WorkflowRegistry': 'Workflow Register',
|
||||
'WebhookDefinitions': 'Webhook Definities',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,5 +1,9 @@
|
|||
import {Component, h, Prop, State} from '@stencil/core';
|
||||
import {RouterHistory} from "@stencil/router";
|
||||
import 'i18next-wc';
|
||||
import {IntlMessage} from "../../../i18n/intl-message";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-studio-webhook-definitions-list',
|
||||
|
|
@ -8,6 +12,11 @@ import {RouterHistory} from "@stencil/router";
|
|||
export class ElsaStudioWebhookDefinitionsList {
|
||||
@Prop() history: RouterHistory;
|
||||
@Prop() serverUrl: string;
|
||||
@Prop() culture: string;
|
||||
|
||||
async componentWillLoad() {
|
||||
await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
|
@ -15,13 +24,13 @@ export class ElsaStudioWebhookDefinitionsList {
|
|||
<div class="elsa-border-b elsa-border-gray-200 elsa-px-4 elsa-py-4 sm:elsa-flex sm:elsa-items-center sm:elsa-justify-between sm:elsa-px-6 lg:elsa-px-8 elsa-bg-white">
|
||||
<div class="elsa-flex-1 elsa-min-w-0">
|
||||
<h1 class="elsa-text-lg elsa-font-medium elsa-leading-6 elsa-text-gray-900 sm:elsa-truncate">
|
||||
Webhook Definitions
|
||||
<IntlMessage label="Title"/>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="elsa-mt-4 elsa-flex sm:elsa-mt-0 sm:elsa-ml-4">
|
||||
<stencil-route-link url="/webhook-definitions/new"
|
||||
class="elsa-order-0 elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-border elsa-border-transparent elsa-shadow-sm elsa-text-sm elsa-font-medium elsa-rounded-md elsa-text-white elsa-bg-blue-600 hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-order-1 sm:elsa-ml-3">
|
||||
Create Webhook
|
||||
<IntlMessage label="CreateButton"/>
|
||||
</stencil-route-link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
default: {
|
||||
'Title': 'Webhook Definitions',
|
||||
'CreateButton': 'Create Webhook'
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
default: {
|
||||
'Title': 'Webhook Definitie',
|
||||
'CreateButton': 'Maak Webhook'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -9,6 +9,7 @@ export class ElsaStudioWorkflowDefinitionsEdit {
|
|||
@Prop() match: MatchResults;
|
||||
@Prop() serverUrl: string;
|
||||
@Prop() monacoLibPath: string;
|
||||
@Prop() culture: string;
|
||||
|
||||
id?: string;
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ export class ElsaStudioWorkflowDefinitionsEdit {
|
|||
const id = this.id;
|
||||
|
||||
return <div>
|
||||
<elsa-workflow-definition-editor-screen server-url={this.serverUrl} workflow-definition-id={id} monaco-lib-path={this.monacoLibPath}/>
|
||||
<elsa-workflow-definition-editor-screen server-url={this.serverUrl} workflow-definition-id={id} monaco-lib-path={this.monacoLibPath} culture={this.culture}/>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
import {Component, h, Prop, State} from '@stencil/core';
|
||||
import {RouterHistory} from "@stencil/router";
|
||||
import 'i18next-wc';
|
||||
import {GetIntlMessage, IntlMessage} from "../../../i18n/intl-message";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
import {i18n} from "i18next";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-studio-workflow-definitions-list',
|
||||
|
|
@ -8,25 +13,33 @@ import {RouterHistory} from "@stencil/router";
|
|||
export class ElsaStudioWorkflowDefinitionsList {
|
||||
@Prop() history: RouterHistory;
|
||||
@Prop() serverUrl: string;
|
||||
@Prop() culture: string;
|
||||
private i18next: i18n;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
render() {
|
||||
const IntlMessage = GetIntlMessage(this.i18next);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div class="elsa-border-b elsa-border-gray-200 elsa-px-4 elsa-py-4 sm:elsa-flex sm:elsa-items-center sm:elsa-justify-between sm:elsa-px-6 lg:elsa-px-8 elsa-bg-white">
|
||||
<div class="elsa-flex-1 elsa-min-w-0">
|
||||
<h1 class="elsa-text-lg elsa-font-medium elsa-leading-6 elsa-text-gray-900 sm:elsa-truncate">
|
||||
Workflow Definitions
|
||||
<IntlMessage label="Title"/>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="elsa-mt-4 elsa-flex sm:elsa-mt-0 sm:elsa-ml-4">
|
||||
<stencil-route-link url="/workflow-definitions/new"
|
||||
class="elsa-order-0 elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-border elsa-border-transparent elsa-shadow-sm elsa-text-sm elsa-font-medium elsa-rounded-md elsa-text-white elsa-bg-blue-600 hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-order-1 sm:elsa-ml-3">
|
||||
Create Workflow
|
||||
<IntlMessage label="CreateButton"/>
|
||||
</stencil-route-link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<elsa-workflow-definitions-list-screen history={this.history} serverUrl={this.serverUrl} />
|
||||
<elsa-workflow-definitions-list-screen history={this.history} serverUrl={this.serverUrl} culture={this.culture} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
default: {
|
||||
'Title': 'Workflow Definitions',
|
||||
'CreateButton': 'Create Workflow'
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
default: {
|
||||
'Title': 'Workflow Definities',
|
||||
'CreateButton': 'Nieuwe Workflow'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import i18next from 'i18next';
|
||||
|
||||
export async function loadTranslations(language: string, resources: any, defaultNamespace?: string): Promise<any> {
|
||||
const instance = i18next.createInstance();
|
||||
await instance.init({
|
||||
lng: language,
|
||||
fallbackLng: "en",
|
||||
resources: resources,
|
||||
defaultNS: defaultNamespace || 'default',
|
||||
debug: true
|
||||
});
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import i18next, {i18n} from 'i18next';
|
||||
import 'i18next-wc';
|
||||
import {h} from "@stencil/core";
|
||||
|
||||
export const IntlMessage = (props) => (<intl-message { ...{i18next, ...props }} />);
|
||||
|
||||
export function GetIntlMessage(i18next: i18n){
|
||||
return (props) => (<intl-message { ...{i18next, ...props }} />);
|
||||
}
|
||||
|
|
@ -1,20 +1,24 @@
|
|||
import {Component, Event, h, Host, State} from '@stencil/core';
|
||||
import {Component, Event, h, Host, Prop, State} from '@stencil/core';
|
||||
import {eventBus} from '../../../../services/event-bus';
|
||||
import state from '../../../../utils/store';
|
||||
import {ActivityDescriptor, ActivityModel, ActivityPropertyDescriptor, EventTypes, WorkflowStorageDescriptor} from "../../../../models";
|
||||
import {propertyDisplayManager} from '../../../../services/property-display-manager';
|
||||
import {checkBox, FormContext, section, selectField, SelectOption, textArea, textInput} from "../../../../utils/forms";
|
||||
import {i18n} from "i18next";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-activity-editor-modal',
|
||||
shadow: false,
|
||||
})
|
||||
export class ElsaActivityEditorModal {
|
||||
|
||||
@Prop() culture: string;
|
||||
@State() workflowStorageDescriptors: Array<WorkflowStorageDescriptor> = [];
|
||||
@State() activityModel: ActivityModel;
|
||||
@State() activityDescriptor: ActivityDescriptor;
|
||||
@State() selectedTab: string = 'Properties';
|
||||
i18next: i18n;
|
||||
dialog: HTMLElsaModalDialogElement;
|
||||
form: HTMLFormElement;
|
||||
formContext: FormContext;
|
||||
|
|
@ -24,18 +28,26 @@ export class ElsaActivityEditorModal {
|
|||
// This prevents the issue where the designer has e.g. one activity where the user edits the properties, cancels out, then opens the editor again, seeing the entered value still there.
|
||||
timestamp: Date = new Date();
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
const t = this.t;
|
||||
|
||||
eventBus.on(EventTypes.ShowActivityEditor, async (activity: ActivityModel, animate: boolean) => {
|
||||
this.activityModel = JSON.parse(JSON.stringify(activity));
|
||||
this.activityDescriptor = state.activityDescriptors.find(x => x.type == activity.type);
|
||||
this.workflowStorageDescriptors = state.workflowStorageDescriptors;
|
||||
this.formContext = new FormContext(this.activityModel, newValue => this.activityModel = newValue);
|
||||
this.selectedTab = 'Properties';
|
||||
this.selectedTab = t('Properties');
|
||||
this.timestamp = new Date();
|
||||
await this.dialog.show(animate);
|
||||
});
|
||||
}
|
||||
|
||||
t = (key: string) => this.i18next.t(key);
|
||||
|
||||
updateActivity(formData: FormData) {
|
||||
const activity = this.activityModel;
|
||||
const activityDescriptor = this.activityDescriptor;
|
||||
|
|
@ -67,15 +79,16 @@ export class ElsaActivityEditorModal {
|
|||
const activityDescriptor: ActivityDescriptor = this.activityDescriptor || {displayName: '', type: '', outcomes: [], category: '', traits: 0, browsable: false, inputProperties: [], outputProperties: [], description: ''};
|
||||
const propertyCategories = activityDescriptor.inputProperties.filter(x => x.category).map(x => x.category).distinct();
|
||||
const defaultProperties = activityDescriptor.inputProperties.filter(x => !x.category || x.category.length == 0);
|
||||
const t = this.t;
|
||||
let tabs: Array<string> = [];
|
||||
|
||||
if (defaultProperties.length > 0) {
|
||||
tabs.push('Properties');
|
||||
tabs.push(t('Tabs.Properties.Name'));
|
||||
}
|
||||
|
||||
tabs = [...tabs, ...propertyCategories];
|
||||
tabs.push('Common');
|
||||
tabs.push('Storage');
|
||||
tabs.push(t('Tabs.Common.Name'));
|
||||
tabs.push(t('Tabs.Storage.Name'));
|
||||
|
||||
let selectedTab = this.selectedTab;
|
||||
|
||||
|
|
@ -103,6 +116,7 @@ export class ElsaActivityEditorModal {
|
|||
const activityModel: ActivityModel = renderProps.activityModel;
|
||||
const inactiveClass = 'elsa-border-transparent elsa-text-gray-500 hover:elsa-text-gray-700 hover:elsa-border-gray-300';
|
||||
const selectedClass = 'elsa-border-blue-500 elsa-text-blue-600';
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
|
||||
|
|
@ -143,12 +157,12 @@ export class ElsaActivityEditorModal {
|
|||
<div class="elsa-bg-gray-50 elsa-px-4 elsa-py-3 sm:elsa-px-6 sm:elsa-flex sm:elsa-flex-row-reverse">
|
||||
<button type="submit"
|
||||
class="elsa-ml-3 elsa-inline-flex elsa-justify-center elsa-py-2 elsa-px-4 elsa-border elsa-border-transparent elsa-shadow-sm elsa-text-sm elsa-font-medium elsa-rounded-md elsa-text-white elsa-bg-blue-600 hover:elsa-bg-blue-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500">
|
||||
Save
|
||||
{t('Buttons.Save')}
|
||||
</button>
|
||||
<button type="button"
|
||||
onClick={() => this.onCancelClick()}
|
||||
class="elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-gray-300 elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-white elsa-text-base elsa-font-medium elsa-text-gray-700 hover:elsa-bg-gray-50 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-blue-500 sm:elsa-mt-0 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
Cancel
|
||||
{t('Buttons.Cancel')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -172,6 +186,7 @@ export class ElsaActivityEditorModal {
|
|||
|
||||
renderStorageTab(activityModel: ActivityModel, activityDescriptor: ActivityDescriptor) {
|
||||
const formContext = this.formContext;
|
||||
const t = this.t;
|
||||
let storageDescriptorOptions: Array<SelectOption> = this.workflowStorageDescriptors.map(x => ({value: x.name, text: x.displayName}));
|
||||
let outputProperties = activityDescriptor.outputProperties;
|
||||
let inputProperties = activityDescriptor.inputProperties;
|
||||
|
|
@ -185,7 +200,7 @@ export class ElsaActivityEditorModal {
|
|||
}
|
||||
|
||||
return (
|
||||
<div class={`flex ${this.getHiddenClass('Storage')}`}>
|
||||
<div class={`flex ${this.getHiddenClass(t('Tabs.Storage.Name'))}`}>
|
||||
<div class="elsa-space-y-8 elsa-w-full">
|
||||
|
||||
{section('Workflow Context')}
|
||||
|
|
@ -209,13 +224,14 @@ export class ElsaActivityEditorModal {
|
|||
|
||||
renderCommonTab(activityModel: ActivityModel) {
|
||||
const formContext = this.formContext;
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<div class={`flex ${this.getHiddenClass('Common')}`}>
|
||||
<div class={`flex ${this.getHiddenClass(t('Tabs.Common.Name'))}`}>
|
||||
<div class="elsa-space-y-8 elsa-w-full">
|
||||
{textInput(formContext, 'name', 'Name', activityModel.name, 'The technical name of the activity.', 'activityName')}
|
||||
{textInput(formContext, 'displayName', 'Display Name', activityModel.displayName, 'A friendly name of the activity.', 'activityDisplayName')}
|
||||
{textArea(formContext, 'description', 'Description', activityModel.description, 'A custom description for this activity', 'activityDescription')}
|
||||
{textInput(formContext, 'name', t('Tabs.Common.Fields.Name.Label'), activityModel.name, t('Tabs.Common.Fields.Name.Hint'), 'activityName')}
|
||||
{textInput(formContext, 'displayName', t('Tabs.Common.Fields.DisplayName.Label'), activityModel.displayName, t('Tabs.Common.Fields.DisplayName.Hint'), 'activityDisplayName')}
|
||||
{textArea(formContext, 'description', t('Tabs.Common.Fields.Description.Label'), activityModel.description, t('Tabs.Common.Fields.Description.Hint'), 'activityDescription')}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
@ -228,9 +244,10 @@ export class ElsaActivityEditorModal {
|
|||
return undefined;
|
||||
|
||||
const key = `activity-settings:${activityModel.activityId}`;
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<div key={key} class={`elsa-grid elsa-grid-cols-1 elsa-gap-y-6 elsa-gap-x-4 sm:elsa-grid-cols-6 ${this.getHiddenClass('Properties')}`}>
|
||||
<div key={key} class={`elsa-grid elsa-grid-cols-1 elsa-gap-y-6 elsa-gap-x-4 sm:elsa-grid-cols-6 ${this.getHiddenClass(t('Tabs.Properties.Name'))}`}>
|
||||
{propertyDescriptors.map(property => this.renderPropertyEditor(activityModel, property))}
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
"Buttons": {
|
||||
'Save': 'Save',
|
||||
'Cancel': 'Cancel'
|
||||
},
|
||||
'Tabs': {
|
||||
'Properties': {
|
||||
'Name': 'Properties'
|
||||
},
|
||||
'Common': {
|
||||
'Name': 'Common',
|
||||
'Fields': {
|
||||
'Name': {
|
||||
'Label': 'Name',
|
||||
'Hint': 'The technical name of the activity.'
|
||||
},
|
||||
'DisplayName': {
|
||||
'Label': 'Display Name',
|
||||
'Hint': 'The friendly name of the activity.'
|
||||
},
|
||||
'Description': {
|
||||
'Label': 'Description',
|
||||
'Hint': 'A custom description for this activity.'
|
||||
}
|
||||
}
|
||||
},
|
||||
'Storage': {
|
||||
'Name': 'Storage'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Buttons': {
|
||||
'Save': 'Opslaan',
|
||||
'Cancel': 'Annuleren'
|
||||
},
|
||||
'Tabs': {
|
||||
'Properties': {
|
||||
'Name': 'Eigenschappen'
|
||||
},
|
||||
'Common': {
|
||||
'Name': 'Algemeen',
|
||||
'Fields': {
|
||||
'Name': {
|
||||
'Label': 'Naam',
|
||||
'Hint': 'De technische naam van de activity.'
|
||||
},
|
||||
'DisplayName': {
|
||||
'Label': 'Weergave Naam',
|
||||
'Hint': 'De gebruikersvriendelijke naam van de activity.'
|
||||
},
|
||||
'Description': {
|
||||
'Label': 'Omschrijving',
|
||||
'Hint': 'Een aangepaste omschrijving van de activity.'
|
||||
}
|
||||
}
|
||||
},
|
||||
'Storage': {
|
||||
'Name': 'Opslag'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -8,6 +8,9 @@ import Tunnel, {WorkflowEditorState} from '../../../../data/workflow-editor';
|
|||
import {downloadFromBlob} from "../../../../utils/download";
|
||||
import {ActivityContextMenuState, WorkflowDesignerMode} from "../../../designers/tree/elsa-designer-tree/models";
|
||||
import {registerClickOutside} from "stencil-click-outside";
|
||||
import {i18n} from "i18next";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-definition-editor-screen',
|
||||
|
|
@ -23,6 +26,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
@Prop({attribute: 'workflow-definition-id', reflect: true}) workflowDefinitionId: string;
|
||||
@Prop({attribute: 'server-url', reflect: true}) serverUrl: string;
|
||||
@Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string;
|
||||
@Prop() culture: string;
|
||||
@State() workflowDefinition: WorkflowDefinition;
|
||||
@State() workflowModel: WorkflowModel;
|
||||
@State() publishing: boolean;
|
||||
|
|
@ -41,6 +45,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
activity: null,
|
||||
};
|
||||
|
||||
i18next: i18n;
|
||||
el: HTMLElement;
|
||||
designer: HTMLElsaDesignerTreeElement;
|
||||
|
||||
|
|
@ -127,11 +132,20 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
}
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
await this.serverUrlChangedHandler(this.serverUrl);
|
||||
await this.workflowDefinitionIdChangedHandler(this.workflowDefinitionId);
|
||||
await this.monacoLibPathChangedHandler(this.monacoLibPath);
|
||||
}
|
||||
|
||||
async componentDidLoad() {
|
||||
|
||||
if (!this.designer) {
|
||||
this.designer = this.el.querySelector("elsa-designer-tree") as HTMLElsaDesignerTreeElement;
|
||||
this.designer.model = this.workflowModel;
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
eventBus.on(EventTypes.UpdateWorkflowSettings, this.onUpdateWorkflowSettings);
|
||||
}
|
||||
|
|
@ -139,13 +153,8 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
disconnectedCallback() {
|
||||
eventBus.detach(EventTypes.UpdateWorkflowSettings, this.onUpdateWorkflowSettings);
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
if (!this.designer) {
|
||||
this.designer = this.el.querySelector("elsa-designer-tree") as HTMLElsaDesignerTreeElement;
|
||||
this.designer.model = this.workflowModel;
|
||||
}
|
||||
}
|
||||
|
||||
t = (key: string) => this.i18next.t(key);
|
||||
|
||||
async loadActivityDescriptors() {
|
||||
const client = createElsaClient(this.serverUrl);
|
||||
|
|
@ -402,6 +411,8 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
}
|
||||
|
||||
renderActivityContextMenu() {
|
||||
const t = this.t;
|
||||
|
||||
return <div
|
||||
data-transition-enter="elsa-transition elsa-ease-out elsa-duration-100"
|
||||
data-transition-enter-start="elsa-transform elsa-opacity-0 elsa-scale-95"
|
||||
|
|
@ -424,7 +435,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
href="#"
|
||||
class="elsa-block elsa-px-4 elsa-py-2 elsa-text-sm elsa-leading-5 elsa-text-gray-700 hover:elsa-bg-gray-100 hover:elsa-text-gray-900 focus:elsa-outline-none focus:elsa-bg-gray-100 focus:elsa-text-gray-900"
|
||||
role="menuitem">
|
||||
Edit
|
||||
{t('ActivityContextMenu.Edit')}
|
||||
</a>
|
||||
</div>
|
||||
<div class="elsa-border-t elsa-border-gray-100"/>
|
||||
|
|
@ -434,7 +445,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
href="#"
|
||||
class="elsa-block elsa-px-4 elsa-py-2 elsa-text-sm elsa-leading-5 elsa-text-gray-700 hover:elsa-bg-gray-100 hover:elsa-text-gray-900 focus:elsa-outline-none focus:elsa-bg-gray-100 focus:elsa-text-gray-900"
|
||||
role="menuitem">
|
||||
Delete
|
||||
{t('ActivityContextMenu.Delete')}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -446,7 +457,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
}
|
||||
|
||||
renderActivityEditor() {
|
||||
return <elsa-activity-editor-modal/>;
|
||||
return <elsa-activity-editor-modal culture={this.culture}/>;
|
||||
}
|
||||
|
||||
renderWorkflowSettingsButton() {
|
||||
|
|
@ -471,8 +482,9 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
if (this.publishing)
|
||||
return undefined;
|
||||
|
||||
const t = this.t;
|
||||
const message =
|
||||
this.unPublishing ? 'Unpublishing...' : this.unPublished ? 'Unpublished'
|
||||
this.unPublishing ? t('Unpublishing...') : this.unPublished ? t('Unpublished')
|
||||
: this.saving ? 'Saving...' : this.saved ? 'Saved'
|
||||
: this.importing ? 'Importing...' : this.imported ? 'Imported'
|
||||
: null;
|
||||
|
|
@ -505,6 +517,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
|
|||
onUnPublishClicked={() => this.onUnPublishClicked()}
|
||||
onExportClicked={() => this.onExportClicked()}
|
||||
onImportClicked={e => this.onImportClicked(e.detail)}
|
||||
culture={this.culture}
|
||||
/>;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
'Publishing': 'Publishing...',
|
||||
'Published': 'Published',
|
||||
"ActivityContextMenu":{
|
||||
"Edit": "Edit",
|
||||
"Delete": "Delete"
|
||||
}
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Publishing': 'Publiceren...',
|
||||
'Published': 'Gepubliceerd',
|
||||
"ActivityContextMenu":{
|
||||
"Edit": "Bewerken",
|
||||
"Delete": "Verwijderen"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
import {Component, Host, h, Prop, State, Event, EventEmitter, Watch} from '@stencil/core';
|
||||
import {enter, leave, toggle} from 'el-transition'
|
||||
import {leave, toggle} from 'el-transition'
|
||||
import {registerClickOutside} from "stencil-click-outside";
|
||||
import {VersionOptions, WorkflowDefinition} from "../../../../models";
|
||||
import {createElsaClient} from "../../../../services/elsa-client";
|
||||
import {WorkflowDefinition} from "../../../../models";
|
||||
import Tunnel from '../../../../data/workflow-editor';
|
||||
import {i18n} from "i18next";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-publish-button',
|
||||
|
|
@ -13,13 +15,21 @@ export class ElsaWorkflowPublishButton {
|
|||
|
||||
@Prop() workflowDefinition: WorkflowDefinition;
|
||||
@Prop() publishing: boolean;
|
||||
@Prop() culture: string;
|
||||
@Event({bubbles: true}) publishClicked: EventEmitter;
|
||||
@Event({bubbles: true}) unPublishClicked: EventEmitter;
|
||||
@Event({bubbles: true}) exportClicked: EventEmitter;
|
||||
@Event({bubbles: true}) importClicked: EventEmitter<File>;
|
||||
|
||||
i18next: i18n;
|
||||
menu: HTMLElement;
|
||||
fileInput: HTMLInputElement;
|
||||
|
||||
async componentWillLoad(){
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
t = (key: string) => this.i18next.t(key);
|
||||
|
||||
closeMenu() {
|
||||
leave(this.menu);
|
||||
|
|
@ -66,6 +76,8 @@ export class ElsaWorkflowPublishButton {
|
|||
}
|
||||
|
||||
render() {
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<Host class="elsa-block" ref={el => registerClickOutside(this, el, this.closeMenu)}>
|
||||
<span class="elsa-relative elsa-z-0 elsa-inline-flex elsa-shadow-sm elsa-rounded-md">
|
||||
|
|
@ -90,11 +102,11 @@ export class ElsaWorkflowPublishButton {
|
|||
|
||||
<div class="elsa-py-1" role="none">
|
||||
<a href="#" onClick={e => this.onExportClick(e)} class="elsa-block elsa-px-4 elsa-py-2 elsa-text-sm elsa-text-gray-700 hover:elsa-bg-gray-100 hover:elsa-text-gray-900" role="menuitem">
|
||||
Export
|
||||
{t('Export')}
|
||||
</a>
|
||||
|
||||
<a href="#" onClick={e => this.onImportClick(e)} class="elsa-block elsa-px-4 elsa-py-2 elsa-text-sm elsa-text-gray-700 hover:elsa-bg-gray-100 hover:elsa-text-gray-900" role="menuitem">
|
||||
Import
|
||||
{t('Import')}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
|
@ -110,16 +122,20 @@ export class ElsaWorkflowPublishButton {
|
|||
}
|
||||
|
||||
renderPublishButton() {
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<button type="button"
|
||||
onClick={() => this.onPublishClick()}
|
||||
class="elsa-relative elsa-inline-flex elsa-items-center elsa-px-4 elsa-py-2 elsa-rounded-l-md elsa-border elsa-border-gray-300 elsa-bg-white elsa-text-sm elsa-font-medium elsa-text-gray-700 hover:elsa-bg-gray-50 focus:elsa-z-10 focus:elsa-outline-none focus:elsa-ring-1 focus:elsa-ring-blue-500 focus:elsa-border-blue-500">
|
||||
|
||||
Publish
|
||||
{t('Publish')}
|
||||
</button>);
|
||||
}
|
||||
|
||||
renderPublishingButton() {
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<button type="button"
|
||||
disabled={true}
|
||||
|
|
@ -129,7 +145,7 @@ export class ElsaWorkflowPublishButton {
|
|||
<circle class="elsa-opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/>
|
||||
<path class="elsa-opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/>
|
||||
</svg>
|
||||
Publishing
|
||||
{t('Publishing')}
|
||||
</button>);
|
||||
}
|
||||
|
||||
|
|
@ -137,10 +153,12 @@ export class ElsaWorkflowPublishButton {
|
|||
if (!this.workflowDefinition.isPublished)
|
||||
return undefined;
|
||||
|
||||
const t = this.t;
|
||||
|
||||
return (
|
||||
<div class="elsa-py-1" role="none">
|
||||
<a href="#" onClick={e => this.onUnPublishClick(e)} class="elsa-block elsa-px-4 elsa-py-2 elsa-text-sm elsa-text-gray-700 hover:elsa-bg-gray-100 hover:elsa-text-gray-900" role="menuitem">
|
||||
Unpublish
|
||||
{t('Unpublish')}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
'Publish': 'Publish',
|
||||
'Publishing': 'Publishing',
|
||||
'Unpublish': 'Unpublish',
|
||||
'Import': 'Import',
|
||||
'Export': 'Export',
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Publish': 'Publiceren',
|
||||
'Publishing': 'Bezig met publiceren',
|
||||
'Unpublish': 'Niet-publiceren',
|
||||
'Import': 'Importeren',
|
||||
'Export': 'Exporteren',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -2,6 +2,10 @@ import {Component, h, Prop, State} from '@stencil/core';
|
|||
import {createElsaClient} from "../../../../services/elsa-client";
|
||||
import {PagedList, VersionOptions, WorkflowDefinitionSummary} from "../../../../models";
|
||||
import {RouterHistory} from "@stencil/router";
|
||||
import {i18n} from "i18next";
|
||||
import {loadTranslations} from "../../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
import {GetIntlMessage} from "../../../i18n/intl-message";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-workflow-definitions-list-screen',
|
||||
|
|
@ -10,17 +14,21 @@ import {RouterHistory} from "@stencil/router";
|
|||
export class ElsaWorkflowDefinitionsListScreen {
|
||||
@Prop() history?: RouterHistory;
|
||||
@Prop() serverUrl: string;
|
||||
@Prop() culture: string;
|
||||
@State() workflowDefinitions: PagedList<WorkflowDefinitionSummary> = {items: [], page: 1, pageSize: 50, totalCount: 0};
|
||||
@State() publishedWorkflowDefinitions: WorkflowDefinitionSummary[] = [];
|
||||
private i18next: i18n;
|
||||
|
||||
confirmDialog: HTMLElsaConfirmDialogElement;
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
await this.loadWorkflowDefinitions();
|
||||
}
|
||||
|
||||
async onDeleteClick(e: Event, workflowDefinition: WorkflowDefinitionSummary) {
|
||||
const result = await this.confirmDialog.show('Delete Workflow Definition', 'Are you sure you wish to permanently delete this workflow, including all of its workflow instances?');
|
||||
const t = x => this.i18next.t(x);
|
||||
const result = await this.confirmDialog.show(t('DeleteConfirmationModel.Title'), t('DeleteConfirmationModel.Message'));
|
||||
|
||||
if (!result)
|
||||
return;
|
||||
|
|
@ -48,6 +56,8 @@ export class ElsaWorkflowDefinitionsListScreen {
|
|||
|
||||
render() {
|
||||
const workflowDefinitions = this.workflowDefinitions.items;
|
||||
const i18next = this.i18next;
|
||||
const IntlMessage = GetIntlMessage(i18next);
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
|
@ -55,15 +65,17 @@ export class ElsaWorkflowDefinitionsListScreen {
|
|||
<table class="elsa-min-w-full">
|
||||
<thead>
|
||||
<tr class="elsa-border-t elsa-border-gray-200">
|
||||
<th class="elsa-px-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-left elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider"><span class="lg:elsa-pl-2">Name</span></th>
|
||||
<th class="elsa-px-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-left elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider">
|
||||
Instances
|
||||
<span class="lg:elsa-pl-2"><IntlMessage label="Name"/></span>
|
||||
</th>
|
||||
<th class="elsa-px-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-left elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider">
|
||||
<IntlMessage label="Instances"/>
|
||||
</th>
|
||||
<th class="hidden md:elsa-table-cell elsa-px-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-right elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider">
|
||||
Latest Version
|
||||
<IntlMessage label="LatestVersion"/>
|
||||
</th>
|
||||
<th class="hidden md:elsa-table-cell elsa-px-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-right elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider">
|
||||
Published Version
|
||||
<IntlMessage label="PublishedVersion"/>
|
||||
</th>
|
||||
<th class="elsa-pr-6 elsa-py-3 elsa-border-b elsa-border-gray-200 elsa-bg-gray-50 elsa-text-right elsa-text-xs elsa-leading-4 elsa-font-medium elsa-text-gray-500 elsa-uppercase elsa-tracking-wider"/>
|
||||
</tr>
|
||||
|
|
@ -112,7 +124,7 @@ export class ElsaWorkflowDefinitionsListScreen {
|
|||
|
||||
<td class="elsa-px-6 elsa-py-3 elsa-text-sm elsa-leading-5 elsa-text-gray-500 elsa-font-medium">
|
||||
<div class="elsa-flex elsa-items-center elsa-space-x-3 lg:elsa-pl-2">
|
||||
<stencil-route-link url={instancesUrl} anchorClass="elsa-truncate hover:elsa-text-gray-600">Instances</stencil-route-link>
|
||||
<stencil-route-link url={instancesUrl} anchorClass="elsa-truncate hover:elsa-text-gray-600"><IntlMessage label="Instances"/></stencil-route-link>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
|
@ -120,8 +132,8 @@ export class ElsaWorkflowDefinitionsListScreen {
|
|||
<td class="hidden md:elsa-table-cell elsa-px-6 elsa-py-3 elsa-whitespace-no-wrap elsa-text-sm elsa-leading-5 elsa-text-gray-500 elsa-text-right">{publishedVersionNumber}</td>
|
||||
<td class="elsa-pr-6">
|
||||
<elsa-context-menu history={this.history} menuItems={[
|
||||
{text: 'Edit', anchorUrl: editUrl, icon: editIcon},
|
||||
{text: 'Delete', clickHandler: e => this.onDeleteClick(e, workflowDefinition), icon: deleteIcon}
|
||||
{text: i18next.t('Edit'), anchorUrl: editUrl, icon: editIcon},
|
||||
{text: i18next.t('Delete'), clickHandler: e => this.onDeleteClick(e, workflowDefinition), icon: deleteIcon}
|
||||
]}/>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -131,7 +143,7 @@ export class ElsaWorkflowDefinitionsListScreen {
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<elsa-confirm-dialog ref={el => this.confirmDialog = el}/>
|
||||
<elsa-confirm-dialog ref={el => this.confirmDialog = el} culture={this.culture}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,30 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
'Name': 'Name',
|
||||
'Instances': 'Instances',
|
||||
'LatestVersion': 'Latest Version',
|
||||
'PublishedVersion': 'Published Version',
|
||||
'Edit': 'Edit',
|
||||
'Delete': 'Delete',
|
||||
'DeleteConfirmationModel': {
|
||||
'Title': 'Delete Workflow Definition',
|
||||
'Message': 'Are you sure you wish to permanently delete this workflow, including all of its workflow instances?'
|
||||
}
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Name': 'Naam',
|
||||
'Instances': 'Instanties',
|
||||
'LatestVersion': 'Laatste Versie',
|
||||
'PublishedVersion': 'Gepubliceerde Versie',
|
||||
'Edit': 'Bewerken',
|
||||
'Delete': 'Verwijderen',
|
||||
'DeleteConfirmationModel': {
|
||||
'Title': 'Verwijder Workflow Definitie',
|
||||
'Message': 'Weet je zeker dat je deze workflow permanent wilt verwijderen, inclusief alle bijbehorende workflow instanties?'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
import {Component, h, Host, Method, State} from '@stencil/core';
|
||||
import {Component, h, Host, Method, Prop, State} from '@stencil/core';
|
||||
import {i18n} from "i18next";
|
||||
import {loadTranslations} from "../../i18n/i18n-loader";
|
||||
import {resources} from "./localizations";
|
||||
|
||||
@Component({
|
||||
tag: 'elsa-confirm-dialog',
|
||||
|
|
@ -8,6 +11,8 @@ export class ElsaConfirmDialog {
|
|||
|
||||
@State() caption: string;
|
||||
@State() message: string;
|
||||
@Prop() culture: string;
|
||||
private i18next: i18n;
|
||||
|
||||
dialog: HTMLElsaModalDialogElement;
|
||||
fulFill: (value: (PromiseLike<boolean> | boolean)) => void;
|
||||
|
|
@ -31,6 +36,10 @@ export class ElsaConfirmDialog {
|
|||
await this.dialog.hide(true);
|
||||
}
|
||||
|
||||
async componentWillLoad() {
|
||||
this.i18next = await loadTranslations(this.culture, resources);
|
||||
}
|
||||
|
||||
async onDismissClick() {
|
||||
this.fulFill(false);
|
||||
await this.hide();
|
||||
|
|
@ -44,6 +53,8 @@ export class ElsaConfirmDialog {
|
|||
}
|
||||
|
||||
render() {
|
||||
const t = x => this.i18next.t(x);
|
||||
|
||||
return (
|
||||
<Host>
|
||||
<elsa-modal-dialog ref={el => this.dialog = el}>
|
||||
|
|
@ -81,12 +92,12 @@ export class ElsaConfirmDialog {
|
|||
<button type="button"
|
||||
onClick={() => this.onAcceptClick()}
|
||||
class="elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-transparent elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-red-600 elsa-text-base elsa-font-medium elsa-text-white hover:elsa-bg-red-700 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:elsa-ring-red-500 sm:elsa-ml-3 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
Yes
|
||||
{t('Yes')}
|
||||
</button>
|
||||
<button type="button"
|
||||
onClick={() => this.onDismissClick()}
|
||||
class="elsa-mt-3 elsa-w-full elsa-inline-flex elsa-justify-center elsa-rounded-md elsa-border elsa-border-gray-300 elsa-shadow-sm elsa-px-4 elsa-py-2 elsa-bg-white elsa-text-base elsa-font-medium elsa-text-gray-700 hover:elsa-text-gray-500 focus:elsa-outline-none focus:elsa-ring-2 focus:elsa-ring-offset-2 focus:ring-indigo-500 sm:elsa-mt-0 sm:elsa-w-auto sm:elsa-text-sm">
|
||||
No
|
||||
{t('No')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
export const resources = {
|
||||
'en': {
|
||||
'default': {
|
||||
'Yes': 'Yes',
|
||||
'No': 'No'
|
||||
}
|
||||
},
|
||||
'nl-NL': {
|
||||
'default': {
|
||||
'Yes': 'Ja',
|
||||
'No': 'Nee',
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<elsa-studio-root server-url="https://localhost:11000" monaco-lib-path="build/assets/js/monaco-editor/min"></elsa-studio-root>
|
||||
<elsa-studio-root server-url="https://localhost:11000" monaco-lib-path="build/assets/js/monaco-editor/min" culture="nl-NL"></elsa-studio-root>
|
||||
<!--<elsa-workflow-definition-editor-screen server-url="https://localhost:11000" monaco-lib-path="build/assets/js/monaco-editor/min"></elsa-workflow-definition-editor-screen>-->
|
||||
<!--<elsa-workflow-instance-list-screen server-url="https://localhost:11000"></elsa-workflow-instance-list-screen>-->
|
||||
<!--<elsa-external-events></elsa-external-events>-->
|
||||
|
|
|
|||
Loading…
Reference in a new issue