@ai-matrx/records-ui 0.107.0 → 0.107.1
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 +6 -0
- package/dist/index.cjs +66 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +66 -17
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records-ui
|
|
2
2
|
|
|
3
|
+
## 0.107.1
|
|
4
|
+
|
|
5
|
+
TYPEFORM-2 resume: "Email the respondent" in Notify on answer — off by default, enabled only when the form has an email question, kept as `presentation.notify.email_respondent` + `respondent_field` and sent by `custom.form_respondent_copy` through the platform notification sender, worded from the ending reached. The builder preview and its two option boxes follow the organization's knobs (`client.formKnobs`, records 0.80.4) under the form's own override.
|
|
6
|
+
|
|
7
|
+
**Consumer action:** none; install records 0.80.4 with it.
|
|
8
|
+
|
|
3
9
|
## 0.107.0
|
|
4
10
|
|
|
5
11
|
TYPEFORM-2, the second pass on forms against Typeform. Runner: Next/Enter refuse an empty required answer ("This field is required") or a bad email / phone / link ("Enter a valid email" …), announced in an `aria-live` alert with the caret kept in the answer, and the old "still needs an answer" line is gone; one large centred question (question ≥ 20 px, answer ≥ 16 px) filling the screen; "press Enter ↵" beside Next; a single choice moves on after a pick (`autoAdvance` prop / `FormSpec.autoAdvance`, default on — knob `forms/choice_auto_advance`); arrow keys move and pick inside the radiogroup and Back lands on the picked choice; focus lands in the first answer after Start; the count is hidden until the store has answered the route once; progress bar `aria-label`; `{{question}}` recall in question words, help and endings (`pipeAnswers`); runner sentences are labels with tooltips. Inputs: email / phone / link carry `inputmode` and `autocomplete`. `FormLookFrame showOwnerHeader` (knob `forms/show_owner_header`, per-form `FormSpec.showOwnerHeader`). Builder: questions listed in respondent order with drag-to-reorder (dnd-kit), unasked fields as "+" chips, the live preview beside the editor (the container query asked itself and never fired), "Notify on answer": Email me (the owner's email subscription, made and handed to the form) and a webhook (a `form_answered` automation, kept as `presentation.notify`); "Show our logo and name" and "Next after a choice" per form; conditions show option labels and badge a missing question. Results: category ticks wrap at words (`wrapTickWords`).
|
package/dist/index.cjs
CHANGED
|
@@ -37957,14 +37957,26 @@ function formPresentation(spec) {
|
|
|
37957
37957
|
theme: themeDocument(spec.theme ?? null),
|
|
37958
37958
|
...typeof spec.showOwnerHeader === "boolean" ? { show_owner_header: spec.showOwnerHeader } : {},
|
|
37959
37959
|
...typeof spec.autoAdvance === "boolean" ? { auto_advance: spec.autoAdvance } : {},
|
|
37960
|
-
...spec.notify && (spec.notify.webhookUrl || spec.notify.webhookAutomationId
|
|
37960
|
+
...spec.notify && (spec.notify.webhookUrl || spec.notify.webhookAutomationId || spec.notify.emailRespondent) ? {
|
|
37961
|
+
notify: strip({
|
|
37962
|
+
webhook_url: text(spec.notify.webhookUrl),
|
|
37963
|
+
webhook_automation_id: text(spec.notify.webhookAutomationId),
|
|
37964
|
+
email_respondent: spec.notify.emailRespondent ? true : null,
|
|
37965
|
+
respondent_field: spec.notify.emailRespondent ? text(spec.notify.respondentField) : null
|
|
37966
|
+
})
|
|
37967
|
+
} : {}
|
|
37961
37968
|
};
|
|
37962
37969
|
}
|
|
37963
37970
|
function notifyFromDocument(raw) {
|
|
37964
37971
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
|
|
37965
37972
|
const d = raw;
|
|
37966
|
-
const n = {
|
|
37967
|
-
|
|
37973
|
+
const n = {
|
|
37974
|
+
webhookUrl: text(d["webhook_url"]),
|
|
37975
|
+
webhookAutomationId: text(d["webhook_automation_id"]),
|
|
37976
|
+
emailRespondent: d["email_respondent"] === true ? true : null,
|
|
37977
|
+
respondentField: text(d["respondent_field"])
|
|
37978
|
+
};
|
|
37979
|
+
return n.webhookUrl || n.webhookAutomationId || n.emailRespondent ? n : null;
|
|
37968
37980
|
}
|
|
37969
37981
|
var bool = (v) => typeof v === "boolean" ? v : null;
|
|
37970
37982
|
function answerRefusal(kind, required, value) {
|
|
@@ -42545,6 +42557,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
42545
42557
|
const [shownUrl, setShownUrl] = (0, import_react232.useState)(null);
|
|
42546
42558
|
const [lookOptions, setLookOptions] = (0, import_react232.useState)(null);
|
|
42547
42559
|
const [lookUnread, setLookUnread] = (0, import_react232.useState)(null);
|
|
42560
|
+
const [orgKnobs, setOrgKnobs] = (0, import_react232.useState)(null);
|
|
42548
42561
|
const [restoredAt, setRestoredAt] = (0, import_react232.useState)(null);
|
|
42549
42562
|
const [showResults, setShowResults] = (0, import_react232.useState)(false);
|
|
42550
42563
|
const [adding, setAdding] = (0, import_react232.useState)(false);
|
|
@@ -42581,6 +42594,15 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
42581
42594
|
(0, import_react232.useEffect)(() => {
|
|
42582
42595
|
void load();
|
|
42583
42596
|
}, [load]);
|
|
42597
|
+
(0, import_react232.useEffect)(() => {
|
|
42598
|
+
let cancelled = false;
|
|
42599
|
+
Promise.resolve().then(() => client.formKnobs()).then((r) => {
|
|
42600
|
+
if (!cancelled && r.ok) setOrgKnobs(r.data);
|
|
42601
|
+
}).catch(() => void 0);
|
|
42602
|
+
return () => {
|
|
42603
|
+
cancelled = true;
|
|
42604
|
+
};
|
|
42605
|
+
}, [client]);
|
|
42584
42606
|
(0, import_react232.useEffect)(() => {
|
|
42585
42607
|
if (!forms || forms.length === 0) return;
|
|
42586
42608
|
if (createOnMount && makeOnMount !== "made") return;
|
|
@@ -42881,6 +42903,11 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
42881
42903
|
formName: draft.name,
|
|
42882
42904
|
ruleId: draft.notifyRuleId,
|
|
42883
42905
|
notify: draft.notify ?? null,
|
|
42906
|
+
emailQuestion: (
|
|
42907
|
+
// An email field first; else a question whose field is named for an email (an imported
|
|
42908
|
+
// "Contact email" kept as text). The store's resolver refuses an answer that is not one.
|
|
42909
|
+
(draft.questions.map((q) => byKey.get(q.field)).find((f) => f && String(editorKindFor(f)) === "email") ?? draft.questions.map((q) => byKey.get(q.field)).find((f) => f && /e-?mail/i.test(`${f.key} ${f.label ?? ""}`)))?.key ?? null
|
|
42910
|
+
),
|
|
42884
42911
|
onRule: (ruleId) => void chooseNotify(ruleId),
|
|
42885
42912
|
onNotify: (notify) => void chooseWebhook(notify)
|
|
42886
42913
|
}
|
|
@@ -42890,7 +42917,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
42890
42917
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|
|
42891
42918
|
import_design_system118.Checkbox,
|
|
42892
42919
|
{
|
|
42893
|
-
checked: draft.showOwnerHeader ?? true,
|
|
42920
|
+
checked: draft.showOwnerHeader ?? orgKnobs?.show_owner_header ?? true,
|
|
42894
42921
|
onCheckedChange: (checked) => patch({ showOwnerHeader: checked === true }),
|
|
42895
42922
|
"aria-label": "Show our logo and name"
|
|
42896
42923
|
}
|
|
@@ -42901,7 +42928,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
42901
42928
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|
|
42902
42929
|
import_design_system118.Checkbox,
|
|
42903
42930
|
{
|
|
42904
|
-
checked: draft.autoAdvance ?? true,
|
|
42931
|
+
checked: draft.autoAdvance ?? orgKnobs?.choice_auto_advance ?? true,
|
|
42905
42932
|
onCheckedChange: (checked) => patch({ autoAdvance: checked === true }),
|
|
42906
42933
|
"aria-label": "Next after a choice"
|
|
42907
42934
|
}
|
|
@@ -43070,7 +43097,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
|
|
|
43070
43097
|
{
|
|
43071
43098
|
className: "w-full shrink-0 overflow-auto rounded border p-2 @3xl:sticky @3xl:top-2 @3xl:max-h-[calc(100dvh-6rem)] @3xl:w-[min(45%,520px)]",
|
|
43072
43099
|
"data-records-form-preview": "",
|
|
43073
|
-
children: showResults && stored ? /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormResultsPanel, { form: stored }) : /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormLookFrame, { look: lookOptions?.look ?? null, title: draft.name, contained: true, showOwnerHeader: draft.showOwnerHeader ?? true, children: /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormRunner, { form: draft, preview: true }) })
|
|
43100
|
+
children: showResults && stored ? /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormResultsPanel, { form: stored }) : /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormLookFrame, { look: lookOptions?.look ?? null, title: draft.name, contained: true, showOwnerHeader: draft.showOwnerHeader ?? orgKnobs?.show_owner_header ?? true, children: /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(FormRunner, { form: draft, preview: true, autoAdvance: draft.autoAdvance ?? orgKnobs?.choice_auto_advance ?? true }) })
|
|
43074
43101
|
}
|
|
43075
43102
|
)
|
|
43076
43103
|
) : null
|
|
@@ -43323,6 +43350,7 @@ function NotifyOnAnswer({
|
|
|
43323
43350
|
formName,
|
|
43324
43351
|
ruleId,
|
|
43325
43352
|
notify,
|
|
43353
|
+
emailQuestion,
|
|
43326
43354
|
onRule,
|
|
43327
43355
|
onNotify
|
|
43328
43356
|
}) {
|
|
@@ -43388,7 +43416,7 @@ function NotifyOnAnswer({
|
|
|
43388
43416
|
try {
|
|
43389
43417
|
if (next === "") {
|
|
43390
43418
|
if (notify?.webhookAutomationId) await client.automationArchive({ automation_id: notify.webhookAutomationId });
|
|
43391
|
-
onNotify(null);
|
|
43419
|
+
onNotify(notify?.emailRespondent ? { ...notify, webhookUrl: null, webhookAutomationId: null } : null);
|
|
43392
43420
|
return;
|
|
43393
43421
|
}
|
|
43394
43422
|
const declared2 = await client.automationDeclare({
|
|
@@ -43401,22 +43429,43 @@ function NotifyOnAnswer({
|
|
|
43401
43429
|
setSaid(Object.values(declared2.data._errors)[0] ?? "Not saved");
|
|
43402
43430
|
return;
|
|
43403
43431
|
}
|
|
43404
|
-
onNotify({ webhookUrl: next, webhookAutomationId: declared2.data.automation_id });
|
|
43432
|
+
onNotify({ ...notify ?? {}, webhookUrl: next, webhookAutomationId: declared2.data.automation_id });
|
|
43405
43433
|
} finally {
|
|
43406
43434
|
setBusy(false);
|
|
43407
43435
|
}
|
|
43408
43436
|
}
|
|
43409
43437
|
return /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("section", { className: "flex flex-col gap-2 rounded border px-2.5 py-2 text-xs", "aria-label": "Notify on answer", "data-records-form-notify": "", children: [
|
|
43410
43438
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)("span", { className: "font-medium", children: "Notify on answer" }),
|
|
43411
|
-
/* @__PURE__ */ (0, import_jsx_runtime133.
|
|
43412
|
-
/* @__PURE__ */ (0, import_jsx_runtime133.
|
|
43413
|
-
|
|
43414
|
-
|
|
43415
|
-
"(",
|
|
43416
|
-
|
|
43417
|
-
|
|
43418
|
-
|
|
43419
|
-
|
|
43439
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1", children: [
|
|
43440
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("label", { className: "flex items-center gap-2", title: "An email to you each time somebody answers.", children: [
|
|
43441
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_design_system118.Checkbox, { checked: Boolean(ruleId), disabled: busy, onCheckedChange: (c) => void emailMe(c === true), "aria-label": "Email me" }),
|
|
43442
|
+
"Email me",
|
|
43443
|
+
chosen && chosen.channel !== "email" ? /* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("span", { className: "text-muted-foreground", children: [
|
|
43444
|
+
"(",
|
|
43445
|
+
chosen.channel === "sms" ? "text" : "in app",
|
|
43446
|
+
")"
|
|
43447
|
+
] }) : null
|
|
43448
|
+
] }),
|
|
43449
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsxs)(
|
|
43450
|
+
"label",
|
|
43451
|
+
{
|
|
43452
|
+
className: (0, import_design_system118.cn)("flex items-center gap-2", !emailQuestion && "text-muted-foreground"),
|
|
43453
|
+
title: emailQuestion ? "An email to the person who answered, in your ending's words." : "Add an email question first.",
|
|
43454
|
+
children: [
|
|
43455
|
+
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|
|
43456
|
+
import_design_system118.Checkbox,
|
|
43457
|
+
{
|
|
43458
|
+
checked: Boolean(notify?.emailRespondent) && Boolean(emailQuestion),
|
|
43459
|
+
disabled: busy || !emailQuestion,
|
|
43460
|
+
onCheckedChange: (c) => onNotify({ ...notify ?? {}, emailRespondent: c === true ? true : null, respondentField: c === true ? emailQuestion : null }),
|
|
43461
|
+
"aria-label": "Email the respondent"
|
|
43462
|
+
}
|
|
43463
|
+
),
|
|
43464
|
+
"Email the respondent"
|
|
43465
|
+
]
|
|
43466
|
+
}
|
|
43467
|
+
)
|
|
43468
|
+
] }),
|
|
43420
43469
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsxs)("label", { className: "flex items-center gap-2", children: [
|
|
43421
43470
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)("span", { className: "shrink-0", children: "Webhook" }),
|
|
43422
43471
|
/* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
|