Skip to content

Commit 991294f

Browse files
authored
improved demo. (#2)
1 parent 3b4cd0c commit 991294f

27 files changed

+537
-115
lines changed

demos/webpack-app/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"build": "yarn clean && webpack --mode production",
1111
"eslint": "eslint ./src --ext .ts",
1212
"test:single": "echo \"No tests yet\"",
13-
"prettier": "prettier --check ./src",
14-
"prettier:fix": "prettier --write ./src"
13+
"prettier": "prettier --check ./src ./public/**/*.{html,css}",
14+
"prettier:fix": "prettier --write ./src ./public/**/*.{html,css}"
1515
},
1616
"dependencies": {
1717
"xstate": "^4.37.2",
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
html,
2+
body {
3+
margin: 0;
4+
padding: 0;
5+
width: 100vw;
6+
height: 100vh;
7+
overflow: hidden;
8+
font: 14px/1.3em Arial, Verdana, sans-serif;
9+
}
10+
body {
11+
display: flex;
12+
flex-direction: row;
13+
}
14+
#designer {
15+
flex: 3;
16+
}
17+
@media (max-width: 768px) {
18+
body {
19+
flex-direction: column;
20+
}
21+
#designer {
22+
flex: 2;
23+
}
24+
}
25+
#playground {
26+
flex: 1;
27+
padding: 10px;
28+
box-sizing: border-box;
29+
background-color: #ccc;
30+
overflow: auto;
31+
}
32+
#playground .title h2 {
33+
display: inline-block;
34+
margin: 0;
35+
padding: 10px 0;
36+
}
37+
#playground .title a {
38+
color: #333;
39+
text-decoration: underline;
40+
margin: 0 5px;
41+
}
42+
#playground .title a:hover {
43+
text-decoration: none;
44+
}
45+
#playground h4 {
46+
margin: 0;
47+
padding: 10px 0;
48+
}
49+
#playground .variables {
50+
padding: 0 5px 5px;
51+
background: #bbb;
52+
border-radius: 5px;
53+
}
54+
#playground .variable-row label {
55+
display: block;
56+
padding: 5px 0;
57+
}
58+
#playground .variable-row input[type='text'] {
59+
padding: 5px;
60+
width: 100%;
61+
box-sizing: border-box;
62+
border: 1px solid #999;
63+
outline: 0;
64+
border-radius: 5px;
65+
}
66+
#playground .logs {
67+
width: 100%;
68+
margin: 0;
69+
padding: 5px;
70+
height: 400px;
71+
overflow-y: auto;
72+
overflow-x: hidden;
73+
box-sizing: border-box;
74+
border: 1px solid #999;
75+
border-radius: 5px;
76+
outline: 0;
77+
background: #fff;
78+
}
79+
#playground .log {
80+
margin: 0;
81+
padding: 3px;
82+
border-top: 1px solid #ccc;
83+
list-style: none;
84+
}
85+
#playground .log:first-child {
86+
border-top: 0;
87+
}
88+
#playground .log.log-trace {
89+
font-size: 8pt;
90+
color: #999;
91+
}
Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,30 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="UTF-8">
5-
<title>🛠 Playground - Sequential Workflow Editor</title>
6-
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
7-
<link rel="icon" href="./assets/favicon.ico">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>🛠 Playground - Sequential Workflow Editor</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
7+
<link rel="icon" href="./assets/favicon.ico" />
8+
<link rel="stylesheet" href="./assets/style.css" />
9+
<script src="./builds/playground.js" defer></script>
10+
</head>
11+
<body>
12+
<div id="designer"></div>
813

9-
<style>
10-
html, body {margin: 0; padding: 0; width: 100vw; height: 100vh; overflow: hidden; font: 14px/1.3em Arial, Verdana, sans-serif;}
11-
body {display: flex; flex-direction: row;}
12-
#designer {flex: 3;}
13-
#playground {flex: 1; padding: 10px; box-sizing: border-box; background-color: #CCC;}
14-
#playground h2 {margin: 0; padding: 10px 0;}
15-
#playground h4 {margin: 0; padding: 10px 0;}
16-
#playground .variables {padding: 0 5px 5px; background: #BBB; border-radius: 5px;}
17-
#playground .variable-row label {display: block; padding: 5px 0;}
18-
#playground .variable-row input[type=text] {padding: 5px; width: 100%; box-sizing: border-box; border: 1px solid #999; outline: 0; border-radius: 5px;}
19-
#playground .logs {width: 100%; padding: 5px; height: 400px; box-sizing: border-box; border: 1px solid #999; border-radius: 5px; outline: 0;}
20-
</style>
21-
</head>
22-
<body>
23-
<div id="designer"></div>
14+
<div id="playground">
15+
<div class="title">
16+
<h2>🛠 Playground</h2>
17+
<a href="https://github.com/nocode-js/sequential-workflow-editor" target="_blank">GitHub</a>
18+
</div>
2419

