Skip to content

Commit dc13380

Browse files
committed
Ensures consistent property ordering
Maintains a predictable structure for script objects by rebuilding them in a fixed order. clarifies merging logic for updates and adds an example script for verification.
1 parent 5f4f231 commit dc13380

File tree

3 files changed

+99
-3
lines changed

3 files changed

+99
-3
lines changed

editor/src/App.tsx

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,9 +318,29 @@ export default function App() {
318318
dispatch({ type: 'UPDATE_STEP', stepId, patch });
319319
};
320320

321-
// Helper to update the script data
321+
// Helper to update the script data while preserving property order
322322
const updateScript = (patch: Partial<ScriptData>) => {
323-
dispatch({ type: 'LOAD_SCRIPT', script: { ...script, ...patch } });
323+
// Merge patch into current script first
324+
const merged = { ...script, ...patch };
325+
326+
// Always reconstruct the script object in the desired property order
327+
const orderedScript: any = {};
328+
329+
// Add properties in the desired order: id, startMode, endMode, activities
330+
if (merged.id !== undefined && merged.id !== '') {
331+
orderedScript.id = merged.id;
332+
}
333+
if (merged.startMode !== undefined) {
334+
orderedScript.startMode = merged.startMode;
335+
}
336+
if (merged.endMode !== undefined) {
337+
orderedScript.endMode = merged.endMode;
338+
}
339+
340+
// Always include activities (required property) last
341+
orderedScript.activities = merged.activities;
342+
343+
dispatch({ type: 'LOAD_SCRIPT', script: orderedScript as ScriptData });
324344
};
325345

326346
// Ensure step logic is properly initialized when a step is selected
@@ -398,6 +418,7 @@ export default function App() {
398418
script={script}
399419
onChange={updateScript}
400420
/>
421+
<pre>{JSON.stringify(script, null, 2)}</pre>
401422
</div>
402423
) : (
403424
<NodeDetailsPanel

editor/src/normalizer.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,25 @@ export function normalizeStep(raw: any, parentActivityType: 'RangeAnalysisScript
9191

9292
export function normalizeScript(raw: any): ScriptData {
9393
const activities = Array.isArray(raw.activities) ? raw.activities.map((a: any) => normalizeActivity(a)) : [];
94-
return { activities };
94+
95+
// Preserve root-level properties in proper order: id, startMode, endMode, activities
96+
const result: ScriptData = { activities };
97+
98+
// Add properties in desired order by reconstructing the object
99+
const orderedResult: ScriptData = { activities: [] };
100+
101+
if (raw.id !== undefined) {
102+
orderedResult.id = raw.id;
103+
}
104+
if (raw.startMode !== undefined) {
105+
orderedResult.startMode = raw.startMode;
106+
}
107+
if (raw.endMode !== undefined) {
108+
orderedResult.endMode = raw.endMode;
109+
}
110+
111+
// Always include activities last (required property)
112+
orderedResult.activities = activities;
113+
114+
return orderedResult;
95115
}

examples/test-order.json

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
{
2+
"$schema": "../schema/1.0.0/app-scripting.schema.json",
3+
"id": "test-script-1",
4+
"startMode": "Overwrite",
5+
"endMode": "Wait",
6+
"activities": [
7+
{
8+
"nodeType": "RangeAnalysisScriptedActivity",
9+
"id": "ra-1",
10+
"introMessage": { "header": "Test Activity", "description": "Testing property order", "seconds": 3 },
11+
"endMessage": { "header": "Done", "description": "", "seconds": 3 },
12+
"steps": [
13+
{
14+
"nodeType": "RangeAnalysisScriptedStep",
15+
"id": "ra-step-1",
16+
"introMessage": {
17+
"header": "Hit 3 shots",
18+
"description": "",
19+
"seconds": 5
20+
},
21+
"successMessage": {
22+
"header": "Great!",
23+
"description": "",
24+
"seconds": 3
25+
},
26+
"failMessage": {
27+
"header": "Try again",
28+
"description": "",
29+
"seconds": 3
30+
},
31+
"logic": {
32+
"nodeType": "RangeAnalysisScriptedLogic",
33+
"setup": {
34+
"nodeType": "RangeAnalysisScriptedSetup",
35+
"club": "Drv",
36+
"distance": 200
37+
},
38+
"successCondition": {
39+
"nodeType": "RangeAnalysisScriptedConditions",
40+
"shots": 3,
41+
"conditions": [{ "parameter": "Total", "min": 200 }]
42+
},
43+
"failCondition": {
44+
"nodeType": "RangeAnalysisScriptedConditions",
45+
"shots": 5
46+
},
47+
"canRetry": true,
48+
"skipOnSuccess": true
49+
},
50+
"ui": { "nodeType": "RangeAnalysisScriptedUI" }
51+
}
52+
]
53+
}
54+
]
55+
}

0 commit comments

Comments
 (0)