@defra/forms-engine-plugin 5.0.0-alpha.3 → 5.0.0-alpha.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.
Files changed (100) hide show
  1. package/.public/javascripts/application.min.js +1 -1
  2. package/.public/javascripts/application.min.js.map +1 -1
  3. package/.public/javascripts/shared.min.js +1 -1
  4. package/.public/javascripts/shared.min.js.map +1 -1
  5. package/.server/client/javascripts/file-upload.js +5 -3
  6. package/.server/client/javascripts/file-upload.js.map +1 -1
  7. package/.server/client/javascripts/geospatial-map.js +31 -26
  8. package/.server/client/javascripts/geospatial-map.js.map +1 -1
  9. package/.server/client/javascripts/location-map.js +9 -1
  10. package/.server/client/javascripts/location-map.js.map +1 -1
  11. package/.server/client/javascripts/sssi-dataset.d.ts +18 -20
  12. package/.server/client/javascripts/sssi-dataset.js +37 -40
  13. package/.server/client/javascripts/sssi-dataset.js.map +1 -1
  14. package/.server/server/constants.d.ts +1 -0
  15. package/.server/server/constants.js +1 -0
  16. package/.server/server/constants.js.map +1 -1
  17. package/.server/server/plugins/engine/components/AutocompleteField.d.ts +1 -0
  18. package/.server/server/plugins/engine/components/ComponentBase.d.ts +1 -0
  19. package/.server/server/plugins/engine/components/ComponentBase.js +2 -0
  20. package/.server/server/plugins/engine/components/ComponentBase.js.map +1 -1
  21. package/.server/server/plugins/engine/components/ComponentCollection.js +2 -1
  22. package/.server/server/plugins/engine/components/ComponentCollection.js.map +1 -1
  23. package/.server/server/plugins/engine/components/DatePartsField.d.ts +1 -0
  24. package/.server/server/plugins/engine/components/DeclarationField.d.ts +1 -0
  25. package/.server/server/plugins/engine/components/DeclarationField.js +1 -1
  26. package/.server/server/plugins/engine/components/DeclarationField.js.map +1 -1
  27. package/.server/server/plugins/engine/components/Details.d.ts +1 -0
  28. package/.server/server/plugins/engine/components/EastingNorthingField.d.ts +2 -0
  29. package/.server/server/plugins/engine/components/EmailAddressField.d.ts +1 -0
  30. package/.server/server/plugins/engine/components/FileUploadField.js +2 -2
  31. package/.server/server/plugins/engine/components/FileUploadField.js.map +1 -1
  32. package/.server/server/plugins/engine/components/FormComponent.d.ts +1 -0
  33. package/.server/server/plugins/engine/components/FormComponent.js +2 -2
  34. package/.server/server/plugins/engine/components/FormComponent.js.map +1 -1
  35. package/.server/server/plugins/engine/components/GeospatialField.d.ts +1 -0
  36. package/.server/server/plugins/engine/components/Html.d.ts +1 -0
  37. package/.server/server/plugins/engine/components/InsetText.d.ts +1 -0
  38. package/.server/server/plugins/engine/components/LatLongField.d.ts +2 -0
  39. package/.server/server/plugins/engine/components/List.d.ts +1 -0
  40. package/.server/server/plugins/engine/components/ListFormComponent.d.ts +1 -0
  41. package/.server/server/plugins/engine/components/LocationFieldBase.d.ts +2 -0
  42. package/.server/server/plugins/engine/components/LocationFieldHelpers.d.ts +2 -0
  43. package/.server/server/plugins/engine/components/Markdown.d.ts +1 -0
  44. package/.server/server/plugins/engine/components/Markdown.js +1 -1
  45. package/.server/server/plugins/engine/components/Markdown.js.map +1 -1
  46. package/.server/server/plugins/engine/components/MonthYearField.d.ts +1 -0
  47. package/.server/server/plugins/engine/components/MultilineTextField.d.ts +1 -0
  48. package/.server/server/plugins/engine/components/NotificationBanner.d.ts +1 -0
  49. package/.server/server/plugins/engine/components/NumberField.d.ts +1 -0
  50. package/.server/server/plugins/engine/components/PaymentField.d.ts +1 -0
  51. package/.server/server/plugins/engine/components/SelectField.d.ts +1 -0
  52. package/.server/server/plugins/engine/components/SelectionControlField.d.ts +1 -0
  53. package/.server/server/plugins/engine/components/TelephoneNumberField.d.ts +1 -0
  54. package/.server/server/plugins/engine/components/UkAddressField.d.ts +1 -0
  55. package/.server/server/plugins/engine/components/types.d.ts +1 -0
  56. package/.server/server/plugins/engine/components/types.js.map +1 -1
  57. package/.server/server/plugins/engine/i18n/translations/cy.json +37 -1
  58. package/.server/server/plugins/engine/i18n/translations/en-GB.json +9 -1
  59. package/.server/server/plugins/engine/i18n/types.d.ts +1 -0
  60. package/.server/server/plugins/engine/i18n/types.js.map +1 -1
  61. package/.server/server/plugins/engine/models/SummaryViewModel.js +7 -3
  62. package/.server/server/plugins/engine/models/SummaryViewModel.js.map +1 -1
  63. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js +3 -5
  64. package/.server/server/plugins/engine/outputFormatters/adapter/v1.js.map +1 -1
  65. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js +20 -7
  66. package/.server/server/plugins/engine/pageControllers/FileUploadPageController.js.map +1 -1
  67. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js +3 -4
  68. package/.server/server/plugins/engine/pageControllers/RepeatPageController.js.map +1 -1
  69. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js +5 -2
  70. package/.server/server/plugins/engine/pageControllers/SummaryPageController.js.map +1 -1
  71. package/.server/server/plugins/engine/services/notifyService.d.ts +1 -1
  72. package/.server/server/plugins/engine/services/notifyService.js +1 -1
  73. package/.server/server/plugins/engine/services/notifyService.js.map +1 -1
  74. package/.server/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  75. package/.server/server/types.d.ts +1 -1
  76. package/.server/server/types.js.map +1 -1
  77. package/package.json +2 -2
  78. package/src/client/javascripts/file-upload.js +10 -3
  79. package/src/client/javascripts/geospatial-map.js +32 -30
  80. package/src/client/javascripts/location-map.js +7 -1
  81. package/src/client/javascripts/sssi-dataset.js +39 -42
  82. package/src/server/constants.js +1 -0
  83. package/src/server/plugins/engine/components/ComponentBase.ts +2 -0
  84. package/src/server/plugins/engine/components/ComponentCollection.ts +4 -5
  85. package/src/server/plugins/engine/components/DeclarationField.ts +1 -2
  86. package/src/server/plugins/engine/components/FileUploadField.ts +2 -2
  87. package/src/server/plugins/engine/components/FormComponent.ts +2 -4
  88. package/src/server/plugins/engine/components/Markdown.ts +2 -3
  89. package/src/server/plugins/engine/components/types.ts +1 -0
  90. package/src/server/plugins/engine/i18n/translations/cy.json +37 -1
  91. package/src/server/plugins/engine/i18n/translations/en-GB.json +9 -1
  92. package/src/server/plugins/engine/i18n/types.ts +1 -0
  93. package/src/server/plugins/engine/models/SummaryViewModel.ts +4 -4
  94. package/src/server/plugins/engine/outputFormatters/adapter/v1.ts +3 -6
  95. package/src/server/plugins/engine/pageControllers/FileUploadPageController.ts +16 -6
  96. package/src/server/plugins/engine/pageControllers/RepeatPageController.ts +2 -2
  97. package/src/server/plugins/engine/pageControllers/SummaryPageController.ts +7 -1
  98. package/src/server/plugins/engine/services/notifyService.ts +1 -0
  99. package/src/server/plugins/engine/views/components/fileuploadfield.html +1 -1
  100. package/src/server/types.ts +1 -0
