@ai-matrx/records-ui 0.58.0 → 0.59.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 +24 -0
- package/dist/index.cjs +46 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +46 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.59.0
|
|
4
|
+
|
|
5
|
+
**Three things the browser walks found by using the builders on real businesses.**
|
|
6
|
+
|
|
7
|
+
* **A booking page's day rows lied about what it would offer.** Every day started
|
|
8
|
+
unticked and read "not taking bookings", while `custom._booking_availability`
|
|
9
|
+
substitutes Monday-to-Friday nine-to-five for an empty window list — so a
|
|
10
|
+
person who saved without touching the days was told the page offered nothing
|
|
11
|
+
and got a page offering the whole working week. `BookingBuilder` now opens on
|
|
12
|
+
the working week, and once the store has answered, the rows are ITS answer.
|
|
13
|
+
* **Both builders offered questions a stranger could never answer.** Ironclad
|
|
14
|
+
Mobile Mechanic ticked "Customer" on his booking page — a relation Field — a
|
|
15
|
+
visitor typed her name, and the store refused at the last step with *"Customer
|
|
16
|
+
points at something that is not there"*, after her slot was already held. A
|
|
17
|
+
relation holds the identity of a record in a Table she cannot open. The new
|
|
18
|
+
`publiclyAnswerable` / `askableFields` / `whyNotAskable` decide what a public
|
|
19
|
+
page may ask for (out: relation, member, attachment, formula, lookup, rollup)
|
|
20
|
+
and both `FormBuilder` and `BookingBuilder` use them — the Fields left out are
|
|
21
|
+
NAMED with the reason, in the place somebody would have ticked them.
|
|
22
|
+
* The Booking and Portal builders and the Digest scheduler carry the container
|
|
23
|
+
queries 0.57.0 gave the form builder, so all four are one column in a rail.
|
|
24
|
+
|
|
25
|
+
**Consumer action:** none.
|
|
26
|
+
|
|
3
27
|
## 0.58.0
|
|
4
28
|
|
|
5
29
|
**A word pasted into a choice column becomes that option — and a paste is no
|
package/dist/index.cjs
CHANGED
|
@@ -156,6 +156,7 @@ __export(src_exports, {
|
|
|
156
156
|
actorBadge: () => actorBadge,
|
|
157
157
|
actorWords: () => actorWords,
|
|
158
158
|
addFields: () => addFields,
|
|
159
|
+
askableFields: () => askableFields,
|
|
159
160
|
blockFromSpec: () => blockFromSpec,
|
|
160
161
|
bodyForReading: () => bodyForReading,
|
|
161
162
|
bodyFromKeys: () => bodyFromKeys,
|
|
@@ -208,6 +209,7 @@ __export(src_exports, {
|
|
|
208
209
|
presentationDocument: () => presentationDocument,
|
|
209
210
|
presentationIsEmpty: () => presentationIsEmpty,
|
|
210
211
|
previewLine: () => previewLine,
|
|
212
|
+
publiclyAnswerable: () => publiclyAnswerable,
|
|
211
213
|
recordName: () => recordName,
|
|
212
214
|
recordsDataSource: () => recordsDataSource,
|
|
213
215
|
refusalForAPerson: () => refusalForAPerson,
|
|
@@ -244,7 +246,8 @@ __export(src_exports, {
|
|
|
244
246
|
whatIsMissing: () => whatIsMissing,
|
|
245
247
|
whatYouMayDo: () => whatYouMayDo,
|
|
246
248
|
whatYouMayDoWithTable: () => whatYouMayDoWithTable,
|
|
247
|
-
whenWords: () => whenWords
|
|
249
|
+
whenWords: () => whenWords,
|
|
250
|
+
whyNotAskable: () => whyNotAskable
|
|
248
251
|
});
|
|
249
252
|
module.exports = __toCommonJS(src_exports);
|
|
250
253
|
|
|
@@ -10604,6 +10607,28 @@ function Question({
|
|
|
10604
10607
|
] });
|
|
10605
10608
|
}
|
|
10606
10609
|
|
|
10610
|
+
// src/publicQuestions.ts
|
|
10611
|
+
var CANNOT_ASK = {
|
|
10612
|
+
relation: "points at a record in another table, and somebody with no account cannot see that table to pick from it",
|
|
10613
|
+
member: "is a person in this organization, and somebody outside it has no way to choose one",
|
|
10614
|
+
attachment: "holds a file in your own store, and a public page has nowhere to put one yet",
|
|
10615
|
+
formula: "is worked out by the store, so there is nothing for anybody to answer",
|
|
10616
|
+
lookup: "is read through a relation, so the store fills it in",
|
|
10617
|
+
rollup: "is added up by the store, so there is nothing for anybody to answer"
|
|
10618
|
+
};
|
|
10619
|
+
function publiclyAnswerable(field) {
|
|
10620
|
+
return !(field.type in CANNOT_ASK);
|
|
10621
|
+
}
|
|
10622
|
+
function askableFields(fields, hidden = []) {
|
|
10623
|
+
return fields.filter((f) => publiclyAnswerable(f) && !hidden.includes(f.key));
|
|
10624
|
+
}
|
|
10625
|
+
function whyNotAskable(fields, hidden = []) {
|
|
10626
|
+
const left = fields.filter((f) => !publiclyAnswerable(f) && !hidden.includes(f.key));
|
|
10627
|
+
if (left.length === 0) return null;
|
|
10628
|
+
const said = left.map((f) => `${f.label || f.key} ${CANNOT_ASK[f.type]}`);
|
|
10629
|
+
return said.length === 1 ? `${said[0]}, so it is not offered here.` : `These are not offered here: ${said.join("; ")}.`;
|
|
10630
|
+
}
|
|
10631
|
+
|
|
10607
10632
|
// src/FormBuilder.tsx
|
|
10608
10633
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
10609
10634
|
function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
@@ -10836,7 +10861,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
10836
10861
|
" fields"
|
|
10837
10862
|
] })
|
|
10838
10863
|
] }),
|
|
10839
|
-
(fields.data ?? []).map((field) => {
|
|
10864
|
+
askableFields(fields.data ?? []).map((field) => {
|
|
10840
10865
|
const index = draft.questions.findIndex((q) => q.field === field.key);
|
|
10841
10866
|
const asked = index >= 0;
|
|
10842
10867
|
const question = asked ? draft.questions[index] : null;
|
|
@@ -10888,6 +10913,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, className }) {
|
|
|
10888
10913
|
] }) : null
|
|
10889
10914
|
] }, field.id);
|
|
10890
10915
|
}),
|
|
10916
|
+
whyNotAskable(fields.data ?? []) ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("p", { className: "text-xs text-muted-foreground", children: whyNotAskable(fields.data ?? []) }) : null,
|
|
10891
10917
|
draft.questions.filter((q) => !byKey.has(q.field)).map((q) => /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("p", { className: "text-xs text-destructive", children: [
|
|
10892
10918
|
'This form asks for "',
|
|
10893
10919
|
q.field,
|
|
@@ -12543,6 +12569,7 @@ var DAYS = [
|
|
|
12543
12569
|
{ weekday: 0, label: "Sun" }
|
|
12544
12570
|
];
|
|
12545
12571
|
var LENGTHS = [15, 20, 30, 45, 60, 90, 120];
|
|
12572
|
+
var WORKING_WEEK = /* @__PURE__ */ new Set([1, 2, 3, 4, 5]);
|
|
12546
12573
|
function draftWindows(availability) {
|
|
12547
12574
|
return DAYS.map((day) => {
|
|
12548
12575
|
const found = availability?.windows.find((w) => w.weekday === day.weekday);
|
|
@@ -12550,7 +12577,7 @@ function draftWindows(availability) {
|
|
|
12550
12577
|
weekday: day.weekday,
|
|
12551
12578
|
from: found?.from ?? "09:00",
|
|
12552
12579
|
to: found?.to ?? "17:00",
|
|
12553
|
-
on: Boolean(found)
|
|
12580
|
+
on: availability ? Boolean(found) : WORKING_WEEK.has(day.weekday)
|
|
12554
12581
|
};
|
|
12555
12582
|
});
|
|
12556
12583
|
}
|
|
@@ -12579,9 +12606,11 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
12579
12606
|
const [formId, setFormId] = (0, import_react90.useState)(bookingId ?? null);
|
|
12580
12607
|
const publicOrigin = host.publicOrigin ?? (typeof window === "undefined" ? "" : window.location.origin);
|
|
12581
12608
|
const askable = (0, import_react90.useMemo)(
|
|
12582
|
-
() => (fields.data ?? [])
|
|
12583
|
-
|
|
12584
|
-
|
|
12609
|
+
() => askableFields(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
12610
|
+
[fields.data]
|
|
12611
|
+
);
|
|
12612
|
+
const leftOut = (0, import_react90.useMemo)(
|
|
12613
|
+
() => whyNotAskable(fields.data ?? [], STORE_ANSWERS_THESE),
|
|
12585
12614
|
[fields.data]
|
|
12586
12615
|
);
|
|
12587
12616
|
const load = (0, import_react90.useCallback)(async () => {
|
|
@@ -12607,6 +12636,15 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
12607
12636
|
if (!existing) return;
|
|
12608
12637
|
setMinutes(existing.slot_minutes);
|
|
12609
12638
|
}, [existing]);
|
|
12639
|
+
(0, import_react90.useEffect)(() => {
|
|
12640
|
+
if (!offer) return;
|
|
12641
|
+
setWindows(draftWindows(offer));
|
|
12642
|
+
setMinutes(offer.slot_minutes);
|
|
12643
|
+
setBuffer(offer.buffer_minutes);
|
|
12644
|
+
setLead(offer.lead_minutes);
|
|
12645
|
+
setPerDay(offer.max_per_day);
|
|
12646
|
+
setDays(offer.days);
|
|
12647
|
+
}, [offer]);
|
|
12610
12648
|
const availability = (0, import_react90.useCallback)(
|
|
12611
12649
|
() => ({
|
|
12612
12650
|
slot_minutes: minutes,
|
|
@@ -12794,7 +12832,8 @@ function BookingBuilder({ tableId, bookingId, onSaved, onClose, className }) {
|
|
|
12794
12832
|
),
|
|
12795
12833
|
fieldName(f)
|
|
12796
12834
|
] }, f.key)) }),
|
|
12797
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "text-xs text-muted-foreground", children: "The time, whether it is booked or cancelled, and who it is with are filled in by the store \u2014 a booking page cannot ask a visitor for any of the three." })
|
|
12835
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "text-xs text-muted-foreground", children: "The time, whether it is booked or cancelled, and who it is with are filled in by the store \u2014 a booking page cannot ask a visitor for any of the three." }),
|
|
12836
|
+
leftOut ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "text-xs text-muted-foreground", children: leftOut }) : null
|
|
12798
12837
|
] }),
|
|
12799
12838
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("label", { className: "flex flex-col gap-1", children: [
|
|
12800
12839
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_design_system45.Label, { className: "text-xs font-medium", children: "What they see after booking" }),
|