@ai-matrx/records-ui 0.107.0 → 0.107.3

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.d.cts CHANGED
@@ -4677,6 +4677,13 @@ interface FormNotify {
4677
4677
  webhookUrl?: string | null;
4678
4678
  /** The `custom.automation_declare` row that posts to `webhookUrl` (trigger form_answered). */
4679
4679
  webhookAutomationId?: Uuid | null;
4680
+ /**
4681
+ * EMAIL THE RESPONDENT (TYPEFORM-2), off unless set: one email to the address the person typed
4682
+ * in `respondentField` (an email question), worded from the ending reached — sent by
4683
+ * `custom.form_respondent_copy` through the platform's notification sender.
4684
+ */
4685
+ emailRespondent?: boolean | null;
4686
+ respondentField?: string | null;
4680
4687
  }
4681
4688
  /**
4682
4689
  * A form as `custom.forms` reports it — the spec a screen renders, plus the
package/dist/index.d.ts CHANGED
@@ -4677,6 +4677,13 @@ interface FormNotify {
4677
4677
  webhookUrl?: string | null;
4678
4678
  /** The `custom.automation_declare` row that posts to `webhookUrl` (trigger form_answered). */
4679
4679
  webhookAutomationId?: Uuid | null;
4680
+ /**
4681
+ * EMAIL THE RESPONDENT (TYPEFORM-2), off unless set: one email to the address the person typed
4682
+ * in `respondentField` (an email question), worded from the ending reached — sent by
4683
+ * `custom.form_respondent_copy` through the platform's notification sender.
4684
+ */
4685
+ emailRespondent?: boolean | null;
4686
+ respondentField?: string | null;
4680
4687
  }
