Skip to content

Commit d1e460c

Browse files
committed
draggable values with support for expressions to trigger flows
1 parent 5fc6ecf commit d1e460c

File tree

13 files changed

+553
-589
lines changed

13 files changed

+553
-589
lines changed
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
{
2+
"schemaType": "flow",
3+
"schemaVersion": "0.0.1",
4+
"id": "1234",
5+
"flows": {
6+
"flow": {
7+
"flowType": "flow",
8+
"nodes": [
9+
{
10+
"id": "7e166d63-47d1-434c-a2aa-a7c75331ec7e",
11+
"x": 9614.665662495308,
12+
"y": 2041.8724614975927,
13+
"width": 200,
14+
"height": 100,
15+
"nodeType": "Shape",
16+
"nodeInfo": {
17+
"type": "expression",
18+
"formValues": {
19+
"expression": "5",
20+
"inputType": "number"
21+
},
22+
"showFormOnlyInPopup": true,
23+
"isSettingsPopup": true
24+
}
25+
},
26+
{
27+
"id": "978bb5b9-95bd-48db-b5d0-32ee0a19f359",
28+
"x": 10155.030522436788,
29+
"y": 2025.1435225993878,
30+
"width": 200,
31+
"height": 100,
32+
"nodeType": "Shape",
33+
"nodeInfo": {
34+
"type": "expression",
35+
"formValues": {
36+
"expression": "input * 2",
37+
"inputType": "number"
38+
},
39+
"showFormOnlyInPopup": true,
40+
"isSettingsPopup": true
41+
}
42+
},
43+
{
44+
"id": "2c2ab16e-ddc9-46ee-be49-5b510c91e354",
45+
"x": 10590.913232625046,
46+
"y": 2075.6191535879448,
47+
"width": 119.99920876217523,
48+
"height": 56.00001459796518,
49+
"nodeType": "Shape",
50+
"nodeInfo": {
51+
"type": "show-input",
52+
"formValues": {
53+
"name": "",
54+
"data-type": "default"
55+
},
56+
"initializeOnStartFlow": true,
57+
"isSettingsPopup": true
58+
}
59+
},
60+
{
61+
"id": "f1ad87fc-c673-4dd2-9f9b-a078309f20e2",
62+
"x": 9782.221443635435,
63+
"y": 1922.6687616066683,
64+
"width": 66.14914512743235,
65+
"height": 27.486956497437404,
66+
"nodeType": "Shape",
67+
"nodeInfo": {
68+
"type": "annotation",
69+
"formValues": {
70+
"annotation": "10",
71+
"fontSize": "16",
72+
"fontWeight": "false"
73+
},
74+
"isSettingsPopup": true,
75+
"nodeCannotBeReplaced": true,
76+
"isAnnotation": true
77+
}
78+
},
79+
{
80+
"id": "5c55d11b-3983-4b13-ac70-166d1899c5cd",
81+
"x": 9777.394152186711,
82+
"y": 2366.7596505691417,
83+
"width": 200,
84+
"height": 100,
85+
"nodeType": "Shape",
86+
"nodeInfo": {
87+
"type": "expression",
88+
"formValues": {
89+
"expression": "[1,2,3]",
90+
"inputType": "number"
91+
},
92+
"showFormOnlyInPopup": true,
93+
"isSettingsPopup": true
94+
}
95+
},
96+
{
97+
"id": "b0174761-22cc-4db6-8e83-27a09ad462c5",
98+
"x": 10183.360322930836,
99+
"y": 2388.8825245919566,
100+
"width": 239.9999549266688,
101+
"height": 55.999943143829334,
102+
"nodeType": "Shape",
103+
"nodeInfo": {
104+
"type": "sum"
105+
}
106+
},
107+
{
108+
"id": "14ec0c88-c5eb-4508-b153-1a5e9d36eb37",
109+
"x": 9956.864328701347,
110+
"y": 2275.756821883576,
111+
"width": 240,
112+
"height": 100,
113+
"nodeType": "Shape",
114+
"nodeInfo": {
115+
"type": "annotation",
116+
"formValues": {
117+
"annotation": "[4,5,6]",
118+
"fontSize": "16",
119+
"fontWeight": "false"
120+
},
121+
"isSettingsPopup": true,
122+
"nodeCannotBeReplaced": true,
123+
"isAnnotation": true
124+
}
125+
},
126+
{
127+
"id": "61581958-5591-4b51-984d-cd0f2ab47372",
128+
"x": 10151.010505581524,
129+
"y": 1792.4660031566073,
130+
"width": 174.4218324956868,
131+
"height": 84.00002331858714,
132+
"nodeType": "Shape",
133+
"nodeInfo": {
134+
"type": "scope-variable",
135+
"formValues": {
136+
"variableName": "test",
137+
"initialValue": "303",
138+
"fieldType": "value",
139+
"fieldValueType": "number",
140+
"enumValues": [],
141+
"initialEnumValue": ""
142+
},
143+
"isVariable": true,
144+
"nodeCannotBeReplaced": true
145+
}
146+
},
147+
{
148+
"id": "92d2514d-6342-43a2-b864-8adc9ec88c8b",
149+
"x": 9821.897279533316,
150+
"y": 1819.556623295406,
151+
"width": 240,
152+
"height": 100,
153+
"nodeType": "Shape",
154+
"nodeInfo": {
155+
"type": "annotation",
156+
"formValues": {
157+
"annotation": "=test + 5",
158+
"fontSize": "16",
159+
"fontWeight": "false"
160+
},
161+
"isSettingsPopup": true,
162+
"nodeCannotBeReplaced": true,
163+
"isAnnotation": true
164+
}
165+
},
166+
{
167+
"id": "ce778a45-3fad-4ef5-8864-c4e08ba8a987",
168+
"x": 9814.665662495308,
169+
"y": 2091.8724614975927,
170+
"endX": 10155.030522436788,
171+
"endY": 2075.143522599388,
172+
"startNodeId": "7e166d63-47d1-434c-a2aa-a7c75331ec7e",
173+
"endNodeId": "978bb5b9-95bd-48db-b5d0-32ee0a19f359",
174+
"startThumbName": "output",
175+
"endThumbName": "input",
176+
"lineType": "BezierCubic",
177+
"nodeType": "Connection",
178+
"layer": 1,
179+
"nodeInfo": {}
180+
},
181+
{
182+
"id": "bdc6c812-445a-4a0b-a39c-fc5cae21e3d7",
183+
"x": 10355.030522436788,
184+
"y": 2075.143522599388,
185+
"endX": 10590.913232625046,
186+
"endY": 2105.6191535879448,
187+
"startNodeId": "978bb5b9-95bd-48db-b5d0-32ee0a19f359",
188+
"endNodeId": "2c2ab16e-ddc9-46ee-be49-5b510c91e354",
189+
"startThumbName": "output",
190+
"endThumbName": "input",
191+
"lineType": "BezierCubic",
192+
"nodeType": "Connection",
193+
"layer": 1,
194+
"nodeInfo": {}
195+
},
196+
{
197+
"id": "8d4611a0-fd49-476d-be0d-c048c3e733e0",
198+
"x": 9977.394152186711,
199+
"y": 2416.7596505691417,
200+
"endX": 10183.360322930836,
201+
"endY": 2416.882496163871,
202+
"startNodeId": "5c55d11b-3983-4b13-ac70-166d1899c5cd",
203+
"endNodeId": "b0174761-22cc-4db6-8e83-27a09ad462c5",
204+
"startThumbName": "output",
205+
"endThumbName": "input",
206+
"lineType": "BezierCubic",
207+
"nodeType": "Connection",
208+
"layer": 1,
209+
"nodeInfo": {}
210+
},
211+
{
212+
"id": "acfcfe5c-aec6-4b3d-adc8-483ed18a2258",
213+
"x": 9904.898398872987,
214+
"y": 1964.8880805353383,
215+
"width": 110.6247244815404,
216+
"height": 37.74433114564067,
217+
"nodeType": "Shape",
218+
"nodeInfo": {
219+
"type": "annotation",
220+
"formValues": {
221+
"annotation": "21.123",
222+
"fontSize": "16",
223+
"fontWeight": "false"
224+
},
225+
"isSettingsPopup": true,
226+
"nodeCannotBeReplaced": true,
227+
"isAnnotation": true,
228+
"taskType": "annotation"
229+
}
230+
},
231+
{
232+
"id": "92a6abc0-21c5-4dba-869f-5658bc4bd22b",
233+
"x": 9926.399921662924,
234+
"y": 1905.2449817802428,
235+
"width": 57.8133295343614,
236+
"height": 31.36911666207766,
237+
"nodeType": "Shape",
238+
"nodeInfo": {
239+
"type": "annotation",
240+
"formValues": {
241+
"annotation": "9998",
242+
"fontSize": "16",
243+
"fontWeight": "false"
244+
},
245+
"isSettingsPopup": true,
246+
"nodeCannotBeReplaced": true,
247+
"isAnnotation": true,
248+
"taskType": "annotation"
249+
}
250+
}
251+
]
252+
}
253+
},
254+
"compositions": {}
255+
}

