@waypointjs/builder 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1492 -539
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -2
- package/dist/index.d.ts +10 -2
- package/dist/index.js +1494 -541
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,9 @@ var core = require('@waypointjs/core');
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var zustand = require('zustand');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var core$1 = require('@dnd-kit/core');
|
|
8
|
+
var sortable = require('@dnd-kit/sortable');
|
|
9
|
+
var utilities = require('@dnd-kit/utilities');
|
|
7
10
|
var react$1 = require('@waypointjs/react');
|
|
8
11
|
var devtools = require('@waypointjs/devtools');
|
|
9
12
|
|
|
@@ -197,6 +200,44 @@ var useBuilderStore = zustand.create((set, _get) => ({
|
|
|
197
200
|
selectedFieldId: s.selectedStepId === stepId ? null : s.selectedFieldId,
|
|
198
201
|
isDirty: true
|
|
199
202
|
})),
|
|
203
|
+
duplicateStep: (stepId) => {
|
|
204
|
+
const state = _get();
|
|
205
|
+
const step = state.schema.steps.find((s) => s.id === stepId);
|
|
206
|
+
if (!step) return;
|
|
207
|
+
const newStepId = generateId("step");
|
|
208
|
+
const fieldIdMap = {};
|
|
209
|
+
for (const f of step.fields) {
|
|
210
|
+
fieldIdMap[f.id] = generateId("field");
|
|
211
|
+
}
|
|
212
|
+
const newFields = step.fields.map((f) => ({
|
|
213
|
+
...f,
|
|
214
|
+
id: fieldIdMap[f.id],
|
|
215
|
+
dependsOn: f.dependsOn?.map((dep) => {
|
|
216
|
+
if (dep.startsWith(`${stepId}.`)) {
|
|
217
|
+
const oldFieldId = dep.slice(stepId.length + 1);
|
|
218
|
+
const newFieldId = fieldIdMap[oldFieldId];
|
|
219
|
+
return newFieldId ? `${newStepId}.${newFieldId}` : dep;
|
|
220
|
+
}
|
|
221
|
+
return dep;
|
|
222
|
+
})
|
|
223
|
+
}));
|
|
224
|
+
const newStep = {
|
|
225
|
+
...step,
|
|
226
|
+
id: newStepId,
|
|
227
|
+
title: `${step.title} (copy)`,
|
|
228
|
+
url: `${step.url}-copy`,
|
|
229
|
+
fields: newFields
|
|
230
|
+
};
|
|
231
|
+
const stepIndex = state.schema.steps.findIndex((s) => s.id === stepId);
|
|
232
|
+
const newSteps = [...state.schema.steps];
|
|
233
|
+
newSteps.splice(stepIndex + 1, 0, newStep);
|
|
234
|
+
set({
|
|
235
|
+
schema: { ...state.schema, steps: newSteps },
|
|
236
|
+
selectedStepId: newStepId,
|
|
237
|
+
selectedFieldId: null,
|
|
238
|
+
isDirty: true
|
|
239
|
+
});
|
|
240
|
+
},
|
|
200
241
|
reorderSteps: (fromIndex, toIndex) => set((s) => {
|
|
201
242
|
const steps = [...s.schema.steps];
|
|
202
243
|
const [moved] = steps.splice(fromIndex, 1);
|
|
@@ -249,6 +290,32 @@ var useBuilderStore = zustand.create((set, _get) => ({
|
|
|
249
290
|
selectedFieldId: s.selectedFieldId === fieldId ? null : s.selectedFieldId,
|
|
250
291
|
isDirty: true
|
|
251
292
|
})),
|
|
293
|
+
duplicateField: (stepId, fieldId) => {
|
|
294
|
+
const state = _get();
|
|
295
|
+
const step = state.schema.steps.find((s) => s.id === stepId);
|
|
296
|
+
if (!step) return;
|
|
297
|
+
const field = step.fields.find((f) => f.id === fieldId);
|
|
298
|
+
if (!field) return;
|
|
299
|
+
const newFieldId = generateId("field");
|
|
300
|
+
const newField = {
|
|
301
|
+
...field,
|
|
302
|
+
id: newFieldId,
|
|
303
|
+
label: `${field.label} (copy)`
|
|
304
|
+
};
|
|
305
|
+
const fieldIndex = step.fields.findIndex((f) => f.id === fieldId);
|
|
306
|
+
const newFields = [...step.fields];
|
|
307
|
+
newFields.splice(fieldIndex + 1, 0, newField);
|
|
308
|
+
set((s) => ({
|
|
309
|
+
schema: {
|
|
310
|
+
...s.schema,
|
|
311
|
+
steps: s.schema.steps.map(
|
|
312
|
+
(st) => st.id === stepId ? { ...st, fields: newFields } : st
|
|
313
|
+
)
|
|
314
|
+
},
|
|
315
|
+
selectedFieldId: newFieldId,
|
|
316
|
+
isDirty: true
|
|
317
|
+
}));
|
|
318
|
+
},
|
|
252
319
|
reorderFields: (stepId, fromIndex, toIndex) => set((s) => ({
|
|
253
320
|
schema: {
|
|
254
321
|
...s.schema,
|
|
@@ -347,6 +414,18 @@ var useBuilderStore = zustand.create((set, _get) => ({
|
|
|
347
414
|
isDirty: true
|
|
348
415
|
}))
|
|
349
416
|
}));
|
|
417
|
+
var BuilderReadOnlyContext = react.createContext(false);
|
|
418
|
+
function useBuilderReadOnly() {
|
|
419
|
+
return react.useContext(BuilderReadOnlyContext);
|
|
420
|
+
}
|
|
421
|
+
var BuilderCustomTypesContext = react.createContext([]);
|
|
422
|
+
function useBuilderCustomTypes() {
|
|
423
|
+
return react.useContext(BuilderCustomTypesContext);
|
|
424
|
+
}
|
|
425
|
+
var BuilderExternalEnumsContext = react.createContext([]);
|
|
426
|
+
function useBuilderExternalEnums() {
|
|
427
|
+
return react.useContext(BuilderExternalEnumsContext);
|
|
428
|
+
}
|
|
350
429
|
var BLANK_FORM = {
|
|
351
430
|
id: "",
|
|
352
431
|
label: "",
|
|
@@ -360,6 +439,7 @@ function ExternalVariablePanel() {
|
|
|
360
439
|
updateExternalVariable,
|
|
361
440
|
removeExternalVariable
|
|
362
441
|
} = useBuilderStore();
|
|
442
|
+
const readOnly = useBuilderReadOnly();
|
|
363
443
|
const variables = schema.externalVariables ?? [];
|
|
364
444
|
const [isAdding, setIsAdding] = react.useState(false);
|
|
365
445
|
const [editingId, setEditingId] = react.useState(null);
|
|
@@ -433,7 +513,7 @@ function ExternalVariablePanel() {
|
|
|
433
513
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: panelStyle, children: [
|
|
434
514
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headerStyle, children: [
|
|
435
515
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: titleStyle, children: "External Variables" }),
|
|
436
|
-
!isAdding && /* @__PURE__ */ jsxRuntime.jsx(
|
|
516
|
+
!readOnly && !isAdding && /* @__PURE__ */ jsxRuntime.jsx(
|
|
437
517
|
"button",
|
|
438
518
|
{
|
|
439
519
|
style: addBtnStyle,
|
|
@@ -488,7 +568,7 @@ function ExternalVariablePanel() {
|
|
|
488
568
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: varLabelStyle, children: v.label }),
|
|
489
569
|
refs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: refsStyle, children: refs.map((ref, i) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: refChipStyle, children: ref }, i)) })
|
|
490
570
|
] }),
|
|
491
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: varActionsStyle, children: [
|
|
571
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: varActionsStyle, children: [
|
|
492
572
|
/* @__PURE__ */ jsxRuntime.jsx("button", { style: actionBtnStyle, onClick: () => startEdit(v), children: "Edit" }),
|
|
493
573
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
494
574
|
"button",
|
|
@@ -815,15 +895,23 @@ var submitBtnStyle = {
|
|
|
815
895
|
// src/hooks/useAllFieldPaths.ts
|
|
816
896
|
function useAllFieldPaths(excludeStepId, excludeFieldId) {
|
|
817
897
|
const { schema } = useBuilderStore();
|
|
898
|
+
const externalEnums = useBuilderExternalEnums();
|
|
818
899
|
const paths = [];
|
|
819
900
|
for (const step of schema.steps) {
|
|
820
901
|
for (const field of step.fields) {
|
|
821
902
|
if (step.id === excludeStepId && field.id === excludeFieldId) continue;
|
|
903
|
+
let options;
|
|
904
|
+
if (field.externalEnumId) {
|
|
905
|
+
options = externalEnums.find((e) => e.id === field.externalEnumId)?.values;
|
|
906
|
+
} else if (field.options?.length) {
|
|
907
|
+
options = field.options;
|
|
908
|
+
}
|
|
822
909
|
paths.push({
|
|
823
910
|
path: `${step.id}.${field.id}`,
|
|
824
911
|
label: `${step.title} \u2192 ${field.label}`,
|
|
825
912
|
stepId: step.id,
|
|
826
|
-
fieldId: field.id
|
|
913
|
+
fieldId: field.id,
|
|
914
|
+
options
|
|
827
915
|
});
|
|
828
916
|
}
|
|
829
917
|
}
|
|
@@ -849,7 +937,9 @@ var OPERATORS = [
|
|
|
849
937
|
{ value: "notIn", label: "not in (comma list)", hasValue: true },
|
|
850
938
|
{ value: "matches", label: "matches regex", hasValue: true },
|
|
851
939
|
{ value: "exists", label: "exists", hasValue: false },
|
|
852
|
-
{ value: "notExists", label: "not exists", hasValue: false }
|
|
940
|
+
{ value: "notExists", label: "not exists", hasValue: false },
|
|
941
|
+
{ value: "inEnum", label: "is in enum", hasValue: true, isEnum: true },
|
|
942
|
+
{ value: "notInEnum", label: "not in enum", hasValue: true, isEnum: true }
|
|
853
943
|
];
|
|
854
944
|
function ConditionBuilder({
|
|
855
945
|
value,
|
|
@@ -858,6 +948,7 @@ function ConditionBuilder({
|
|
|
858
948
|
excludeFieldId
|
|
859
949
|
}) {
|
|
860
950
|
const allPaths = useAllFieldPaths(excludeStepId, excludeFieldId);
|
|
951
|
+
const externalEnums = useBuilderExternalEnums();
|
|
861
952
|
const group = value ?? { combinator: "and", rules: [] };
|
|
862
953
|
const updateRule = (index, updates) => {
|
|
863
954
|
const rules = group.rules.map((r, i) => i === index ? { ...r, ...updates } : r);
|
|
@@ -920,15 +1011,48 @@ function ConditionBuilder({
|
|
|
920
1011
|
children: OPERATORS.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, children: o.label }, o.value))
|
|
921
1012
|
}
|
|
922
1013
|
),
|
|
923
|
-
opDef?.hasValue && /* @__PURE__ */ jsxRuntime.
|
|
924
|
-
"
|
|
1014
|
+
opDef?.hasValue && (opDef.isEnum ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1015
|
+
"select",
|
|
925
1016
|
{
|
|
926
|
-
style: styles.
|
|
927
|
-
placeholder: "value",
|
|
1017
|
+
style: { ...styles.select, width: 140 },
|
|
928
1018
|
value: rule.value != null ? String(rule.value) : "",
|
|
929
|
-
onChange: (e) => updateRule(index, { value: e.target.value })
|
|
1019
|
+
onChange: (e) => updateRule(index, { value: e.target.value }),
|
|
1020
|
+
children: [
|
|
1021
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u2014 pick enum \u2014" }),
|
|
1022
|
+
externalEnums.map((en) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: en.id, children: en.label }, en.id))
|
|
1023
|
+
]
|
|
930
1024
|
}
|
|
931
|
-
),
|
|
1025
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles.valueGroup, children: [
|
|
1026
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1027
|
+
"input",
|
|
1028
|
+
{
|
|
1029
|
+
style: styles.valueInput,
|
|
1030
|
+
placeholder: "value",
|
|
1031
|
+
value: rule.value != null ? String(rule.value) : "",
|
|
1032
|
+
onChange: (e) => updateRule(index, { value: e.target.value })
|
|
1033
|
+
}
|
|
1034
|
+
),
|
|
1035
|
+
externalEnums.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1036
|
+
"select",
|
|
1037
|
+
{
|
|
1038
|
+
style: styles.enumPicker,
|
|
1039
|
+
title: "Pick a value from an enum",
|
|
1040
|
+
value: "",
|
|
1041
|
+
onChange: (e) => {
|
|
1042
|
+
if (e.target.value) updateRule(index, { value: e.target.value });
|
|
1043
|
+
},
|
|
1044
|
+
children: [
|
|
1045
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u229E" }),
|
|
1046
|
+
externalEnums.map((en) => /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: en.label, children: en.values.map((v) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: String(v.value), children: [
|
|
1047
|
+
v.label,
|
|
1048
|
+
" (",
|
|
1049
|
+
v.value,
|
|
1050
|
+
")"
|
|
1051
|
+
] }, String(v.value))) }, en.id))
|
|
1052
|
+
]
|
|
1053
|
+
}
|
|
1054
|
+
)
|
|
1055
|
+
] })),
|
|
932
1056
|
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles.removeBtn, onClick: () => removeRule(index), children: "\u2715" })
|
|
933
1057
|
] }, index);
|
|
934
1058
|
}),
|
|
@@ -1006,6 +1130,17 @@ var styles = {
|
|
|
1006
1130
|
alignSelf: "flex-start",
|
|
1007
1131
|
color: "var(--wp-text-secondary)"
|
|
1008
1132
|
},
|
|
1133
|
+
valueGroup: { display: "flex", alignItems: "center", gap: 4 },
|
|
1134
|
+
enumPicker: {
|
|
1135
|
+
fontSize: 11,
|
|
1136
|
+
padding: "4px 4px",
|
|
1137
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1138
|
+
borderRadius: "var(--wp-radius)",
|
|
1139
|
+
background: "var(--wp-canvas)",
|
|
1140
|
+
color: "var(--wp-primary)",
|
|
1141
|
+
cursor: "pointer",
|
|
1142
|
+
flexShrink: 0
|
|
1143
|
+
},
|
|
1009
1144
|
preview: { marginTop: 4 },
|
|
1010
1145
|
previewLabel: {
|
|
1011
1146
|
fontSize: 10,
|
|
@@ -1027,6 +1162,244 @@ var styles = {
|
|
|
1027
1162
|
color: "var(--wp-text-mono)"
|
|
1028
1163
|
}
|
|
1029
1164
|
};
|
|
1165
|
+
var VALIDATION_RULES = [
|
|
1166
|
+
{ type: "required", label: "Required", hasValue: false },
|
|
1167
|
+
{ type: "min", label: "Min value", hasValue: true },
|
|
1168
|
+
{ type: "max", label: "Max value", hasValue: true },
|
|
1169
|
+
{ type: "minLength", label: "Min length", hasValue: true },
|
|
1170
|
+
{ type: "maxLength", label: "Max length", hasValue: true },
|
|
1171
|
+
{ type: "email", label: "Email format", hasValue: false },
|
|
1172
|
+
{ type: "url", label: "URL format", hasValue: false },
|
|
1173
|
+
{ type: "regex", label: "Matches regex", hasValue: true },
|
|
1174
|
+
{ type: "equals", label: "equals", hasValue: true },
|
|
1175
|
+
{ type: "notEquals", label: "not equals", hasValue: true },
|
|
1176
|
+
{ type: "greaterThan", label: ">", hasValue: true },
|
|
1177
|
+
{ type: "greaterThanOrEqual", label: ">=", hasValue: true },
|
|
1178
|
+
{ type: "lessThan", label: "<", hasValue: true },
|
|
1179
|
+
{ type: "lessThanOrEqual", label: "<=", hasValue: true },
|
|
1180
|
+
{ type: "contains", label: "contains", hasValue: true },
|
|
1181
|
+
{ type: "notContains", label: "not contains", hasValue: true },
|
|
1182
|
+
{ type: "matches", label: "matches regex", hasValue: true },
|
|
1183
|
+
{ type: "inEnum", label: "is in enum", hasValue: true, isEnum: true },
|
|
1184
|
+
{ type: "notInEnum", label: "not in enum", hasValue: true, isEnum: true },
|
|
1185
|
+
{ type: "custom", label: "Custom validator", hasValue: false }
|
|
1186
|
+
];
|
|
1187
|
+
var COMPARATOR_TYPES = /* @__PURE__ */ new Set([
|
|
1188
|
+
"equals",
|
|
1189
|
+
"notEquals",
|
|
1190
|
+
"greaterThan",
|
|
1191
|
+
"greaterThanOrEqual",
|
|
1192
|
+
"lessThan",
|
|
1193
|
+
"lessThanOrEqual",
|
|
1194
|
+
"contains",
|
|
1195
|
+
"notContains"
|
|
1196
|
+
]);
|
|
1197
|
+
function ValidationBuilder({ value, onChange }) {
|
|
1198
|
+
const externalEnums = useBuilderExternalEnums();
|
|
1199
|
+
const allFieldPaths = useAllFieldPaths();
|
|
1200
|
+
const updateRule = (index, updates) => {
|
|
1201
|
+
onChange(value.map((r, i) => i === index ? { ...r, ...updates } : r));
|
|
1202
|
+
};
|
|
1203
|
+
const addRule = () => {
|
|
1204
|
+
onChange([...value, { type: "required", message: "This field is required" }]);
|
|
1205
|
+
};
|
|
1206
|
+
const removeRule = (index) => {
|
|
1207
|
+
onChange(value.filter((_, i) => i !== index));
|
|
1208
|
+
};
|
|
1209
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles2.container, children: [
|
|
1210
|
+
value.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles2.empty, children: "No rules \u2014 field is optional by default." }),
|
|
1211
|
+
value.map((rule, index) => {
|
|
1212
|
+
const def = VALIDATION_RULES.find((r) => r.type === rule.type);
|
|
1213
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles2.rule, children: [
|
|
1214
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1215
|
+
"select",
|
|
1216
|
+
{
|
|
1217
|
+
style: styles2.typeSelect,
|
|
1218
|
+
value: rule.type,
|
|
1219
|
+
onChange: (e) => updateRule(index, { type: e.target.value }),
|
|
1220
|
+
children: VALIDATION_RULES.map((r) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: r.type, children: r.label }, r.type))
|
|
1221
|
+
}
|
|
1222
|
+
),
|
|
1223
|
+
def?.hasValue && (def.isEnum ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1224
|
+
"select",
|
|
1225
|
+
{
|
|
1226
|
+
style: { ...styles2.typeSelect, flex: "0 0 140px" },
|
|
1227
|
+
value: rule.value != null ? String(rule.value) : "",
|
|
1228
|
+
onChange: (e) => updateRule(index, { value: e.target.value }),
|
|
1229
|
+
children: [
|
|
1230
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u2014 pick enum \u2014" }),
|
|
1231
|
+
externalEnums.map((en) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: en.id, children: en.label }, en.id))
|
|
1232
|
+
]
|
|
1233
|
+
}
|
|
1234
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles2.valueGroup, children: [
|
|
1235
|
+
COMPARATOR_TYPES.has(rule.type) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1236
|
+
"button",
|
|
1237
|
+
{
|
|
1238
|
+
type: "button",
|
|
1239
|
+
style: {
|
|
1240
|
+
...styles2.refToggle,
|
|
1241
|
+
background: rule.refField !== void 0 ? "var(--wp-primary)" : "var(--wp-surface-muted)",
|
|
1242
|
+
color: rule.refField !== void 0 ? "#fff" : "var(--wp-text-secondary)"
|
|
1243
|
+
},
|
|
1244
|
+
title: rule.refField !== void 0 ? "Comparing to field \u2014 click for static value" : "Static value \u2014 click to compare to another field",
|
|
1245
|
+
onClick: () => {
|
|
1246
|
+
if (rule.refField !== void 0) {
|
|
1247
|
+
updateRule(index, { refField: void 0, value: "" });
|
|
1248
|
+
} else {
|
|
1249
|
+
updateRule(index, { refField: "", value: void 0 });
|
|
1250
|
+
}
|
|
1251
|
+
},
|
|
1252
|
+
children: "\u21C4"
|
|
1253
|
+
}
|
|
1254
|
+
),
|
|
1255
|
+
rule.refField !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1256
|
+
"select",
|
|
1257
|
+
{
|
|
1258
|
+
style: { ...styles2.typeSelect, flex: "1 1 auto" },
|
|
1259
|
+
value: rule.refField,
|
|
1260
|
+
onChange: (e) => updateRule(index, { refField: e.target.value }),
|
|
1261
|
+
children: [
|
|
1262
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u2014 pick field \u2014" }),
|
|
1263
|
+
allFieldPaths.filter((fp) => !fp.isExternal).map((fp) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: fp.path, children: fp.label }, fp.path))
|
|
1264
|
+
]
|
|
1265
|
+
}
|
|
1266
|
+
) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1267
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1268
|
+
"input",
|
|
1269
|
+
{
|
|
1270
|
+
style: styles2.valueInput,
|
|
1271
|
+
placeholder: "value",
|
|
1272
|
+
value: rule.value != null ? String(rule.value) : "",
|
|
1273
|
+
onChange: (e) => updateRule(index, { value: e.target.value })
|
|
1274
|
+
}
|
|
1275
|
+
),
|
|
1276
|
+
externalEnums.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1277
|
+
"select",
|
|
1278
|
+
{
|
|
1279
|
+
style: styles2.enumPicker,
|
|
1280
|
+
title: "Pick a value from an enum",
|
|
1281
|
+
value: "",
|
|
1282
|
+
onChange: (e) => {
|
|
1283
|
+
if (e.target.value) updateRule(index, { value: e.target.value });
|
|
1284
|
+
},
|
|
1285
|
+
children: [
|
|
1286
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u229E" }),
|
|
1287
|
+
externalEnums.map((en) => /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: en.label, children: en.values.map((v) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: String(v.value), children: [
|
|
1288
|
+
v.label,
|
|
1289
|
+
" (",
|
|
1290
|
+
v.value,
|
|
1291
|
+
")"
|
|
1292
|
+
] }, String(v.value))) }, en.id))
|
|
1293
|
+
]
|
|
1294
|
+
}
|
|
1295
|
+
)
|
|
1296
|
+
] })
|
|
1297
|
+
] })),
|
|
1298
|
+
rule.type === "custom" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1299
|
+
"input",
|
|
1300
|
+
{
|
|
1301
|
+
style: styles2.valueInput,
|
|
1302
|
+
placeholder: "validatorId",
|
|
1303
|
+
value: rule.customValidatorId ?? "",
|
|
1304
|
+
onChange: (e) => updateRule(index, { customValidatorId: e.target.value })
|
|
1305
|
+
}
|
|
1306
|
+
),
|
|
1307
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1308
|
+
"input",
|
|
1309
|
+
{
|
|
1310
|
+
style: styles2.messageInput,
|
|
1311
|
+
placeholder: "error message",
|
|
1312
|
+
value: rule.message,
|
|
1313
|
+
onChange: (e) => updateRule(index, { message: e.target.value })
|
|
1314
|
+
}
|
|
1315
|
+
),
|
|
1316
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles2.removeBtn, onClick: () => removeRule(index), children: "\u2715" })
|
|
1317
|
+
] }, index);
|
|
1318
|
+
}),
|
|
1319
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles2.addBtn, onClick: addRule, children: "+ Add rule" })
|
|
1320
|
+
] });
|
|
1321
|
+
}
|
|
1322
|
+
var styles2 = {
|
|
1323
|
+
container: { display: "flex", flexDirection: "column", gap: 10 },
|
|
1324
|
+
empty: { fontSize: 13, color: "var(--wp-text-subtle)", textAlign: "center", padding: "12px 0" },
|
|
1325
|
+
rule: {
|
|
1326
|
+
display: "flex",
|
|
1327
|
+
alignItems: "center",
|
|
1328
|
+
gap: 8,
|
|
1329
|
+
background: "var(--wp-surface)",
|
|
1330
|
+
border: "1px solid var(--wp-border)",
|
|
1331
|
+
borderRadius: "var(--wp-radius-lg)",
|
|
1332
|
+
padding: "8px 10px"
|
|
1333
|
+
},
|
|
1334
|
+
typeSelect: {
|
|
1335
|
+
flex: "0 0 150px",
|
|
1336
|
+
fontSize: 12,
|
|
1337
|
+
padding: "5px 6px",
|
|
1338
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1339
|
+
borderRadius: "var(--wp-radius)",
|
|
1340
|
+
background: "var(--wp-canvas)",
|
|
1341
|
+
color: "var(--wp-text)"
|
|
1342
|
+
},
|
|
1343
|
+
valueGroup: { display: "flex", alignItems: "center", gap: 4, flex: "1 1 auto" },
|
|
1344
|
+
refToggle: {
|
|
1345
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1346
|
+
borderRadius: "var(--wp-radius)",
|
|
1347
|
+
cursor: "pointer",
|
|
1348
|
+
fontSize: 11,
|
|
1349
|
+
padding: "4px 6px",
|
|
1350
|
+
flexShrink: 0,
|
|
1351
|
+
fontWeight: 600,
|
|
1352
|
+
lineHeight: 1
|
|
1353
|
+
},
|
|
1354
|
+
valueInput: {
|
|
1355
|
+
width: 90,
|
|
1356
|
+
fontSize: 12,
|
|
1357
|
+
padding: "5px 6px",
|
|
1358
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1359
|
+
borderRadius: "var(--wp-radius)",
|
|
1360
|
+
background: "var(--wp-canvas)",
|
|
1361
|
+
color: "var(--wp-text)"
|
|
1362
|
+
},
|
|
1363
|
+
enumPicker: {
|
|
1364
|
+
fontSize: 11,
|
|
1365
|
+
padding: "4px 4px",
|
|
1366
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1367
|
+
borderRadius: "var(--wp-radius)",
|
|
1368
|
+
background: "var(--wp-canvas)",
|
|
1369
|
+
color: "var(--wp-primary)",
|
|
1370
|
+
cursor: "pointer",
|
|
1371
|
+
flexShrink: 0
|
|
1372
|
+
},
|
|
1373
|
+
messageInput: {
|
|
1374
|
+
flex: 1,
|
|
1375
|
+
fontSize: 12,
|
|
1376
|
+
padding: "5px 6px",
|
|
1377
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1378
|
+
borderRadius: "var(--wp-radius)",
|
|
1379
|
+
background: "var(--wp-canvas)",
|
|
1380
|
+
color: "var(--wp-text)",
|
|
1381
|
+
minWidth: 0
|
|
1382
|
+
},
|
|
1383
|
+
removeBtn: {
|
|
1384
|
+
border: "none",
|
|
1385
|
+
background: "transparent",
|
|
1386
|
+
color: "var(--wp-danger)",
|
|
1387
|
+
cursor: "pointer",
|
|
1388
|
+
fontSize: 13,
|
|
1389
|
+
flexShrink: 0
|
|
1390
|
+
},
|
|
1391
|
+
addBtn: {
|
|
1392
|
+
fontSize: 12,
|
|
1393
|
+
padding: "6px 12px",
|
|
1394
|
+
background: "var(--wp-surface-muted)",
|
|
1395
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1396
|
+
borderRadius: "var(--wp-radius)",
|
|
1397
|
+
cursor: "pointer",
|
|
1398
|
+
fontWeight: 500,
|
|
1399
|
+
alignSelf: "flex-start",
|
|
1400
|
+
color: "var(--wp-text-secondary)"
|
|
1401
|
+
}
|
|
1402
|
+
};
|
|
1030
1403
|
function DependsOnInput({
|
|
1031
1404
|
value,
|
|
1032
1405
|
onChange,
|
|
@@ -1059,17 +1432,17 @@ function DependsOnInput({
|
|
|
1059
1432
|
}, []);
|
|
1060
1433
|
const getLabel = (path) => allPaths.find((p) => p.path === path)?.label ?? path;
|
|
1061
1434
|
const isExternal = (path) => path.startsWith("$ext.");
|
|
1062
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, style:
|
|
1063
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1064
|
-
value.map((path) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { ...
|
|
1435
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: containerRef, style: styles3.container, children: [
|
|
1436
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles3.tags, children: [
|
|
1437
|
+
value.map((path) => /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { ...styles3.tag, ...isExternal(path) ? styles3.tagExt : {} }, children: [
|
|
1065
1438
|
getLabel(path),
|
|
1066
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
1439
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles3.tagRemove, onClick: () => remove(path), children: "\u2715" })
|
|
1067
1440
|
] }, path)),
|
|
1068
1441
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1069
1442
|
"input",
|
|
1070
1443
|
{
|
|
1071
1444
|
ref: inputRef,
|
|
1072
|
-
style:
|
|
1445
|
+
style: styles3.input,
|
|
1073
1446
|
placeholder: value.length === 0 ? "Search fields or $ext vars\u2026" : "Add more\u2026",
|
|
1074
1447
|
value: query,
|
|
1075
1448
|
onChange: (e) => {
|
|
@@ -1080,28 +1453,28 @@ function DependsOnInput({
|
|
|
1080
1453
|
}
|
|
1081
1454
|
)
|
|
1082
1455
|
] }),
|
|
1083
|
-
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1084
|
-
available.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1456
|
+
open && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles3.dropdown, children: [
|
|
1457
|
+
available.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles3.noResults, children: allPaths.length === 0 ? "No fields available in the tree yet." : "No matching fields." }),
|
|
1085
1458
|
available.map((p) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1086
1459
|
"button",
|
|
1087
1460
|
{
|
|
1088
|
-
style:
|
|
1461
|
+
style: styles3.option,
|
|
1089
1462
|
onMouseDown: (e) => {
|
|
1090
1463
|
e.preventDefault();
|
|
1091
1464
|
add(p.path);
|
|
1092
1465
|
},
|
|
1093
1466
|
children: [
|
|
1094
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1095
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1467
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles3.optionLabel, children: p.label }),
|
|
1468
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles3.optionPath, children: p.path })
|
|
1096
1469
|
]
|
|
1097
1470
|
},
|
|
1098
1471
|
p.path
|
|
1099
1472
|
))
|
|
1100
1473
|
] }),
|
|
1101
|
-
value.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1474
|
+
value.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles3.hint, children: "This field will be blocked until all dependencies have a value." })
|
|
1102
1475
|
] });
|
|
1103
1476
|
}
|
|
1104
|
-
var
|
|
1477
|
+
var styles3 = {
|
|
1105
1478
|
container: { position: "relative" },
|
|
1106
1479
|
tags: {
|
|
1107
1480
|
display: "flex",
|
|
@@ -1183,15 +1556,15 @@ function Modal({ title, onClose, children, width = 560 }) {
|
|
|
1183
1556
|
document.addEventListener("keydown", handler);
|
|
1184
1557
|
return () => document.removeEventListener("keydown", handler);
|
|
1185
1558
|
}, [onClose]);
|
|
1186
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1187
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1188
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1189
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
1559
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles4.overlay, onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { ...styles4.panel, width }, onClick: (e) => e.stopPropagation(), children: [
|
|
1560
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles4.header, children: [
|
|
1561
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles4.title, children: title }),
|
|
1562
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles4.closeBtn, onClick: onClose, children: "\u2715" })
|
|
1190
1563
|
] }),
|
|
1191
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1564
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles4.body, children })
|
|
1192
1565
|
] }) });
|
|
1193
1566
|
}
|
|
1194
|
-
var
|
|
1567
|
+
var styles4 = {
|
|
1195
1568
|
overlay: {
|
|
1196
1569
|
position: "fixed",
|
|
1197
1570
|
inset: 0,
|
|
@@ -1228,16 +1601,7 @@ var styles3 = {
|
|
|
1228
1601
|
},
|
|
1229
1602
|
body: { overflowY: "auto", padding: 20, color: "var(--wp-text)" }
|
|
1230
1603
|
};
|
|
1231
|
-
var
|
|
1232
|
-
{ type: "required", label: "Required", hasValue: false },
|
|
1233
|
-
{ type: "min", label: "Min value", hasValue: true },
|
|
1234
|
-
{ type: "max", label: "Max value", hasValue: true },
|
|
1235
|
-
{ type: "minLength", label: "Min length", hasValue: true },
|
|
1236
|
-
{ type: "maxLength", label: "Max length", hasValue: true },
|
|
1237
|
-
{ type: "email", label: "Email format", hasValue: false },
|
|
1238
|
-
{ type: "url", label: "URL format", hasValue: false },
|
|
1239
|
-
{ type: "regex", label: "Regex pattern", hasValue: true }
|
|
1240
|
-
];
|
|
1604
|
+
var ENUM_FIELD_TYPES = ["select", "multiselect", "radio"];
|
|
1241
1605
|
function FieldEditor() {
|
|
1242
1606
|
const {
|
|
1243
1607
|
schema,
|
|
@@ -1246,85 +1610,171 @@ function FieldEditor() {
|
|
|
1246
1610
|
updateField,
|
|
1247
1611
|
setFieldCondition
|
|
1248
1612
|
} = useBuilderStore();
|
|
1249
|
-
const
|
|
1613
|
+
const readOnly = useBuilderReadOnly();
|
|
1614
|
+
const externalEnums = useBuilderExternalEnums();
|
|
1250
1615
|
const [conditionModalOpen, setConditionModalOpen] = react.useState(false);
|
|
1616
|
+
const [validationModalOpen, setValidationModalOpen] = react.useState(false);
|
|
1617
|
+
const [dynDefaultModalOpen, setDynDefaultModalOpen] = react.useState(false);
|
|
1618
|
+
const [editingDynIdx, setEditingDynIdx] = react.useState(null);
|
|
1251
1619
|
const step = schema.steps.find((s) => s.id === selectedStepId);
|
|
1252
1620
|
const field = step?.fields.find((f) => f.id === selectedFieldId);
|
|
1253
1621
|
if (!field || !step) {
|
|
1254
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1622
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.empty, children: "Select a field in the middle panel to edit its properties." });
|
|
1255
1623
|
}
|
|
1256
1624
|
const validation = field.validation ?? [];
|
|
1257
1625
|
const isRequired = validation.some((v) => v.type === "required");
|
|
1258
1626
|
const hasCondition = !!field.visibleWhen;
|
|
1259
1627
|
const ruleCount = field.visibleWhen?.rules.length ?? 0;
|
|
1260
|
-
const
|
|
1261
|
-
|
|
1262
|
-
updateField(step.id, field.id, { validation: updated });
|
|
1263
|
-
};
|
|
1264
|
-
const removeValidationRule = (index) => {
|
|
1265
|
-
const updated = validation.filter((_, i) => i !== index);
|
|
1266
|
-
updateField(step.id, field.id, { validation: updated.length ? updated : void 0 });
|
|
1267
|
-
};
|
|
1268
|
-
const addValidationRule = () => {
|
|
1269
|
-
const newRule = {
|
|
1270
|
-
type: newValidationType,
|
|
1271
|
-
message: `${newValidationType} error`
|
|
1272
|
-
};
|
|
1273
|
-
updateField(step.id, field.id, { validation: [...validation, newRule] });
|
|
1628
|
+
const handleValidationChange = (rules) => {
|
|
1629
|
+
updateField(step.id, field.id, { validation: rules.length ? rules : void 0 });
|
|
1274
1630
|
};
|
|
1275
1631
|
const handleDependsOnChange = (paths) => {
|
|
1276
1632
|
updateField(step.id, field.id, { dependsOn: paths.length ? paths : void 0 });
|
|
1277
1633
|
};
|
|
1278
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1279
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1280
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1281
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1282
|
-
!isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1283
|
-
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1634
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.container, children: [
|
|
1635
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.header, children: [
|
|
1636
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.headerLeft, children: [
|
|
1637
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.headerTitle, children: "Field Editor" }),
|
|
1638
|
+
!isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.optionalBadge, children: "optional" }),
|
|
1639
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.requiredBadge, children: "required" })
|
|
1284
1640
|
] }),
|
|
1285
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1641
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.fieldId, children: [
|
|
1286
1642
|
"id: ",
|
|
1287
1643
|
field.id
|
|
1288
1644
|
] })
|
|
1289
1645
|
] }),
|
|
1290
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1291
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1292
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style:
|
|
1646
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.body, children: [
|
|
1647
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.group, children: [
|
|
1648
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles5.label, children: "Label" }),
|
|
1293
1649
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1294
1650
|
"input",
|
|
1295
1651
|
{
|
|
1296
|
-
style:
|
|
1652
|
+
style: styles5.input,
|
|
1297
1653
|
value: field.label,
|
|
1298
1654
|
onChange: (e) => updateField(step.id, field.id, { label: e.target.value })
|
|
1299
1655
|
}
|
|
1300
1656
|
)
|
|
1301
1657
|
] }),
|
|
1302
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1303
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style:
|
|
1658
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.group, children: [
|
|
1659
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles5.label, children: "Placeholder" }),
|
|
1304
1660
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1305
1661
|
"input",
|
|
1306
1662
|
{
|
|
1307
|
-
style:
|
|
1663
|
+
style: styles5.input,
|
|
1308
1664
|
value: field.placeholder ?? "",
|
|
1309
1665
|
placeholder: "Optional",
|
|
1310
1666
|
onChange: (e) => updateField(step.id, field.id, { placeholder: e.target.value || void 0 })
|
|
1311
1667
|
}
|
|
1312
1668
|
)
|
|
1313
1669
|
] }),
|
|
1314
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1315
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style:
|
|
1670
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.group, children: [
|
|
1671
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles5.label, children: "Default value" }),
|
|
1316
1672
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1317
1673
|
"input",
|
|
1318
1674
|
{
|
|
1319
|
-
style:
|
|
1675
|
+
style: styles5.input,
|
|
1320
1676
|
value: field.defaultValue != null ? String(field.defaultValue) : "",
|
|
1321
1677
|
placeholder: "Optional",
|
|
1322
1678
|
onChange: (e) => updateField(step.id, field.id, { defaultValue: e.target.value || void 0 })
|
|
1323
1679
|
}
|
|
1324
1680
|
)
|
|
1325
1681
|
] }),
|
|
1326
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1327
|
-
/* @__PURE__ */ jsxRuntime.
|
|
1682
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionRow, children: [
|
|
1683
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionInfo, children: [
|
|
1684
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.label, children: "Dynamic defaults" }),
|
|
1685
|
+
(field.dynamicDefault?.length ?? 0) > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: field.dynamicDefault.map((rule, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
1686
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.conditionBadge, children: [
|
|
1687
|
+
rule.when.rules.length,
|
|
1688
|
+
" rule",
|
|
1689
|
+
rule.when.rules.length !== 1 ? "s" : ""
|
|
1690
|
+
] }),
|
|
1691
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: { fontSize: 11, color: "var(--wp-text-subtle)" }, children: [
|
|
1692
|
+
"\u2192 ",
|
|
1693
|
+
JSON.stringify(rule.value)
|
|
1694
|
+
] }),
|
|
1695
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1696
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1697
|
+
"button",
|
|
1698
|
+
{
|
|
1699
|
+
style: { ...styles5.editConditionBtn, fontSize: 10, padding: "2px 6px" },
|
|
1700
|
+
onClick: () => {
|
|
1701
|
+
setEditingDynIdx(i);
|
|
1702
|
+
setDynDefaultModalOpen(true);
|
|
1703
|
+
},
|
|
1704
|
+
children: "Edit"
|
|
1705
|
+
}
|
|
1706
|
+
),
|
|
1707
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1708
|
+
"button",
|
|
1709
|
+
{
|
|
1710
|
+
style: { ...styles5.clearConditionBtn, fontSize: 10, padding: "2px 6px" },
|
|
1711
|
+
onClick: () => {
|
|
1712
|
+
const updated = field.dynamicDefault.filter((_, j) => j !== i);
|
|
1713
|
+
updateField(step.id, field.id, { dynamicDefault: updated.length ? updated : void 0 });
|
|
1714
|
+
},
|
|
1715
|
+
children: "\xD7"
|
|
1716
|
+
}
|
|
1717
|
+
)
|
|
1718
|
+
] })
|
|
1719
|
+
] }, i)) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.conditionNone, children: "No dynamic defaults" })
|
|
1720
|
+
] }),
|
|
1721
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.conditionActions, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1722
|
+
"button",
|
|
1723
|
+
{
|
|
1724
|
+
style: styles5.editConditionBtn,
|
|
1725
|
+
onClick: () => {
|
|
1726
|
+
setEditingDynIdx(null);
|
|
1727
|
+
setDynDefaultModalOpen(true);
|
|
1728
|
+
},
|
|
1729
|
+
children: "Add"
|
|
1730
|
+
}
|
|
1731
|
+
) })
|
|
1732
|
+
] }),
|
|
1733
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.divider }),
|
|
1734
|
+
ENUM_FIELD_TYPES.includes(field.type) && externalEnums.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.group, children: [
|
|
1735
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles5.label, children: "Options source" }),
|
|
1736
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
1737
|
+
"select",
|
|
1738
|
+
{
|
|
1739
|
+
style: styles5.input,
|
|
1740
|
+
disabled: readOnly,
|
|
1741
|
+
value: field.externalEnumId ?? "",
|
|
1742
|
+
onChange: (e) => {
|
|
1743
|
+
const enumId = e.target.value || void 0;
|
|
1744
|
+
updateField(step.id, field.id, {
|
|
1745
|
+
externalEnumId: enumId,
|
|
1746
|
+
// Clear hardcoded options when switching to an enum
|
|
1747
|
+
options: enumId ? void 0 : field.options
|
|
1748
|
+
});
|
|
1749
|
+
},
|
|
1750
|
+
children: [
|
|
1751
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u2014 Hardcoded options \u2014" }),
|
|
1752
|
+
externalEnums.map((en) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: en.id, children: [
|
|
1753
|
+
en.label,
|
|
1754
|
+
" (",
|
|
1755
|
+
en.values.length,
|
|
1756
|
+
" items)"
|
|
1757
|
+
] }, en.id))
|
|
1758
|
+
]
|
|
1759
|
+
}
|
|
1760
|
+
),
|
|
1761
|
+
field.externalEnumId && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.enumInfo, children: (() => {
|
|
1762
|
+
const en = externalEnums.find((e) => e.id === field.externalEnumId);
|
|
1763
|
+
return en ? /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.enumBadge, children: [
|
|
1764
|
+
"\u229E ",
|
|
1765
|
+
en.label,
|
|
1766
|
+
" \xB7 ",
|
|
1767
|
+
en.values.length,
|
|
1768
|
+
" options"
|
|
1769
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.enumMissing, children: [
|
|
1770
|
+
'\u26A0 Enum "',
|
|
1771
|
+
field.externalEnumId,
|
|
1772
|
+
'" not found'
|
|
1773
|
+
] });
|
|
1774
|
+
})() })
|
|
1775
|
+
] }),
|
|
1776
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.group, children: [
|
|
1777
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles5.label, children: "Depends on" }),
|
|
1328
1778
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1329
1779
|
DependsOnInput,
|
|
1330
1780
|
{
|
|
@@ -1335,92 +1785,101 @@ function FieldEditor() {
|
|
|
1335
1785
|
}
|
|
1336
1786
|
)
|
|
1337
1787
|
] }),
|
|
1338
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1339
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1340
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1341
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1342
|
-
hasCondition ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1343
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
1788
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.divider }),
|
|
1789
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionRow, children: [
|
|
1790
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionInfo, children: [
|
|
1791
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.label, children: "Visibility condition" }),
|
|
1792
|
+
hasCondition ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionSummary, children: [
|
|
1793
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.conditionBadge, children: [
|
|
1344
1794
|
ruleCount,
|
|
1345
1795
|
" rule",
|
|
1346
1796
|
ruleCount !== 1 ? "s" : "",
|
|
1347
1797
|
" \xB7 ",
|
|
1348
1798
|
field.visibleWhen.combinator.toUpperCase()
|
|
1349
1799
|
] }),
|
|
1350
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
1351
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1800
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.conditionDesc, children: "Field is conditional" })
|
|
1801
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.conditionNone, children: "Always visible" })
|
|
1352
1802
|
] }),
|
|
1353
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1354
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
1803
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionActions, children: [
|
|
1804
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles5.editConditionBtn, onClick: () => setConditionModalOpen(true), children: hasCondition ? "Edit" : "Add" }),
|
|
1355
1805
|
hasCondition && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1356
1806
|
"button",
|
|
1357
1807
|
{
|
|
1358
|
-
style:
|
|
1808
|
+
style: styles5.clearConditionBtn,
|
|
1359
1809
|
onClick: () => setFieldCondition(step.id, field.id, void 0),
|
|
1360
1810
|
children: "Clear"
|
|
1361
1811
|
}
|
|
1362
1812
|
)
|
|
1363
1813
|
] })
|
|
1364
1814
|
] }),
|
|
1365
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1366
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1367
|
-
"
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
"input",
|
|
1391
|
-
{
|
|
1392
|
-
style: styles4.ruleInput,
|
|
1393
|
-
value: rule.value != null ? String(rule.value) : "",
|
|
1394
|
-
onChange: (e) => updateValidationRule(index, { value: e.target.value })
|
|
1395
|
-
}
|
|
1396
|
-
)
|
|
1397
|
-
] }),
|
|
1398
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles4.ruleRow, children: [
|
|
1399
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles4.ruleLabel, children: "Error message" }),
|
|
1400
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1401
|
-
"input",
|
|
1402
|
-
{
|
|
1403
|
-
style: styles4.ruleInput,
|
|
1404
|
-
value: rule.message,
|
|
1405
|
-
onChange: (e) => updateValidationRule(index, { message: e.target.value })
|
|
1406
|
-
}
|
|
1407
|
-
)
|
|
1408
|
-
] })
|
|
1409
|
-
] }, index);
|
|
1410
|
-
}),
|
|
1411
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles4.addRule, children: [
|
|
1412
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1413
|
-
"select",
|
|
1414
|
-
{
|
|
1415
|
-
style: styles4.ruleSelect,
|
|
1416
|
-
value: newValidationType,
|
|
1417
|
-
onChange: (e) => setNewValidationType(e.target.value),
|
|
1418
|
-
children: VALIDATION_TYPES.map((vt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: vt.type, children: vt.label }, vt.type))
|
|
1419
|
-
}
|
|
1420
|
-
),
|
|
1421
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles4.addRuleBtn, onClick: addValidationRule, children: "+ Add rule" })
|
|
1815
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.divider }),
|
|
1816
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionRow, children: [
|
|
1817
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionInfo, children: [
|
|
1818
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.label, children: "Validation" }),
|
|
1819
|
+
validation.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionSummary, children: [
|
|
1820
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles5.validationBadge, children: [
|
|
1821
|
+
validation.length,
|
|
1822
|
+
" rule",
|
|
1823
|
+
validation.length !== 1 ? "s" : "",
|
|
1824
|
+
isRequired ? " \xB7 required" : ""
|
|
1825
|
+
] }),
|
|
1826
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles5.conditionDesc, children: validation.map((r) => r.type).join(", ") })
|
|
1827
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.conditionNone, children: "No rules \xB7 field is optional" })
|
|
1828
|
+
] }),
|
|
1829
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles5.conditionActions, children: [
|
|
1830
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles5.editConditionBtn, onClick: () => setValidationModalOpen(true), children: validation.length > 0 ? "Edit" : "Add" }),
|
|
1831
|
+
validation.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1832
|
+
"button",
|
|
1833
|
+
{
|
|
1834
|
+
style: styles5.clearConditionBtn,
|
|
1835
|
+
onClick: () => updateField(step.id, field.id, { validation: void 0 }),
|
|
1836
|
+
children: "Clear"
|
|
1837
|
+
}
|
|
1838
|
+
)
|
|
1839
|
+
] })
|
|
1422
1840
|
] })
|
|
1423
1841
|
] }),
|
|
1842
|
+
validationModalOpen && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1843
|
+
Modal,
|
|
1844
|
+
{
|
|
1845
|
+
title: `Validation \u2014 "${field.label}"`,
|
|
1846
|
+
onClose: () => setValidationModalOpen(false),
|
|
1847
|
+
width: 680,
|
|
1848
|
+
children: [
|
|
1849
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles5.modalHint, children: "Define validation rules for this field. All rules must pass for the field to be valid." }),
|
|
1850
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1851
|
+
ValidationBuilder,
|
|
1852
|
+
{
|
|
1853
|
+
value: validation,
|
|
1854
|
+
onChange: handleValidationChange
|
|
1855
|
+
}
|
|
1856
|
+
),
|
|
1857
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.modalFooter, children: /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles5.modalCloseBtn, onClick: () => setValidationModalOpen(false), children: "Done" }) })
|
|
1858
|
+
]
|
|
1859
|
+
}
|
|
1860
|
+
),
|
|
1861
|
+
dynDefaultModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1862
|
+
DynDefaultModal,
|
|
1863
|
+
{
|
|
1864
|
+
rule: editingDynIdx !== null ? field.dynamicDefault?.[editingDynIdx] : void 0,
|
|
1865
|
+
onSave: (rule) => {
|
|
1866
|
+
const current = field.dynamicDefault ?? [];
|
|
1867
|
+
let updated;
|
|
1868
|
+
if (editingDynIdx !== null) {
|
|
1869
|
+
updated = current.map((r, i) => i === editingDynIdx ? rule : r);
|
|
1870
|
+
} else {
|
|
1871
|
+
updated = [...current, rule];
|
|
1872
|
+
}
|
|
1873
|
+
updateField(step.id, field.id, { dynamicDefault: updated });
|
|
1874
|
+
setDynDefaultModalOpen(false);
|
|
1875
|
+
setEditingDynIdx(null);
|
|
1876
|
+
},
|
|
1877
|
+
onClose: () => {
|
|
1878
|
+
setDynDefaultModalOpen(false);
|
|
1879
|
+
setEditingDynIdx(null);
|
|
1880
|
+
}
|
|
1881
|
+
}
|
|
1882
|
+
),
|
|
1424
1883
|
conditionModalOpen && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1425
1884
|
Modal,
|
|
1426
1885
|
{
|
|
@@ -1428,7 +1887,7 @@ function FieldEditor() {
|
|
|
1428
1887
|
onClose: () => setConditionModalOpen(false),
|
|
1429
1888
|
width: 620,
|
|
1430
1889
|
children: [
|
|
1431
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
1890
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles5.modalHint, children: "Define when this field is visible within its step." }),
|
|
1432
1891
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1433
1892
|
ConditionBuilder,
|
|
1434
1893
|
{
|
|
@@ -1438,13 +1897,103 @@ function FieldEditor() {
|
|
|
1438
1897
|
excludeFieldId: field.id
|
|
1439
1898
|
}
|
|
1440
1899
|
),
|
|
1441
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1900
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles5.modalFooter, children: /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles5.modalCloseBtn, onClick: () => setConditionModalOpen(false), children: "Done" }) })
|
|
1442
1901
|
]
|
|
1443
1902
|
}
|
|
1444
1903
|
)
|
|
1445
1904
|
] });
|
|
1446
1905
|
}
|
|
1447
|
-
|
|
1906
|
+
function DynDefaultModal({
|
|
1907
|
+
rule,
|
|
1908
|
+
onSave,
|
|
1909
|
+
onClose
|
|
1910
|
+
}) {
|
|
1911
|
+
const [condition, setCondition] = react.useState(rule?.when);
|
|
1912
|
+
const [value, setValue] = react.useState(rule?.value != null ? String(rule.value) : "");
|
|
1913
|
+
const canSave = condition && condition.rules.length > 0 && value !== "";
|
|
1914
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1915
|
+
Modal,
|
|
1916
|
+
{
|
|
1917
|
+
title: rule ? "Edit dynamic default" : "Add dynamic default",
|
|
1918
|
+
onClose,
|
|
1919
|
+
width: 620,
|
|
1920
|
+
children: [
|
|
1921
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: 13, color: "var(--wp-text-muted)", margin: "0 0 16px" }, children: "When the condition matches, this value will be used as the field default." }),
|
|
1922
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 16 }, children: [
|
|
1923
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 600, color: "var(--wp-text-muted)", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 6 }, children: "Condition" }),
|
|
1924
|
+
/* @__PURE__ */ jsxRuntime.jsx(ConditionBuilder, { value: condition, onChange: setCondition })
|
|
1925
|
+
] }),
|
|
1926
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 20 }, children: [
|
|
1927
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 11, fontWeight: 600, color: "var(--wp-text-muted)", textTransform: "uppercase", letterSpacing: "0.05em", marginBottom: 6 }, children: "Default value when condition matches" }),
|
|
1928
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1929
|
+
"input",
|
|
1930
|
+
{
|
|
1931
|
+
style: {
|
|
1932
|
+
fontSize: 13,
|
|
1933
|
+
padding: "6px 8px",
|
|
1934
|
+
border: "1px solid var(--wp-border-muted)",
|
|
1935
|
+
borderRadius: "var(--wp-radius)",
|
|
1936
|
+
outline: "none",
|
|
1937
|
+
width: "100%",
|
|
1938
|
+
boxSizing: "border-box",
|
|
1939
|
+
background: "var(--wp-canvas)",
|
|
1940
|
+
color: "var(--wp-text)"
|
|
1941
|
+
},
|
|
1942
|
+
value,
|
|
1943
|
+
placeholder: "Value to set as default",
|
|
1944
|
+
onChange: (e) => setValue(e.target.value)
|
|
1945
|
+
}
|
|
1946
|
+
)
|
|
1947
|
+
] }),
|
|
1948
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "flex-end", gap: 8 }, children: [
|
|
1949
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1950
|
+
"button",
|
|
1951
|
+
{
|
|
1952
|
+
style: {
|
|
1953
|
+
fontSize: 13,
|
|
1954
|
+
padding: "7px 16px",
|
|
1955
|
+
background: "transparent",
|
|
1956
|
+
color: "var(--wp-text-muted)",
|
|
1957
|
+
border: "1px solid var(--wp-border)",
|
|
1958
|
+
borderRadius: "var(--wp-radius-lg)",
|
|
1959
|
+
cursor: "pointer"
|
|
1960
|
+
},
|
|
1961
|
+
onClick: onClose,
|
|
1962
|
+
children: "Cancel"
|
|
1963
|
+
}
|
|
1964
|
+
),
|
|
1965
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1966
|
+
"button",
|
|
1967
|
+
{
|
|
1968
|
+
disabled: !canSave,
|
|
1969
|
+
style: {
|
|
1970
|
+
fontSize: 13,
|
|
1971
|
+
padding: "7px 20px",
|
|
1972
|
+
background: canSave ? "var(--wp-primary)" : "var(--wp-border)",
|
|
1973
|
+
color: "var(--wp-canvas)",
|
|
1974
|
+
border: "none",
|
|
1975
|
+
borderRadius: "var(--wp-radius-lg)",
|
|
1976
|
+
cursor: canSave ? "pointer" : "not-allowed",
|
|
1977
|
+
fontWeight: 600,
|
|
1978
|
+
opacity: canSave ? 1 : 0.5
|
|
1979
|
+
},
|
|
1980
|
+
onClick: () => {
|
|
1981
|
+
if (!canSave || !condition) return;
|
|
1982
|
+
let parsed = value;
|
|
1983
|
+
if (value === "true") parsed = true;
|
|
1984
|
+
else if (value === "false") parsed = false;
|
|
1985
|
+
else if (!isNaN(Number(value)) && value.trim() !== "") parsed = Number(value);
|
|
1986
|
+
onSave({ when: condition, value: parsed });
|
|
1987
|
+
},
|
|
1988
|
+
children: rule ? "Update" : "Add"
|
|
1989
|
+
}
|
|
1990
|
+
)
|
|
1991
|
+
] })
|
|
1992
|
+
]
|
|
1993
|
+
}
|
|
1994
|
+
);
|
|
1995
|
+
}
|
|
1996
|
+
var styles5 = {
|
|
1448
1997
|
container: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" },
|
|
1449
1998
|
empty: {
|
|
1450
1999
|
display: "flex",
|
|
@@ -1528,60 +2077,30 @@ var styles4 = {
|
|
|
1528
2077
|
borderRadius: "var(--wp-radius)",
|
|
1529
2078
|
cursor: "pointer"
|
|
1530
2079
|
},
|
|
1531
|
-
|
|
1532
|
-
optionalHint: { fontSize: 10, color: "var(--wp-text-subtle)", fontWeight: 400, textTransform: "none", letterSpacing: 0 },
|
|
1533
|
-
noRules: { fontSize: 12, color: "var(--wp-text-subtle)" },
|
|
1534
|
-
ruleCard: {
|
|
1535
|
-
background: "var(--wp-surface)",
|
|
1536
|
-
border: "1px solid var(--wp-border)",
|
|
1537
|
-
borderRadius: "var(--wp-radius-lg)",
|
|
1538
|
-
padding: 10,
|
|
1539
|
-
display: "flex",
|
|
1540
|
-
flexDirection: "column",
|
|
1541
|
-
gap: 8
|
|
1542
|
-
},
|
|
1543
|
-
ruleHeader: { display: "flex", justifyContent: "space-between", alignItems: "center" },
|
|
1544
|
-
ruleBadge: {
|
|
2080
|
+
validationBadge: {
|
|
1545
2081
|
fontSize: 11,
|
|
1546
2082
|
fontWeight: 700,
|
|
1547
|
-
color: "var(--wp-primary-dark)",
|
|
1548
2083
|
background: "var(--wp-primary-bg)",
|
|
2084
|
+
color: "var(--wp-primary-dark)",
|
|
1549
2085
|
padding: "2px 8px",
|
|
1550
|
-
borderRadius: 4
|
|
1551
|
-
},
|
|
1552
|
-
requiredRuleBadge: { background: "var(--wp-danger-bg-strong)", color: "var(--wp-danger)" },
|
|
1553
|
-
removeRuleBtn: { border: "none", background: "transparent", color: "var(--wp-danger)", cursor: "pointer", fontSize: 12 },
|
|
1554
|
-
ruleRow: { display: "flex", flexDirection: "column", gap: 3 },
|
|
1555
|
-
ruleLabel: { fontSize: 10, fontWeight: 600, color: "var(--wp-text-subtle)", textTransform: "uppercase" },
|
|
1556
|
-
ruleInput: {
|
|
1557
|
-
fontSize: 12,
|
|
1558
|
-
padding: "4px 6px",
|
|
1559
|
-
border: "1px solid var(--wp-border-muted)",
|
|
1560
|
-
borderRadius: 4,
|
|
1561
|
-
outline: "none",
|
|
1562
|
-
background: "var(--wp-canvas)",
|
|
1563
|
-
color: "var(--wp-text)"
|
|
1564
|
-
},
|
|
1565
|
-
addRule: { display: "flex", gap: 8, alignItems: "center" },
|
|
1566
|
-
ruleSelect: {
|
|
1567
|
-
flex: 1,
|
|
1568
|
-
fontSize: 12,
|
|
1569
|
-
padding: "5px 6px",
|
|
1570
|
-
border: "1px solid var(--wp-border-muted)",
|
|
1571
|
-
borderRadius: "var(--wp-radius)",
|
|
1572
|
-
background: "var(--wp-canvas)",
|
|
1573
|
-
color: "var(--wp-text)"
|
|
2086
|
+
borderRadius: 4
|
|
1574
2087
|
},
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
2088
|
+
enumInfo: { marginTop: 4 },
|
|
2089
|
+
enumBadge: {
|
|
2090
|
+
fontSize: 11,
|
|
2091
|
+
fontWeight: 600,
|
|
2092
|
+
padding: "2px 8px",
|
|
2093
|
+
background: "var(--wp-info-bg)",
|
|
2094
|
+
color: "var(--wp-info-text)",
|
|
2095
|
+
borderRadius: 4
|
|
2096
|
+
},
|
|
2097
|
+
enumMissing: {
|
|
2098
|
+
fontSize: 11,
|
|
2099
|
+
fontWeight: 600,
|
|
2100
|
+
padding: "2px 8px",
|
|
2101
|
+
background: "var(--wp-warning-bg)",
|
|
2102
|
+
color: "var(--wp-warning)",
|
|
2103
|
+
borderRadius: 4
|
|
1585
2104
|
},
|
|
1586
2105
|
modalHint: { fontSize: 13, color: "var(--wp-text-muted)", marginBottom: 16, marginTop: 0 },
|
|
1587
2106
|
modalFooter: { marginTop: 20, display: "flex", justifyContent: "flex-end" },
|
|
@@ -1693,6 +2212,107 @@ function getStepDependencyLabels(stepId, deps, schema) {
|
|
|
1693
2212
|
const required = deps.get(stepId) ?? /* @__PURE__ */ new Set();
|
|
1694
2213
|
return [...required].map((id) => schema.steps.find((s) => s.id === id)?.title ?? id).filter(Boolean);
|
|
1695
2214
|
}
|
|
2215
|
+
function SortableItem({ id, disabled, children }) {
|
|
2216
|
+
const {
|
|
2217
|
+
attributes,
|
|
2218
|
+
listeners,
|
|
2219
|
+
setNodeRef,
|
|
2220
|
+
transform,
|
|
2221
|
+
transition,
|
|
2222
|
+
isDragging
|
|
2223
|
+
} = sortable.useSortable({ id, disabled });
|
|
2224
|
+
const style = {
|
|
2225
|
+
transform: utilities.CSS.Transform.toString(transform),
|
|
2226
|
+
transition,
|
|
2227
|
+
opacity: isDragging ? 0.4 : 1,
|
|
2228
|
+
position: "relative"
|
|
2229
|
+
};
|
|
2230
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: setNodeRef, style, children: children({
|
|
2231
|
+
handleProps: { ...attributes, ...listeners },
|
|
2232
|
+
isDragging
|
|
2233
|
+
}) });
|
|
2234
|
+
}
|
|
2235
|
+
function DragHandle({ handleProps, disabled }) {
|
|
2236
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2237
|
+
"button",
|
|
2238
|
+
{
|
|
2239
|
+
type: "button",
|
|
2240
|
+
...handleProps,
|
|
2241
|
+
style: {
|
|
2242
|
+
...dragHandleStyle,
|
|
2243
|
+
...disabled ? dragHandleDisabledStyle : {}
|
|
2244
|
+
},
|
|
2245
|
+
title: "Drag to reorder",
|
|
2246
|
+
"aria-label": "Drag handle",
|
|
2247
|
+
children: "\u283F"
|
|
2248
|
+
}
|
|
2249
|
+
);
|
|
2250
|
+
}
|
|
2251
|
+
var dragHandleStyle = {
|
|
2252
|
+
cursor: "grab",
|
|
2253
|
+
touchAction: "none",
|
|
2254
|
+
border: "none",
|
|
2255
|
+
background: "transparent",
|
|
2256
|
+
color: "var(--wp-text-muted)",
|
|
2257
|
+
fontSize: 16,
|
|
2258
|
+
padding: "2px 4px",
|
|
2259
|
+
borderRadius: 4,
|
|
2260
|
+
display: "flex",
|
|
2261
|
+
alignItems: "center",
|
|
2262
|
+
justifyContent: "center",
|
|
2263
|
+
flexShrink: 0,
|
|
2264
|
+
lineHeight: 1
|
|
2265
|
+
};
|
|
2266
|
+
var dragHandleDisabledStyle = {
|
|
2267
|
+
cursor: "not-allowed",
|
|
2268
|
+
opacity: 0.3
|
|
2269
|
+
};
|
|
2270
|
+
function SortableList({
|
|
2271
|
+
items,
|
|
2272
|
+
disabled,
|
|
2273
|
+
onReorder,
|
|
2274
|
+
renderItem,
|
|
2275
|
+
renderOverlay
|
|
2276
|
+
}) {
|
|
2277
|
+
const [activeId, setActiveId] = react.useState(null);
|
|
2278
|
+
const sensors = core$1.useSensors(
|
|
2279
|
+
core$1.useSensor(core$1.PointerSensor, { activationConstraint: { distance: 8 } }),
|
|
2280
|
+
core$1.useSensor(core$1.TouchSensor, { activationConstraint: { delay: 150, tolerance: 5 } }),
|
|
2281
|
+
core$1.useSensor(core$1.KeyboardSensor)
|
|
2282
|
+
);
|
|
2283
|
+
const handleDragStart = react.useCallback((event) => {
|
|
2284
|
+
setActiveId(String(event.active.id));
|
|
2285
|
+
}, []);
|
|
2286
|
+
const handleDragEnd = react.useCallback(
|
|
2287
|
+
(event) => {
|
|
2288
|
+
setActiveId(null);
|
|
2289
|
+
const { active, over } = event;
|
|
2290
|
+
if (!over || active.id === over.id) return;
|
|
2291
|
+
const fromIndex = items.indexOf(String(active.id));
|
|
2292
|
+
const toIndex = items.indexOf(String(over.id));
|
|
2293
|
+
if (fromIndex === -1 || toIndex === -1) return;
|
|
2294
|
+
onReorder(fromIndex, toIndex);
|
|
2295
|
+
},
|
|
2296
|
+
[items, onReorder]
|
|
2297
|
+
);
|
|
2298
|
+
const handleDragCancel = react.useCallback(() => {
|
|
2299
|
+
setActiveId(null);
|
|
2300
|
+
}, []);
|
|
2301
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2302
|
+
core$1.DndContext,
|
|
2303
|
+
{
|
|
2304
|
+
sensors,
|
|
2305
|
+
collisionDetection: core$1.closestCenter,
|
|
2306
|
+
onDragStart: handleDragStart,
|
|
2307
|
+
onDragEnd: handleDragEnd,
|
|
2308
|
+
onDragCancel: handleDragCancel,
|
|
2309
|
+
children: [
|
|
2310
|
+
/* @__PURE__ */ jsxRuntime.jsx(sortable.SortableContext, { items, strategy: sortable.verticalListSortingStrategy, disabled, children: items.map((id, index) => renderItem(id, index)) }),
|
|
2311
|
+
/* @__PURE__ */ jsxRuntime.jsx(core$1.DragOverlay, { dropAnimation: null, children: activeId && renderOverlay ? renderOverlay(activeId) : null })
|
|
2312
|
+
]
|
|
2313
|
+
}
|
|
2314
|
+
);
|
|
2315
|
+
}
|
|
1696
2316
|
var FIELD_TYPES = [
|
|
1697
2317
|
"text",
|
|
1698
2318
|
"number",
|
|
@@ -1715,10 +2335,14 @@ function FieldList() {
|
|
|
1715
2335
|
selectedFieldId,
|
|
1716
2336
|
addField,
|
|
1717
2337
|
removeField,
|
|
2338
|
+
duplicateField,
|
|
1718
2339
|
updateField,
|
|
1719
2340
|
selectField,
|
|
1720
2341
|
reorderFields
|
|
1721
2342
|
} = useBuilderStore();
|
|
2343
|
+
const readOnly = useBuilderReadOnly();
|
|
2344
|
+
const appCustomTypes = useBuilderCustomTypes();
|
|
2345
|
+
const externalEnums = useBuilderExternalEnums();
|
|
1722
2346
|
const [moveError, setMoveError] = react.useState(null);
|
|
1723
2347
|
const step = schema.steps.find((s) => s.id === selectedStepId);
|
|
1724
2348
|
const allDependencyTargets = /* @__PURE__ */ new Set();
|
|
@@ -1730,7 +2354,7 @@ function FieldList() {
|
|
|
1730
2354
|
}
|
|
1731
2355
|
}
|
|
1732
2356
|
if (!step) {
|
|
1733
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
2357
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.empty, children: "Select a step on the left to manage its fields." });
|
|
1734
2358
|
}
|
|
1735
2359
|
const tryMove = (fromIndex, toIndex) => {
|
|
1736
2360
|
const check = isFieldMoveValid(step.fields, step.id, fromIndex, toIndex);
|
|
@@ -1742,127 +2366,180 @@ function FieldList() {
|
|
|
1742
2366
|
setMoveError(null);
|
|
1743
2367
|
reorderFields(step.id, fromIndex, toIndex);
|
|
1744
2368
|
};
|
|
1745
|
-
|
|
1746
|
-
|
|
2369
|
+
const fieldIds = step.fields.map((f) => f.id);
|
|
2370
|
+
const renderOverlay = (id) => {
|
|
2371
|
+
const field = step.fields.find((f) => f.id === id);
|
|
2372
|
+
if (!field) return null;
|
|
2373
|
+
const ct = appCustomTypes.find((c) => c.id === field.type);
|
|
2374
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...styles6.card, ...styles6.cardDragOverlay }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.cardTop, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.cardLeft, children: [
|
|
2375
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles6.typeBadge, ...ct ? styles6.typeBadgeCustom : {} }, children: ct ? `${ct.icon ? ct.icon + " " : ""}${ct.label}` : field.type }),
|
|
2376
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.fieldLabel, children: field.label })
|
|
2377
|
+
] }) }) });
|
|
2378
|
+
};
|
|
2379
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.container, children: [
|
|
2380
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.header, children: [
|
|
1747
2381
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
1748
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1749
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2382
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.stepTitle, children: step.title }),
|
|
2383
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.stepSub, children: [
|
|
1750
2384
|
step.fields.length,
|
|
1751
2385
|
" field",
|
|
1752
2386
|
step.fields.length !== 1 ? "s" : ""
|
|
1753
2387
|
] })
|
|
1754
2388
|
] }),
|
|
1755
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
2389
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles6.addBtn, onClick: () => addField(step.id), children: "+ Add field" })
|
|
1756
2390
|
] }),
|
|
1757
|
-
moveError && /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2391
|
+
moveError && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.errorBanner, children: [
|
|
1758
2392
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u26A0" }),
|
|
1759
2393
|
" ",
|
|
1760
2394
|
moveError
|
|
1761
2395
|
] }),
|
|
1762
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
1763
|
-
step.fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
{
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
2396
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.list, children: [
|
|
2397
|
+
step.fields.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.emptyFields, children: 'No fields yet. Click "Add field" to start.' }),
|
|
2398
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2399
|
+
SortableList,
|
|
2400
|
+
{
|
|
2401
|
+
items: fieldIds,
|
|
2402
|
+
disabled: readOnly,
|
|
2403
|
+
onReorder: tryMove,
|
|
2404
|
+
renderOverlay,
|
|
2405
|
+
renderItem: (id, index) => {
|
|
2406
|
+
const field = step.fields[index];
|
|
2407
|
+
const isSelected = field.id === selectedFieldId;
|
|
2408
|
+
const isRequired = field.validation?.some((v) => v.type === "required") ?? false;
|
|
2409
|
+
const hasCondition = !!field.visibleWhen;
|
|
2410
|
+
const hasDeps = (field.dependsOn?.length ?? 0) > 0;
|
|
2411
|
+
const enumDef = field.externalEnumId ? externalEnums.find((e) => e.id === field.externalEnumId) : void 0;
|
|
2412
|
+
const isUsedAsDep = allDependencyTargets.has(`${step.id}.${field.id}`);
|
|
2413
|
+
const canMoveUp = index > 0 && isFieldMoveValid(step.fields, step.id, index, index - 1).valid;
|
|
2414
|
+
const canMoveDown = index < step.fields.length - 1 && isFieldMoveValid(step.fields, step.id, index, index + 1).valid;
|
|
2415
|
+
const intraStepDeps = (field.dependsOn ?? []).filter((p) => p.startsWith(`${step.id}.`)).map((p) => {
|
|
2416
|
+
const fieldId = p.slice(step.id.length + 1);
|
|
2417
|
+
return step.fields.find((f) => f.id === fieldId)?.label ?? fieldId;
|
|
2418
|
+
});
|
|
2419
|
+
const intraStepDependents = step.fields.filter(
|
|
2420
|
+
(f) => f.id !== field.id && (f.dependsOn ?? []).includes(`${step.id}.${field.id}`)
|
|
2421
|
+
);
|
|
2422
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SortableItem, { id: field.id, disabled: readOnly, children: ({ handleProps }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2423
|
+
"div",
|
|
2424
|
+
{
|
|
2425
|
+
style: { ...styles6.card, ...isSelected ? styles6.cardSelected : {} },
|
|
2426
|
+
onClick: () => selectField(field.id),
|
|
2427
|
+
children: [
|
|
2428
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.cardTop, children: [
|
|
2429
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.cardLeft, children: [
|
|
2430
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(DragHandle, { handleProps }),
|
|
2431
|
+
(() => {
|
|
2432
|
+
const ct = appCustomTypes.find((c) => c.id === field.type);
|
|
2433
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles6.typeBadge, ...ct ? styles6.typeBadgeCustom : {} }, children: ct ? `${ct.icon ? ct.icon + " " : ""}${ct.label}` : field.type });
|
|
2434
|
+
})(),
|
|
2435
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.fieldLabel, children: field.label })
|
|
2436
|
+
] }),
|
|
2437
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.cardRight, children: [
|
|
2438
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2439
|
+
"select",
|
|
2440
|
+
{
|
|
2441
|
+
style: styles6.typeSelect,
|
|
2442
|
+
value: field.type,
|
|
2443
|
+
onClick: (e) => e.stopPropagation(),
|
|
2444
|
+
onChange: (e) => {
|
|
2445
|
+
const newType = e.target.value;
|
|
2446
|
+
const customType = appCustomTypes.find((ct) => ct.id === newType);
|
|
2447
|
+
updateField(step.id, field.id, {
|
|
2448
|
+
type: newType,
|
|
2449
|
+
...customType?.defaultValidation ? { validation: customType.defaultValidation } : {}
|
|
2450
|
+
});
|
|
2451
|
+
},
|
|
2452
|
+
children: [
|
|
2453
|
+
FIELD_TYPES.map((t) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: t, children: t }, t)),
|
|
2454
|
+
appCustomTypes.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("optgroup", { label: "Custom", children: appCustomTypes.map((ct) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: ct.id, children: [
|
|
2455
|
+
ct.icon ? `${ct.icon} ` : "",
|
|
2456
|
+
ct.label
|
|
2457
|
+
] }, ct.id)) })
|
|
2458
|
+
]
|
|
2459
|
+
}
|
|
2460
|
+
),
|
|
2461
|
+
!readOnly && index > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2462
|
+
"button",
|
|
2463
|
+
{
|
|
2464
|
+
style: { ...styles6.iconBtn, ...canMoveUp ? {} : styles6.iconBtnBlocked },
|
|
2465
|
+
title: canMoveUp ? "Move up" : "Can't move \u2014 dependency order required",
|
|
2466
|
+
onClick: (e) => {
|
|
2467
|
+
e.stopPropagation();
|
|
2468
|
+
tryMove(index, index - 1);
|
|
2469
|
+
},
|
|
2470
|
+
children: "\u2191"
|
|
2471
|
+
}
|
|
2472
|
+
),
|
|
2473
|
+
!readOnly && index < step.fields.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2474
|
+
"button",
|
|
2475
|
+
{
|
|
2476
|
+
style: { ...styles6.iconBtn, ...canMoveDown ? {} : styles6.iconBtnBlocked },
|
|
2477
|
+
title: canMoveDown ? "Move down" : "Can't move \u2014 dependency order required",
|
|
2478
|
+
onClick: (e) => {
|
|
2479
|
+
e.stopPropagation();
|
|
2480
|
+
tryMove(index, index + 1);
|
|
2481
|
+
},
|
|
2482
|
+
children: "\u2193"
|
|
2483
|
+
}
|
|
2484
|
+
),
|
|
2485
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2486
|
+
"button",
|
|
2487
|
+
{
|
|
2488
|
+
style: styles6.iconBtn,
|
|
2489
|
+
title: "Duplicate field",
|
|
2490
|
+
onClick: (e) => {
|
|
2491
|
+
e.stopPropagation();
|
|
2492
|
+
duplicateField(step.id, field.id);
|
|
2493
|
+
},
|
|
2494
|
+
children: "\u29C9"
|
|
2495
|
+
}
|
|
2496
|
+
),
|
|
2497
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2498
|
+
"button",
|
|
2499
|
+
{
|
|
2500
|
+
style: { ...styles6.iconBtn, color: "var(--wp-danger)" },
|
|
2501
|
+
title: "Remove field",
|
|
2502
|
+
onClick: (e) => {
|
|
2503
|
+
e.stopPropagation();
|
|
2504
|
+
removeField(step.id, field.id);
|
|
2505
|
+
},
|
|
2506
|
+
children: "\u2715"
|
|
2507
|
+
}
|
|
2508
|
+
)
|
|
2509
|
+
] })
|
|
2510
|
+
] }),
|
|
2511
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.badges, children: [
|
|
2512
|
+
!isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.badgeOptional, children: "optional" }),
|
|
2513
|
+
isRequired && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.badgeRequired, children: "required" }),
|
|
2514
|
+
hasCondition && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.badgeCondition, children: "conditional" }),
|
|
2515
|
+
hasDeps && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles6.badgeDep, children: [
|
|
2516
|
+
"depends on ",
|
|
2517
|
+
field.dependsOn.length
|
|
2518
|
+
] }),
|
|
2519
|
+
isUsedAsDep && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.badgeUsed, children: "\u2190 dependency" }),
|
|
2520
|
+
field.externalEnumId && /* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles6.badgeEnum, children: [
|
|
2521
|
+
"\u229E ",
|
|
2522
|
+
enumDef ? enumDef.label : field.externalEnumId
|
|
2523
|
+
] })
|
|
2524
|
+
] }),
|
|
2525
|
+
intraStepDeps.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.depRow, children: [
|
|
2526
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.depLabel, children: "needs:" }),
|
|
2527
|
+
intraStepDeps.map((label) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.depBadge, children: label }, label))
|
|
2528
|
+
] }),
|
|
2529
|
+
intraStepDependents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.depRow, children: [
|
|
2530
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.depLabelUsed, children: "used by:" }),
|
|
2531
|
+
intraStepDependents.map((f) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles6.depBadgeUsed, children: f.label }, f.id))
|
|
2532
|
+
] })
|
|
2533
|
+
]
|
|
2534
|
+
}
|
|
2535
|
+
) }, field.id);
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
)
|
|
1862
2539
|
] })
|
|
1863
2540
|
] });
|
|
1864
2541
|
}
|
|
1865
|
-
var
|
|
2542
|
+
var styles6 = {
|
|
1866
2543
|
container: { display: "flex", flexDirection: "column", height: "100%" },
|
|
1867
2544
|
empty: {
|
|
1868
2545
|
display: "flex",
|
|
@@ -1919,6 +2596,12 @@ var styles5 = {
|
|
|
1919
2596
|
gap: 6
|
|
1920
2597
|
},
|
|
1921
2598
|
cardSelected: { background: "var(--wp-primary-muted)", border: "1px solid var(--wp-primary-border)" },
|
|
2599
|
+
cardDragOverlay: {
|
|
2600
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.25)",
|
|
2601
|
+
border: "1px solid var(--wp-primary-border)",
|
|
2602
|
+
background: "var(--wp-surface)",
|
|
2603
|
+
opacity: 0.95
|
|
2604
|
+
},
|
|
1922
2605
|
cardTop: { display: "flex", alignItems: "center", justifyContent: "space-between" },
|
|
1923
2606
|
cardLeft: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 },
|
|
1924
2607
|
cardRight: { display: "flex", alignItems: "center", gap: 4, flexShrink: 0 },
|
|
@@ -1931,6 +2614,10 @@ var styles5 = {
|
|
|
1931
2614
|
fontWeight: 600,
|
|
1932
2615
|
flexShrink: 0
|
|
1933
2616
|
},
|
|
2617
|
+
typeBadgeCustom: {
|
|
2618
|
+
background: "var(--wp-success-bg)",
|
|
2619
|
+
color: "var(--wp-success)"
|
|
2620
|
+
},
|
|
1934
2621
|
fieldLabel: {
|
|
1935
2622
|
fontSize: 13,
|
|
1936
2623
|
fontWeight: 600,
|
|
@@ -2005,6 +2692,14 @@ var styles5 = {
|
|
|
2005
2692
|
borderRadius: 3,
|
|
2006
2693
|
textTransform: "uppercase"
|
|
2007
2694
|
},
|
|
2695
|
+
badgeEnum: {
|
|
2696
|
+
fontSize: 9,
|
|
2697
|
+
fontWeight: 600,
|
|
2698
|
+
padding: "1px 6px",
|
|
2699
|
+
background: "var(--wp-info-bg)",
|
|
2700
|
+
color: "var(--wp-info-text)",
|
|
2701
|
+
borderRadius: 3
|
|
2702
|
+
},
|
|
2008
2703
|
depRow: { display: "flex", alignItems: "center", flexWrap: "wrap", gap: 4 },
|
|
2009
2704
|
depLabel: { fontSize: 10, fontWeight: 600, color: "var(--wp-text-muted)", textTransform: "uppercase" },
|
|
2010
2705
|
depLabelUsed: { fontSize: 10, fontWeight: 600, color: "var(--wp-success)", textTransform: "uppercase" },
|
|
@@ -2025,12 +2720,28 @@ var styles5 = {
|
|
|
2025
2720
|
borderRadius: 4
|
|
2026
2721
|
}
|
|
2027
2722
|
};
|
|
2028
|
-
function PreviewPanel({ store, schema }) {
|
|
2723
|
+
function PreviewPanel({ store, schema, externalEnums }) {
|
|
2029
2724
|
const [done, setDone] = react.useState(false);
|
|
2030
|
-
const { tree, currentStep, progress } = react$1.useWaypoint(store);
|
|
2725
|
+
const { tree, currentStep, progress } = react$1.useWaypoint(store, externalEnums);
|
|
2031
2726
|
const stepId = currentStep?.definition.id ?? "";
|
|
2032
2727
|
const { fields, stepData, setFieldValue } = react$1.useWaypointStep(store, stepId);
|
|
2033
2728
|
const [errors, setErrors] = react.useState({});
|
|
2729
|
+
const extVarDefs = schema.externalVariables ?? [];
|
|
2730
|
+
const [mockVars, setMockVars] = react.useState(() => {
|
|
2731
|
+
const initial = {};
|
|
2732
|
+
for (const v of extVarDefs) {
|
|
2733
|
+
initial[v.id] = v.type === "boolean" ? false : v.type === "number" ? 0 : "";
|
|
2734
|
+
}
|
|
2735
|
+
return initial;
|
|
2736
|
+
});
|
|
2737
|
+
react.useEffect(() => {
|
|
2738
|
+
for (const [varId, value] of Object.entries(mockVars)) {
|
|
2739
|
+
store.getState().setExternalVar(varId, value);
|
|
2740
|
+
}
|
|
2741
|
+
}, [mockVars]);
|
|
2742
|
+
function handleMockVarChange(varId, value) {
|
|
2743
|
+
setMockVars((prev) => ({ ...prev, [varId]: value }));
|
|
2744
|
+
}
|
|
2034
2745
|
function handleNext() {
|
|
2035
2746
|
const newErrors = {};
|
|
2036
2747
|
for (const field of fields) {
|
|
@@ -2050,8 +2761,11 @@ function PreviewPanel({ store, schema }) {
|
|
|
2050
2761
|
setErrors({});
|
|
2051
2762
|
const oldIds = tree.steps.map((s) => s.definition.id).join(",");
|
|
2052
2763
|
store.getState().setStepData(stepId, stepData);
|
|
2764
|
+
if ((store.getState().skippedSteps ?? []).includes(stepId)) {
|
|
2765
|
+
store.getState().unskipStep(stepId);
|
|
2766
|
+
}
|
|
2053
2767
|
const newData = store.getState().data;
|
|
2054
|
-
const newTree = core.resolveTree(schema, newData,
|
|
2768
|
+
const newTree = core.resolveTree(schema, newData, store.getState().externalVars, externalEnums);
|
|
2055
2769
|
const newIds = newTree.steps.map((s) => s.definition.id).join(",");
|
|
2056
2770
|
if (oldIds !== newIds) {
|
|
2057
2771
|
store.getState().truncateHistoryAt(stepId);
|
|
@@ -2069,6 +2783,9 @@ function PreviewPanel({ store, schema }) {
|
|
|
2069
2783
|
}
|
|
2070
2784
|
function handleRestart() {
|
|
2071
2785
|
store.getState().init(schema);
|
|
2786
|
+
for (const [varId, value] of Object.entries(mockVars)) {
|
|
2787
|
+
store.getState().setExternalVar(varId, value);
|
|
2788
|
+
}
|
|
2072
2789
|
setDone(false);
|
|
2073
2790
|
setErrors({});
|
|
2074
2791
|
}
|
|
@@ -2076,77 +2793,124 @@ function PreviewPanel({ store, schema }) {
|
|
|
2076
2793
|
(s) => s.definition.id === currentStep?.definition.id
|
|
2077
2794
|
);
|
|
2078
2795
|
if (done) {
|
|
2079
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2080
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2796
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.panel, children: [
|
|
2797
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.leftCol, children: [
|
|
2798
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2799
|
+
StepList,
|
|
2800
|
+
{
|
|
2801
|
+
tree,
|
|
2802
|
+
currentIdx,
|
|
2803
|
+
onSelect: (id) => store.getState().setCurrentStep(id),
|
|
2804
|
+
skippedStepIds: store.getState().skippedSteps
|
|
2805
|
+
}
|
|
2806
|
+
),
|
|
2807
|
+
extVarDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2808
|
+
MockVarPanel,
|
|
2809
|
+
{
|
|
2810
|
+
extVarDefs,
|
|
2811
|
+
mockVars,
|
|
2812
|
+
onChange: handleMockVarChange
|
|
2813
|
+
}
|
|
2814
|
+
)
|
|
2815
|
+
] }),
|
|
2816
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.divider }),
|
|
2817
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.rightCol, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.doneScreen, children: [
|
|
2818
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.doneIcon, children: "\u2713" }),
|
|
2819
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.doneTitle, children: "Parcours termin\xE9 !" }),
|
|
2820
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles7.doneText, children: "Toutes les \xE9tapes ont \xE9t\xE9 compl\xE9t\xE9es avec succ\xE8s." }),
|
|
2821
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles7.primaryBtn, onClick: handleRestart, children: "Recommencer" })
|
|
2822
|
+
] }) })
|
|
2823
|
+
] });
|
|
2824
|
+
}
|
|
2825
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.panel, children: [
|
|
2826
|
+
/* @__PURE__ */ jsxRuntime.jsx(devtools.DevPanel, { store }),
|
|
2827
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.leftCol, children: [
|
|
2828
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2081
2829
|
StepList,
|
|
2082
2830
|
{
|
|
2083
2831
|
tree,
|
|
2084
2832
|
currentIdx,
|
|
2085
2833
|
onSelect: (id) => store.getState().setCurrentStep(id)
|
|
2086
2834
|
}
|
|
2087
|
-
)
|
|
2088
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2089
|
-
|
|
2090
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.doneIcon, children: "\u2713" }),
|
|
2091
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.doneTitle, children: "Parcours termin\xE9 !" }),
|
|
2092
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles6.doneText, children: "Toutes les \xE9tapes ont \xE9t\xE9 compl\xE9t\xE9es avec succ\xE8s." }),
|
|
2093
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles6.primaryBtn, onClick: handleRestart, children: "Recommencer" })
|
|
2094
|
-
] }) })
|
|
2095
|
-
] });
|
|
2096
|
-
}
|
|
2097
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.panel, children: [
|
|
2098
|
-
/* @__PURE__ */ jsxRuntime.jsx(devtools.DevPanel, { store }),
|
|
2099
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.leftCol, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2100
|
-
StepList,
|
|
2101
|
-
{
|
|
2102
|
-
tree,
|
|
2103
|
-
currentIdx,
|
|
2104
|
-
onSelect: (id) => store.getState().setCurrentStep(id)
|
|
2105
|
-
}
|
|
2106
|
-
) }),
|
|
2107
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.divider }),
|
|
2108
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.rightCol, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles6.stepRenderer, children: [
|
|
2109
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.progressTrack, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...styles6.progressFill, width: `${progress}%` } }) }),
|
|
2110
|
-
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: styles6.stepTitle, children: currentStep?.definition.title ?? "" }),
|
|
2111
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles6.fieldsContainer, children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2112
|
-
FieldRenderer,
|
|
2835
|
+
),
|
|
2836
|
+
extVarDefs.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2837
|
+
MockVarPanel,
|
|
2113
2838
|
{
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2839
|
+
extVarDefs,
|
|
2840
|
+
mockVars,
|
|
2841
|
+
onChange: handleMockVarChange
|
|
2842
|
+
}
|
|
2843
|
+
)
|
|
2844
|
+
] }),
|
|
2845
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.divider }),
|
|
2846
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.rightCol, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.stepRenderer, children: [
|
|
2847
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.progressTrack, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...styles7.progressFill, width: `${progress}%` } }) }),
|
|
2848
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: styles7.stepTitle, children: currentStep?.definition.title ?? "" }),
|
|
2849
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.fieldsContainer, children: fields.map((field) => {
|
|
2850
|
+
const storedVal = stepData[field.definition.id];
|
|
2851
|
+
const displayVal = storedVal !== void 0 && storedVal !== null && storedVal !== "" ? storedVal : field.resolvedDefaultValue ?? field.definition.defaultValue ?? void 0;
|
|
2852
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2853
|
+
FieldRenderer,
|
|
2854
|
+
{
|
|
2855
|
+
field,
|
|
2856
|
+
value: displayVal,
|
|
2857
|
+
error: errors[field.definition.id],
|
|
2858
|
+
onChange: (val) => {
|
|
2859
|
+
setFieldValue(field.definition.id, val);
|
|
2860
|
+
if (errors[field.definition.id]) {
|
|
2861
|
+
setErrors((prev) => {
|
|
2862
|
+
const next = { ...prev };
|
|
2863
|
+
delete next[field.definition.id];
|
|
2864
|
+
return next;
|
|
2865
|
+
});
|
|
2866
|
+
}
|
|
2125
2867
|
}
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
)
|
|
2130
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2131
|
-
currentIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
2132
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2868
|
+
},
|
|
2869
|
+
field.definition.id
|
|
2870
|
+
);
|
|
2871
|
+
}) }),
|
|
2872
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.navRow, children: [
|
|
2873
|
+
currentIdx > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles7.secondaryBtn, onClick: handlePrev, children: "\u2190 Pr\xE9c\xE9dent" }),
|
|
2874
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, marginLeft: "auto" }, children: [
|
|
2875
|
+
currentStep?.definition.skippable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2876
|
+
"button",
|
|
2877
|
+
{
|
|
2878
|
+
style: styles7.secondaryBtn,
|
|
2879
|
+
onClick: () => {
|
|
2880
|
+
setErrors({});
|
|
2881
|
+
store.getState().skipStep(stepId);
|
|
2882
|
+
const next = core.getNextStep(tree.steps, stepId);
|
|
2883
|
+
if (next) {
|
|
2884
|
+
store.getState().setCurrentStep(next.definition.id);
|
|
2885
|
+
} else {
|
|
2886
|
+
setDone(true);
|
|
2887
|
+
}
|
|
2888
|
+
},
|
|
2889
|
+
children: "Passer"
|
|
2890
|
+
}
|
|
2891
|
+
),
|
|
2892
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles7.primaryBtn, onClick: handleNext, children: core.getNextStep(tree.steps, stepId) ? "Continuer \u2192" : "Terminer \u2713" })
|
|
2893
|
+
] })
|
|
2133
2894
|
] })
|
|
2134
2895
|
] }) })
|
|
2135
2896
|
] });
|
|
2136
2897
|
}
|
|
2137
|
-
function StepList({ tree, currentIdx, onSelect }) {
|
|
2898
|
+
function StepList({ tree, currentIdx, onSelect, skippedStepIds }) {
|
|
2899
|
+
const skipped = new Set(skippedStepIds ?? []);
|
|
2138
2900
|
const allSteps = [
|
|
2139
2901
|
...tree.steps.map((s) => ({ ...s, hidden: false })),
|
|
2140
2902
|
...tree.hiddenSteps.map((s) => ({ ...s, hidden: true }))
|
|
2141
2903
|
];
|
|
2142
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2143
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
2904
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.stepList, children: [
|
|
2905
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.stepListTitle, children: "\xC9tapes" }),
|
|
2144
2906
|
allSteps.map((step) => {
|
|
2145
|
-
const
|
|
2907
|
+
const isStepVisible = !step.hidden;
|
|
2146
2908
|
const visIdx = tree.steps.findIndex((s) => s.definition.id === step.definition.id);
|
|
2909
|
+
const isSkipped = skipped.has(step.definition.id);
|
|
2147
2910
|
let status = "hidden";
|
|
2148
|
-
if (
|
|
2149
|
-
if (visIdx < currentIdx) status = "
|
|
2911
|
+
if (isStepVisible) {
|
|
2912
|
+
if (isSkipped && visIdx < currentIdx) status = "skipped";
|
|
2913
|
+
else if (visIdx < currentIdx) status = "done";
|
|
2150
2914
|
else if (visIdx === currentIdx) status = "current";
|
|
2151
2915
|
else status = "upcoming";
|
|
2152
2916
|
}
|
|
@@ -2154,23 +2918,26 @@ function StepList({ tree, currentIdx, onSelect }) {
|
|
|
2154
2918
|
"div",
|
|
2155
2919
|
{
|
|
2156
2920
|
style: {
|
|
2157
|
-
...
|
|
2158
|
-
...status === "current" ?
|
|
2159
|
-
...status === "hidden" ?
|
|
2160
|
-
|
|
2921
|
+
...styles7.stepItem,
|
|
2922
|
+
...status === "current" ? styles7.stepItemCurrent : {},
|
|
2923
|
+
...status === "hidden" ? styles7.stepItemHidden : {},
|
|
2924
|
+
...status === "skipped" ? { opacity: 0.6 } : {},
|
|
2925
|
+
cursor: status === "done" || status === "skipped" ? "pointer" : "default"
|
|
2161
2926
|
},
|
|
2162
2927
|
onClick: () => {
|
|
2163
|
-
if (status === "done") onSelect(step.definition.id);
|
|
2928
|
+
if (status === "done" || status === "skipped") onSelect(step.definition.id);
|
|
2164
2929
|
},
|
|
2165
2930
|
children: [
|
|
2166
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
2931
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles7.stepStatus, children: [
|
|
2167
2932
|
status === "done" && "\u2713",
|
|
2933
|
+
status === "skipped" && "\u23ED",
|
|
2168
2934
|
status === "current" && "\u2192",
|
|
2169
2935
|
status === "upcoming" && "\u25CB",
|
|
2170
2936
|
status === "hidden" && "\u2013"
|
|
2171
2937
|
] }),
|
|
2172
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2173
|
-
status === "hidden" && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2938
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles7.stepName, children: step.definition.title }),
|
|
2939
|
+
status === "hidden" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles7.hiddenBadge, children: "hidden" }),
|
|
2940
|
+
status === "skipped" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: { ...styles7.hiddenBadge, color: "var(--wp-warning)", background: "var(--wp-warning-bg)" }, children: "skipped" })
|
|
2174
2941
|
]
|
|
2175
2942
|
},
|
|
2176
2943
|
step.definition.id
|
|
@@ -2178,13 +2945,51 @@ function StepList({ tree, currentIdx, onSelect }) {
|
|
|
2178
2945
|
})
|
|
2179
2946
|
] });
|
|
2180
2947
|
}
|
|
2948
|
+
function MockVarPanel({ extVarDefs, mockVars, onChange }) {
|
|
2949
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.mockPanel, children: [
|
|
2950
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.mockPanelTitle, children: [
|
|
2951
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u26A1 External Variables" }),
|
|
2952
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles7.mockPanelHint, children: "mock values" })
|
|
2953
|
+
] }),
|
|
2954
|
+
extVarDefs.map((v) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.mockVarRow, children: [
|
|
2955
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.mockVarLabel, children: [
|
|
2956
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles7.mockVarId, children: [
|
|
2957
|
+
"$",
|
|
2958
|
+
`ext.${v.id}`
|
|
2959
|
+
] }),
|
|
2960
|
+
v.blocking && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles7.mockBlockingBadge, children: "!" })
|
|
2961
|
+
] }),
|
|
2962
|
+
v.type === "boolean" ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: styles7.mockCheckRow, children: [
|
|
2963
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2964
|
+
"input",
|
|
2965
|
+
{
|
|
2966
|
+
type: "checkbox",
|
|
2967
|
+
checked: Boolean(mockVars[v.id]),
|
|
2968
|
+
onChange: (e) => onChange(v.id, e.target.checked)
|
|
2969
|
+
}
|
|
2970
|
+
),
|
|
2971
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 11, color: "var(--wp-text-muted)" }, children: String(mockVars[v.id]) })
|
|
2972
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2973
|
+
"input",
|
|
2974
|
+
{
|
|
2975
|
+
style: styles7.mockInput,
|
|
2976
|
+
type: v.type === "number" ? "number" : "text",
|
|
2977
|
+
value: String(mockVars[v.id] ?? ""),
|
|
2978
|
+
placeholder: v.label,
|
|
2979
|
+
onChange: (e) => onChange(v.id, v.type === "number" ? Number(e.target.value) : e.target.value)
|
|
2980
|
+
}
|
|
2981
|
+
)
|
|
2982
|
+
] }, v.id))
|
|
2983
|
+
] });
|
|
2984
|
+
}
|
|
2181
2985
|
function FieldRenderer({ field, value, error, onChange }) {
|
|
2182
2986
|
const { definition } = field;
|
|
2183
|
-
const
|
|
2184
|
-
|
|
2185
|
-
|
|
2987
|
+
const options = field.resolvedOptions ?? definition.options ?? [];
|
|
2988
|
+
const inputStyle2 = { ...styles7.input, ...error ? styles7.inputError : {} };
|
|
2989
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles7.fieldGroup, children: [
|
|
2990
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: styles7.label, children: [
|
|
2186
2991
|
definition.label,
|
|
2187
|
-
definition.validation?.some((r) => r.type === "required") && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2992
|
+
definition.validation?.some((r) => r.type === "required") && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles7.required, children: " *" })
|
|
2188
2993
|
] }),
|
|
2189
2994
|
(definition.type === "text" || definition.type === "email" || definition.type === "tel" || definition.type === "password" || definition.type === "url" || definition.type === "number" || definition.type === "date") && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2190
2995
|
"input",
|
|
@@ -2213,7 +3018,7 @@ function FieldRenderer({ field, value, error, onChange }) {
|
|
|
2213
3018
|
onChange: (e) => onChange(e.target.value),
|
|
2214
3019
|
children: [
|
|
2215
3020
|
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "\u2014 Choisir \u2014" }),
|
|
2216
|
-
|
|
3021
|
+
options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: String(opt.value), children: opt.label }, String(opt.value)))
|
|
2217
3022
|
]
|
|
2218
3023
|
}
|
|
2219
3024
|
),
|
|
@@ -2227,10 +3032,10 @@ function FieldRenderer({ field, value, error, onChange }) {
|
|
|
2227
3032
|
const selected = Array.from(e.target.selectedOptions).map((o) => o.value);
|
|
2228
3033
|
onChange(selected);
|
|
2229
3034
|
},
|
|
2230
|
-
children:
|
|
3035
|
+
children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: String(opt.value), children: opt.label }, String(opt.value)))
|
|
2231
3036
|
}
|
|
2232
3037
|
),
|
|
2233
|
-
definition.type === "radio" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children:
|
|
3038
|
+
definition.type === "radio" && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: options.map((opt) => /* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 13 }, children: [
|
|
2234
3039
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2235
3040
|
"input",
|
|
2236
3041
|
{
|
|
@@ -2254,10 +3059,10 @@ function FieldRenderer({ field, value, error, onChange }) {
|
|
|
2254
3059
|
),
|
|
2255
3060
|
definition.placeholder ?? definition.label
|
|
2256
3061
|
] }),
|
|
2257
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3062
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles7.errorMsg, children: error })
|
|
2258
3063
|
] });
|
|
2259
3064
|
}
|
|
2260
|
-
var
|
|
3065
|
+
var styles7 = {
|
|
2261
3066
|
panel: {
|
|
2262
3067
|
display: "flex",
|
|
2263
3068
|
flex: 1,
|
|
@@ -2426,6 +3231,80 @@ var styles6 = {
|
|
|
2426
3231
|
letterSpacing: "0.3px",
|
|
2427
3232
|
flexShrink: 0
|
|
2428
3233
|
},
|
|
3234
|
+
// Mock var panel
|
|
3235
|
+
mockPanel: {
|
|
3236
|
+
borderTop: "1px solid var(--wp-border)",
|
|
3237
|
+
padding: "12px",
|
|
3238
|
+
display: "flex",
|
|
3239
|
+
flexDirection: "column",
|
|
3240
|
+
gap: 8
|
|
3241
|
+
},
|
|
3242
|
+
mockPanelTitle: {
|
|
3243
|
+
display: "flex",
|
|
3244
|
+
alignItems: "center",
|
|
3245
|
+
justifyContent: "space-between",
|
|
3246
|
+
fontSize: 11,
|
|
3247
|
+
fontWeight: 700,
|
|
3248
|
+
color: "var(--wp-text-muted)",
|
|
3249
|
+
textTransform: "uppercase",
|
|
3250
|
+
letterSpacing: "0.5px",
|
|
3251
|
+
marginBottom: 4
|
|
3252
|
+
},
|
|
3253
|
+
mockPanelHint: {
|
|
3254
|
+
fontSize: 9,
|
|
3255
|
+
fontWeight: 500,
|
|
3256
|
+
color: "var(--wp-warning)",
|
|
3257
|
+
textTransform: "none",
|
|
3258
|
+
background: "var(--wp-warning-bg)",
|
|
3259
|
+
padding: "1px 5px",
|
|
3260
|
+
borderRadius: 4
|
|
3261
|
+
},
|
|
3262
|
+
mockVarRow: {
|
|
3263
|
+
display: "flex",
|
|
3264
|
+
flexDirection: "column",
|
|
3265
|
+
gap: 3
|
|
3266
|
+
},
|
|
3267
|
+
mockVarLabel: {
|
|
3268
|
+
display: "flex",
|
|
3269
|
+
alignItems: "center",
|
|
3270
|
+
gap: 4
|
|
3271
|
+
},
|
|
3272
|
+
mockVarId: {
|
|
3273
|
+
fontSize: 10,
|
|
3274
|
+
fontFamily: "monospace",
|
|
3275
|
+
fontWeight: 600,
|
|
3276
|
+
color: "var(--wp-text-secondary)"
|
|
3277
|
+
},
|
|
3278
|
+
mockBlockingBadge: {
|
|
3279
|
+
fontSize: 9,
|
|
3280
|
+
fontWeight: 700,
|
|
3281
|
+
width: 13,
|
|
3282
|
+
height: 13,
|
|
3283
|
+
borderRadius: "50%",
|
|
3284
|
+
background: "var(--wp-danger-bg-strong)",
|
|
3285
|
+
color: "var(--wp-danger)",
|
|
3286
|
+
display: "flex",
|
|
3287
|
+
alignItems: "center",
|
|
3288
|
+
justifyContent: "center",
|
|
3289
|
+
flexShrink: 0
|
|
3290
|
+
},
|
|
3291
|
+
mockInput: {
|
|
3292
|
+
fontSize: 11,
|
|
3293
|
+
padding: "4px 6px",
|
|
3294
|
+
border: "1px solid var(--wp-border-muted)",
|
|
3295
|
+
borderRadius: "var(--wp-radius)",
|
|
3296
|
+
background: "var(--wp-canvas)",
|
|
3297
|
+
color: "var(--wp-text)",
|
|
3298
|
+
outline: "none",
|
|
3299
|
+
width: "100%",
|
|
3300
|
+
boxSizing: "border-box"
|
|
3301
|
+
},
|
|
3302
|
+
mockCheckRow: {
|
|
3303
|
+
display: "flex",
|
|
3304
|
+
alignItems: "center",
|
|
3305
|
+
gap: 6,
|
|
3306
|
+
cursor: "pointer"
|
|
3307
|
+
},
|
|
2429
3308
|
// Done screen
|
|
2430
3309
|
doneScreen: {
|
|
2431
3310
|
display: "flex",
|
|
@@ -2462,83 +3341,100 @@ var styles6 = {
|
|
|
2462
3341
|
};
|
|
2463
3342
|
function StepEditor() {
|
|
2464
3343
|
const { schema, selectedStepId, updateStep, setStepCondition } = useBuilderStore();
|
|
3344
|
+
const readOnly = useBuilderReadOnly();
|
|
2465
3345
|
const [conditionModalOpen, setConditionModalOpen] = react.useState(false);
|
|
2466
3346
|
const step = schema.steps.find((s) => s.id === selectedStepId);
|
|
2467
3347
|
if (!step) {
|
|
2468
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3348
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.empty, children: "Select a step to configure its properties." });
|
|
2469
3349
|
}
|
|
2470
3350
|
const hasCondition = !!step.visibleWhen;
|
|
2471
3351
|
const ruleCount = step.visibleWhen?.rules.length ?? 0;
|
|
2472
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2473
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2474
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
2475
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3352
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.container, children: [
|
|
3353
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.header, children: [
|
|
3354
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.headerTitle, children: "Step Config" }),
|
|
3355
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.stepId, children: [
|
|
2476
3356
|
"id: ",
|
|
2477
3357
|
step.id
|
|
2478
3358
|
] })
|
|
2479
3359
|
] }),
|
|
2480
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2481
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2482
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style:
|
|
3360
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.body, children: [
|
|
3361
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.group, children: [
|
|
3362
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles8.label, children: "Title" }),
|
|
2483
3363
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2484
3364
|
"input",
|
|
2485
3365
|
{
|
|
2486
|
-
style:
|
|
3366
|
+
style: styles8.input,
|
|
2487
3367
|
value: step.title,
|
|
2488
3368
|
placeholder: "Step title",
|
|
2489
|
-
|
|
3369
|
+
readOnly,
|
|
3370
|
+
onChange: readOnly ? void 0 : (e) => updateStep(step.id, { title: e.target.value })
|
|
2490
3371
|
}
|
|
2491
3372
|
)
|
|
2492
3373
|
] }),
|
|
2493
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2494
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { style:
|
|
3374
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.group, children: [
|
|
3375
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { style: styles8.label, children: "URL" }),
|
|
2495
3376
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2496
3377
|
"input",
|
|
2497
3378
|
{
|
|
2498
|
-
style:
|
|
3379
|
+
style: styles8.input,
|
|
2499
3380
|
value: step.url,
|
|
2500
3381
|
placeholder: "/onboarding/step-name",
|
|
2501
|
-
|
|
3382
|
+
readOnly,
|
|
3383
|
+
onChange: readOnly ? void 0 : (e) => updateStep(step.id, { url: e.target.value })
|
|
2502
3384
|
}
|
|
2503
3385
|
),
|
|
2504
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3386
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.hint, children: [
|
|
2505
3387
|
"Supports ",
|
|
2506
3388
|
"{{PARAM}}",
|
|
2507
3389
|
" placeholders"
|
|
2508
3390
|
] })
|
|
2509
3391
|
] }),
|
|
2510
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3392
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.checkRow, children: [
|
|
2511
3393
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2512
3394
|
"input",
|
|
2513
3395
|
{
|
|
2514
3396
|
type: "checkbox",
|
|
2515
3397
|
id: `resume-${step.id}`,
|
|
2516
3398
|
checked: !!step.enableResumeFromHere,
|
|
2517
|
-
|
|
3399
|
+
disabled: readOnly,
|
|
3400
|
+
onChange: readOnly ? void 0 : (e) => updateStep(step.id, { enableResumeFromHere: e.target.checked || void 0 })
|
|
2518
3401
|
}
|
|
2519
3402
|
),
|
|
2520
|
-
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `resume-${step.id}`, style:
|
|
3403
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `resume-${step.id}`, style: styles8.checkLabel, children: "Resume from this step" })
|
|
2521
3404
|
] }),
|
|
2522
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
3405
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.checkRow, children: [
|
|
3406
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3407
|
+
"input",
|
|
3408
|
+
{
|
|
3409
|
+
type: "checkbox",
|
|
3410
|
+
id: `skippable-${step.id}`,
|
|
3411
|
+
checked: !!step.skippable,
|
|
3412
|
+
disabled: readOnly,
|
|
3413
|
+
onChange: readOnly ? void 0 : (e) => updateStep(step.id, { skippable: e.target.checked || void 0 })
|
|
3414
|
+
}
|
|
3415
|
+
),
|
|
3416
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: `skippable-${step.id}`, style: styles8.checkLabel, children: "Skippable (user can bypass this step)" })
|
|
3417
|
+
] }),
|
|
3418
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.divider }),
|
|
3419
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.conditionRow, children: [
|
|
3420
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.conditionInfo, children: [
|
|
3421
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.label, children: "Visibility condition" }),
|
|
3422
|
+
hasCondition ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.conditionSummary, children: [
|
|
3423
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles8.conditionBadge, children: [
|
|
2528
3424
|
ruleCount,
|
|
2529
3425
|
" rule",
|
|
2530
3426
|
ruleCount !== 1 ? "s" : "",
|
|
2531
3427
|
" \xB7 ",
|
|
2532
3428
|
step.visibleWhen.combinator.toUpperCase()
|
|
2533
3429
|
] }),
|
|
2534
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2535
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3430
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.conditionDesc, children: "Step is conditional" })
|
|
3431
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.conditionNone, children: "Always visible" })
|
|
2536
3432
|
] }),
|
|
2537
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
3433
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.conditionActions, children: [
|
|
2538
3434
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2539
3435
|
"button",
|
|
2540
3436
|
{
|
|
2541
|
-
style:
|
|
3437
|
+
style: styles8.editConditionBtn,
|
|
2542
3438
|
onClick: () => setConditionModalOpen(true),
|
|
2543
3439
|
children: hasCondition ? "Edit" : "Add condition"
|
|
2544
3440
|
}
|
|
@@ -2546,7 +3442,7 @@ function StepEditor() {
|
|
|
2546
3442
|
hasCondition && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2547
3443
|
"button",
|
|
2548
3444
|
{
|
|
2549
|
-
style:
|
|
3445
|
+
style: styles8.clearConditionBtn,
|
|
2550
3446
|
onClick: () => setStepCondition(step.id, void 0),
|
|
2551
3447
|
children: "Clear"
|
|
2552
3448
|
}
|
|
@@ -2561,7 +3457,7 @@ function StepEditor() {
|
|
|
2561
3457
|
onClose: () => setConditionModalOpen(false),
|
|
2562
3458
|
width: 620,
|
|
2563
3459
|
children: [
|
|
2564
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
3460
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: styles8.modalHint, children: "Define when this step is visible. Leave empty to always show it." }),
|
|
2565
3461
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2566
3462
|
ConditionBuilder,
|
|
2567
3463
|
{
|
|
@@ -2569,10 +3465,10 @@ function StepEditor() {
|
|
|
2569
3465
|
onChange: (c) => setStepCondition(step.id, c)
|
|
2570
3466
|
}
|
|
2571
3467
|
),
|
|
2572
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3468
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles8.modalFooter, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2573
3469
|
"button",
|
|
2574
3470
|
{
|
|
2575
|
-
style:
|
|
3471
|
+
style: styles8.modalCloseBtn,
|
|
2576
3472
|
onClick: () => setConditionModalOpen(false),
|
|
2577
3473
|
children: "Done"
|
|
2578
3474
|
}
|
|
@@ -2582,7 +3478,7 @@ function StepEditor() {
|
|
|
2582
3478
|
)
|
|
2583
3479
|
] });
|
|
2584
3480
|
}
|
|
2585
|
-
var
|
|
3481
|
+
var styles8 = {
|
|
2586
3482
|
container: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" },
|
|
2587
3483
|
empty: {
|
|
2588
3484
|
display: "flex",
|
|
@@ -2671,128 +3567,164 @@ var styles7 = {
|
|
|
2671
3567
|
}
|
|
2672
3568
|
};
|
|
2673
3569
|
function StepList2() {
|
|
2674
|
-
const { schema, selectedStepId, addStep, removeStep, selectStep, reorderSteps } = useBuilderStore();
|
|
3570
|
+
const { schema, selectedStepId, addStep, removeStep, duplicateStep, selectStep, reorderSteps } = useBuilderStore();
|
|
3571
|
+
const readOnly = useBuilderReadOnly();
|
|
2675
3572
|
const [moveError, setMoveError] = react.useState(null);
|
|
2676
3573
|
const steps = schema.steps;
|
|
2677
3574
|
const deps = computeStepDependencies(schema);
|
|
2678
|
-
const tryMove = (
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
3575
|
+
const tryMove = react.useCallback(
|
|
3576
|
+
(fromIndex, toIndex) => {
|
|
3577
|
+
const check = isMoveValid(steps, deps, fromIndex, toIndex);
|
|
3578
|
+
if (!check.valid) {
|
|
3579
|
+
setMoveError(check.reason ?? "Invalid move");
|
|
3580
|
+
setTimeout(() => setMoveError(null), 3e3);
|
|
3581
|
+
return;
|
|
3582
|
+
}
|
|
3583
|
+
setMoveError(null);
|
|
3584
|
+
reorderSteps(fromIndex, toIndex);
|
|
3585
|
+
},
|
|
3586
|
+
[steps, deps, reorderSteps]
|
|
3587
|
+
);
|
|
3588
|
+
const stepIds = steps.map((s) => s.id);
|
|
3589
|
+
const renderOverlay = (id) => {
|
|
3590
|
+
const step = steps.find((s) => s.id === id);
|
|
3591
|
+
if (!step) return null;
|
|
3592
|
+
const index = steps.indexOf(step);
|
|
3593
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { ...styles9.card, ...styles9.cardDragOverlay }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.cardMain, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.cardLeft, children: [
|
|
3594
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.cardIndex, children: index + 1 }),
|
|
3595
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.cardTitle, children: step.title })
|
|
3596
|
+
] }) }) });
|
|
2687
3597
|
};
|
|
2688
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2689
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2690
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { style:
|
|
3598
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.container, children: [
|
|
3599
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.header, children: [
|
|
3600
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { style: styles9.title, children: [
|
|
2691
3601
|
"Steps (",
|
|
2692
3602
|
steps.length,
|
|
2693
3603
|
")"
|
|
2694
3604
|
] }),
|
|
2695
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
3605
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles9.addBtn, onClick: () => addStep(), children: "+ Add step" })
|
|
2696
3606
|
] }),
|
|
2697
|
-
moveError && /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2698
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3607
|
+
moveError && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.errorBanner, children: [
|
|
3608
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.errorIcon, children: "\u26A0" }),
|
|
2699
3609
|
moveError
|
|
2700
3610
|
] }),
|
|
2701
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2702
|
-
steps.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
children:
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
3611
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.list, children: [
|
|
3612
|
+
steps.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.empty, children: 'No steps yet. Click "Add step" to start.' }),
|
|
3613
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3614
|
+
SortableList,
|
|
3615
|
+
{
|
|
3616
|
+
items: stepIds,
|
|
3617
|
+
disabled: readOnly,
|
|
3618
|
+
onReorder: tryMove,
|
|
3619
|
+
renderOverlay,
|
|
3620
|
+
renderItem: (id, index) => {
|
|
3621
|
+
const step = steps[index];
|
|
3622
|
+
const isSelected = step.id === selectedStepId;
|
|
3623
|
+
const hasCondition = !!step.visibleWhen;
|
|
3624
|
+
const depLabels = getStepDependencyLabels(step.id, deps, schema);
|
|
3625
|
+
const canMoveUp = index > 0 && isMoveValid(steps, deps, index, index - 1).valid;
|
|
3626
|
+
const canMoveDown = index < steps.length - 1 && isMoveValid(steps, deps, index, index + 1).valid;
|
|
3627
|
+
const dependents = steps.filter(
|
|
3628
|
+
(s) => (deps.get(s.id) ?? /* @__PURE__ */ new Set()).has(step.id)
|
|
3629
|
+
);
|
|
3630
|
+
return /* @__PURE__ */ jsxRuntime.jsx(SortableItem, { id: step.id, disabled: readOnly, children: ({ handleProps }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3631
|
+
"div",
|
|
3632
|
+
{
|
|
3633
|
+
style: {
|
|
3634
|
+
...styles9.card,
|
|
3635
|
+
...isSelected ? styles9.cardSelected : {}
|
|
3636
|
+
},
|
|
3637
|
+
onClick: () => selectStep(step.id),
|
|
3638
|
+
children: [
|
|
3639
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.cardMain, children: [
|
|
3640
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.cardLeft, children: [
|
|
3641
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(DragHandle, { handleProps }),
|
|
3642
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.cardIndex, children: index + 1 }),
|
|
3643
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
|
|
3644
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles9.cardTitle, children: step.title }),
|
|
3645
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.cardMeta, children: [
|
|
3646
|
+
step.fields.length,
|
|
3647
|
+
" field",
|
|
3648
|
+
step.fields.length !== 1 ? "s" : "",
|
|
3649
|
+
hasCondition && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.conditionBadge, children: "conditional" })
|
|
3650
|
+
] })
|
|
3651
|
+
] })
|
|
3652
|
+
] }),
|
|
3653
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.cardActions, children: [
|
|
3654
|
+
index > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3655
|
+
"button",
|
|
3656
|
+
{
|
|
3657
|
+
style: {
|
|
3658
|
+
...styles9.iconBtn,
|
|
3659
|
+
...canMoveUp ? {} : styles9.iconBtnBlocked
|
|
3660
|
+
},
|
|
3661
|
+
title: canMoveUp ? "Move up" : `Can't move up \u2014 dependency order required`,
|
|
3662
|
+
onClick: (e) => {
|
|
3663
|
+
e.stopPropagation();
|
|
3664
|
+
tryMove(index, index - 1);
|
|
3665
|
+
},
|
|
3666
|
+
children: "\u2191"
|
|
3667
|
+
}
|
|
3668
|
+
),
|
|
3669
|
+
index < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3670
|
+
"button",
|
|
3671
|
+
{
|
|
3672
|
+
style: {
|
|
3673
|
+
...styles9.iconBtn,
|
|
3674
|
+
...canMoveDown ? {} : styles9.iconBtnBlocked
|
|
3675
|
+
},
|
|
3676
|
+
title: canMoveDown ? "Move down" : `Can't move down \u2014 dependency order required`,
|
|
3677
|
+
onClick: (e) => {
|
|
3678
|
+
e.stopPropagation();
|
|
3679
|
+
tryMove(index, index + 1);
|
|
3680
|
+
},
|
|
3681
|
+
children: "\u2193"
|
|
3682
|
+
}
|
|
3683
|
+
),
|
|
3684
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3685
|
+
"button",
|
|
3686
|
+
{
|
|
3687
|
+
style: styles9.iconBtn,
|
|
3688
|
+
title: "Duplicate step",
|
|
3689
|
+
onClick: (e) => {
|
|
3690
|
+
e.stopPropagation();
|
|
3691
|
+
duplicateStep(step.id);
|
|
3692
|
+
},
|
|
3693
|
+
children: "\u29C9"
|
|
3694
|
+
}
|
|
3695
|
+
),
|
|
3696
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3697
|
+
"button",
|
|
3698
|
+
{
|
|
3699
|
+
style: { ...styles9.iconBtn, ...styles9.deleteBtn },
|
|
3700
|
+
title: "Remove step",
|
|
3701
|
+
onClick: (e) => {
|
|
3702
|
+
e.stopPropagation();
|
|
3703
|
+
removeStep(step.id);
|
|
3704
|
+
},
|
|
3705
|
+
children: "\u2715"
|
|
3706
|
+
}
|
|
3707
|
+
)
|
|
2731
3708
|
] })
|
|
3709
|
+
] }),
|
|
3710
|
+
depLabels.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.depRow, children: [
|
|
3711
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.depLabel, children: "needs:" }),
|
|
3712
|
+
depLabels.map((label) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.depBadge, children: label }, label))
|
|
3713
|
+
] }),
|
|
3714
|
+
dependents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles9.depRow, children: [
|
|
3715
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.depLabelUsed, children: "used by:" }),
|
|
3716
|
+
dependents.map((s) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles9.depBadgeUsed, children: s.title }, s.id))
|
|
2732
3717
|
] })
|
|
2733
|
-
]
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
...styles8.iconBtn,
|
|
2740
|
-
...canMoveUp ? {} : styles8.iconBtnBlocked
|
|
2741
|
-
},
|
|
2742
|
-
title: canMoveUp ? "Move up" : `Can't move up \u2014 dependency order required`,
|
|
2743
|
-
onClick: (e) => {
|
|
2744
|
-
e.stopPropagation();
|
|
2745
|
-
tryMove(index, index - 1);
|
|
2746
|
-
},
|
|
2747
|
-
children: "\u2191"
|
|
2748
|
-
}
|
|
2749
|
-
),
|
|
2750
|
-
index < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2751
|
-
"button",
|
|
2752
|
-
{
|
|
2753
|
-
style: {
|
|
2754
|
-
...styles8.iconBtn,
|
|
2755
|
-
...canMoveDown ? {} : styles8.iconBtnBlocked
|
|
2756
|
-
},
|
|
2757
|
-
title: canMoveDown ? "Move down" : `Can't move down \u2014 dependency order required`,
|
|
2758
|
-
onClick: (e) => {
|
|
2759
|
-
e.stopPropagation();
|
|
2760
|
-
tryMove(index, index + 1);
|
|
2761
|
-
},
|
|
2762
|
-
children: "\u2193"
|
|
2763
|
-
}
|
|
2764
|
-
),
|
|
2765
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2766
|
-
"button",
|
|
2767
|
-
{
|
|
2768
|
-
style: { ...styles8.iconBtn, ...styles8.deleteBtn },
|
|
2769
|
-
title: "Remove step",
|
|
2770
|
-
onClick: (e) => {
|
|
2771
|
-
e.stopPropagation();
|
|
2772
|
-
removeStep(step.id);
|
|
2773
|
-
},
|
|
2774
|
-
children: "\u2715"
|
|
2775
|
-
}
|
|
2776
|
-
)
|
|
2777
|
-
] })
|
|
2778
|
-
] }),
|
|
2779
|
-
depLabels.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.depRow, children: [
|
|
2780
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.depLabel, children: "needs:" }),
|
|
2781
|
-
depLabels.map((label) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.depBadge, children: label }, label))
|
|
2782
|
-
] }),
|
|
2783
|
-
dependents.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles8.depRow, children: [
|
|
2784
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.depLabelUsed, children: "used by:" }),
|
|
2785
|
-
dependents.map((s) => /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles8.depBadgeUsed, children: s.title }, s.id))
|
|
2786
|
-
] })
|
|
2787
|
-
]
|
|
2788
|
-
},
|
|
2789
|
-
step.id
|
|
2790
|
-
);
|
|
2791
|
-
})
|
|
3718
|
+
]
|
|
3719
|
+
}
|
|
3720
|
+
) }, step.id);
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
)
|
|
2792
3724
|
] })
|
|
2793
3725
|
] });
|
|
2794
3726
|
}
|
|
2795
|
-
var
|
|
3727
|
+
var styles9 = {
|
|
2796
3728
|
container: { display: "flex", flexDirection: "column", height: "100%" },
|
|
2797
3729
|
header: {
|
|
2798
3730
|
display: "flex",
|
|
@@ -2840,6 +3772,12 @@ var styles8 = {
|
|
|
2840
3772
|
gap: 6
|
|
2841
3773
|
},
|
|
2842
3774
|
cardSelected: { background: "var(--wp-primary-muted)", border: "1px solid var(--wp-primary-border)" },
|
|
3775
|
+
cardDragOverlay: {
|
|
3776
|
+
boxShadow: "0 4px 16px rgba(0,0,0,0.25)",
|
|
3777
|
+
border: "1px solid var(--wp-primary-border)",
|
|
3778
|
+
background: "var(--wp-surface)",
|
|
3779
|
+
opacity: 0.95
|
|
3780
|
+
},
|
|
2843
3781
|
cardMain: { display: "flex", alignItems: "center", justifyContent: "space-between" },
|
|
2844
3782
|
cardLeft: { display: "flex", alignItems: "center", gap: 10, minWidth: 0, flex: 1 },
|
|
2845
3783
|
cardIndex: {
|
|
@@ -2912,7 +3850,7 @@ var styles8 = {
|
|
|
2912
3850
|
borderRadius: 4
|
|
2913
3851
|
}
|
|
2914
3852
|
};
|
|
2915
|
-
function Toolbar({ onSave, previewMode, onTest, isMobile }) {
|
|
3853
|
+
function Toolbar({ onSave, previewMode, onTest, isMobile, readOnly }) {
|
|
2916
3854
|
const { schema, isDirty, resetSchema } = useBuilderStore();
|
|
2917
3855
|
const handleExport = () => {
|
|
2918
3856
|
const json = JSON.stringify(schema, null, 2);
|
|
@@ -2952,31 +3890,31 @@ ${result.errors.map((e2) => `\u2022 ${e2}`).join("\n")}`);
|
|
|
2952
3890
|
input.click();
|
|
2953
3891
|
};
|
|
2954
3892
|
if (previewMode) {
|
|
2955
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2956
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2957
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2958
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3893
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles10.toolbar, children: [
|
|
3894
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles10.left, children: [
|
|
3895
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.logo, children: "\u25C8 waypoint" }),
|
|
3896
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.separator, children: "/" }),
|
|
2959
3897
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2960
3898
|
"button",
|
|
2961
3899
|
{
|
|
2962
|
-
style: { ...
|
|
3900
|
+
style: { ...styles10.btn, ...styles10.editBtn },
|
|
2963
3901
|
onClick: onTest,
|
|
2964
3902
|
children: "\u2190 \xC9diter"
|
|
2965
3903
|
}
|
|
2966
3904
|
)
|
|
2967
3905
|
] }),
|
|
2968
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
3906
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: styles10.right, children: /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 12, color: "var(--wp-text-muted)", fontStyle: "italic" }, children: "Mode aper\xE7u" }) })
|
|
2969
3907
|
] });
|
|
2970
3908
|
}
|
|
2971
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2972
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2973
|
-
!isMobile && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
2974
|
-
!isMobile && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3909
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles10.toolbar, children: [
|
|
3910
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles10.left, children: [
|
|
3911
|
+
!isMobile && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.logo, children: "\u25C8 waypoint" }),
|
|
3912
|
+
!isMobile && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.separator, children: "/" }),
|
|
2975
3913
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2976
3914
|
"input",
|
|
2977
3915
|
{
|
|
2978
3916
|
style: {
|
|
2979
|
-
...
|
|
3917
|
+
...styles10.journeyName,
|
|
2980
3918
|
...isMobile ? { maxWidth: 120, fontSize: 12 } : {}
|
|
2981
3919
|
},
|
|
2982
3920
|
value: schema.name,
|
|
@@ -2987,25 +3925,26 @@ ${result.errors.map((e2) => `\u2022 ${e2}`).join("\n")}`);
|
|
|
2987
3925
|
}))
|
|
2988
3926
|
}
|
|
2989
3927
|
),
|
|
2990
|
-
isDirty && /* @__PURE__ */ jsxRuntime.jsx("span", { style:
|
|
3928
|
+
isDirty && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.dirtyDot, title: "Unsaved changes" })
|
|
2991
3929
|
] }),
|
|
2992
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
2993
|
-
|
|
2994
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
2995
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
2996
|
-
|
|
3930
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: styles10.right, children: [
|
|
3931
|
+
readOnly && /* @__PURE__ */ jsxRuntime.jsx("span", { style: styles10.readOnlyBadge, children: "View only" }),
|
|
3932
|
+
!readOnly && onTest && /* @__PURE__ */ jsxRuntime.jsx("button", { style: { ...styles10.btn, ...styles10.testBtn }, onClick: onTest, title: "Tester", children: isMobile ? "\u25B6" : "\u25B6 Tester" }),
|
|
3933
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx("button", { style: styles10.btn, onClick: handleImport, title: "Import", children: isMobile ? "\u2193" : "Import" }),
|
|
3934
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: styles10.btn, onClick: handleExport, title: "Export JSON", children: isMobile ? "\u2191" : "Export JSON" }),
|
|
3935
|
+
!readOnly && onSave && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2997
3936
|
"button",
|
|
2998
3937
|
{
|
|
2999
|
-
style: { ...
|
|
3938
|
+
style: { ...styles10.btn, ...styles10.saveBtn },
|
|
3000
3939
|
onClick: () => onSave(schema),
|
|
3001
3940
|
title: "Save",
|
|
3002
3941
|
children: isMobile ? "\u2713" : "Save"
|
|
3003
3942
|
}
|
|
3004
3943
|
),
|
|
3005
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3944
|
+
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3006
3945
|
"button",
|
|
3007
3946
|
{
|
|
3008
|
-
style: { ...
|
|
3947
|
+
style: { ...styles10.btn, color: "var(--wp-danger)" },
|
|
3009
3948
|
title: "Reset",
|
|
3010
3949
|
onClick: () => {
|
|
3011
3950
|
if (confirm("Reset the journey? All changes will be lost.")) resetSchema();
|
|
@@ -3016,7 +3955,7 @@ ${result.errors.map((e2) => `\u2022 ${e2}`).join("\n")}`);
|
|
|
3016
3955
|
] })
|
|
3017
3956
|
] });
|
|
3018
3957
|
}
|
|
3019
|
-
var
|
|
3958
|
+
var styles10 = {
|
|
3020
3959
|
toolbar: {
|
|
3021
3960
|
display: "flex",
|
|
3022
3961
|
alignItems: "center",
|
|
@@ -3058,6 +3997,15 @@ var styles9 = {
|
|
|
3058
3997
|
fontWeight: 500
|
|
3059
3998
|
},
|
|
3060
3999
|
saveBtn: { background: "var(--wp-primary)", color: "var(--wp-canvas)", border: "1px solid var(--wp-primary)" },
|
|
4000
|
+
readOnlyBadge: {
|
|
4001
|
+
fontSize: 11,
|
|
4002
|
+
fontWeight: 600,
|
|
4003
|
+
color: "var(--wp-text-subtle)",
|
|
4004
|
+
background: "var(--wp-surface)",
|
|
4005
|
+
border: "1px solid var(--wp-border)",
|
|
4006
|
+
borderRadius: "var(--wp-radius)",
|
|
4007
|
+
padding: "3px 8px"
|
|
4008
|
+
},
|
|
3061
4009
|
testBtn: { background: "var(--wp-success, #22c55e)", color: "#fff", border: "1px solid var(--wp-success, #22c55e)", fontWeight: 600 },
|
|
3062
4010
|
editBtn: { background: "transparent", color: "var(--wp-toolbar-text)", border: "none", fontWeight: 600, cursor: "pointer", fontSize: 13, padding: "5px 0" }
|
|
3063
4011
|
};
|
|
@@ -3067,7 +4015,10 @@ function WaypointBuilder({
|
|
|
3067
4015
|
onSave,
|
|
3068
4016
|
theme,
|
|
3069
4017
|
className,
|
|
3070
|
-
style
|
|
4018
|
+
style,
|
|
4019
|
+
readOnly = false,
|
|
4020
|
+
appCustomTypes = [],
|
|
4021
|
+
externalEnums = []
|
|
3071
4022
|
}) {
|
|
3072
4023
|
const { loadSchema, schema, selectedStepId, selectedFieldId } = useBuilderStore();
|
|
3073
4024
|
const [previewMode, setPreviewMode] = react.useState(false);
|
|
@@ -3100,14 +4051,15 @@ function WaypointBuilder({
|
|
|
3100
4051
|
setPreviewMode(true);
|
|
3101
4052
|
}
|
|
3102
4053
|
const themeVars = buildThemeVars(theme);
|
|
3103
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...rootStyle, ...themeVars, ...style }, children: [
|
|
4054
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BuilderReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxRuntime.jsx(BuilderCustomTypesContext.Provider, { value: appCustomTypes, children: /* @__PURE__ */ jsxRuntime.jsx(BuilderExternalEnumsContext.Provider, { value: externalEnums, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { ...rootStyle, ...themeVars, ...style }, children: [
|
|
3104
4055
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3105
4056
|
Toolbar,
|
|
3106
4057
|
{
|
|
3107
4058
|
isMobile,
|
|
3108
|
-
|
|
4059
|
+
readOnly,
|
|
4060
|
+
onSave: !previewMode && !readOnly && onSave ? () => onSave(schema) : void 0,
|
|
3109
4061
|
previewMode,
|
|
3110
|
-
onTest: previewMode ? () => setPreviewMode(false) : handleTest
|
|
4062
|
+
onTest: !readOnly ? previewMode ? () => setPreviewMode(false) : handleTest : void 0
|
|
3111
4063
|
}
|
|
3112
4064
|
),
|
|
3113
4065
|
previewMode ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -3115,6 +4067,7 @@ function WaypointBuilder({
|
|
|
3115
4067
|
{
|
|
3116
4068
|
store: previewStoreRef.current,
|
|
3117
4069
|
schema,
|
|
4070
|
+
externalEnums,
|
|
3118
4071
|
onEdit: () => setPreviewMode(false)
|
|
3119
4072
|
}
|
|
3120
4073
|
) : isMobile ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3152,7 +4105,7 @@ function WaypointBuilder({
|
|
|
3152
4105
|
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, overflow: "hidden" }, children: /* @__PURE__ */ jsxRuntime.jsx(FieldEditor, {}) })
|
|
3153
4106
|
] })
|
|
3154
4107
|
] })
|
|
3155
|
-
] });
|
|
4108
|
+
] }) }) }) });
|
|
3156
4109
|
}
|
|
3157
4110
|
var rootStyle = {
|
|
3158
4111
|
display: "flex",
|