4681
4688
  /**
4682
4689
  * A form as `custom.forms` reports it — the spec a screen renders, plus the
package/dist/index.js CHANGED
@@ -37759,14 +37759,26 @@ function formPresentation(spec) {
37759
37759
  theme: themeDocument(spec.theme ?? null),
37760
37760
  ...typeof spec.showOwnerHeader === "boolean" ? { show_owner_header: spec.showOwnerHeader } : {},
37761
37761
  ...typeof spec.autoAdvance === "boolean" ? { auto_advance: spec.autoAdvance } : {},
37762
- ...spec.notify && (spec.notify.webhookUrl || spec.notify.webhookAutomationId) ? { notify: strip({ webhook_url: text(spec.notify.webhookUrl), webhook_automation_id: text(spec.notify.webhookAutomationId) }) } : {}
37762
+ ...spec.notify && (spec.notify.webhookUrl || spec.notify.webhookAutomationId || spec.notify.emailRespondent) ? {
37763
+ notify: strip({
37764
+ webhook_url: text(spec.notify.webhookUrl),
37765
+ webhook_automation_id: text(spec.notify.webhookAutomationId),
37766
+ email_respondent: spec.notify.emailRespondent ? true : null,
37767
+ respondent_field: spec.notify.emailRespondent ? text(spec.notify.respondentField) : null
37768
+ })
37769
+ } : {}
37763
37770
  };
37764
37771
  }
37765
37772
  function notifyFromDocument(raw) {
37766
37773
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return null;
37767
37774
  const d = raw;
37768
- const n = { webhookUrl: text(d["webhook_url"]), webhookAutomationId: text(d["webhook_automation_id"]) };
37769
- return n.webhookUrl || n.webhookAutomationId ? n : null;
37775
+ const n = {
37776
+ webhookUrl: text(d["webhook_url"]),
37777
+ webhookAutomationId: text(d["webhook_automation_id"]),
37778
+ emailRespondent: d["email_respondent"] === true ? true : null,
37779
+ respondentField: text(d["respondent_field"])
37780
+ };
37781
+ return n.webhookUrl || n.webhookAutomationId || n.emailRespondent ? n : null;
37770
37782
  }
37771
37783
  var bool = (v) => typeof v === "boolean" ? v : null;
37772
37784
  function answerRefusal(kind, required, value) {
@@ -42390,6 +42402,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42390
42402
  const [shownUrl, setShownUrl] = useState110(null);
42391
42403
  const [lookOptions, setLookOptions] = useState110(null);
42392
42404
  const [lookUnread, setLookUnread] = useState110(null);
42405
+ const [orgKnobs, setOrgKnobs] = useState110(null);
42393
42406
  const [restoredAt, setRestoredAt] = useState110(null);
42394
42407
  const [showResults, setShowResults] = useState110(false);
42395
42408
  const [adding, setAdding] = useState110(false);
@@ -42426,6 +42439,15 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42426
42439
  useEffect96(() => {
42427
42440
  void load();
42428
42441
  }, [load]);
42442
+ useEffect96(() => {
42443
+ let cancelled = false;
42444
+ Promise.resolve().then(() => client.formKnobs()).then((r) => {
42445
+ if (!cancelled && r.ok) setOrgKnobs(r.data);
42446
+ }).catch(() => void 0);
42447
+ return () => {
42448
+ cancelled = true;
42449
+ };
42450
+ }, [client]);
42429
42451
  useEffect96(() => {
42430
42452
  if (!forms || forms.length === 0) return;
42431
42453
  if (createOnMount && makeOnMount !== "made") return;
@@ -42726,6 +42748,11 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42726
42748
  formName: draft.name,
42727
42749
  ruleId: draft.notifyRuleId,
42728
42750
  notify: draft.notify ?? null,
42751
+ emailQuestion: (
42752
+ // An email field first; else a question whose field is named for an email (an imported
42753
+ // "Contact email" kept as text). The store's resolver refuses an answer that is not one.
42754
+ (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
42755
+ ),
42729
42756
  onRule: (ruleId) => void chooseNotify(ruleId),
42730
42757
  onNotify: (notify) => void chooseWebhook(notify)
42731
42758
  }
@@ -42735,7 +42762,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42735
42762
  /* @__PURE__ */ jsx133(
42736
42763
  Checkbox15,
42737
42764
  {
42738
- checked: draft.showOwnerHeader ?? true,
42765
+ checked: draft.showOwnerHeader ?? orgKnobs?.show_owner_header ?? true,
42739
42766
  onCheckedChange: (checked) => patch({ showOwnerHeader: checked === true }),
42740
42767
  "aria-label": "Show our logo and name"
42741
42768
  }
@@ -42746,7 +42773,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42746
42773
  /* @__PURE__ */ jsx133(
42747
42774
  Checkbox15,
42748
42775
  {
42749
- checked: draft.autoAdvance ?? true,
42776
+ checked: draft.autoAdvance ?? orgKnobs?.choice_auto_advance ?? true,
42750
42777
  onCheckedChange: (checked) => patch({ autoAdvance: checked === true }),
42751
42778
  "aria-label": "Next after a choice"
42752
42779
  }
@@ -42915,7 +42942,7 @@ function FormBuilder({ tableId, seed, activeFormId, onActiveForm, startWithOne,
42915
42942
  {
42916
42943
  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)]",
42917
42944
  "data-records-form-preview": "",
42918
- children: showResults && stored ? /* @__PURE__ */ jsx133(FormResultsPanel, { form: stored }) : /* @__PURE__ */ jsx133(FormLookFrame, { look: lookOptions?.look ?? null, title: draft.name, contained: true, showOwnerHeader: draft.showOwnerHeader ?? true, children: /* @__PURE__ */ jsx133(FormRunner, { form: draft, preview: true }) })
42945
+ children: showResults && stored ? /* @__PURE__ */ jsx133(FormResultsPanel, { form: stored }) : /* @__PURE__ */ jsx133(FormLookFrame, { look: lookOptions?.look ?? null, title: draft.name, contained: true, showOwnerHeader: draft.showOwnerHeader ?? orgKnobs?.show_owner_header ?? true, children: /* @__PURE__ */ jsx133(FormRunner, { form: draft, preview: true, autoAdvance: draft.autoAdvance ?? orgKnobs?.choice_auto_advance ?? true }) })
42919
42946
  }
42920
42947
  )
42921
42948
  ) : null
