Skip to content

Commit 9521daf

Browse files
committed
store json-node state in history and improve visualisation of variable node-type for object values
1 parent 544e42b commit 9521daf

File tree

4 files changed

+188
-2
lines changed

4 files changed

+188
-2
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
{
2+
"schemaType": "flow",
3+
"schemaVersion": "0.0.1",
4+
"id": "1234",
5+
"flows": {
6+
"flow": {
7+
"flowType": "flow",
8+
"nodes": [
9+
{
10+
"id": "63f8fb39-7e8f-4fcb-bd01-9e97f4a9aaf3",
11+
"x": 3917.1829622013615,
12+
"y": 1337.7741673439134,
13+
"width": 111.7109375,
14+
"height": 112,
15+
"nodeType": "Shape",
16+
"nodeInfo": {
17+
"type": "json-node",
18+
"formValues": {
19+
"json": "{\n \"@set:test\" : \"input\",\n \"hello\":\"world\",\n \"lorem\" : \"ipsum\"\n}"
20+
},
21+
"nodeCannotBeReplaced": true,
22+
"showFormOnlyInPopup": true,
23+
"useInCompositionOnly": false,
24+
"keepPopupOpenAfterUpdate": true
25+
}
26+
},
27+
{
28+
"id": "cecdf03e-1258-43c7-bf7e-e8b3b3255f22",
29+
"x": 3916.308108208468,
30+
"y": 1079.4571224381473,
31+
"width": 174.42193012003736,
32+
"height": 180.00000923049612,
33+
"nodeType": "Shape",
34+
"nodeInfo": {
35+
"type": "scope-variable",
36+
"formValues": {
37+
"variableName": "something",
38+
"initialValue": "",
39+
"fieldType": "value",
40+
"fieldValueType": "object",
41+
"enumValues": [],
42+
"initialEnumValue": ""
43+
},
44+
"isVariable": true,
45+
"nodeCannotBeReplaced": true
46+
}
47+
},
48+
{
49+
"id": "dc503057-d15d-4c65-85ca-001a0b9d6e71",
50+
"x": 3380.1014694405635,
51+
"y": 1309.2653809435571,
52+
"width": 200,
53+
"height": 112,
54+
"nodeType": "Shape",
55+
"nodeInfo": {
56+
"type": "value",
57+
"formValues": {
58+
"value": "a value"
59+
}
60+
}
61+
},
62+
{
63+
"id": "c61d2736-5945-46dc-abdb-0b8900dba8ba",
64+
"x": 4294.618156523115,
65+
"y": 1391.2182663403976,
66+
"width": 200,
67+
"height": 128,
68+
"nodeType": "Shape",
69+
"nodeInfo": {
70+
"type": "set-variable",
71+
"formValues": {
72+
"variableName": "something"
73+
},
74+
"nodeCannotBeReplaced": false,
75+
"showFormOnlyInPopup": false,
76+
"useInCompositionOnly": false,
77+
"keepPopupOpenAfterUpdate": false
78+
}
79+
},
80+
{
81+
"id": "722f438a-c1f6-4662-9a4e-e83555d7ea4c",
82+
"x": 3580.1014694405635,
83+
"y": 1365.2653809435571,
84+
"endX": 3917.1829622013615,
85+
"endY": 1393.7741673439134,
86+
"startNodeId": "dc503057-d15d-4c65-85ca-001a0b9d6e71",
87+
"endNodeId": "63f8fb39-7e8f-4fcb-bd01-9e97f4a9aaf3",
88+
"startThumbName": "output",
89+
"endThumbName": "input",
90+
"lineType": "BezierCubic",
91+
"nodeType": "Connection",
92+
"layer": 1,
93+
"nodeInfo": {}
94+
},
95+
{
96+
"id": "dde8118a-d43f-4991-99a9-9bd91658c6a1",
97+
"x": 4028.8938997013615,
98+
"y": 1393.7741673439134,
99+
"endX": 4294.618156523115,
100+
"endY": 1455.2182663403976,
101+
"startNodeId": "63f8fb39-7e8f-4fcb-bd01-9e97f4a9aaf3",
102+
"endNodeId": "c61d2736-5945-46dc-abdb-0b8900dba8ba",
103+
"startThumbName": "output",
104+
"endThumbName": "input",
105+
"lineType": "BezierCubic",
106+
"nodeType": "Connection",
107+
"layer": 1,
108+
"nodeInfo": {}
109+
}
110+
]
111+
}
112+
},
113+
"compositions": {}
114+
}

