@camstack/ui-library 1.2.260 → 1.2.261
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 +57 -16
- package/dist/index.js +57 -16
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -29241,6 +29241,13 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
29241
29241
|
};
|
|
29242
29242
|
const canRemove = rows.length > minRows;
|
|
29243
29243
|
const canAdd = rows.length < maxRows;
|
|
29244
|
+
const idKey = field.itemIdKey ?? "id";
|
|
29245
|
+
const rowReactKey = (row, idx) => {
|
|
29246
|
+
const raw = row[idKey];
|
|
29247
|
+
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
29248
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
29249
|
+
return `row-${String(idx)}`;
|
|
29250
|
+
};
|
|
29244
29251
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
29245
29252
|
className: "col-span-full space-y-2",
|
|
29246
29253
|
children: [
|
|
@@ -29287,7 +29294,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
29287
29294
|
onAction
|
|
29288
29295
|
}, sub.key))
|
|
29289
29296
|
})]
|
|
29290
|
-
}, idx))
|
|
29297
|
+
}, rowReactKey(row, idx)))
|
|
29291
29298
|
}),
|
|
29292
29299
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
29293
29300
|
type: "button",
|
|
@@ -30166,23 +30173,44 @@ var Chevron$1 = ({ open }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg",
|
|
|
30166
30173
|
"aria-hidden": true,
|
|
30167
30174
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("polyline", { points: "9 18 15 12 9 6" })
|
|
30168
30175
|
});
|
|
30176
|
+
function isValueBearingField(f) {
|
|
30177
|
+
return f.type !== "separator" && f.type !== "info" && f.type !== "button" && f.type !== "group";
|
|
30178
|
+
}
|
|
30169
30179
|
function extractValues(schema) {
|
|
30170
30180
|
const out = {};
|
|
30171
30181
|
if (!schema) return out;
|
|
30172
30182
|
for (const s of schema.sections) for (const f of s.fields) {
|
|
30173
|
-
if (f
|
|
30183
|
+
if (!isValueBearingField(f)) continue;
|
|
30174
30184
|
const key = f.key;
|
|
30175
30185
|
out[key] = f.value;
|
|
30176
30186
|
}
|
|
30177
30187
|
return out;
|
|
30178
30188
|
}
|
|
30189
|
+
/** Paint operator edits into the hydrated schema so controlled inputs keep focus. */
|
|
30190
|
+
function applyValuesToSchema(schema, nextValues) {
|
|
30191
|
+
return {
|
|
30192
|
+
...schema,
|
|
30193
|
+
sections: schema.sections.map((s) => ({
|
|
30194
|
+
...s,
|
|
30195
|
+
fields: s.fields.map((f) => {
|
|
30196
|
+
if (!isValueBearingField(f)) return f;
|
|
30197
|
+
const key = f.key;
|
|
30198
|
+
if (!(key in nextValues)) return f;
|
|
30199
|
+
return {
|
|
30200
|
+
...f,
|
|
30201
|
+
value: nextValues[key]
|
|
30202
|
+
};
|
|
30203
|
+
})
|
|
30204
|
+
}))
|
|
30205
|
+
};
|
|
30206
|
+
}
|
|
30179
30207
|
function stripValues(schema) {
|
|
30180
30208
|
return {
|
|
30181
30209
|
...schema,
|
|
30182
30210
|
sections: schema.sections.map((s) => ({
|
|
30183
30211
|
...s,
|
|
30184
30212
|
fields: s.fields.map((f) => {
|
|
30185
|
-
if (f
|
|
30213
|
+
if (!isValueBearingField(f)) return f;
|
|
30186
30214
|
const { value: _drop, ...rest } = f;
|
|
30187
30215
|
return rest;
|
|
30188
30216
|
})
|
|
@@ -30198,6 +30226,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30198
30226
|
const [open, setOpen] = (0, react$1.useState)(defaultOpen ?? false);
|
|
30199
30227
|
const [overrideValues, setOverrideValues] = (0, react$1.useState)({});
|
|
30200
30228
|
const [baseValues, setBaseValues] = (0, react$1.useState)(null);
|
|
30229
|
+
/** Bumps on every persist edit; a stale refetch must not clobber a newer local paint. */
|
|
30230
|
+
const persistSeq = (0, react$1.useRef)(0);
|
|
30201
30231
|
(0, react$1.useEffect)(() => {
|
|
30202
30232
|
setBaseValues(null);
|
|
30203
30233
|
setOverrideValues({});
|
|
@@ -30266,7 +30296,10 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30266
30296
|
const patch = {};
|
|
30267
30297
|
for (const k of Object.keys(nextValues)) if (nextValues[k] !== values[k]) patch[k] = nextValues[k];
|
|
30268
30298
|
if (Object.keys(patch).length === 0) return;
|
|
30299
|
+
const seq = ++persistSeq.current;
|
|
30300
|
+
setHydrated((prev) => prev === null ? prev : applyValuesToSchema(prev, nextValues));
|
|
30269
30301
|
setSaving(true);
|
|
30302
|
+
setError(null);
|
|
30270
30303
|
try {
|
|
30271
30304
|
await trpc.addonSettings.updateGlobalSettings.mutate({
|
|
30272
30305
|
addonId,
|
|
@@ -30277,12 +30310,12 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30277
30310
|
addonId,
|
|
30278
30311
|
nodeId
|
|
30279
30312
|
});
|
|
30280
|
-
if (next) setHydrated(next);
|
|
30281
|
-
onAfterChange?.();
|
|
30313
|
+
if (next && seq === persistSeq.current) setHydrated(next);
|
|
30314
|
+
if (seq === persistSeq.current) onAfterChange?.();
|
|
30282
30315
|
} catch (err) {
|
|
30283
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
30316
|
+
if (seq === persistSeq.current) setError(err instanceof Error ? err.message : String(err));
|
|
30284
30317
|
} finally {
|
|
30285
|
-
setSaving(false);
|
|
30318
|
+
if (seq === persistSeq.current) setSaving(false);
|
|
30286
30319
|
}
|
|
30287
30320
|
};
|
|
30288
30321
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -30314,15 +30347,23 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30314
30347
|
...values,
|
|
30315
30348
|
...overrideValues
|
|
30316
30349
|
} : values;
|
|
30317
|
-
const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
30318
|
-
|
|
30319
|
-
|
|
30320
|
-
|
|
30321
|
-
|
|
30322
|
-
|
|
30323
|
-
|
|
30324
|
-
|
|
30325
|
-
|
|
30350
|
+
const body = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
30351
|
+
effectiveMode === "override" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
30352
|
+
className: "mb-2 text-[11px] text-foreground-subtle",
|
|
30353
|
+
children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
|
|
30354
|
+
}) : null,
|
|
30355
|
+
saving ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
30356
|
+
className: "mb-2 text-[11px] text-foreground-subtle",
|
|
30357
|
+
"aria-live": "polite",
|
|
30358
|
+
children: "Saving…"
|
|
30359
|
+
}) : null,
|
|
30360
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigFormBuilder, {
|
|
30361
|
+
schema: schemaNoValues,
|
|
30362
|
+
values: effectiveValues,
|
|
30363
|
+
onChange: handleChange,
|
|
30364
|
+
disabled: disabled === true
|
|
30365
|
+
})
|
|
30366
|
+
] });
|
|
30326
30367
|
if (collapsible === true) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
30327
30368
|
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
30328
30369
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
package/dist/index.js
CHANGED
|
@@ -29217,6 +29217,13 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
29217
29217
|
};
|
|
29218
29218
|
const canRemove = rows.length > minRows;
|
|
29219
29219
|
const canAdd = rows.length < maxRows;
|
|
29220
|
+
const idKey = field.itemIdKey ?? "id";
|
|
29221
|
+
const rowReactKey = (row, idx) => {
|
|
29222
|
+
const raw = row[idKey];
|
|
29223
|
+
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
29224
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
29225
|
+
return `row-${String(idx)}`;
|
|
29226
|
+
};
|
|
29220
29227
|
return /* @__PURE__ */ jsxs("div", {
|
|
29221
29228
|
className: "col-span-full space-y-2",
|
|
29222
29229
|
children: [
|
|
@@ -29263,7 +29270,7 @@ function EditableArrayField({ field, value, onChange, disabled, translationFn, o
|
|
|
29263
29270
|
onAction
|
|
29264
29271
|
}, sub.key))
|
|
29265
29272
|
})]
|
|
29266
|
-
}, idx))
|
|
29273
|
+
}, rowReactKey(row, idx)))
|
|
29267
29274
|
}),
|
|
29268
29275
|
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("button", {
|
|
29269
29276
|
type: "button",
|
|
@@ -30142,23 +30149,44 @@ var Chevron$1 = ({ open }) => /* @__PURE__ */ jsx("svg", {
|
|
|
30142
30149
|
"aria-hidden": true,
|
|
30143
30150
|
children: /* @__PURE__ */ jsx("polyline", { points: "9 18 15 12 9 6" })
|
|
30144
30151
|
});
|
|
30152
|
+
function isValueBearingField(f) {
|
|
30153
|
+
return f.type !== "separator" && f.type !== "info" && f.type !== "button" && f.type !== "group";
|
|
30154
|
+
}
|
|
30145
30155
|
function extractValues(schema) {
|
|
30146
30156
|
const out = {};
|
|
30147
30157
|
if (!schema) return out;
|
|
30148
30158
|
for (const s of schema.sections) for (const f of s.fields) {
|
|
30149
|
-
if (f
|
|
30159
|
+
if (!isValueBearingField(f)) continue;
|
|
30150
30160
|
const key = f.key;
|
|
30151
30161
|
out[key] = f.value;
|
|
30152
30162
|
}
|
|
30153
30163
|
return out;
|
|
30154
30164
|
}
|
|
30165
|
+
/** Paint operator edits into the hydrated schema so controlled inputs keep focus. */
|
|
30166
|
+
function applyValuesToSchema(schema, nextValues) {
|
|
30167
|
+
return {
|
|
30168
|
+
...schema,
|
|
30169
|
+
sections: schema.sections.map((s) => ({
|
|
30170
|
+
...s,
|
|
30171
|
+
fields: s.fields.map((f) => {
|
|
30172
|
+
if (!isValueBearingField(f)) return f;
|
|
30173
|
+
const key = f.key;
|
|
30174
|
+
if (!(key in nextValues)) return f;
|
|
30175
|
+
return {
|
|
30176
|
+
...f,
|
|
30177
|
+
value: nextValues[key]
|
|
30178
|
+
};
|
|
30179
|
+
})
|
|
30180
|
+
}))
|
|
30181
|
+
};
|
|
30182
|
+
}
|
|
30155
30183
|
function stripValues(schema) {
|
|
30156
30184
|
return {
|
|
30157
30185
|
...schema,
|
|
30158
30186
|
sections: schema.sections.map((s) => ({
|
|
30159
30187
|
...s,
|
|
30160
30188
|
fields: s.fields.map((f) => {
|
|
30161
|
-
if (f
|
|
30189
|
+
if (!isValueBearingField(f)) return f;
|
|
30162
30190
|
const { value: _drop, ...rest } = f;
|
|
30163
30191
|
return rest;
|
|
30164
30192
|
})
|
|
@@ -30174,6 +30202,8 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30174
30202
|
const [open, setOpen] = useState(defaultOpen ?? false);
|
|
30175
30203
|
const [overrideValues, setOverrideValues] = useState({});
|
|
30176
30204
|
const [baseValues, setBaseValues] = useState(null);
|
|
30205
|
+
/** Bumps on every persist edit; a stale refetch must not clobber a newer local paint. */
|
|
30206
|
+
const persistSeq = useRef(0);
|
|
30177
30207
|
useEffect(() => {
|
|
30178
30208
|
setBaseValues(null);
|
|
30179
30209
|
setOverrideValues({});
|
|
@@ -30242,7 +30272,10 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30242
30272
|
const patch = {};
|
|
30243
30273
|
for (const k of Object.keys(nextValues)) if (nextValues[k] !== values[k]) patch[k] = nextValues[k];
|
|
30244
30274
|
if (Object.keys(patch).length === 0) return;
|
|
30275
|
+
const seq = ++persistSeq.current;
|
|
30276
|
+
setHydrated((prev) => prev === null ? prev : applyValuesToSchema(prev, nextValues));
|
|
30245
30277
|
setSaving(true);
|
|
30278
|
+
setError(null);
|
|
30246
30279
|
try {
|
|
30247
30280
|
await trpc.addonSettings.updateGlobalSettings.mutate({
|
|
30248
30281
|
addonId,
|
|
@@ -30253,12 +30286,12 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30253
30286
|
addonId,
|
|
30254
30287
|
nodeId
|
|
30255
30288
|
});
|
|
30256
|
-
if (next) setHydrated(next);
|
|
30257
|
-
onAfterChange?.();
|
|
30289
|
+
if (next && seq === persistSeq.current) setHydrated(next);
|
|
30290
|
+
if (seq === persistSeq.current) onAfterChange?.();
|
|
30258
30291
|
} catch (err) {
|
|
30259
|
-
setError(err instanceof Error ? err.message : String(err));
|
|
30292
|
+
if (seq === persistSeq.current) setError(err instanceof Error ? err.message : String(err));
|
|
30260
30293
|
} finally {
|
|
30261
|
-
setSaving(false);
|
|
30294
|
+
if (seq === persistSeq.current) setSaving(false);
|
|
30262
30295
|
}
|
|
30263
30296
|
};
|
|
30264
30297
|
if (loading) return /* @__PURE__ */ jsxs("div", {
|
|
@@ -30290,15 +30323,23 @@ function AddonGlobalSettingsForm({ trpc, addonId, nodeId, title, disabled, onAft
|
|
|
30290
30323
|
...values,
|
|
30291
30324
|
...overrideValues
|
|
30292
30325
|
} : values;
|
|
30293
|
-
const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
30294
|
-
|
|
30295
|
-
|
|
30296
|
-
|
|
30297
|
-
|
|
30298
|
-
|
|
30299
|
-
|
|
30300
|
-
|
|
30301
|
-
|
|
30326
|
+
const body = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
30327
|
+
effectiveMode === "override" ? /* @__PURE__ */ jsx("div", {
|
|
30328
|
+
className: "mb-2 text-[11px] text-foreground-subtle",
|
|
30329
|
+
children: "Benchmark override — applies to this run only. The addon's saved settings are not changed."
|
|
30330
|
+
}) : null,
|
|
30331
|
+
saving ? /* @__PURE__ */ jsx("div", {
|
|
30332
|
+
className: "mb-2 text-[11px] text-foreground-subtle",
|
|
30333
|
+
"aria-live": "polite",
|
|
30334
|
+
children: "Saving…"
|
|
30335
|
+
}) : null,
|
|
30336
|
+
/* @__PURE__ */ jsx(ConfigFormBuilder, {
|
|
30337
|
+
schema: schemaNoValues,
|
|
30338
|
+
values: effectiveValues,
|
|
30339
|
+
onChange: handleChange,
|
|
30340
|
+
disabled: disabled === true
|
|
30341
|
+
})
|
|
30342
|
+
] });
|
|
30302
30343
|
if (collapsible === true) return /* @__PURE__ */ jsxs("section", {
|
|
30303
30344
|
className: "rounded-lg border border-border bg-surface overflow-hidden",
|
|
30304
30345
|
children: [/* @__PURE__ */ jsxs("button", {
|