@@ -43035,6 +43062,7 @@ function QuestionList({
43035
43062
  field: byKey.get(question.field) ?? null,
43036
43063
  draft,
43037
43064
  conditionFields: asked3.filter((f) => f.key !== question.field),
43065
+ jumpFields: asked3,
43038
43066
  label,
43039
43067
  onChange: (change) => onQuestion(index, change),
43040
43068
  onRemove: () => onQuestions(draft.questions.filter((q) => q.field !== question.field))
@@ -43074,6 +43102,7 @@ function QuestionRow({
43074
43102
  field: field2,
43075
43103
  draft,
43076
43104
  conditionFields,
43105
+ jumpFields,
43077
43106
  label,
43078
43107
  onChange,
43079
43108
  onRemove
@@ -43152,7 +43181,7 @@ function QuestionRow({
43152
43181
  questions: draft.questions,
43153
43182
  endings: draft.endings ?? [],
43154
43183
  field: field2,
43155
- fieldKeys: conditionFields,
43184
+ fieldKeys: jumpFields,
43156
43185
  label,
43157
43186
  onChange
43158
43187
  }
@@ -43168,6 +43197,7 @@ function NotifyOnAnswer({
43168
43197
  formName,
43169
43198
  ruleId,
43170
43199
  notify,
43200
+ emailQuestion,
43171
43201
  onRule,
43172
43202
  onNotify
43173
43203
  }) {
@@ -43233,7 +43263,7 @@ function NotifyOnAnswer({
43233
43263
  try {
43234
43264
  if (next === "") {
43235
43265
  if (notify?.webhookAutomationId) await client.automationArchive({ automation_id: notify.webhookAutomationId });
43236
- onNotify(null);
43266
+ onNotify(notify?.emailRespondent ? { ...notify, webhookUrl: null, webhookAutomationId: null } : null);
43237
43267
  return;
43238
43268
  }
43239
43269
  const declared2 = await client.automationDeclare({
@@ -43246,22 +43276,43 @@ function NotifyOnAnswer({
43246
43276
  setSaid(Object.values(declared2.data._errors)[0] ?? "Not saved");
43247
43277
  return;
43248
43278
  }
43249
- onNotify({ webhookUrl: next, webhookAutomationId: declared2.data.automation_id });
43279
+ onNotify({ ...notify ?? {}, webhookUrl: next, webhookAutomationId: declared2.data.automation_id });
43250
43280
  } finally {
43251
43281
  setBusy(false);
43252
43282
  }
43253
43283
  }
43254
43284
  return /* @__PURE__ */ jsxs123("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: [
43255
43285
  /* @__PURE__ */ jsx133("span", { className: "font-medium", children: "Notify on answer" }),
43256
- /* @__PURE__ */ jsx133("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1", children: /* @__PURE__ */ jsxs123("label", { className: "flex items-center gap-2", title: "An email to you each time somebody answers.", children: [
43257
- /* @__PURE__ */ jsx133(Checkbox15, { checked: Boolean(ruleId), disabled: busy, onCheckedChange: (c) => void emailMe(c === true), "aria-label": "Email me" }),
43258
- "Email me",
43259
- chosen && chosen.channel !== "email" ? /* @__PURE__ */ jsxs123("span", { className: "text-muted-foreground", children: [
43260
- "(",
43261
- chosen.channel === "sms" ? "text" : "in app",
43262
- ")"
43263
- ] }) : null
43264
- ] }) }),
43286
+ /* @__PURE__ */ jsxs123("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-1", children: [
43287
+ /* @__PURE__ */ jsxs123("label", { className: "flex items-center gap-2", title: "An email to you each time somebody answers.", children: [
43288
+ /* @__PURE__ */ jsx133(Checkbox15, { checked: Boolean(ruleId), disabled: busy, onCheckedChange: (c) => void emailMe(c === true), "aria-label": "Email me" }),
43289
+ "Email me",
43290
+ chosen && chosen.channel !== "email" ? /* @__PURE__ */ jsxs123("span", { className: "text-muted-foreground", children: [
43291
+ "(",
43292
+ chosen.channel === "sms" ? "text" : "in app",
43293
+ ")"
43294
+ ] }) : null
43295
+ ] }),
43296
+ /* @__PURE__ */ jsxs123(
43297
+ "label",
43298
+ {
43299
+ className: cn78("flex items-center gap-2", !emailQuestion && "text-muted-foreground"),
43300
+ title: emailQuestion ? "An email to the person who answered, in your ending's words." : "Add an email question first.",
43301
+ children: [
43302
+ /* @__PURE__ */ jsx133(
43303
+ Checkbox15,
43304
+ {
43305
+ checked: Boolean(notify?.emailRespondent) && Boolean(emailQuestion),
43306
+ disabled: busy || !emailQuestion,
43307
+ onCheckedChange: (c) => onNotify({ ...notify ?? {}, emailRespondent: c === true ? true : null, respondentField: c === true ? emailQuestion : null }),
43308
+ "aria-label": "Email the respondent"
43309
+ }
43310
+ ),
43311
+ "Email the respondent"
43312
+ ]
43313
+ }
43314
+ )
43315
+ ] }),
43265
43316
  /* @__PURE__ */ jsxs123("label", { className: "flex items-center gap-2", children: [
43266
43317
  /* @__PURE__ */ jsx133("span", { className: "shrink-0", children: "Webhook" }),
43267
43318
  /* @__PURE__ */ jsx133(