libs/visual-programming-system/src/utils/getFormattedValue.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ export const getFormattedVariableValue = (
2323
append: string
2424
) => {
2525
const appendText = `${append ? ` ${append}` : ''}`;
26-
if (typeof value === 'number') {
26+
27+
if (typeof value === 'object') {
28+
return JSON.stringify(value, null, 2);
29+
} else if (typeof value === 'number') {
2730
return `${(value as number).toFixed(decimalCount)}${appendText}`;
2831
} else if (typeof value === 'string') {
2932
return `${value}${appendText}` || '-';

libs/web-flow-executor/src/nodes/raw-json.tsx

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,16 @@ export const getRawJsonNode: NodeTaskFactory<NodeInfo> = (
8989
canvasAppInstance
9090
);
9191

92-
currentSerializedInput = payloadForExpression;
92+
currentSerializedInput = structuredClone(payloadForExpression);
93+
94+
canvasAppInstance?.getVariableNames(scopeId).forEach((variableName) => {
95+
const variableValue = canvasAppInstance?.getVariable(
96+
variableName,
97+
undefined,
98+
scopeId
99+
);
100+
currentSerializedInput[variableName] = variableValue;
101+
});
93102

94103
const json = JSON.parse(
95104
node.nodeInfo.formValues['json'].replace('[openai-key]', openAIKey)
@@ -122,6 +131,21 @@ export const getRawJsonNode: NodeTaskFactory<NodeInfo> = (
122131
}
123132
};
124133

134+
const getNodeStatedHandler = () => {
135+
return {
136+
data: {
137+
input: currentSerializedInput,
138+
output: currentOutput,
139+
},
140+
id: node.id,
141+
};
142+
};
143+
144+
const setNodeStatedHandler = (_id: string, data: any) => {
145+
currentSerializedInput = data.input;
146+
currentOutput = data.output;
147+
};
148+
125149
const Text = () => (
126150
<div class="text-white text-center text-2xl p-4">JSON Mapper</div>
127151
);
@@ -216,6 +240,18 @@ export const getRawJsonNode: NodeTaskFactory<NodeInfo> = (
216240
},
217241
},
218242
];
243+
244+
if (nodeInstance.node.id) {
245+
const id = nodeInstance.node.id;
246+
canvasAppInstance.registeGetNodeStateHandler(
247+
id,
248+
getNodeStatedHandler
249+
);
250+
canvasAppInstance.registeSetNodeStateHandler(
251+
id,
252+
setNodeStatedHandler
253+
);
254+
}
219255
}
220256
},
221257
{

libs/web-flow-executor/src/nodes/scoped-variable.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,10 +343,33 @@ export const getScopedVariable =
343343
const variableScopeType = isGlobal ? 'global' : 'scope dependent';
344344
return `${description}<br />(${variableScopeType})`;
345345
}
346+
347+
function resetHtmlNodeStyle() {
348+
if (htmlNode && htmlNode?.domElement) {
349+
(htmlNode.domElement as unknown as HTMLElement).classList.remove(
350+
'text-left'
351+
);
352+
(htmlNode.domElement as unknown as HTMLElement).classList.remove(
353+
'whitespace-pre'
354+
);
355+
}
356+
}
357+
358+
function formatHtmlNodeAsObject() {
359+
if (htmlNode && htmlNode?.domElement) {
360+
(htmlNode.domElement as unknown as HTMLElement).classList.add(
361+
'text-left'
362+
);
363+
(htmlNode.domElement as unknown as HTMLElement).classList.add(
364+
'whitespace-pre'
365+
);
366+
}
367+
}
346368
const initializeCompute = () => {
347369
const variableName = node?.nodeInfo?.formValues?.['variableName'] ?? '';
348370
lastStoredDataState = undefined;
349371

372+
resetHtmlNodeStyle();
350373
scopedData = {};
351374
currentValue = undefined;
352375
fieldType = node?.nodeInfo?.formValues?.['fieldType'] ?? 'value';
@@ -368,6 +391,7 @@ export const getScopedVariable =
368391
return;
369392
}
370393

394+
resetHtmlNodeStyle();
371395
if (fieldType === 'value') {
372396
// if (isNaN(currentValue)) {
373397
// currentValue = 0;
@@ -379,6 +403,10 @@ export const getScopedVariable =
379403
if (htmlNode && htmlNode?.domElement) {
380404
(htmlNode.domElement as unknown as HTMLElement).innerHTML =
381405
getLabelAsHtml(getFormattedVariableValue(currentValue, 2, ''));
406+
407+
if (typeof currentValue === 'object') {
408+
formatHtmlNodeAsObject();
409+
}
382410
}
383411
canvasAppInstance?.setVariable(
384412
variableName,
@@ -504,12 +532,17 @@ export const getScopedVariable =
504532
return;
505533
}
506534
if (htmlNode) {
535+
resetHtmlNodeStyle();
507536
if (fieldType === 'value') {
508537
if (htmlNode?.domElement) {
509538
(htmlNode?.domElement as unknown as HTMLElement).innerHTML =
510539
getLabelAsHtml(
511540
getFormattedVariableValue(lastStoredDataState, 2, '')
512541
);
542+
543+
if (typeof lastStoredDataState === 'object') {
544+
formatHtmlNodeAsObject();
545+
}
513546
}
514547
if (rect && rect.resize) {
515548
rect.resize(120);

0 commit comments

Comments
 (0)