25-
<div id="playground">
26-
<h2>🛠 Playground</h2>
20+
<h4>Inputs</h4>
21+
<div id="inputs" class="variables"></div>
2722

28-
<h4>Inputs</h4>
29-
<div id="inputs" class="variables"></div>
23+
<h4>Logs</h4>
24+
<ul id="logs" class="logs"></ul>
3025

31-
<h4>Logs</h4>
32-
<textarea id="logs" class="logs"></textarea>
33-
34-
<h4>Outputs</h4>
35-
<div id="outputs" class="variables"></div>
36-
</div>
37-
38-
<script src="./builds/playground.js"></script>
39-
</body>
26+
<h4>Outputs</h4>
27+
<div id="outputs" class="variables"></div>
28+
</div>
29+
</body>
4030
</html>

demos/webpack-app/src/playground/app.ts

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { Designer } from 'sequential-workflow-designer';
1+
import { Definition, DefinitionWalker, Designer } from 'sequential-workflow-designer';
22
import { editorProvider } from './editor-provider';
3-
import { tryReadDefinition, saveDefinition } from './storage';
3+
import { AppState, AppStorage } from './storage';
44
import { Playground } from './playground';
55
import { executeMachine } from './machine/machine-executor';
66
import { MyDefinition, definitionModel } from './model/definition-model';
7+
import { defaultAppState } from './default-state';
78

