@ai-matrx/records-ui 0.78.0 → 0.79.0
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/CHANGELOG.md +29 -0
- package/dist/index.cjs +48 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +48 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.79.0
|
|
4
|
+
|
|
5
|
+
**A joined column says what joins it.** (lane STORE-TAILS-2, VERIFIER-11 finding F5.)
|
|
6
|
+
|
|
7
|
+
Greenline Landscaping Crew's Jobs board, "Job label" joining Job Number and Service Type,
|
|
8
|
+
read `GL-2034mow_edge` on all 35 rows — beside a cell reading `Mow & Edge`. Two wrongs in
|
|
9
|
+
one string. The machine's word is the store's half and is fixed there (`custom.rule_eval`'s
|
|
10
|
+
concat arm now resolves a choice to its label and a relation to its display words through
|
|
11
|
+
`custom.field_words`, while every comparison keeps the stored value). The missing separator
|
|
12
|
+
is this package's: nothing on the field panel ever asked for one, so there was no way to
|
|
13
|
+
send one.
|
|
14
|
+
|
|
15
|
+
* **"Joined by"** — a new box on the worked-out-column builder, offered only for *Join them
|
|
16
|
+
together*, defaulting to ` — `. It is sent as `expr.separator`, which the store has
|
|
17
|
+
accepted since the migration above. Emptying it sends no key at all, which is exactly what
|
|
18
|
+
every formula written before today already holds, so nothing saved changes its answer.
|
|
19
|
+
* A sum, a product or a difference is not offered the box and never sends the key — a
|
|
20
|
+
control that set something the evaluator ignores would be a setting that silently does
|
|
21
|
+
nothing.
|
|
22
|
+
* **The panel reads an existing worked-out column back** — its operation, its columns and
|
|
23
|
+
its separator — instead of starting at "concat" with nothing picked whatever the column
|
|
24
|
+
actually held.
|
|
25
|
+
* **And it says out loud what it still cannot do.** Opening an existing worked-out column
|
|
26
|
+
draws no formula controls (this panel never has), and now it says so in a sentence instead
|
|
27
|
+
of standing silent over the one thing that column is. Re-aiming an existing formula needs
|
|
28
|
+
`expr` on `FieldPatch` in `@ai-matrx/records`; the store door already takes it.
|
|
29
|
+
|
|
30
|
+
Consumer action: none.
|
|
31
|
+
|
|
3
32
|
## 0.78.0
|
|
4
33
|
|
|
5
34
|
**The button that could not get rid of a table now can, and says what it does.** (lane
|
package/dist/index.cjs
CHANGED
|
@@ -5132,6 +5132,9 @@ var ROLLUP_OPERATIONS = ROLLUP_AGG_VALUES.map((value) => ({
|
|
|
5132
5132
|
value,
|
|
5133
5133
|
label: ROLLUP_AGG_LABEL[value]
|
|
5134
5134
|
}));
|
|
5135
|
+
var FORMULA_SEPARATOR_LABEL = "Joined by";
|
|
5136
|
+
var EDITING_A_WORKED_OUT_COLUMN = "This column works out its answer from other columns. Which columns it uses, and what joins them, cannot be changed on this screen yet \u2014 remove it and add it again to change them.";
|
|
5137
|
+
var FORMULA_DEFAULT_SEPARATOR = " \u2014 ";
|
|
5135
5138
|
var FORMULA_OPERATIONS = FORMULA_OP_VALUES.map((value) => ({
|
|
5136
5139
|
value,
|
|
5137
5140
|
label: FORMULA_OP_LABEL[value],
|
|
@@ -5168,8 +5171,9 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
5168
5171
|
const [of, setOf] = (0, import_react30.useState)(String(field?.config?.["of"] ?? ""));
|
|
5169
5172
|
const [relationTarget, setRelationTarget] = (0, import_react30.useState)(String(field?.relation_target ?? ""));
|
|
5170
5173
|
const [display, setDisplay] = (0, import_react30.useState)(field?.display ?? null);
|
|
5171
|
-
const [formulaOp, setFormulaOp] = (0, import_react30.useState)(
|
|
5172
|
-
const [formulaFields, setFormulaFields] = (0, import_react30.useState)(
|
|
5174
|
+
const [formulaOp, setFormulaOp] = (0, import_react30.useState)(() => formulaOpOf(field));
|
|
5175
|
+
const [formulaFields, setFormulaFields] = (0, import_react30.useState)(() => formulaFieldIdsOf(field));
|
|
5176
|
+
const [formulaSeparator, setFormulaSeparator] = (0, import_react30.useState)(() => formulaSeparatorOf(field));
|
|
5173
5177
|
const [askingToRemove, setAskingToRemove] = (0, import_react30.useState)(false);
|
|
5174
5178
|
const [notLanded, setNotLanded] = (0, import_react30.useState)(false);
|
|
5175
5179
|
const others = (0, import_react30.useMemo)(
|
|
@@ -5243,7 +5247,7 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
5243
5247
|
...type === "datetime" ? { kind: withTime ? "datetime" : "date" } : {},
|
|
5244
5248
|
...type === "lookup" ? { via, pick } : {},
|
|
5245
5249
|
...type === "rollup" ? { via, agg, ...agg === "count" ? {} : { of } } : {},
|
|
5246
|
-
...type === "formula" ? { expr: formulaExpression(formulaOp, formulaFields) } : {}
|
|
5250
|
+
...type === "formula" ? { expr: formulaExpression(formulaOp, formulaFields, formulaSeparator) } : {}
|
|
5247
5251
|
};
|
|
5248
5252
|
const written = await mutation.declare({ table_id: tableId, spec });
|
|
5249
5253
|
if (written === null) return;
|
|
@@ -5301,6 +5305,7 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
5301
5305
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-muted-foreground", children: editing ? "What a column holds cannot be changed here \u2014 every value already saved would have to be converted. Add a new column and move the values across." : choice?.explanation ?? "" })
|
|
5302
5306
|
] })
|
|
5303
5307
|
] }),
|
|
5308
|
+
editing && type === "formula" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-muted-foreground", children: EDITING_A_WORKED_OUT_COLUMN }) : null,
|
|
5304
5309
|
!editing || type === "select" || type === "multi_select" || type === "relation" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5305
5310
|
TypeQuestions,
|
|
5306
5311
|
{
|
|
@@ -5329,6 +5334,8 @@ function FieldEditor({ tableId, field, onSaved, onCancel, onRemoved, className }
|
|
|
5329
5334
|
setFormulaOp,
|
|
5330
5335
|
formulaFields,
|
|
5331
5336
|
setFormulaFields,
|
|
5337
|
+
formulaSeparator,
|
|
5338
|
+
setFormulaSeparator,
|
|
5332
5339
|
relations,
|
|
5333
5340
|
others,
|
|
5334
5341
|
existingOptionsTable: Boolean(field?.options_table_id ?? field?.config?.["options_table_id"])
|
|
@@ -5513,10 +5520,30 @@ function startingType(field) {
|
|
|
5513
5520
|
if (fieldTypeChoice(kind)) return kind;
|
|
5514
5521
|
return "text";
|
|
5515
5522
|
}
|
|
5516
|
-
function formulaExpression(op, fieldIds) {
|
|
5523
|
+
function formulaExpression(op, fieldIds, separator) {
|
|
5517
5524
|
const args = fieldIds.filter((id) => id !== "").map((id) => ({ field: id }));
|
|
5518
|
-
|
|
5519
|
-
return { op, args };
|
|
5525
|
+
const joined = op === "concat" && separator !== "" ? { separator } : {};
|
|
5526
|
+
if (args.length === 0) return { op, ...joined, args: [{ const: "" }] };
|
|
5527
|
+
return { op, ...joined, args };
|
|
5528
|
+
}
|
|
5529
|
+
function formulaExprOf(field) {
|
|
5530
|
+
const expr = field?.config?.["expr"];
|
|
5531
|
+
return expr !== null && typeof expr === "object" ? expr : null;
|
|
5532
|
+
}
|
|
5533
|
+
function formulaOpOf(field) {
|
|
5534
|
+
const op = formulaExprOf(field)?.["op"];
|
|
5535
|
+
return typeof op === "string" && op !== "" ? op : "concat";
|
|
5536
|
+
}
|
|
5537
|
+
function formulaFieldIdsOf(field) {
|
|
5538
|
+
const args = formulaExprOf(field)?.["args"];
|
|
5539
|
+
if (!Array.isArray(args)) return [];
|
|
5540
|
+
return args.map((a) => a !== null && typeof a === "object" ? a["field"] : void 0).filter((id) => typeof id === "string" && id !== "");
|
|
5541
|
+
}
|
|
5542
|
+
function formulaSeparatorOf(field) {
|
|
5543
|
+
const expr = formulaExprOf(field);
|
|
5544
|
+
if (expr === null) return FORMULA_DEFAULT_SEPARATOR;
|
|
5545
|
+
const sep = expr["separator"];
|
|
5546
|
+
return typeof sep === "string" ? sep : "";
|
|
5520
5547
|
}
|
|
5521
5548
|
function TypeQuestions(props) {
|
|
5522
5549
|
const { type } = props;
|
|
@@ -5655,7 +5682,21 @@ function TypeQuestions(props) {
|
|
|
5655
5682
|
);
|
|
5656
5683
|
}) }),
|
|
5657
5684
|
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "In the order you pick them. Columns are remembered by which column they are, so renaming one never breaks this." })
|
|
5658
|
-
] })
|
|
5685
|
+
] }),
|
|
5686
|
+
props.formulaOp === "concat" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex flex-col gap-1", children: [
|
|
5687
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_design_system15.Label, { className: "text-xs", children: FORMULA_SEPARATOR_LABEL }),
|
|
5688
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
5689
|
+
import_design_system15.BasicInput,
|
|
5690
|
+
{
|
|
5691
|
+
value: props.formulaSeparator,
|
|
5692
|
+
"aria-label": FORMULA_SEPARATOR_LABEL,
|
|
5693
|
+
placeholder: "\u2014",
|
|
5694
|
+
className: "max-w-[10rem]",
|
|
5695
|
+
onChange: (e) => props.setFormulaSeparator(e.target.value)
|
|
5696
|
+
}
|
|
5697
|
+
),
|
|
5698
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-[11px] text-muted-foreground", children: "What goes between the columns. Leave it empty to run them straight together." })
|
|
5699
|
+
] }) : null
|
|
5659
5700
|
] });
|
|
5660
5701
|
}
|
|
5661
5702
|
return null;
|