@fieldia/core 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +362 -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 +337 -3
- package/src/lib/record/data-source.d.ts +337 -3
- 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/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 +15 -9
- package/src/lib/record/form-approvals.js.map +1 -1
- package/src/lib/record/form-approvals.mjs +14 -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 +125 -7
- package/src/lib/record/form.d.ts +125 -7
- package/src/lib/record/form.js +277 -77
- package/src/lib/record/form.js.map +1 -1
- package/src/lib/record/form.mjs +278 -78
- 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 +11 -1
- package/src/lib/record/locales/ar.js.map +1 -1
- package/src/lib/record/locales/ar.mjs +11 -1
- package/src/lib/record/locales/ar.mjs.map +1 -1
- package/src/lib/record/locales/de.js +11 -1
- package/src/lib/record/locales/de.js.map +1 -1
- package/src/lib/record/locales/de.mjs +11 -1
- 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 +11 -1
- package/src/lib/record/locales/fr.js.map +1 -1
- package/src/lib/record/locales/fr.mjs +11 -1
- 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 +7 -4
- package/src/lib/record/memory-approvals.d.ts +7 -4
- package/src/lib/record/memory-approvals.js +54 -7
- package/src/lib/record/memory-approvals.js.map +1 -1
- package/src/lib/record/memory-approvals.mjs +54 -7
- package/src/lib/record/memory-approvals.mjs.map +1 -1
- package/src/lib/record/memory-assist.d.mts +7 -2
- package/src/lib/record/memory-assist.d.ts +7 -2
- package/src/lib/record/memory-assist.js +47 -12
- package/src/lib/record/memory-assist.js.map +1 -1
- package/src/lib/record/memory-assist.mjs +46 -12
- package/src/lib/record/memory-assist.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 +60 -4
- package/src/lib/record/memory-data-source.d.ts +60 -4
- package/src/lib/record/memory-data-source.js +69 -1
- package/src/lib/record/memory-data-source.js.map +1 -1
- package/src/lib/record/memory-data-source.mjs +69 -1
- 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 +60 -0
- package/src/lib/record/memory-views.js.map +1 -0
- package/src/lib/record/memory-views.mjs +57 -0
- package/src/lib/record/memory-views.mjs.map +1 -0
- package/src/lib/record/messages.d.mts +24 -3
- package/src/lib/record/messages.d.ts +24 -3
- package/src/lib/record/messages.js +18 -3
- package/src/lib/record/messages.js.map +1 -1
- package/src/lib/record/messages.mjs +18 -3
- 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 +71 -8
- package/src/lib/record/run.d.ts +71 -8
- package/src/lib/record/run.js +40 -13
- package/src/lib/record/run.js.map +1 -1
- package/src/lib/record/run.mjs +38 -12
- 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 +99 -0
- package/src/lib/record/survey-kit.js.map +1 -0
- package/src/lib/record/survey-kit.mjs +96 -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,87 @@ 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
|
+
keep: () => void ((options.drafts || onServer()) && scheduleDraft()),
|
|
618
|
+
order: (list) => void (steps = list ?? layoutSteps),
|
|
619
|
+
refuse(name, message) {
|
|
620
|
+
// Said until the field changes from what it holds, as a refused save's words are.
|
|
621
|
+
serverErrors[name] = { message, value: JSON.stringify(state.values[name] ?? null) };
|
|
622
|
+
set({ errors: { ...state.errors, [name]: message } });
|
|
623
|
+
},
|
|
624
|
+
reload: () => load(true),
|
|
625
|
+
};
|
|
626
|
+
/** The person's changes to the record shown, as made (history.ts); and whether one is being taken back or made again now. */
|
|
627
|
+
let noted = [];
|
|
628
|
+
let replaying = false;
|
|
629
|
+
/**
|
|
630
|
+
* A person's change written to `field` (on `line`), noted for Undo with what it held `before`: typing on joins it
|
|
631
|
+
* (`joins`). The undo part takes them as they come, asked for with the first: in by the time the person presses Ctrl+Z.
|
|
632
|
+
*/
|
|
633
|
+
const noteChange = (field, line, before, joins) => {
|
|
634
|
+
if (replaying)
|
|
635
|
+
return;
|
|
636
|
+
noted.push([field, line, before ?? null, state.values[field] ?? null, joins]);
|
|
637
|
+
const part = undo_later_1.pressUndoPart.loaded;
|
|
638
|
+
if (part)
|
|
639
|
+
part.takeNoted(noted, inner.same);
|
|
640
|
+
// Kept while it comes; where it cannot, the oldest let go.
|
|
641
|
+
else if (noted.length > 500)
|
|
642
|
+
noted.shift();
|
|
643
|
+
else
|
|
644
|
+
undo_later_1.pressUndoPart.load().catch(() => undefined);
|
|
645
|
+
};
|
|
646
|
+
/**
|
|
647
|
+
* Undo (`back`) or Redo, once the undo part has come: the change taken, written as the person's own change back —
|
|
648
|
+
* the page's `change` steps and the source's onchange run as for any — once its field still holds what the change
|
|
649
|
+
* left and may be changed.
|
|
650
|
+
*/
|
|
651
|
+
function replay(back) {
|
|
652
|
+
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;
|
|
653
|
+
if (!step)
|
|
654
|
+
return null;
|
|
655
|
+
const { value, ...taken } = step;
|
|
656
|
+
replaying = true;
|
|
657
|
+
try {
|
|
658
|
+
writeValues({ ...state.values, [taken.field]: (0, values_1.structuredCopy)(value) });
|
|
659
|
+
afterEdit(taken.field);
|
|
660
|
+
changed(taken.field, 'person', taken.line === undefined ? {} : { line: taken.line });
|
|
661
|
+
}
|
|
662
|
+
finally {
|
|
663
|
+
replaying = false;
|
|
664
|
+
}
|
|
665
|
+
return taken;
|
|
666
|
+
}
|
|
562
667
|
function set(patch) {
|
|
563
668
|
const was = state.values;
|
|
564
669
|
const choicesWas = state.choices;
|
|
@@ -592,6 +697,10 @@ function innerForm(options, within, place, outer) {
|
|
|
592
697
|
part.inner.show(inside(state.errors, part.name));
|
|
593
698
|
for (const listener of [...listeners])
|
|
594
699
|
listener(state);
|
|
700
|
+
// What the parts that join the form follow of it: the record shown, watched for changes made elsewhere and for who
|
|
701
|
+
// else has it open, asked again as that changes.
|
|
702
|
+
for (const join of joins)
|
|
703
|
+
join?.changed?.();
|
|
595
704
|
// Choices that change with a value that just changed are asked for again.
|
|
596
705
|
if (state.values !== was) {
|
|
597
706
|
// After someone's change, a choice its new choices do not offer is taken out and said, as a line's is.
|
|
@@ -631,6 +740,7 @@ function innerForm(options, within, place, outer) {
|
|
|
631
740
|
/** 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
741
|
function newGeneration() {
|
|
633
742
|
generation++;
|
|
743
|
+
noted = [];
|
|
634
744
|
// Another record's lines ask the source anew.
|
|
635
745
|
lineAsks = new Map();
|
|
636
746
|
answers = new Map();
|
|
@@ -743,6 +853,9 @@ function innerForm(options, within, place, outer) {
|
|
|
743
853
|
return;
|
|
744
854
|
told = step;
|
|
745
855
|
emit('step', { step });
|
|
856
|
+
// A step with a time limit: its clock starts as it is first entered.
|
|
857
|
+
for (const join of joins)
|
|
858
|
+
join?.entered?.(step);
|
|
746
859
|
const list = page.on?.show?.[step];
|
|
747
860
|
if (list)
|
|
748
861
|
void track(moment(`on.show.${step}`, list, chain, true));
|
|
@@ -1114,13 +1227,13 @@ function innerForm(options, within, place, outer) {
|
|
|
1114
1227
|
if (!node)
|
|
1115
1228
|
throw new Error(`The page has no element "${id}"`);
|
|
1116
1229
|
const { context: ctx, env } = reading();
|
|
1117
|
-
const hidden = (at) => (at ? !(0, roles_1.rolesAllow)(at.roles, userRoles) || at.invisible.evaluate(ctx, env) : false);
|
|
1230
|
+
const hidden = (at) => (at ? anyJoin((join) => join.hides?.(at.id)) || !(0, roles_1.rolesAllow)(at.roles, userRoles) || at.invisible.evaluate(ctx, env) : false);
|
|
1118
1231
|
let invisible = hidden(node);
|
|
1119
1232
|
for (let parent = node.parent; !invisible && parent; parent = index.get(parent)?.parent ?? null) {
|
|
1120
1233
|
invisible = hidden(index.get(parent));
|
|
1121
1234
|
}
|
|
1122
|
-
// A section read-only right now makes everything inside it read-only too.
|
|
1123
|
-
let readonly = node.readonly.evaluate(ctx, env);
|
|
1235
|
+
// A section read-only right now makes everything inside it read-only too; a page's, or a step's, time run out too.
|
|
1236
|
+
let readonly = node.readonly.evaluate(ctx, env) || anyJoin((join) => join.locks?.(id));
|
|
1124
1237
|
for (let parent = node.parent; !readonly && parent; parent = index.get(parent)?.parent ?? null) {
|
|
1125
1238
|
readonly = index.get(parent)?.readonly.evaluate(ctx, env) ?? false;
|
|
1126
1239
|
}
|
|
@@ -1138,7 +1251,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1138
1251
|
if (answer !== undefined && signedNow().has(answer))
|
|
1139
1252
|
readonly = true;
|
|
1140
1253
|
// A record waiting for approval: locked but for the fields the page leaves open (the approvals part).
|
|
1141
|
-
if (answer !== undefined &&
|
|
1254
|
+
if (answer !== undefined && anyJoin((join) => join.locksField?.(answer)))
|
|
1142
1255
|
readonly = true;
|
|
1143
1256
|
return {
|
|
1144
1257
|
invisible,
|
|
@@ -1280,6 +1393,9 @@ function innerForm(options, within, place, outer) {
|
|
|
1280
1393
|
const errors = {};
|
|
1281
1394
|
const seen = new Set();
|
|
1282
1395
|
for (const node of visibleFieldNodes(root)) {
|
|
1396
|
+
// The answers of a time run out go as they stood: their checks refuse nothing.
|
|
1397
|
+
if (anyJoin((join) => join.locks?.(node.id)))
|
|
1398
|
+
continue;
|
|
1283
1399
|
const name = node.field;
|
|
1284
1400
|
seen.add(name);
|
|
1285
1401
|
const end = rangeEnd(node);
|
|
@@ -1588,6 +1704,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1588
1704
|
return {
|
|
1589
1705
|
values,
|
|
1590
1706
|
...(steps.length ? { step: state.step, skipped: [...state.skipped] } : {}),
|
|
1707
|
+
...Object.assign({}, ...joins.map((join) => join?.kept?.())),
|
|
1591
1708
|
...(Object.keys(state.unread).length ? { unread: (0, values_1.structuredCopy)(state.unread) } : {}),
|
|
1592
1709
|
answered: Object.keys(fields).filter((name) => state.dirty.includes(name)),
|
|
1593
1710
|
savedAt: new Date(clock()).toISOString(),
|
|
@@ -1643,6 +1760,10 @@ function innerForm(options, within, place, outer) {
|
|
|
1643
1760
|
/** 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
1761
|
function applyDraft(draft) {
|
|
1645
1762
|
found = null;
|
|
1763
|
+
// Its draw and its clocks, by the survey flow's part: now, or once it came.
|
|
1764
|
+
laid = draft;
|
|
1765
|
+
for (const join of joins)
|
|
1766
|
+
join?.lay?.(draft);
|
|
1646
1767
|
writeValues(withDraft(draft.values ?? {}), { draft: null }, true);
|
|
1647
1768
|
const known = (draft.skipped ?? []).filter((id) => steps.includes(id));
|
|
1648
1769
|
// Text typed that did not read stays as typed, said as it was, where its field is still on the page.
|
|
@@ -1737,27 +1858,8 @@ function innerForm(options, within, place, outer) {
|
|
|
1737
1858
|
function limitsMade(part) {
|
|
1738
1859
|
if (limitsKit || disposed)
|
|
1739
1860
|
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
|
-
});
|
|
1861
|
+
// The one kit, made at the limits' own moment: once the form knows it keeps them (joins.ts).
|
|
1862
|
+
const kit = part.formLimits(inner);
|
|
1761
1863
|
limitsKit = kit;
|
|
1762
1864
|
kit.show();
|
|
1763
1865
|
if (kit.asks() && (state.recordId == null || loadedOnce))
|
|
@@ -1778,15 +1880,6 @@ function innerForm(options, within, place, outer) {
|
|
|
1778
1880
|
}
|
|
1779
1881
|
/** A choice of a full option, picked by the person, refused under its field: the field keeps what it held. */
|
|
1780
1882
|
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
1883
|
function scheduleAutosave() {
|
|
1791
1884
|
const autosave = options.autosave;
|
|
1792
1885
|
// A record the person may not change is never saved unasked: it would only be refused.
|
|
@@ -1863,9 +1956,24 @@ function innerForm(options, within, place, outer) {
|
|
|
1863
1956
|
}
|
|
1864
1957
|
return shown;
|
|
1865
1958
|
}
|
|
1866
|
-
|
|
1867
|
-
|
|
1959
|
+
/** A response's answers as they go: those shown, and what the parts that join the form add (a link's hidden fields). */
|
|
1960
|
+
function answersSent() {
|
|
1961
|
+
const values = shownValues();
|
|
1962
|
+
for (const join of joins)
|
|
1963
|
+
join.values?.(values);
|
|
1964
|
+
return values;
|
|
1965
|
+
}
|
|
1966
|
+
async function save(chain = [], yes) {
|
|
1967
|
+
return (await saving(chain, yes)) === null;
|
|
1968
|
+
}
|
|
1969
|
+
/** 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. */
|
|
1970
|
+
function through(kind, sent, send) {
|
|
1971
|
+
return joins.reduce((go, join) => (join.around ? (one) => join.around(kind, one, go) : go), send)(sent);
|
|
1868
1972
|
}
|
|
1973
|
+
/** Started again, or another record opened: the parts that join the form let go of what the one before had. */
|
|
1974
|
+
const joinsReset = () => joins.forEach((join) => join.reset?.());
|
|
1975
|
+
/** The record loaded, or saved: what the parts that join the form ask again (a record's approvals). */
|
|
1976
|
+
const joinsLoaded = () => joins.forEach((join) => join.loaded?.());
|
|
1869
1977
|
/** Every value, for a source that saves whole records: those of fields hidden from the person, which they never had, left out. */
|
|
1870
1978
|
function sentValues() {
|
|
1871
1979
|
const values = (0, values_1.structuredCopy)(state.values);
|
|
@@ -1893,14 +2001,14 @@ function innerForm(options, within, place, outer) {
|
|
|
1893
2001
|
* save with the version the first got back, never as someone else's. A save
|
|
1894
2002
|
* the page's own beforeSave steps ask for runs inside the one that set them off.
|
|
1895
2003
|
*/
|
|
1896
|
-
function saving(chain) {
|
|
2004
|
+
function saving(chain, yes) {
|
|
1897
2005
|
if (chain.includes('on.beforeSave'))
|
|
1898
|
-
return savingNow(chain);
|
|
2006
|
+
return savingNow(chain, yes);
|
|
1899
2007
|
const before = saveRunning;
|
|
1900
2008
|
const mine = (async () => {
|
|
1901
2009
|
if (before)
|
|
1902
2010
|
await before;
|
|
1903
|
-
return savingNow(chain);
|
|
2011
|
+
return savingNow(chain, yes);
|
|
1904
2012
|
})();
|
|
1905
2013
|
const done = mine.then(() => undefined, () => undefined);
|
|
1906
2014
|
saveRunning = done;
|
|
@@ -1910,7 +2018,7 @@ function innerForm(options, within, place, outer) {
|
|
|
1910
2018
|
});
|
|
1911
2019
|
return mine;
|
|
1912
2020
|
}
|
|
1913
|
-
async function savingNow(chain) {
|
|
2021
|
+
async function savingNow(chain, yes) {
|
|
1914
2022
|
// A record its source does not let this person change is refused here, in its words or the form's: no source is asked.
|
|
1915
2023
|
if (page.data.kind === 'record' && state.can?.edit === false) {
|
|
1916
2024
|
const problem = { kind: 'rule', message: state.can.reason ?? named(messages.mayNotEditNoun, messages.mayNotEdit) };
|
|
@@ -1958,7 +2066,8 @@ function innerForm(options, within, place, outer) {
|
|
|
1958
2066
|
if (page.on?.beforeSave) {
|
|
1959
2067
|
// Its run stops of itself on a record shown by anything but its own steps (a `call`'s `{ record }`, a reload):
|
|
1960
2068
|
// those move the save on with it.
|
|
1961
|
-
|
|
2069
|
+
// Its questions' Yes goes on with what set the save off: its words (Submit, a button's).
|
|
2070
|
+
const before = await moment('on.beforeSave', page.on.beforeSave, chain, false, yes);
|
|
1962
2071
|
if (!before.done) {
|
|
1963
2072
|
// A check's problems, or an inner save's, are shown already; any other stop is this save's problem.
|
|
1964
2073
|
if (before.reason !== 'check' && before.reason !== 'save') {
|
|
@@ -1972,8 +2081,22 @@ function innerForm(options, within, place, outer) {
|
|
|
1972
2081
|
const refused = await stillTaking(asked);
|
|
1973
2082
|
if (refused)
|
|
1974
2083
|
return refused;
|
|
1975
|
-
//
|
|
2084
|
+
// The parts that join the form (`formJoins`), waited for where they have not come.
|
|
2085
|
+
if (joining) {
|
|
2086
|
+
await joining;
|
|
2087
|
+
if (asked !== generation)
|
|
2088
|
+
return elsewhere();
|
|
2089
|
+
}
|
|
2090
|
+
// A file that did not reach the store stops it, under its field, with the form's own checks — and what the parts that
|
|
2091
|
+
// join the form find: an email or a phone not proved by a code; a payment not taken sends nothing.
|
|
1976
2092
|
const errors = { ...collectErrors(), ...fileProblems() };
|
|
2093
|
+
for (const join of joins) {
|
|
2094
|
+
// A part that never came (a hole) has nothing to say.
|
|
2095
|
+
if ((await join?.before?.(errors)) === false)
|
|
2096
|
+
return { reason: 'save' };
|
|
2097
|
+
if (asked !== generation)
|
|
2098
|
+
return elsewhere();
|
|
2099
|
+
}
|
|
1977
2100
|
if (Object.keys(errors).length) {
|
|
1978
2101
|
set({ errors, ...unstored(errors) });
|
|
1979
2102
|
return { reason: 'save', message: Object.values(errors)[0] };
|
|
@@ -2003,13 +2126,18 @@ function innerForm(options, within, place, outer) {
|
|
|
2003
2126
|
if (page.data.kind === 'responses') {
|
|
2004
2127
|
if (!source?.submit)
|
|
2005
2128
|
throw new Error('This page has no data source to send its answers to');
|
|
2006
|
-
const sent =
|
|
2129
|
+
const sent = answersSent();
|
|
2007
2130
|
const before = state.values;
|
|
2008
2131
|
at = generation;
|
|
2009
2132
|
const resetAt = resets;
|
|
2010
2133
|
const seen = botReport();
|
|
2134
|
+
// A quiz's marking, in before the answers go: what the person sees of their results.
|
|
2011
2135
|
// What the source answered: the id it gave the response, and the values it added — what an ending reads.
|
|
2012
|
-
const
|
|
2136
|
+
const request = { pageId: page.id, values: sent, ...(seen ? { bot: seen } : {}), ...draft };
|
|
2137
|
+
// Through the parts that join the form: kept on the device where an outbox finds no signal (null), the form going
|
|
2138
|
+
// on as though it went.
|
|
2139
|
+
const got = await through('submit', request, (one) => source.submit(one));
|
|
2140
|
+
const answer = got ?? {};
|
|
2013
2141
|
// The captcha's token is spent once sent: the next send waits for a new one.
|
|
2014
2142
|
if (seen?.captcha)
|
|
2015
2143
|
bot.captcha = null;
|
|
@@ -2021,8 +2149,13 @@ function innerForm(options, within, place, outer) {
|
|
|
2021
2149
|
sentAs = before;
|
|
2022
2150
|
const added = answer.values && typeof answer.values === 'object' ? (0, values_1.structuredCopy)(answer.values) : {};
|
|
2023
2151
|
// Started again meanwhile (`reset`): a new response is on screen, and no ending is the old one's.
|
|
2024
|
-
|
|
2152
|
+
// A quiz's results: the source's marking, else the page's, on the answers as sent.
|
|
2153
|
+
const quiz = answer.quiz ?? joined('surveyflow')?.marked(sent);
|
|
2154
|
+
set({ status: 'saved', unsent: unsentNow(), ...(resets === resetAt ? { sent: { id: answer.id ?? null, values: { ...(0, values_1.structuredCopy)(sent), ...added }, ...(quiz ? { quiz } : {}) } } : {}) });
|
|
2025
2155
|
emit('send', { values: sent, ...(seen ? { bot: seen } : {}) });
|
|
2156
|
+
// Kept, not sent: its counts and its after-save steps wait for a send that went.
|
|
2157
|
+
if (got === null)
|
|
2158
|
+
return null;
|
|
2026
2159
|
// Counted again: one response fewer to take, this person's sent.
|
|
2027
2160
|
if (asksLimits())
|
|
2028
2161
|
void track(askLimits());
|
|
@@ -2035,7 +2168,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2035
2168
|
const sent = state.values;
|
|
2036
2169
|
at = generation;
|
|
2037
2170
|
const resetAt = resets;
|
|
2038
|
-
const
|
|
2171
|
+
const request = {
|
|
2039
2172
|
model: page.data.model,
|
|
2040
2173
|
id: state.recordId,
|
|
2041
2174
|
fields,
|
|
@@ -2044,7 +2177,10 @@ function innerForm(options, within, place, outer) {
|
|
|
2044
2177
|
// The version it was opened at, for a source that refuses a save over someone else's.
|
|
2045
2178
|
...(state.recordId != null && state.version ? { version: state.version } : {}),
|
|
2046
2179
|
...draft,
|
|
2047
|
-
}
|
|
2180
|
+
};
|
|
2181
|
+
const got = await through('save', request, (one) => source.save(one));
|
|
2182
|
+
// Kept on the device (null): the record as it was, its version too.
|
|
2183
|
+
const result = got ?? { id: state.recordId, version: state.version ?? undefined };
|
|
2048
2184
|
// Answered for a record no longer shown — another opened, or this one loaded again: the source has it, and the
|
|
2049
2185
|
// form lays nothing of it over the record it shows now.
|
|
2050
2186
|
if (at !== generation)
|
|
@@ -2063,11 +2199,11 @@ function innerForm(options, within, place, outer) {
|
|
|
2063
2199
|
scheduleAutosave();
|
|
2064
2200
|
}
|
|
2065
2201
|
// A save may have sent it for approval, or moved it on: its approvals asked again.
|
|
2066
|
-
|
|
2067
|
-
void track(askApprovals());
|
|
2202
|
+
joinsLoaded();
|
|
2068
2203
|
// The record as this save left it: a change made while it was on its way is no value of it.
|
|
2069
2204
|
emit('save', { recordId: state.recordId, values: baseline });
|
|
2070
|
-
|
|
2205
|
+
if (got)
|
|
2206
|
+
void track(moment('on.afterSave', page.on?.afterSave, chain, false));
|
|
2071
2207
|
return null;
|
|
2072
2208
|
}
|
|
2073
2209
|
catch (error) {
|
|
@@ -2173,7 +2309,8 @@ function innerForm(options, within, place, outer) {
|
|
|
2173
2309
|
}
|
|
2174
2310
|
function addLine(field, values, by) {
|
|
2175
2311
|
const def = lineField(field);
|
|
2176
|
-
const
|
|
2312
|
+
const before = state.values[field];
|
|
2313
|
+
const current = before ?? [];
|
|
2177
2314
|
// A key no line holds: lines given (a line's own lines, back from its form) may hold new-… keys already.
|
|
2178
2315
|
let key = `new-${++lineKeys}`;
|
|
2179
2316
|
while (current.some((line) => line.key === key))
|
|
@@ -2186,6 +2323,8 @@ function innerForm(options, within, place, outer) {
|
|
|
2186
2323
|
}
|
|
2187
2324
|
const lines = [...current, line];
|
|
2188
2325
|
writeValues({ ...state.values, [field]: lines });
|
|
2326
|
+
if (by === 'person')
|
|
2327
|
+
noteChange(field, key, before, false);
|
|
2189
2328
|
afterEdit(field);
|
|
2190
2329
|
changed(field, by, by === 'person' ? { line: key } : { keep: true });
|
|
2191
2330
|
return key;
|
|
@@ -2330,8 +2469,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2330
2469
|
if (asksLimits())
|
|
2331
2470
|
void track(askLimits());
|
|
2332
2471
|
// Its approvals: where it stands, what was decided, what this person may decide — its fields locked while it waits.
|
|
2333
|
-
|
|
2334
|
-
void track(askApprovals());
|
|
2472
|
+
joinsLoaded();
|
|
2335
2473
|
if (again)
|
|
2336
2474
|
return;
|
|
2337
2475
|
offerDraft();
|
|
@@ -2367,6 +2505,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2367
2505
|
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 };
|
|
2368
2506
|
if (id != null) {
|
|
2369
2507
|
set({ ...fresh, recordId: id, status: 'idle' });
|
|
2508
|
+
joinsReset();
|
|
2370
2509
|
await load();
|
|
2371
2510
|
return true;
|
|
2372
2511
|
}
|
|
@@ -2374,6 +2513,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2374
2513
|
baseline = startFrom(startingValues(true, false));
|
|
2375
2514
|
const values = syncParts((0, values_1.structuredCopy)(baseline), 'start');
|
|
2376
2515
|
set({ ...fresh, recordId: null, status: 'ready', values, warnings: withValues(values, collectWarnings) });
|
|
2516
|
+
joinsReset();
|
|
2377
2517
|
if (asksLimits())
|
|
2378
2518
|
void track(askLimits());
|
|
2379
2519
|
offerDraft();
|
|
@@ -2674,7 +2814,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2674
2814
|
});
|
|
2675
2815
|
// A moment's run is on the record it was set off on: one set off again while its run goes, and run after it, is let
|
|
2676
2816
|
// go when another record is shown by then (its steps were for that one).
|
|
2677
|
-
const moment = (0, run_1.createMoments)((key, list, chain, on) => runTop(list, { id: key, chain, generation: on }), () => generation);
|
|
2817
|
+
const moment = (0, run_1.createMoments)((key, list, chain, on, yes) => runTop(list, { id: key, chain, generation: on, yes }), () => generation);
|
|
2678
2818
|
/**
|
|
2679
2819
|
* Whether steps do something before their first save — set a status, call the app, open a page — so a record's
|
|
2680
2820
|
* button made of them saves first. Steps that start with the save (Save and close), or only check before it, need
|
|
@@ -2698,14 +2838,20 @@ function innerForm(options, within, place, outer) {
|
|
|
2698
2838
|
const builtin = 'builtin' in source && !list.length ? source.builtin : undefined;
|
|
2699
2839
|
if (builtin)
|
|
2700
2840
|
list.push({ do: builtin });
|
|
2701
|
-
|
|
2841
|
+
// Undo after it, in place of asking first: a built-in with `undo` asks nothing unless it says so.
|
|
2842
|
+
const offers = 'undo' in source ? source.undo : undefined;
|
|
2843
|
+
const asked = offers !== undefined ? undefined : builtin === 'archive' ? named(messages.archiveConfirmNoun, messages.archiveConfirm) : builtin === 'delete' ? named(messages.deleteConfirmNoun, messages.deleteConfirm) : undefined;
|
|
2702
2844
|
const confirm = 'confirm' in source && source.confirm !== undefined ? source.confirm : asked;
|
|
2845
|
+
if (offers !== undefined)
|
|
2846
|
+
scope.taken = (0, run_1.takenNow)(state.values);
|
|
2847
|
+
// Its question's Yes, and its ask steps', say what it does: its own words, else Archive or Delete.
|
|
2848
|
+
scope.yes ??= source.label || (builtin === 'archive' ? messages.archiveYes : builtin === 'delete' ? messages.deleteYes : undefined);
|
|
2703
2849
|
// On the record it was pressed on: another shown while its question is asked, it does nothing to that one.
|
|
2704
2850
|
scope.generation ??= generation;
|
|
2705
2851
|
// Pressed by the person: what is typed is read before a step reads the form or hands its values on.
|
|
2706
2852
|
scope.typed ??= 'first';
|
|
2707
2853
|
return track((async () => {
|
|
2708
|
-
if (confirm && !(await runner.ask(confirm))) {
|
|
2854
|
+
if (confirm && !(await runner.ask(confirm, scope.yes))) {
|
|
2709
2855
|
const result = { done: false, reason: 'no', message: confirm };
|
|
2710
2856
|
emit('run', { id: scope.id, steps: list, result });
|
|
2711
2857
|
return result;
|
|
@@ -2724,16 +2870,28 @@ function innerForm(options, within, place, outer) {
|
|
|
2724
2870
|
}
|
|
2725
2871
|
// Then the save first, then the steps.
|
|
2726
2872
|
if (saveFirst && (state.recordId == null || state.dirty.length > 0 || Object.keys(state.unread ?? {}).length > 0 || state.uploads.some(uploads_1.uploadGoing))) {
|
|
2727
|
-
const first = await saving(scope.chain);
|
|
2873
|
+
const first = await saving(scope.chain, scope.yes);
|
|
2728
2874
|
if (first) {
|
|
2729
2875
|
const result = { done: false, step: { do: 'save' }, reason: first.reason, ...(first.message !== undefined ? { message: first.message } : {}), ...(first.error !== undefined ? { error: first.error } : {}) };
|
|
2730
2876
|
emit('run', { id: scope.id, steps: list, result });
|
|
2731
2877
|
return result;
|
|
2732
2878
|
}
|
|
2733
2879
|
}
|
|
2734
|
-
|
|
2880
|
+
const result = await runTop(list, scope);
|
|
2881
|
+
if (scope.taken)
|
|
2882
|
+
offerUndo(source, scope, result, offers);
|
|
2883
|
+
return result;
|
|
2735
2884
|
})());
|
|
2736
2885
|
}
|
|
2886
|
+
/**
|
|
2887
|
+
* A press that offers Undo has ended: its words said — the last with Undo, where what it did can be taken back — by
|
|
2888
|
+
* the undo part (press-undo.ts), which a page whose buttons offer Undo asks for first; plainly where it cannot come.
|
|
2889
|
+
*/
|
|
2890
|
+
function offerUndo(source, scope, result, offers) {
|
|
2891
|
+
const taken = scope.taken;
|
|
2892
|
+
scope.taken = undefined;
|
|
2893
|
+
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))));
|
|
2894
|
+
}
|
|
2737
2895
|
const form = {
|
|
2738
2896
|
page,
|
|
2739
2897
|
...(table ? { functions: table } : {}),
|
|
@@ -2758,7 +2916,10 @@ function innerForm(options, within, place, outer) {
|
|
|
2758
2916
|
// A choice whose places are all taken is shown, and refused when the person picks it: said under its field.
|
|
2759
2917
|
if ((how?.by ?? 'person') === 'person' && refusedFull(name, value))
|
|
2760
2918
|
return;
|
|
2919
|
+
const before = state.values[name];
|
|
2761
2920
|
writeValues({ ...state.values, [name]: (0, values_1.structuredCopy)(value) });
|
|
2921
|
+
if ((how?.by ?? 'person') === 'person')
|
|
2922
|
+
noteChange(name, undefined, before, true);
|
|
2762
2923
|
afterEdit(name);
|
|
2763
2924
|
changed(name, how?.by ?? 'person');
|
|
2764
2925
|
},
|
|
@@ -2783,7 +2944,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2783
2944
|
// Nothing of the record changed; what shows of it may have.
|
|
2784
2945
|
set({});
|
|
2785
2946
|
},
|
|
2786
|
-
fieldReadonly: (name) => lockedField(fieldDef(name)) || state.can?.edit === false || state.can?.readonlyFields?.includes(name) === true || signedNow().has(name) ||
|
|
2947
|
+
fieldReadonly: (name) => lockedField(fieldDef(name)) || state.can?.edit === false || state.can?.readonlyFields?.includes(name) === true || signedNow().has(name) || anyJoin((join) => join.locksField?.(name)),
|
|
2787
2948
|
loadChoices: (field) => loadChoices(field),
|
|
2788
2949
|
loadDefinitions,
|
|
2789
2950
|
addDefinition,
|
|
@@ -2824,8 +2985,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2824
2985
|
return null;
|
|
2825
2986
|
if (state.unread[name])
|
|
2826
2987
|
return state.unread[name].message;
|
|
2827
|
-
// A property's text left unread answers for its field
|
|
2828
|
-
|
|
2988
|
+
// A property's text left unread answers for its field, and so does a box of a value drawn in parts (a repeat
|
|
2989
|
+
// rule's number, an opening hour's time: `field.part`).
|
|
2990
|
+
if (['properties', 'json', 'char'].includes(page.fields[name].type)) {
|
|
2829
2991
|
const row = Object.keys(state.unread).find((path) => path.startsWith(`${name}.`));
|
|
2830
2992
|
if (row)
|
|
2831
2993
|
return state.unread[row].message;
|
|
@@ -2839,7 +3001,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2839
3001
|
const field = path.split('.')[0];
|
|
2840
3002
|
// A line's cell (`field.lineKey.subfield`), or a property (`field.property`).
|
|
2841
3003
|
const def = fieldDef(field);
|
|
2842
|
-
|
|
3004
|
+
// 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
|
|
3005
|
+
// time: `field.part`, of a char or a json field).
|
|
3006
|
+
if (path.includes('.') && def.type !== 'properties' && !((def.type === 'json' || def.type === 'char') && path.split('.').length === 2))
|
|
2843
3007
|
lineField(field);
|
|
2844
3008
|
const had = state.unread[path];
|
|
2845
3009
|
if (!unread && !had)
|
|
@@ -2862,6 +3026,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2862
3026
|
set({ unread: next, errors });
|
|
2863
3027
|
},
|
|
2864
3028
|
boxLeft(path) {
|
|
3029
|
+
noted.push([path.split('.')[0]]);
|
|
2865
3030
|
const problem = leftProblem(path);
|
|
2866
3031
|
if (!problem || state.errors[path] === problem)
|
|
2867
3032
|
return;
|
|
@@ -2884,14 +3049,15 @@ function innerForm(options, within, place, outer) {
|
|
|
2884
3049
|
if (seen.captcha !== undefined)
|
|
2885
3050
|
bot.captcha = seen.captcha;
|
|
2886
3051
|
},
|
|
3052
|
+
joined: (name) => (joins[joinParts.findIndex((part) => part.name === name)] ?? null),
|
|
2887
3053
|
reading: () => readingNow > 0 || [...attached.values()].some((part) => part.inner.form.reading()),
|
|
2888
|
-
validate() {
|
|
3054
|
+
validate(within) {
|
|
2889
3055
|
readTyped();
|
|
2890
|
-
const errors = collectErrors();
|
|
3056
|
+
const errors = collectErrors(within);
|
|
2891
3057
|
set({ errors });
|
|
2892
3058
|
return Object.keys(errors).length === 0;
|
|
2893
3059
|
},
|
|
2894
|
-
save: () => track(save()),
|
|
3060
|
+
save: (how) => track(save([], how?.yes)),
|
|
2895
3061
|
canUpload: () => typeof options.dataSource?.upload === 'function',
|
|
2896
3062
|
today,
|
|
2897
3063
|
now: () => options.now?.() ?? new Date(),
|
|
@@ -2980,6 +3146,7 @@ function innerForm(options, within, place, outer) {
|
|
|
2980
3146
|
holding = setWhen.holding(baseline);
|
|
2981
3147
|
// The person's own Discard: nothing of theirs is left at risk, and a save on its way lands as the record it stored.
|
|
2982
3148
|
resets++;
|
|
3149
|
+
noted = [];
|
|
2983
3150
|
personal.clear();
|
|
2984
3151
|
personalLines.clear();
|
|
2985
3152
|
filed.clear();
|
|
@@ -2988,6 +3155,9 @@ function innerForm(options, within, place, outer) {
|
|
|
2988
3155
|
bot = { ...bot, honeypot: false, since: clock() };
|
|
2989
3156
|
const values = syncParts((0, values_1.structuredCopy)(baseline), 'start');
|
|
2990
3157
|
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 });
|
|
3158
|
+
// Started again: a new response proves and pays its own; a new respondent is drawn anew (unless the app or the
|
|
3159
|
+
// person's id is the seed), on the first step drawn, no clock running.
|
|
3160
|
+
joinsReset();
|
|
2991
3161
|
// Started again: whether the page takes another response, and each choice's places, asked again.
|
|
2992
3162
|
if (asksLimits())
|
|
2993
3163
|
void track(askLimits());
|
|
@@ -3007,8 +3177,10 @@ function innerForm(options, within, place, outer) {
|
|
|
3007
3177
|
const def = lineField(field);
|
|
3008
3178
|
if (!def.fields[name])
|
|
3009
3179
|
throw new Error(`The lines of "${field}" have no field "${name}"`);
|
|
3010
|
-
const
|
|
3180
|
+
const before = state.values[field];
|
|
3181
|
+
const lines = (before ?? []).map((line) => line.key === key ? { ...line, values: { ...line.values, [name]: (0, values_1.structuredCopy)(value) } } : line);
|
|
3011
3182
|
writeValues({ ...state.values, [field]: lines });
|
|
3183
|
+
noteChange(field, key, before, true);
|
|
3012
3184
|
afterEdit(field);
|
|
3013
3185
|
changed(field, 'person', { line: key });
|
|
3014
3186
|
},
|
|
@@ -3038,7 +3210,9 @@ function innerForm(options, within, place, outer) {
|
|
|
3038
3210
|
const value = trusted ? (i >= low && i <= high ? pool[i - low] : line.values[sequence]) : i + 1;
|
|
3039
3211
|
return value === line.values[sequence] ? line : { ...line, values: { ...line.values, [sequence]: value } };
|
|
3040
3212
|
});
|
|
3213
|
+
const was = state.values[field];
|
|
3041
3214
|
writeValues({ ...state.values, [field]: renumbered });
|
|
3215
|
+
noteChange(field, undefined, was, false);
|
|
3042
3216
|
afterEdit(field);
|
|
3043
3217
|
changed(field, 'person');
|
|
3044
3218
|
},
|
|
@@ -3052,8 +3226,10 @@ function innerForm(options, within, place, outer) {
|
|
|
3052
3226
|
throw new Error(`The line "${key}" of "${field}" cannot be deleted now: its table's lineDelete does not hold on it`);
|
|
3053
3227
|
}
|
|
3054
3228
|
}
|
|
3055
|
-
const
|
|
3229
|
+
const before = state.values[field];
|
|
3230
|
+
const lines = (before ?? []).filter((line) => line.key !== key);
|
|
3056
3231
|
writeValues({ ...state.values, [field]: lines });
|
|
3232
|
+
noteChange(field, key, before, false);
|
|
3057
3233
|
afterEdit(field);
|
|
3058
3234
|
changed(field, 'person', { line: key });
|
|
3059
3235
|
},
|
|
@@ -3120,6 +3296,8 @@ function innerForm(options, within, place, outer) {
|
|
|
3120
3296
|
set({ step: previous, errors: {} });
|
|
3121
3297
|
return true;
|
|
3122
3298
|
},
|
|
3299
|
+
startTimer: () => joined('surveyflow')?.start(),
|
|
3300
|
+
countdown: () => joined('surveyflow')?.countdown() ?? null,
|
|
3123
3301
|
skip() {
|
|
3124
3302
|
const current = state.step;
|
|
3125
3303
|
if (!current || !optionalStep(current))
|
|
@@ -3245,7 +3423,7 @@ function innerForm(options, within, place, outer) {
|
|
|
3245
3423
|
lines: { field: source.field, keys: [...keys], ids: lines.flatMap((line) => (line.id === undefined ? [] : [line.id])), values: lines.map((line) => (0, values_1.structuredCopy)(line.values)) },
|
|
3246
3424
|
});
|
|
3247
3425
|
},
|
|
3248
|
-
run: (list, context = {}) => track(runTop(list, { id: context.id ?? 'run', chain: [], typed: 'first', ...(context.recordIds ? { recordIds: [...context.recordIds] } : {}) })),
|
|
3426
|
+
run: (list, context = {}) => track(runTop(list, { id: context.id ?? 'run', chain: [], typed: 'first', ...(context.recordIds ? { recordIds: [...context.recordIds] } : {}), yes: context.yes })),
|
|
3249
3427
|
shown(tab) {
|
|
3250
3428
|
// A wizard's steps are told by the form itself, as they are entered.
|
|
3251
3429
|
if (steps.includes(tab))
|
|
@@ -3281,14 +3459,18 @@ function innerForm(options, within, place, outer) {
|
|
|
3281
3459
|
return saved;
|
|
3282
3460
|
},
|
|
3283
3461
|
refreshLimits: () => askLimits(),
|
|
3284
|
-
refreshApprovals
|
|
3462
|
+
async refreshApprovals() {
|
|
3463
|
+
await joining;
|
|
3464
|
+
await joined('approvals')?.ask();
|
|
3465
|
+
},
|
|
3285
3466
|
async decide(level, decision, reason) {
|
|
3286
|
-
|
|
3467
|
+
await joining;
|
|
3468
|
+
const kit = joined('approvals');
|
|
3287
3469
|
if (!kit)
|
|
3288
3470
|
throw new Error('No approvals on this page');
|
|
3289
3471
|
return track(kit.decide(level, decision, reason));
|
|
3290
3472
|
},
|
|
3291
|
-
approvalLock: (name) =>
|
|
3473
|
+
approvalLock: (name) => joined('approvals')?.lockWords(name) ?? null,
|
|
3292
3474
|
async reloadTheirs() {
|
|
3293
3475
|
// A save on its way first: its answer is not dropped by the load.
|
|
3294
3476
|
const asked = shownNow();
|
|
@@ -3388,6 +3570,9 @@ function innerForm(options, within, place, outer) {
|
|
|
3388
3570
|
if (state.setAside)
|
|
3389
3571
|
set({ setAside: null });
|
|
3390
3572
|
},
|
|
3573
|
+
undo: () => replay(true),
|
|
3574
|
+
redo: () => replay(false),
|
|
3575
|
+
history: () => undo_later_1.pressUndoPart.loaded?.nextSteps(noted, inner.same) ?? { undo: null, redo: null },
|
|
3391
3576
|
async settled() {
|
|
3392
3577
|
while (pending.size)
|
|
3393
3578
|
await Promise.allSettled([...pending]);
|
|
@@ -3454,6 +3639,8 @@ function innerForm(options, within, place, outer) {
|
|
|
3454
3639
|
dispose() {
|
|
3455
3640
|
// An answer that lands after is for no record shown.
|
|
3456
3641
|
disposed = true;
|
|
3642
|
+
for (const join of joins)
|
|
3643
|
+
join?.dispose?.();
|
|
3457
3644
|
newGeneration();
|
|
3458
3645
|
clearFiles();
|
|
3459
3646
|
if (draftTimer !== null)
|
|
@@ -3473,9 +3660,22 @@ function innerForm(options, within, place, outer) {
|
|
|
3473
3660
|
// choice's places as the source tells them: a record's own once it is loaded, its own choices not counted against it.
|
|
3474
3661
|
if (keepsLimits())
|
|
3475
3662
|
void track(limitsCode());
|
|
3476
|
-
//
|
|
3477
|
-
|
|
3478
|
-
|
|
3663
|
+
// 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
|
|
3664
|
+
// draw over it; a record's approvals ready by the time its record is loaded; the record made live — each made at once
|
|
3665
|
+
// where it has come, else as it does, a draft laid meanwhile laid on it.
|
|
3666
|
+
if (joinParts.length) {
|
|
3667
|
+
const made = (at) => (part) => {
|
|
3668
|
+
if (disposed || joins[at])
|
|
3669
|
+
return;
|
|
3670
|
+
const join = (joins[at] = part.join(inner));
|
|
3671
|
+
if (laid)
|
|
3672
|
+
join.lay?.(laid);
|
|
3673
|
+
// Its record loaded before it came: what it asks of a loaded record, asked now.
|
|
3674
|
+
if (loadedOnce)
|
|
3675
|
+
join.loaded?.();
|
|
3676
|
+
};
|
|
3677
|
+
joining = Promise.all(joinParts.map((part, at) => (part.loaded ? made(at)(part.loaded) : track(part.load().then(made(at), () => undefined)))));
|
|
3678
|
+
}
|
|
3479
3679
|
// A new form has its values now — a draft continued from its key once it is laid — and opens once whoever made it
|
|
3480
3680
|
// has had the chance to listen.
|
|
3481
3681
|
if (state.recordId == null) {
|