89
import 'sequential-workflow-designer/css/designer.css';
910
import 'sequential-workflow-designer/css/designer-light.css';
@@ -13,9 +14,10 @@ export class App {
1314
public static create(): App {
1415
const placeholder = document.getElementById('designer') as HTMLElement;
1516

16-
const startDefinition: MyDefinition = tryReadDefinition() ?? editorProvider.activateDefinition();
17+
const startState: AppState = AppStorage.tryGet() ?? defaultAppState;
1718

18-
const designer: Designer<MyDefinition> = Designer.create(placeholder, startDefinition, {
19+
const definitionWalker = new DefinitionWalker();
20+
const designer: Designer<MyDefinition> = Designer.create(placeholder, startState.definition, {
1921
controlBar: true,
2022
editors: {
2123
globalEditorProvider: editorProvider.createRootEditorProvider(),
@@ -25,44 +27,60 @@ export class App {
2527
step: editorProvider.createStepValidator(),
2628
root: editorProvider.createRootValidator()
2729
},
28-
steps: {},
30+
steps: {
31+
iconUrlProvider: (_, type: string) => `./assets/icon-${type}.svg`
32+
},
2933
toolbox: {
3034
groups: [
3135
{
3236
name: 'Steps',
3337
steps: Object.keys(definitionModel.steps).map(stepType => editorProvider.activateStep(stepType))
3438
}
3539
]
36-
}
40+
},
41+
undoStackSize: 10,
42+
definitionWalker
3743
});
3844

39-
const playground = Playground.create();
40-
const app = new App(designer, playground);
45+
const playground = Playground.create(startState.inputData);
46+
const app = new App(definitionWalker, designer, playground);
4147
designer.onReady.subscribe(app.execute);
4248
designer.onDefinitionChanged.subscribe(app.execute);
4349
playground.onInputChanged.subscribe(app.execute);
4450
return app;
4551
}
4652

47-
private constructor(private readonly designer: Designer<MyDefinition>, private readonly playground: Playground) {}
53+
private constructor(
54+
private readonly definitionWalker: DefinitionWalker,
55+
private readonly designer: Designer<MyDefinition>,
56+
private readonly playground: Playground
57+
) {}
4858

4959
private readonly execute = async () => {
5060
this.playground.clearLogs();
5161

5262
const definition = this.designer.getDefinition();
5363
this.playground.updateVariables(definition);
54-
saveDefinition(definition);
64+
AppStorage.set(definition, this.playground.readInputData());
5565

5666
try {
57-
const inputVariableValues = this.playground.readInputVariables();
67+
const inputVariablesState = this.playground.readInputVariableState();
5868

5969
if (!this.designer.isValid()) {
6070
throw new Error('Definition is not valid');
6171
}
6272

63-
const snapshot = await executeMachine(definition, inputVariableValues, statePath => {
64-
this.playground.log(`<state: ${statePath}>`);
65-
});
73+
const snapshot = await executeMachine(
74+
definition,
75+
inputVariablesState,
76+
statePath => {
77+
const name = readStateName(statePath, definition, this.definitionWalker);
78+
this.playground.log(`state: ${name}`, 'trace');
79+
},
80+
log => {
81+
this.playground.log(log);
82+
}
83+
);
6684

6785
if (snapshot.unhandledError) {
6886
const error = snapshot.unhandledError as Error;
@@ -83,4 +101,17 @@ export class App {
83101
};
84102
}
85103

104+
function readStateName(statePath: string[], definition: Definition, walker: DefinitionWalker): string {
105+
const path = [...statePath].reverse();
106+
const deepestStepId = path.find(x => x.startsWith('STEP_'))?.substring(5);
107+
if (deepestStepId) {
108+
const step = walker.getById(definition, deepestStepId);
109+
if (path[0].startsWith('STEP_')) {
110+
return step.name;
111+
}
112+
return `${step.name} (${path[0]})`;
113+
}
114+
return statePath.join('/');
115+
}
116+
86117
document.addEventListener('DOMContentLoaded', App.create, false);
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import { SequentialStep } from 'sequential-workflow-model';
2+
import { MyDefinition } from './model/definition-model';
3+
import { RawInputData } from './playground';
4+
import { AppState } from './storage';
5+
6+
const definition: MyDefinition = {
7+
properties: {
8+
inputs: { variables: [{ name: 'loops', type: 'number' }] },
9+
outputs: { variables: [{ name: 'message', type: 'string' }] }
10+
},
11+
sequence: [
12+
{
13+
id: 'a282bc1908816678905a3c94049478aa',
14+
name: 'index < loops',
15+
type: 'loop',
16+
componentType: 'container',
17+
properties: {
18+
from: { modelId: 'number', value: 0 },
19+
operator: '<',
20+
to: { modelId: 'nullableVariable', value: { name: 'loops' } },
21+
increment: { modelId: 'number', value: 1 },
22+
indexVariable: { name: 'index', type: 'number' },
23+
variables: { variables: [{ name: 'diff', type: 'number' }] }
24+
},
25+
sequence: [
26+
{
27+
id: '32529a3fbef39d5e480df8454164edae',
28+
name: 'diff = index % 2',
29+
type: 'calculate',
30+
componentType: 'task',
31+
properties: {
32+
a: { modelId: 'nullableVariable', value: { name: 'index' } },
33+
operator: '%',
34+
b: { modelId: 'number', value: 2 },
35+
result: { name: 'diff' }
36+
}
37+
},
38+
{
39+
id: 'f2f35f162f009e7683cf31c24a1e9589',
40+
name: 'If diff == 0',
41+
type: 'if',
42+
componentType: 'switch',
43+
properties: {
44+
a: { modelId: 'nullableVariable', value: { name: 'diff' } },
45+
operator: '=',
46+
b: { modelId: 'number', value: 0 }
47+
},
48+
branches: {
49+
true: [
50+
{
51+
id: '2cfa6c319e150facd7e43841beca33cb',
52+
name: 'print true 🌺',
53+
type: 'log',
54+
componentType: 'task',
55+
properties: {
56+
message: { modelId: 'string', value: '🌺 TRUE 🌺' },
57+
variables: { variables: [{ name: 'index', type: 'number' }] }
58+
}
59+
}
60+
],
61+
false: [
62+
{
63+
id: '9646bc44d1d07898bcdc240c5b3ce198',
64+
name: 'print false 🌼',
65+
type: 'log',
66+
componentType: 'task',
67+
properties: {
68+
message: { modelId: 'string', value: '🌼 FALSE 🌼' },
69+
variables: { variables: [{ name: 'index', type: 'number' }] }
70+
}
71+
}
72+
]
73+
}
74+
}
75+
]
76+
} as SequentialStep,
77+
{
78+
id: '0a0278f55466c980fcd35d778dc679f4',
79+
name: 'set output',
80+
type: 'setStringValue',
81+
componentType: 'task',
82+
properties: { variable: { name: 'message' }, value: { modelId: 'string', value: 'Done!' } }
83+
}
84+
]
85+
};
86+
87+
const inputData: RawInputData = {
88+
loops: '2'
89+
};
90+
91+
export const defaultAppState: AppState = {
92+
definition,
93+
inputData
94+
};

0 commit comments

Comments
 (0)