libs/app-canvas/src/app/flow-app.element.tsx

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ import {
3636
IFlowCanvasBase,
3737
} from '@devhelpr/visual-programming-system';
3838

39-
import { registerCustomFunction } from '@devhelpr/expression-compiler';
39+
import {
40+
compileExpressionAsInfo,
41+
registerCustomFunction,
42+
runExpression,
43+
} from '@devhelpr/expression-compiler';
4044

4145
import {
4246
setSpeedMeter,
@@ -107,6 +111,7 @@ import {
107111
connectionExecuteHistory,
108112
getNodeFactoryNames,
109113
getNodeTaskFactory,
114+
getVariablePayloadInputUtils,
110115
increaseRunIndex,
111116
initFlowVariableScope,
112117
registerComposition,
@@ -245,6 +250,42 @@ export class FlowAppElement extends AppElement<NodeInfo> {
245250
this.canvasActionPayload = payload;
246251
});
247252

253+
this.canvasApp.setOnDroppedOnNode((node, droppedNode) => {
254+
const connection = droppedNode as IConnectionNodeComponent<NodeInfo>;
255+
if (connection.startNodeThumb) {
256+
const text = node.nodeInfo?.formValues?.annotation;
257+
if (
258+
text &&
259+
node &&
260+
node.nodeInfo?.type === 'annotation' &&
261+
connection &&
262+
connection.nodeType === NodeType.Connection &&
263+
connection.endNode &&
264+
connection.startNodeThumb &&
265+
this.canvasApp
266+
) {
267+
// Copy & paste clipboard to connection and trigger connection
268+
269+
const canvasApp = this.canvasApp;
270+
const endNode = connection.endNode;
271+
const startNodeThumb = connection.startNodeThumb;
272+
273+
runNodeFromThumb(
274+
startNodeThumb,
275+
canvasApp,
276+
() => {
277+
//
278+
},
279+
this.transformValueForNodeTrigger(text),
280+
endNode,
281+
undefined,
282+
undefined,
283+
this.createRunCounterContext(true, false)
284+
);
285+
}
286+
}
287+
});
288+
248289
this.canvasApp.setOnAddcomposition(this.onAddFlowComposition);
249290
this.mediaLibary = createMediaLibrary();
250291
this.canvasApp.setMediaLibrary(this.mediaLibary);
@@ -2177,7 +2218,7 @@ export class FlowAppElement extends AppElement<NodeInfo> {
21772218
() => {
21782219
//
21792220
},
2180-
text,
2221+
this.transformValueForNodeTrigger(text),
21812222
endNode,
21822223
undefined,
21832224
undefined,
@@ -2191,4 +2232,66 @@ export class FlowAppElement extends AppElement<NodeInfo> {
21912232
}
21922233
return true;
21932234
};
2235+
2236+
handleExpression = (expression: string, payload: any) => {
2237+
try {
2238+
const compiledExpression = compileExpressionAsInfo(expression);
2239+
const expressionFunction = (
2240+
new Function('payload', `${compiledExpression.script}`) as unknown as (
2241+
payload?: any
2242+
) => any
2243+
).bind(compiledExpression.bindings);
2244+
2245+
const result = runExpression(
2246+
expressionFunction,
2247+
payload,
2248+
false,
2249+
compiledExpression.payloadProperties
2250+
);
2251+
return result;
2252+
} catch (error) {
2253+
console.error('Split-by-case: Error in handleExpression', error);
2254+
return false;
2255+
}
2256+
};
2257+
2258+
transformValueForNodeTrigger = (value: string) => {
2259+
if (typeof value === 'string') {
2260+
let trimmedValue = value.trim();
2261+
if (
2262+
(trimmedValue.startsWith('[') && trimmedValue.endsWith(']')) ||
2263+
trimmedValue.startsWith('=')
2264+
) {
2265+
if (trimmedValue.startsWith('=')) {
2266+
trimmedValue = trimmedValue.slice(1);
2267+
}
2268+
const payloadForExpression = getVariablePayloadInputUtils(
2269+
'',
2270+
{},
2271+
'number',
2272+
-1,
2273+
-1,
2274+
undefined,
2275+
this.currentCanvasApp
2276+
);
2277+
const expressionResult = this.handleExpression(
2278+
trimmedValue,
2279+
payloadForExpression
2280+
);
2281+
if (expressionResult !== false) {
2282+
return expressionResult;
2283+
}
2284+
return '';
2285+
}
2286+
if (trimmedValue.startsWith('{') && trimmedValue.endsWith('}')) {
2287+
try {
2288+
return JSON.parse(trimmedValue);
2289+
} catch (e) {
2290+
return trimmedValue;
2291+
}
2292+
}
2293+
return value;
2294+
}
2295+
return '';
2296+
};
21942297
}

0 commit comments

Comments
 (0)