@@ -62,6 +62,7 @@ export declare class EastingNorthingField extends FormComponent {
62
62
  upload?: {
63
63
  count: number;
64
64
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
65
+ uploadingLabel?: string;
65
66
  };
66
67
  } | {
67
68
  instructionText: string;
@@ -110,6 +111,7 @@ export declare class EastingNorthingField extends FormComponent {
110
111
  upload?: {
111
112
  count: number;
112
113
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
114
+ uploadingLabel?: string;
113
115
  };
114
116
  };
115
117
  getViewErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
@@ -52,6 +52,7 @@ export declare class EmailAddressField extends FormComponent {
52
52
  upload?: {
53
53
  count: number;
54
54
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
55
+ uploadingLabel?: string;
55
56
  };
56
57
  };
57
58
  /**
@@ -88,7 +88,7 @@ export class FileUploadField extends FormComponent {
88
88
  if (!files?.length) {
89
89
  return '';
90
90
  }
91
- return translator.t('components.fileUploadField.filesCount', {
91
+ return translator.t('pages.summary.fileUpload', {
92
92
  count: files.length
93
93
  });
94
94
  }
@@ -164,7 +164,7 @@ export class FileUploadField extends FormComponent {
164
164
  const href = page?.getHref(`${page.path}${path}`) ?? '#';
165
165
  items.push({
166
166
  href,
167
- text: 'Remove',
167
+ text: t('pages.fileUpload.remove'),
168
168
  classes: 'govuk-link--no-visited-state',
169
169
  attributes: {
170
170
  id: `${id}__${index}`
@@ -1 +1 @@
1
- {"version":3,"file":"FileUploadField.js","names":["Boom","joi","FormComponent","isUploadState","InvalidComponentStateError","messageTemplate","FileStatus","UploadStatus","render","resolveLanguage","uploadIdSchema","string","uuid","required","fileSchema","object","fileId","filename","contentLength","number","tempFileSchema","append","fileStatus","valid","complete","rejected","pending","errorMessage","optional","formFileSchema","metadataSchema","keys","retrievalKey","email","tempStatusSchema","uploadStatus","ready","metadata","form","file","array","items","single","numberOfRejectedFiles","formStatusSchema","itemSchema","uploadId","tempItemSchema","status","formItemSchema","FileUploadField","constructor","def","props","options","schema","formSchema","label","length","max","min","stateSchema","default","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","files","translator","t","count","getDisplayStringFromState","getContextValueFromFormValue","map","getContextValueFromState","getViewModel","context","errors","isForceAccess","page","viewModel","attributes","id","filtered","filter","rows","item","index","tag","classes","text","valueHtml","view","params","trim","keyHtml","path","href","getHref","push","visuallyHiddenText","key","html","actions","accept","allowsMultiple","summaryList","multiple","upload","getAllPossibleErrors","onSubmit","request","language","model","createTranslator","notificationEmail","Error","app","services","formSubmissionService","values","initiatedRetrievalKey","persistFiles","error","isBoom","output","statusCode","baseErrors","type","template","selectRequired","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/FileUploadField.ts"],"sourcesContent":["import {\n type FileUploadFieldComponent,\n type FormMetadata\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport joi, { type ArraySchema } from 'joi'\n\nimport {\n FormComponent,\n isUploadState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { InvalidComponentStateError } from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n FileStatus,\n UploadStatus,\n type ErrorMessageTemplateList,\n type FileState,\n type FileUpload,\n type FileUploadMetadata,\n type FormContext,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type SummaryList,\n type SummaryListAction,\n type SummaryListRow,\n type UploadState,\n type UploadStatusFileResponse,\n type UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\nimport { render } from '~/src/server/plugins/nunjucks/index.js'\nimport { type FormRequestPayload } from '~/src/server/routes/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport const uploadIdSchema = joi.string().uuid().required()\n\nexport const fileSchema = joi\n .object<FileUpload>({\n fileId: joi.string().uuid().required(),\n filename: joi.string().required(),\n contentLength: joi.number().required()\n })\n .required()\n\nexport const tempFileSchema = fileSchema.append({\n fileStatus: joi\n .string()\n .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)\n .required(),\n errorMessage: joi.string().optional()\n})\n\nexport const formFileSchema = fileSchema.append({\n fileStatus: joi.string().valid(FileStatus.complete).required()\n})\n\nexport const metadataSchema = joi\n .object<FileUploadMetadata>()\n .keys({\n retrievalKey: joi.string().email().required()\n })\n .required()\n\nexport const tempStatusSchema = joi\n .object<UploadStatusFileResponse>({\n uploadStatus: joi\n .string()\n .valid(UploadStatus.ready, UploadStatus.pending)\n .required(),\n metadata: metadataSchema,\n form: joi\n .object()\n .required()\n .keys({\n file: joi.array().items(tempFileSchema).single().required()\n }),\n numberOfRejectedFiles: joi.number().optional()\n })\n .required()\n\nexport const formStatusSchema = joi\n .object<UploadStatusResponse>({\n uploadStatus: joi.string().valid(UploadStatus.ready).required(),\n metadata: metadataSchema,\n form: joi.object().required().keys({\n file: formFileSchema\n }),\n numberOfRejectedFiles: joi.number().required()\n })\n .required()\n\nexport const itemSchema = joi.object<FileState>({\n uploadId: uploadIdSchema\n})\n\nexport const tempItemSchema = itemSchema.append({\n status: tempStatusSchema\n})\n\nexport const formItemSchema = itemSchema.append({\n status: formStatusSchema\n})\n\nexport class FileUploadField extends FormComponent {\n declare options: FileUploadFieldComponent['options']\n declare schema: FileUploadFieldComponent['schema']\n declare formSchema: ArraySchema<FileState>\n declare stateSchema: ArraySchema<FileState>\n\n constructor(\n def: FileUploadFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .array<FileState>()\n .label(this.label)\n .single()\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n if (typeof schema.length !== 'number') {\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n } else if (options.required !== false) {\n formSchema = formSchema.min(1)\n }\n } else {\n formSchema = formSchema.length(schema.length)\n }\n\n this.formSchema = formSchema.items(formItemSchema)\n this.stateSchema = formSchema\n .items(formItemSchema)\n .default(null)\n .allow(null)\n\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n files: FileState[] | undefined,\n translator: Translator\n ): string {\n if (!files?.length) {\n return ''\n }\n\n return translator.t('components.fileUploadField.filesCount', {\n count: files.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const files = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(files, translator)\n }\n\n getContextValueFromFormValue(\n files: UploadState | undefined\n ): string[] | null {\n return files?.map(({ status }) => status.form.file.fileId) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const files = this.getFormValueFromState(state)\n return this.getContextValueFromFormValue(files)\n }\n\n getViewModel(context: RenderContext) {\n const { errors, isForceAccess = false } = context\n const { t } = context.translator\n const { options, page, schema } = this\n\n const viewModel = super.getViewModel(context)\n const { attributes, id, value } = viewModel\n\n const files = this.getFormValue(value) ?? []\n const filtered = files.filter(\n (file) => file.status.form.file.fileStatus === FileStatus.complete\n )\n const count = filtered.length\n\n const rows: SummaryListRow[] = filtered.map((item, index) => {\n const { status } = item\n const { form } = status\n const { file } = form\n\n const tag = {\n classes: 'govuk-tag--green',\n text: t('components.fileUploadField.uploaded')\n }\n\n const valueHtml = render\n .view('components/fileuploadfield-value.html', {\n context: { params: { tag } }\n })\n .trim()\n\n const keyHtml = render\n .view('components/fileuploadfield-key.html', {\n context: {\n params: {\n name: file.filename,\n errorMessage: errors && file.errorMessage\n }\n }\n })\n .trim()\n\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n const path = `/${file.fileId}/confirm-delete`\n const href = page?.getHref(`${page.path}${path}`) ?? '#'\n\n items.push({\n href,\n text: 'Remove',\n classes: 'govuk-link--no-visited-state',\n attributes: { id: `${id}__${index}` },\n visuallyHiddenText: file.filename\n })\n }\n\n return {\n key: {\n html: keyHtml\n },\n value: {\n html: valueHtml\n },\n actions: {\n items\n }\n } satisfies SummaryListRow\n })\n\n // Set up the `accept` attribute\n if ('accept' in options && options.accept) {\n attributes.accept = options.accept\n }\n\n // Allow multiple file selection when schema permits more than 1 file\n const allowsMultiple = schema.max !== 1 && schema.length !== 1\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-key',\n rows\n }\n\n return {\n ...viewModel,\n\n // File input can't have a initial value\n value: '',\n\n // Override the component name we send to CDP\n name: 'file',\n\n // Enable multi-file selection in the file picker\n ...(allowsMultiple && { multiple: true }),\n\n upload: {\n count,\n summaryList\n }\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is UploadState {\n return isUploadState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FileUploadField.getAllPossibleErrors()\n }\n\n async onSubmit(\n request: FormRequestPayload,\n metadata: FormMetadata,\n context: FormContext\n ) {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n const notificationEmail = metadata.notificationEmail\n\n if (!notificationEmail) {\n // this should not happen because notificationEmail is checked further up\n // the chain in SummaryPageController before submitForm is called.\n throw new Error('Unexpected missing notificationEmail in metadata')\n }\n\n if (!request.app.model?.services.formSubmissionService) {\n throw new Error('No form submission service available in app model')\n }\n\n const { formSubmissionService } = request.app.model.services\n const values = this.getFormValueFromState(context.state) ?? []\n\n const files = values.map((value) => ({\n fileId: value.status.form.file.fileId,\n initiatedRetrievalKey: value.status.metadata.retrievalKey\n }))\n\n if (!files.length) {\n return\n }\n\n try {\n await formSubmissionService.persistFiles(files, notificationEmail)\n } catch (error) {\n if (\n Boom.isBoom(error) &&\n (error.output.statusCode === 403 || // Forbidden - retrieval key invalid\n error.output.statusCode === 404 || // Not Found - file not found\n error.output.statusCode === 410) // Gone - file expired (took to long to submit, etc)\n ) {\n // Failed to persist files. We can't recover from this, the only real way we can recover the submissions is\n // by resetting the problematic components and letting the user re-try.\n // Scenarios: file missing from S3, invalid retrieval key (timing problem), etc.\n throw new InvalidComponentStateError(\n this,\n t('components.fileUploadField.uploadFailed')\n )\n }\n\n throw error\n }\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'selectRequired', template: messageTemplate.selectRequired },\n {\n type: 'filesMimes',\n template: 'The selected file must be a {{#limit}}'\n },\n {\n type: 'filesSize',\n template: 'The selected file must be smaller than 100MB'\n },\n { type: 'filesEmpty', template: 'The selected file is empty' },\n { type: 'filesVirus', template: 'The selected file contains a virus' },\n {\n type: 'filesPartial',\n template: 'The selected file has not fully uploaded'\n },\n {\n type: 'filesError',\n template: 'The selected file could not be uploaded – try again'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'filesMin',\n template: 'You must upload {{#limit}} files or more'\n },\n {\n type: 'filesMax',\n template: 'You can only upload {{#limit}} files or less'\n },\n {\n type: 'filesExact',\n template: 'You must upload exactly {{#limit}} files'\n }\n ]\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"FileUploadField.js","names":["Boom","joi","FormComponent","isUploadState","InvalidComponentStateError","messageTemplate","FileStatus","UploadStatus","render","resolveLanguage","uploadIdSchema","string","uuid","required","fileSchema","object","fileId","filename","contentLength","number","tempFileSchema","append","fileStatus","valid","complete","rejected","pending","errorMessage","optional","formFileSchema","metadataSchema","keys","retrievalKey","email","tempStatusSchema","uploadStatus","ready","metadata","form","file","array","items","single","numberOfRejectedFiles","formStatusSchema","itemSchema","uploadId","tempItemSchema","status","formItemSchema","FileUploadField","constructor","def","props","options","schema","formSchema","label","length","max","min","stateSchema","default","allow","getFormValueFromState","state","name","getFormValue","value","isValue","undefined","getDisplayStringFromFormValue","files","translator","t","count","getDisplayStringFromState","getContextValueFromFormValue","map","getContextValueFromState","getViewModel","context","errors","isForceAccess","page","viewModel","attributes","id","filtered","filter","rows","item","index","tag","classes","text","valueHtml","view","params","trim","keyHtml","path","href","getHref","push","visuallyHiddenText","key","html","actions","accept","allowsMultiple","summaryList","multiple","upload","getAllPossibleErrors","onSubmit","request","language","model","createTranslator","notificationEmail","Error","app","services","formSubmissionService","values","initiatedRetrievalKey","persistFiles","error","isBoom","output","statusCode","baseErrors","type","template","selectRequired","advancedSettingsErrors"],"sources":["../../../../../src/server/plugins/engine/components/FileUploadField.ts"],"sourcesContent":["import {\n type FileUploadFieldComponent,\n type FormMetadata\n} from '@defra/forms-model'\nimport Boom from '@hapi/boom'\nimport joi, { type ArraySchema } from 'joi'\n\nimport {\n FormComponent,\n isUploadState\n} from '~/src/server/plugins/engine/components/FormComponent.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport { InvalidComponentStateError } from '~/src/server/plugins/engine/pageControllers/errors.js'\nimport { messageTemplate } from '~/src/server/plugins/engine/pageControllers/validationOptions.js'\nimport {\n FileStatus,\n UploadStatus,\n type ErrorMessageTemplateList,\n type FileState,\n type FileUpload,\n type FileUploadMetadata,\n type FormContext,\n type FormState,\n type FormStateValue,\n type FormSubmissionState,\n type SummaryList,\n type SummaryListAction,\n type SummaryListRow,\n type UploadState,\n type UploadStatusFileResponse,\n type UploadStatusResponse\n} from '~/src/server/plugins/engine/types.js'\nimport { render } from '~/src/server/plugins/nunjucks/index.js'\nimport { type FormRequestPayload } from '~/src/server/routes/types.js'\nimport { resolveLanguage } from '~/src/server/utils/utils.js'\n\nexport const uploadIdSchema = joi.string().uuid().required()\n\nexport const fileSchema = joi\n .object<FileUpload>({\n fileId: joi.string().uuid().required(),\n filename: joi.string().required(),\n contentLength: joi.number().required()\n })\n .required()\n\nexport const tempFileSchema = fileSchema.append({\n fileStatus: joi\n .string()\n .valid(FileStatus.complete, FileStatus.rejected, FileStatus.pending)\n .required(),\n errorMessage: joi.string().optional()\n})\n\nexport const formFileSchema = fileSchema.append({\n fileStatus: joi.string().valid(FileStatus.complete).required()\n})\n\nexport const metadataSchema = joi\n .object<FileUploadMetadata>()\n .keys({\n retrievalKey: joi.string().email().required()\n })\n .required()\n\nexport const tempStatusSchema = joi\n .object<UploadStatusFileResponse>({\n uploadStatus: joi\n .string()\n .valid(UploadStatus.ready, UploadStatus.pending)\n .required(),\n metadata: metadataSchema,\n form: joi\n .object()\n .required()\n .keys({\n file: joi.array().items(tempFileSchema).single().required()\n }),\n numberOfRejectedFiles: joi.number().optional()\n })\n .required()\n\nexport const formStatusSchema = joi\n .object<UploadStatusResponse>({\n uploadStatus: joi.string().valid(UploadStatus.ready).required(),\n metadata: metadataSchema,\n form: joi.object().required().keys({\n file: formFileSchema\n }),\n numberOfRejectedFiles: joi.number().required()\n })\n .required()\n\nexport const itemSchema = joi.object<FileState>({\n uploadId: uploadIdSchema\n})\n\nexport const tempItemSchema = itemSchema.append({\n status: tempStatusSchema\n})\n\nexport const formItemSchema = itemSchema.append({\n status: formStatusSchema\n})\n\nexport class FileUploadField extends FormComponent {\n declare options: FileUploadFieldComponent['options']\n declare schema: FileUploadFieldComponent['schema']\n declare formSchema: ArraySchema<FileState>\n declare stateSchema: ArraySchema<FileState>\n\n constructor(\n def: FileUploadFieldComponent,\n props: ConstructorParameters<typeof FormComponent>[1]\n ) {\n super(def, props)\n\n const { options, schema } = def\n\n let formSchema = joi\n .array<FileState>()\n .label(this.label)\n .single()\n .required()\n\n if (options.required === false) {\n formSchema = formSchema.optional()\n }\n\n if (typeof schema.length !== 'number') {\n if (typeof schema.max === 'number') {\n formSchema = formSchema.max(schema.max)\n }\n\n if (typeof schema.min === 'number') {\n formSchema = formSchema.min(schema.min)\n } else if (options.required !== false) {\n formSchema = formSchema.min(1)\n }\n } else {\n formSchema = formSchema.length(schema.length)\n }\n\n this.formSchema = formSchema.items(formItemSchema)\n this.stateSchema = formSchema\n .items(formItemSchema)\n .default(null)\n .allow(null)\n\n this.options = options\n this.schema = schema\n }\n\n getFormValueFromState(state: FormSubmissionState) {\n const { name } = this\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getDisplayStringFromFormValue(\n files: FileState[] | undefined,\n translator: Translator\n ): string {\n if (!files?.length) {\n return ''\n }\n\n return translator.t('pages.summary.fileUpload', {\n count: files.length\n })\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ) {\n const files = this.getFormValueFromState(state)\n\n return this.getDisplayStringFromFormValue(files, translator)\n }\n\n getContextValueFromFormValue(\n files: UploadState | undefined\n ): string[] | null {\n return files?.map(({ status }) => status.form.file.fileId) ?? null\n }\n\n getContextValueFromState(state: FormSubmissionState) {\n const files = this.getFormValueFromState(state)\n return this.getContextValueFromFormValue(files)\n }\n\n getViewModel(context: RenderContext) {\n const { errors, isForceAccess = false } = context\n const { t } = context.translator\n const { options, page, schema } = this\n\n const viewModel = super.getViewModel(context)\n const { attributes, id, value } = viewModel\n\n const files = this.getFormValue(value) ?? []\n const filtered = files.filter(\n (file) => file.status.form.file.fileStatus === FileStatus.complete\n )\n const count = filtered.length\n\n const rows: SummaryListRow[] = filtered.map((item, index) => {\n const { status } = item\n const { form } = status\n const { file } = form\n\n const tag = {\n classes: 'govuk-tag--green',\n text: t('components.fileUploadField.uploaded')\n }\n\n const valueHtml = render\n .view('components/fileuploadfield-value.html', {\n context: { params: { tag } }\n })\n .trim()\n\n const keyHtml = render\n .view('components/fileuploadfield-key.html', {\n context: {\n params: {\n name: file.filename,\n errorMessage: errors && file.errorMessage\n }\n }\n })\n .trim()\n\n const items: SummaryListAction[] = []\n\n // Remove summary list actions from previews\n if (!isForceAccess) {\n const path = `/${file.fileId}/confirm-delete`\n const href = page?.getHref(`${page.path}${path}`) ?? '#'\n\n items.push({\n href,\n text: t('pages.fileUpload.remove'),\n classes: 'govuk-link--no-visited-state',\n attributes: { id: `${id}__${index}` },\n visuallyHiddenText: file.filename\n })\n }\n\n return {\n key: {\n html: keyHtml\n },\n value: {\n html: valueHtml\n },\n actions: {\n items\n }\n } satisfies SummaryListRow\n })\n\n // Set up the `accept` attribute\n if ('accept' in options && options.accept) {\n attributes.accept = options.accept\n }\n\n // Allow multiple file selection when schema permits more than 1 file\n const allowsMultiple = schema.max !== 1 && schema.length !== 1\n\n const summaryList: SummaryList = {\n classes: 'govuk-summary-list--long-key',\n rows\n }\n\n return {\n ...viewModel,\n\n // File input can't have a initial value\n value: '',\n\n // Override the component name we send to CDP\n name: 'file',\n\n // Enable multi-file selection in the file picker\n ...(allowsMultiple && { multiple: true }),\n\n upload: {\n count,\n summaryList\n }\n }\n }\n\n isValue(value?: FormStateValue | FormState): value is UploadState {\n return isUploadState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FileUploadField.getAllPossibleErrors()\n }\n\n async onSubmit(\n request: FormRequestPayload,\n metadata: FormMetadata,\n context: FormContext\n ) {\n const language = resolveLanguage(request)\n const { t } = this.model.createTranslator(language)\n\n const notificationEmail = metadata.notificationEmail\n\n if (!notificationEmail) {\n // this should not happen because notificationEmail is checked further up\n // the chain in SummaryPageController before submitForm is called.\n throw new Error('Unexpected missing notificationEmail in metadata')\n }\n\n if (!request.app.model?.services.formSubmissionService) {\n throw new Error('No form submission service available in app model')\n }\n\n const { formSubmissionService } = request.app.model.services\n const values = this.getFormValueFromState(context.state) ?? []\n\n const files = values.map((value) => ({\n fileId: value.status.form.file.fileId,\n initiatedRetrievalKey: value.status.metadata.retrievalKey\n }))\n\n if (!files.length) {\n return\n }\n\n try {\n await formSubmissionService.persistFiles(files, notificationEmail)\n } catch (error) {\n if (\n Boom.isBoom(error) &&\n (error.output.statusCode === 403 || // Forbidden - retrieval key invalid\n error.output.statusCode === 404 || // Not Found - file not found\n error.output.statusCode === 410) // Gone - file expired (took to long to submit, etc)\n ) {\n // Failed to persist files. We can't recover from this, the only real way we can recover the submissions is\n // by resetting the problematic components and letting the user re-try.\n // Scenarios: file missing from S3, invalid retrieval key (timing problem), etc.\n throw new InvalidComponentStateError(\n this,\n t('components.fileUploadField.uploadFailed')\n )\n }\n\n throw error\n }\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [\n { type: 'selectRequired', template: messageTemplate.selectRequired },\n {\n type: 'filesMimes',\n template: 'The selected file must be a {{#limit}}'\n },\n {\n type: 'filesSize',\n template: 'The selected file must be smaller than 100MB'\n },\n { type: 'filesEmpty', template: 'The selected file is empty' },\n { type: 'filesVirus', template: 'The selected file contains a virus' },\n {\n type: 'filesPartial',\n template: 'The selected file has not fully uploaded'\n },\n {\n type: 'filesError',\n template: 'The selected file could not be uploaded – try again'\n }\n ],\n advancedSettingsErrors: [\n {\n type: 'filesMin',\n template: 'You must upload {{#limit}} files or more'\n },\n {\n type: 'filesMax',\n template: 'You can only upload {{#limit}} files or less'\n },\n {\n type: 'filesExact',\n template: 'You must upload exactly {{#limit}} files'\n }\n ]\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -76,6 +76,7 @@ export declare class FormComponent extends ComponentBase {
76
76
  upload?: {
77
77
  count: number;
78
78
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
79
+ uploadingLabel?: string;
79
80
  };
80
81
  };
81
82
  getDisplayStringFromFormValue(value: FormValue | FormPayload, _translator: Translator): string;
@@ -128,12 +128,12 @@ export class FormComponent extends ComponentBase {
128
128
  } = translator;
129
129
  const isRequired = !('required' in options) || options.required !== false;
130
130
  const hideOptional = 'optionalText' in options && options.optionalText;
131
- const resolvedTitle = tComponent(this, 'title') || title;
131
+ const resolvedTitle = tComponent(this.def, 'title') || title;
132
132
  const optionalTag = !isRequired && !hideOptional ? ` ${t('common.optional')}` : '';
133
133
  const label = `${resolvedTitle}${optionalTag}`;
134
134
  if (hint) {
135
135
  viewModel.hint = {
136
- text: tComponent(this, 'hint') || hint
136
+ text: tComponent(this.def, 'hint') || hint
137
137
  };
138
138
  }
139
139
 
@@ -1 +1 @@
1
- {"version":3,"file":"FormComponent.js","names":["ComponentBase","FormComponent","type","hint","label","summaryLabel","isFormComponent","isAppendageStateSingleObject","constructor","def","props","getLabel","getSummaryLabel","errorDescription","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","_translator","errors","list","filter","error","path","includes","length","getFirstError","translator","getViewErrors","firstError","getValidationMessagesOverride","getViewModel","isForceAccess","_isForceAccess","options","viewModel","t","tComponent","isRequired","required","hideOptional","optionalText","resolvedTitle","optionalTag","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type ComponentDef,\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\nimport { type LanguageMessages } from 'joi'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n summaryLabel: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n\n this.label = this.getLabel(def)\n this.summaryLabel = this.getSummaryLabel(def)\n }\n\n getLabel(def: FormComponentsDef) {\n if ('errorDescription' in def && def.errorDescription) {\n return def.errorDescription\n }\n\n return this.getSummaryLabel(def)\n }\n\n getSummaryLabel(def: FormComponentsDef) {\n if ('shortDescription' in def && def.shortDescription) {\n return def.shortDescription\n }\n\n return def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(\n _translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(translator, errors)?.[0]\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(translator, errors)\n return firstError && [firstError]\n }\n\n /**\n * Override in composite fields to return translated Joi message overrides for\n * their sub-fields, applied at validation time so schema-level English messages\n * are replaced with the correct language. Return null to skip message patching.\n */\n getValidationMessagesOverride(\n _translator: Translator\n ): LanguageMessages | null {\n return null\n }\n\n getViewModel({\n payload,\n errors,\n translator,\n isForceAccess: _isForceAccess = false\n }: RenderContext) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const { t, tComponent } = translator\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n\n const resolvedTitle =\n tComponent(this as unknown as ComponentDef, 'title') || title\n const optionalTag =\n !isRequired && !hideOptional ? ` ${t('common.optional')}` : ''\n const label = `${resolvedTitle}${optionalTag}`\n\n if (hint) {\n viewModel.hint = {\n text: tComponent(this as unknown as ComponentDef, 'hint') || hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(translator, errors)\n const componentError = this.getFirstError(translator, componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(\n value: FormValue | FormPayload,\n _translator: Translator\n ): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [],\n advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"AAQA,SAASA,aAAa;AAuBtB,OAAO,MAAMC,aAAa,SAASD,aAAa,CAAC;EAC/CE,IAAI;EACJC,IAAI;EACJC,KAAK;EACLC,YAAY;EAEZC,eAAe,GAAG,IAAI;EACtBC,4BAA4B,GAAG,KAAK;EAEpCC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEP,IAAI;MAAED;IAAK,CAAC,GAAGO,GAAG;IAE1B,IAAI,CAACP,IAAI,GAAGA,IAAI;IAChB,IAAI,CAACC,IAAI,GAAGA,IAAI;IAEhB,IAAI,CAACC,KAAK,GAAG,IAAI,CAACO,QAAQ,CAACF,GAAG,CAAC;IAC/B,IAAI,CAACJ,YAAY,GAAG,IAAI,CAACO,eAAe,CAACH,GAAG,CAAC;EAC/C;EAEAE,QAAQA,CAACF,GAAsB,EAAE;IAC/B,IAAI,kBAAkB,IAAIA,GAAG,IAAIA,GAAG,CAACI,gBAAgB,EAAE;MACrD,OAAOJ,GAAG,CAACI,gBAAgB;IAC7B;IAEA,OAAO,IAAI,CAACD,eAAe,CAACH,GAAG,CAAC;EAClC;EAEAG,eAAeA,CAACH,GAAsB,EAAE;IACtC,IAAI,kBAAkB,IAAIA,GAAG,IAAIA,GAAG,CAACK,gBAAgB,EAAE;MACrD,OAAOL,GAAG,CAACK,gBAAgB;IAC7B;IAEA,OAAOL,GAAG,CAACM,KAAK;EAClB;EAEA,IAAIC,IAAIA,CAAA,EAAG;IACT,MAAM;MAAEC,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,MAAM;QAAEE;MAAO,CAAC,GAAGF,UAAU;MAC7B,OAAO,CAACC,IAAI,EAAE,GAAGC,MAAM,CAACC,GAAG,CAAC,CAAC;QAAEF;MAAK,CAAC,KAAKA,IAAI,CAAC,CAAC;IAClD;IAEA,OAAO,CAACA,IAAI,CAAC;EACf;EAEAG,oBAAoBA,CAACC,KAA0B,EAAe;IAC5D,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACI,oBAAoB,CAACC,KAAK,CAAC;IAC/C;IAEA,OAAO;MACL,CAACJ,IAAI,GAAG,IAAI,CAACK,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC;IACvC,CAAC;EACH;EAEAM,qBAAqBA,CAACF,KAA0B,EAA2B;IACzE,MAAM;MAAEL,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACO,qBAAqB,CAACF,KAAK,CAAC;IAChD;IAEA,OAAO,IAAI,CAACC,YAAY,CAACD,KAAK,CAACJ,IAAI,CAAC,CAAC;EACvC;EAEAK,YAAYA,CAACE,KAAkC,EAAE;IAC/C,OAAO,IAAI,CAACC,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAGE,SAAS;EAChD;EAEAC,qBAAqBA,CAACC,OAAoB,EAAa;IACrD,MAAM;MAAEZ,UAAU;MAAEC;IAAK,CAAC,GAAG,IAAI;IAEjC,IAAID,UAAU,EAAE;MACd,OAAOA,UAAU,CAACW,qBAAqB,CAACC,OAAO,CAAC;IAClD;IAEA,OAAO;MACL,CAACX,IAAI,GAAG,IAAI,CAACK,YAAY,CAACM,OAAO,CAACX,IAAI,CAAC,CAAC,IAAI;IAC9C,CAAC;EACH;EAEAY,SAASA,CACPC,WAAuB,EACvBC,MAA8B,EACK;IACnC,MAAM;MAAEd;IAAK,CAAC,GAAG,IAAI;;IAErB;IACA,MAAMe,IAAI,GAAGD,MAAM,EAAEE,MAAM,CACxBC,KAAK,IACJA,KAAK,CAACjB,IAAI,KAAKA,IAAI,IACnBiB,KAAK,CAACC,IAAI,CAACC,QAAQ,CAACnB,IAAI,CAAC,IACzB,IAAI,CAACF,IAAI,CAACqB,QAAQ,CAACF,KAAK,CAACjB,IAAI,CACjC,CAAC;IAED,IAAI,CAACe,IAAI,EAAEK,MAAM,EAAE;MACjB;IACF;IAEA,OAAOL,IAAI;EACb;EAEAM,aAAaA,CACXC,UAAsB,EACtBR,MAA8B,EACG;IACjC,OAAO,IAAI,CAACF,SAAS,CAACU,UAAU,EAAER,MAAM,CAAC,GAAG,CAAC,CAAC;EAChD;EAEAS,aAAaA,CACXD,UAAsB,EACtBR,MAA8B,EACK;IACnC,MAAMU,UAAU,GAAG,IAAI,CAACH,aAAa,CAACC,UAAU,EAAER,MAAM,CAAC;IACzD,OAAOU,UAAU,IAAI,CAACA,UAAU,CAAC;EACnC;;EAEA;AACF;AACA;AACA;AACA;EACEC,6BAA6BA,CAC3BZ,WAAuB,EACE;IACzB,OAAO,IAAI;EACb;EAEAa,YAAYA,CAAC;IACXf,OAAO;IACPG,MAAM;IACNQ,UAAU;IACVK,aAAa,EAAEC,cAAc,GAAG;EACnB,CAAC,EAAE;IAChB,MAAM;MAAE3C,IAAI;MAAEe,IAAI;MAAE6B,OAAO,GAAG,CAAC,CAAC;MAAEhC,KAAK;MAAEiC;IAAU,CAAC,GAAG,IAAI;IAE3D,MAAM;MAAEC,CAAC;MAAEC;IAAW,CAAC,GAAGV,UAAU;IAEpC,MAAMW,UAAU,GAAG,EAAE,UAAU,IAAIJ,OAAO,CAAC,IAAIA,OAAO,CAACK,QAAQ,KAAK,KAAK;IACzE,MAAMC,YAAY,GAAG,cAAc,IAAIN,OAAO,IAAIA,OAAO,CAACO,YAAY;IAEtE,MAAMC,aAAa,GACjBL,UAAU,CAAC,IAAI,EAA6B,OAAO,CAAC,IAAInC,KAAK;IAC/D,MAAMyC,WAAW,GACf,CAACL,UAAU,IAAI,CAACE,YAAY,GAAG,IAAIJ,CAAC,CAAC,iBAAiB,CAAC,EAAE,GAAG,EAAE;IAChE,MAAM7C,KAAK,GAAG,GAAGmD,aAAa,GAAGC,WAAW,EAAE;IAE9C,IAAIrD,IAAI,EAAE;MACR6C,SAAS,CAAC7C,IAAI,GAAG;QACfsD,IAAI,EAAEP,UAAU,CAAC,IAAI,EAA6B,MAAM,CAAC,IAAI/C;MAC/D,CAAC;IACH;;IAEA;IACA,MAAMuD,eAAe,GAAG,IAAI,CAAC5B,SAAS,CAACU,UAAU,EAAER,MAAM,CAAC;IAC1D,MAAM2B,cAAc,GAAG,IAAI,CAACpB,aAAa,CAACC,UAAU,EAAEkB,eAAe,CAAC;IAEtE,IAAIA,eAAe,EAAE;MACnBV,SAAS,CAAChB,MAAM,GAAG0B,eAAe;IACpC;IAEA,IAAIC,cAAc,EAAE;MAClBX,SAAS,CAACY,YAAY,GAAG;QACvBH,IAAI,EAAEE,cAAc,CAACF;MACvB,CAAC;IACH;IAEA,OAAO;MACL,GAAGT,SAAS;MACZ5C,KAAK,EAAE;QACLqD,IAAI,EAAErD;MACR,CAAC;MACDyD,EAAE,EAAE3C,IAAI;MACRA,IAAI;MACJO,KAAK,EAAEI,OAAO,CAACX,IAAI;IACrB,CAAC;EACH;EAEA4C,6BAA6BA,CAC3BrC,KAA8B,EAC9BM,WAAuB,EACf;IACR;IACA;IACA,OAAO,IAAI,CAACL,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,CAACsC,QAAQ,CAAC,CAAC,GAAG,EAAE;EACpD;EAEAC,yBAAyBA,CACvB1C,KAA0B,EAC1BkB,UAAsB,EACd;IACR,MAAMf,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAC/C,OAAO,IAAI,CAACwC,6BAA6B,CAACrC,KAAK,EAAEe,UAAU,CAAC;EAC9D;EAEAyB,4BAA4BA,CAC1BxC,KAA8B,EACU;IACxC;IACA,IAAI,IAAI,CAACyC,OAAO,CAACzC,KAAK,CAAC,EAAE;MACvB,MAAM0C,MAAM,GAAGC,MAAM,CAACD,MAAM,CAAC1C,KAAK,CAAC,CAACS,MAAM,CAACmC,WAAW,CAAC;MACvD,OAAOF,MAAM,CAAC7B,MAAM,GAAG6B,MAAM,GAAG,IAAI;IACtC;;IAEA;IACA,IAAI,IAAI,CAACzC,OAAO,CAACD,KAAK,CAAC,IAAI6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;MAC/C,OAAOA,KAAK,CAACS,MAAM,CAACmC,WAAW,CAAC;IAClC;IAEA,OAAO,IAAI,CAAC3C,OAAO,CAACD,KAAK,CAAC,GAAGA,KAAK,GAAG,IAAI;EAC3C;EAEA+C,wBAAwBA,CACtBlD,KAA0B,EACc;IACxC,MAAMG,KAAK,GAAG,IAAI,CAACD,qBAAqB,CAACF,KAAK,CAAC;IAE/C,OAAO,IAAI,CAAC2C,4BAA4B,CAACxC,KAAK,CAAC;EACjD;EAEAC,OAAOA,CACLD,KAAkC,EACI;IACtC,OAAO4C,WAAW,CAAC5C,KAAK,CAAC;EAC3B;EAEAyC,OAAOA,CAACzC,KAAkC,EAAsB;IAC9D,OAAOgD,WAAW,CAAChD,KAAK,CAAC;EAC3B;;EAEA;AACF;AACA;EACEiD,oBAAoBA,CAAA,EAA6B;IAC/C,OAAOzE,aAAa,CAACyE,oBAAoB,CAAC,CAAC;EAC7C;;EAEA;AACF;AACA;EACE,OAAOA,oBAAoBA,CAAA,EAA6B;IACtD,OAAO;MACLC,UAAU,EAAE,EAAE;MACdC,sBAAsB,EAAE;IAC1B,CAAC;EACH;EAEAC,QAAQA,CACNC,QAA4B,EAC5BC,SAAuB,EACvBC,QAAqB,EACN;IACf,OAAOC,OAAO,CAACC,OAAO,CAAC,CAAC;EAC1B;AACF;;AAEA;AACA;AACA;AACA,OAAO,SAASb,WAAWA,CACzB5C,KAAe,EACqB;EACpC,OACG,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACa,MAAM,GAAG,CAAC,IAC9C,OAAOb,KAAK,KAAK,QAAQ,IACzB,OAAOA,KAAK,KAAK,SAAS;AAE9B;;AAEA;AACA;AACA;AACA,OAAO,SAASgD,WAAWA,CAAChD,KAAe,EAAsB;EAC/D,IAAIA,KAAK,KAAK,IAAI,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACvE,OAAO,KAAK;EACd;;EAEA;EACA,OAAO,CAAC,CAAC2C,MAAM,CAACD,MAAM,CAAC1C,KAAK,CAAC,CAACa,MAAM;AACtC;;AAEA;AACA;AACA;AACA,OAAO,SAAS6C,aAAaA,CAAC1D,KAAe,EAA4B;EACvE,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACC,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASA,aAAaA,CAAC5D,KAAe,EAA4B;EACvE,OAAOgD,WAAW,CAAChD,KAAK,CAAC,IAAI,OAAOA,KAAK,CAAC6D,MAAM,KAAK,QAAQ;AAC/D;;AAEA;AACA;AACA;AACA,OAAO,SAASC,aAAaA,CAAC9D,KAAe,EAAwB;EACnE,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACI,aAAa,CAAC;AACnC;;AAEA;AACA;AACA;AACA,OAAO,SAASC,iBAAiBA,CAAChE,KAAe,EAA4B;EAC3E,IAAI,CAAC6C,KAAK,CAACC,OAAO,CAAC9C,KAAK,CAAC,EAAE;IACzB,OAAO,KAAK;EACd;;EAEA;EACA,IAAI,CAACA,KAAK,CAACa,MAAM,EAAE;IACjB,OAAO,IAAI;EACb;EAEA,OAAOb,KAAK,CAAC2D,KAAK,CAACM,iBAAiB,CAAC;AACvC;;AAEA;AACA;AACA;AACA,OAAO,SAASF,aAAaA,CAAC/D,KAAe,EAAsB;EACjE,OAAOgD,WAAW,CAAChD,KAAK,CAAC,IAAI,OAAOA,KAAK,CAACkE,QAAQ,KAAK,QAAQ;AACjE;;AAEA;AACA;AACA;AACA,OAAO,SAASD,iBAAiBA,CAACjE,KAAe,EAAoB;EACnE,OACEgD,WAAW,CAAChD,KAAK,CAAC,IAClB,OAAOA,KAAK,CAACvB,IAAI,KAAK,QAAQ,IAC9BuB,KAAK,CAACvB,IAAI,KAAK,SAAS;AAE5B","ignoreList":[]}
1
+ {"version":3,"file":"FormComponent.js","names":["ComponentBase","FormComponent","type","hint","label","summaryLabel","isFormComponent","isAppendageStateSingleObject","constructor","def","props","getLabel","getSummaryLabel","errorDescription","shortDescription","title","keys","collection","name","fields","map","getFormDataFromState","state","getFormValue","getFormValueFromState","value","isValue","undefined","getStateFromValidForm","payload","getErrors","_translator","errors","list","filter","error","path","includes","length","getFirstError","translator","getViewErrors","firstError","getValidationMessagesOverride","getViewModel","isForceAccess","_isForceAccess","options","viewModel","t","tComponent","isRequired","required","hideOptional","optionalText","resolvedTitle","optionalTag","text","componentErrors","componentError","errorMessage","id","getDisplayStringFromFormValue","toString","getDisplayStringFromState","getContextValueFromFormValue","isState","values","Object","isFormValue","Array","isArray","getContextValueFromState","isFormState","getAllPossibleErrors","baseErrors","advancedSettingsErrors","onSubmit","_request","_metadata","_context","Promise","resolve","isRepeatState","every","isRepeatValue","itemId","isUploadState","isUploadValue","isGeospatialState","isGeospatialValue","uploadId"],"sources":["../../../../../src/server/plugins/engine/components/FormComponent.ts"],"sourcesContent":["import {\n type FormComponentsDef,\n type FormMetadata,\n type Item\n} from '@defra/forms-model'\nimport { type LanguageMessages } from 'joi'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormContext,\n type FormRequestPayload\n} from '~/src/server/plugins/engine/types/index.js'\nimport {\n type ErrorMessageTemplateList,\n type Feature,\n type FileState,\n type FormPayload,\n type FormState,\n type FormStateValue,\n type FormSubmissionError,\n type FormSubmissionState,\n type FormValue,\n type GeospatialState,\n type RepeatItemState,\n type RepeatListState,\n type UploadState\n} from '~/src/server/plugins/engine/types.js'\n\nexport class FormComponent extends ComponentBase {\n type: FormComponentsDef['type']\n hint: FormComponentsDef['hint']\n label: string\n summaryLabel: string\n\n isFormComponent = true\n isAppendageStateSingleObject = false\n\n constructor(\n def: FormComponentsDef,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { hint, type } = def\n\n this.type = type\n this.hint = hint\n\n this.label = this.getLabel(def)\n this.summaryLabel = this.getSummaryLabel(def)\n }\n\n getLabel(def: FormComponentsDef) {\n if ('errorDescription' in def && def.errorDescription) {\n return def.errorDescription\n }\n\n return this.getSummaryLabel(def)\n }\n\n getSummaryLabel(def: FormComponentsDef) {\n if ('shortDescription' in def && def.shortDescription) {\n return def.shortDescription\n }\n\n return def.title\n }\n\n get keys() {\n const { collection, name } = this\n\n if (collection) {\n const { fields } = collection\n return [name, ...fields.map(({ name }) => name)]\n }\n\n return [name]\n }\n\n getFormDataFromState(state: FormSubmissionState): FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormDataFromState(state)\n }\n\n return {\n [name]: this.getFormValue(state[name])\n }\n }\n\n getFormValueFromState(state: FormSubmissionState): FormValue | FormPayload {\n const { collection, name } = this\n\n if (collection) {\n return collection.getFormValueFromState(state)\n }\n\n return this.getFormValue(state[name])\n }\n\n getFormValue(value?: FormStateValue | FormState) {\n return this.isValue(value) ? value : undefined\n }\n\n getStateFromValidForm(payload: FormPayload): FormState {\n const { collection, name } = this\n\n if (collection) {\n return collection.getStateFromValidForm(payload)\n }\n\n return {\n [name]: this.getFormValue(payload[name]) ?? null\n }\n }\n\n getErrors(\n _translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const { name } = this\n\n // Filter component and child errors only\n const list = errors?.filter(\n (error) =>\n error.name === name ||\n error.path.includes(name) ||\n this.keys.includes(error.name)\n )\n\n if (!list?.length) {\n return\n }\n\n return list\n }\n\n getFirstError(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError | undefined {\n return this.getErrors(translator, errors)?.[0]\n }\n\n getViewErrors(\n translator: Translator,\n errors?: FormSubmissionError[]\n ): FormSubmissionError[] | undefined {\n const firstError = this.getFirstError(translator, errors)\n return firstError && [firstError]\n }\n\n /**\n * Override in composite fields to return translated Joi message overrides for\n * their sub-fields, applied at validation time so schema-level English messages\n * are replaced with the correct language. Return null to skip message patching.\n */\n getValidationMessagesOverride(\n _translator: Translator\n ): LanguageMessages | null {\n return null\n }\n\n getViewModel({\n payload,\n errors,\n translator,\n isForceAccess: _isForceAccess = false\n }: RenderContext) {\n const { hint, name, options = {}, title, viewModel } = this\n\n const { t, tComponent } = translator\n\n const isRequired = !('required' in options) || options.required !== false\n const hideOptional = 'optionalText' in options && options.optionalText\n\n const resolvedTitle = tComponent(this.def, 'title') || title\n const optionalTag =\n !isRequired && !hideOptional ? ` ${t('common.optional')}` : ''\n const label = `${resolvedTitle}${optionalTag}`\n\n if (hint) {\n viewModel.hint = {\n text: tComponent(this.def, 'hint') || hint\n }\n }\n\n // Filter component errors only\n const componentErrors = this.getErrors(translator, errors)\n const componentError = this.getFirstError(translator, componentErrors)\n\n if (componentErrors) {\n viewModel.errors = componentErrors\n }\n\n if (componentError) {\n viewModel.errorMessage = {\n text: componentError.text\n }\n }\n\n return {\n ...viewModel,\n label: {\n text: label\n },\n id: name,\n name,\n value: payload[name]\n }\n }\n\n getDisplayStringFromFormValue(\n value: FormValue | FormPayload,\n _translator: Translator\n ): string {\n // Map selected values to text\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n return this.isValue(value) ? value.toString() : ''\n }\n\n getDisplayStringFromState(\n state: FormSubmissionState,\n translator: Translator\n ): string {\n const value = this.getFormValueFromState(state)\n return this.getDisplayStringFromFormValue(value, translator)\n }\n\n getContextValueFromFormValue(\n value: FormValue | FormPayload\n ): Item['value'] | Item['value'][] | null {\n // Filter object field values\n if (this.isState(value)) {\n const values = Object.values(value).filter(isFormValue)\n return values.length ? values : null\n }\n\n // Filter array field values\n if (this.isValue(value) && Array.isArray(value)) {\n return value.filter(isFormValue)\n }\n\n return this.isValue(value) ? value : null\n }\n\n getContextValueFromState(\n state: FormSubmissionState\n ): Item['value'] | Item['value'][] | null {\n const value = this.getFormValueFromState(state)\n\n return this.getContextValueFromFormValue(value)\n }\n\n isValue(\n value?: FormStateValue | FormState\n ): value is NonNullable<FormStateValue> {\n return isFormValue(value)\n }\n\n isState(value?: FormStateValue | FormState): value is FormState {\n return isFormState(value)\n }\n\n /**\n * For error preview page that shows all possible errors on a component\n */\n getAllPossibleErrors(): ErrorMessageTemplateList {\n return FormComponent.getAllPossibleErrors()\n }\n\n /**\n * Static version of getAllPossibleErrors that doesn't require a component instance.\n */\n static getAllPossibleErrors(): ErrorMessageTemplateList {\n return {\n baseErrors: [],\n advancedSettingsErrors: []\n }\n }\n\n onSubmit(\n _request: FormRequestPayload,\n _metadata: FormMetadata,\n _context: FormContext\n ): Promise<void> {\n return Promise.resolve()\n }\n}\n\n/**\n * Check for form value\n */\nexport function isFormValue(\n value?: unknown\n): value is string | number | boolean {\n return (\n (typeof value === 'string' && value.length > 0) ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n )\n}\n\n/**\n * Check for form state with nested values\n */\nexport function isFormState(value?: unknown): value is FormState {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n\n // Skip empty objects\n return !!Object.values(value).length\n}\n\n/**\n * Check for repeat list state\n */\nexport function isRepeatState(value?: unknown): value is RepeatListState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isRepeatValue)\n}\n\n/**\n * Check for repeat list value\n */\nexport function isRepeatValue(value?: unknown): value is RepeatItemState {\n return isFormState(value) && typeof value.itemId === 'string'\n}\n\n/**\n * Check for upload state\n */\nexport function isUploadState(value?: unknown): value is UploadState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isUploadValue)\n}\n\n/**\n * Check for geospatial state\n */\nexport function isGeospatialState(value?: unknown): value is GeospatialState {\n if (!Array.isArray(value)) {\n return false\n }\n\n // Skip checks when empty\n if (!value.length) {\n return true\n }\n\n return value.every(isGeospatialValue)\n}\n\n/**\n * Check for upload state value\n */\nexport function isUploadValue(value?: unknown): value is FileState {\n return isFormState(value) && typeof value.uploadId === 'string'\n}\n\n/**\n * Check for geospatial state value\n */\nexport function isGeospatialValue(value?: unknown): value is Feature {\n return (\n isFormState(value) &&\n typeof value.type === 'string' &&\n value.type === 'Feature'\n )\n}\n"],"mappings":"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","ignoreList":[]}
@@ -66,6 +66,7 @@ export declare class GeospatialField extends FormComponent {
66
66
  upload?: {
67
67
  count: number;
68
68
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
69
+ uploadingLabel?: string;
69
70
  };
70
71
  };
71
72
  getErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
@@ -49,6 +49,7 @@ export declare class Html extends ComponentBase {
49
49
  upload?: {
50
50
  count: number;
51
51
  summaryList: import("../types.js").SummaryList;
52
+ uploadingLabel?: string;
52
53
  };
53
54
  };
54
55
  }
@@ -48,6 +48,7 @@ export declare class InsetText extends ComponentBase {
48
48
  upload?: {
49
49
  count: number;
50
50
  summaryList: import("../types.js").SummaryList;
51
+ uploadingLabel?: string;
51
52
  };
52
53
  };
53
54
  }
@@ -62,6 +62,7 @@ export declare class LatLongField extends FormComponent {
62
62
  upload?: {
63
63
  count: number;
64
64
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
65
+ uploadingLabel?: string;
65
66
  };
66
67
  } | {
67
68
  instructionText: string;
@@ -110,6 +111,7 @@ export declare class LatLongField extends FormComponent {
110
111
  upload?: {
111
112
  count: number;
112
113
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
114
+ uploadingLabel?: string;
113
115
  };
114
116
  };
115
117
  getViewErrors(translator: Translator, errors?: FormSubmissionError[]): FormSubmissionError[] | undefined;
@@ -52,6 +52,7 @@ export declare class List extends ComponentBase {
52
52
  upload?: {
53
53
  count: number;
54
54
  summaryList: import("../types.js").SummaryList;
55
+ uploadingLabel?: string;
55
56
  };
56
57
  };
57
58
  }
@@ -65,6 +65,7 @@ export declare class ListFormComponent extends FormComponent {
65
65
  upload?: {
66
66
  count: number;
67
67
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
68
+ uploadingLabel?: string;
68
69
  };
69
70
  };
70
71
  /**
@@ -79,6 +79,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
79
79
  upload?: {
80
80
  count: number;
81
81
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
82
+ uploadingLabel?: string;
82
83
  };
83
84
  } | {
84
85
  instructionText: string;
@@ -128,6 +129,7 @@ export declare abstract class LocationFieldBase extends FormComponent {
128
129
  upload?: {
129
130
  count: number;
130
131
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
132
+ uploadingLabel?: string;
131
133
  };
132
134
  };
133
135
  getAllPossibleErrors(): ErrorMessageTemplateList;
@@ -62,6 +62,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
62
62
  upload?: {
63
63
  count: number;
64
64
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
65
+ uploadingLabel?: string;
65
66
  };
66
67
  } | {
67
68
  instructionText: string;
@@ -110,6 +111,7 @@ export declare function getLocationFieldViewModel(component: LocationField, view
110
111
  upload?: {
111
112
  count: number;
112
113
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
114
+ uploadingLabel?: string;
113
115
  };
114
116
  };
115
117
  /**
@@ -52,6 +52,7 @@ export declare class Markdown extends ComponentBase {
52
52
  upload?: {
53
53
  count: number;
54
54
  summaryList: import("../types.js").SummaryList;
55
+ uploadingLabel?: string;
55
56
  };
56
57
  };
57
58
  }
@@ -22,7 +22,7 @@ export class Markdown extends ComponentBase {
22
22
  } = context.translator;
23
23
  return {
24
24
  ...viewModel,
25
- content: tComponent(this, 'content') || content,
25
+ content: tComponent(this.def, 'content') || content,
26
26
  headerStartLevel: this.headerStartLevel
27
27
  };
28
28
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Markdown.js","names":["ComponentBase","Markdown","content","headerStartLevel","constructor","def","props","options","getViewModel","context","viewModel","tComponent","translator"],"sources":["../../../../../src/server/plugins/engine/components/Markdown.ts"],"sourcesContent":["import { type ComponentDef, type MarkdownComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\n\nexport class Markdown extends ComponentBase {\n declare options: MarkdownComponent['options']\n content: MarkdownComponent['content']\n headerStartLevel: number\n\n constructor(\n def: MarkdownComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n this.headerStartLevel = 2\n }\n\n getViewModel(context: RenderContext) {\n const { content, viewModel } = this\n\n const { tComponent } = context.translator\n\n return {\n ...viewModel,\n content:\n tComponent(this as unknown as ComponentDef, 'content') || content,\n headerStartLevel: this.headerStartLevel\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAGtB,OAAO,MAAMC,QAAQ,SAASD,aAAa,CAAC;EAE1CE,OAAO;EACPC,gBAAgB;EAEhBC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEJ,OAAO;MAAEK;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACH,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACK,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACJ,gBAAgB,GAAG,CAAC;EAC3B;EAEAK,YAAYA,CAACC,OAAsB,EAAE;IACnC,MAAM;MAAEP,OAAO;MAAEQ;IAAU,CAAC,GAAG,IAAI;IAEnC,MAAM;MAAEC;IAAW,CAAC,GAAGF,OAAO,CAACG,UAAU;IAEzC,OAAO;MACL,GAAGF,SAAS;MACZR,OAAO,EACLS,UAAU,CAAC,IAAI,EAA6B,SAAS,CAAC,IAAIT,OAAO;MACnEC,gBAAgB,EAAE,IAAI,CAACA;IACzB,CAAC;EACH;AACF","ignoreList":[]}
1
+ {"version":3,"file":"Markdown.js","names":["ComponentBase","Markdown","content","headerStartLevel","constructor","def","props","options","getViewModel","context","viewModel","tComponent","translator"],"sources":["../../../../../src/server/plugins/engine/components/Markdown.ts"],"sourcesContent":["import { type MarkdownComponent } from '@defra/forms-model'\n\nimport { ComponentBase } from '~/src/server/plugins/engine/components/ComponentBase.js'\nimport { type RenderContext } from '~/src/server/plugins/engine/components/types.js'\n\nexport class Markdown extends ComponentBase {\n declare options: MarkdownComponent['options']\n content: MarkdownComponent['content']\n headerStartLevel: number\n\n constructor(\n def: MarkdownComponent,\n props: ConstructorParameters<typeof ComponentBase>[1]\n ) {\n super(def, props)\n\n const { content, options } = def\n\n this.content = content\n this.options = options\n this.headerStartLevel = 2\n }\n\n getViewModel(context: RenderContext) {\n const { content, viewModel } = this\n\n const { tComponent } = context.translator\n\n return {\n ...viewModel,\n content: tComponent(this.def, 'content') || content,\n headerStartLevel: this.headerStartLevel\n }\n }\n}\n"],"mappings":"AAEA,SAASA,aAAa;AAGtB,OAAO,MAAMC,QAAQ,SAASD,aAAa,CAAC;EAE1CE,OAAO;EACPC,gBAAgB;EAEhBC,WAAWA,CACTC,GAAsB,EACtBC,KAAqD,EACrD;IACA,KAAK,CAACD,GAAG,EAAEC,KAAK,CAAC;IAEjB,MAAM;MAAEJ,OAAO;MAAEK;IAAQ,CAAC,GAAGF,GAAG;IAEhC,IAAI,CAACH,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACK,OAAO,GAAGA,OAAO;IACtB,IAAI,CAACJ,gBAAgB,GAAG,CAAC;EAC3B;EAEAK,YAAYA,CAACC,OAAsB,EAAE;IACnC,MAAM;MAAEP,OAAO;MAAEQ;IAAU,CAAC,GAAG,IAAI;IAEnC,MAAM;MAAEC;IAAW,CAAC,GAAGF,OAAO,CAACG,UAAU;IAEzC,OAAO;MACL,GAAGF,SAAS;MACZR,OAAO,EAAES,UAAU,CAAC,IAAI,CAACN,GAAG,EAAE,SAAS,CAAC,IAAIH,OAAO;MACnDC,gBAAgB,EAAE,IAAI,CAACA;IACzB,CAAC;EACH;AACF","ignoreList":[]}
@@ -64,6 +64,7 @@ export declare class MonthYearField extends FormComponent {
64
64
  upload?: {
65
65
  count: number;
66
66
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
67
+ uploadingLabel?: string;
67
68
  };
68
69
  };
69
70
  isState(value?: FormStateValue | FormState): value is MonthYearState;
@@ -59,6 +59,7 @@ export declare class MultilineTextField extends FormComponent {
59
59
  upload?: {
60
60
  count: number;
61
61
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
62
+ uploadingLabel?: string;
62
63
  };
63
64
  };
64
65
  buildMinMaxText(min?: number, max?: number): string;
@@ -51,6 +51,7 @@ export declare class NotificationBanner extends ComponentBase {
51
51
  upload?: {
52
52
  count: number;
53
53
  summaryList: import("../types.js").SummaryList;
54
+ uploadingLabel?: string;
54
55
  };
55
56
  };
56
57
  }
@@ -58,6 +58,7 @@ export declare class NumberField extends FormComponent {
58
58
  upload?: {
59
59
  count: number;
60
60
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
61
+ uploadingLabel?: string;
61
62
  };
62
63
  };
63
64
  isValue(value?: FormStateValue | FormState): value is number;
@@ -69,6 +69,7 @@ export declare class PaymentField extends FormComponent {
69
69
  upload?: {
70
70
  count: number;
71
71
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
72
+ uploadingLabel?: string;
72
73
  };
73
74
  };
74
75
  /**
@@ -51,6 +51,7 @@ export declare class SelectField extends ListFormComponent {
51
51
  upload?: {
52
52
  count: number;
53
53
  summaryList: import("../types.js").SummaryList;
54
+ uploadingLabel?: string;
54
55
  };
55
56
  };
56
57
  }
@@ -52,6 +52,7 @@ export declare class SelectionControlField extends ListFormComponent {
52
52
  upload?: {
53
53
  count: number;
54
54
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
55
+ uploadingLabel?: string;
55
56
  };
56
57
  };
57
58
  /**
@@ -55,6 +55,7 @@ export declare class TelephoneNumberField extends FormComponent {
55
55
  upload?: {
56
56
  count: number;
57
57
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
58
+ uploadingLabel?: string;
58
59
  };
59
60
  };
60
61
  /**
@@ -69,6 +69,7 @@ export declare class UkAddressField extends FormComponent {
69
69
  upload?: {
70
70
  count: number;
71
71
  summaryList: import("../../../../server/plugins/engine/types.js").SummaryList;
72
+ uploadingLabel?: string;
72
73
  };
73
74
  };
74
75
  isState(value?: FormStateValue | FormState): value is UkAddressState;
@@ -104,6 +104,7 @@ export interface ViewModel extends Record<string, unknown> {
104
104
  upload?: {
105
105
  count: number;
106
106
  summaryList: SummaryList;
107
+ uploadingLabel?: string;
107
108
  };
108
109
  }
109
110
  export interface ComponentViewModel {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormPayload,\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport interface RenderContext {\n payload: FormPayload\n errors: FormSubmissionError[] | undefined\n translator: Translator\n isForceAccess?: boolean\n}\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n // Prefix/suffix are used by location fields (e.g., LatLong, EastingNorthing) for units like \"°\"\n // but not by date fields. This interface is reused by both component types.\n prefix?: ComponentText\n suffix?: ComponentText\n errorMessage?: {\n text: string\n }\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n showFieldsetError?: boolean\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n\nexport interface EastingNorthingState extends Record<string, number> {\n easting: number\n northing: number\n}\n\nexport interface LatLongState extends Record<string, number> {\n latitude: number\n longitude: number\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../../../src/server/plugins/engine/components/types.ts"],"sourcesContent":["import { type ComponentType, type Item } from '@defra/forms-model'\n\nimport { type Translator } from '~/src/server/plugins/engine/i18n/types.js'\nimport {\n type FormPayload,\n type FormSubmissionError,\n type FormValue,\n type SummaryList\n} from '~/src/server/plugins/engine/types.js'\n\nexport interface RenderContext {\n payload: FormPayload\n errors: FormSubmissionError[] | undefined\n translator: Translator\n isForceAccess?: boolean\n}\n\nexport type ComponentText = {\n classes?: string\n attributes?: string | Record<string, string>\n} & (\n | {\n text: string\n html?: string\n }\n | {\n text?: string\n html: string\n }\n)\n\nexport interface Label {\n text: string\n classes?: string\n html?: string\n isPageHeading?: boolean\n}\n\nexport interface Content {\n title?: string\n text: string\n condition?: string\n}\n\nexport interface BackLink {\n text: string\n href: string\n}\n\nexport type ListItemLabel = Omit<Label, 'text' | 'isPageHeading'>\n\nexport interface ListItem {\n text?: string\n value?: Item['value']\n hint?: {\n id?: string\n text: string\n }\n checked?: boolean\n selected?: boolean\n label?: ListItemLabel\n condition?: string\n}\n\nexport interface DateInputItem {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: Item['value']\n classes?: string\n // Prefix/suffix are used by location fields (e.g., LatLong, EastingNorthing) for units like \"°\"\n // but not by date fields. This interface is reused by both component types.\n prefix?: ComponentText\n suffix?: ComponentText\n errorMessage?: {\n text: string\n }\n condition?: undefined\n}\n\nexport interface ViewModel extends Record<string, unknown> {\n label?: Label\n type?: string\n id?: string\n name?: string\n value?: FormValue\n hint?: {\n id?: string\n text: string\n }\n prefix?: ComponentText\n suffix?: ComponentText\n classes?: string\n condition?: string\n errors?: FormSubmissionError[]\n errorMessage?: {\n text: string\n }\n summaryHtml?: string\n html?: string\n attributes: {\n autocomplete?: string\n maxlength?: number\n multiple?: string\n accept?: string\n inputmode?: string\n }\n content?: Content | Content[] | string\n maxlength?: number\n maxwords?: number\n rows?: number\n items?: ListItem[] | DateInputItem[]\n fieldset?: {\n attributes?: string | Record<string, string>\n legend?: Label\n }\n formGroup?: {\n classes?: string\n attributes?: string | Record<string, string>\n }\n showFieldsetError?: boolean\n components?: ComponentViewModel[]\n upload?: {\n count: number\n summaryList: SummaryList\n uploadingLabel?: string\n }\n}\n\nexport interface ComponentViewModel {\n type: ComponentType\n isFormComponent: boolean\n model: ViewModel\n}\n\nexport interface DatePartsState extends Record<string, number> {\n day: number\n month: number\n year: number\n}\n\nexport interface MonthYearState extends Record<string, number> {\n month: number\n year: number\n}\n\nexport interface EastingNorthingState extends Record<string, number> {\n easting: number\n northing: number\n}\n\nexport interface LatLongState extends Record<string, number> {\n latitude: number\n longitude: number\n}\n"],"mappings":"","ignoreList":[]}
@@ -60,6 +60,12 @@
60
60
  "totalAmount": "Cyfanswm",
61
61
  "reference": "Cyfeirnod",
62
62
  "dateOfPayment": "Dyddiad talu",
63
+ "fileUpload_zero": "Ni uwchlwythwyd unrhyw ffeiliau",
64
+ "fileUpload_one": "Uwchlwythwyd [[count]] ffeil",
65
+ "fileUpload_two": "Uwchlwythwyd dwy feil",
66
+ "fileUpload_few": "Uwchlwythwyd [[count]] ffeil",
67
+ "fileUpload_many": "Uwchlwythwyd [[count]] o ffeiliau",
68
+ "fileUpload_other": "Uwchlwythwyd [[count]] ffeil",
63
69
  "submissionFailed": "Roedd problem ac ni chyflwynwyd eich ffurflen. Ceisiwch gyflwyno'r ffurflen eto",
64
70
  "submissionFailedContactSuffix": " neu gallwch [[contactUsLink]] a dyfynnu'ch cyfeirnod i drefnu ad-daliad",
65
71
  "contactUsLinkText": "cysylltu â ni (yn agor mewn tab newydd)",
@@ -79,17 +85,34 @@
79
85
  "change": "Newid",
80
86
  "notProvided": "Heb ei ddarparu",
81
87
  "visuallyHiddenItem": "eitem [[index]]",
88
+ "pageTitle_zero": "Nid ydych wedi ychwanegu unrhyw atebion",
82
89
  "pageTitle_one": "Rydych wedi ychwanegu [[count]] ateb",
90
+ "pageTitle_two": "Rydych wedi ychwanegu dau ateb",
91
+ "pageTitle_few": "Rydych wedi ychwanegu [[count]] ateb",
92
+ "pageTitle_many": "Rydych wedi ychwanegu [[count]] o atebion",
83
93
  "pageTitle_other": "Rydych wedi ychwanegu [[count]] ateb",
94
+ "tooMany_zero": "Ni allwch ychwanegu unrhyw atebion",
84
95
  "tooMany_one": "Dim ond hyd at [[count]] ateb y gallwch ei ychwanegu",
96
+ "tooMany_two": "Dim ond hyd at ddau gateb y gallwch eu hychwanegu",
97
+ "tooMany_few": "Dim ond hyd at [[count]] ateb y gallwch eu hychwanegu",
98
+ "tooMany_many": "Dim ond hyd at [[count]] o atebion y gallwch eu hychwanegu",
85
99
  "tooMany_other": "Dim ond hyd at [[count]] ateb y gallwch eu hychwanegu",
100
+ "tooFew_zero": "Rhaid i chi ychwanegu atebion",
86
101
  "tooFew_one": "Rhaid i chi ychwanegu o leiaf [[count]] ateb",
102
+ "tooFew_two": "Rhaid i chi ychwanegu o leiaf ddau gateb",
103
+ "tooFew_few": "Rhaid i chi ychwanegu o leiaf [[count]] ateb",
104
+ "tooFew_many": "Rhaid i chi ychwanegu o leiaf [[count]] o atebion",
87
105
  "tooFew_other": "Rhaid i chi ychwanegu o leiaf [[count]] ateb"
88
106
  },
89
107
 
90
108
  "fileUpload": {
91
109
  "upload": "Uwchlwytho ffeil",
92
- "maxFilesReached": "Rydych wedi cyrraedd nifer uchaf y ffeiliau. Tynnwch ffeil i uwchlwytho rhagor."
110
+ "maxFilesReached": "Rydych wedi cyrraedd nifer uchaf y ffeiliau. Tynnwch ffeil i uwchlwytho rhagor.",
111
+ "remove": "Tynnu",
112
+ "removeFileTitle": "Ydych chi'n siŵr eich bod chi eisiau dileu'r ffeil hon?",
113
+ "removeFileBody": "Ni allwch adfer ffeiliau a dynnwyd.",
114
+ "removeFileButton": "Dileu ffeil",
115
+ "cancel": "Canslo"
93
116
  },
94
117
 
95
118
  "exit": {
@@ -135,7 +158,11 @@
135
158
  "findAnAddressInstead": "dod o hyd i gyfeiriad yn lle hynny",
136
159
  "noAddressFoundTitle": "Ni chanfuwyd cyfeiriad",
137
160
  "noAddressFoundBody": "Ni allem ddod o hyd i gyfeiriad cyfatebol",
161
+ "addressFound_zero": "Ni chanfuwyd unrhyw gyfeiriadau ar gyfer",
138
162
  "addressFound_one": "Canfuwyd [[count]] cyfeiriad ar gyfer",
163
+ "addressFound_two": "Canfuwyd dau gyfeiriad ar gyfer",
164
+ "addressFound_few": "Canfuwyd [[count]] chyfeiriad ar gyfer",
165
+ "addressFound_many": "Canfuwyd [[count]] o gyfeiriadau ar gyfer",
139
166
  "addressFound_other": "Canfuwyd [[count]] cyfeiriad ar gyfer",
140
167
  "validation": {
141
168
  "invalidPostcode": "Nodwch god post dilys neu nodwch gyfeiriad â llaw",
@@ -237,7 +264,11 @@
237
264
  },
238
265
 
239
266
  "geospatialField": {
267
+ "added_zero": "Ni ychwanegwyd unrhyw leoliadau",
240
268
  "added_one": "Ychwanegwyd [[count]] lleoliad",
269
+ "added_two": "Ychwanegwyd dau leoliad",
270
+ "added_few": "Ychwanegwyd [[count]] lleoliad",
271
+ "added_many": "Ychwanegwyd [[count]] o leoliadau",
241
272
  "added_other": "Ychwanegwyd [[count]] lleoliad",
242
273
  "validation": {
243
274
  "descriptionRequired": "Rhowch ddisgrifiad ar gyfer lleoliad [[count]]",
@@ -262,10 +293,15 @@
262
293
  },
263
294
 
264
295
  "fileUploadField": {
296
+ "uploading": "Yn uwchlwytho…",
265
297
  "uploaded": "Wedi'i uwchlwytho",
266
298
  "uploadFailed": "Roedd problem gyda'ch ffeiliau a uwchlwythwyd. Uwchlwythwch nhw eto cyn cyflwyno'r ffurflen.",
267
299
  "uploadedFilesHeading": "Ffeiliau a uwchlwythwyd",
300
+ "filesCount_zero": "Uwchlwythwyd [[count]] o ffeiliau",
268
301
  "filesCount_one": "Uwchlwythwyd [[count]] ffeil",
302
+ "filesCount_two": "Uwchlwythwyd [[count]] ffeil",
303
+ "filesCount_few": "Uwchlwythwyd [[count]] ffeil",
304
+ "filesCount_many": "Uwchlwythwyd [[count]] o ffeiliau",
269
305
  "filesCount_other": "Uwchlwythwyd [[count]] ffeil"
270
306
  },
271
307