@fieldia/core 0.30.1 → 0.31.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/README.md +373 -1
- package/package.json +1 -1
- package/schema/page.schema.json +758 -1
- package/src/index.d.mts +13 -2
- package/src/index.d.ts +13 -2
- package/src/index.js +45 -2
- package/src/index.js.map +1 -1
- package/src/index.mjs +18 -2
- package/src/index.mjs.map +1 -1
- package/src/lib/format/actions.d.mts +16 -16
- package/src/lib/format/actions.d.ts +16 -16
- package/src/lib/format/actions.js +3 -0
- package/src/lib/format/actions.js.map +1 -1
- package/src/lib/format/actions.mjs +3 -0
- package/src/lib/format/actions.mjs.map +1 -1
- package/src/lib/format/address-search.js +3 -0
- package/src/lib/format/address-search.js.map +1 -1
- package/src/lib/format/address-search.mjs +3 -0
- package/src/lib/format/address-search.mjs.map +1 -1
- package/src/lib/format/duplicates.js +3 -0
- package/src/lib/format/duplicates.js.map +1 -1
- package/src/lib/format/duplicates.mjs +3 -0
- package/src/lib/format/duplicates.mjs.map +1 -1
- package/src/lib/format/endings.js +3 -0
- package/src/lib/format/endings.js.map +1 -1
- package/src/lib/format/endings.mjs +3 -0
- package/src/lib/format/endings.mjs.map +1 -1
- package/src/lib/format/field.d.mts +669 -0
- package/src/lib/format/field.d.ts +669 -0
- package/src/lib/format/field.js +42 -4
- package/src/lib/format/field.js.map +1 -1
- package/src/lib/format/field.mjs +42 -4
- package/src/lib/format/field.mjs.map +1 -1
- package/src/lib/format/flow-checks.d.mts +14 -0
- package/src/lib/format/flow-checks.d.ts +14 -0
- package/src/lib/format/flow-checks.js +61 -0
- package/src/lib/format/flow-checks.js.map +1 -0
- package/src/lib/format/flow-checks.mjs +58 -0
- package/src/lib/format/flow-checks.mjs.map +1 -0
- package/src/lib/format/flow.d.mts +43 -0
- package/src/lib/format/flow.d.ts +43 -0
- package/src/lib/format/flow.js +22 -0
- package/src/lib/format/flow.js.map +1 -0
- package/src/lib/format/flow.mjs +19 -0
- package/src/lib/format/flow.mjs.map +1 -0
- package/src/lib/format/from-schema.d.mts +70 -0
- package/src/lib/format/from-schema.d.ts +70 -0
- package/src/lib/format/from-schema.js +599 -0
- package/src/lib/format/from-schema.js.map +1 -0
- package/src/lib/format/from-schema.mjs +591 -0
- package/src/lib/format/from-schema.mjs.map +1 -0
- package/src/lib/format/jitless.d.mts +1 -0
- package/src/lib/format/jitless.d.ts +1 -0
- package/src/lib/format/jitless.js +27 -0
- package/src/lib/format/jitless.js.map +1 -0
- package/src/lib/format/jitless.mjs +24 -0
- package/src/lib/format/jitless.mjs.map +1 -0
- package/src/lib/format/json-schema.js +3 -0
- package/src/lib/format/json-schema.js.map +1 -1
- package/src/lib/format/json-schema.mjs +3 -0
- package/src/lib/format/json-schema.mjs.map +1 -1
- package/src/lib/format/json.js +3 -0
- package/src/lib/format/json.js.map +1 -1
- package/src/lib/format/json.mjs +3 -0
- package/src/lib/format/json.mjs.map +1 -1
- package/src/lib/format/languages-checks.d.mts +2 -1
- package/src/lib/format/languages-checks.d.ts +2 -1
- package/src/lib/format/languages-checks.js +8 -2
- package/src/lib/format/languages-checks.js.map +1 -1
- package/src/lib/format/languages-checks.mjs +8 -2
- package/src/lib/format/languages-checks.mjs.map +1 -1
- package/src/lib/format/later-checks.d.mts +3 -1
- package/src/lib/format/later-checks.d.ts +3 -1
- package/src/lib/format/later-checks.js +3 -1
- package/src/lib/format/later-checks.js.map +1 -1
- package/src/lib/format/later-checks.mjs +3 -1
- package/src/lib/format/later-checks.mjs.map +1 -1
- package/src/lib/format/layout.d.mts +13192 -7550
- package/src/lib/format/layout.d.ts +13192 -7550
- package/src/lib/format/layout.js +61 -3
- package/src/lib/format/layout.js.map +1 -1
- package/src/lib/format/layout.mjs +59 -1
- package/src/lib/format/layout.mjs.map +1 -1
- package/src/lib/format/layout.types.d.mts +3 -1
- package/src/lib/format/layout.types.d.ts +3 -1
- package/src/lib/format/limits.js +3 -0
- package/src/lib/format/limits.js.map +1 -1
- package/src/lib/format/limits.mjs +3 -0
- package/src/lib/format/limits.mjs.map +1 -1
- package/src/lib/format/list-checks.d.mts +1 -1
- package/src/lib/format/list-checks.d.ts +1 -1
- package/src/lib/format/list-checks.js +67 -22
- package/src/lib/format/list-checks.js.map +1 -1
- package/src/lib/format/list-checks.mjs +67 -22
- package/src/lib/format/list-checks.mjs.map +1 -1
- package/src/lib/format/list-rows-checks.d.mts +11 -0
- package/src/lib/format/list-rows-checks.d.ts +11 -0
- package/src/lib/format/list-rows-checks.js +62 -0
- package/src/lib/format/list-rows-checks.js.map +1 -0
- package/src/lib/format/list-rows-checks.mjs +59 -0
- package/src/lib/format/list-rows-checks.mjs.map +1 -0
- package/src/lib/format/media-options.d.mts +84 -0
- package/src/lib/format/media-options.d.ts +84 -0
- package/src/lib/format/media-options.js +86 -0
- package/src/lib/format/media-options.js.map +1 -0
- package/src/lib/format/media-options.mjs +80 -0
- package/src/lib/format/media-options.mjs.map +1 -0
- package/src/lib/format/outbox-checks.d.mts +11 -0
- package/src/lib/format/outbox-checks.d.ts +11 -0
- package/src/lib/format/outbox-checks.js +12 -0
- package/src/lib/format/outbox-checks.js.map +1 -0
- package/src/lib/format/outbox-checks.mjs +9 -0
- package/src/lib/format/outbox-checks.mjs.map +1 -0
- package/src/lib/format/page.d.mts +3057 -966
- package/src/lib/format/page.d.ts +3057 -966
- package/src/lib/format/page.js +15 -0
- package/src/lib/format/page.js.map +1 -1
- package/src/lib/format/page.mjs +15 -0
- package/src/lib/format/page.mjs.map +1 -1
- package/src/lib/format/part-checks.d.mts +3 -0
- package/src/lib/format/part-checks.d.ts +3 -0
- package/src/lib/format/payment-checks.d.mts +13 -0
- package/src/lib/format/payment-checks.d.ts +13 -0
- package/src/lib/format/payment-checks.js +30 -0
- package/src/lib/format/payment-checks.js.map +1 -0
- package/src/lib/format/payment-checks.mjs +27 -0
- package/src/lib/format/payment-checks.mjs.map +1 -0
- package/src/lib/format/payment.d.mts +37 -0
- package/src/lib/format/payment.d.ts +37 -0
- package/src/lib/format/payment.js +15 -0
- package/src/lib/format/payment.js.map +1 -0
- package/src/lib/format/payment.mjs +12 -0
- package/src/lib/format/payment.mjs.map +1 -0
- package/src/lib/format/phone.js +3 -0
- package/src/lib/format/phone.js.map +1 -1
- package/src/lib/format/phone.mjs +3 -0
- package/src/lib/format/phone.mjs.map +1 -1
- package/src/lib/format/picker-options.d.mts +12 -0
- package/src/lib/format/picker-options.d.ts +12 -0
- package/src/lib/format/picker-options.js +21 -3
- package/src/lib/format/picker-options.js.map +1 -1
- package/src/lib/format/picker-options.mjs +20 -2
- package/src/lib/format/picker-options.mjs.map +1 -1
- package/src/lib/format/prefill-checks.d.mts +13 -0
- package/src/lib/format/prefill-checks.d.ts +13 -0
- package/src/lib/format/prefill-checks.js +35 -0
- package/src/lib/format/prefill-checks.js.map +1 -0
- package/src/lib/format/prefill-checks.mjs +32 -0
- package/src/lib/format/prefill-checks.mjs.map +1 -0
- package/src/lib/format/prefill.d.mts +33 -0
- package/src/lib/format/prefill.d.ts +33 -0
- package/src/lib/format/prefill.js +20 -0
- package/src/lib/format/prefill.js.map +1 -0
- package/src/lib/format/prefill.mjs +17 -0
- package/src/lib/format/prefill.mjs.map +1 -0
- package/src/lib/format/quiz.d.mts +58 -0
- package/src/lib/format/quiz.d.ts +58 -0
- package/src/lib/format/quiz.js +24 -0
- package/src/lib/format/quiz.js.map +1 -0
- package/src/lib/format/quiz.mjs +21 -0
- package/src/lib/format/quiz.mjs.map +1 -0
- package/src/lib/format/records.js +3 -0
- package/src/lib/format/records.js.map +1 -1
- package/src/lib/format/records.mjs +3 -0
- package/src/lib/format/records.mjs.map +1 -1
- package/src/lib/format/references.d.mts +1 -1
- package/src/lib/format/references.d.ts +1 -1
- package/src/lib/format/references.js +56 -7
- package/src/lib/format/references.js.map +1 -1
- package/src/lib/format/references.mjs +57 -8
- package/src/lib/format/references.mjs.map +1 -1
- package/src/lib/format/schedule-checks.d.mts +8 -0
- package/src/lib/format/schedule-checks.d.ts +8 -0
- package/src/lib/format/schedule-checks.js +16 -0
- package/src/lib/format/schedule-checks.js.map +1 -0
- package/src/lib/format/schedule-checks.mjs +13 -0
- package/src/lib/format/schedule-checks.mjs.map +1 -0
- package/src/lib/format/signature-checks.d.mts +8 -0
- package/src/lib/format/signature-checks.d.ts +8 -0
- package/src/lib/format/signature-checks.js +21 -0
- package/src/lib/format/signature-checks.js.map +1 -1
- package/src/lib/format/signature-checks.mjs +20 -0
- package/src/lib/format/signature-checks.mjs.map +1 -1
- package/src/lib/format/signature-options.js +3 -0
- package/src/lib/format/signature-options.js.map +1 -1
- package/src/lib/format/signature-options.mjs +3 -0
- package/src/lib/format/signature-options.mjs.map +1 -1
- package/src/lib/format/slots-options.js +3 -0
- package/src/lib/format/slots-options.js.map +1 -1
- package/src/lib/format/slots-options.mjs +3 -0
- package/src/lib/format/slots-options.mjs.map +1 -1
- package/src/lib/format/templates-checks.d.mts +6 -0
- package/src/lib/format/templates-checks.d.ts +6 -0
- package/src/lib/format/templates-checks.js +16 -0
- package/src/lib/format/templates-checks.js.map +1 -0
- package/src/lib/format/templates-checks.mjs +13 -0
- package/src/lib/format/templates-checks.mjs.map +1 -0
- package/src/lib/format/translate.d.mts +2 -0
- package/src/lib/format/translate.d.ts +2 -0
- package/src/lib/format/translate.js +6 -2
- package/src/lib/format/translate.js.map +1 -1
- package/src/lib/format/translate.mjs +4 -2
- package/src/lib/format/translate.mjs.map +1 -1
- package/src/lib/format/typed-options.d.mts +43 -0
- package/src/lib/format/typed-options.d.ts +43 -0
- package/src/lib/format/typed-options.js +50 -0
- package/src/lib/format/typed-options.js.map +1 -0
- package/src/lib/format/typed-options.mjs +46 -0
- package/src/lib/format/typed-options.mjs.map +1 -0
- package/src/lib/format/upgrade.d.mts +5 -1
- package/src/lib/format/upgrade.d.ts +5 -1
- package/src/lib/format/upgrade.js +5 -1
- package/src/lib/format/upgrade.js.map +1 -1
- package/src/lib/format/upgrade.mjs +5 -1
- package/src/lib/format/upgrade.mjs.map +1 -1
- package/src/lib/format/validate.js +3 -0
- package/src/lib/format/validate.js.map +1 -1
- package/src/lib/format/validate.mjs +3 -0
- package/src/lib/format/validate.mjs.map +1 -1
- package/src/lib/format/verify-checks.d.mts +10 -0
- package/src/lib/format/verify-checks.d.ts +10 -0
- package/src/lib/format/verify-checks.js +44 -0
- package/src/lib/format/verify-checks.js.map +1 -0
- package/src/lib/format/verify-checks.mjs +41 -0
- package/src/lib/format/verify-checks.mjs.map +1 -0
- package/src/lib/format/version.d.mts +2 -2
- package/src/lib/format/version.d.ts +2 -2
- package/src/lib/format/version.js +2 -2
- package/src/lib/format/version.js.map +1 -1
- package/src/lib/format/version.mjs +2 -2
- package/src/lib/format/version.mjs.map +1 -1
- package/src/lib/format/week.d.mts +18 -0
- package/src/lib/format/week.d.ts +18 -0
- package/src/lib/format/week.js +58 -0
- package/src/lib/format/week.js.map +1 -0
- package/src/lib/format/week.mjs +55 -0
- package/src/lib/format/week.mjs.map +1 -0
- package/src/lib/record/approvals-part.d.mts +1 -1
- package/src/lib/record/approvals-part.d.ts +1 -1
- package/src/lib/record/approvals-part.js +2 -2
- package/src/lib/record/approvals-part.js.map +1 -1
- package/src/lib/record/approvals-part.mjs +1 -1
- package/src/lib/record/approvals-part.mjs.map +1 -1
- package/src/lib/record/data-source.d.mts +348 -5
- package/src/lib/record/data-source.d.ts +348 -5
- package/src/lib/record/data-source.js.map +1 -1
- package/src/lib/record/data-source.mjs.map +1 -1
- package/src/lib/record/day-words.d.mts +22 -1
- package/src/lib/record/day-words.d.ts +22 -1
- package/src/lib/record/day-words.js +29 -2
- package/src/lib/record/day-words.js.map +1 -1
- package/src/lib/record/day-words.mjs +24 -2
- package/src/lib/record/day-words.mjs.map +1 -1
- package/src/lib/record/drafts.d.mts +9 -0
- package/src/lib/record/drafts.d.ts +9 -0
- package/src/lib/record/drafts.js +20 -0
- package/src/lib/record/drafts.js.map +1 -1
- package/src/lib/record/drafts.mjs +19 -0
- package/src/lib/record/drafts.mjs.map +1 -1
- package/src/lib/record/files-part.d.mts +1 -0
- package/src/lib/record/files-part.d.ts +1 -0
- package/src/lib/record/files-part.js +7 -1
- package/src/lib/record/files-part.js.map +1 -1
- package/src/lib/record/files-part.mjs +5 -1
- package/src/lib/record/files-part.mjs.map +1 -1
- package/src/lib/record/form-approvals.d.mts +12 -17
- package/src/lib/record/form-approvals.d.ts +12 -17
- package/src/lib/record/form-approvals.js +19 -9
- package/src/lib/record/form-approvals.js.map +1 -1
- package/src/lib/record/form-approvals.mjs +18 -8
- package/src/lib/record/form-approvals.mjs.map +1 -1
- package/src/lib/record/form-limits.d.mts +4 -28
- package/src/lib/record/form-limits.d.ts +4 -28
- package/src/lib/record/form-limits.js +8 -5
- package/src/lib/record/form-limits.js.map +1 -1
- package/src/lib/record/form-limits.mjs +8 -5
- package/src/lib/record/form-limits.mjs.map +1 -1
- package/src/lib/record/form.d.mts +118 -3
- package/src/lib/record/form.d.ts +118 -3
- package/src/lib/record/form.js +283 -75
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +285 -77
- package/src/lib/record/form.mjs.map +1 -1
- package/src/lib/record/history-steps.d.mts +38 -0
- package/src/lib/record/history-steps.d.ts +38 -0
- package/src/lib/record/history-steps.js +63 -0
- package/src/lib/record/history-steps.js.map +1 -0
- package/src/lib/record/history-steps.mjs +58 -0
- package/src/lib/record/history-steps.mjs.map +1 -0
- package/src/lib/record/history.d.mts +16 -0
- package/src/lib/record/history.d.ts +16 -0
- package/src/lib/record/history.js +3 -0
- package/src/lib/record/history.js.map +1 -0
- package/src/lib/record/history.mjs +2 -0
- package/src/lib/record/history.mjs.map +1 -0
- package/src/lib/record/input-rules.d.mts +2 -0
- package/src/lib/record/input-rules.d.ts +2 -0
- package/src/lib/record/input-rules.js +4 -1
- package/src/lib/record/input-rules.js.map +1 -1
- package/src/lib/record/input-rules.mjs +2 -0
- package/src/lib/record/input-rules.mjs.map +1 -1
- package/src/lib/record/joins.d.mts +143 -0
- package/src/lib/record/joins.d.ts +143 -0
- package/src/lib/record/joins.js +28 -0
- package/src/lib/record/joins.js.map +1 -0
- package/src/lib/record/joins.mjs +24 -0
- package/src/lib/record/joins.mjs.map +1 -0
- package/src/lib/record/limits.js +7 -4
- package/src/lib/record/limits.js.map +1 -1
- package/src/lib/record/limits.mjs +8 -5
- package/src/lib/record/limits.mjs.map +1 -1
- package/src/lib/record/link-values.d.mts +31 -0
- package/src/lib/record/link-values.d.ts +31 -0
- package/src/lib/record/link-values.js +132 -0
- package/src/lib/record/link-values.js.map +1 -0
- package/src/lib/record/link-values.mjs +125 -0
- package/src/lib/record/link-values.mjs.map +1 -0
- package/src/lib/record/live-later.d.mts +15 -0
- package/src/lib/record/live-later.d.ts +15 -0
- package/src/lib/record/live-later.js +10 -0
- package/src/lib/record/live-later.js.map +1 -0
- package/src/lib/record/live-later.mjs +7 -0
- package/src/lib/record/live-later.mjs.map +1 -0
- package/src/lib/record/live-part.d.mts +6 -0
- package/src/lib/record/live-part.d.ts +6 -0
- package/src/lib/record/live-part.js +12 -0
- package/src/lib/record/live-part.js.map +1 -0
- package/src/lib/record/live-part.mjs +7 -0
- package/src/lib/record/live-part.mjs.map +1 -0
- package/src/lib/record/live.d.mts +8 -0
- package/src/lib/record/live.d.ts +8 -0
- package/src/lib/record/live.js +133 -0
- package/src/lib/record/live.js.map +1 -0
- package/src/lib/record/live.mjs +129 -0
- package/src/lib/record/live.mjs.map +1 -0
- package/src/lib/record/locales/all.d.mts +5 -5
- package/src/lib/record/locales/all.d.ts +5 -5
- package/src/lib/record/locales/all.js +3 -3
- package/src/lib/record/locales/all.js.map +1 -1
- package/src/lib/record/locales/all.mjs +3 -3
- package/src/lib/record/locales/all.mjs.map +1 -1
- package/src/lib/record/locales/ar.js +8 -0
- package/src/lib/record/locales/ar.js.map +1 -1
- package/src/lib/record/locales/ar.mjs +8 -0
- package/src/lib/record/locales/ar.mjs.map +1 -1
- package/src/lib/record/locales/de.js +8 -0
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +8 -0
- package/src/lib/record/locales/de.mjs.map +1 -1
- package/src/lib/record/locales/es.d.mts +8 -0
- package/src/lib/record/locales/es.d.ts +8 -0
- package/src/lib/record/locales/es.js +111 -0
- package/src/lib/record/locales/es.js.map +1 -0
- package/src/lib/record/locales/es.mjs +108 -0
- package/src/lib/record/locales/es.mjs.map +1 -0
- package/src/lib/record/locales/fa.d.mts +5 -0
- package/src/lib/record/locales/fa.d.ts +5 -0
- package/src/lib/record/locales/fa.js +117 -0
- package/src/lib/record/locales/fa.js.map +1 -0
- package/src/lib/record/locales/fa.mjs +114 -0
- package/src/lib/record/locales/fa.mjs.map +1 -0
- package/src/lib/record/locales/fr.js +8 -0
- package/src/lib/record/locales/fr.js.map +1 -1
- package/src/lib/record/locales/fr.mjs +8 -0
- package/src/lib/record/locales/fr.mjs.map +1 -1
- package/src/lib/record/locales/later.d.mts +8 -0
- package/src/lib/record/locales/later.d.ts +8 -0
- package/src/lib/record/locales/later.js +16 -0
- package/src/lib/record/locales/later.js.map +1 -0
- package/src/lib/record/locales/later.mjs +13 -0
- package/src/lib/record/locales/later.mjs.map +1 -0
- package/src/lib/record/locales/tr.d.mts +6 -0
- package/src/lib/record/locales/tr.d.ts +6 -0
- package/src/lib/record/locales/tr.js +118 -0
- package/src/lib/record/locales/tr.js.map +1 -0
- package/src/lib/record/locales/tr.mjs +115 -0
- package/src/lib/record/locales/tr.mjs.map +1 -0
- package/src/lib/record/locales/ur.d.mts +9 -0
- package/src/lib/record/locales/ur.d.ts +9 -0
- package/src/lib/record/locales/ur.js +118 -0
- package/src/lib/record/locales/ur.js.map +1 -0
- package/src/lib/record/locales/ur.mjs +115 -0
- package/src/lib/record/locales/ur.mjs.map +1 -0
- package/src/lib/record/memory-approvals.d.mts +4 -1
- package/src/lib/record/memory-approvals.d.ts +4 -1
- package/src/lib/record/memory-approvals.js +29 -0
- package/src/lib/record/memory-approvals.js.map +1 -1
- package/src/lib/record/memory-approvals.mjs +29 -0
- package/src/lib/record/memory-approvals.mjs.map +1 -1
- package/src/lib/record/memory-codes.d.mts +37 -0
- package/src/lib/record/memory-codes.d.ts +37 -0
- package/src/lib/record/memory-codes.js +50 -0
- package/src/lib/record/memory-codes.js.map +1 -0
- package/src/lib/record/memory-codes.mjs +47 -0
- package/src/lib/record/memory-codes.mjs.map +1 -0
- package/src/lib/record/memory-data-source.d.mts +56 -2
- package/src/lib/record/memory-data-source.d.ts +56 -2
- package/src/lib/record/memory-data-source.js +80 -2
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +80 -2
- package/src/lib/record/memory-data-source.mjs.map +1 -1
- package/src/lib/record/memory-kept.d.mts +3 -1
- package/src/lib/record/memory-kept.d.ts +3 -1
- package/src/lib/record/memory-kept.js +7 -2
- package/src/lib/record/memory-kept.js.map +1 -1
- package/src/lib/record/memory-kept.mjs +7 -2
- package/src/lib/record/memory-kept.mjs.map +1 -1
- package/src/lib/record/memory-later.d.mts +3 -1
- package/src/lib/record/memory-later.d.ts +3 -1
- package/src/lib/record/memory-later.js +9 -5
- package/src/lib/record/memory-later.js.map +1 -1
- package/src/lib/record/memory-later.mjs +8 -4
- package/src/lib/record/memory-later.mjs.map +1 -1
- package/src/lib/record/memory-live.d.mts +8 -0
- package/src/lib/record/memory-live.d.ts +8 -0
- package/src/lib/record/memory-live.js +70 -0
- package/src/lib/record/memory-live.js.map +1 -0
- package/src/lib/record/memory-live.mjs +67 -0
- package/src/lib/record/memory-live.mjs.map +1 -0
- package/src/lib/record/memory-views.d.mts +11 -0
- package/src/lib/record/memory-views.d.ts +11 -0
- package/src/lib/record/memory-views.js +68 -0
- package/src/lib/record/memory-views.js.map +1 -0
- package/src/lib/record/memory-views.mjs +65 -0
- package/src/lib/record/memory-views.mjs.map +1 -0
- package/src/lib/record/messages.d.mts +21 -3
- package/src/lib/record/messages.d.ts +21 -3
- package/src/lib/record/messages.js +15 -2
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +15 -2
- package/src/lib/record/messages.mjs.map +1 -1
- package/src/lib/record/order.d.mts +21 -0
- package/src/lib/record/order.d.ts +21 -0
- package/src/lib/record/order.js +129 -0
- package/src/lib/record/order.js.map +1 -0
- package/src/lib/record/order.mjs +122 -0
- package/src/lib/record/order.mjs.map +1 -0
- package/src/lib/record/outbox-form.d.mts +79 -0
- package/src/lib/record/outbox-form.d.ts +79 -0
- package/src/lib/record/outbox-form.js +291 -0
- package/src/lib/record/outbox-form.js.map +1 -0
- package/src/lib/record/outbox-form.mjs +286 -0
- package/src/lib/record/outbox-form.mjs.map +1 -0
- package/src/lib/record/outbox-part.d.mts +6 -0
- package/src/lib/record/outbox-part.d.ts +6 -0
- package/src/lib/record/outbox-part.js +13 -0
- package/src/lib/record/outbox-part.js.map +1 -0
- package/src/lib/record/outbox-part.mjs +7 -0
- package/src/lib/record/outbox-part.mjs.map +1 -0
- package/src/lib/record/pay-part.d.mts +6 -0
- package/src/lib/record/pay-part.d.ts +6 -0
- package/src/lib/record/pay-part.js +11 -0
- package/src/lib/record/pay-part.js.map +1 -0
- package/src/lib/record/pay-part.mjs +7 -0
- package/src/lib/record/pay-part.mjs.map +1 -0
- package/src/lib/record/payment-form.d.mts +25 -0
- package/src/lib/record/payment-form.d.ts +25 -0
- package/src/lib/record/payment-form.js +98 -0
- package/src/lib/record/payment-form.js.map +1 -0
- package/src/lib/record/payment-form.mjs +95 -0
- package/src/lib/record/payment-form.mjs.map +1 -0
- package/src/lib/record/prefill-part.d.mts +7 -0
- package/src/lib/record/prefill-part.d.ts +7 -0
- package/src/lib/record/prefill-part.js +15 -0
- package/src/lib/record/prefill-part.js.map +1 -0
- package/src/lib/record/prefill-part.mjs +8 -0
- package/src/lib/record/prefill-part.mjs.map +1 -0
- package/src/lib/record/press-undo.d.mts +42 -0
- package/src/lib/record/press-undo.d.ts +42 -0
- package/src/lib/record/press-undo.js +115 -0
- package/src/lib/record/press-undo.js.map +1 -0
- package/src/lib/record/press-undo.mjs +110 -0
- package/src/lib/record/press-undo.mjs.map +1 -0
- package/src/lib/record/quiz.d.mts +36 -0
- package/src/lib/record/quiz.d.ts +36 -0
- package/src/lib/record/quiz.js +90 -0
- package/src/lib/record/quiz.js.map +1 -0
- package/src/lib/record/quiz.mjs +87 -0
- package/src/lib/record/quiz.mjs.map +1 -0
- package/src/lib/record/record-words.js +1 -1
- package/src/lib/record/record-words.js.map +1 -1
- package/src/lib/record/record-words.mjs +1 -1
- package/src/lib/record/record-words.mjs.map +1 -1
- package/src/lib/record/run.d.mts +54 -2
- package/src/lib/record/run.d.ts +54 -2
- package/src/lib/record/run.js +30 -6
- package/src/lib/record/run.js.map +1 -1
- package/src/lib/record/run.mjs +28 -5
- package/src/lib/record/run.mjs.map +1 -1
- package/src/lib/record/survey-kit.d.mts +37 -0
- package/src/lib/record/survey-kit.d.ts +37 -0
- package/src/lib/record/survey-kit.js +110 -0
- package/src/lib/record/survey-kit.js.map +1 -0
- package/src/lib/record/survey-kit.mjs +107 -0
- package/src/lib/record/survey-kit.mjs.map +1 -0
- package/src/lib/record/survey.d.mts +16 -0
- package/src/lib/record/survey.d.ts +16 -0
- package/src/lib/record/survey.js +17 -0
- package/src/lib/record/survey.js.map +1 -0
- package/src/lib/record/survey.mjs +13 -0
- package/src/lib/record/survey.mjs.map +1 -0
- package/src/lib/record/surveyflow-part.d.mts +9 -0
- package/src/lib/record/surveyflow-part.d.ts +9 -0
- package/src/lib/record/surveyflow-part.js +20 -0
- package/src/lib/record/surveyflow-part.js.map +1 -0
- package/src/lib/record/surveyflow-part.mjs +10 -0
- package/src/lib/record/surveyflow-part.mjs.map +1 -0
- package/src/lib/record/timing.d.mts +76 -0
- package/src/lib/record/timing.d.ts +76 -0
- package/src/lib/record/timing.js +112 -0
- package/src/lib/record/timing.js.map +1 -0
- package/src/lib/record/timing.mjs +104 -0
- package/src/lib/record/timing.mjs.map +1 -0
- package/src/lib/record/undo-later.d.mts +9 -0
- package/src/lib/record/undo-later.d.ts +9 -0
- package/src/lib/record/undo-later.js +10 -0
- package/src/lib/record/undo-later.js.map +1 -0
- package/src/lib/record/undo-later.mjs +7 -0
- package/src/lib/record/undo-later.mjs.map +1 -0
- package/src/lib/record/undo-part.d.mts +8 -0
- package/src/lib/record/undo-part.d.ts +8 -0
- package/src/lib/record/undo-part.js +17 -0
- package/src/lib/record/undo-part.js.map +1 -0
- package/src/lib/record/undo-part.mjs +9 -0
- package/src/lib/record/undo-part.mjs.map +1 -0
- package/src/lib/record/upload-to-later.d.mts +10 -0
- package/src/lib/record/upload-to-later.d.ts +10 -0
- package/src/lib/record/upload-to-later.js +15 -0
- package/src/lib/record/upload-to-later.js.map +1 -0
- package/src/lib/record/upload-to-later.mjs +12 -0
- package/src/lib/record/upload-to-later.mjs.map +1 -0
- package/src/lib/record/uploads.d.mts +5 -0
- package/src/lib/record/uploads.d.ts +5 -0
- package/src/lib/record/uploads.js.map +1 -1
- package/src/lib/record/uploads.mjs.map +1 -1
- package/src/lib/record/values.d.mts +6 -0
- package/src/lib/record/values.d.ts +6 -0
- package/src/lib/record/values.js.map +1 -1
- package/src/lib/record/values.mjs.map +1 -1
- package/src/lib/record/verify-form.d.mts +24 -0
- package/src/lib/record/verify-form.d.ts +24 -0
- package/src/lib/record/verify-form.js +65 -0
- package/src/lib/record/verify-form.js.map +1 -0
- package/src/lib/record/verify-form.mjs +62 -0
- package/src/lib/record/verify-form.mjs.map +1 -0
- package/src/lib/record/verify-part.d.mts +6 -0
- package/src/lib/record/verify-part.d.ts +6 -0
- package/src/lib/record/verify-part.js +11 -0
- package/src/lib/record/verify-part.js.map +1 -0
- package/src/lib/record/verify-part.mjs +7 -0
- package/src/lib/record/verify-part.mjs.map +1 -0
- package/src/lib/record/words-chunks.d.mts +37 -0
- package/src/lib/record/words-chunks.d.ts +37 -0
- package/src/lib/record/words-chunks.js +94 -0
- package/src/lib/record/words-chunks.js.map +1 -0
- package/src/lib/record/words-chunks.mjs +86 -0
- package/src/lib/record/words-chunks.mjs.map +1 -0
- package/src/runtime.d.mts +28 -6
- package/src/runtime.d.ts +28 -6
- package/src/runtime.js +35 -6
- package/src/runtime.js.map +1 -1
- package/src/runtime.mjs +15 -3
- package/src/runtime.mjs.map +1 -1
package/src/lib/record/form.js
CHANGED
|
@@ -28,12 +28,13 @@ const line_choices_1 = require("./line-choices");
|
|
|
28
28
|
const data_source_1 = require("./data-source");
|
|
29
29
|
const taking_1 = require("./taking");
|
|
30
30
|
const languages_1 = require("./languages");
|
|
31
|
-
const approving_1 = require("./approving");
|
|
32
31
|
const drafts_1 = require("./drafts");
|
|
33
32
|
const waits_1 = require("./waits");
|
|
34
33
|
const uploads_1 = require("./uploads");
|
|
35
34
|
const scheduler_1 = require("./scheduler");
|
|
36
35
|
const signed_1 = require("./signed");
|
|
36
|
+
const joins_1 = require("./joins");
|
|
37
|
+
const undo_later_1 = require("./undo-later");
|
|
37
38
|
const run_1 = require("./run");
|
|
38
39
|
const values_1 = require("./values");
|
|
39
40
|
/**
|
|
@@ -95,7 +96,9 @@ function innerForm(options, within, place, outer) {
|
|
|
95
96
|
// A field's label small inside a message's sentence where the page asks (`lowerLabels`).
|
|
96
97
|
// …and a day written in the page's order where it says one (`look.dateOrder`): "can't be after Oct 20, 2026".
|
|
97
98
|
const dateOrder = page.look?.dateOrder;
|
|
98
|
-
|
|
99
|
+
// The page's ask over the language's messages, each read through to them as it is said: a language whose words come in a
|
|
100
|
+
// chunk of their own fills its table in place once they have come (words-chunks.ts).
|
|
101
|
+
const messages = page.lowerLabels || dateOrder ? Object.assign(Object.create(options.messages ?? messages_1.MESSAGES.en), { lowerLabels: page.lowerLabels, dateOrder }) : (options.messages ?? messages_1.MESSAGES.en);
|
|
99
102
|
/** One of the form's sentences in the words the page names its records by (`records`), else as the language says it plainly. */
|
|
100
103
|
const named = (noun, plain) => (0, record_words_1.recordSentence)(page.records, noun, plain, messages.locale);
|
|
101
104
|
/** The app's functions the page's expressions call: a name none may call is refused now. */
|
|
@@ -192,7 +195,23 @@ function innerForm(options, within, place, outer) {
|
|
|
192
195
|
placeholderOf('#title', page.layout.title);
|
|
193
196
|
/** Whether any rule only warns: without one, there are never warnings to look for. */
|
|
194
197
|
const warns = [...nodeRules.values()].some((rules) => rules.some((compiled) => compiled.rule.level === 'warning'));
|
|
195
|
-
const
|
|
198
|
+
const layoutSteps = page.layout.type === 'wizard' ? page.layout.children.map((step) => step.id) : [];
|
|
199
|
+
/** The wizard's steps in the order shown: the page's, or the order drawn for this respondent (`state.order`). */
|
|
200
|
+
let steps = layoutSteps;
|
|
201
|
+
/**
|
|
202
|
+
* The parts that join this form where its page or its source asks (`formJoins`: an offline outbox, the fields its link
|
|
203
|
+
* fills, proof by a code, a payment, a survey's flow, a record's approvals, the record made live), each made as it
|
|
204
|
+
* comes — at once where it has — and kept in their order: holes until then. While one has not come, a send waits for it
|
|
205
|
+
* (`joining`); a draft laid before one came is laid on it as it does (`laid`).
|
|
206
|
+
*/
|
|
207
|
+
const joins = [];
|
|
208
|
+
const joinParts = (0, joins_1.formJoins)(page, options).filter((part) => !outer || part.name !== 'approvals');
|
|
209
|
+
let joining;
|
|
210
|
+
let laid = null;
|
|
211
|
+
/** A part's side of this form, by its name, once it came. */
|
|
212
|
+
const joined = (name) => (joins[joinParts.findIndex((part) => part.name === name)] ?? null);
|
|
213
|
+
/** Whether a part that joins the form says so of a part of the page, or of a field. */
|
|
214
|
+
const anyJoin = (says) => joins.some((join) => join && says(join));
|
|
196
215
|
const storeKey = () => `fieldia:draft:${page.id}:${state.recordId ?? 'new'}`;
|
|
197
216
|
/** Today, on the clock of the page's time zone (the browser's own when it names none). */
|
|
198
217
|
const today = () => (0, zones_1.dayIn)(options.now?.() ?? new Date(), page.timeZone);
|
|
@@ -370,6 +389,9 @@ function innerForm(options, within, place, outer) {
|
|
|
370
389
|
limits: null,
|
|
371
390
|
resume: null,
|
|
372
391
|
approval: null,
|
|
392
|
+
order: null,
|
|
393
|
+
timers: {},
|
|
394
|
+
timeUp: [],
|
|
373
395
|
};
|
|
374
396
|
started = true;
|
|
375
397
|
/**
|
|
@@ -462,6 +484,8 @@ function innerForm(options, within, place, outer) {
|
|
|
462
484
|
filesChanged();
|
|
463
485
|
},
|
|
464
486
|
track,
|
|
487
|
+
// Through the parts that join the form: a photo taken without signal kept as its bytes, on a page with an outbox.
|
|
488
|
+
through,
|
|
465
489
|
});
|
|
466
490
|
/**
|
|
467
491
|
* Files on their way changed, here or in a saved form placed here: the
|
|
@@ -559,6 +583,88 @@ function innerForm(options, within, place, outer) {
|
|
|
559
583
|
const listed = (0, line_choices_1.listedColumns)(page.fields);
|
|
560
584
|
/** Whether the values set now are a change someone made (`writeValues`), after which a line's choice no longer offered is cleared. */
|
|
561
585
|
let edit = false;
|
|
586
|
+
/**
|
|
587
|
+
* The one kit the parts that work inside the form are given of it (joins.ts): the parts that join it, its limits, the
|
|
588
|
+
* undo part's press.
|
|
589
|
+
*/
|
|
590
|
+
const inner = {
|
|
591
|
+
get form() {
|
|
592
|
+
return form;
|
|
593
|
+
},
|
|
594
|
+
page,
|
|
595
|
+
fields,
|
|
596
|
+
options,
|
|
597
|
+
messages,
|
|
598
|
+
scheduler,
|
|
599
|
+
state: () => state,
|
|
600
|
+
set,
|
|
601
|
+
reading,
|
|
602
|
+
sending: () => (page.data.kind === 'responses' ? answersSent() : sentValues()),
|
|
603
|
+
baseline: () => baseline,
|
|
604
|
+
same: (name, one, other) => sameValue(fields[name], one, other),
|
|
605
|
+
conflictOf,
|
|
606
|
+
store,
|
|
607
|
+
settled: savesSettled,
|
|
608
|
+
track,
|
|
609
|
+
shownNow,
|
|
610
|
+
generation: () => generation,
|
|
611
|
+
emit,
|
|
612
|
+
replaced,
|
|
613
|
+
clock,
|
|
614
|
+
started: () => started,
|
|
615
|
+
listened: () => listeners.size > 0,
|
|
616
|
+
disposed: () => disposed,
|
|
617
|
+
// A clock started is kept at once where drafts are kept here: a reload a moment after Start finds it.
|
|
618
|
+
keep: () => (onServer() ? scheduleDraft() : keepHere(draftNow())),
|
|
619
|
+
order: (list) => void (steps = list ?? layoutSteps),
|
|
620
|
+
refuse(name, message) {
|
|
621
|
+
// Said until the field changes from what it holds, as a refused save's words are.
|
|
622
|
+
serverErrors[name] = { message, value: JSON.stringify(state.values[name] ?? null) };
|
|
623
|
+
set({ errors: { ...state.errors, [name]: message } });
|
|
624
|
+
},
|
|
625
|
+
reload: () => load(true),
|
|
626
|
+
};
|
|
627
|
+
/** The person's changes to the record shown, as made (history.ts); and whether one is being taken back or made again now. */
|
|
628
|
+
let noted = [];
|
|
629
|
+
let replaying = false;
|
|
630
|
+
/**
|
|
631
|
+
* A person's change written to `field` (on `line`), noted for Undo with what it held `before`: typing on joins it
|
|
632
|
+
* (`joins`). The undo part takes them as they come, asked for with the first: in by the time the person presses Ctrl+Z.
|
|
633
|
+
*/
|
|
634
|
+
const noteChange = (field, line, before, joins) => {
|
|
635
|
+
if (replaying)
|
|
636
|
+
return;
|
|
637
|
+
noted.push([field, line, before ?? null, state.values[field] ?? null, joins]);
|
|
638
|
+
const part = undo_later_1.pressUndoPart.loaded;
|
|
639
|
+
if (part)
|
|
640
|
+
part.takeNoted(noted, inner.same);
|
|
641
|
+
// Kept while it comes; where it cannot, the oldest let go.
|
|
642
|
+
else if (noted.length > 500)
|
|
643
|
+
noted.shift();
|
|
644
|
+
else
|
|
645
|
+
undo_later_1.pressUndoPart.load().catch(() => undefined);
|
|
646
|
+
};
|
|
647
|
+
/**
|
|
648
|
+
* Undo (`back`) or Redo, once the undo part has come: the change taken, written as the person's own change back —
|
|
649
|
+
* the page's `change` steps and the source's onchange run as for any — once its field still holds what the change
|
|
650
|
+
* left and may be changed.
|
|
651
|
+
*/
|
|
652
|
+
function replay(back) {
|
|
653
|
+
const step = editing ? undo_later_1.pressUndoPart.loaded?.takeStep(noted, inner.same, back, (one, left) => !form.fieldReadonly(one.field) && sameValue(fields[one.field], state.values[one.field], left)) : null;
|
|
654
|
+
if (!step)
|
|
655
|
+
return null;
|
|
656
|
+
const { value, ...taken } = step;
|
|
657
|
+
replaying = true;
|
|
658
|
+
try {
|
|
659
|
+
writeValues({ ...state.values, [taken.field]: (0, values_1.structuredCopy)(value) });
|
|
660
|
+
afterEdit(taken.field);
|
|
661
|
+
changed(taken.field, 'person', taken.line === undefined ? {} : { line: taken.line });
|
|
662
|
+
}
|
|
663
|
+
finally {
|
|
664
|
+
replaying = false;
|
|
665
|
+
}
|
|
666
|
+
return taken;
|
|
667
|
+
}
|
|
562
668
|
function set(patch) {
|
|
563
669
|
const was = state.values;
|
|
564
670
|
const choicesWas = state.choices;
|
|
@@ -592,6 +698,10 @@ function innerForm(options, within, place, outer) {
|
|
|
592
698
|
part.inner.show(inside(state.errors, part.name));
|
|
593
699
|
for (const listener of [...listeners])
|
|
594
700
|
listener(state);
|
|
701
|
+
// What the parts that join the form follow of it: the record shown, watched for changes made elsewhere and for who
|
|
702
|
+
// else has it open, asked again as that changes.
|
|
703
|
+
for (const join of joins)
|
|
704
|
+
join?.changed?.();
|
|
595
705
|
// Choices that change with a value that just changed are asked for again.
|
|
596
706
|
if (state.values !== was) {
|
|
597
707
|
// After someone's change, a choice its new choices do not offer is taken out and said, as a line's is.
|
|
@@ -631,6 +741,7 @@ function innerForm(options, within, place, outer) {
|
|
|
631
741
|
/** Another record is shown: nothing of the last one's is the person's work any more, and its files on their way stop. */
|
|
632
742
|
function newGeneration() {
|
|
633
743
|
generation++;
|
|
744
|
+
noted = [];
|
|
634
745
|
// Another record's lines ask the source anew.
|
|
635
746
|
lineAsks = new Map();
|
|
636
747
|
answers = new Map();
|
|
@@ -743,6 +854,9 @@ function innerForm(options, within, place, outer) {
|
|
|
743
854
|
return;
|
|
744
855
|
told = step;
|
|
745
856
|
emit('step', { step });
|
|
857
|
+
// A step with a time limit: its clock starts as it is first entered.
|
|
858
|
+
for (const join of joins)
|
|
859
|
+
join?.entered?.(step);
|
|
746
860
|
const list = page.on?.show?.[step];
|
|
747
861
|
if (list)
|
|
748
862
|
void track(moment(`on.show.${step}`, list, chain, true));
|
|
@@ -1114,13 +1228,13 @@ function innerForm(options, within, place, outer) {
|
|
|
1114
1228
|
if (!node)
|
|
1115
1229
|
throw new Error(`The page has no element "${id}"`);
|
|
1116
1230
|
const { context: ctx, env } = reading();
|
|
1117
|
-
const hidden = (at) => (at ? !(0, roles_1.rolesAllow)(at.roles, userRoles) || at.invisible.evaluate(ctx, env) : false);
|
|
1231
|
+
const hidden = (at) => (at ? anyJoin((join) => join.hides?.(at.id)) || !(0, roles_1.rolesAllow)(at.roles, userRoles) || at.invisible.evaluate(ctx, env) : false);
|
|
1118
1232
|
let invisible = hidden(node);
|
|
1119
1233
|
for (let parent = node.parent; !invisible && parent; parent = index.get(parent)?.parent ?? null) {
|
|
1120
1234
|
invisible = hidden(index.get(parent));
|
|
1121
1235
|
}
|
|
1122
|
-
// A section read-only right now makes everything inside it read-only too.
|
|
1123
|
-
let readonly = node.readonly.evaluate(ctx, env);
|
|
1236
|
+
// A section read-only right now makes everything inside it read-only too; a page's, or a step's, time run out too.
|
|
1237
|
+
let readonly = node.readonly.evaluate(ctx, env) || anyJoin((join) => join.locks?.(id));
|
|
1124
1238
|
for (let parent = node.parent; !readonly && parent; parent = index.get(parent)?.parent ?? null) {
|
|
1125
1239
|
readonly = index.get(parent)?.readonly.evaluate(ctx, env) ?? false;
|
|
1126
1240
|
}
|
|
@@ -1138,7 +1252,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1138
1252
|
if (answer !== undefined && signedNow().has(answer))
|
|
1139
1253
|
readonly = true;
|
|
1140
1254
|
// A record waiting for approval: locked but for the fields the page leaves open (the approvals part).
|
|
1141
|
-
if (answer !== undefined &&
|
|
1255
|
+
if (answer !== undefined && anyJoin((join) => join.locksField?.(answer)))
|
|
1142
1256
|
readonly = true;
|
|
1143
1257
|
return {
|
|
1144
1258
|
invisible,
|
|
@@ -1280,6 +1394,9 @@ function innerForm(options, within, place, outer) {
|
|
|
1280
1394
|
const errors = {};
|
|
1281
1395
|
const seen = new Set();
|
|
1282
1396
|
for (const node of visibleFieldNodes(root)) {
|
|
1397
|
+
// The answers of a time run out go as they stood: their checks refuse nothing.
|
|
1398
|
+
if (anyJoin((join) => join.locks?.(node.id)))
|
|
1399
|
+
continue;
|
|
1283
1400
|
const name = node.field;
|
|
1284
1401
|
seen.add(name);
|
|
1285
1402
|
const end = rangeEnd(node);
|
|
@@ -1556,8 +1673,10 @@ function innerForm(options, within, place, outer) {
|
|
|
1556
1673
|
* form continues one by its key). A page without either keeps its drafts where it always did.
|
|
1557
1674
|
*/
|
|
1558
1675
|
const onServer = () => !!options.dataSource?.saveDraft && !!options.dataSource.loadDraft && (page.continueLater === true || !!options.resume);
|
|
1559
|
-
/**
|
|
1560
|
-
const
|
|
1676
|
+
/** Where drafts are kept in the browser: the app's store, else a timed page's tab (`timedStore`); none else. */
|
|
1677
|
+
const draftStore = options.drafts?.store ?? (0, drafts_1.timedStore)(page);
|
|
1678
|
+
/** Whether drafts are kept: in a store, or on the server. */
|
|
1679
|
+
const draftsOn = () => !!draftStore || onServer();
|
|
1561
1680
|
/** The key of the draft kept on the server for the record shown; null until the source gave one. */
|
|
1562
1681
|
let serverKey = null;
|
|
1563
1682
|
/** Counted each time the draft is let go (sent, discarded, another record shown): a keeping answered after is dropped. */
|
|
@@ -1588,6 +1707,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1588
1707
|
return {
|
|
1589
1708
|
values,
|
|
1590
1709
|
...(steps.length ? { step: state.step, skipped: [...state.skipped] } : {}),
|
|
1710
|
+
...Object.assign({}, ...joins.map((join) => join?.kept?.())),
|
|
1591
1711
|
...(Object.keys(state.unread).length ? { unread: (0, values_1.structuredCopy)(state.unread) } : {}),
|
|
1592
1712
|
answered: Object.keys(fields).filter((name) => state.dirty.includes(name)),
|
|
1593
1713
|
savedAt: new Date(clock()).toISOString(),
|
|
@@ -1596,7 +1716,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1596
1716
|
/** A draft in the browser's store, where the app gave one: a store that is full keeps none. */
|
|
1597
1717
|
function keepHere(kept) {
|
|
1598
1718
|
try {
|
|
1599
|
-
|
|
1719
|
+
draftStore?.setItem(storeKey(), JSON.stringify(kept));
|
|
1600
1720
|
}
|
|
1601
1721
|
catch {
|
|
1602
1722
|
// The draft is a convenience: the form goes on without it.
|
|
@@ -1643,6 +1763,10 @@ function innerForm(options, within, place, outer) {
|
|
|
1643
1763
|
/** A draft laid on the form: its answers as a starting point, its wizard step (or the nearest before it that applies), its text that does not read. */
|
|
1644
1764
|
function applyDraft(draft) {
|
|
1645
1765
|
found = null;
|
|
1766
|
+
// Its draw and its clocks, by the survey flow's part: now, or once it came.
|
|
1767
|
+
laid = draft;
|
|
1768
|
+
for (const join of joins)
|
|
1769
|
+
join?.lay?.(draft);
|
|
1646
1770
|
writeValues(withDraft(draft.values ?? {}), { draft: null }, true);
|
|
1647
1771
|
const known = (draft.skipped ?? []).filter((id) => steps.includes(id));
|
|
1648
1772
|
// Text typed that did not read stays as typed, said as it was, where its field is still on the page.
|
|
@@ -1665,12 +1789,15 @@ function innerForm(options, within, place, outer) {
|
|
|
1665
1789
|
serverKey = null;
|
|
1666
1790
|
if (state.resume)
|
|
1667
1791
|
set({ resume: null });
|
|
1668
|
-
|
|
1792
|
+
draftStore?.removeItem(storeKey());
|
|
1669
1793
|
}
|
|
1670
|
-
/**
|
|
1671
|
-
|
|
1794
|
+
/**
|
|
1795
|
+
* A draft found: laid at once (`restore: "auto"`, a draft continued from its key over nothing typed, one kept in a
|
|
1796
|
+
* timed page's tab, or one whose clock started — let go, it would start again), else offered.
|
|
1797
|
+
*/
|
|
1798
|
+
function offer(draft, auto = !options.drafts || options.drafts.restore === 'auto') {
|
|
1672
1799
|
// What the person typed while it was asked for is theirs: the draft is offered, never laid over it.
|
|
1673
|
-
if (auto && !state.dirty.length && !Object.keys(state.unread).length)
|
|
1800
|
+
if ((auto || draft.timers) && !state.dirty.length && !Object.keys(state.unread).length)
|
|
1674
1801
|
return applyDraft(draft);
|
|
1675
1802
|
found = draft;
|
|
1676
1803
|
set({ draft: { savedAt: draft.savedAt } });
|
|
@@ -1684,7 +1811,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1684
1811
|
const source = options.dataSource;
|
|
1685
1812
|
const given = resumeKey;
|
|
1686
1813
|
resumeKey = undefined;
|
|
1687
|
-
const kept = given ? null : (0, drafts_1.draftRead)(
|
|
1814
|
+
const kept = given ? null : (0, drafts_1.draftRead)(draftStore?.getItem(storeKey()) ?? null);
|
|
1688
1815
|
if (!given && !kept)
|
|
1689
1816
|
return;
|
|
1690
1817
|
if (kept && !('key' in kept))
|
|
@@ -1702,7 +1829,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1702
1829
|
set({ status: 'ready' });
|
|
1703
1830
|
if (!draft) {
|
|
1704
1831
|
// Sent, or gone: the form starts empty, and says so where it was asked to continue it.
|
|
1705
|
-
|
|
1832
|
+
draftStore?.removeItem(storeKey());
|
|
1706
1833
|
if (given)
|
|
1707
1834
|
set({ resume: { key, missing: true } });
|
|
1708
1835
|
return;
|
|
@@ -1737,27 +1864,8 @@ function innerForm(options, within, place, outer) {
|
|
|
1737
1864
|
function limitsMade(part) {
|
|
1738
1865
|
if (limitsKit || disposed)
|
|
1739
1866
|
return limitsKit;
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
dataSource: options.dataSource,
|
|
1743
|
-
user: options.user,
|
|
1744
|
-
messages,
|
|
1745
|
-
scheduler,
|
|
1746
|
-
state: () => state,
|
|
1747
|
-
set,
|
|
1748
|
-
clock,
|
|
1749
|
-
started: () => started,
|
|
1750
|
-
shownNow,
|
|
1751
|
-
generation: () => generation,
|
|
1752
|
-
replaced: () => named(messages.recordReplacedNoun, messages.recordReplaced),
|
|
1753
|
-
listened: () => listeners.size > 0,
|
|
1754
|
-
disposed: () => disposed,
|
|
1755
|
-
refuse(name, message) {
|
|
1756
|
-
// Said until the field changes from what it holds, as a refused save's words are.
|
|
1757
|
-
serverErrors[name] = { message, value: JSON.stringify(state.values[name] ?? null) };
|
|
1758
|
-
set({ errors: { ...state.errors, [name]: message } });
|
|
1759
|
-
},
|
|
1760
|
-
});
|
|
1867
|
+
// The one kit, made at the limits' own moment: once the form knows it keeps them (joins.ts).
|
|
1868
|
+
const kit = part.formLimits(inner);
|
|
1761
1869
|
limitsKit = kit;
|
|
1762
1870
|
kit.show();
|
|
1763
1871
|
if (kit.asks() && (state.recordId == null || loadedOnce))
|
|
@@ -1778,15 +1886,6 @@ function innerForm(options, within, place, outer) {
|
|
|
1778
1886
|
}
|
|
1779
1887
|
/** A choice of a full option, picked by the person, refused under its field: the field keeps what it held. */
|
|
1780
1888
|
const refusedFull = (name, value) => !!limitsKit?.refusedFull(name, value);
|
|
1781
|
-
// ---- a record's approvals (the approvals part: form-approvals.ts) ---------------------------------------------------
|
|
1782
|
-
/** The approvals made for this form from the approvals part, once it came: none before, nor on a page without them. */
|
|
1783
|
-
let approvalKit = null;
|
|
1784
|
-
/** Whether the form asks for approvals: a page with `approval` (a record's own, as its check says), its source telling them. */
|
|
1785
|
-
const keepsApprovals = !outer && !!page.approval && !!options.dataSource?.approvals;
|
|
1786
|
-
/** The approvals, made from their part once it came; null without them, or where it could not come. */
|
|
1787
|
-
const approvalsCode = () => keepsApprovals ? approving_1.formApprovalsPart.load().then((part) => (approvalKit ??= part.formApprovals({ form, dataSource: options.dataSource, messages, set, reload: () => load(true) })), () => null) : Promise.resolve(null);
|
|
1788
|
-
/** Ask the record shown's approvals, once their part came; nothing on a page without them. */
|
|
1789
|
-
const askApprovals = () => approvalsCode().then((kit) => kit?.ask());
|
|
1790
1889
|
function scheduleAutosave() {
|
|
1791
1890
|
const autosave = options.autosave;
|
|
1792
1891
|
// A record the person may not change is never saved unasked: it would only be refused.
|
|
@@ -1863,9 +1962,24 @@ function innerForm(options, within, place, outer) {
|
|
|
1863
1962
|
}
|
|
1864
1963
|
return shown;
|
|
1865
1964
|
}
|
|
1965
|
+
/** A response's answers as they go: those shown, and what the parts that join the form add (a link's hidden fields). */
|
|
1966
|
+
function answersSent() {
|
|
1967
|
+
const values = shownValues();
|
|
1968
|
+
for (const join of joins)
|
|
1969
|
+
join.values?.(values);
|
|
1970
|
+
return values;
|
|
1971
|
+
}
|
|
1866
1972
|
async function save(chain = [], yes) {
|
|
1867
1973
|
return (await saving(chain, yes)) === null;
|
|
1868
1974
|
}
|
|
1975
|
+
/** A send — a response's, a save's, an upload's — through the parts that join the form, each around the next. Null: kept, not sent. */
|
|
1976
|
+
function through(kind, sent, send) {
|
|
1977
|
+
return joins.reduce((go, join) => (join.around ? (one) => join.around(kind, one, go) : go), send)(sent);
|
|
1978
|
+
}
|
|
1979
|
+
/** Started again, or another record opened: the parts that join the form let go of what the one before had. */
|
|
1980
|
+
const joinsReset = () => joins.forEach((join) => join.reset?.());
|
|
1981
|
+
/** The record loaded, or saved: what the parts that join the form ask again (a record's approvals). */
|
|
1982
|
+
const joinsLoaded = () => joins.forEach((join) => join.loaded?.());
|
|
1869
1983
|
/** Every value, for a source that saves whole records: those of fields hidden from the person, which they never had, left out. */
|
|
1870
1984
|
function sentValues() {
|
|
1871
1985
|
const values = (0, values_1.structuredCopy)(state.values);
|
|
@@ -1973,8 +2087,22 @@ function innerForm(options, within, place, outer) {
|
|
|
1973
2087
|
const refused = await stillTaking(asked);
|
|
1974
2088
|
if (refused)
|
|
1975
2089
|
return refused;
|
|
1976
|
-
//
|
|
2090
|
+
// The parts that join the form (`formJoins`), waited for where they have not come.
|
|
2091
|
+
if (joining) {
|
|
2092
|
+
await joining;
|
|
2093
|
+
if (asked !== generation)
|
|
2094
|
+
return elsewhere();
|
|
2095
|
+
}
|
|
2096
|
+
// A file that did not reach the store stops it, under its field, with the form's own checks — and what the parts that
|
|
2097
|
+
// join the form find: an email or a phone not proved by a code; a payment not taken sends nothing.
|
|
1977
2098
|
const errors = { ...collectErrors(), ...fileProblems() };
|
|
2099
|
+
for (const join of joins) {
|
|
2100
|
+
// A part that never came (a hole) has nothing to say.
|
|
2101
|
+
if ((await join?.before?.(errors)) === false)
|
|
2102
|
+
return { reason: 'save' };
|
|
2103
|
+
if (asked !== generation)
|
|
2104
|
+
return elsewhere();
|
|
2105
|
+
}
|
|
1978
2106
|
if (Object.keys(errors).length) {
|
|
1979
2107
|
set({ errors, ...unstored(errors) });
|
|
1980
2108
|
return { reason: 'save', message: Object.values(errors)[0] };
|
|
@@ -2004,13 +2132,18 @@ function innerForm(options, within, place, outer) {
|
|
|
2004
2132
|
if (page.data.kind === 'responses') {
|
|
2005
2133
|
if (!source?.submit)
|
|
2006
2134
|
throw new Error('This page has no data source to send its answers to');
|
|
2007
|
-
const sent =
|
|
2135
|
+
const sent = answersSent();
|
|
2008
2136
|
const before = state.values;
|
|
2009
2137
|
at = generation;
|
|
2010
2138
|
const resetAt = resets;
|
|
2011
2139
|
const seen = botReport();
|
|
2140
|
+
// A quiz's marking, in before the answers go: what the person sees of their results.
|
|
2012
2141
|
// What the source answered: the id it gave the response, and the values it added — what an ending reads.
|
|
2013
|
-
const
|
|
2142
|
+
const request = { pageId: page.id, values: sent, ...(seen ? { bot: seen } : {}), ...draft };
|
|
2143
|
+
// Through the parts that join the form: kept on the device where an outbox finds no signal (null), the form going
|
|
2144
|
+
// on as though it went.
|
|
2145
|
+
const got = await through('submit', request, (one) => source.submit(one));
|
|
2146
|
+
const answer = got ?? {};
|
|
2014
2147
|
// The captcha's token is spent once sent: the next send waits for a new one.
|
|
2015
2148
|
if (seen?.captcha)
|
|
2016
2149
|
bot.captcha = null;
|
|
@@ -2022,8 +2155,13 @@ function innerForm(options, within, place, outer) {
|
|
|
2022
2155
|
sentAs = before;
|
|
2023
2156
|
const added = answer.values && typeof answer.values === 'object' ? (0, values_1.structuredCopy)(answer.values) : {};
|
|
2024
2157
|
// Started again meanwhile (`reset`): a new response is on screen, and no ending is the old one's.
|
|
2025
|
-
|
|
2158
|
+
// A quiz's results: the source's marking, else the page's, on the answers as sent.
|
|
2159
|
+
const quiz = answer.quiz ?? joined('surveyflow')?.marked(sent);
|
|
2160
|
+
set({ status: 'saved', unsent: unsentNow(), ...(resets === resetAt ? { sent: { id: answer.id ?? null, values: { ...(0, values_1.structuredCopy)(sent), ...added }, ...(quiz ? { quiz } : {}) } } : {}) });
|
|
2026
2161
|
emit('send', { values: sent, ...(seen ? { bot: seen } : {}) });
|
|
2162
|
+
// Kept, not sent: its counts and its after-save steps wait for a send that went.
|
|
2163
|
+
if (got === null)
|
|
2164
|
+
return null;
|
|
2027
2165
|
// Counted again: one response fewer to take, this person's sent.
|
|
2028
2166
|
if (asksLimits())
|
|
2029
2167
|
void track(askLimits());
|
|
@@ -2036,7 +2174,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2036
2174
|
const sent = state.values;
|
|
2037
2175
|
at = generation;
|
|
2038
2176
|
const resetAt = resets;
|
|
2039
|
-
const
|
|
2177
|
+
const request = {
|
|
2040
2178
|
model: page.data.model,
|
|
2041
2179
|
id: state.recordId,
|
|
2042
2180
|
fields,
|
|
@@ -2045,7 +2183,10 @@ function innerForm(options, within, place, outer) {
|
|
|
2045
2183
|
// The version it was opened at, for a source that refuses a save over someone else's.
|
|
2046
2184
|
...(state.recordId != null && state.version ? { version: state.version } : {}),
|
|
2047
2185
|
...draft,
|
|
2048
|
-
}
|
|
2186
|
+
};
|
|
2187
|
+
const got = await through('save', request, (one) => source.save(one));
|
|
2188
|
+
// Kept on the device (null): the record as it was, its version too.
|
|
2189
|
+
const result = got ?? { id: state.recordId, version: state.version ?? undefined };
|
|
2049
2190
|
// Answered for a record no longer shown — another opened, or this one loaded again: the source has it, and the
|
|
2050
2191
|
// form lays nothing of it over the record it shows now.
|
|
2051
2192
|
if (at !== generation)
|
|
@@ -2057,6 +2198,11 @@ function innerForm(options, within, place, outer) {
|
|
|
2057
2198
|
sentAs = baseline;
|
|
2058
2199
|
// Its version now, for the next save to carry; and what the person may do now, when the save changed that.
|
|
2059
2200
|
// The person's changes it did not send are at risk (`unsent`): every way out asks before it leaves them.
|
|
2201
|
+
// A save starts the person's changes afresh, as one saved is no change to take back (the viewer's Ctrl+Z says
|
|
2202
|
+
// nothing changed since). Not on a page that saves itself as it is changed (`autosave`), whose changes are taken
|
|
2203
|
+
// back across its saves; nor where a change made while it saved goes on past it.
|
|
2204
|
+
if (!options.autosave && !dirty.length && got)
|
|
2205
|
+
noted = [];
|
|
2060
2206
|
set({ status: 'saved', recordId: result.id, values, dirty, warnings: withValues(values, collectWarnings), version: result.version ?? null, ...(result.can ? { can: result.can } : {}) });
|
|
2061
2207
|
// Changed while it saved: kept in a draft, and saved as any change is.
|
|
2062
2208
|
if (dirty.length) {
|
|
@@ -2064,11 +2210,11 @@ function innerForm(options, within, place, outer) {
|
|
|
2064
2210
|
scheduleAutosave();
|
|
2065
2211
|
}
|
|
2066
2212
|
// A save may have sent it for approval, or moved it on: its approvals asked again.
|
|
2067
|
-
|
|
2068
|
-
void track(askApprovals());
|
|
2213
|
+
joinsLoaded();
|
|
2069
2214
|
// The record as this save left it: a change made while it was on its way is no value of it.
|
|
2070
2215
|
emit('save', { recordId: state.recordId, values: baseline });
|
|
2071
|
-
|
|
2216
|
+
if (got)
|
|
2217
|
+
void track(moment('on.afterSave', page.on?.afterSave, chain, false));
|
|
2072
2218
|
return null;
|
|
2073
2219
|
}
|
|
2074
2220
|
catch (error) {
|
|
@@ -2174,7 +2320,8 @@ function innerForm(options, within, place, outer) {
|
|
|
2174
2320
|
}
|
|
2175
2321
|
function addLine(field, values, by) {
|
|
2176
2322
|
const def = lineField(field);
|
|
2177
|
-
const
|
|
2323
|
+
const before = state.values[field];
|
|
2324
|
+
const current = before ?? [];
|
|
2178
2325
|
// A key no line holds: lines given (a line's own lines, back from its form) may hold new-… keys already.
|
|
2179
2326
|
let key = `new-${++lineKeys}`;
|
|
2180
2327
|
while (current.some((line) => line.key === key))
|
|
@@ -2187,6 +2334,8 @@ function innerForm(options, within, place, outer) {
|
|
|
2187
2334
|
}
|
|
2188
2335
|
const lines = [...current, line];
|
|
2189
2336
|
writeValues({ ...state.values, [field]: lines });
|
|
2337
|
+
if (by === 'person')
|
|
2338
|
+
noteChange(field, key, before, false);
|
|
2190
2339
|
afterEdit(field);
|
|
2191
2340
|
changed(field, by, by === 'person' ? { line: key } : { keep: true });
|
|
2192
2341
|
return key;
|
|
@@ -2331,8 +2480,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2331
2480
|
if (asksLimits())
|
|
2332
2481
|
void track(askLimits());
|
|
2333
2482
|
// Its approvals: where it stands, what was decided, what this person may decide — its fields locked while it waits.
|
|
2334
|
-
|
|
2335
|
-
void track(askApprovals());
|
|
2483
|
+
joinsLoaded();
|
|
2336
2484
|
if (again)
|
|
2337
2485
|
return;
|
|
2338
2486
|
offerDraft();
|
|
@@ -2368,6 +2516,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2368
2516
|
const fresh = { dirty: [], errors: {}, warning: null, warningField: null, error: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null, version: null, can: null, conflict: null, setAside: null, unsent: [], unread: {}, takenOut: {}, resume: null, approval: null };
|
|
2369
2517
|
if (id != null) {
|
|
2370
2518
|
set({ ...fresh, recordId: id, status: 'idle' });
|
|
2519
|
+
joinsReset();
|
|
2371
2520
|
await load();
|
|
2372
2521
|
return true;
|
|
2373
2522
|
}
|
|
@@ -2375,6 +2524,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2375
2524
|
baseline = startFrom(startingValues(true, false));
|
|
2376
2525
|
const values = syncParts((0, values_1.structuredCopy)(baseline), 'start');
|
|
2377
2526
|
set({ ...fresh, recordId: null, status: 'ready', values, warnings: withValues(values, collectWarnings) });
|
|
2527
|
+
joinsReset();
|
|
2378
2528
|
if (asksLimits())
|
|
2379
2529
|
void track(askLimits());
|
|
2380
2530
|
offerDraft();
|
|
@@ -2699,8 +2849,12 @@ function innerForm(options, within, place, outer) {
|
|
|
2699
2849
|
const builtin = 'builtin' in source && !list.length ? source.builtin : undefined;
|
|
2700
2850
|
if (builtin)
|
|
2701
2851
|
list.push({ do: builtin });
|
|
2702
|
-
|
|
2852
|
+
// Undo after it, in place of asking first: a built-in with `undo` asks nothing unless it says so.
|
|
2853
|
+
const offers = 'undo' in source ? source.undo : undefined;
|
|
2854
|
+
const asked = offers !== undefined ? undefined : builtin === 'archive' ? named(messages.archiveConfirmNoun, messages.archiveConfirm) : builtin === 'delete' ? named(messages.deleteConfirmNoun, messages.deleteConfirm) : undefined;
|
|
2703
2855
|
const confirm = 'confirm' in source && source.confirm !== undefined ? source.confirm : asked;
|
|
2856
|
+
if (offers !== undefined)
|
|
2857
|
+
scope.taken = (0, run_1.takenNow)(state.values);
|
|
2704
2858
|
// Its question's Yes, and its ask steps', say what it does: its own words, else Archive or Delete.
|
|
2705
2859
|
scope.yes ??= source.label || (builtin === 'archive' ? messages.archiveYes : builtin === 'delete' ? messages.deleteYes : undefined);
|
|
2706
2860
|
// On the record it was pressed on: another shown while its question is asked, it does nothing to that one.
|
|
@@ -2734,9 +2888,21 @@ function innerForm(options, within, place, outer) {
|
|
|
2734
2888
|
return result;
|
|
2735
2889
|
}
|
|
2736
2890
|
}
|
|
2737
|
-
|
|
2891
|
+
const result = await runTop(list, scope);
|
|
2892
|
+
if (scope.taken)
|
|
2893
|
+
offerUndo(source, scope, result, offers);
|
|
2894
|
+
return result;
|
|
2738
2895
|
})());
|
|
2739
2896
|
}
|
|
2897
|
+
/**
|
|
2898
|
+
* A press that offers Undo has ended: its words said — the last with Undo, where what it did can be taken back — by
|
|
2899
|
+
* the undo part (press-undo.ts), which a page whose buttons offer Undo asks for first; plainly where it cannot come.
|
|
2900
|
+
*/
|
|
2901
|
+
function offerUndo(source, scope, result, offers) {
|
|
2902
|
+
const taken = scope.taken;
|
|
2903
|
+
scope.taken = undefined;
|
|
2904
|
+
void track(undo_later_1.pressUndoPart.load().then((part) => part.offerUndo(inner, { kit: runner.kit, source, scope, taken, result, offers }), () => taken.said.forEach((words) => options.host?.say(words.message, words.tone))));
|
|
2905
|
+
}
|
|
2740
2906
|
const form = {
|
|
2741
2907
|
page,
|
|
2742
2908
|
...(table ? { functions: table } : {}),
|
|
@@ -2761,7 +2927,10 @@ function innerForm(options, within, place, outer) {
|
|
|
2761
2927
|
// A choice whose places are all taken is shown, and refused when the person picks it: said under its field.
|
|
2762
2928
|
if ((how?.by ?? 'person') === 'person' && refusedFull(name, value))
|
|
2763
2929
|
return;
|
|
2930
|
+
const before = state.values[name];
|
|
2764
2931
|
writeValues({ ...state.values, [name]: (0, values_1.structuredCopy)(value) });
|
|
2932
|
+
if ((how?.by ?? 'person') === 'person')
|
|
2933
|
+
noteChange(name, undefined, before, true);
|
|
2765
2934
|
afterEdit(name);
|
|
2766
2935
|
changed(name, how?.by ?? 'person');
|
|
2767
2936
|
},
|
|
@@ -2786,7 +2955,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2786
2955
|
// Nothing of the record changed; what shows of it may have.
|
|
2787
2956
|
set({});
|
|
2788
2957
|
},
|
|
2789
|
-
fieldReadonly: (name) => lockedField(fieldDef(name)) || state.can?.edit === false || state.can?.readonlyFields?.includes(name) === true || signedNow().has(name) ||
|
|
2958
|
+
fieldReadonly: (name) => lockedField(fieldDef(name)) || state.can?.edit === false || state.can?.readonlyFields?.includes(name) === true || signedNow().has(name) || anyJoin((join) => join.locksField?.(name)),
|
|
2790
2959
|
loadChoices: (field) => loadChoices(field),
|
|
2791
2960
|
loadDefinitions,
|
|
2792
2961
|
addDefinition,
|
|
@@ -2827,8 +2996,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2827
2996
|
return null;
|
|
2828
2997
|
if (state.unread[name])
|
|
2829
2998
|
return state.unread[name].message;
|
|
2830
|
-
// A property's text left unread answers for its field
|
|
2831
|
-
|
|
2999
|
+
// A property's text left unread answers for its field, and so does a box of a value drawn in parts (a repeat
|
|
3000
|
+
// rule's number, an opening hour's time: `field.part`).
|
|
3001
|
+
if (['properties', 'json', 'char'].includes(page.fields[name].type)) {
|
|
2832
3002
|
const row = Object.keys(state.unread).find((path) => path.startsWith(`${name}.`));
|
|
2833
3003
|
if (row)
|
|
2834
3004
|
return state.unread[row].message;
|
|
@@ -2842,7 +3012,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2842
3012
|
const field = path.split('.')[0];
|
|
2843
3013
|
// A line's cell (`field.lineKey.subfield`), or a property (`field.property`).
|
|
2844
3014
|
const def = fieldDef(field);
|
|
2845
|
-
|
|
3015
|
+
// A line's cell, a property, or one of the boxes a value is drawn in (a repeat rule's number, an opening hour's
|
|
3016
|
+
// time: `field.part`, of a char or a json field).
|
|
3017
|
+
if (path.includes('.') && def.type !== 'properties' && !((def.type === 'json' || def.type === 'char') && path.split('.').length === 2))
|
|
2846
3018
|
lineField(field);
|
|
2847
3019
|
const had = state.unread[path];
|
|
2848
3020
|
if (!unread && !had)
|
|
@@ -2865,6 +3037,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2865
3037
|
set({ unread: next, errors });
|
|
2866
3038
|
},
|
|
2867
3039
|
boxLeft(path) {
|
|
3040
|
+
noted.push([path.split('.')[0]]);
|
|
2868
3041
|
const problem = leftProblem(path);
|
|
2869
3042
|
if (!problem || state.errors[path] === problem)
|
|
2870
3043
|
return;
|
|
@@ -2887,10 +3060,11 @@ function innerForm(options, within, place, outer) {
|
|
|
2887
3060
|
if (seen.captcha !== undefined)
|
|
2888
3061
|
bot.captcha = seen.captcha;
|
|
2889
3062
|
},
|
|
3063
|
+
joined: (name) => (joins[joinParts.findIndex((part) => part.name === name)] ?? null),
|
|
2890
3064
|
reading: () => readingNow > 0 || [...attached.values()].some((part) => part.inner.form.reading()),
|
|
2891
|
-
validate() {
|
|
3065
|
+
validate(within) {
|
|
2892
3066
|
readTyped();
|
|
2893
|
-
const errors = collectErrors();
|
|
3067
|
+
const errors = collectErrors(within);
|
|
2894
3068
|
set({ errors });
|
|
2895
3069
|
return Object.keys(errors).length === 0;
|
|
2896
3070
|
},
|
|
@@ -2983,6 +3157,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2983
3157
|
holding = setWhen.holding(baseline);
|
|
2984
3158
|
// The person's own Discard: nothing of theirs is left at risk, and a save on its way lands as the record it stored.
|
|
2985
3159
|
resets++;
|
|
3160
|
+
noted = [];
|
|
2986
3161
|
personal.clear();
|
|
2987
3162
|
personalLines.clear();
|
|
2988
3163
|
filed.clear();
|
|
@@ -2991,6 +3166,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2991
3166
|
bot = { ...bot, honeypot: false, since: clock() };
|
|
2992
3167
|
const values = syncParts((0, values_1.structuredCopy)(baseline), 'start');
|
|
2993
3168
|
set({ values, dirty: [], errors: {}, warnings: withValues(values, collectWarnings), warning: null, warningField: null, draft: null, step: steps[0] ?? null, skipped: [], saveProblem: null, conflict: null, unsent: [], unread: {}, takenOut: {}, sent: null });
|
|
3169
|
+
// Started again: a new response proves and pays its own; a new respondent is drawn anew (unless the app or the
|
|
3170
|
+
// person's id is the seed), on the first step drawn, no clock running.
|
|
3171
|
+
joinsReset();
|
|
2994
3172
|
// Started again: whether the page takes another response, and each choice's places, asked again.
|
|
2995
3173
|
if (asksLimits())
|
|
2996
3174
|
void track(askLimits());
|
|
@@ -3010,8 +3188,10 @@ function innerForm(options, within, place, outer) {
|
|
|
3010
3188
|
const def = lineField(field);
|
|
3011
3189
|
if (!def.fields[name])
|
|
3012
3190
|
throw new Error(`The lines of "${field}" have no field "${name}"`);
|
|
3013
|
-
const
|
|
3191
|
+
const before = state.values[field];
|
|
3192
|
+
const lines = (before ?? []).map((line) => line.key === key ? { ...line, values: { ...line.values, [name]: (0, values_1.structuredCopy)(value) } } : line);
|
|
3014
3193
|
writeValues({ ...state.values, [field]: lines });
|
|
3194
|
+
noteChange(field, key, before, true);
|
|
3015
3195
|
afterEdit(field);
|
|
3016
3196
|
changed(field, 'person', { line: key });
|
|
3017
3197
|
},
|
|
@@ -3041,7 +3221,9 @@ function innerForm(options, within, place, outer) {
|
|
|
3041
3221
|
const value = trusted ? (i >= low && i <= high ? pool[i - low] : line.values[sequence]) : i + 1;
|
|
3042
3222
|
return value === line.values[sequence] ? line : { ...line, values: { ...line.values, [sequence]: value } };
|
|
3043
3223
|
});
|
|
3224
|
+
const was = state.values[field];
|
|
3044
3225
|
writeValues({ ...state.values, [field]: renumbered });
|
|
3226
|
+
noteChange(field, undefined, was, false);
|
|
3045
3227
|
afterEdit(field);
|
|
3046
3228
|
changed(field, 'person');
|
|
3047
3229
|
},
|
|
@@ -3055,8 +3237,10 @@ function innerForm(options, within, place, outer) {
|
|
|
3055
3237
|
throw new Error(`The line "${key}" of "${field}" cannot be deleted now: its table's lineDelete does not hold on it`);
|
|
3056
3238
|
}
|
|
3057
3239
|
}
|
|
3058
|
-
const
|
|
3240
|
+
const before = state.values[field];
|
|
3241
|
+
const lines = (before ?? []).filter((line) => line.key !== key);
|
|
3059
3242
|
writeValues({ ...state.values, [field]: lines });
|
|
3243
|
+
noteChange(field, key, before, false);
|
|
3060
3244
|
afterEdit(field);
|
|
3061
3245
|
changed(field, 'person', { line: key });
|
|
3062
3246
|
},
|
|
@@ -3123,6 +3307,8 @@ function innerForm(options, within, place, outer) {
|
|
|
3123
3307
|
set({ step: previous, errors: {} });
|
|
3124
3308
|
return true;
|
|
3125
3309
|
},
|
|
3310
|
+
startTimer: () => joined('surveyflow')?.start(),
|
|
3311
|
+
countdown: () => joined('surveyflow')?.countdown() ?? null,
|
|
3126
3312
|
skip() {
|
|
3127
3313
|
const current = state.step;
|
|
3128
3314
|
if (!current || !optionalStep(current))
|
|
@@ -3263,7 +3449,7 @@ function innerForm(options, within, place, outer) {
|
|
|
3263
3449
|
return () => void heard.delete(listener);
|
|
3264
3450
|
},
|
|
3265
3451
|
restoreDraft() {
|
|
3266
|
-
const kept = found ?? (0, drafts_1.draftRead)(
|
|
3452
|
+
const kept = found ?? (0, drafts_1.draftRead)(draftStore?.getItem(storeKey()) ?? null);
|
|
3267
3453
|
if (kept && 'values' in kept)
|
|
3268
3454
|
applyDraft(kept);
|
|
3269
3455
|
},
|
|
@@ -3284,14 +3470,18 @@ function innerForm(options, within, place, outer) {
|
|
|
3284
3470
|
return saved;
|
|
3285
3471
|
},
|
|
3286
3472
|
refreshLimits: () => askLimits(),
|
|
3287
|
-
refreshApprovals
|
|
3473
|
+
async refreshApprovals() {
|
|
3474
|
+
await joining;
|
|
3475
|
+
await joined('approvals')?.ask();
|
|
3476
|
+
},
|
|
3288
3477
|
async decide(level, decision, reason) {
|
|
3289
|
-
|
|
3478
|
+
await joining;
|
|
3479
|
+
const kit = joined('approvals');
|
|
3290
3480
|
if (!kit)
|
|
3291
3481
|
throw new Error('No approvals on this page');
|
|
3292
3482
|
return track(kit.decide(level, decision, reason));
|
|
3293
3483
|
},
|
|
3294
|
-
approvalLock: (name) =>
|
|
3484
|
+
approvalLock: (name) => joined('approvals')?.lockWords(name) ?? null,
|
|
3295
3485
|
async reloadTheirs() {
|
|
3296
3486
|
// A save on its way first: its answer is not dropped by the load.
|
|
3297
3487
|
const asked = shownNow();
|
|
@@ -3391,6 +3581,9 @@ function innerForm(options, within, place, outer) {
|
|
|
3391
3581
|
if (state.setAside)
|
|
3392
3582
|
set({ setAside: null });
|
|
3393
3583
|
},
|
|
3584
|
+
undo: () => replay(true),
|
|
3585
|
+
redo: () => replay(false),
|
|
3586
|
+
history: () => undo_later_1.pressUndoPart.loaded?.nextSteps(noted, inner.same) ?? { undo: null, redo: null },
|
|
3394
3587
|
async settled() {
|
|
3395
3588
|
while (pending.size)
|
|
3396
3589
|
await Promise.allSettled([...pending]);
|
|
@@ -3457,6 +3650,8 @@ function innerForm(options, within, place, outer) {
|
|
|
3457
3650
|
dispose() {
|
|
3458
3651
|
// An answer that lands after is for no record shown.
|
|
3459
3652
|
disposed = true;
|
|
3653
|
+
for (const join of joins)
|
|
3654
|
+
join?.dispose?.();
|
|
3460
3655
|
newGeneration();
|
|
3461
3656
|
clearFiles();
|
|
3462
3657
|
if (draftTimer !== null)
|
|
@@ -3476,9 +3671,22 @@ function innerForm(options, within, place, outer) {
|
|
|
3476
3671
|
// choice's places as the source tells them: a record's own once it is loaded, its own choices not counted against it.
|
|
3477
3672
|
if (keepsLimits())
|
|
3478
3673
|
void track(limitsCode());
|
|
3479
|
-
//
|
|
3480
|
-
|
|
3481
|
-
|
|
3674
|
+
// The parts its page or its source asks to join it — a survey's draw made before a draft is laid, which lays its own
|
|
3675
|
+
// draw over it; a record's approvals ready by the time its record is loaded; the record made live — each made at once
|
|
3676
|
+
// where it has come, else as it does, a draft laid meanwhile laid on it.
|
|
3677
|
+
if (joinParts.length) {
|
|
3678
|
+
const made = (at) => (part) => {
|
|
3679
|
+
if (disposed || joins[at])
|
|
3680
|
+
return;
|
|
3681
|
+
const join = (joins[at] = part.join(inner));
|
|
3682
|
+
if (laid)
|
|
3683
|
+
join.lay?.(laid);
|
|
3684
|
+
// Its record loaded before it came: what it asks of a loaded record, asked now.
|
|
3685
|
+
if (loadedOnce)
|
|
3686
|
+
join.loaded?.();
|
|
3687
|
+
};
|
|
3688
|
+
joining = Promise.all(joinParts.map((part, at) => (part.loaded ? made(at)(part.loaded) : track(part.load().then(made(at), () => undefined)))));
|
|
3689
|
+
}
|
|
3482
3690
|
// A new form has its values now — a draft continued from its key once it is laid — and opens once whoever made it
|
|
3483
3691
|
// has had the chance to listen.
|
|
3484
3692
|
if (state.recordId == null) {
|