@10x-media/form-builder 0.1.0-beta.4 → 0.1.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -0
- package/README.md +3 -3
- package/dist/actions/body/serializeBody.d.ts +8 -5
- package/dist/actions/body/serializeBody.js.map +1 -1
- package/dist/actions/body/textOfBody.d.ts +13 -0
- package/dist/actions/body/textOfBody.js +35 -0
- package/dist/actions/body/textOfBody.js.map +1 -0
- package/dist/actions/builtin/confirmation.js +81 -48
- package/dist/actions/builtin/confirmation.js.map +1 -1
- package/dist/actions/builtin/emailTeam.js +67 -38
- package/dist/actions/builtin/emailTeam.js.map +1 -1
- package/dist/actions/builtin/index.d.ts +9 -3
- package/dist/actions/builtin/index.js +8 -5
- package/dist/actions/builtin/index.js.map +1 -1
- package/dist/actions/defineAction.d.ts +1 -1
- package/dist/actions/emailRecipients.d.ts +12 -0
- package/dist/actions/emailRecipients.js +72 -0
- package/dist/actions/emailRecipients.js.map +1 -0
- package/dist/actions/fromAddresses.d.ts +21 -0
- package/dist/actions/fromAddresses.js +74 -0
- package/dist/actions/fromAddresses.js.map +1 -0
- package/dist/actions/task.js +9 -8
- package/dist/actions/task.js.map +1 -1
- package/dist/aggregation/aggregateResponses.d.ts +9 -0
- package/dist/aggregation/aggregateResponses.js +8 -14
- package/dist/aggregation/aggregateResponses.js.map +1 -1
- package/dist/aggregation/resolveResultsRequest.d.ts +19 -6
- package/dist/aggregation/resolveResultsRequest.js +58 -12
- package/dist/aggregation/resolveResultsRequest.js.map +1 -1
- package/dist/calc/computeCalcFields.js +2 -1
- package/dist/calc/computeCalcFields.js.map +1 -1
- package/dist/client/ByteSizeField.d.ts +8 -0
- package/dist/client/ByteSizeField.js +3 -1
- package/dist/client/ByteSizeField.js.map +1 -1
- package/dist/client/ClosePollButton.d.ts +15 -0
- package/dist/client/ClosePollButton.js +80 -0
- package/dist/client/ClosePollButton.js.map +1 -0
- package/dist/client/CondensedArray.d.ts +15 -0
- package/dist/client/CondensedArray.js +97 -0
- package/dist/client/CondensedArray.js.map +1 -0
- package/dist/client/ConsentBlockLabel.d.ts +15 -0
- package/dist/client/ConsentBlockLabel.js +71 -0
- package/dist/client/ConsentBlockLabel.js.map +1 -0
- package/dist/client/ConsentSourceRowLabel.d.ts +9 -0
- package/dist/client/ConsentSourceRowLabel.js +21 -0
- package/dist/client/ConsentSourceRowLabel.js.map +1 -0
- package/dist/client/EndpointOptionsSelect.d.ts +46 -0
- package/dist/client/EndpointOptionsSelect.js +106 -0
- package/dist/client/EndpointOptionsSelect.js.map +1 -0
- package/dist/client/FieldBlockLabel.d.ts +18 -0
- package/dist/client/FieldBlockLabel.js +34 -0
- package/dist/client/FieldBlockLabel.js.map +1 -0
- package/dist/client/FieldNameSelect.d.ts +21 -4
- package/dist/client/FieldNameSelect.js +29 -15
- package/dist/client/FieldNameSelect.js.map +1 -1
- package/dist/client/FlowBuilder.d.ts +2 -1
- package/dist/client/FlowBuilder.js +63 -57
- package/dist/client/FlowBuilder.js.map +1 -1
- package/dist/client/RecipientsSelect.d.ts +31 -0
- package/dist/client/RecipientsSelect.js +174 -0
- package/dist/client/RecipientsSelect.js.map +1 -0
- package/dist/client/RuleDescription.d.ts +21 -0
- package/dist/client/RuleDescription.js +19 -0
- package/dist/client/RuleDescription.js.map +1 -0
- package/dist/client/admin.css +41 -0
- package/dist/client/endpointOptions.js +29 -0
- package/dist/client/endpointOptions.js.map +1 -0
- package/dist/client/flowAuthoring.js +114 -7
- package/dist/client/flowAuthoring.js.map +1 -1
- package/dist/client/synthesizeClientField.js +15 -8
- package/dist/client/synthesizeClientField.js.map +1 -1
- package/dist/collections/buttonFields.d.ts +34 -0
- package/dist/collections/buttonFields.js +35 -0
- package/dist/collections/buttonFields.js.map +1 -0
- package/dist/collections/cells/FieldCountCell.d.ts +15 -0
- package/dist/collections/cells/FieldCountCell.js +18 -0
- package/dist/collections/cells/FieldCountCell.js.map +1 -0
- package/dist/collections/cells/FlowStepsCell.d.ts +14 -0
- package/dist/collections/cells/FlowStepsCell.js +17 -0
- package/dist/collections/cells/FlowStepsCell.js.map +1 -0
- package/dist/collections/formSubmissions.js +23 -17
- package/dist/collections/formSubmissions.js.map +1 -1
- package/dist/collections/forms.js +323 -134
- package/dist/collections/forms.js.map +1 -1
- package/dist/collections/redirectFields.d.ts +29 -0
- package/dist/consent/applyConsentStatements.d.ts +14 -0
- package/dist/consent/applyConsentStatements.js +17 -0
- package/dist/consent/applyConsentStatements.js.map +1 -0
- package/dist/consent/captureConsent.d.ts +31 -11
- package/dist/consent/captureConsent.js +53 -13
- package/dist/consent/captureConsent.js.map +1 -1
- package/dist/consent/consentSourcesField.d.ts +62 -0
- package/dist/consent/consentSourcesField.js +86 -0
- package/dist/consent/consentSourcesField.js.map +1 -0
- package/dist/consent/resolveConsentEntries.d.ts +24 -0
- package/dist/consent/resolveConsentEntries.js +43 -0
- package/dist/consent/resolveConsentEntries.js.map +1 -0
- package/dist/consent/resolveConsentSourcesRequest.d.ts +37 -0
- package/dist/consent/resolveConsentSourcesRequest.js +55 -0
- package/dist/consent/resolveConsentSourcesRequest.js.map +1 -0
- package/dist/consent/resolveConsentStatements.d.ts +45 -0
- package/dist/consent/resolveConsentStatements.js +44 -0
- package/dist/consent/resolveConsentStatements.js.map +1 -0
- package/dist/consent/resolvePublishedVersionRef.d.ts +17 -11
- package/dist/consent/resolvePublishedVersionRef.js +13 -10
- package/dist/consent/resolvePublishedVersionRef.js.map +1 -1
- package/dist/consent/types.d.ts +53 -0
- package/dist/email/departments.d.ts +59 -0
- package/dist/email/departments.js +87 -0
- package/dist/email/departments.js.map +1 -0
- package/dist/email/departmentsField.d.ts +53 -0
- package/dist/email/departmentsField.js +73 -0
- package/dist/email/departmentsField.js.map +1 -0
- package/dist/exports/client.d.ts +11 -1
- package/dist/exports/client.js +11 -1
- package/dist/exports/react.d.ts +8 -3
- package/dist/exports/react.js +6 -2
- package/dist/exports/rsc.d.ts +3 -1
- package/dist/exports/rsc.js +4 -2
- package/dist/exports/types.d.ts +16 -8
- package/dist/fields/buildFieldBlocks.js +28 -13
- package/dist/fields/buildFieldBlocks.js.map +1 -1
- package/dist/fields/builtin/calculation.js +7 -0
- package/dist/fields/builtin/calculation.js.map +1 -1
- package/dist/fields/builtin/checkbox.js +8 -0
- package/dist/fields/builtin/checkbox.js.map +1 -1
- package/dist/fields/builtin/consent.js +32 -21
- package/dist/fields/builtin/consent.js.map +1 -1
- package/dist/fields/builtin/country.d.ts +13 -0
- package/dist/fields/builtin/country.js +30 -0
- package/dist/fields/builtin/country.js.map +1 -0
- package/dist/fields/builtin/date.js +2 -0
- package/dist/fields/builtin/date.js.map +1 -1
- package/dist/fields/builtin/file.js +14 -7
- package/dist/fields/builtin/file.js.map +1 -1
- package/dist/fields/builtin/index.d.ts +8 -6
- package/dist/fields/builtin/index.js +12 -11
- package/dist/fields/builtin/index.js.map +1 -1
- package/dist/fields/builtin/message.js +8 -4
- package/dist/fields/builtin/message.js.map +1 -1
- package/dist/fields/builtin/repeater.js +1 -0
- package/dist/fields/builtin/repeater.js.map +1 -1
- package/dist/fields/builtin/select.js +1 -0
- package/dist/fields/builtin/select.js.map +1 -1
- package/dist/fields/builtin/state.d.ts +13 -0
- package/dist/fields/builtin/state.js +30 -0
- package/dist/fields/builtin/state.js.map +1 -0
- package/dist/fields/data/regions.d.ts +21 -0
- package/dist/fields/data/regions.js +1238 -0
- package/dist/fields/data/regions.js.map +1 -0
- package/dist/fields/fieldKey.d.ts +15 -0
- package/dist/fields/fieldKey.js +16 -0
- package/dist/fields/fieldKey.js.map +1 -0
- package/dist/fields/fieldNamesOfType.js +13 -8
- package/dist/fields/fieldNamesOfType.js.map +1 -1
- package/dist/fields/instanceOptions.js +20 -0
- package/dist/fields/instanceOptions.js.map +1 -0
- package/dist/fields/registry.d.ts +1 -0
- package/dist/fields/registry.js +21 -2
- package/dist/fields/registry.js.map +1 -1
- package/dist/fields/sharedConfig.js +46 -9
- package/dist/fields/sharedConfig.js.map +1 -1
- package/dist/fields/types.d.ts +63 -5
- package/dist/flow/engine.d.ts +6 -4
- package/dist/flow/engine.js +11 -6
- package/dist/flow/engine.js.map +1 -1
- package/dist/flow/normalizeFlow.js +16 -7
- package/dist/flow/normalizeFlow.js.map +1 -1
- package/dist/flow/types.d.ts +12 -3
- package/dist/flow/types.js +11 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/form/pollState.d.ts +4 -4
- package/dist/form/pollState.js.map +1 -1
- package/dist/form/toFormDocument.d.ts +54 -12
- package/dist/form/toFormDocument.js +56 -8
- package/dist/form/toFormDocument.js.map +1 -1
- package/dist/form/types.d.ts +31 -14
- package/dist/index.d.ts +153 -29
- package/dist/index.js +47 -15
- package/dist/index.js.map +1 -1
- package/dist/plugin/customState.js +26 -0
- package/dist/plugin/customState.js.map +1 -0
- package/dist/plugin/registerCollections.js +24 -13
- package/dist/plugin/registerCollections.js.map +1 -1
- package/dist/plugin/uploadsCollection.d.ts +5 -0
- package/dist/plugin/uploadsCollection.js +10 -1
- package/dist/plugin/uploadsCollection.js.map +1 -1
- package/dist/poll/applyPollOptions.js +3 -2
- package/dist/poll/applyPollOptions.js.map +1 -1
- package/dist/poll/buildPollOptionSourceFields.js +2 -5
- package/dist/poll/buildPollOptionSourceFields.js.map +1 -1
- package/dist/poll/closeJob.d.ts +52 -0
- package/dist/poll/closeJob.js +119 -0
- package/dist/poll/closeJob.js.map +1 -0
- package/dist/poll/definePollOptionSource.d.ts +10 -1
- package/dist/poll/definePollOptionSource.js.map +1 -1
- package/dist/poll/definePollType.d.ts +34 -0
- package/dist/poll/definePollType.js +6 -0
- package/dist/poll/definePollType.js.map +1 -0
- package/dist/poll/effectivePollOptions.d.ts +38 -0
- package/dist/poll/effectivePollOptions.js +64 -0
- package/dist/poll/effectivePollOptions.js.map +1 -0
- package/dist/poll/mostVoted.d.ts +21 -0
- package/dist/poll/mostVoted.js +32 -0
- package/dist/poll/mostVoted.js.map +1 -0
- package/dist/poll/outcomeBeforeChange.js +91 -0
- package/dist/poll/outcomeBeforeChange.js.map +1 -0
- package/dist/poll/outcomeFields.d.ts +38 -0
- package/dist/poll/outcomeFields.js +52 -0
- package/dist/poll/outcomeFields.js.map +1 -0
- package/dist/poll/pollTypeRegistry.d.ts +34 -0
- package/dist/poll/pollTypeRegistry.js +71 -0
- package/dist/poll/pollTypeRegistry.js.map +1 -0
- package/dist/poll/resolvePollCloseRequest.js +105 -0
- package/dist/poll/resolvePollCloseRequest.js.map +1 -0
- package/dist/poll/resolvePollOptions.d.ts +2 -1
- package/dist/poll/resolvePollOptions.js +5 -17
- package/dist/poll/resolvePollOptions.js.map +1 -1
- package/dist/poll/resolvePollOptionsRequest.js +51 -0
- package/dist/poll/resolvePollOptionsRequest.js.map +1 -0
- package/dist/poll/resolvePollOutcome.d.ts +22 -9
- package/dist/poll/resolvePollOutcome.js +54 -14
- package/dist/poll/resolvePollOutcome.js.map +1 -1
- package/dist/poll/resultsField.js +21 -0
- package/dist/poll/resultsField.js.map +1 -0
- package/dist/prefill/valuesFromSearchParams.js +2 -1
- package/dist/prefill/valuesFromSearchParams.js.map +1 -1
- package/dist/react/Form.d.ts +8 -8
- package/dist/react/Form.js +74 -62
- package/dist/react/Form.js.map +1 -1
- package/dist/react/FormContext.d.ts +6 -4
- package/dist/react/FormContext.js.map +1 -1
- package/dist/react/FormControls.d.ts +3 -3
- package/dist/react/FormControls.js +3 -3
- package/dist/react/FormControls.js.map +1 -1
- package/dist/react/FormResults.d.ts +5 -5
- package/dist/react/FormResults.js +6 -6
- package/dist/react/FormResults.js.map +1 -1
- package/dist/react/Poll.d.ts +2 -2
- package/dist/react/Poll.js +5 -5
- package/dist/react/Poll.js.map +1 -1
- package/dist/react/contract.d.ts +2 -3
- package/dist/react/contract.js.map +1 -1
- package/dist/react/primitives/Checkbox.d.ts +4 -2
- package/dist/react/primitives/Checkbox.js +2 -1
- package/dist/react/primitives/Checkbox.js.map +1 -1
- package/dist/react/primitives/FieldShell.d.ts +2 -4
- package/dist/react/primitives/FieldShell.js +12 -19
- package/dist/react/primitives/FieldShell.js.map +1 -1
- package/dist/react/renderers/calculation.js +1 -2
- package/dist/react/renderers/calculation.js.map +1 -1
- package/dist/react/renderers/checkbox.js +1 -2
- package/dist/react/renderers/checkbox.js.map +1 -1
- package/dist/react/renderers/consent.js +78 -34
- package/dist/react/renderers/consent.js.map +1 -1
- package/dist/react/renderers/date.js +1 -3
- package/dist/react/renderers/date.js.map +1 -1
- package/dist/react/renderers/email.js +1 -2
- package/dist/react/renderers/email.js.map +1 -1
- package/dist/react/renderers/file.js +1 -2
- package/dist/react/renderers/file.js.map +1 -1
- package/dist/react/renderers/index.js +3 -0
- package/dist/react/renderers/index.js.map +1 -1
- package/dist/react/renderers/number.js +1 -2
- package/dist/react/renderers/number.js.map +1 -1
- package/dist/react/renderers/region.js +45 -0
- package/dist/react/renderers/region.js.map +1 -0
- package/dist/react/renderers/repeater.js +7 -10
- package/dist/react/renderers/repeater.js.map +1 -1
- package/dist/react/renderers/select.js +1 -2
- package/dist/react/renderers/select.js.map +1 -1
- package/dist/react/renderers/text.js +1 -2
- package/dist/react/renderers/text.js.map +1 -1
- package/dist/react/renderers/textarea.js +1 -2
- package/dist/react/renderers/textarea.js.map +1 -1
- package/dist/react/state.d.ts +0 -3
- package/dist/react/state.js +7 -11
- package/dist/react/state.js.map +1 -1
- package/dist/react/useField.d.ts +0 -1
- package/dist/react/useField.js +0 -1
- package/dist/react/useField.js.map +1 -1
- package/dist/react/useFormState.d.ts +1 -1
- package/dist/react/useFormState.js +1 -1
- package/dist/react/useFormState.js.map +1 -1
- package/dist/react/validateField.js +3 -6
- package/dist/react/validateField.js.map +1 -1
- package/dist/recall/interpolate.d.ts +4 -3
- package/dist/recall/interpolate.js +5 -4
- package/dist/recall/interpolate.js.map +1 -1
- package/dist/recall/resolver.d.ts +1 -1
- package/dist/recall/resolver.js +14 -2
- package/dist/recall/resolver.js.map +1 -1
- package/dist/spam/captcha.d.ts +1 -1
- package/dist/spam/captcha.js +1 -1
- package/dist/spam/captcha.js.map +1 -1
- package/dist/submissions/SubmissionAnswers.js +6 -2
- package/dist/submissions/SubmissionAnswers.js.map +1 -1
- package/dist/submissions/SubmissionAnswersClient.js +100 -64
- package/dist/submissions/SubmissionAnswersClient.js.map +1 -1
- package/dist/submissions/createSubmission.d.ts +36 -0
- package/dist/submissions/createSubmission.js +26 -0
- package/dist/submissions/createSubmission.js.map +1 -0
- package/dist/submissions/runSubmission.d.ts +10 -0
- package/dist/submissions/runSubmission.js +31 -19
- package/dist/submissions/runSubmission.js.map +1 -1
- package/dist/submissions/types.d.ts +11 -4
- package/dist/submissions/validateSubmission.js +39 -23
- package/dist/submissions/validateSubmission.js.map +1 -1
- package/dist/submissions/votedCookie.js +3 -3
- package/dist/submissions/votedCookie.js.map +1 -1
- package/dist/translations/de.js +104 -26
- package/dist/translations/de.js.map +1 -1
- package/dist/translations/en.js +105 -27
- package/dist/translations/en.js.map +1 -1
- package/dist/translations/keys.d.ts +99 -21
- package/dist/translations/keys.js +100 -22
- package/dist/translations/keys.js.map +1 -1
- package/dist/uploads/resolveFileRef.js +2 -1
- package/dist/uploads/resolveFileRef.js.map +1 -1
- package/dist/validation/buildRuleBlocks.js +18 -17
- package/dist/validation/buildRuleBlocks.js.map +1 -1
- package/dist/validation/builtin/email.js +1 -0
- package/dist/validation/builtin/email.js.map +1 -1
- package/dist/validation/builtin/matchesField.js +3 -7
- package/dist/validation/builtin/matchesField.js.map +1 -1
- package/dist/validation/builtin/max.js +1 -0
- package/dist/validation/builtin/max.js.map +1 -1
- package/dist/validation/builtin/maxDate.js +1 -0
- package/dist/validation/builtin/maxDate.js.map +1 -1
- package/dist/validation/builtin/maxLength.js +1 -0
- package/dist/validation/builtin/maxLength.js.map +1 -1
- package/dist/validation/builtin/min.js +1 -0
- package/dist/validation/builtin/min.js.map +1 -1
- package/dist/validation/builtin/minDate.js +1 -0
- package/dist/validation/builtin/minDate.js.map +1 -1
- package/dist/validation/builtin/minLength.js +1 -0
- package/dist/validation/builtin/minLength.js.map +1 -1
- package/dist/validation/builtin/notAlreadySubmitted.js +1 -0
- package/dist/validation/builtin/notAlreadySubmitted.js.map +1 -1
- package/dist/validation/builtin/oneOf.js +1 -0
- package/dist/validation/builtin/oneOf.js.map +1 -1
- package/dist/validation/builtin/pattern.js +11 -2
- package/dist/validation/builtin/pattern.js.map +1 -1
- package/dist/validation/builtin/url.js +1 -0
- package/dist/validation/builtin/url.js.map +1 -1
- package/dist/validation/builtin/validateRegexParams.js +44 -0
- package/dist/validation/builtin/validateRegexParams.js.map +1 -0
- package/dist/validation/fieldTargetParam.d.ts +22 -0
- package/dist/validation/fieldTargetParam.js +38 -0
- package/dist/validation/fieldTargetParam.js.map +1 -0
- package/dist/validation/runValidation.js +8 -29
- package/dist/validation/runValidation.js.map +1 -1
- package/dist/validation/types.d.ts +5 -11
- package/package.json +6 -6
- package/dist/consent/buildConsentSourceConfig.js +0 -49
- package/dist/consent/buildConsentSourceConfig.js.map +0 -1
- package/dist/consent/builtin/index.d.ts +0 -17
- package/dist/consent/builtin/index.js +0 -21
- package/dist/consent/builtin/index.js.map +0 -1
- package/dist/consent/builtin/pageReference.js +0 -75
- package/dist/consent/builtin/pageReference.js.map +0 -1
- package/dist/consent/builtin/static.js +0 -48
- package/dist/consent/builtin/static.js.map +0 -1
- package/dist/consent/defineConsentSource.d.ts +0 -35
- package/dist/consent/defineConsentSource.js +0 -6
- package/dist/consent/defineConsentSource.js.map +0 -1
- package/dist/consent/registry.d.ts +0 -16
- package/dist/consent/registry.js +0 -16
- package/dist/consent/registry.js.map +0 -1
- package/dist/consent/resolveConsentLinks.d.ts +0 -19
- package/dist/consent/resolveConsentLinks.js +0 -26
- package/dist/consent/resolveConsentLinks.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { localizedIf } from "../fields/localizedIf.js";
|
|
2
|
+
import { keys } from "../translations/keys.js";
|
|
3
|
+
import { labelForKey } from "../translations/server.js";
|
|
4
|
+
//#region src/collections/buttonFields.ts
|
|
5
|
+
/** The default submit button label field (`buttons.submitLabel`), localized when `localize` is true. */
|
|
6
|
+
const buildSubmitLabelField = (localize) => ({
|
|
7
|
+
name: "submitLabel",
|
|
8
|
+
type: "text",
|
|
9
|
+
label: labelForKey(keys.buttonsSubmitLabel),
|
|
10
|
+
...localizedIf(localize)
|
|
11
|
+
});
|
|
12
|
+
/** The default "Next" button label field (`buttons.nextLabel`); applies to multi-step forms. */
|
|
13
|
+
const buildNextLabelField = (localize) => ({
|
|
14
|
+
name: "nextLabel",
|
|
15
|
+
type: "text",
|
|
16
|
+
label: labelForKey(keys.buttonsNextLabel),
|
|
17
|
+
...localizedIf(localize)
|
|
18
|
+
});
|
|
19
|
+
/** The default "Previous" button label field (`buttons.prevLabel`); applies to multi-step forms. */
|
|
20
|
+
const buildPrevLabelField = (localize) => ({
|
|
21
|
+
name: "prevLabel",
|
|
22
|
+
type: "text",
|
|
23
|
+
label: labelForKey(keys.buttonsPrevLabel),
|
|
24
|
+
...localizedIf(localize)
|
|
25
|
+
});
|
|
26
|
+
/** All three defaults with the localization flag applied: exactly what the seam is handed. */
|
|
27
|
+
const buildDefaultButtonFields = (localize) => ({
|
|
28
|
+
submit: buildSubmitLabelField(localize),
|
|
29
|
+
prev: buildPrevLabelField(localize),
|
|
30
|
+
next: buildNextLabelField(localize)
|
|
31
|
+
});
|
|
32
|
+
//#endregion
|
|
33
|
+
export { buildDefaultButtonFields, buildNextLabelField, buildPrevLabelField, buildSubmitLabelField };
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=buttonFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buttonFields.js","names":[],"sources":["../../src/collections/buttonFields.ts"],"sourcesContent":["import type { Field } from 'payload'\nimport { localizedIf } from '../fields/localizedIf'\nimport { keys } from '../translations/keys'\nimport { labelForKey } from '../translations/server'\n\n/** The default button-label fields, keyed by button. What the `buttons.fields` seam receives. */\nexport type DefaultButtonFields = {\n\tsubmit: Field\n\tprev: Field\n\tnext: Field\n}\n\n/**\n * Composes the three form-level button fields. Receives the defaults with the content localization\n * flag already applied and returns the field for each slot; the collection places `submit` at the\n * bottom of the Fields tab and `prev`/`next` in a row on the Flow tab. Any slot may return the\n * default, a replacement, or the default wrapped in a `row` alongside a host field (e.g. an icon\n * select), so adjacent fields ride along in the same slot.\n */\nexport type ButtonFieldsOverride = (args: {\n\tdefaultFields: DefaultButtonFields\n}) => DefaultButtonFields\n\n/** The plugin `buttons` option: form-level button labels and the group's composition seam. */\nexport type ButtonsOption = {\n\tfields?: ButtonFieldsOverride\n}\n\n/** The default submit button label field (`buttons.submitLabel`), localized when `localize` is true. */\nexport const buildSubmitLabelField = (localize: boolean): Field => ({\n\tname: 'submitLabel',\n\ttype: 'text',\n\tlabel: labelForKey(keys.buttonsSubmitLabel),\n\t...localizedIf(localize),\n})\n\n/** The default \"Next\" button label field (`buttons.nextLabel`); applies to multi-step forms. */\nexport const buildNextLabelField = (localize: boolean): Field => ({\n\tname: 'nextLabel',\n\ttype: 'text',\n\tlabel: labelForKey(keys.buttonsNextLabel),\n\t...localizedIf(localize),\n})\n\n/** The default \"Previous\" button label field (`buttons.prevLabel`); applies to multi-step forms. */\nexport const buildPrevLabelField = (localize: boolean): Field => ({\n\tname: 'prevLabel',\n\ttype: 'text',\n\tlabel: labelForKey(keys.buttonsPrevLabel),\n\t...localizedIf(localize),\n})\n\n/** All three defaults with the localization flag applied: exactly what the seam is handed. */\nexport const buildDefaultButtonFields = (localize: boolean): DefaultButtonFields => ({\n\tsubmit: buildSubmitLabelField(localize),\n\tprev: buildPrevLabelField(localize),\n\tnext: buildNextLabelField(localize),\n})\n"],"mappings":";;;;;AA6BA,MAAa,yBAAyB,cAA8B;CACnE,MAAM;CACN,MAAM;CACN,OAAO,YAAY,KAAK,kBAAkB;CAC1C,GAAG,YAAY,QAAQ;AACxB;;AAGA,MAAa,uBAAuB,cAA8B;CACjE,MAAM;CACN,MAAM;CACN,OAAO,YAAY,KAAK,gBAAgB;CACxC,GAAG,YAAY,QAAQ;AACxB;;AAGA,MAAa,uBAAuB,cAA8B;CACjE,MAAM;CACN,MAAM;CACN,OAAO,YAAY,KAAK,gBAAgB;CACxC,GAAG,YAAY,QAAQ;AACxB;;AAGA,MAAa,4BAA4B,cAA4C;CACpF,QAAQ,sBAAsB,QAAQ;CACtC,MAAM,oBAAoB,QAAQ;CAClC,MAAM,oBAAoB,QAAQ;AACnC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/collections/cells/FieldCountCell.d.ts
|
|
2
|
+
/** The subset of Payload's `DefaultCellComponentProps` this cell reads: the raw `fields` blocks array. */
|
|
3
|
+
type FieldCountCellProps = {
|
|
4
|
+
cellData?: unknown[] | null;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* List-view cell for the `fields` blocks field: a localized field count instead of Payload's
|
|
8
|
+
* default "N Fields - Text, Email, ..." block-type summary.
|
|
9
|
+
*/
|
|
10
|
+
declare const FieldCountCell: ({
|
|
11
|
+
cellData
|
|
12
|
+
}: FieldCountCellProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { FieldCountCell };
|
|
15
|
+
//# sourceMappingURL=FieldCountCell.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { keys } from "../../translations/keys.js";
|
|
3
|
+
import { useTranslation } from "../../translations/useTranslation.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/collections/cells/FieldCountCell.tsx
|
|
6
|
+
/**
|
|
7
|
+
* List-view cell for the `fields` blocks field: a localized field count instead of Payload's
|
|
8
|
+
* default "N Fields - Text, Email, ..." block-type summary.
|
|
9
|
+
*/
|
|
10
|
+
const FieldCountCell = ({ cellData }) => {
|
|
11
|
+
const { t } = useTranslation();
|
|
12
|
+
const count = Array.isArray(cellData) ? cellData.length : 0;
|
|
13
|
+
return /* @__PURE__ */ jsx("span", { children: t(count === 1 ? keys.cellFieldCountOne : keys.cellFieldCountOther, { count }) });
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { FieldCountCell };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=FieldCountCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FieldCountCell.js","names":[],"sources":["../../../src/collections/cells/FieldCountCell.tsx"],"sourcesContent":["'use client'\n\nimport { keys } from '../../translations/keys'\nimport { useTranslation } from '../../translations/useTranslation'\n\n/** The subset of Payload's `DefaultCellComponentProps` this cell reads: the raw `fields` blocks array. */\ntype FieldCountCellProps = {\n\tcellData?: unknown[] | null\n}\n\n/**\n * List-view cell for the `fields` blocks field: a localized field count instead of Payload's\n * default \"N Fields - Text, Email, ...\" block-type summary.\n */\nexport const FieldCountCell = ({ cellData }: FieldCountCellProps) => {\n\tconst { t } = useTranslation()\n\tconst count = Array.isArray(cellData) ? cellData.length : 0\n\treturn (\n\t\t<span>{t(count === 1 ? keys.cellFieldCountOne : keys.cellFieldCountOther, { count })}</span>\n\t)\n}\n"],"mappings":";;;;;;;;;AAcA,MAAa,kBAAkB,EAAE,eAAoC;CACpE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,QAAQ,MAAM,QAAQ,QAAQ,IAAI,SAAS,SAAS;CAC1D,OACC,oBAAC,QAAD,EAAA,UAAO,EAAE,UAAU,IAAI,KAAK,oBAAoB,KAAK,qBAAqB,EAAE,MAAM,CAAC,EAAQ,CAAA;AAE7F"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/collections/cells/FlowStepsCell.d.ts
|
|
2
|
+
/** The subset of Payload's `DefaultCellComponentProps` this cell reads: the raw `flow` json value. */
|
|
3
|
+
type FlowStepsCellProps = {
|
|
4
|
+
cellData?: {
|
|
5
|
+
steps?: unknown[];
|
|
6
|
+
} | null;
|
|
7
|
+
};
|
|
8
|
+
/** List-view cell for the `flow` json field: a localized step count instead of raw JSON. */
|
|
9
|
+
declare const FlowStepsCell: ({
|
|
10
|
+
cellData
|
|
11
|
+
}: FlowStepsCellProps) => import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//#endregion
|
|
13
|
+
export { FlowStepsCell };
|
|
14
|
+
//# sourceMappingURL=FlowStepsCell.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { keys } from "../../translations/keys.js";
|
|
3
|
+
import { useTranslation } from "../../translations/useTranslation.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/collections/cells/FlowStepsCell.tsx
|
|
6
|
+
const stepCountOf = (cellData) => Array.isArray(cellData?.steps) ? cellData.steps.length : 0;
|
|
7
|
+
/** List-view cell for the `flow` json field: a localized step count instead of raw JSON. */
|
|
8
|
+
const FlowStepsCell = ({ cellData }) => {
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
const count = stepCountOf(cellData);
|
|
11
|
+
if (count === 0) return /* @__PURE__ */ jsx("span", { children: "—" });
|
|
12
|
+
return /* @__PURE__ */ jsx("span", { children: t(count === 1 ? keys.cellStepCountOne : keys.cellStepCountOther, { count }) });
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { FlowStepsCell };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=FlowStepsCell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FlowStepsCell.js","names":[],"sources":["../../../src/collections/cells/FlowStepsCell.tsx"],"sourcesContent":["'use client'\n\nimport { keys } from '../../translations/keys'\nimport { useTranslation } from '../../translations/useTranslation'\n\n/** The subset of Payload's `DefaultCellComponentProps` this cell reads: the raw `flow` json value. */\ntype FlowStepsCellProps = {\n\tcellData?: { steps?: unknown[] } | null\n}\n\nconst stepCountOf = (cellData: FlowStepsCellProps['cellData']): number =>\n\tArray.isArray(cellData?.steps) ? cellData.steps.length : 0\n\n/** List-view cell for the `flow` json field: a localized step count instead of raw JSON. */\nexport const FlowStepsCell = ({ cellData }: FlowStepsCellProps) => {\n\tconst { t } = useTranslation()\n\tconst count = stepCountOf(cellData)\n\tif (count === 0) {\n\t\treturn <span>—</span>\n\t}\n\treturn <span>{t(count === 1 ? keys.cellStepCountOne : keys.cellStepCountOther, { count })}</span>\n}\n"],"mappings":";;;;;AAUA,MAAM,eAAe,aACpB,MAAM,QAAQ,UAAU,KAAK,IAAI,SAAS,MAAM,SAAS;;AAG1D,MAAa,iBAAiB,EAAE,eAAmC;CAClE,MAAM,EAAE,MAAM,eAAe;CAC7B,MAAM,QAAQ,YAAY,QAAQ;CAClC,IAAI,UAAU,GACb,OAAO,oBAAC,QAAD,EAAA,UAAM,IAAO,CAAA;CAErB,OAAO,oBAAC,QAAD,EAAA,UAAO,EAAE,UAAU,IAAI,KAAK,mBAAmB,KAAK,oBAAoB,EAAE,MAAM,CAAC,EAAQ,CAAA;AACjG"}
|
|
@@ -2,7 +2,6 @@ import { keys } from "../translations/keys.js";
|
|
|
2
2
|
import { labelForKey } from "../translations/server.js";
|
|
3
3
|
import { dispatchActions } from "../actions/dispatch.js";
|
|
4
4
|
import { resolveEventSink } from "../events/resolveEventSink.js";
|
|
5
|
-
import { pollConfigOf } from "../form/pollState.js";
|
|
6
5
|
import { isLoggedIn } from "../plugin/access.js";
|
|
7
6
|
import { buildSpamGuard } from "../spam/spamGuard.js";
|
|
8
7
|
import { FORMS_SLUG } from "./forms.js";
|
|
@@ -76,24 +75,21 @@ const makeVotedCookieHook = () => {
|
|
|
76
75
|
const formId = formIdOf(doc.form);
|
|
77
76
|
if (formId == null) return doc;
|
|
78
77
|
const stashed = req.context?.[POLL_CONTEXT_KEY];
|
|
79
|
-
let
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
poll = form ? pollConfigOf(form.poll) : void 0;
|
|
89
|
-
}
|
|
90
|
-
if (poll?.enabled !== true) return doc;
|
|
78
|
+
let pollEnabled = typeof stashed === "boolean" ? stashed : void 0;
|
|
79
|
+
if (pollEnabled === void 0) pollEnabled = (await req.payload.findByID({
|
|
80
|
+
collection: FORMS_SLUG,
|
|
81
|
+
id: formId,
|
|
82
|
+
depth: 0,
|
|
83
|
+
overrideAccess: true,
|
|
84
|
+
req
|
|
85
|
+
}).catch(() => null))?.pollEnabled === true;
|
|
86
|
+
if (!pollEnabled) return doc;
|
|
91
87
|
req.responseHeaders ??= new Headers();
|
|
92
88
|
req.responseHeaders.append("Set-Cookie", `${votedCookieName(formId)}=1; Path=/; Max-Age=31536000; HttpOnly; SameSite=Lax`);
|
|
93
89
|
return doc;
|
|
94
90
|
};
|
|
95
91
|
};
|
|
96
|
-
const buildSubmissionsCollection = ({ registry, ruleRegistry,
|
|
92
|
+
const buildSubmissionsCollection = ({ registry, ruleRegistry, consentSources, consentSnapshot, actionRegistry = /* @__PURE__ */ new Map(), events, hasRunner = false, richText, uploadSlug, spam, votedCookie = false, pollSourceRegistry, showRawFields = false, overrides }) => {
|
|
97
93
|
const defaultFields = [
|
|
98
94
|
{
|
|
99
95
|
name: "form",
|
|
@@ -112,6 +108,7 @@ const buildSubmissionsCollection = ({ registry, ruleRegistry, consentRegistry, a
|
|
|
112
108
|
label: labelForKey(keys.statusPartial),
|
|
113
109
|
value: "partial"
|
|
114
110
|
}],
|
|
111
|
+
admin: { isClearable: false },
|
|
115
112
|
access: {
|
|
116
113
|
create: isLoggedIn,
|
|
117
114
|
update: isLoggedIn
|
|
@@ -124,7 +121,8 @@ const buildSubmissionsCollection = ({ registry, ruleRegistry, consentRegistry, a
|
|
|
124
121
|
},
|
|
125
122
|
{
|
|
126
123
|
name: "locale",
|
|
127
|
-
type: "text"
|
|
124
|
+
type: "text",
|
|
125
|
+
admin: { hidden: !showRawFields }
|
|
128
126
|
},
|
|
129
127
|
{
|
|
130
128
|
name: "values",
|
|
@@ -143,7 +141,8 @@ const buildSubmissionsCollection = ({ registry, ruleRegistry, consentRegistry, a
|
|
|
143
141
|
},
|
|
144
142
|
{
|
|
145
143
|
name: "meta",
|
|
146
|
-
type: "json"
|
|
144
|
+
type: "json",
|
|
145
|
+
admin: { hidden: !showRawFields }
|
|
147
146
|
}
|
|
148
147
|
];
|
|
149
148
|
return {
|
|
@@ -156,6 +155,12 @@ const buildSubmissionsCollection = ({ registry, ruleRegistry, consentRegistry, a
|
|
|
156
155
|
},
|
|
157
156
|
admin: {
|
|
158
157
|
group: "Forms",
|
|
158
|
+
defaultColumns: [
|
|
159
|
+
"form",
|
|
160
|
+
"status",
|
|
161
|
+
"locale",
|
|
162
|
+
"createdAt"
|
|
163
|
+
],
|
|
159
164
|
...overrides?.admin ?? {}
|
|
160
165
|
},
|
|
161
166
|
access: {
|
|
@@ -171,7 +176,8 @@ const buildSubmissionsCollection = ({ registry, ruleRegistry, consentRegistry, a
|
|
|
171
176
|
validateSubmission({
|
|
172
177
|
registry,
|
|
173
178
|
ruleRegistry,
|
|
174
|
-
|
|
179
|
+
consentSources,
|
|
180
|
+
consentSnapshot,
|
|
175
181
|
uploadSlug,
|
|
176
182
|
pollSourceRegistry
|
|
177
183
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formSubmissions.js","names":[],"sources":["../../src/collections/formSubmissions.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, Field } from 'payload'\nimport type { RichTextBodyOption } from '../actions/body/serializeBody'\nimport { dispatchActions } from '../actions/dispatch'\nimport type { ActionRegistry } from '../actions/registry'\nimport type { ActionInstance } from '../actions/runActions'\nimport type { ConsentSourceRegistry } from '../consent/registry'\nimport { resolveEventSink } from '../events/resolveEventSink'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport { pollConfigOf } from '../form/pollState'\nimport { isLoggedIn } from '../plugin/access'\nimport type { CollectionOverrides } from '../plugin/collectionOverrides'\nimport type { PollOptionSourceRegistry } from '../poll/registry'\nimport { buildSpamGuard } from '../spam/spamGuard'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { validateSubmission } from '../submissions/validateSubmission'\nimport { POLL_CONTEXT_KEY, votedCookieName } from '../submissions/votedCookie'\nimport { keys } from '../translations/keys'\nimport { labelForKey } from '../translations/server'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { FORMS_SLUG } from './forms'\n\nexport const FORM_SUBMISSIONS_SLUG = 'form-submissions'\n\ntype BuildSubmissionsCollectionArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\tconsentRegistry: ConsentSourceRegistry\n\tactionRegistry?: ActionRegistry\n\tevents?: FormEventSink\n\t/** Whether a job runner is likely present; gates the queued vs bounded-inline dispatch path. */\n\thasRunner?: boolean\n\t/** Body serialization customization forwarded to the inline action dispatch path. */\n\trichText?: RichTextBodyOption\n\t/** The plugin-configured uploads collection slug; absent when uploads are disabled. */\n\tuploadSlug?: string\n\t/** Resolved spam config; when active, prepends the spam guard before validation. `false` disables it. */\n\tspam?: ResolvedSpamConfig | false\n\t/** Opt-in (`poll.votedCookie`): set an httpOnly `fb-voted-{formId}` cookie on poll submission creates. */\n\tvotedCookie?: boolean\n\t/** Registered poll option sources; submission validation resolves allowed values through them. */\n\tpollSourceRegistry?: PollOptionSourceRegistry\n\t/**\n\t * When `true`, shows the raw `values`, `descriptors`, and `consent` JSON fields in the admin UI.\n\t * Default `false` — they are fully represented by the `SubmissionAnswers` UI component.\n\t */\n\tshowRawFields?: boolean\n\toverrides?: CollectionOverrides\n}\n\nconst formIdOf = (form: unknown): number | string | undefined => {\n\tif (typeof form === 'number' || typeof form === 'string') {\n\t\treturn form\n\t}\n\tif (form && typeof form === 'object' && 'id' in form) {\n\t\tconst id = (form as { id: unknown }).id\n\t\tif (typeof id === 'number' || typeof id === 'string') {\n\t\t\treturn id\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * On a completed submission create, dispatch the form's post-submit actions and emit `submission.created`.\n * Both are side effects on an already-written row, so the whole body is wrapped: nothing it does can throw\n * past the hook (a failed action or sink must never fail the submission write). Dispatch is itself bounded\n * and non-throwing; the inline fallback is awaited so the bound caps the added latency, while the queued\n * path returns immediately. The form's `actions` are null-guarded for legacy rows created before the field\n * existed.\n */\nconst makeAfterChange =\n\t(args: {\n\t\tactionRegistry: ActionRegistry\n\t\tevents?: FormEventSink\n\t\thasRunner: boolean\n\t\trichText?: RichTextBodyOption\n\t}): CollectionAfterChangeHook =>\n\tasync ({ doc, operation, req }) => {\n\t\tif (operation !== 'create' || (doc.status != null && doc.status !== 'complete')) {\n\t\t\treturn doc\n\t\t}\n\t\tconst { payload } = req\n\t\ttry {\n\t\t\tconst formId = formIdOf(doc.form)\n\t\t\tif (formId == null) {\n\t\t\t\treturn doc\n\t\t\t}\n\t\t\tconst form = await payload\n\t\t\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t\t\t.catch(() => null)\n\n\t\t\tawait dispatchActions({\n\t\t\t\tactions: (form?.actions ?? null) as ActionInstance[] | null,\n\t\t\t\tformId,\n\t\t\t\tsubmissionId: doc.id as number | string,\n\t\t\t\tregistry: args.actionRegistry,\n\t\t\t\tpayload,\n\t\t\t\treq,\n\t\t\t\thasRunner: args.hasRunner,\n\t\t\t\trichText: args.richText,\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\tawait resolveEventSink(args.events).emit({\n\t\t\t\t\ttype: 'submission.created',\n\t\t\t\t\tformId: String(formId),\n\t\t\t\t\tsubmissionId: String(doc.id),\n\t\t\t\t\tat: new Date().toISOString(),\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tpayload.logger?.error(\n\t\t\t\t\t`@10x-media/form-builder: submission.created sink threw: ${\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t\t}`\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tpayload.logger?.error(\n\t\t\t\t`@10x-media/form-builder: afterChange dispatch failed for submission ${String(doc.id)}: ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`\n\t\t\t)\n\t\t}\n\t\treturn doc\n\t}\n\n/**\n * Opt-in (`poll.votedCookie`) hook: after a submission to a poll-enabled form is created, appends\n * an httpOnly `fb-voted-{formId}=1` cookie via `req.responseHeaders`, Payload's supported channel\n * for hook-set response headers (its own auth strategies use it; `handleEndpoints` merges it into\n * every REST response). Reads the poll config `validateSubmission` stashed on `req.context`,\n * falling back to a form fetch when absent. httpOnly keeps the marker readable only server-side\n * (`hasVotedCookie`); the client `<Poll>` keeps its localStorage guard.\n */\nconst makeVotedCookieHook = (): CollectionAfterChangeHook => {\n\treturn async ({ doc, operation, req }) => {\n\t\tif (operation !== 'create') {\n\t\t\treturn doc\n\t\t}\n\t\tconst formId = formIdOf(doc.form)\n\t\tif (formId == null) {\n\t\t\treturn doc\n\t\t}\n\t\tconst stashed = req.context?.[POLL_CONTEXT_KEY]\n\t\tlet poll = pollConfigOf(stashed)\n\t\tif (stashed === undefined) {\n\t\t\tconst form = await req.payload\n\t\t\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t\t\t.catch(() => null)\n\t\t\tpoll = form ? pollConfigOf(form.poll) : undefined\n\t\t}\n\t\tif (poll?.enabled !== true) {\n\t\t\treturn doc\n\t\t}\n\t\treq.responseHeaders ??= new Headers()\n\t\treq.responseHeaders.append(\n\t\t\t'Set-Cookie',\n\t\t\t`${votedCookieName(formId)}=1; Path=/; Max-Age=31536000; HttpOnly; SameSite=Lax`\n\t\t)\n\t\treturn doc\n\t}\n}\n\nexport const buildSubmissionsCollection = ({\n\tregistry,\n\truleRegistry,\n\tconsentRegistry,\n\tactionRegistry = new Map(),\n\tevents,\n\thasRunner = false,\n\trichText,\n\tuploadSlug,\n\tspam,\n\tvotedCookie = false,\n\tpollSourceRegistry,\n\tshowRawFields = false,\n\toverrides,\n}: BuildSubmissionsCollectionArgs): CollectionConfig => {\n\tconst defaultFields: Field[] = [\n\t\t{ name: 'form', type: 'relationship', relationTo: FORMS_SLUG, required: true },\n\t\t{\n\t\t\tname: 'status',\n\t\t\ttype: 'select',\n\t\t\tdefaultValue: 'complete',\n\t\t\toptions: [\n\t\t\t\t{ label: labelForKey(keys.statusComplete), value: 'complete' },\n\t\t\t\t{ label: labelForKey(keys.statusPartial), value: 'partial' },\n\t\t\t],\n\t\t\t// Defense-in-depth at the REST layer: anonymous clients cannot set status via the API.\n\t\t\t// The validateSubmission hook also forces 'complete' server-side, so this covers both paths.\n\t\t\taccess: { create: isLoggedIn, update: isLoggedIn },\n\t\t},\n\t\t// answers UI appears first so it is the dominant view when opening a submission document.\n\t\t{\n\t\t\tname: 'answers',\n\t\t\ttype: 'ui',\n\t\t\tadmin: {\n\t\t\t\tcomponents: { Field: '@10x-media/form-builder/rsc#SubmissionAnswers' },\n\t\t\t},\n\t\t},\n\t\t{ name: 'locale', type: 'text' },\n\t\t{ name: 'values', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'descriptors', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'consent', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'meta', type: 'json' },\n\t]\n\n\treturn {\n\t\t...(overrides ?? {}),\n\t\tslug: FORM_SUBMISSIONS_SLUG,\n\t\tlabels: {\n\t\t\tsingular: labelForKey(keys.collectionSubmissionSingular),\n\t\t\tplural: labelForKey(keys.collectionSubmissionPlural),\n\t\t\t...(overrides?.labels ?? {}),\n\t\t},\n\t\tadmin: { group: 'Forms', ...(overrides?.admin ?? {}) },\n\t\taccess: {\n\t\t\tcreate: () => true,\n\t\t\tread: isLoggedIn,\n\t\t\tupdate: () => false,\n\t\t\t...(overrides?.access ?? {}),\n\t\t},\n\t\thooks: {\n\t\t\t...(overrides?.hooks ?? {}),\n\t\t\t// Spam guard + validateSubmission must remain first: they enforce the security invariant\n\t\t\t// that anonymous callers cannot bypass post-submit actions or supply a forged status.\n\t\t\t// Consumer beforeValidate hooks are appended after so they run on already-validated data.\n\t\t\tbeforeValidate: [\n\t\t\t\t...(spam ? [buildSpamGuard(spam)] : []),\n\t\t\t\tvalidateSubmission({\n\t\t\t\t\tregistry,\n\t\t\t\t\truleRegistry,\n\t\t\t\t\tconsentRegistry,\n\t\t\t\t\tuploadSlug,\n\t\t\t\t\tpollSourceRegistry,\n\t\t\t\t}),\n\t\t\t\t...(overrides?.hooks?.beforeValidate ?? []),\n\t\t\t],\n\t\t\tafterChange: [\n\t\t\t\tmakeAfterChange({ actionRegistry, events, hasRunner, richText }),\n\t\t\t\t...(votedCookie ? [makeVotedCookieHook()] : []),\n\t\t\t\t...(overrides?.hooks?.afterChange ?? []),\n\t\t\t],\n\t\t},\n\t\tfields: overrides?.fields ? overrides.fields({ defaultFields }) : defaultFields,\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"formSubmissions.js","names":[],"sources":["../../src/collections/formSubmissions.ts"],"sourcesContent":["import type { CollectionAfterChangeHook, CollectionConfig, Field } from 'payload'\nimport type { RichTextBodyOption } from '../actions/body/serializeBody'\nimport { dispatchActions } from '../actions/dispatch'\nimport type { ActionRegistry } from '../actions/registry'\nimport type { ActionInstance } from '../actions/runActions'\nimport type { ConsentSnapshotMode } from '../consent/captureConsent'\nimport type { ConsentSourcesResolver } from '../consent/types'\nimport { resolveEventSink } from '../events/resolveEventSink'\nimport type { FormEventSink } from '../events/types'\nimport type { FieldTypeRegistry } from '../fields/registry'\nimport { isLoggedIn } from '../plugin/access'\nimport type { CollectionOverrides } from '../plugin/collectionOverrides'\nimport type { PollOptionSourceRegistry } from '../poll/registry'\nimport { buildSpamGuard } from '../spam/spamGuard'\nimport type { ResolvedSpamConfig } from '../spam/types'\nimport { validateSubmission } from '../submissions/validateSubmission'\nimport { POLL_CONTEXT_KEY, votedCookieName } from '../submissions/votedCookie'\nimport { keys } from '../translations/keys'\nimport { labelForKey } from '../translations/server'\nimport type { ValidationRuleRegistry } from '../validation/registry'\nimport { FORMS_SLUG } from './forms'\n\nexport const FORM_SUBMISSIONS_SLUG = 'form-submissions'\n\ntype BuildSubmissionsCollectionArgs = {\n\tregistry: FieldTypeRegistry\n\truleRegistry: ValidationRuleRegistry\n\t/** The host's consent sources resolver (plugin option `consent.sources`); absent when no sources are configured. */\n\tconsentSources?: ConsentSourcesResolver\n\t/** What each consent proof snapshots of the agreed wording (plugin option `consent.snapshot`). */\n\tconsentSnapshot?: ConsentSnapshotMode\n\tactionRegistry?: ActionRegistry\n\tevents?: FormEventSink\n\t/** Whether a job runner is likely present; gates the queued vs bounded-inline dispatch path. */\n\thasRunner?: boolean\n\t/** Body serialization customization forwarded to the inline action dispatch path. */\n\trichText?: RichTextBodyOption\n\t/** The plugin-configured uploads collection slug; absent when uploads are disabled. */\n\tuploadSlug?: string\n\t/** Resolved spam config; when active, prepends the spam guard before validation. `false` disables it. */\n\tspam?: ResolvedSpamConfig | false\n\t/** Opt-in (`poll.votedCookie`): set an httpOnly `fb-voted-{formId}` cookie on poll submission creates. */\n\tvotedCookie?: boolean\n\t/** Registered poll option sources; submission validation resolves allowed values through them. */\n\tpollSourceRegistry?: PollOptionSourceRegistry\n\t/**\n\t * When `true`, reveals the standalone `locale`, `values`, `descriptors`, `consent`, and `meta`\n\t * fields in the admin UI. Default `false`, because the `SubmissionAnswers` UI component already\n\t * represents them fully (locale and meta are folded into its Submission-details section).\n\t */\n\tshowRawFields?: boolean\n\toverrides?: CollectionOverrides\n}\n\nconst formIdOf = (form: unknown): number | string | undefined => {\n\tif (typeof form === 'number' || typeof form === 'string') {\n\t\treturn form\n\t}\n\tif (form && typeof form === 'object' && 'id' in form) {\n\t\tconst id = (form as { id: unknown }).id\n\t\tif (typeof id === 'number' || typeof id === 'string') {\n\t\t\treturn id\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * On a completed submission create, dispatch the form's post-submit actions and emit `submission.created`.\n * Both are side effects on an already-written row, so the whole body is wrapped: nothing it does can throw\n * past the hook (a failed action or sink must never fail the submission write). Dispatch is itself bounded\n * and non-throwing; the inline fallback is awaited so the bound caps the added latency, while the queued\n * path returns immediately. The form's `actions` are null-guarded for legacy rows created before the field\n * existed.\n */\nconst makeAfterChange =\n\t(args: {\n\t\tactionRegistry: ActionRegistry\n\t\tevents?: FormEventSink\n\t\thasRunner: boolean\n\t\trichText?: RichTextBodyOption\n\t}): CollectionAfterChangeHook =>\n\tasync ({ doc, operation, req }) => {\n\t\tif (operation !== 'create' || (doc.status != null && doc.status !== 'complete')) {\n\t\t\treturn doc\n\t\t}\n\t\tconst { payload } = req\n\t\ttry {\n\t\t\tconst formId = formIdOf(doc.form)\n\t\t\tif (formId == null) {\n\t\t\t\treturn doc\n\t\t\t}\n\t\t\tconst form = await payload\n\t\t\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t\t\t.catch(() => null)\n\n\t\t\tawait dispatchActions({\n\t\t\t\tactions: (form?.actions ?? null) as ActionInstance[] | null,\n\t\t\t\tformId,\n\t\t\t\tsubmissionId: doc.id as number | string,\n\t\t\t\tregistry: args.actionRegistry,\n\t\t\t\tpayload,\n\t\t\t\treq,\n\t\t\t\thasRunner: args.hasRunner,\n\t\t\t\trichText: args.richText,\n\t\t\t})\n\n\t\t\ttry {\n\t\t\t\tawait resolveEventSink(args.events).emit({\n\t\t\t\t\ttype: 'submission.created',\n\t\t\t\t\tformId: String(formId),\n\t\t\t\t\tsubmissionId: String(doc.id),\n\t\t\t\t\tat: new Date().toISOString(),\n\t\t\t\t})\n\t\t\t} catch (error) {\n\t\t\t\tpayload.logger?.error(\n\t\t\t\t\t`@10x-media/form-builder: submission.created sink threw: ${\n\t\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t\t}`\n\t\t\t\t)\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tpayload.logger?.error(\n\t\t\t\t`@10x-media/form-builder: afterChange dispatch failed for submission ${String(doc.id)}: ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`\n\t\t\t)\n\t\t}\n\t\treturn doc\n\t}\n\n/**\n * Opt-in (`poll.votedCookie`) hook: after a submission to a poll-enabled form is created, appends\n * an httpOnly `fb-voted-{formId}=1` cookie via `req.responseHeaders`, Payload's supported channel\n * for hook-set response headers (its own auth strategies use it; `handleEndpoints` merges it into\n * every REST response). Reads the poll config `validateSubmission` stashed on `req.context`,\n * falling back to a form fetch when absent. httpOnly keeps the marker readable only server-side\n * (`hasVotedCookie`); the client `<Poll>` keeps its localStorage guard.\n */\nconst makeVotedCookieHook = (): CollectionAfterChangeHook => {\n\treturn async ({ doc, operation, req }) => {\n\t\tif (operation !== 'create') {\n\t\t\treturn doc\n\t\t}\n\t\tconst formId = formIdOf(doc.form)\n\t\tif (formId == null) {\n\t\t\treturn doc\n\t\t}\n\t\tconst stashed = req.context?.[POLL_CONTEXT_KEY]\n\t\tlet pollEnabled = typeof stashed === 'boolean' ? stashed : undefined\n\t\tif (pollEnabled === undefined) {\n\t\t\tconst form = await req.payload\n\t\t\t\t.findByID({ collection: FORMS_SLUG, id: formId, depth: 0, overrideAccess: true, req })\n\t\t\t\t.catch(() => null)\n\t\t\tpollEnabled = form?.pollEnabled === true\n\t\t}\n\t\tif (!pollEnabled) {\n\t\t\treturn doc\n\t\t}\n\t\treq.responseHeaders ??= new Headers()\n\t\treq.responseHeaders.append(\n\t\t\t'Set-Cookie',\n\t\t\t`${votedCookieName(formId)}=1; Path=/; Max-Age=31536000; HttpOnly; SameSite=Lax`\n\t\t)\n\t\treturn doc\n\t}\n}\n\nexport const buildSubmissionsCollection = ({\n\tregistry,\n\truleRegistry,\n\tconsentSources,\n\tconsentSnapshot,\n\tactionRegistry = new Map(),\n\tevents,\n\thasRunner = false,\n\trichText,\n\tuploadSlug,\n\tspam,\n\tvotedCookie = false,\n\tpollSourceRegistry,\n\tshowRawFields = false,\n\toverrides,\n}: BuildSubmissionsCollectionArgs): CollectionConfig => {\n\tconst defaultFields: Field[] = [\n\t\t{ name: 'form', type: 'relationship', relationTo: FORMS_SLUG, required: true },\n\t\t{\n\t\t\tname: 'status',\n\t\t\ttype: 'select',\n\t\t\tdefaultValue: 'complete',\n\t\t\toptions: [\n\t\t\t\t{ label: labelForKey(keys.statusComplete), value: 'complete' },\n\t\t\t\t{ label: labelForKey(keys.statusPartial), value: 'partial' },\n\t\t\t],\n\t\t\t// Not clearable: aggregation counts `status: complete` submissions, so a cleared status\n\t\t\t// would drop the submission out of every poll result with nothing in the UI saying so.\n\t\t\tadmin: { isClearable: false },\n\t\t\t// Defense-in-depth at the REST layer: anonymous clients cannot set status via the API.\n\t\t\t// The validateSubmission hook also forces 'complete' server-side, so this covers both paths.\n\t\t\taccess: { create: isLoggedIn, update: isLoggedIn },\n\t\t},\n\t\t// answers UI appears first so it is the dominant view when opening a submission document.\n\t\t{\n\t\t\tname: 'answers',\n\t\t\ttype: 'ui',\n\t\t\tadmin: {\n\t\t\t\tcomponents: { Field: '@10x-media/form-builder/rsc#SubmissionAnswers' },\n\t\t\t},\n\t\t},\n\t\t{ name: 'locale', type: 'text', admin: { hidden: !showRawFields } },\n\t\t{ name: 'values', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'descriptors', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'consent', type: 'json', admin: { hidden: !showRawFields } },\n\t\t{ name: 'meta', type: 'json', admin: { hidden: !showRawFields } },\n\t]\n\n\treturn {\n\t\t...(overrides ?? {}),\n\t\tslug: FORM_SUBMISSIONS_SLUG,\n\t\tlabels: {\n\t\t\tsingular: labelForKey(keys.collectionSubmissionSingular),\n\t\t\tplural: labelForKey(keys.collectionSubmissionPlural),\n\t\t\t...(overrides?.labels ?? {}),\n\t\t},\n\t\tadmin: {\n\t\t\tgroup: 'Forms',\n\t\t\tdefaultColumns: ['form', 'status', 'locale', 'createdAt'],\n\t\t\t...(overrides?.admin ?? {}),\n\t\t},\n\t\taccess: {\n\t\t\tcreate: () => true,\n\t\t\tread: isLoggedIn,\n\t\t\tupdate: () => false,\n\t\t\t...(overrides?.access ?? {}),\n\t\t},\n\t\thooks: {\n\t\t\t...(overrides?.hooks ?? {}),\n\t\t\t// Spam guard + validateSubmission must remain first: they enforce the security invariant\n\t\t\t// that anonymous callers cannot bypass post-submit actions or supply a forged status.\n\t\t\t// Consumer beforeValidate hooks are appended after so they run on already-validated data.\n\t\t\tbeforeValidate: [\n\t\t\t\t...(spam ? [buildSpamGuard(spam)] : []),\n\t\t\t\tvalidateSubmission({\n\t\t\t\t\tregistry,\n\t\t\t\t\truleRegistry,\n\t\t\t\t\tconsentSources,\n\t\t\t\t\tconsentSnapshot,\n\t\t\t\t\tuploadSlug,\n\t\t\t\t\tpollSourceRegistry,\n\t\t\t\t}),\n\t\t\t\t...(overrides?.hooks?.beforeValidate ?? []),\n\t\t\t],\n\t\t\tafterChange: [\n\t\t\t\tmakeAfterChange({ actionRegistry, events, hasRunner, richText }),\n\t\t\t\t...(votedCookie ? [makeVotedCookieHook()] : []),\n\t\t\t\t...(overrides?.hooks?.afterChange ?? []),\n\t\t\t],\n\t\t},\n\t\tfields: overrides?.fields ? overrides.fields({ defaultFields }) : defaultFields,\n\t}\n}\n"],"mappings":"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"}
|