Added feature panel. Added ability to manage experimental features. (#2619)

This commit is contained in:
simona-taran 2021-12-21 15:33:17 +02:00 committed by GitHub
parent 5bc368efe7
commit 88e6987176
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 369 additions and 29 deletions

View file

@ -0,0 +1,7 @@
{
"workflowLayout": {
"enabled": true,
"ui": true,
"defaultValue": "topbottom"
}
}

View file

@ -49,6 +49,9 @@ export namespace Components {
interface ElsaCopyButton {
"value": string;
}
interface ElsaDesignerPanel {
"culture": string;
}
interface ElsaDesignerTree {
"activityBorderColor"?: (activity: ActivityModel) => string;
"activityContextMenu"?: ActivityContextMenuState;
@ -201,8 +204,9 @@ export namespace Components {
"addPlugin": (pluginType: any) => Promise<void>;
"addPlugins": (pluginTypes: Array<any>) => Promise<void>;
"basePath": string;
"config": string;
"culture": string;
"featuresString": string;
"features": any;
"monacoLibPath": string;
"serverUrl": string;
}
@ -285,6 +289,7 @@ export namespace Components {
"basePath": string;
"culture": string;
"exportWorkflow": () => Promise<void>;
"features": string;
"getServerUrl": () => Promise<string>;
"getWorkflowDefinitionId": () => Promise<string>;
"history": RouterHistory;
@ -410,6 +415,12 @@ declare global {
prototype: HTMLElsaCopyButtonElement;
new (): HTMLElsaCopyButtonElement;
};
interface HTMLElsaDesignerPanelElement extends Components.ElsaDesignerPanel, HTMLStencilElement {
}
var HTMLElsaDesignerPanelElement: {
prototype: HTMLElsaDesignerPanelElement;
new (): HTMLElsaDesignerPanelElement;
};
interface HTMLElsaDesignerTreeElement extends Components.ElsaDesignerTree, HTMLStencilElement {
}
var HTMLElsaDesignerTreeElement: {
@ -731,6 +742,7 @@ declare global {
"elsa-context-menu": HTMLElsaContextMenuElement;
"elsa-control": HTMLElsaControlElement;
"elsa-copy-button": HTMLElsaCopyButtonElement;
"elsa-designer-panel": HTMLElsaDesignerPanelElement;
"elsa-designer-tree": HTMLElsaDesignerTreeElement;
"elsa-dictionary-property": HTMLElsaDictionaryPropertyElement;
"elsa-dropdown-button": HTMLElsaDropdownButtonElement;
@ -815,6 +827,11 @@ declare namespace LocalJSX {
interface ElsaCopyButton {
"value"?: string;
}
interface ElsaDesignerPanel {
"culture"?: string;
"onFeatureChanged"?: (event: CustomEvent<string>) => void;
"onFeatureStatusChanged"?: (event: CustomEvent<string>) => void;
}
interface ElsaDesignerTree {
"activityBorderColor"?: (activity: ActivityModel) => string;
"activityContextMenu"?: ActivityContextMenuState;
@ -973,8 +990,9 @@ declare namespace LocalJSX {
}
interface ElsaStudioRoot {
"basePath"?: string;
"config"?: string;
"culture"?: string;
"featuresString"?: string;
"features"?: any;
"monacoLibPath"?: string;
"onInitialized"?: (event: CustomEvent<ElsaStudio>) => void;
"onInitializing"?: (event: CustomEvent<ElsaStudio>) => void;
@ -1053,6 +1071,7 @@ declare namespace LocalJSX {
interface ElsaWorkflowDefinitionEditorScreen {
"basePath"?: string;
"culture"?: string;
"features"?: string;
"history"?: RouterHistory;
"monacoLibPath"?: string;
"onWorkflowSaved"?: (event: CustomEvent<WorkflowDefinition>) => void;
@ -1136,6 +1155,7 @@ declare namespace LocalJSX {
"elsa-context-menu": ElsaContextMenu;
"elsa-control": ElsaControl;
"elsa-copy-button": ElsaCopyButton;
"elsa-designer-panel": ElsaDesignerPanel;
"elsa-designer-tree": ElsaDesignerTree;
"elsa-dictionary-property": ElsaDictionaryProperty;
"elsa-dropdown-button": ElsaDropdownButton;
@ -1202,6 +1222,7 @@ declare module "@stencil/core" {
"elsa-context-menu": LocalJSX.ElsaContextMenu & JSXBase.HTMLAttributes<HTMLElsaContextMenuElement>;
"elsa-control": LocalJSX.ElsaControl & JSXBase.HTMLAttributes<HTMLElsaControlElement>;
"elsa-copy-button": LocalJSX.ElsaCopyButton & JSXBase.HTMLAttributes<HTMLElsaCopyButtonElement>;
"elsa-designer-panel": LocalJSX.ElsaDesignerPanel & JSXBase.HTMLAttributes<HTMLElsaDesignerPanelElement>;
"elsa-designer-tree": LocalJSX.ElsaDesignerTree & JSXBase.HTMLAttributes<HTMLElsaDesignerTreeElement>;
"elsa-dictionary-property": LocalJSX.ElsaDictionaryProperty & JSXBase.HTMLAttributes<HTMLElsaDictionaryPropertyElement>;
"elsa-dropdown-button": LocalJSX.ElsaDropdownButton & JSXBase.HTMLAttributes<HTMLElsaDropdownButtonElement>;

View file

@ -1,4 +1,4 @@
import {Component, Event, EventEmitter, h, Listen, Method, Prop} from '@stencil/core';
import {Component, Event, EventEmitter, h, Listen, Method, Prop, State} from '@stencil/core';
import Tunnel, {DashboardState} from "../../../../data/dashboard";
import {ElsaStudio, WorkflowModel} from "../../../../models";
import {
@ -10,7 +10,8 @@ import {
createElsaClient,
createHttpClient,
ElsaClient,
propertyDisplayManager
propertyDisplayManager,
featuresDataManager
} from "../../../../services";
import {AxiosInstance} from "axios";
import {EventTypes} from "../../../../models";
@ -27,7 +28,9 @@ export class ElsaStudioRoot {
@Prop({attribute: 'monaco-lib-path', reflect: true}) monacoLibPath: string;
@Prop({attribute: 'culture', reflect: true}) culture: string;
@Prop({attribute: 'base-path', reflect: true}) basePath: string = '';
@Prop({attribute: 'features', reflect: true}) featuresString: string;
@Prop() features: any;
@Prop() config: string;
@State() featuresConfig: any;
@Event() initializing: EventEmitter<ElsaStudio>;
@Event() initialized: EventEmitter<ElsaStudio>;
@ -67,13 +70,26 @@ export class ElsaStudioRoot {
async componentWillLoad() {
const elsaClientFactory: () => Promise<ElsaClient> = () => createElsaClient(this.serverUrl);
const httpClientFactory: () => Promise<AxiosInstance> = () => createHttpClient(this.serverUrl);
await fetch(`${document.location.origin}/${this.config}`)
.then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.json()
})
.then(data => {
this.featuresConfig = data;
}).catch((error) => {
console.error(error)
});
const elsaClient = await elsaClientFactory();
const elsaStudio: ElsaStudio = this.elsaStudio = {
serverUrl: this.serverUrl,
basePath: this.basePath,
featuresString: this.featuresString,
features: this.featuresConfig,
serverFeatures: [],
eventBus,
pluginManager,
@ -91,6 +107,7 @@ export class ElsaStudioRoot {
await eventBus.emit(EventTypes.Root.Initializing);
pluginManager.initialize(elsaStudio);
propertyDisplayManager.initialize(elsaStudio);
featuresDataManager.initialize(elsaStudio);
elsaStudio.serverFeatures = await elsaClient.featuresApi.list();
}

View file

@ -7,13 +7,14 @@
## Properties
| Property | Attribute | Description | Type | Default |
| ---------------- | ----------------- | ----------- | -------- | ----------- |
| `basePath` | `base-path` | | `string` | `''` |
| `culture` | `culture` | | `string` | `undefined` |
| `featuresString` | `features` | | `string` | `undefined` |
| `monacoLibPath` | `monaco-lib-path` | | `string` | `undefined` |
| `serverUrl` | `server-url` | | `string` | `undefined` |
| Property | Attribute | Description | Type | Default |
| --------------- | ----------------- | ----------- | -------- | ----------- |
| `basePath` | `base-path` | | `string` | `''` |
| `config` | `config` | | `string` | `undefined` |
| `culture` | `culture` | | `string` | `undefined` |
| `features` | `features` | | `any` | `undefined` |
| `monacoLibPath` | `monaco-lib-path` | | `string` | `undefined` |
| `serverUrl` | `server-url` | | `string` | `undefined` |
## Events

View file

@ -36,6 +36,7 @@ graph TD;
elsa-workflow-definition-editor-screen --> elsa-tab-content
elsa-workflow-definition-editor-screen --> elsa-workflow-properties-panel
elsa-workflow-definition-editor-screen --> elsa-workflow-test-panel
elsa-workflow-definition-editor-screen --> elsa-designer-panel
elsa-workflow-definition-editor-screen --> context-consumer
elsa-workflow-settings-modal --> elsa-modal-dialog
elsa-workflow-settings-modal --> elsa-monaco

View file

@ -46,7 +46,7 @@ export class ElsaWorkflowDesigner {
@Prop() connectionContextMenu?: ActivityContextMenuState;
@Prop() activityContextTestMenu?: ActivityContextMenuState;
@Prop() mode: WorkflowDesignerMode = WorkflowDesignerMode.Edit;
@Prop() layoutDirection: LayoutDirection = LayoutDirection.Vertical;
@Prop() layoutDirection: LayoutDirection = LayoutDirection.TopBottom;
@Prop({attribute: 'enable-multiple-connections'}) enableMultipleConnectionsFromSingleSource: boolean;
@Event({
eventName: 'workflow-changed',
@ -568,9 +568,7 @@ export class ElsaWorkflowDesigner {
setEntities() {
this.graph = new dagreD3.graphlib.Graph().setGraph({});
const layoutDirection = this.layoutDirection;
this.graph.graph().rankdir = layoutDirection == LayoutDirection.Vertical ? 'TB' : 'LR';
this.graph.graph().rankdir = this.getLayoutDirection();
const rootActivities = this.getRootActivities();
@ -947,4 +945,18 @@ export class ElsaWorkflowDesigner {
</Host>
);
}
private getLayoutDirection = () => {
switch (this.layoutDirection) {
case LayoutDirection.BottomTop:
return 'BT';
case LayoutDirection.LeftRight:
return 'LR';
case LayoutDirection.RightLeft:
return 'RL';
case LayoutDirection.TopBottom:
default:
return 'TB';
}
}
}

View file

@ -17,6 +17,8 @@ export interface ActivityContextMenuState {
}
export enum LayoutDirection {
Horizontal,
Vertical
LeftRight ='leftright',
TopBottom = 'topbottom',
RightLeft = 'rightleft',
BottomTop = 'bottomtop'
}

View file

@ -15,7 +15,7 @@
| `activityContextTestMenu` | -- | | `ActivityContextMenuState` | `undefined` |
| `connectionContextMenu` | -- | | `ActivityContextMenuState` | `undefined` |
| `enableMultipleConnectionsFromSingleSource` | `enable-multiple-connections` | | `boolean` | `undefined` |
| `layoutDirection` | `layout-direction` | | `LayoutDirection.Horizontal \| LayoutDirection.Vertical` | `LayoutDirection.Vertical` |
| `layoutDirection` | `layout-direction` | | `LayoutDirection.BottomTop \| LayoutDirection.LeftRight \| LayoutDirection.RightLeft \| LayoutDirection.TopBottom` | `LayoutDirection.TopBottom` |
| `mode` | `mode` | | `WorkflowDesignerMode.Blueprint \| WorkflowDesignerMode.Edit \| WorkflowDesignerMode.Instance \| WorkflowDesignerMode.Test` | `WorkflowDesignerMode.Edit` |
| `model` | -- | | `WorkflowModel` | `{ activities: [], connections: [], persistenceBehavior: WorkflowPersistenceBehavior.WorkflowBurst }` |
| `selectedActivityIds` | -- | | `string[]` | `[]` |

View file

@ -1,33 +1,38 @@
import {Component, Event, EventEmitter, h, Host, Listen, Method, Prop, State, Watch} from '@stencil/core';
import {RouterHistory, injectHistory} from '@stencil/router';
import {injectHistory, RouterHistory} from '@stencil/router';
import {
ActivityDefinition,
ActivityDescriptor,
ActivityModel,
ConfigureComponentCustomButtonContext,
ComponentCustomButtonClickContext,
ConfigureComponentCustomButtonContext,
ConnectionDefinition,
ConnectionModel,
EventTypes,
VersionOptions,
WorkflowDefinition,
WorkflowInstance,
WorkflowModel,
WorkflowPersistenceBehavior,
WorkflowTestActivityMessage,
WorkflowInstance, WorkflowTestActivityMessageStatus,
WorkflowTestActivityMessageStatus,
} from "../../../../models";
import {
ActivityStats,
createElsaClient,
eventBus,
SaveWorkflowDefinitionRequest, toastNotificationService,
WorkflowTestRestartFromActivityRequest
featuresDataManager,
SaveWorkflowDefinitionRequest
} from "../../../../services";
import state from '../../../../utils/store';
import WorkflowEditorTunnel, {WorkflowEditorState} from '../../../../data/workflow-editor';
import DashboardTunnel from "../../../../data/dashboard";
import {downloadFromBlob} from "../../../../utils/download";
import {ActivityContextMenuState, WorkflowDesignerMode} from "../../../designers/tree/elsa-designer-tree/models";
import {
ActivityContextMenuState,
LayoutDirection,
WorkflowDesignerMode
} from "../../../designers/tree/elsa-designer-tree/models";
import {i18n} from "i18next";
import {loadTranslations} from "../../../i18n/i18n-loader";
import {resources} from "./localizations";
@ -44,6 +49,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() features: string;
@Prop() culture: string;
@Prop() basePath: string;
@Prop() serverFeatures: Array<string> = [];
@ -64,6 +70,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
@State() workflowInstance?: WorkflowInstance;
@State() workflowInstanceId?: string;
@State() activityStats?: ActivityStats;
@State() layoutDirection: LayoutDirection = LayoutDirection.TopBottom;//???
@State() activityContextMenuState: ActivityContextMenuState = {
shown: false,
@ -197,6 +204,11 @@ export class ElsaWorkflowDefinitionEditorScreen {
async componentWillLoad() {
this.i18next = await loadTranslations(this.culture, resources);
this.workflowDesignerMode = WorkflowDesignerMode.Edit;
const layoutFeature = featuresDataManager.getFeatureConfig(featuresDataManager.supportedFeatures.workflowLayout);
if (layoutFeature && layoutFeature.enabled) {
this.layoutDirection = layoutFeature.value as LayoutDirection;
}
await this.serverUrlChangedHandler(this.serverUrl);
await this.workflowDefinitionIdChangedHandler(this.workflowDefinitionId);
await this.monacoLibPathChangedHandler(this.monacoLibPath);
@ -647,6 +659,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
<div class="elsa-flex-1 elsa-flex elsa-relative">
<elsa-designer-tree model={this.workflowModel}
mode={this.workflowDesignerMode}
layoutDirection={this.layoutDirection}
activityContextMenuButton={this.workflowDesignerMode == WorkflowDesignerMode.Edit
? activityContextMenuButton
: this.renderActivityStatsButton}
@ -1061,6 +1074,7 @@ export class ElsaWorkflowDefinitionEditorScreen {
/>
</elsa-tab-content>
{this.renderTestPanel()}
{this.renderDesignerPanel()}
</elsa-flyout-panel>
);
}
@ -1081,6 +1095,44 @@ export class ElsaWorkflowDefinitionEditorScreen {
</elsa-tab-content>
];
}
private renderDesignerPanel = () => {
const isFeaturePanelVisible = featuresDataManager.getUIFeatureList().length != 0;
if (isFeaturePanelVisible) {
return [
<elsa-tab-header tab="designer" slot="header">Designer</elsa-tab-header>,
<elsa-tab-content tab="designer" slot="content">
<elsa-designer-panel
onFeatureChanged={this.handleFeatureChange}
onFeatureStatusChanged={this.handleFeatureStatusChange}
/>
</elsa-tab-content>
];
}
}
handleFeatureChange = (e: CustomEvent<string>) => {
const feature = e.detail;
if (feature === featuresDataManager.supportedFeatures.workflowLayout) {
const layoutFeature = featuresDataManager.getFeatureConfig(feature);
this.layoutDirection = layoutFeature.value as LayoutDirection;
}
}
handleFeatureStatusChange = (e: CustomEvent<string>) => {
const feature = e.detail;
if (feature === featuresDataManager.supportedFeatures.workflowLayout) {
const layoutFeature = featuresDataManager.getFeatureConfig(feature);
if (layoutFeature.enabled) {
this.layoutDirection = layoutFeature.value as LayoutDirection;
} else {
this.layoutDirection = LayoutDirection.TopBottom;
}
}
}
}
injectHistory(ElsaWorkflowDefinitionEditorScreen);

View file

@ -10,6 +10,7 @@
| Property | Attribute | Description | Type | Default |
| ---------------------- | ------------------------ | ----------- | --------------- | ----------- |
| `culture` | `culture` | | `string` | `undefined` |
| `features` | `features` | | `string` | `undefined` |
| `history` | -- | | `RouterHistory` | `undefined` |
| `monacoLibPath` | `monaco-lib-path` | | `string` | `undefined` |
| `serverUrl` | `server-url` | | `string` | `undefined` |
@ -88,6 +89,7 @@ Type: `Promise<void>`
- [elsa-tab-content](../../../shared/elsa-tab-content)
- [elsa-workflow-properties-panel](../elsa-workflow-properties-panel)
- [elsa-workflow-test-panel](../elsa-workflow-test-panel)
- [elsa-designer-panel](../../../shared/elsa-designer-panel)
- context-consumer
### Graph
@ -107,6 +109,7 @@ graph TD;
elsa-workflow-definition-editor-screen --> elsa-tab-content
elsa-workflow-definition-editor-screen --> elsa-workflow-properties-panel
elsa-workflow-definition-editor-screen --> elsa-workflow-test-panel
elsa-workflow-definition-editor-screen --> elsa-designer-panel
elsa-workflow-definition-editor-screen --> context-consumer
elsa-workflow-settings-modal --> elsa-modal-dialog
elsa-workflow-settings-modal --> elsa-monaco

View file

@ -0,0 +1,100 @@
import {Component, Host, h, Event, EventEmitter, Prop, State} from '@stencil/core';
import {FeatureConfig, featuresDataManager} from "../../../services";
import {LayoutDirection} from "../../designers/tree/elsa-designer-tree/models";
import {i18n} from "i18next";
import {resources} from "./localizations";
import {loadTranslations} from "../../i18n/i18n-loader";
@Component({
tag: 'elsa-designer-panel',
shadow: false,
})
export class ElsaDesignerPanel {
@Prop() culture: string;
@State() lastChangeTime: Date;
@Event() featureChanged: EventEmitter<string>;
@Event() featureStatusChanged: EventEmitter<string>;
i18next: i18n;
async componentWillLoad() {
this.i18next = await loadTranslations(this.culture, resources);
}
t = (key: string, options?: any) => this.i18next.t(key, options);
render() {
const features = featuresDataManager.getUIFeatureList();
const {t} = this;
return (
<Host>
<div class="elsa-mt-4">
{features.map(name => {
const feature = featuresDataManager.getFeatureConfig(name);
return (
<div>
<div class="elsa-relative elsa-flex elsa-items-start elsa-ml-1">
<div class="elsa-flex elsa-items-center elsa-h-5">
<input
id={name}
name={name}
type="checkbox"
value={`${feature.enabled}`}
checked={feature.enabled}
onChange={e => this.onToggleChange(e, name)}
class="focus:elsa-ring-blue-500 elsa-h-4 elsa-w-4 elsa-text-blue-600 elsa-border-gray-300 rounded"
/>
</div>
<div class="elsa-ml-3 elsa-text-sm">
<label htmlFor={name} class="elsa-font-medium elsa-text-gray-700">{t(`${name}Name`)}</label>
<p class="elsa-text-gray-500">{t(`${name}Description`)}</p>
</div>
</div>
<div class="elsa-ml-1 elsa-my-4">
{this.renderFeatureData(name, feature)}
</div>
</div>
)
})}
</div>
</Host>
);
}
renderFeatureData = (name: string, feature: FeatureConfig) => {
if (!feature.enabled) {
return null;
}
const {t} = this;
switch (name) {
case featuresDataManager.supportedFeatures.workflowLayout:
return (
<select id={name} name={name} onChange={e => this.onPropertyChange(e, name)} class="block focus:elsa-ring-blue-500 focus:elsa-border-blue-500 elsa-w-full elsa-shadow-sm sm:elsa-text-sm elsa-border-gray-300 elsa-rounded-md">
{Object.keys(LayoutDirection).map(key => {
return <option value={LayoutDirection[key]} selected={LayoutDirection[key] === feature.value}>{t(key)}</option>;
})}
</select>
)
default:
return null;
}
}
onToggleChange = (e: Event, name: string) => {
const element = e.target as HTMLInputElement;
featuresDataManager.setEnableStatus(name, element.checked);
this.lastChangeTime = new Date();
this.featureStatusChanged.emit(name);
}
onPropertyChange = (e: Event, name: string) => {
const element = e.target as HTMLInputElement;
featuresDataManager.setFeatureConfig(name, element.value.trim());
this.featureChanged.emit(name);
}
}

View file

@ -0,0 +1,12 @@
export const resources = {
'en': {
default: {
'workflowLayoutName': 'Workflow Layout',
'workflowLayoutDescription': 'Determines the directions cards are displayed in. Changed for every workflow.',
'TopBottom': 'Top to Bottom',
'LeftRight': 'Left to Right',
'BottomTop': 'Bottom to Top',
'RightLeft': 'Right to Left',
}
}
};

View file

@ -0,0 +1,38 @@
# elsa-designer-panel
<!-- Auto Generated Below -->
## Properties
| Property | Attribute | Description | Type | Default |
| --------- | --------- | ----------- | -------- | ----------- |
| `culture` | `culture` | | `string` | `undefined` |
## Events
| Event | Description | Type |
| ---------------------- | ----------- | --------------------- |
| `featureChanged` | | `CustomEvent<string>` |
| `featureStatusChanged` | | `CustomEvent<string>` |
## Dependencies
### Used by
- [elsa-workflow-definition-editor-screen](../../screens/workflow-definition-editor/elsa-workflow-definition-editor-screen)
### Graph
```mermaid
graph TD;
elsa-workflow-definition-editor-screen --> elsa-designer-panel
style elsa-designer-panel fill:#f9f,stroke:#333,stroke-width:4px
```
----------------------------------------------
*Built with [StencilJS](https://stenciljs.com/)*

View file

@ -14,7 +14,7 @@
</head>
<body>
<elsa-studio-root server-url="https://localhost:11000" monaco-lib-path="build/assets/js/monaco-editor/min" culture="en-US">
<elsa-studio-root server-url="https://localhost:11000" monaco-lib-path="build/assets/js/monaco-editor/min" culture="en-US" config="build/assets/designer.config.json">
<!-- The root dashboard component -->
<elsa-studio-dashboard></elsa-studio-dashboard>

View file

@ -8,7 +8,7 @@ import {ActivityModel} from "./view";
export interface ElsaStudio {
serverUrl: string;
basePath: string;
featuresString: string;
features: any;
serverFeatures: Array<string>;
pluginManager: PluginManager;
propertyDisplayManager: PropertyDisplayManager;

View file

@ -0,0 +1,73 @@
import {ElsaStudio} from "../models/";
export interface FeatureConfig {
enabled: boolean;
ui: boolean;
defaultValue: string;
value?: string;
}
type FeatureConfigMap = {
[key:string]: FeatureConfig;
}
export class FeaturesDataManager {
elsaStudio: ElsaStudio;
initialized: boolean;
features: FeatureConfigMap;
supportedFeatures = {
workflowLayout: 'workflowLayout'
}
initialize(elsaStudio: ElsaStudio) {
if (this.initialized)
return;
this.elsaStudio = elsaStudio;
this.initialized = true;
this.features = elsaStudio.features || {};
}
getFeatureList = () => {
return Object.keys(this.features);
}
getUIFeatureList = () => {
return Object.keys(this.features).filter(feature => this.features[feature].ui);
}
getFeatureConfig = (name: string) => {
const value = localStorage.getItem(`elsa.properties.${name}`);
const enabled = localStorage.getItem(`elsa.properties.${name}.enabled`);
const feature = this.features[name];
if (feature) {
return {
...feature,
value: value === null ? feature.defaultValue : value,
'enabled': enabled === null ? feature.enabled : enabled === 'true'
}
}
}
setFeatureConfig = (name: string, value: string) => {
const feature = this.features[name];
if (feature) {
localStorage.setItem(`elsa.properties.${name}`, value);
}
}
setEnableStatus = (name: string, value: boolean) => {
const feature = this.features[name];
if (feature) {
localStorage.setItem(`elsa.properties.${name}.enabled`, `${value}`);
console.log(`elsa.properties.${name}-enabled`, value);
}
}
}
export const featuresDataManager = new FeaturesDataManager();

View file

@ -4,6 +4,7 @@ export * from './toast-notification-service';
export * from './elsa-plugin';
export * from './elsa-client';
export * from './event-bus';
export * from './features-data-manager';
export * from './plugin-manager';
export * from './property-display-driver';
export * from './property-display-manager';
export * from './property-display-manager';