From b084b55d6368cd6635a2805d4564b4b3a5d68097 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 6 Nov 2024 17:25:23 +0000 Subject: [PATCH 01/32] feat: update reference template --- .../templates/reference-template/README.md | 22 ++++ .../src/components/README.md | 3 + .../reference-template/src/fields/README.md | 21 ++++ .../src/forms/Prerequisites.ts | 118 ----------------- .../reference-template/src/forms/README.md | 32 +++++ .../approvedForm.ts} | 0 .../descriptionSection/descriptionSection.ts | 71 +++++++++++ .../getDataFromExternalDataSection.ts | 63 ++++++++++ .../{ExampleForm.ts => exampleForm/index.ts} | 27 ++-- .../exampleForm/introSection/introSection.ts | 20 +++ .../simpleInputsSection/checkboxSubsection.ts | 37 ++++++ .../simpleInputsSection/dateSubsection.ts | 12 ++ .../fileUploadSubsection.ts | 15 +++ .../exampleForm/simpleInputsSection/index.ts | 22 ++++ .../simpleInputsSection/phoneSubsection.ts | 12 ++ .../simpleInputsSection/radioSubsection.ts | 26 ++++ .../simpleInputsSection/selectSubsection.ts | 26 ++++ .../textInputSubsection.ts | 119 ++++++++++++++++++ .../pendingReview.ts} | 0 .../prerequisitesForm/prerequisitesForm.ts | 70 +++++++++++ .../rejectedForm.ts} | 0 .../reviewApplication.ts} | 2 +- .../waitingToAssignForm.ts} | 0 .../src/lib/ReferenceApplicationTemplate.ts | 32 ++--- .../reference-template/src/lib/messages.ts | 36 ++++++ .../reference-template/src/utils/options.ts | 14 +++ 26 files changed, 649 insertions(+), 151 deletions(-) create mode 100644 libs/application/templates/reference-template/src/components/README.md create mode 100644 libs/application/templates/reference-template/src/fields/README.md delete mode 100644 libs/application/templates/reference-template/src/forms/Prerequisites.ts create mode 100644 libs/application/templates/reference-template/src/forms/README.md rename libs/application/templates/reference-template/src/forms/{Approved.ts => approvedForm/approvedForm.ts} (100%) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts rename libs/application/templates/reference-template/src/forms/{ExampleForm.ts => exampleForm/index.ts} (94%) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/fileUploadSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts rename libs/application/templates/reference-template/src/forms/{PendingReview.ts => pendingReviewForm/pendingReview.ts} (100%) create mode 100644 libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts rename libs/application/templates/reference-template/src/forms/{Rejected.ts => rejectedForm/rejectedForm.ts} (100%) rename libs/application/templates/reference-template/src/forms/{ReviewApplication.ts => reviewApplicationForm/reviewApplication.ts} (98%) rename libs/application/templates/reference-template/src/forms/{WaitingToAssign.ts => waitingToAssignForm/waitingToAssignForm.ts} (100%) create mode 100644 libs/application/templates/reference-template/src/utils/options.ts diff --git a/libs/application/templates/reference-template/README.md b/libs/application/templates/reference-template/README.md index c4af4abb3e17..028f936a0606 100644 --- a/libs/application/templates/reference-template/README.md +++ b/libs/application/templates/reference-template/README.md @@ -66,3 +66,25 @@ To access the list of national ids for applicantActors that have come in contact ```ts const applicantActors = application.applicantActors ``` + +## Coding guidelines + +The aim is to have all applications to be coded in a similar way, so that every developer that is familiar with the application system can open any application and everything is consistent and feels familiar. + +- Reduce the amount of custom components to a minimum. +- Reduce the use of the "as" and "any" keywords as much as possible. Both of those keywords are tricking the linter to accept code that would otherwise throw errors and might cause hard to trace bugs. +- Try to use the `getValueViaPath` function to access the answers of the application. It makes accessing nested values easier and the code more readable. Note that this function is generic and a type can be provided to make sure the type of the value is correct E.g: + +`getValueViaPath(application.answers, 'some.nested.value', 'optional fallback')` + +- Don't use fake steps, stepper should only be showing steps of the current form. On the first step in the main form, there shouldn't be a back button or the illusion that you can go back to the prerequsites step. + +## Folder structure + +|-- components - optional folder for React components that are used by custom components. +|-- dataProviders - folder for data providers. +|-- fields - optional folder for custom components if the application needs any. +|-- forms - folder for forms. +|-- lib - folder for data schema, messages, and the main template file. +|-- shared - optional folder for code that might be needed in the template-api-modules or other places outside the template. +|-- utils - folder for utility functions, constants, enums and types. diff --git a/libs/application/templates/reference-template/src/components/README.md b/libs/application/templates/reference-template/src/components/README.md new file mode 100644 index 000000000000..f51286858e87 --- /dev/null +++ b/libs/application/templates/reference-template/src/components/README.md @@ -0,0 +1,3 @@ +# The components folder + +This folder contains all React components that are not custom components on their own but are used by custom components. diff --git a/libs/application/templates/reference-template/src/fields/README.md b/libs/application/templates/reference-template/src/fields/README.md new file mode 100644 index 000000000000..50011f40db2a --- /dev/null +++ b/libs/application/templates/reference-template/src/fields/README.md @@ -0,0 +1,21 @@ +# The fields folder + +This folder contains all custom components that are used by the application. + +## Organisation + +- All components should be in a folder that holds the .tsx file and the .css.ts file. + The folders should be named like the component, but with the first letter in lowercase (camelCase), and then the .tsx and .css.ts files should be capitalized (PascalCase). +- The folder should have an index.ts file that re-exports all the components. +- The index.ts file in the /src folder should then re-export the components in the /fields folder. + +## Useage of custom components + +Before creating a custom component, you should: + +1. Try to use the shared components, `buildTextField`, `buildCheckboxField`, `buildSelectField`, `buildFileUploadField` and so on. This is most preferable to make the look and feel of the application more consistent and uniform. +2. If the shared components almost fullfill your needs but you need something more, consider consulting with the designer of the application and try to adjust the design to the built in components. +3. If the design can not be adjusted to the built in components, then consult Norda if a shared component can possibly be adjusted or expanded to fulfill your needs. +4. Is there another application that has made a similar custom component before? If so, then it should be a shared component. +5. If you still need a new component, ask yourself if this is a component that another application might also need in the future. If so make the new component shared. +6. Make a custom component if none of the above apply. diff --git a/libs/application/templates/reference-template/src/forms/Prerequisites.ts b/libs/application/templates/reference-template/src/forms/Prerequisites.ts deleted file mode 100644 index 27de62ca28ef..000000000000 --- a/libs/application/templates/reference-template/src/forms/Prerequisites.ts +++ /dev/null @@ -1,118 +0,0 @@ -import get from 'lodash/get' -import { - buildForm, - buildDescriptionField, - buildMultiField, - buildSection, - buildSubmitField, - buildExternalDataProvider, - buildDataProviderItem, -} from '@island.is/application/core' -import { Application, Form, FormModes } from '@island.is/application/types' -import { m } from '../lib/messages' - -import { UserProfileApi } from '@island.is/application/types' -import { - ReferenceDataApi, - MyMockProvider, - NationalRegistryApi, -} from '../dataProviders' - -export const Prerequisites: Form = buildForm({ - id: 'PrerequisitesDraft', - title: 'Skilyrði', - mode: FormModes.DRAFT, - children: [ - buildSection({ - id: 'conditions', - title: m.conditionsSection, - children: [ - buildExternalDataProvider({ - id: 'approveExternalData', - title: 'Utanaðkomandi gögn', - dataProviders: [ - buildDataProviderItem({ - provider: UserProfileApi, - title: 'User profile', - subTitle: 'User profile', - }), - buildDataProviderItem({ - provider: ReferenceDataApi, - title: 'getReferenceData', - subTitle: 'Reference data', - }), - buildDataProviderItem({ - provider: NationalRegistryApi, - title: 'Þjóðskrá', - subTitle: 'Upplýsingar um þig í Þjóðskrá.', - }), - buildDataProviderItem({ - provider: MyMockProvider, - title: 'Mock Data', - subTitle: 'Returns data for mocking', - }), - ], - }), - buildMultiField({ - id: 'externalDataSuccess', - title: 'Tókst að sækja gögn', - children: [ - buildDescriptionField({ - id: 'externalDataSuccessDescription', - title: '', - description: (application: Application) => - `Gildið frá data provider: ${get( - application.externalData, - 'getReferenceData.data.referenceData.numbers', - 'fannst ekki', - )}`, - }), - buildDescriptionField({ - id: 'externalDataSuccessDescription.mock', - title: '', - description: (application: Application) => - `Gildið frá mock data provider: ${get( - application.externalData, - 'referenceMock.data.mockObject.mockString', - 'fannst ekki', - )}`, - }), - buildSubmitField({ - id: 'toDraft', - placement: 'footer', - title: 'Hefja umsókn', - refetchApplicationAfterSubmit: true, - actions: [ - { - event: 'SUBMIT', - name: 'Hefja umsókn', - type: 'primary', - }, - ], - }), - ], - }), - buildDescriptionField({ - id: 'neverDisplayed', - title: '', - description: '', - }), - ], - }), - buildSection({ - id: 'intro', - title: m.introSection, - children: [], - }), - buildSection({ - id: 'career', - title: m.career, - children: [], - }), - buildSection({ - id: 'confirmation', - title: 'Staðfesta', - children: [], - }), - ], -}) diff --git a/libs/application/templates/reference-template/src/forms/README.md b/libs/application/templates/reference-template/src/forms/README.md new file mode 100644 index 000000000000..4a39d8668337 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/README.md @@ -0,0 +1,32 @@ +# The forms folder + +This folder contains all the forms that are used by the application. + +At minimum there should be a prerequisites form, application form and a confirmation form to reflect the possible states of an application. +For more complecated applications you could have different forms depending on the user type and you could have more states like approved, rejected, waiting to assign... + +## Organization + +All forms should be in a folder with the same name as the form. The folder and files in it should follow camelCase, PascalCase should be reserved for React components. +A simple form with one screen, like the prerequisites form can be just a single file. +Form with more than one section and possibly subsections should be broken down into one file per screen. + +Example folder structure: + +| /prerequisitesForm +| |-- prerequisitesForm.tsx + +| /applicationForm +| |-- index.ts (This file has a buildForm function) +| |-- /section1 +| | |-- index.ts (This file has a buildSection function) +| | |-- /subsection1.ts (This file has a buildSubSection function) +| | |-- /subsection2.ts (This file has a buildSubSection function) +| | |-- /subsection3.ts (This file has a buildSubSection function) +| |-- /section2 +| | |-- index.ts (This file has a buildSection function) +| |-- /section3 +| | |-- index.ts (This file has a buildSection function) + +| /confirmationForm +| |-- confirmationForm.ts diff --git a/libs/application/templates/reference-template/src/forms/Approved.ts b/libs/application/templates/reference-template/src/forms/approvedForm/approvedForm.ts similarity index 100% rename from libs/application/templates/reference-template/src/forms/Approved.ts rename to libs/application/templates/reference-template/src/forms/approvedForm/approvedForm.ts diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts new file mode 100644 index 000000000000..11f0e60eda03 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts @@ -0,0 +1,71 @@ +import { + buildDescriptionField, + buildMultiField, + buildSection, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' + +export const descriptionSection = buildSection({ + id: 'descriptionSection', + title: 'Description', + children: [ + buildMultiField({ + id: 'description', + title: 'The description field', + children: [ + buildDescriptionField({ + id: 'description', + title: 'Default title size ', + description: 'Description inserted as a regular string', + marginBottom: [2], + tooltip: 'Tooltip text', + titleTooltip: 'Title tooltip text', + }), + buildDescriptionField({ + id: 'description', + title: 'h1 title size', + titleVariant: 'h1', + description: m.regularTextExample, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description', + title: 'h2 title size (same as default)', + titleVariant: 'h2', + description: m.markdownHeadingExample, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description', + title: 'h3 title size', + titleVariant: 'h3', + description: m.markdownBulletListExample, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description', + title: 'h4 title size', + titleVariant: 'h4', + description: m.markdownNumberedListExample, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description', + title: 'h5 title size', + titleVariant: 'h5', + description: { + ...m.markdownMiscExample, + values: { value1: 'MY VALUE' }, + }, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description', + title: '', + description: m.markdownCodeExample, + marginBottom: [2], + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts new file mode 100644 index 000000000000..7e8dfdb95f48 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts @@ -0,0 +1,63 @@ +import { + buildDescriptionField, + buildMultiField, + buildSection, + getValueViaPath, +} from '@island.is/application/core' +import { Application } from '@island.is/application/types' + +export const getDataFromExternalDataSection = buildSection({ + id: 'getDataFromExternalData', + title: 'External data', + children: [ + buildMultiField({ + id: 'externalDataSuccess', + title: '', + children: [ + buildDescriptionField({ + id: 'externalDataSuccessTitle', + title: 'Dæmi um að gögn séu sótt úr external data', + marginBottom: [4], + }), + buildDescriptionField({ + id: 'externalDataSuccessDescription', + title: 'Gildi frá data provider', + titleVariant: 'h4', + description: (application: Application) => { + const value = getValueViaPath( + application.externalData, + 'getReferenceData.data.referenceData.applicantName', + ) + + return value ?? 'Fannst ekki' + }, + }), + buildDescriptionField({ + id: 'externalDataSuccessDescription2', + title: '', + description: (application: Application) => { + const value = getValueViaPath( + application.externalData, + 'getReferenceData.data.referenceData.numbers', + ) + + return value ? `${value}` : 'Fannst ekki' + }, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'externalDataSuccessDescriptionMock', + title: 'Gildi frá mock data provider', + titleVariant: 'h4', + description: (application: Application) => { + const value = getValueViaPath( + application.externalData, + 'referenceMock.data.mockObject.mockString', + ) + return value ?? 'Fannst ekki' + }, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/ExampleForm.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts similarity index 94% rename from libs/application/templates/reference-template/src/forms/ExampleForm.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/index.ts index c402a020c9fd..b0d055e103da 100644 --- a/libs/application/templates/reference-template/src/forms/ExampleForm.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -22,19 +22,22 @@ import { FormModes, FormValue, } from '@island.is/application/types' -import { ApiActions } from '../shared' -import { m } from '../lib/messages' +import { m } from '../../lib/messages' +import { ApiActions } from '../../shared' +import { introSection } from './introSection/introSection' +import { getDataFromExternalDataSection } from './getDataFromExternalDataSection/getDataFromExternalDataSection' +import { simpleInputsSection } from './simpleInputsSection' +import { descriptionSection } from './descriptionSection/descriptionSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', - title: 'Atvinnuleysisbætur', + title: 'Main form', mode: FormModes.DRAFT, children: [ - buildSection({ - id: 'conditions', - title: m.conditionsSection, - children: [], - }), + introSection, + getDataFromExternalDataSection, + descriptionSection, + simpleInputsSection, buildSection({ id: 'tableRepeaterWithPhone', title: 'Table repeater', @@ -95,14 +98,6 @@ export const ExampleForm: Form = buildForm({ id: 'intro', title: m.introSection, children: [ - buildDescriptionField({ - id: 'field', - title: m.introField, - description: (application) => ({ - ...m.introIntroduction, - values: { name: application.answers.name }, - }), - }), buildMultiField({ id: 'about', title: m.about.defaultMessage, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts new file mode 100644 index 000000000000..f56476e44fb3 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts @@ -0,0 +1,20 @@ +import { + buildDescriptionField, + buildSection, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' + +export const introSection = buildSection({ + id: 'introSection', + title: 'Inngangur', + children: [ + buildDescriptionField({ + id: 'field', + title: m.introField, + description: (application) => ({ + ...m.introIntroduction, + values: { name: application.answers.name }, + }), + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts new file mode 100644 index 000000000000..dd4c30b5b557 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts @@ -0,0 +1,37 @@ +import { + buildCheckboxField, + buildMultiField, + buildSubSection, +} from '@island.is/application/core' +import { checkboxOptions } from '../../../utils/options' + +export const checkboxSubsection = buildSubSection({ + id: 'checkbox', + title: 'Checkboxes', + children: [ + buildMultiField({ + id: 'checkboxMultiField', + title: 'Checkboxes', + children: [ + buildCheckboxField({ + id: 'checkbox', + title: 'Full width checkboxes', + options: checkboxOptions, // Importing options from utils makes the templatemuch more readable + }), + buildCheckboxField({ + id: 'checkbox', + title: 'Half width checkboxes', + width: 'half', + options: checkboxOptions, + }), + buildCheckboxField({ + id: 'checkbox', + title: 'Half width strong checkboxes', + width: 'half', + strong: true, + options: checkboxOptions, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts new file mode 100644 index 000000000000..171a12e3c6de --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts @@ -0,0 +1,12 @@ +import { buildDateField, buildSubSection } from '@island.is/application/core' + +export const dateSubsection = buildSubSection({ + id: 'date', + title: 'Date', + children: [ + buildDateField({ + id: 'date', + title: 'Date', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/fileUploadSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/fileUploadSubsection.ts new file mode 100644 index 000000000000..434a89b55c66 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/fileUploadSubsection.ts @@ -0,0 +1,15 @@ +import { + buildFileUploadField, + buildSubSection, +} from '@island.is/application/core' + +export const fileUploadSubsection = buildSubSection({ + id: 'fileUpload', + title: 'File Upload', + children: [ + buildFileUploadField({ + id: 'fileUpload', + title: 'File Upload', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts new file mode 100644 index 000000000000..2324826cc486 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts @@ -0,0 +1,22 @@ +import { buildSection } from '@island.is/application/core' +import { textInputSubsection } from './textInputSubsection' +import { checkboxSubsection } from './checkboxSubsection' +import { radioSubsection } from './radioSubsection' +import { selectSubsection } from './selectSubsection' +import { phoneSubsection } from './phoneSubsection' +import { dateSubsection } from './dateSubsection' +import { fileUploadSubsection } from './fileUploadSubsection' + +export const simpleInputsSection = buildSection({ + id: 'simpleInputsSection', + title: 'Simple inputs', + children: [ + textInputSubsection, + checkboxSubsection, + radioSubsection, + selectSubsection, + phoneSubsection, + dateSubsection, + fileUploadSubsection, + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts new file mode 100644 index 000000000000..c0015f970fc7 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts @@ -0,0 +1,12 @@ +import { buildPhoneField, buildSubSection } from '@island.is/application/core' + +export const phoneSubsection = buildSubSection({ + id: 'phone', + title: 'Phone', + children: [ + buildPhoneField({ + id: 'phone', + title: 'Phone', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts new file mode 100644 index 000000000000..c4be420a0195 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts @@ -0,0 +1,26 @@ +import { buildRadioField, buildSubSection } from '@island.is/application/core' + +export const radioSubsection = buildSubSection({ + id: 'radio', + title: 'Radio', + children: [ + buildRadioField({ + id: 'radio', + title: 'Radio', + options: [ + { + label: 'Radio 1', + value: 'radio1', + }, + { + label: 'Radio 2', + value: 'radio2', + }, + { + label: 'Radio 3', + value: 'radio3', + }, + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts new file mode 100644 index 000000000000..a46b13ddcf1d --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts @@ -0,0 +1,26 @@ +import { buildSelectField, buildSubSection } from '@island.is/application/core' + +export const selectSubsection = buildSubSection({ + id: 'select', + title: 'Select', + children: [ + buildSelectField({ + id: 'select', + title: 'Select', + options: [ + { + label: 'Select 1', + value: 'select1', + }, + { + label: 'Select 2', + value: 'select2', + }, + { + label: 'Select 3', + value: 'select3', + }, + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts new file mode 100644 index 000000000000..57a111407982 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts @@ -0,0 +1,119 @@ +import { + buildMultiField, + buildSubSection, + buildTextField, +} from '@island.is/application/core' + +export const textInputSubsection = buildSubSection({ + id: 'textInput', + title: 'Text Input', + children: [ + buildMultiField({ + id: 'textInput', + title: 'Text input', + children: [ + buildTextField({ + id: 'textInput', + title: '', + placeholder: 'The most basic text input', + }), + buildTextField({ + id: 'halfTextInput', + title: '', + placeholder: 'Half width text input', + width: 'half', + }), + buildTextField({ + id: 'rightAlignedTextInput', + title: '', + placeholder: 'Right aligned', + width: 'half', + rightAlign: true, + }), + buildTextField({ + id: 'readOnlydTextInput', + title: '', + defaultValue: 'Read only', + width: 'half', + readOnly: true, + }), + buildTextField({ + id: 'maxLengthTextInput', + title: '', + placeholder: 'Max length 3', + width: 'half', + maxLength: 3, + }), + buildTextField({ + id: 'formatTextInput', + title: '', + placeholder: 'Special format (kennitala)', + format: '######-####', + }), + buildTextField({ + id: 'whiteBackgroundTextInput', + title: '', + placeholder: 'White background (try to use blue if possible)', + backgroundColor: 'white', + }), + buildTextField({ + id: 'textTextInput', + title: '', + placeholder: 'Variant text (same as default)', + variant: 'text', + width: 'half', + }), + buildTextField({ + id: 'emailTextInput', + title: '', + placeholder: 'Variant email', + variant: 'email', + width: 'half', + }), + buildTextField({ + id: 'numberTextInput', + title: '', + placeholder: 'Variant number', + variant: 'number', + width: 'half', + }), + buildTextField({ + id: 'currencyTextInput', + title: '', + placeholder: 'Variant currency', + variant: 'currency', + width: 'half', + }), + buildTextField({ + id: 'currencyTextInput', + title: '', + placeholder: 'Variant currency ($)', + variant: 'currency', + width: 'half', + suffix: ' $', + }), + buildTextField({ + id: 'currencyTextInput', + title: '', + placeholder: 'Variant currency (€)', + variant: 'currency', + width: 'half', + suffix: ' €', + }), + buildTextField({ + id: 'telTextInput', + title: '', + placeholder: 'Variant tel (try to use buildPhoneField)', + variant: 'tel', + }), + buildTextField({ + id: 'textAreaTextInput', + title: '', + placeholder: 'Textarea', + variant: 'textarea', + rows: 10, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/PendingReview.ts b/libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts similarity index 100% rename from libs/application/templates/reference-template/src/forms/PendingReview.ts rename to libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts diff --git a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts new file mode 100644 index 000000000000..f4b241da84f1 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts @@ -0,0 +1,70 @@ +import { + buildForm, + buildSection, + buildExternalDataProvider, + buildDataProviderItem, + buildSubmitField, + coreMessages, +} from '@island.is/application/core' +import { DefaultEvents, Form, FormModes } from '@island.is/application/types' +import { UserProfileApi } from '@island.is/application/types' +import { + ReferenceDataApi, + MyMockProvider, + NationalRegistryApi, +} from '../../dataProviders' + +export const Prerequisites: Form = buildForm({ + id: 'PrerequisitesDraft', + title: 'Forkröfur', + mode: FormModes.NOT_STARTED, + renderLastScreenButton: true, + children: [ + buildSection({ + id: 'conditions', + title: '', // If this is empty, we will not have a visible stepper on the right side of the screen. + children: [ + buildExternalDataProvider({ + id: 'approveExternalData', + title: 'Utanaðkomandi gögn', + dataProviders: [ + buildDataProviderItem({ + provider: UserProfileApi, + title: 'User profile', + subTitle: 'User profile', + }), + buildDataProviderItem({ + provider: ReferenceDataApi, + title: 'getReferenceData', + subTitle: 'Reference data', + }), + buildDataProviderItem({ + provider: NationalRegistryApi, + title: 'Þjóðskrá', + subTitle: 'Upplýsingar um þig í Þjóðskrá.', + }), + buildDataProviderItem({ + provider: MyMockProvider, + title: 'Mock Data', + subTitle: 'Returns data for mocking', + }), + ], + // Button to trigger the submit event to move the application from the NOT_STARTED state to the DRAFT state. + submitField: buildSubmitField({ + id: 'submit', + placement: 'footer', + title: '', + refetchApplicationAfterSubmit: true, + actions: [ + { + event: DefaultEvents.SUBMIT, + name: coreMessages.buttonNext, + type: 'primary', + }, + ], + }), + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/Rejected.ts b/libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts similarity index 100% rename from libs/application/templates/reference-template/src/forms/Rejected.ts rename to libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts diff --git a/libs/application/templates/reference-template/src/forms/ReviewApplication.ts b/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts similarity index 98% rename from libs/application/templates/reference-template/src/forms/ReviewApplication.ts rename to libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts index bd1b2815fafe..fc71730a02e8 100644 --- a/libs/application/templates/reference-template/src/forms/ReviewApplication.ts +++ b/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts @@ -10,7 +10,7 @@ import { buildTextField, } from '@island.is/application/core' import { Form, FormModes } from '@island.is/application/types' -import { m } from '../lib/messages' +import { m } from '../../lib/messages' export const ReviewApplication: Form = buildForm({ id: 'ExampleInReview', diff --git a/libs/application/templates/reference-template/src/forms/WaitingToAssign.ts b/libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts similarity index 100% rename from libs/application/templates/reference-template/src/forms/WaitingToAssign.ts rename to libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index 579378424e97..ad028d6ab0ee 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -50,16 +50,16 @@ enum Roles { } const determineMessageFromApplicationAnswers = (application: Application) => { - const careerHistory = getValueViaPath( + const careerHistory = getValueViaPath( application.answers, 'careerHistory', undefined, - ) as string | undefined - const careerIndustry = getValueViaPath( + ) + const careerIndustry = getValueViaPath( application.answers, 'careerIndustry', undefined, - ) as string | undefined + ) if (careerHistory === 'no') { return m.nameApplicationNeverWorkedBefore @@ -103,8 +103,8 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/Prerequisites').then((module) => - Promise.resolve(module.Prerequisites), + import('../forms/prerequisitesForm/prerequisitesForm').then( + (module) => Promise.resolve(module.Prerequisites), ), actions: [ { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' }, @@ -154,7 +154,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/ExampleForm').then((module) => + import('../forms/exampleForm').then((module) => Promise.resolve(module.ExampleForm), ), actions: [ @@ -207,8 +207,8 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/WaitingToAssign').then((val) => - Promise.resolve(val.PendingReview), + import('../forms/waitingToAssignForm/waitingToAssignForm').then( + (val) => Promise.resolve(val.PendingReview), ), read: 'all', write: 'all', @@ -217,8 +217,8 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.ASSIGNEE, formLoader: () => - import('../forms/WaitingToAssign').then((val) => - Promise.resolve(val.PendingReview), + import('../forms/waitingToAssignForm/waitingToAssignForm').then( + (val) => Promise.resolve(val.PendingReview), ), read: 'all', }, @@ -263,8 +263,8 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.ASSIGNEE, formLoader: () => - import('../forms/ReviewApplication').then((val) => - Promise.resolve(val.ReviewApplication), + import('../forms/reviewApplicationForm/reviewApplication').then( + (val) => Promise.resolve(val.ReviewApplication), ), actions: [ { event: 'APPROVE', name: 'Samþykkja', type: 'primary' }, @@ -279,7 +279,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/PendingReview').then((val) => + import('../forms/pendingReviewForm/pendingReview').then((val) => Promise.resolve(val.PendingReview), ), read: 'all', @@ -301,7 +301,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/Approved').then((val) => + import('../forms/approvedForm/approvedForm').then((val) => Promise.resolve(val.Approved), ), read: 'all', @@ -320,7 +320,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< { id: Roles.APPLICANT, formLoader: () => - import('../forms/Rejected').then((val) => + import('../forms/rejectedForm/rejectedForm').then((val) => Promise.resolve(val.Rejected), ), }, diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index c12509c9901e..040f4e01eb1c 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -180,4 +180,40 @@ export const m = defineMessages({ 'Vinsamlegast tilgreindu hvort umsóknin sé samþykkt eða ekki', description: 'Some description', }, + regularTextExample: { + id: 'example.application:regularTextExample', + defaultMessage: + 'Regular text coming from a message file, this can be overwritten in contentful by webmaster', + description: 'Example use of messages', + }, + markdownHeadingExample: { + id: 'example.application:markdownHeadingExample#markdown', + defaultMessage: + '# Markdown heading 1\n ## Markdown heading 2\n ### Markdown heading 3\n #### Markdown heading 4\n Regular markdown text', + description: 'Example use of markdown', + }, + markdownBulletListExample: { + id: 'example.application:markdownBulletListExample#markdown', + defaultMessage: + 'Markdown bullet list\n * bullet 1\n * bullet 2\n * bullet 3', + description: 'Example use of markdown', + }, + markdownNumberedListExample: { + id: 'example.application:markdownNumberedListExample#markdown', + defaultMessage: + 'Markdown numbered list\n 1. number 1\n 2. number 2\n 3. number 3', + description: 'Example use of markdown', + }, + markdownMiscExample: { + id: 'example.application:markdownMiscExample#markdown', + defaultMessage: + 'A markdown link will open in a new tab: [This is a link to Google!](http://google.com)\n\n Markdown value inserted {value1}\n\n **Bold text**\n\n *Italic text*\n\n ***Bold and italic text***', + description: 'Example use of markdown link', + }, + markdownCodeExample: { + id: 'example.application:markdownCodeExample#markdown', + defaultMessage: + 'Markdown code inline `const x = 123` with text\n\n Code block\n\n ```\n const x = 123\n if (x < 100) {\n return true\n }\n```', + description: 'Example use of markdown code', + }, }) diff --git a/libs/application/templates/reference-template/src/utils/options.ts b/libs/application/templates/reference-template/src/utils/options.ts new file mode 100644 index 000000000000..aa2dfca257a6 --- /dev/null +++ b/libs/application/templates/reference-template/src/utils/options.ts @@ -0,0 +1,14 @@ +export const checkboxOptions = [ + { + label: 'Checkbox 1', + value: 'checkbox1', + }, + { + label: 'Checkbox 2', + value: 'checkbox2', + }, + { + label: 'Checkbox 3', + value: 'checkbox3', + }, +] From 556b8c957d861610c644dfccf2de7a08508d168b Mon Sep 17 00:00:00 2001 From: Jonni Date: Thu, 7 Nov 2024 14:52:43 +0000 Subject: [PATCH 02/32] feat: showcare date, radio, checkbox, select --- .../src/assets/plate-110-510.tsx | 40 +++++++++++ .../src/assets/plate-155-305.tsx | 41 ++++++++++++ .../src/assets/plate-200-280.tsx | 40 +++++++++++ .../accordionSection/accordionSection.ts | 24 +++++++ .../src/forms/exampleForm/index.ts | 3 + .../repeaterSection/repeaterSection.ts | 7 ++ .../simpleInputsSection/checkboxSubsection.ts | 4 +- .../simpleInputsSection/dateSubsection.ts | 50 ++++++++++++-- .../simpleInputsSection/phoneSubsection.ts | 44 ++++++++++-- .../simpleInputsSection/radioSubsection.ts | 67 ++++++++++++++----- .../simpleInputsSection/selectSubsection.ts | 59 +++++++++++----- .../reference-template/src/utils/dateUtils.ts | 3 + .../reference-template/src/utils/options.ts | 54 +++++++++++++++ 13 files changed, 392 insertions(+), 44 deletions(-) create mode 100644 libs/application/templates/reference-template/src/assets/plate-110-510.tsx create mode 100644 libs/application/templates/reference-template/src/assets/plate-155-305.tsx create mode 100644 libs/application/templates/reference-template/src/assets/plate-200-280.tsx create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts create mode 100644 libs/application/templates/reference-template/src/utils/dateUtils.ts diff --git a/libs/application/templates/reference-template/src/assets/plate-110-510.tsx b/libs/application/templates/reference-template/src/assets/plate-110-510.tsx new file mode 100644 index 000000000000..0fb47c525126 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/plate-110-510.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react' + +export const plate110: FC> = () => ( + + + + + + + +) diff --git a/libs/application/templates/reference-template/src/assets/plate-155-305.tsx b/libs/application/templates/reference-template/src/assets/plate-155-305.tsx new file mode 100644 index 000000000000..c8a11270d8b8 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/plate-155-305.tsx @@ -0,0 +1,41 @@ +import { FC } from 'react' + +export const plate155: FC> = () => ( + + + + + + + +) diff --git a/libs/application/templates/reference-template/src/assets/plate-200-280.tsx b/libs/application/templates/reference-template/src/assets/plate-200-280.tsx new file mode 100644 index 000000000000..08bea6c5787b --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/plate-200-280.tsx @@ -0,0 +1,40 @@ +import { FC } from 'react' + +export const plate200: FC> = () => ( + + + + + + + +) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts new file mode 100644 index 000000000000..667128775ac3 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts @@ -0,0 +1,24 @@ +import { buildAccordionField, buildSection } from '@island.is/application/core' + +export const accordionSection = buildSection({ + id: 'accordion', + title: 'Accordion', + children: [ + buildAccordionField({ + id: 'accordion', + title: 'Accordion', + accordionItems: [ + { + itemTitle: 'Item 1', + itemContent: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.', + }, + { + itemTitle: 'Item 2', + itemContent: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + }, + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index b0d055e103da..4778dc786134 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -28,6 +28,7 @@ import { introSection } from './introSection/introSection' import { getDataFromExternalDataSection } from './getDataFromExternalDataSection/getDataFromExternalDataSection' import { simpleInputsSection } from './simpleInputsSection' import { descriptionSection } from './descriptionSection/descriptionSection' +import { accordionSection } from './accordionSection/accordionSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', @@ -38,6 +39,8 @@ export const ExampleForm: Form = buildForm({ getDataFromExternalDataSection, descriptionSection, simpleInputsSection, + accordionSection, + // repeterSection, buildSection({ id: 'tableRepeaterWithPhone', title: 'Table repeater', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts new file mode 100644 index 000000000000..bf9af9a93c25 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts @@ -0,0 +1,7 @@ +import { buildSection } from '@island.is/application/core' + +export const repeaterSection = buildSection({ + id: 'repeater', + title: 'Repeater', + children: [], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts index dd4c30b5b557..0cb98c321334 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts @@ -19,13 +19,13 @@ export const checkboxSubsection = buildSubSection({ options: checkboxOptions, // Importing options from utils makes the templatemuch more readable }), buildCheckboxField({ - id: 'checkbox', + id: 'checkboxHalf', title: 'Half width checkboxes', width: 'half', options: checkboxOptions, }), buildCheckboxField({ - id: 'checkbox', + id: 'checkboxHalfStrong', title: 'Half width strong checkboxes', width: 'half', strong: true, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts index 171a12e3c6de..d113c21aabda 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/dateSubsection.ts @@ -1,12 +1,54 @@ -import { buildDateField, buildSubSection } from '@island.is/application/core' +import { + buildDateField, + buildMultiField, + buildSubSection, +} from '@island.is/application/core' +import { minDate, maxDate } from '../../../utils/dateUtils' export const dateSubsection = buildSubSection({ id: 'date', title: 'Date', children: [ - buildDateField({ - id: 'date', - title: 'Date', + buildMultiField({ + id: 'dateMultiField', + title: 'Date fields', + children: [ + buildDateField({ + id: 'date', + title: 'Regular datepicker', + }), + buildDateField({ + id: 'halfDate', + title: 'Half datepicker', + width: 'half', + }), + buildDateField({ + id: 'minAndMaxDate', + title: 'Min and max dates datepicker', + width: 'half', + minDate: minDate, + maxDate: maxDate, + }), + buildDateField({ + id: 'whiteDate', + title: 'White datepicker (try to use blue if possible)', + width: 'half', + backgroundColor: 'white', + }), + buildDateField({ + id: 'placeholderDate', + title: 'Placeholder datepicker', + placeholder: 'Select a date', + width: 'half', + }), + buildDateField({ + id: 'readOnlyDate', + title: 'Readonly datepicker', + width: 'half', + readOnly: true, + defaultValue: '2024-01-01', + }), + ], }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts index c0015f970fc7..d3946b41a517 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/phoneSubsection.ts @@ -1,12 +1,48 @@ -import { buildPhoneField, buildSubSection } from '@island.is/application/core' +import { + buildMultiField, + buildPhoneField, + buildSubSection, +} from '@island.is/application/core' export const phoneSubsection = buildSubSection({ id: 'phone', title: 'Phone', children: [ - buildPhoneField({ - id: 'phone', - title: 'Phone', + buildMultiField({ + id: 'phoneMultiField', + title: 'Phone fields', + children: [ + buildPhoneField({ + id: 'phone', + title: 'Regular', + }), + buildPhoneField({ + id: 'halfPhone', + title: 'Half', + width: 'half', + }), + buildPhoneField({ + id: 'whitePhone', + title: 'White (try to use blue if possible)', + backgroundColor: 'white', + }), + buildPhoneField({ + id: 'placeholderPhone', + title: 'Placeholder', + placeholder: 'Enter your phone number', + }), + buildPhoneField({ + id: 'countrySelectPhone', + title: 'Country select', + enableCountrySelector: true, + }), + buildPhoneField({ + id: 'countrySelectOnlyAllowedPhone', + title: 'Limited country select', + enableCountrySelector: true, + allowedCountryCodes: ['IS', 'IM', 'VC', 'AI', 'AW'], + }), + ], }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts index c4be420a0195..9a64349466b6 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/radioSubsection.ts @@ -1,25 +1,58 @@ -import { buildRadioField, buildSubSection } from '@island.is/application/core' +import { + buildMultiField, + buildRadioField, + buildSubSection, +} from '@island.is/application/core' +import { + defaultRadioOption, + radioIllustrationOptions, + radioOptions, +} from '../../../utils/options' export const radioSubsection = buildSubSection({ id: 'radio', title: 'Radio', children: [ - buildRadioField({ - id: 'radio', - title: 'Radio', - options: [ - { - label: 'Radio 1', - value: 'radio1', - }, - { - label: 'Radio 2', - value: 'radio2', - }, - { - label: 'Radio 3', - value: 'radio3', - }, + buildMultiField({ + id: 'radioMultiField', + title: 'Radio fields', + children: [ + buildRadioField({ + id: 'radio', + title: 'Full width radio', + options: radioOptions, + }), + buildRadioField({ + id: 'halfRadio', + title: 'Half width radio', + width: 'half', + options: radioOptions, + }), + buildRadioField({ + id: 'smallButtonsRadio', + title: 'Small radio buttons', + options: radioOptions, + largeButtons: false, + }), + buildRadioField({ + id: 'radioIllustrations', + title: 'Radio with illustrations', + options: radioIllustrationOptions, + widthWithIllustration: '1/3', + hasIllustration: true, + }), + buildRadioField({ + id: 'defaultRadio', + title: 'Radio with a default value', + options: radioOptions, + defaultValue: defaultRadioOption, + }), + buildRadioField({ + id: 'WhiteBackgroundRadio', + title: 'White background (try to use blue if possible)', + options: radioOptions, + backgroundColor: 'white', + }), ], }), ], diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts index a46b13ddcf1d..b781ab57a7e7 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/selectSubsection.ts @@ -1,25 +1,50 @@ -import { buildSelectField, buildSubSection } from '@island.is/application/core' +import { + buildMultiField, + buildSelectField, + buildSubSection, +} from '@island.is/application/core' +import { selectOptions } from '../../../utils/options' +import { title } from 'process' export const selectSubsection = buildSubSection({ id: 'select', title: 'Select', children: [ - buildSelectField({ - id: 'select', - title: 'Select', - options: [ - { - label: 'Select 1', - value: 'select1', - }, - { - label: 'Select 2', - value: 'select2', - }, - { - label: 'Select 3', - value: 'select3', - }, + buildMultiField({ + id: 'selectMultiField', + title: 'Select fields', + children: [ + buildSelectField({ + id: 'select', + title: 'Regular select', + options: selectOptions, + }), + buildSelectField({ + id: 'halfSelect', + title: 'Half select', + options: selectOptions, + width: 'half', + }), + buildSelectField({ + id: 'whiteSelect', + title: 'White (try to use blue if possible)', + options: selectOptions, + width: 'half', + backgroundColor: 'white', + }), + buildSelectField({ + id: 'placeholderSelect', + title: 'Placeholder select', + options: selectOptions, + placeholder: 'Select an option', + width: 'half', + }), + buildSelectField({ + id: 'multiSelect', + title: 'Multi select', + options: selectOptions, + isMulti: true, + }), ], }), ], diff --git a/libs/application/templates/reference-template/src/utils/dateUtils.ts b/libs/application/templates/reference-template/src/utils/dateUtils.ts new file mode 100644 index 000000000000..5b2eee38976b --- /dev/null +++ b/libs/application/templates/reference-template/src/utils/dateUtils.ts @@ -0,0 +1,3 @@ +export const oneDayInMs = 24 * 60 * 60 * 1000 +export const minDate = new Date(Date.now() - 3 * oneDayInMs) // Three days ago +export const maxDate = new Date(Date.now() + 3 * oneDayInMs) // Three days from now diff --git a/libs/application/templates/reference-template/src/utils/options.ts b/libs/application/templates/reference-template/src/utils/options.ts index aa2dfca257a6..cdb78dfdd452 100644 --- a/libs/application/templates/reference-template/src/utils/options.ts +++ b/libs/application/templates/reference-template/src/utils/options.ts @@ -1,3 +1,7 @@ +import { plate110 } from '../assets/plate-110-510' +import { plate200 } from '../assets/plate-200-280' +import { plate155 } from '../assets/plate-155-305' + export const checkboxOptions = [ { label: 'Checkbox 1', @@ -12,3 +16,53 @@ export const checkboxOptions = [ value: 'checkbox3', }, ] + +export const radioOptions = [ + { + label: 'Radio 1', + value: 'radio1', + }, + { + label: 'Radio 2', + value: 'radio2', + }, + { + label: 'Radio 3', + value: 'radio3', + }, +] + +export const defaultRadioOption = 'radio2' + +export const radioIllustrationOptions = [ + { + label: 'Radio 1', + value: 'radio1', + illustration: plate110, + }, + { + label: 'Radio 2', + value: 'radio2', + illustration: plate200, + }, + { + label: 'Radio 3', + value: 'radio3', + illustration: plate155, + }, +] + +export const selectOptions = [ + { + label: 'Select 1', + value: 'select1', + }, + { + label: 'Select 2', + value: 'select2', + }, + { + label: 'Select 3', + value: 'select3', + }, +] From 5432a137ff63cb2d4aa68288b5a0b916c0eafe6c Mon Sep 17 00:00:00 2001 From: Jonni Date: Fri, 8 Nov 2024 16:20:23 +0000 Subject: [PATCH 03/32] feat: more fields added to reference template --- .../application/core/src/lib/fieldBuilders.ts | 18 +- .../forms/FundingGovernmentProjectsForm.ts | 1 + .../src/forms/ParentalLeaveForm.ts | 3 + .../src/assets/akureyri.svg | 157 +++++++++++ .../src/assets/isafjardarbaer.svg | 12 + .../src/assets/sambandid.svg | 6 + .../src/components/Logo/Logo.tsx | 34 +++ .../src/components/README.md | 2 +- .../actionCardSection/actionCardSection.ts | 64 +++++ .../applicantInfoSubsection.ts | 9 + .../compositeFieldsSection/index.ts | 9 + .../nationalIdWithNameSubsection.ts | 15 ++ .../dividerSection/dividerSection.ts | 26 ++ .../src/forms/exampleForm/index.ts | 251 ++---------------- .../keyValueSection/keyValueSection.ts | 43 +++ .../repeaterSection/repeaterSection.ts | 7 - .../asyncSelectSubsection.ts | 78 ++++++ .../companySearchSubsection.ts | 33 +++ .../exampleForm/simpleInputsSection/index.ts | 6 + .../simpleInputsSection/sliderSubsection.ts | 134 ++++++++++ .../staticTableSection/StaticTableSection.ts | 48 ++++ .../tableRepeaterSection.ts | 73 +++++ .../prerequisitesForm/prerequisitesForm.ts | 15 +- .../src/graphql/sampleQuery.ts | 18 ++ .../reference-template/src/utils/types.ts | 24 ++ libs/application/types/src/lib/Fields.ts | 1 + .../lib/SelectFormField/SelectFormField.tsx | 1 - .../SliderFormField.stories.mdx | 2 + .../lib/SliderFormField/SliderFormField.tsx | 124 +++++---- 29 files changed, 917 insertions(+), 297 deletions(-) create mode 100644 libs/application/templates/reference-template/src/assets/akureyri.svg create mode 100644 libs/application/templates/reference-template/src/assets/isafjardarbaer.svg create mode 100644 libs/application/templates/reference-template/src/assets/sambandid.svg create mode 100644 libs/application/templates/reference-template/src/components/Logo/Logo.tsx create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/applicantInfoSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/nationalIdWithNameSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts delete mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/companySearchSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/sliderSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts create mode 100644 libs/application/templates/reference-template/src/graphql/sampleQuery.ts create mode 100644 libs/application/templates/reference-template/src/utils/types.ts diff --git a/libs/application/core/src/lib/fieldBuilders.ts b/libs/application/core/src/lib/fieldBuilders.ts index dabe437861a0..c6fce7cb6602 100644 --- a/libs/application/core/src/lib/fieldBuilders.ts +++ b/libs/application/core/src/lib/fieldBuilders.ts @@ -615,6 +615,7 @@ export const buildExpandableDescriptionField = ( component: FieldComponents.EXPANDABLE_DESCRIPTION, } } + export const buildAlertMessageField = ( data: Omit, ): AlertMessageField => { @@ -958,9 +959,12 @@ export const buildStaticTableField = ( } export const buildSliderField = ( - data: Omit, + data: Omit, ): SliderField => { const { + id, + title, + titleVariant = 'h2', condition, min = 0, max = 10, @@ -968,26 +972,27 @@ export const buildSliderField = ( snap = true, trackStyle, calculateCellStyle, - showLabel = false, - showMinMaxLabels = false, showRemainderOverlay = true, showProgressOverlay = true, showToolTip = false, label, + showLabel = false, + showMinMaxLabels = false, rangeDates, currentIndex, onChange, onChangeEnd, labelMultiplier = 1, - id, saveAsString, } = data return { - title: '', + component: FieldComponents.SLIDER, id, + title, + titleVariant, + condition, children: undefined, type: FieldTypes.SLIDER, - component: FieldComponents.SLIDER, min, max, step, @@ -1005,7 +1010,6 @@ export const buildSliderField = ( onChange, onChangeEnd, labelMultiplier, - condition, saveAsString, } } diff --git a/libs/application/templates/funding-government-projects/src/forms/FundingGovernmentProjectsForm.ts b/libs/application/templates/funding-government-projects/src/forms/FundingGovernmentProjectsForm.ts index 2b5ffa9d68f6..126b4f812e12 100644 --- a/libs/application/templates/funding-government-projects/src/forms/FundingGovernmentProjectsForm.ts +++ b/libs/application/templates/funding-government-projects/src/forms/FundingGovernmentProjectsForm.ts @@ -123,6 +123,7 @@ export const FundingGovernmentProjectsForm: Form = buildForm({ }), buildSliderField({ id: 'project.refundableYears', + title: '', label: { singular: shared.yearSingular, plural: shared.yearPlural, diff --git a/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts b/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts index 6272df76192c..1ea7f6cdf6ec 100644 --- a/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts +++ b/libs/application/templates/parental-leave/src/forms/ParentalLeaveForm.ts @@ -1223,6 +1223,7 @@ export const ParentalLeaveForm: Form = buildForm({ children: [ buildSliderField({ id: 'multipleBirthsRequestDays', + title: '', label: { singular: parentalLeaveFormMessages.shared.day, plural: parentalLeaveFormMessages.shared.days, @@ -1317,6 +1318,7 @@ export const ParentalLeaveForm: Form = buildForm({ children: [ buildSliderField({ id: 'requestRights.requestDays', + title: '', label: { singular: parentalLeaveFormMessages.shared.day, plural: parentalLeaveFormMessages.shared.days, @@ -1365,6 +1367,7 @@ export const ParentalLeaveForm: Form = buildForm({ children: [ buildSliderField({ id: 'giveRights.giveDays', + title: '', label: { singular: parentalLeaveFormMessages.shared.day, plural: parentalLeaveFormMessages.shared.days, diff --git a/libs/application/templates/reference-template/src/assets/akureyri.svg b/libs/application/templates/reference-template/src/assets/akureyri.svg new file mode 100644 index 000000000000..1ad88a2af433 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/akureyri.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/application/templates/reference-template/src/assets/isafjardarbaer.svg b/libs/application/templates/reference-template/src/assets/isafjardarbaer.svg new file mode 100644 index 000000000000..5ec71102e333 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/isafjardarbaer.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/libs/application/templates/reference-template/src/assets/sambandid.svg b/libs/application/templates/reference-template/src/assets/sambandid.svg new file mode 100644 index 000000000000..a88407920cb4 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/sambandid.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/libs/application/templates/reference-template/src/components/Logo/Logo.tsx b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx new file mode 100644 index 000000000000..9863b06d98c7 --- /dev/null +++ b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx @@ -0,0 +1,34 @@ +import { useEffect, useState } from 'react' +import { Application } from '@island.is/application/types' +import { getValueViaPath } from '@island.is/application/core' + +type Props = { + application: Application +} + +// In the prereq when there is no applicant, the logo is the default one. +// When there is an applicant, the logo is dynamic based on the applicant's identity number. +// Gervimaður Færeyjar shows the logo of Ísafjarðarbær and all others show the logo of Akureyri. +export const Logo = ({ application }: Props) => { + const [logo, setLogo] = useState() + + useEffect(() => { + const getLogo = async () => { + console.log(application) + + const applicant = application.applicant + + const town = !applicant + ? 'sambandid' + : applicant === '0101302399' + ? 'isafjardarbaer' + : 'akureyri' + + const svgLogo = await import(`../../assets/${town}.svg`) + setLogo(svgLogo.default) + } + getLogo() + }, []) + + return Municipality logo +} diff --git a/libs/application/templates/reference-template/src/components/README.md b/libs/application/templates/reference-template/src/components/README.md index f51286858e87..6b3d80449453 100644 --- a/libs/application/templates/reference-template/src/components/README.md +++ b/libs/application/templates/reference-template/src/components/README.md @@ -1,3 +1,3 @@ # The components folder -This folder contains all React components that are not custom components on their own but are used by custom components. +This folder contains all React components that are not custom components on their own but are used by custom components or a component for the form logo if it is dynamic. diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts new file mode 100644 index 000000000000..bc10363a4a54 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts @@ -0,0 +1,64 @@ +import { + buildSection, + buildActionCardListField, +} from '@island.is/application/core' + +export const actionCardSection = buildSection({ + id: 'actionCardSection', + title: 'Action card', + children: [ + buildActionCardListField({ + id: 'actionCardList', + title: 'Action card list', + items: (application, lang) => { + return [ + { + eyebrow: 'Card eyebrow', + heading: 'Card heading, all the options', + headingVariant: 'h3', + text: 'Card text, lorem ipsum dolor sit amet dolor sit amet lorem ipsum dolor sit amet', + cta: { + label: 'Card cta', + variant: 'primary', + external: true, + to: 'https://www.google.com', + }, + tag: { + label: 'Outlined label', + outlined: true, + variant: 'blue', + }, + }, + { + heading: 'Card heading', + headingVariant: 'h4', + tag: { + label: 'Not outlined label', + outlined: false, + variant: 'blue', + }, + cta: { + label: 'Card cta', + variant: 'primary', + external: true, + to: 'https://www.google.com', + }, + unavailable: { + label: 'Unavailable label', + message: 'Unavailable message', + }, + }, + { + heading: 'Card heading', + headingVariant: 'h4', + tag: { + label: 'White label', + outlined: true, + variant: 'white', + }, + }, + ] + }, + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/applicantInfoSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/applicantInfoSubsection.ts new file mode 100644 index 000000000000..7f157f065962 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/applicantInfoSubsection.ts @@ -0,0 +1,9 @@ +import { buildSubSection } from '@island.is/application/core' +import { applicantInformationMultiField } from '@island.is/application/ui-forms' + +export const applicantInfoSubsection = buildSubSection({ + id: 'aplicantInfoSubsection', + title: 'Aplicant Info Subsection', + // Common form, fills automatically with applicant information + children: [applicantInformationMultiField()], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts new file mode 100644 index 000000000000..ac5b7bafc63f --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts @@ -0,0 +1,9 @@ +import { buildSection } from '@island.is/application/core' +import { nationalIdWithNameSubsection } from './nationalIdWithNameSubsection' +import { applicantInfoSubsection } from './applicantInfoSubsection' + +export const compositeFieldsSection = buildSection({ + id: 'compositeFieldsSection', + title: 'Composite fields', + children: [nationalIdWithNameSubsection, applicantInfoSubsection], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/nationalIdWithNameSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/nationalIdWithNameSubsection.ts new file mode 100644 index 000000000000..3e86de1f4078 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/nationalIdWithNameSubsection.ts @@ -0,0 +1,15 @@ +import { + buildNationalIdWithNameField, + buildSubSection, +} from '@island.is/application/core' + +export const nationalIdWithNameSubsection = buildSubSection({ + id: 'nationalIdWithNameSubsection', + title: 'National ID with name subsection', + children: [ + buildNationalIdWithNameField({ + id: 'pickRole.electPerson', + title: 'Lookup name by national ID', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts new file mode 100644 index 000000000000..f41df687c25f --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts @@ -0,0 +1,26 @@ +import { + buildDividerField, + buildMultiField, + buildSection, +} from '@island.is/application/core' +import { Colors } from '@island.is/island-ui/theme' + +export const dividerSection = buildSection({ + id: 'dividerSection', + title: 'Divider', + children: [ + buildMultiField({ + id: 'dividerMultiField', + title: 'Divider', + children: [ + buildDividerField({}), + buildDividerField({ + title: 'Divider with title', + }), + buildDividerField({ + color: 'red600', + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 4778dc786134..181852b03871 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -1,27 +1,12 @@ import { - buildCheckboxField, buildForm, buildDescriptionField, buildMultiField, - buildRadioField, buildSection, buildSubmitField, - buildSubSection, - buildTextField, - buildFileUploadField, buildRedirectToServicePortalField, - buildSelectField, - buildPhoneField, - buildHiddenInput, - buildHiddenInputWithWatchedValue, - buildTableRepeaterField, } from '@island.is/application/core' -import { - Comparators, - Form, - FormModes, - FormValue, -} from '@island.is/application/types' +import { Application, Form, FormModes } from '@island.is/application/types' import { m } from '../../lib/messages' import { ApiActions } from '../../shared' import { introSection } from './introSection/introSection' @@ -29,230 +14,36 @@ import { getDataFromExternalDataSection } from './getDataFromExternalDataSection import { simpleInputsSection } from './simpleInputsSection' import { descriptionSection } from './descriptionSection/descriptionSection' import { accordionSection } from './accordionSection/accordionSection' - +import { tableRepeaterSection } from './tableRepeaterSection/tableRepeaterSection' +import { staticTableSection } from './staticTableSection/StaticTableSection' +import { actionCardSection } from './actionCardSection/actionCardSection' +import { compositeFieldsSection } from './compositeFieldsSection' +import { createElement } from 'react' +import { Logo } from '../../components/Logo/Logo' +import { dividerSection } from './dividerSection/dividerSection' +import { keyValueSection } from './keyValueSection/keyValueSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', title: 'Main form', mode: FormModes.DRAFT, + // The logo prop can either take in a React component or a function that returns a React component. + // Dynamic logo can be based on answers or external data + logo: (application: Application) => { + const logo = createElement(Logo, { application }) + return () => logo + }, children: [ introSection, getDataFromExternalDataSection, descriptionSection, + dividerSection, simpleInputsSection, + compositeFieldsSection, accordionSection, - // repeterSection, - buildSection({ - id: 'tableRepeaterWithPhone', - title: 'Table repeater', - children: [ - buildTableRepeaterField({ - id: 'rentalHousingLandlordInfoTable', - title: '', - marginTop: 1, - fields: { - name: { - component: 'input', - label: 'test 1', - width: 'half', - }, - nationalId: { - component: 'input', - label: 'test 2', - format: '######-####', - width: 'half', - }, - phone: { - component: 'phone', - label: 'test 3', - format: '###-####', - width: 'half', - }, - email: { - component: 'input', - label: 'test 4', - type: 'email', - width: 'half', - }, - isRepresentative: { - component: 'checkbox', - large: true, - displayInTable: false, - label: 'test 5', - options: [ - { - label: 'test 6', - value: 'YES', - }, - ], - }, - }, - table: { - header: [ - 'nameInputLabel', - 'nationalIdHeaderLabel', - 'phoneInputLabel', - 'emailInputLabel', - ], - }, - }), - ], - }), - buildSection({ - id: 'intro', - title: m.introSection, - children: [ - buildMultiField({ - id: 'about', - title: m.about.defaultMessage, - children: [ - buildTextField({ - id: 'person.name', - title: m.personName, - }), - buildHiddenInput({ - id: 'person.someHiddenInputRequired', - defaultValue: () => { - return 'validAnswer' - }, - }), - buildHiddenInputWithWatchedValue({ - id: 'person.someHiddenInputWatchedRequired', - watchValue: 'person.name', - valueModifier: (watchedValue: any) => { - return watchedValue + 'Valid' - }, - }), - buildTextField({ - id: 'person.nationalId', - title: m.nationalId, - width: 'half', - }), - buildTextField({ - id: 'person.age', - title: m.age, - width: 'half', - }), - buildTextField({ - id: 'person.email', - title: m.email, - width: 'half', - }), - buildPhoneField({ - id: 'person.phoneNumber', - title: m.phoneNumber, - width: 'half', - condition: { - questionId: 'person.age', - isMultiCheck: false, - comparator: Comparators.GTE, - value: '18', - }, - }), - ], - }), - buildFileUploadField({ - id: 'attachments', - title: (application, locale) => { - if (locale === 'is') { - return 'Viðhengi' - } - return 'Attachments' - }, - introduction: 'Hér getur þú bætt við viðhengjum við umsóknina þína.', - uploadMultiple: true, - }), - ], - }), - buildSection({ - id: 'career', - title: m.career, - children: [ - buildSubSection({ - id: 'history', - title: m.history, - children: [ - buildSelectField({ - id: 'careerIndustry', - title: m.careerIndustry, - description: m.careerIndustryDescription, - required: true, - options: (options, application, locale) => { - if (locale === 'is') { - return [ - { label: locale, value: locale }, - { label: 'Hugbúnaður', value: 'software' }, - { label: 'Fjármál', value: 'finance' }, - { label: 'Efnahagsráðgjöf', value: 'consulting' }, - { label: 'Önnur', value: 'other' }, - ] - } - return [ - { label: locale, value: locale }, - { label: 'Software', value: 'software' }, - { label: 'Finance', value: 'finance' }, - { label: 'Consulting', value: 'consulting' }, - { label: 'Other', value: 'other' }, - ] - }, - }), - buildRadioField({ - id: 'careerHistory', - title: m.careerHistory, - options: [ - { value: 'yes', label: m.yesOptionLabel }, - { value: 'no', label: m.noOptionLabel }, - ], - condition: (formValue: FormValue) => { - return ( - (formValue as { person: { age: string } })?.person?.age >= - '18' - ) - }, - }), - buildMultiField({ - id: 'careerHistoryDetails', - title: '', - children: [ - buildCheckboxField({ - id: 'careerHistoryDetails.careerHistoryCompanies', - title: m.careerHistoryCompanies, - options: [ - { value: 'government', label: m.governmentOptionLabel }, - { value: 'aranja', label: 'Aranja' }, - { value: 'advania', label: 'Advania' }, - { value: 'other', label: 'Annað' }, - ], - }), - buildTextField({ - id: 'careerHistoryDetails.careerHistoryOther', - title: m.careerHistoryOther, - }), - ], - }), - ], - }), - buildSubSection({ - id: 'future', - title: m.future, - children: [ - buildTextField({ - id: 'dreamJob', - title: m.dreamJob, - }), - ], - }), - buildSubSection({ - id: 'assignee', - title: m.assigneeTitle, - children: [ - buildTextField({ - id: 'assigneeEmail', - title: m.assignee, - }), - ], - }), - ], - }), + tableRepeaterSection, + staticTableSection, + actionCardSection, + keyValueSection, buildSection({ id: 'confirmation', title: 'Staðfesta', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts new file mode 100644 index 000000000000..c296787626a4 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts @@ -0,0 +1,43 @@ +import { buildSection, buildKeyValueField } from '@island.is/application/core' +import { buildMultiField } from 'libs/application/core/src/lib/formBuilders' + +export const keyValueSection = buildSection({ + id: 'keyValueSection', + title: 'Key-Value', + children: [ + buildMultiField({ + id: 'keyValueMultiField', + title: 'Key-Value', + children: [ + buildKeyValueField({ + label: 'Key value label', + value: 'One value', + }), + buildKeyValueField({ + label: 'Key value with divider', + value: ['Many values', 'Value 2', 'Value 3'], + divider: true, + }), + buildKeyValueField({ + label: 'Key value displax flex', + value: ['Value', 'Value 2', 'Value 3'], + divider: true, + display: 'flex', + }), + buildKeyValueField({ + label: 'Key value half width', + value: 'One value', + divider: true, + width: 'half', + }), + buildKeyValueField({ + label: 'Key value half width', + value: 'Custom colspan', + divider: true, + width: 'half', + colSpan: '5/12', + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts deleted file mode 100644 index bf9af9a93c25..000000000000 --- a/libs/application/templates/reference-template/src/forms/exampleForm/repeaterSection/repeaterSection.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { buildSection } from '@island.is/application/core' - -export const repeaterSection = buildSection({ - id: 'repeater', - title: 'Repeater', - children: [], -}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts new file mode 100644 index 000000000000..e49e3064e68a --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts @@ -0,0 +1,78 @@ +import { buildAsyncSelectField } from '@island.is/application/core' +import { Context, Option } from '@island.is/application/types' +import { + buildMultiField, + buildSubSection, +} from 'libs/application/core/src/lib/formBuilders' +import { FriggSchoolsByMunicipality } from '../../../utils/types' +import { friggSchoolsByMunicipalityQuery } from '../../../graphql/sampleQuery' + +export const asyncSelectSubsection = buildSubSection({ + id: 'asyncSelectSubsection', + title: 'Async Select Subsection', + children: [ + buildMultiField({ + id: 'asyncSelectMultiField', + title: 'Async Select', + children: [ + buildAsyncSelectField({ + id: 'asyncSelect', + title: 'Async Select', + placeholder: 'Placeholder text', + loadingError: 'Loading error', + loadOptions: async ({ apolloClient }) => { + const { data } = + await apolloClient.query({ + query: friggSchoolsByMunicipalityQuery, + }) + + return ( + data?.friggSchoolsByMunicipality?.map((municipality) => ({ + value: municipality.name, + label: municipality.name, + })) ?? [] + ) + }, + }), + buildAsyncSelectField({ + id: 'asyncSelectSearchable', + title: 'Async Select Searchable', + isSearchable: true, + loadingError: 'Loading error', + loadOptions: async ({ apolloClient }) => { + const { data } = + await apolloClient.query({ + query: friggSchoolsByMunicipalityQuery, + }) + + return ( + data?.friggSchoolsByMunicipality?.map((municipality) => ({ + value: municipality.name, + label: municipality.name, + })) ?? [] + ) + }, + }), + buildAsyncSelectField({ + id: 'asyncSelectMulti', + title: 'Async Select Multi select', + isMulti: true, + loadingError: 'Loading error', + loadOptions: async ({ apolloClient }) => { + const { data } = + await apolloClient.query({ + query: friggSchoolsByMunicipalityQuery, + }) + + return ( + data?.friggSchoolsByMunicipality?.map((municipality) => ({ + value: municipality.name, + label: municipality.name, + })) ?? [] + ) + }, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/companySearchSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/companySearchSubsection.ts new file mode 100644 index 000000000000..8376800ce7f6 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/companySearchSubsection.ts @@ -0,0 +1,33 @@ +import { + buildCompanySearchField, + buildMultiField, + buildSubSection, +} from '@island.is/application/core' + +export const companySearchSubsection = buildSubSection({ + id: 'companySearchSubsection', + title: 'Company Search Subsection', + children: [ + buildMultiField({ + id: 'companySearchMultiField', + title: 'Company Search MultiField', + children: [ + buildCompanySearchField({ + id: 'companySearch', + title: 'Company Search', + placeholder: 'Search for a company', + }), + buildCompanySearchField({ + id: 'companySearchShouldIncludeIsatNumber', + title: 'Company Search Should include ISAT number', + shouldIncludeIsatNumber: true, + }), + buildCompanySearchField({ + id: 'companySearchCheckIfEmployerIsOnForbiddenList', + title: 'Company Search Check if employer is on forbidden list', + checkIfEmployerIsOnForbiddenList: true, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts index 2324826cc486..180a28ea74f0 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts @@ -6,6 +6,9 @@ import { selectSubsection } from './selectSubsection' import { phoneSubsection } from './phoneSubsection' import { dateSubsection } from './dateSubsection' import { fileUploadSubsection } from './fileUploadSubsection' +import { sliderSubsection } from './sliderSubsection' +import { companySearchSubsection } from './companySearchSubsection' +import { asyncSelectSubsection } from './asyncSelectSubsection' export const simpleInputsSection = buildSection({ id: 'simpleInputsSection', @@ -15,8 +18,11 @@ export const simpleInputsSection = buildSection({ checkboxSubsection, radioSubsection, selectSubsection, + asyncSelectSubsection, + companySearchSubsection, phoneSubsection, dateSubsection, fileUploadSubsection, + sliderSubsection, ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/sliderSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/sliderSubsection.ts new file mode 100644 index 000000000000..80cf17ab9c6c --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/sliderSubsection.ts @@ -0,0 +1,134 @@ +import { + buildMultiField, + buildSliderField, + buildSubSection, +} from '@island.is/application/core' + +export const sliderSubsection = buildSubSection({ + id: 'sliderSubsection', + title: 'Slider Field', + children: [ + buildMultiField({ + id: 'slider', + title: '', + children: [ + buildSliderField({ + id: 'basicSlider', + title: 'Basic slider', + min: 1, + max: 10, + trackStyle: { gridTemplateRows: 5 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + label: { + singular: 'day', + plural: 'days', + }, + }), + buildSliderField({ + id: 'basicSliderWithLabels', + title: 'Slider with labels', + min: 1, + max: 10, + trackStyle: { gridTemplateRows: 5 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + label: { + singular: 'day', + plural: 'days', + }, + showMinMaxLabels: true, + showLabel: true, + showToolTip: true, + }), + buildSliderField({ + id: 'basicSliderWithProgressOverlay', + title: 'Slider with progress overlay', + min: 1, + max: 10, + trackStyle: { gridTemplateRows: 5 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + label: { + singular: 'day', + plural: 'days', + }, + showRemainderOverlay: true, + showProgressOverlay: true, + }), + buildSliderField({ + id: 'basicSliderRangeDates', + title: 'Slider with range dates', + min: 1, + max: 10, + trackStyle: { gridTemplateRows: 5 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + label: { + singular: 'day', + plural: 'days', + }, + rangeDates: { + start: { + date: '2024-01-01', + message: 'Start date', + }, + end: { + date: '2024-01-10', + message: 'End date', + }, + }, + showToolTip: true, + }), + buildSliderField({ + id: 'basicSliderWithSteps', + title: 'Slider with steps', + min: 1, + max: 10, + step: 2, + trackStyle: { gridTemplateRows: 5 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + label: { + singular: 'day', + plural: 'days', + }, + }), + + buildSliderField({ + id: 'thickSlider', + title: 'Thick slider', + min: 0, + max: 100, + step: 1, + label: { + singular: 'day', + plural: 'days', + }, + defaultValue: 5, + trackStyle: { gridTemplateRows: 200 }, + calculateCellStyle: () => { + return { + background: 'ccccd8', + } + }, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts new file mode 100644 index 000000000000..2661ca6e5766 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts @@ -0,0 +1,48 @@ +import { + buildSection, + buildStaticTableField, +} from '@island.is/application/core' + +export const staticTableSection = buildSection({ + id: 'staticTableSection', + title: 'Static table', + children: [ + buildStaticTableField({ + title: 'Static table', + // Header, rows and summary can also be functions that access external data or answers + header: [ + 'Table heading 1', + 'Table heading 2', + 'Table heading 3', + 'Table heading 4', + ], + rows: [ + [ + 'Row 1, Column 1', + 'Row 1, Column 2', + 'Row 1, Column 3', + 'Row 1, Column 4', + ], + [ + 'Row 2, Column 1', + 'Row 2, Column 2', + 'Row 2, Column 3', + 'Row 2, Column 4', + ], + [ + 'Row 3, Column 1', + 'Row 3, Column 2', + 'Row 3, Column 3', + 'Row 3, Column 4', + ], + ], + // Summary is optional + summary: [ + { + label: 'Summary label', + value: 'Summary value', + }, + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts new file mode 100644 index 000000000000..936f79feaeb6 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts @@ -0,0 +1,73 @@ +import { + buildSection, + buildTableRepeaterField, +} from '@island.is/application/core' +import { selectOptions } from '../../../utils/options' + +export const tableRepeaterSection = buildSection({ + id: 'repeater', + title: 'Table Repeater', + children: [ + buildTableRepeaterField({ + id: 'tableRepeater', + title: 'Table Repeater Field', + formTitle: 'Table Repeater Form Title', // Todo: doesn't work + addItemButtonText: 'Custom Add item text', + saveItemButtonText: 'Custom Save item text', + removeButtonTooltipText: 'Custom Remove item text', + editButtonTooltipText: 'Custom Edit item text', + editField: true, + maxRows: 10, + getStaticTableData: (_application) => { + // Possibility to populate the table with data from the answers or external data + // Populated data will not be editable or deletable + return [ + { + fullName: 'John Doe', + nationalId: '000000-0000', + relation: 'select1', + }, + { + fullName: 'Jane Doe', + nationalId: '000000-0001', + relation: 'select2', + }, + ] + }, + // Possible fields: input, select, radio, checkbox, date, nationalIdWithName + fields: { + fullName: { + component: 'input', + label: 'Input label', + width: 'half', + type: 'text', + dataTestId: 'sibling-full-name', + }, + nationalId: { + component: 'input', + label: 'National ID label', + width: 'half', + type: 'text', + format: '######-####', + placeholder: '000000-0000', + dataTestId: 'sibling-national-id', + }, + relation: { + component: 'select', + label: 'Select label', + placeholder: 'Select placeholder', + options: selectOptions, + dataTestId: 'sibling-relation', + }, + }, + table: { + // Format values for display in the table + format: { + fullName: (value) => `${value} - custom format`, + }, + // Overwrite header for the table. If not provided, the labels from the fields will be used + header: ['Full name', 'National ID', 'Relation'], + }, + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts index f4b241da84f1..b57d83e26973 100644 --- a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts +++ b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts @@ -6,18 +6,31 @@ import { buildSubmitField, coreMessages, } from '@island.is/application/core' -import { DefaultEvents, Form, FormModes } from '@island.is/application/types' +import { + Application, + DefaultEvents, + Form, + FormModes, +} from '@island.is/application/types' import { UserProfileApi } from '@island.is/application/types' import { ReferenceDataApi, MyMockProvider, NationalRegistryApi, } from '../../dataProviders' +import { createElement } from 'react' +import { Logo } from '../../components/Logo/Logo' export const Prerequisites: Form = buildForm({ id: 'PrerequisitesDraft', title: 'Forkröfur', mode: FormModes.NOT_STARTED, + // The logo prop can either take in a React component or a function that returns a React component. + // Dynamic logo can be based on answers or external data + logo: (application: Application) => { + const logo = createElement(Logo, { application }) + return () => logo + }, renderLastScreenButton: true, children: [ buildSection({ diff --git a/libs/application/templates/reference-template/src/graphql/sampleQuery.ts b/libs/application/templates/reference-template/src/graphql/sampleQuery.ts new file mode 100644 index 000000000000..ff815976888a --- /dev/null +++ b/libs/application/templates/reference-template/src/graphql/sampleQuery.ts @@ -0,0 +1,18 @@ +import gql from 'graphql-tag' +export const friggSchoolsByMunicipalityQuery = gql` + query FriggSchoolsByMunicipality { + friggSchoolsByMunicipality { + id + nationalId + name + type + children { + id + nationalId + name + type + gradeLevels + } + } + } +` diff --git a/libs/application/templates/reference-template/src/utils/types.ts b/libs/application/templates/reference-template/src/utils/types.ts new file mode 100644 index 000000000000..b2ca863d7e12 --- /dev/null +++ b/libs/application/templates/reference-template/src/utils/types.ts @@ -0,0 +1,24 @@ +export enum OrganizationModelTypeEnum { + Municipality = 'Municipality', + National = 'National', + School = 'School', +} + +export type FriggSchoolsByMunicipality = { + __typename?: 'Query' + friggSchoolsByMunicipality?: Array<{ + __typename?: 'EducationFriggOrganizationModel' + id: string + nationalId: string + name: string + type: OrganizationModelTypeEnum + children?: Array<{ + __typename?: 'EducationFriggOrganizationModel' + id: string + nationalId: string + name: string + type: OrganizationModelTypeEnum + gradeLevels?: Array | null + }> | null + }> | null +} diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts index c6763dbb9141..c00a0973276b 100644 --- a/libs/application/types/src/lib/Fields.ts +++ b/libs/application/types/src/lib/Fields.ts @@ -763,6 +763,7 @@ export interface SliderField extends BaseField { readonly type: FieldTypes.SLIDER readonly color?: Colors component: FieldComponents.SLIDER + titleVariant?: TitleVariants min: number max: MaybeWithApplicationAndField step?: number diff --git a/libs/application/ui-fields/src/lib/SelectFormField/SelectFormField.tsx b/libs/application/ui-fields/src/lib/SelectFormField/SelectFormField.tsx index 9e942d004f7f..cf057ecda0ce 100644 --- a/libs/application/ui-fields/src/lib/SelectFormField/SelectFormField.tsx +++ b/libs/application/ui-fields/src/lib/SelectFormField/SelectFormField.tsx @@ -1,5 +1,4 @@ import React, { FC, useMemo } from 'react' - import { formatText, buildFieldOptions, diff --git a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.stories.mdx b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.stories.mdx index eed93c43088e..6a909d1bb270 100644 --- a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.stories.mdx +++ b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.stories.mdx @@ -36,6 +36,7 @@ You can create a SliderFormField using the following function `buildSliderField` code={dedent(` buildSliderField({ id: 'field.id', + title: 'Slider title', label: { singular: 'day', plural: 'days', @@ -62,6 +63,7 @@ The previous configuration object will result in the following component: application={createMockApplication()} field={{ id: 'field.id', + title: 'Slider title', label: { singular: 'day', plural: 'days', diff --git a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx index b9ad91b7a687..9c8359e2cf4b 100644 --- a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx +++ b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx @@ -9,7 +9,7 @@ import { Slider } from '@island.is/application/ui-components' import { getValueViaPath } from '@island.is/application/core' import { useLocale } from '@island.is/localization' import { formatText } from '@island.is/application/core' -import { Box } from '@island.is/island-ui/core' +import { Text, Box } from '@island.is/island-ui/core' import { getDefaultValue } from '../../getDefaultValue' type SliderFormFieldProps = { @@ -20,6 +20,27 @@ type SliderFormFieldProps = { export const SliderFormField: FC< React.PropsWithChildren > = ({ application, field }) => { + const { + id, + min, + max, + title, + titleVariant, + trackStyle, + calculateCellStyle, + showLabel, + showMinMaxLabels, + showRemainderOverlay, + showProgressOverlay, + showToolTip, + label, + rangeDates, + onChangeEnd, + labelMultiplier, + snap, + step, + saveAsString, + } = field const { clearErrors, setValue } = useFormContext() const { formatMessage } = useLocale() const computeMax = ( @@ -36,60 +57,63 @@ export const SliderFormField: FC< const finalMax = useMemo( () => computeMax( - field.max as MaybeWithApplicationAndField, + max as MaybeWithApplicationAndField, application, field, ), - [field, application], + [field, max, application], ) return ( - - ( - { - clearErrors(field.id) - const value = field.saveAsString ? String(val) : val - onChange(value) - setValue(field.id, value) - }} - onChangeEnd={field.onChangeEnd} - labelMultiplier={field.labelMultiplier} - /> - )} - /> - +
+ {title && ( + + {formatText(title, application, formatMessage)} + + )} + + ( + { + clearErrors(id) + const value = saveAsString ? String(val) : val + onChange(value) + setValue(id, value) + }} + onChangeEnd={onChangeEnd} + labelMultiplier={labelMultiplier} + /> + )} + /> + +
) } From d9fdb4f415a1df51a11483f7d18f069b230360c5 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 12 Nov 2024 10:45:29 +0000 Subject: [PATCH 04/32] feat: display bank account section --- .../bankAccountSubsection.ts | 15 +++++++++++++++ .../exampleForm/compositeFieldsSection/index.ts | 7 ++++++- 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/bankAccountSubsection.ts diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/bankAccountSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/bankAccountSubsection.ts new file mode 100644 index 000000000000..8351750821f1 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/bankAccountSubsection.ts @@ -0,0 +1,15 @@ +import { + buildBankAccountField, + buildSubSection, +} from '@island.is/application/core' + +export const bankAccountSubsection = buildSubSection({ + id: 'bankAccountSubSection', + title: 'Bank account', + children: [ + buildBankAccountField({ + id: 'bankAccountfield', + title: 'Bank account field', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts index ac5b7bafc63f..a4ffc6c2e115 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/compositeFieldsSection/index.ts @@ -1,9 +1,14 @@ import { buildSection } from '@island.is/application/core' import { nationalIdWithNameSubsection } from './nationalIdWithNameSubsection' import { applicantInfoSubsection } from './applicantInfoSubsection' +import { bankAccountSubsection } from './bankAccountSubsection' export const compositeFieldsSection = buildSection({ id: 'compositeFieldsSection', title: 'Composite fields', - children: [nationalIdWithNameSubsection, applicantInfoSubsection], + children: [ + nationalIdWithNameSubsection, + applicantInfoSubsection, + bankAccountSubsection, + ], }) From 20f61e7cf36c44ecccceefd9d9f61681f28f9cd1 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 12 Nov 2024 14:42:50 +0000 Subject: [PATCH 05/32] feat: added section common actions --- .../application/core/src/lib/fieldBuilders.ts | 1 - .../src/components/Logo/Logo.tsx | 2 - .../conditions2Subsection.ts | 31 ++++++++ .../conditionsSubsection.ts | 78 +++++++++++++++++++ .../getDataFromExternalDataSection.ts | 4 +- .../exampleForm/commonActionsSection/index.ts | 14 ++++ .../customSection/customSection.ts | 17 ++++ .../src/forms/exampleForm/index.ts | 6 +- .../reference-template/src/lib/messages.ts | 6 ++ .../lib/SliderFormField/SliderFormField.tsx | 10 +-- 10 files changed, 157 insertions(+), 12 deletions(-) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts rename libs/application/templates/reference-template/src/forms/exampleForm/{getDataFromExternalDataSection => commonActionsSection}/getDataFromExternalDataSection.ts (95%) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts diff --git a/libs/application/core/src/lib/fieldBuilders.ts b/libs/application/core/src/lib/fieldBuilders.ts index c6fce7cb6602..c4eafc6c1036 100644 --- a/libs/application/core/src/lib/fieldBuilders.ts +++ b/libs/application/core/src/lib/fieldBuilders.ts @@ -21,7 +21,6 @@ import { FormTextArray, KeyValueField, LinkField, - MaybeWithApplicationAndField, MessageWithLinkButtonField, Option, PaymentChargeOverviewField, diff --git a/libs/application/templates/reference-template/src/components/Logo/Logo.tsx b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx index 9863b06d98c7..e3ff03fa7c07 100644 --- a/libs/application/templates/reference-template/src/components/Logo/Logo.tsx +++ b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx @@ -14,8 +14,6 @@ export const Logo = ({ application }: Props) => { useEffect(() => { const getLogo = async () => { - console.log(application) - const applicant = application.applicant const town = !applicant diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts new file mode 100644 index 000000000000..3bdf5eea1f20 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts @@ -0,0 +1,31 @@ +import { + buildDescriptionField, + buildSubSection, + getValueViaPath, + YES, +} from '@island.is/application/core' + +export const conditions2Subsection = buildSubSection({ + condition: (answers) => { + console.log(answers) + + const checkbox2Value = getValueViaPath>( + answers, + 'conditions2Checkbox', + ) + + console.log(checkbox2Value) + + return checkbox2Value ? checkbox2Value[0] === YES : false + }, + id: 'condition2Subsection', + title: 'This shows on condition', + children: [ + buildDescriptionField({ + id: 'condition2Description', + title: 'This is shown based on previous answers', + description: + 'This way you can make your form branch depending on different scenarios, get extra information and so on', + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts new file mode 100644 index 000000000000..c743291bb7bc --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts @@ -0,0 +1,78 @@ +import { + buildCheckboxField, + buildDescriptionField, + buildHiddenInput, + buildMultiField, + buildSubSection, + buildTextField, + getValueViaPath, + YES, +} from '@island.is/application/core' + +export const conditionsSubsection = buildSubSection({ + id: 'conditionsSubsection', + title: 'Conditions', + children: [ + buildMultiField({ + id: 'conditionsMultiField', + title: 'Conditions', + children: [ + buildDescriptionField({ + id: 'conditionsDescription', + title: 'Conditional render', + description: + 'Conditions can be used either on whole sections/subsections or individual field', + }), + buildCheckboxField({ + id: 'conditionsCheckbox', + title: 'Conditions checkbox', + options: [ + { + label: 'Check this box to see additional fields', + value: YES, + }, + ], + }), + buildTextField({ + condition: (answers) => { + const checkboxValue = getValueViaPath>( + answers, + 'conditionsCheckbox', + ) + + return checkboxValue ? checkboxValue[0] === YES : false + }, + id: 'conditionsTextField', + variant: 'textarea', + rows: 8, + title: 'This field is only visible if the checkbox above is checked', + }), + buildCheckboxField({ + id: 'conditions2Checkbox', + title: 'Condition for sections or subsections', + options: [ + { + label: + 'Check this box to see and extra subsection being added into the stepper ------>', + value: YES, + }, + ], + }), + buildTextField({ + condition: (answers) => { + const checkboxValue = getValueViaPath>( + answers, + 'conditions2Checkbox', + ) + + return checkboxValue ? checkboxValue[0] === YES : false + }, + id: 'conditionsTextField', + variant: 'textarea', + rows: 8, + title: 'Now you should see the next step in the stepper', + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts similarity index 95% rename from libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts index 7e8dfdb95f48..535832296c8c 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/getDataFromExternalDataSection/getDataFromExternalDataSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts @@ -1,12 +1,12 @@ import { buildDescriptionField, buildMultiField, - buildSection, + buildSubSection, getValueViaPath, } from '@island.is/application/core' import { Application } from '@island.is/application/types' -export const getDataFromExternalDataSection = buildSection({ +export const getDataFromExternalDataSubsection = buildSubSection({ id: 'getDataFromExternalData', title: 'External data', children: [ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts new file mode 100644 index 000000000000..7c258fd59df0 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts @@ -0,0 +1,14 @@ +import { buildSection } from '@island.is/application/core' +import { conditionsSubsection } from './conditionsSubsection' +import { conditions2Subsection } from './conditions2Subsection' +import { getDataFromExternalDataSubsection } from './getDataFromExternalDataSection' + +export const commonActionsSection = buildSection({ + id: 'commonActions', + title: 'Common actions', + children: [ + getDataFromExternalDataSubsection, + conditionsSubsection, + conditions2Subsection, + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts new file mode 100644 index 000000000000..152d672cf7fe --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts @@ -0,0 +1,17 @@ +import { + buildDescriptionField, + buildSection, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' + +export const customSection = buildSection({ + id: 'customSection', + title: 'Custom section', + children: [ + buildDescriptionField({ + id: 'customDescription', + title: 'This is a custom section', + description: m.customComponentDescription, + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 181852b03871..32ad71732c63 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -10,7 +10,6 @@ import { Application, Form, FormModes } from '@island.is/application/types' import { m } from '../../lib/messages' import { ApiActions } from '../../shared' import { introSection } from './introSection/introSection' -import { getDataFromExternalDataSection } from './getDataFromExternalDataSection/getDataFromExternalDataSection' import { simpleInputsSection } from './simpleInputsSection' import { descriptionSection } from './descriptionSection/descriptionSection' import { accordionSection } from './accordionSection/accordionSection' @@ -22,6 +21,8 @@ import { createElement } from 'react' import { Logo } from '../../components/Logo/Logo' import { dividerSection } from './dividerSection/dividerSection' import { keyValueSection } from './keyValueSection/keyValueSection' +import { commonActionsSection } from './commonActionsSection' +import { customSection } from './customSection/customSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', title: 'Main form', @@ -34,7 +35,7 @@ export const ExampleForm: Form = buildForm({ }, children: [ introSection, - getDataFromExternalDataSection, + commonActionsSection, descriptionSection, dividerSection, simpleInputsSection, @@ -44,6 +45,7 @@ export const ExampleForm: Form = buildForm({ staticTableSection, actionCardSection, keyValueSection, + customSection, buildSection({ id: 'confirmation', title: 'Staðfesta', diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index 040f4e01eb1c..941d2ec66ada 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -216,4 +216,10 @@ export const m = defineMessages({ 'Markdown code inline `const x = 123` with text\n\n Code block\n\n ```\n const x = 123\n if (x < 100) {\n return true\n }\n```', description: 'Example use of markdown code', }, + customComponentDescription: { + id: 'example.application:customComponentDescription#markdown', + defaultMessage: + '1. Try to use the shared components, `buildTextField`, `buildCheckboxField`, `buildSelectField`, `buildFileUploadField` and so on. This is most preferable to make the look and feel of the application more consistent and uniform.\n\n 2. If the shared components almost fullfill your needs but you need something more, consider consulting with the designer of the application and try to adjust the design to the built in components.\n\n 3. If the design can not be adjusted to the built in components, then consult Norda if a shared component can possibly be adjusted or expanded to fulfill your needs.\n\n 4. Is there another application that has made a similar custom component before? If so, then it should be a shared component. 5. If you still need a new component, ask yourself if this is a component that another application might also need in the future. If so make the new component shared. 6. Make a custom component if none of the above apply.', + description: 'Rules for custom components', + }, }) diff --git a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx index 9c8359e2cf4b..ce9573591465 100644 --- a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx +++ b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx @@ -25,7 +25,6 @@ export const SliderFormField: FC< min, max, title, - titleVariant, trackStyle, calculateCellStyle, showLabel, @@ -66,12 +65,13 @@ export const SliderFormField: FC< return (
- {title && ( - + {/* todo fix */} + {/* {title && ( + {formatText(title, application, formatMessage)} - )} - + )} */} + Date: Thu, 21 Nov 2024 15:39:51 +0000 Subject: [PATCH 06/32] feat: custom components and overview --- .../src/fields/Overview/Overview.tsx | 69 +++++++++++++++++++ .../reference-template/src/fields/README.md | 2 +- .../TestCustomComponent.css.ts | 10 +++ .../TestCustomComponent.tsx | 40 +++++++++++ .../reference-template/src/fields/index.ts | 2 + .../conditions2Subsection.ts | 4 -- .../customSection/customSection.ts | 33 +++++++-- .../src/forms/exampleForm/index.ts | 2 + .../overviewSection/overviewSection.ts | 43 ++++++++++++ .../src/lib/ReferenceApplicationTemplate.ts | 38 ++++------ .../reference-template/src/lib/messages.ts | 30 +++++++- .../reference-template/src/utils/constants.ts | 8 +++ .../reference-template/src/utils/types.ts | 6 ++ 13 files changed, 254 insertions(+), 33 deletions(-) create mode 100644 libs/application/templates/reference-template/src/fields/Overview/Overview.tsx create mode 100644 libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts create mode 100644 libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/overviewSection/overviewSection.ts create mode 100644 libs/application/templates/reference-template/src/utils/constants.ts diff --git a/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx b/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx new file mode 100644 index 000000000000..04d574d41ae1 --- /dev/null +++ b/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx @@ -0,0 +1,69 @@ +import { FieldBaseProps, StaticText } from '@island.is/application/types' +import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core' +import { formatText, getValueViaPath } from '@island.is/application/core' +import { useLocale } from '@island.is/localization' +import { m } from '../../lib/messages' +import { ReviewGroup } from '@island.is/application/ui-components' +import { States } from '../../utils/constants' + +type TableRepeaterAnswers = { + fullName: string + nationalId: string + relation: string +} + +const KeyValue = ({ label, value }: { label: StaticText; value: string }) => { + const { formatMessage } = useLocale() + return ( + + + {formatMessage(label)} + + {value} + + ) +} + +export const Overview = ({ application, goToScreen }: FieldBaseProps) => { + const { formatMessage } = useLocale() + + const changeScreens = (screen: string) => { + if (goToScreen) goToScreen(screen) + } + + console.log(application.answers) + + const tableRepeaterAnswers = getValueViaPath>( + application.answers, + 'tableRepeater', + ) + + return ( + + + changeScreens('tableRepeater')} + isEditable={application.state === States.DRAFT} + > + + + + Values from the table repeater + + {tableRepeaterAnswers && + tableRepeaterAnswers.map((ans, i) => { + return ( + + ) + })} + + + + {/* More review groups as needed... */} + + ) +} diff --git a/libs/application/templates/reference-template/src/fields/README.md b/libs/application/templates/reference-template/src/fields/README.md index 50011f40db2a..c0f2d54fb2bf 100644 --- a/libs/application/templates/reference-template/src/fields/README.md +++ b/libs/application/templates/reference-template/src/fields/README.md @@ -4,7 +4,7 @@ This folder contains all custom components that are used by the application. ## Organisation -- All components should be in a folder that holds the .tsx file and the .css.ts file. +- All components should be in a folder that holds all files for that component. This includes the .tsx file, possibly a .css.ts file and maybe others. The folders should be named like the component, but with the first letter in lowercase (camelCase), and then the .tsx and .css.ts files should be capitalized (PascalCase). - The folder should have an index.ts file that re-exports all the components. - The index.ts file in the /src folder should then re-export the components in the /fields folder. diff --git a/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts b/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts new file mode 100644 index 000000000000..de8bdda26696 --- /dev/null +++ b/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts @@ -0,0 +1,10 @@ +import { theme } from '@island.is/island-ui/theme' +import { style } from '@vanilla-extract/css' + +export const boldNames = style({ + fontWeight: 'bold', +}) + +export const bottomBorderRadius = style({ + borderRadius: `0 0 ${theme.border.radius.large} ${theme.border.radius.large}`, +}) diff --git a/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx b/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx new file mode 100644 index 000000000000..dc45de845b17 --- /dev/null +++ b/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx @@ -0,0 +1,40 @@ +import { FieldBaseProps } from '@island.is/application/types' +import { useLocale } from '@island.is/localization' +import * as styles from './TestCustomComponent.css' +import { Box, Text } from '@island.is/island-ui/core' +import { m } from '../../lib/messages' + +interface Props { + field: { + props: { + someData: string[] + } + } +} + +export const TestCustomComponent = ({ + application, + field, +}: Props & FieldBaseProps) => { + const { formatMessage } = useLocale() + const { someData } = field.props + if (!someData) return null + + return ( + + + {formatMessage(m.customComponentAbout)} + + + {someData.map((item) => ( +

{item}

+ ))} +
+
+ ) +} diff --git a/libs/application/templates/reference-template/src/fields/index.ts b/libs/application/templates/reference-template/src/fields/index.ts index c953dd689bb2..849894504a49 100644 --- a/libs/application/templates/reference-template/src/fields/index.ts +++ b/libs/application/templates/reference-template/src/fields/index.ts @@ -1,2 +1,4 @@ export { default as ExampleCountryField } from './ExampleCountryField' export { default as CustomRepeater } from './CustomRepeater' +export { TestCustomComponent } from './TestCustomComponent/TestCustomComponent' +export { Overview } from './Overview/Overview' diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts index 3bdf5eea1f20..9579fdd8b8cf 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts @@ -7,15 +7,11 @@ import { export const conditions2Subsection = buildSubSection({ condition: (answers) => { - console.log(answers) - const checkbox2Value = getValueViaPath>( answers, 'conditions2Checkbox', ) - console.log(checkbox2Value) - return checkbox2Value ? checkbox2Value[0] === YES : false }, id: 'condition2Subsection', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts index 152d672cf7fe..c98dd2f0e95b 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts @@ -1,5 +1,7 @@ import { + buildCustomField, buildDescriptionField, + buildMultiField, buildSection, } from '@island.is/application/core' import { m } from '../../../lib/messages' @@ -8,10 +10,33 @@ export const customSection = buildSection({ id: 'customSection', title: 'Custom section', children: [ - buildDescriptionField({ - id: 'customDescription', - title: 'This is a custom section', - description: m.customComponentDescription, + buildMultiField({ + id: 'customMultiField', + title: '', + children: [ + buildDescriptionField({ + id: 'customDescription', + title: 'Custom Components', + description: m.customComponentDescription, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'customDescription2', + title: '', + description: m.customComponentNumberedList, + marginBottom: [2], + }), + buildCustomField( + { + id: 'customComponent', + title: 'The custom component', + component: 'TestCustomComponent', + }, + { + someData: ['foo', 'bar', 'baz'], + }, + ), + ], }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 32ad71732c63..0d9d2df619a8 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -23,6 +23,7 @@ import { dividerSection } from './dividerSection/dividerSection' import { keyValueSection } from './keyValueSection/keyValueSection' import { commonActionsSection } from './commonActionsSection' import { customSection } from './customSection/customSection' +import { overviewSection } from './overviewSection/overviewSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', title: 'Main form', @@ -46,6 +47,7 @@ export const ExampleForm: Form = buildForm({ actionCardSection, keyValueSection, customSection, + overviewSection, buildSection({ id: 'confirmation', title: 'Staðfesta', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/overviewSection/overviewSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/overviewSection/overviewSection.ts new file mode 100644 index 000000000000..6bf72bd620d8 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/overviewSection/overviewSection.ts @@ -0,0 +1,43 @@ +import { + buildSection, + buildMultiField, + buildDescriptionField, + buildCustomField, + buildSubmitField, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' +import { DefaultEvents } from '@island.is/application/types' + +export const overviewSection = buildSection({ + id: 'overview', + title: 'Overview', + children: [ + buildMultiField({ + id: 'overviewMultiField', + title: '', + children: [ + buildDescriptionField({ + id: 'overview', + title: 'Overview', + description: m.overviewDescription, + }), + buildCustomField({ + id: 'customComponent', + title: '', + component: 'Overview', + }), + buildSubmitField({ + id: 'submitApplication', + title: '', + actions: [ + { + event: DefaultEvents.SUBMIT, + name: m.overviewSubmit, + type: 'primary', + }, + ], + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index ad028d6ab0ee..32750cd78011 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -27,15 +27,7 @@ import { NationalRegistryApi, } from '../dataProviders' import { ExampleSchema } from './dataSchema' - -const States = { - prerequisites: 'prerequisites', - draft: 'draft', - inReview: 'inReview', - approved: 'approved', - rejected: 'rejected', - waitingToAssign: 'waitingToAssign', -} +import { States } from '../utils/constants' type ReferenceTemplateEvent = | { type: DefaultEvents.APPROVE } @@ -86,9 +78,9 @@ const ReferenceApplicationTemplate: ApplicationTemplate< allowMultipleApplicationsInDraft: true, stateMachineConfig: { - initial: States.prerequisites, + initial: States.PREREQUISITES, states: { - [States.prerequisites]: { + [States.PREREQUISITES]: { meta: { name: 'Skilyrði', progress: 0, @@ -132,11 +124,11 @@ const ReferenceApplicationTemplate: ApplicationTemplate< }, on: { SUBMIT: { - target: States.draft, + target: States.DRAFT, }, }, }, - [States.draft]: { + [States.DRAFT]: { meta: { name: 'Umsókn um ökunám', @@ -168,12 +160,12 @@ const ReferenceApplicationTemplate: ApplicationTemplate< on: { SUBMIT: [ { - target: States.waitingToAssign, + target: States.WAITINGTOASSIGN, }, ], }, }, - [States.waitingToAssign]: { + [States.WAITINGTOASSIGN]: { meta: { name: 'Waiting to assign', progress: 0.75, @@ -225,12 +217,12 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - SUBMIT: { target: States.inReview }, - ASSIGN: { target: States.inReview }, - EDIT: { target: States.draft }, + SUBMIT: { target: States.INREVIEW }, + ASSIGN: { target: States.INREVIEW }, + EDIT: { target: States.DRAFT }, }, }, - [States.inReview]: { + [States.INREVIEW]: { meta: { name: 'In Review', progress: 0.75, @@ -287,11 +279,11 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - APPROVE: { target: States.approved }, - REJECT: { target: States.rejected }, + APPROVE: { target: States.APPROVED }, + REJECT: { target: States.REJECTED }, }, }, - [States.approved]: { + [States.APPROVED]: { meta: { name: 'Approved', progress: 1, @@ -309,7 +301,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, }, - [States.rejected]: { + [States.REJECTED]: { meta: { name: 'Rejected', progress: 1, diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index 941d2ec66ada..06d39ebdaa92 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -217,9 +217,37 @@ export const m = defineMessages({ description: 'Example use of markdown code', }, customComponentDescription: { + id: 'example.application:customComponentDescription', + defaultMessage: + 'Before you make a custom component, go through this list to determine if you really need a custom component. A custom component should be the last option you go for when building an application.', + description: 'Rules for custom components', + }, + customComponentNumberedList: { id: 'example.application:customComponentDescription#markdown', defaultMessage: - '1. Try to use the shared components, `buildTextField`, `buildCheckboxField`, `buildSelectField`, `buildFileUploadField` and so on. This is most preferable to make the look and feel of the application more consistent and uniform.\n\n 2. If the shared components almost fullfill your needs but you need something more, consider consulting with the designer of the application and try to adjust the design to the built in components.\n\n 3. If the design can not be adjusted to the built in components, then consult Norda if a shared component can possibly be adjusted or expanded to fulfill your needs.\n\n 4. Is there another application that has made a similar custom component before? If so, then it should be a shared component. 5. If you still need a new component, ask yourself if this is a component that another application might also need in the future. If so make the new component shared. 6. Make a custom component if none of the above apply.', + '1. Try to use the shared components, such as `buildTextField`, `buildCheckboxField`, `buildSelectField`, `buildFileUploadField`, and others. This approach ensures a more consistent and uniform look and feel for the application.\n- If the shared components almost fulfill your needs but require slight adjustments, consult with the designer of the application to explore adapting the design to the built-in components.\n- If the design cannot be adjusted to the built-in components, consult Norda to determine if the shared components can be modified or expanded to meet your requirements.\n- Check if another application has created a similar custom component before. If so, it should be made into a shared component.\n- If you still need a new component, evaluate whether it is something that other applications might need in the future. If so, make the new component shared.\n- Create a custom component only if none of the above conditions apply.', description: 'Rules for custom components', }, + customComponentAbout: { + id: 'example.application:customComponentAbout', + defaultMessage: + 'Custom components are just regular React components. They can take in some data you specify in the template and they have access to the application object. They can also be styled with vanilla-extract.', + description: 'About custom components', + }, + overviewTitle: { + id: 'example.application:overviewTitle', + defaultMessage: 'Overview', + description: 'Overview title', + }, + overviewDescription: { + id: 'example.application:overviewTitle', + defaultMessage: + 'At the moment the form overview is a custom component. The plan is to make this a shared component in the near future.', + description: 'Overview title', + }, + overviewSubmit: { + id: 'example.application:overviewSubmit', + defaultMessage: 'Submit', + description: 'Overview title', + }, }) diff --git a/libs/application/templates/reference-template/src/utils/constants.ts b/libs/application/templates/reference-template/src/utils/constants.ts new file mode 100644 index 000000000000..bf73ada91471 --- /dev/null +++ b/libs/application/templates/reference-template/src/utils/constants.ts @@ -0,0 +1,8 @@ +export enum States { + PREREQUISITES = 'prerequisites', + DRAFT = 'draft', + INREVIEW = 'inReview', + APPROVED = 'approved', + REJECTED = 'rejected', + WAITINGTOASSIGN = 'waitingToAssign', +} diff --git a/libs/application/templates/reference-template/src/utils/types.ts b/libs/application/templates/reference-template/src/utils/types.ts index b2ca863d7e12..660af48f154a 100644 --- a/libs/application/templates/reference-template/src/utils/types.ts +++ b/libs/application/templates/reference-template/src/utils/types.ts @@ -22,3 +22,9 @@ export type FriggSchoolsByMunicipality = { }> | null }> | null } + +export type TableRepeaterAnswers = { + fullName: string + nationalId: string + relation: string +} From 9ee1f9cbeaa07fc2439543c32ecd968e7ebe8e19 Mon Sep 17 00:00:00 2001 From: Jonni Date: Fri, 22 Nov 2024 09:47:16 +0000 Subject: [PATCH 07/32] feat: diagram and use default events --- .../src/fields/Overview/Overview.tsx | 2 -- .../src/lib/ReferenceApplicationTemplate.ts | 28 +++++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx b/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx index 04d574d41ae1..4fa85d42ab6d 100644 --- a/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx +++ b/libs/application/templates/reference-template/src/fields/Overview/Overview.tsx @@ -31,8 +31,6 @@ export const Overview = ({ application, goToScreen }: FieldBaseProps) => { if (goToScreen) goToScreen(screen) } - console.log(application.answers) - const tableRepeaterAnswers = getValueViaPath>( application.answers, 'tableRepeater', diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index 32750cd78011..fe82b7f5b16f 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -1,3 +1,14 @@ +/* + *** + *** The state machine is for this template is as follows: + *** + *** /-> Approved + *** Prerequisites -> Draft -> Waiting to assign -> In review -- + *** Λ | \-> Rejected + *** |_____________| + *** + */ + import { DefaultStateLifeCycle, getValueViaPath, @@ -64,6 +75,7 @@ const determineMessageFromApplicationAnswers = (application: Application) => { } return m.name } + const ReferenceApplicationTemplate: ApplicationTemplate< ApplicationContext, ApplicationStateSchema, @@ -123,7 +135,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - SUBMIT: { + [DefaultEvents.SUBMIT]: { target: States.DRAFT, }, }, @@ -131,7 +143,6 @@ const ReferenceApplicationTemplate: ApplicationTemplate< [States.DRAFT]: { meta: { name: 'Umsókn um ökunám', - actionCard: { description: m.draftDescription, historyLogs: { @@ -158,7 +169,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - SUBMIT: [ + [DefaultEvents.SUBMIT]: [ { target: States.WAITINGTOASSIGN, }, @@ -217,9 +228,9 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - SUBMIT: { target: States.INREVIEW }, - ASSIGN: { target: States.INREVIEW }, - EDIT: { target: States.DRAFT }, + [DefaultEvents.SUBMIT]: { target: States.INREVIEW }, + [DefaultEvents.ASSIGN]: { target: States.INREVIEW }, + [DefaultEvents.EDIT]: { target: States.DRAFT }, }, }, [States.INREVIEW]: { @@ -279,8 +290,8 @@ const ReferenceApplicationTemplate: ApplicationTemplate< ], }, on: { - APPROVE: { target: States.APPROVED }, - REJECT: { target: States.REJECTED }, + [DefaultEvents.APPROVE]: { target: States.APPROVED }, + [DefaultEvents.REJECT]: { target: States.REJECTED }, }, }, [States.APPROVED]: { @@ -307,7 +318,6 @@ const ReferenceApplicationTemplate: ApplicationTemplate< progress: 1, status: 'rejected', lifecycle: DefaultStateLifeCycle, - roles: [ { id: Roles.APPLICANT, From b948d8010249507345ae49d44d14a997337afdfd Mon Sep 17 00:00:00 2001 From: Jonni Date: Mon, 25 Nov 2024 11:30:31 +0000 Subject: [PATCH 08/32] chore: update dataSchema --- .../src/lib/ReferenceApplicationTemplate.ts | 4 +- .../reference-template/src/lib/dataSchema.ts | 119 ++++++++++-------- .../reference-template/src/utils/constants.ts | 24 ++++ 3 files changed, 90 insertions(+), 57 deletions(-) diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index fe82b7f5b16f..29b067003f3a 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -37,7 +37,7 @@ import { MyMockProvider, NationalRegistryApi, } from '../dataProviders' -import { ExampleSchema } from './dataSchema' +import { dataSchema } from './dataSchema' import { States } from '../utils/constants' type ReferenceTemplateEvent = @@ -85,7 +85,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< name: determineMessageFromApplicationAnswers, institution: m.institutionName, translationNamespaces: [ApplicationConfigurations.ExampleForm.translation], - dataSchema: ExampleSchema, + dataSchema: dataSchema, featureFlag: Features.exampleApplication, allowMultipleApplicationsInDraft: true, diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index faa3b728cff4..caef277333e5 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -1,7 +1,20 @@ +/* + * DataSchema uses Zod to validate the answers object and can be used to refine values, provide + * error messages, and more. + * + * When checking if a value is of an enum type, use z.nativeEnum instead of z.enum. This eliminates the need to list up all possible values in the enum. + */ + import { z } from 'zod' import * as kennitala from 'kennitala' import { isValidNumber } from 'libphonenumber-js' import { m } from './messages' +import { + ApprovedByReviewerEnum, + CareerHistoryEnum, + CareerIndustryEnum, + YesNoEnum, +} from '../utils/constants' const careerHistoryCompaniesValidation = (data: any) => { // Applicant selected other but didnt supply the reason so we dont allow it @@ -13,63 +26,47 @@ const careerHistoryCompaniesValidation = (data: any) => { } return true } -export const ExampleSchema = z.object({ - approveExternalData: z.boolean().refine((v) => v), - person: z.object({ - name: z.string().min(1).max(256), - age: z.string().refine((x) => { - const asNumber = parseInt(x) - if (isNaN(asNumber)) { - return false - } - return asNumber > 15 - }), - nationalId: z - .string() - /** - * We are depending on this template for the e2e tests on the application-system-api. - * Because we are not allowing committing valid kennitala, I reversed the condition - * to check for invalid kenitala so it passes the test. - */ - .refine((n) => n && !kennitala.isValid(n), { - params: m.dataSchemeNationalId, - }), - phoneNumber: z - .string() - .refine(isValidNumber, { params: m.dataSchemePhoneNumber }), - email: z.string().email(), - // removed due to e2e tests failing, example still works - // someHiddenInputRequired: z.string().refine((x) => x === 'validAnswer'), - // someHiddenInputWatchedRequired: z - // .string() - // .refine((x) => x.includes('Valid')), + +const personSchema = z.object({ + name: z.string().min(1).max(256), + age: z.string().refine((x) => { + const asNumber = parseInt(x) + if (isNaN(asNumber)) { + return false + } + return asNumber > 15 }), - careerHistory: z.enum(['yes', 'no']).optional(), - careerIndustry: z.enum(['software', 'finance', 'consulting', 'other']), - careerHistoryDetails: z - .object({ - careerHistoryCompanies: z - .array(z.enum(['government', 'aranja', 'advania', 'other'])) - .nonempty(), - careerHistoryOther: z.string(), - }) - .partial() - .refine((data) => careerHistoryCompaniesValidation(data), { - params: m.careerHistoryOtherError, - path: ['careerHistoryOther'], - }), - deepNestedValues: z.object({ - something: z.object({ - very: z.object({ - deep: z.object({ + nationalId: z.string().refine((n) => n && !kennitala.isValid(n), { + params: m.dataSchemeNationalId, + }), + phoneNumber: z + .string() + .refine(isValidNumber, { params: m.dataSchemePhoneNumber }), + email: z.string().email(), +}) + +const careerHistoryDetailsSchema = z + .object({ + careerHistoryCompanies: z.array(z.nativeEnum(CareerHistoryEnum)).nonempty(), + careerHistoryOther: z.string(), + }) + .partial() + .refine((data) => careerHistoryCompaniesValidation(data), { + params: m.careerHistoryOtherError, + path: ['careerHistoryOther'], + }) + +const deepNestedSchema = z.object({ + something: z.object({ + very: z.object({ + deep: z.object({ + so: z.object({ so: z.object({ - so: z.object({ + very: z.object({ very: z.object({ - very: z.object({ - deep: z.object({ - nested: z.object({ - value: z.string(), - }), + deep: z.object({ + nested: z.object({ + value: z.string(), }), }), }), @@ -79,7 +76,19 @@ export const ExampleSchema = z.object({ }), }), }), +}) + +// The exported dataSchema should be as flat and easy to read as possible. +export const dataSchema = z.object({ + approveExternalData: z.boolean().refine((v) => v), + person: personSchema, + careerHistory: z.nativeEnum(YesNoEnum).optional(), + careerIndustry: z.nativeEnum(CareerIndustryEnum), + careerHistoryDetails: careerHistoryDetailsSchema, + deepNestedValues: deepNestedSchema, dreamJob: z.string().optional(), assigneeEmail: z.string().email(), - approvedByReviewer: z.enum(['APPROVE', 'REJECT']), + approvedByReviewer: z.nativeEnum(ApprovedByReviewerEnum), }) + +export type AnswersSchema = z.infer diff --git a/libs/application/templates/reference-template/src/utils/constants.ts b/libs/application/templates/reference-template/src/utils/constants.ts index bf73ada91471..b44f3134b11a 100644 --- a/libs/application/templates/reference-template/src/utils/constants.ts +++ b/libs/application/templates/reference-template/src/utils/constants.ts @@ -6,3 +6,27 @@ export enum States { REJECTED = 'rejected', WAITINGTOASSIGN = 'waitingToAssign', } + +export enum YesNoEnum { + YES = 'yes', + NO = 'no', +} + +export enum CareerHistoryEnum { + GOVERNMENT = 'government', + ARANJA = 'aranja', + ADVANIA = 'advania', + OTHER = 'other', +} + +export enum CareerIndustryEnum { + SOFTWARE = 'software', + FINANCE = 'finance', + CONSULTING = 'consulting', + OTHER = 'other', +} + +export enum ApprovedByReviewerEnum { + APPROVE = 'APPROVE', + REJECT = 'REJECT', +} From 36e917497f77575ab92a913f7a179345852d9f2a Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 11 Dec 2024 17:11:26 +0000 Subject: [PATCH 09/32] chore: move some fields from sections to subsections --- .../src/forms/exampleForm/index.ts | 17 ++++--------- .../exampleForm/introSection/introSection.ts | 24 +++++++++++++------ .../accordionSubsection.ts} | 9 ++++--- .../actionCardSubsection.ts} | 6 ++--- .../descriptionSubsection.ts} | 6 ++--- .../dividerSubsection.ts} | 7 +++--- .../exampleForm/noInputFieldsSection/index.ts | 17 +++++++++++++ .../keyValueSubsection.ts} | 11 +++++---- .../src/lib/ReferenceApplicationTemplate.ts | 2 +- .../reference-template/src/lib/messages.ts | 18 +++++++++----- 10 files changed, 74 insertions(+), 43 deletions(-) rename libs/application/templates/reference-template/src/forms/exampleForm/{accordionSection/accordionSection.ts => noInputFieldsSection/accordionSubsection.ts} (85%) rename libs/application/templates/reference-template/src/forms/exampleForm/{actionCardSection/actionCardSection.ts => noInputFieldsSection/actionCardSubsection.ts} (94%) rename libs/application/templates/reference-template/src/forms/exampleForm/{descriptionSection/descriptionSection.ts => noInputFieldsSection/descriptionSubsection.ts} (94%) rename libs/application/templates/reference-template/src/forms/exampleForm/{dividerSection/dividerSection.ts => noInputFieldsSection/dividerSubsection.ts} (75%) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts rename libs/application/templates/reference-template/src/forms/exampleForm/{keyValueSection/keyValueSection.ts => noInputFieldsSection/keyValueSubsection.ts} (81%) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 0d9d2df619a8..113136c02ad4 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -1,3 +1,4 @@ +import { createElement } from 'react' import { buildForm, buildDescriptionField, @@ -11,19 +12,15 @@ import { m } from '../../lib/messages' import { ApiActions } from '../../shared' import { introSection } from './introSection/introSection' import { simpleInputsSection } from './simpleInputsSection' -import { descriptionSection } from './descriptionSection/descriptionSection' -import { accordionSection } from './accordionSection/accordionSection' import { tableRepeaterSection } from './tableRepeaterSection/tableRepeaterSection' import { staticTableSection } from './staticTableSection/StaticTableSection' -import { actionCardSection } from './actionCardSection/actionCardSection' import { compositeFieldsSection } from './compositeFieldsSection' -import { createElement } from 'react' -import { Logo } from '../../components/Logo/Logo' -import { dividerSection } from './dividerSection/dividerSection' -import { keyValueSection } from './keyValueSection/keyValueSection' import { commonActionsSection } from './commonActionsSection' import { customSection } from './customSection/customSection' import { overviewSection } from './overviewSection/overviewSection' +import { noInputFieldsSection } from './noInputFieldsSection' +import { Logo } from '../../components/Logo/Logo' + export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', title: 'Main form', @@ -37,15 +34,11 @@ export const ExampleForm: Form = buildForm({ children: [ introSection, commonActionsSection, - descriptionSection, - dividerSection, + noInputFieldsSection, simpleInputsSection, compositeFieldsSection, - accordionSection, tableRepeaterSection, staticTableSection, - actionCardSection, - keyValueSection, customSection, overviewSection, buildSection({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts index f56476e44fb3..a840bc32ffde 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/introSection/introSection.ts @@ -1,5 +1,6 @@ import { buildDescriptionField, + buildMultiField, buildSection, } from '@island.is/application/core' import { m } from '../../../lib/messages' @@ -8,13 +9,22 @@ export const introSection = buildSection({ id: 'introSection', title: 'Inngangur', children: [ - buildDescriptionField({ - id: 'field', - title: m.introField, - description: (application) => ({ - ...m.introIntroduction, - values: { name: application.answers.name }, - }), + buildMultiField({ + id: 'intro', + title: m.introTitle, + children: [ + buildDescriptionField({ + id: 'introDescription', + title: '', + description: m.introDescription, + marginBottom: 2, + }), + buildDescriptionField({ + id: 'introDescription2', + title: '', + description: m.introDescription2, + }), + ], }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/accordionSubsection.ts similarity index 85% rename from libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/accordionSubsection.ts index 667128775ac3..d21002cfaa9b 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/accordionSection/accordionSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/accordionSubsection.ts @@ -1,7 +1,10 @@ -import { buildAccordionField, buildSection } from '@island.is/application/core' +import { + buildAccordionField, + buildSubSection, +} from '@island.is/application/core' -export const accordionSection = buildSection({ - id: 'accordion', +export const accordionSubsection = buildSubSection({ + id: 'accordionSubsection', title: 'Accordion', children: [ buildAccordionField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts similarity index 94% rename from libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts index bc10363a4a54..3b3ad42fa004 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/actionCardSection/actionCardSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts @@ -1,10 +1,10 @@ import { - buildSection, buildActionCardListField, + buildSubSection, } from '@island.is/application/core' -export const actionCardSection = buildSection({ - id: 'actionCardSection', +export const actionCardSubsection = buildSubSection({ + id: 'actionCardSubsection', title: 'Action card', children: [ buildActionCardListField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts similarity index 94% rename from libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts index 11f0e60eda03..c8c0d612856d 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/descriptionSection/descriptionSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts @@ -1,12 +1,12 @@ import { buildDescriptionField, buildMultiField, - buildSection, + buildSubSection, } from '@island.is/application/core' import { m } from '../../../lib/messages' -export const descriptionSection = buildSection({ - id: 'descriptionSection', +export const descriptionSubsection = buildSubSection({ + id: 'descriptionSubsection', title: 'Description', children: [ buildMultiField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/dividerSubsection.ts similarity index 75% rename from libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/dividerSubsection.ts index f41df687c25f..b591c9c3509a 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/dividerSection/dividerSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/dividerSubsection.ts @@ -1,12 +1,11 @@ import { buildDividerField, buildMultiField, - buildSection, + buildSubSection, } from '@island.is/application/core' -import { Colors } from '@island.is/island-ui/theme' -export const dividerSection = buildSection({ - id: 'dividerSection', +export const dividerSubsection = buildSubSection({ + id: 'dividerSubsection', title: 'Divider', children: [ buildMultiField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts new file mode 100644 index 000000000000..7ca7fa2bd956 --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts @@ -0,0 +1,17 @@ +import { buildSection } from '@island.is/application/core' +import { descriptionSubsection } from './descriptionSubsection' +import { dividerSubsection } from './dividerSubsection' +import { accordionSubsection } from './accordionSubsection' +import { actionCardSubsection } from './actionCardSubsection' +import { keyValueSubsection } from './keyValueSubsection' +export const noInputFieldsSection = buildSection({ + id: 'noInputFieldsSection', + title: 'Fields with no inputs', + children: [ + descriptionSubsection, + dividerSubsection, + accordionSubsection, + actionCardSubsection, + keyValueSubsection, + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/keyValueSubsection.ts similarity index 81% rename from libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/keyValueSubsection.ts index c296787626a4..3e07e42070ec 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/keyValueSection/keyValueSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/keyValueSubsection.ts @@ -1,8 +1,11 @@ -import { buildSection, buildKeyValueField } from '@island.is/application/core' -import { buildMultiField } from 'libs/application/core/src/lib/formBuilders' +import { + buildKeyValueField, + buildMultiField, + buildSubSection, +} from '@island.is/application/core' -export const keyValueSection = buildSection({ - id: 'keyValueSection', +export const keyValueSubsection = buildSubSection({ + id: 'keyValueSubsection', title: 'Key-Value', children: [ buildMultiField({ diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index 29b067003f3a..9b308d213c2d 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -142,7 +142,7 @@ const ReferenceApplicationTemplate: ApplicationTemplate< }, [States.DRAFT]: { meta: { - name: 'Umsókn um ökunám', + name: 'Dæmi um umsókn', actionCard: { description: m.draftDescription, historyLogs: { diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index 06d39ebdaa92..f22525581297 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -41,15 +41,21 @@ export const m = defineMessages({ defaultMessage: 'Upplýsingar', description: 'Some description', }, - introField: { - id: 'example.application:intro.field', - defaultMessage: 'Velkomin(n)', + introTitle: { + id: 'example.application:intro.title', + defaultMessage: 'Velkomin', description: 'Some description', }, - introIntroduction: { - id: 'example.application:intro.introduction', + introDescription: { + id: 'example.application:intro.description', defaultMessage: - '*Hello*, **{name}**! [This is a link to Google!](http://google.com)', + 'Þessi umsókn sýnir hvernig á að smíða umsókn. Hver umsókn skiptist niður í nokkur form og eru mismunandi form sýnd eftir stöðu umsóknarinnar og/eða hlutverki notandans. Formið sem umsóknin er að birta núna er "exampleForm" og núna er umsóknin í stöðunni "draft" og merkir það að þú hafir komist í gegnum fyrsta formið "prerequisitesForm" þar sem staðan var "prerequisites".', + description: 'Some description', + }, + introDescription2: { + id: 'example.application:intro.description2', + defaultMessage: + 'Í Þessu formi er farið yfir allar mögulegar einingar sem kerfið býður upp á og sýndar eru mismunandi stillingar sem að láta einingarnar birtast eða hegða sér á mismunandi vegu.', description: 'Some description', }, about: { From 162562b9ecee82cc7aaf0a80e2f57cd27da0949c Mon Sep 17 00:00:00 2001 From: Jonni Date: Mon, 16 Dec 2024 10:02:08 +0000 Subject: [PATCH 10/32] feat: order and add more description --- .../exampleForm/commonActionsSection/index.ts | 4 +- .../validadionSubsection.ts | 54 +++++++++++++++++++ .../reference-template/src/lib/dataSchema.ts | 9 ++++ .../reference-template/src/lib/messages.ts | 12 +++++ .../reference-template/src/utils/types.ts | 6 +++ 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts index 7c258fd59df0..fcbb9bdc73e9 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts @@ -2,12 +2,14 @@ import { buildSection } from '@island.is/application/core' import { conditionsSubsection } from './conditionsSubsection' import { conditions2Subsection } from './conditions2Subsection' import { getDataFromExternalDataSubsection } from './getDataFromExternalDataSection' +import { validationSubsection } from './validadionSubsection' export const commonActionsSection = buildSection({ id: 'commonActions', - title: 'Common actions', + title: 'Algengar aðgerðir', children: [ getDataFromExternalDataSubsection, + validationSubsection, conditionsSubsection, conditions2Subsection, ], diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts new file mode 100644 index 000000000000..6a599baa6b1f --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts @@ -0,0 +1,54 @@ +import { + buildDescriptionField, + buildMultiField, + buildRadioField, + buildSubSection, + buildTextField, +} from '@island.is/application/core' +import { m } from '../../../lib/messages' +import { radioValidationExampleEnum } from '../../../utils/types' + +export const validationSubsection = buildSubSection({ + id: 'validationSubsection', + title: 'Validation', + children: [ + buildMultiField({ + id: 'validationMultiField', + title: 'Validation', + children: [ + buildDescriptionField({ + id: 'validationDescriptionField', + title: '', + description: m.validationDescription, + marginBottom: 2, + }), + buildDescriptionField({ + id: 'validationDescriptionField2', + title: '', + description: + 'Allir reitir á þessari síðu eru með validation sem verður að fylla út til að halda áfram', + }), + buildTextField({ + id: 'validation.validationTextField', + title: 'Verður að vera 3 stafir eða meira', + required: true, // Adds the red star to the field + }), + buildDescriptionField({ + id: 'validation.validationDescriptionField3', + title: '', + description: m.validationDescription3, + marginTop: 4, + }), + buildRadioField({ + id: 'validation.validationRadioField', + title: '', + options: [ + { label: 'Option 1', value: radioValidationExampleEnum.OPTION_1 }, + { label: 'Option 2', value: radioValidationExampleEnum.OPTION_2 }, + { label: 'Option 3', value: radioValidationExampleEnum.OPTION_3 }, + ], + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index caef277333e5..d616ce439c15 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -15,6 +15,7 @@ import { CareerIndustryEnum, YesNoEnum, } from '../utils/constants' +import { radioValidationExampleEnum } from '../utils/types' const careerHistoryCompaniesValidation = (data: any) => { // Applicant selected other but didnt supply the reason so we dont allow it @@ -78,6 +79,13 @@ const deepNestedSchema = z.object({ }), }) +const validationSchema = z.object({ + validationTextField: z.string().min(3, { + message: 'Custom validation message', + }), + validationRadioField: z.nativeEnum(radioValidationExampleEnum), +}) + // The exported dataSchema should be as flat and easy to read as possible. export const dataSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), @@ -89,6 +97,7 @@ export const dataSchema = z.object({ dreamJob: z.string().optional(), assigneeEmail: z.string().email(), approvedByReviewer: z.nativeEnum(ApprovedByReviewerEnum), + validation: validationSchema, }) export type AnswersSchema = z.infer diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index f22525581297..3c9bc263e866 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -256,4 +256,16 @@ export const m = defineMessages({ defaultMessage: 'Submit', description: 'Overview title', }, + validationDescription: { + id: 'example.application:validation.description#markdown', + defaultMessage: + 'Einhver field bjóða upp á að setja gildið `required: true`, sem nýtir innbyggða virkni í `html` og getur verið afvirkjað með því að skoða DOM-ið fyrir síðuna.\n\n Almennt er best að setja allt sem verður að vera fyllt út eða verður að vera fyllt út á ákveðinn hátt í `/lib/dataSchema.ts`. Fyrir validation skal nota *zod*.', + description: 'Validation description', + }, + validationDescription3: { + id: 'example.application:validation.description3#markdown', + defaultMessage: + 'Ef valkostir í field eru allir í einu `enum`, þá skal nota `z.nativeEnum()` í zod validation til að sleppa við að lista upp alla hvern valkost í enum-inu eins og þarf að gera ef stuðst er við `z.enum()` ', + description: 'Validation description', + }, }) diff --git a/libs/application/templates/reference-template/src/utils/types.ts b/libs/application/templates/reference-template/src/utils/types.ts index 660af48f154a..23f160994302 100644 --- a/libs/application/templates/reference-template/src/utils/types.ts +++ b/libs/application/templates/reference-template/src/utils/types.ts @@ -28,3 +28,9 @@ export type TableRepeaterAnswers = { nationalId: string relation: string } + +export enum radioValidationExampleEnum { + OPTION_1 = 'option1', + OPTION_2 = 'option2', + OPTION_3 = 'option3', +} From 780b59e55f7c53745f629c2827676e95565ab1bb Mon Sep 17 00:00:00 2001 From: Jonni Date: Mon, 16 Dec 2024 16:24:23 +0000 Subject: [PATCH 11/32] chore: update text to Icelandic --- .../conditions2Subsection.ts | 6 ++-- .../conditionsSubsection.ts | 36 +++++++++++++------ .../descriptionSubsection.ts | 15 +++++++- .../exampleForm/noInputFieldsSection/index.ts | 2 +- .../reference-template/src/lib/dataSchema.ts | 3 +- .../reference-template/src/lib/messages.ts | 18 ++++++++++ 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts index 9579fdd8b8cf..38634d1f3e5d 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts @@ -15,13 +15,13 @@ export const conditions2Subsection = buildSubSection({ return checkbox2Value ? checkbox2Value[0] === YES : false }, id: 'condition2Subsection', - title: 'This shows on condition', + title: 'Þetta section er skilyrt', children: [ buildDescriptionField({ id: 'condition2Description', - title: 'This is shown based on previous answers', + title: 'Þessi skjár sést byggt á fyrri svörum', description: - 'This way you can make your form branch depending on different scenarios, get extra information and so on', + 'Með þessari virkni getur umsóknin greinst í sundur og safnað mismunandi gögnum fyrir mismunandi svör notenda', }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts index c743291bb7bc..6086e7228436 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts @@ -8,6 +8,7 @@ import { getValueViaPath, YES, } from '@island.is/application/core' +import { m } from '../../../lib/messages' export const conditionsSubsection = buildSubSection({ id: 'conditionsSubsection', @@ -19,16 +20,30 @@ export const conditionsSubsection = buildSubSection({ children: [ buildDescriptionField({ id: 'conditionsDescription', - title: 'Conditional render', + title: '', description: - 'Conditions can be used either on whole sections/subsections or individual field', + 'Hægt er að skilyrða bæði staka reiti og texta eða heil section/subsection', + marginBottom: 2, + }), + buildDescriptionField({ + id: 'conditionsDescription2', + title: '', + description: m.conditionsDescription2, + marginBottom: 2, + }), + buildDescriptionField({ + id: 'conditionsDescription3', + title: '', + description: + 'Birting á hverju sem er getur því verið háð svörum frá notanda í umsókninni eða eftir utanaðkomandi gögnum sem eru sótt og sett í external data', + marginBottom: 2, }), buildCheckboxField({ id: 'conditionsCheckbox', - title: 'Conditions checkbox', + title: 'Skilyrði fyrir staka reiti', options: [ { - label: 'Check this box to see additional fields', + label: 'Hakaðu í þetta box til að sjá auka reit bistast', value: YES, }, ], @@ -45,20 +60,22 @@ export const conditionsSubsection = buildSubSection({ id: 'conditionsTextField', variant: 'textarea', rows: 8, - title: 'This field is only visible if the checkbox above is checked', + title: 'Þessi reitur er bara í boði ef hakað er í boxið hér að ofan', }), buildCheckboxField({ id: 'conditions2Checkbox', - title: 'Condition for sections or subsections', + title: 'Skilyrði fyrir section/subsection', options: [ { label: - 'Check this box to see and extra subsection being added into the stepper ------>', + 'Hakaðu í þetta box til að sjá nýtt subsection birtast í stepper ------>', value: YES, }, ], }), - buildTextField({ + buildHiddenInput({ + // This is a bit of a hack, but in order for the stepper to update and show the conditionally added step, there + // has to be a field on the current step with a matching condition. condition: (answers) => { const checkboxValue = getValueViaPath>( answers, @@ -68,9 +85,6 @@ export const conditionsSubsection = buildSubSection({ return checkboxValue ? checkboxValue[0] === YES : false }, id: 'conditionsTextField', - variant: 'textarea', - rows: 8, - title: 'Now you should see the next step in the stepper', }), ], }), diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts index c8c0d612856d..d547b188363e 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts @@ -11,8 +11,21 @@ export const descriptionSubsection = buildSubSection({ children: [ buildMultiField({ id: 'description', - title: 'The description field', + title: 'Textar með buildDescriptionField', children: [ + buildDescriptionField({ + id: 'description', + title: '', + description: m.descriptionFieldDescription, + marginBottom: [2], + }), + buildDescriptionField({ + id: 'description2', + title: '', + description: m.descriptionFieldDescription2, + marginBottom: [2], + }), + buildDescriptionField({ id: 'description', title: 'Default title size ', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts index 7ca7fa2bd956..0689b55068b1 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts @@ -6,7 +6,7 @@ import { actionCardSubsection } from './actionCardSubsection' import { keyValueSubsection } from './keyValueSubsection' export const noInputFieldsSection = buildSection({ id: 'noInputFieldsSection', - title: 'Fields with no inputs', + title: 'Fields með engin input', children: [ descriptionSubsection, dividerSubsection, diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index 77ac2eea842c..9bbebc6adb3c 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -36,6 +36,8 @@ const personSchema = z.object({ return false } return asNumber > 15 + }), +}) export const ExampleSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), @@ -81,7 +83,6 @@ export const ExampleSchema = z.object({ // someHiddenInputWatchedRequired: z // .string() // .refine((x) => x.includes('Valid')), - }), nationalId: z.string().refine((n) => n && !kennitala.isValid(n), { params: m.dataSchemeNationalId, diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index 3c9bc263e866..d85814deffac 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -268,4 +268,22 @@ export const m = defineMessages({ 'Ef valkostir í field eru allir í einu `enum`, þá skal nota `z.nativeEnum()` í zod validation til að sleppa við að lista upp alla hvern valkost í enum-inu eins og þarf að gera ef stuðst er við `z.enum()` ', description: 'Validation description', }, + conditionsDescription2: { + id: 'example.application:conditions.description2#markdown', + defaultMessage: + 'Þetta er gert á sama hátt í báðum tilvikum. Allt ætti að geta tekið inn `condition` sem parameter og condition tekur inn fall `(answers, externalData) => { ... }` sem skilar `true` eða `false`', + description: 'Validation description', + }, + descriptionFieldDescription: { + id: 'example.application:descriptionFieldDescription', + defaultMessage: + 'Allur texti sem birtist í umsóknum ætti að koma úr `lib/messages.ts`. Þessum texta er svo hlaðið upp í contentful með því að keyra `yarn nx run :extract-strings`, þar sem `` er nafnið á umsókninni eins og það er skrifað í `project.json` í viðeigandi template. Fyrir þessa umsókn er þetta `yarn nx run application-templates-reference-template:extract-strings`. Í contentfull sér skilastjóri eða starfsmaður stofnunar um að setja inn enskar þýðingar og uppfæra textan frá því sem forritari setur inn í defaultMessage.', + description: 'Description field description', + }, + descriptionFieldDescription2: { + id: 'example.application:descriptionFieldDescription2', + defaultMessage: + 'Hér eru listaðir upp allir möguleikar á texta frá buildDescriptionField. Flestir þeirra tengjast því að bæta við `#markdown` í id-ið til að geta notað markdown í textanum. Einnig er hægt að setja breytur inn í texta og stýra fyrirsagnastærð', + description: 'Description field description', + }, }) From f8eda5dcfee930802aea30b7eb0b4504c7c6a040 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 10:21:53 +0000 Subject: [PATCH 12/32] feat: make tables and repeater section --- .../application/core/src/lib/fieldBuilders.ts | 2 - .../src/forms/exampleForm/index.ts | 6 +-- .../actionCardSubsection.ts | 2 +- .../textInputSubsection.ts | 6 +-- .../StaticTableSubsection.ts} | 6 +-- .../fieldsRepeaterSubsection.ts | 46 +++++++++++++++++++ .../tablesAndRepeatersSection/index.ts | 14 ++++++ .../tableRepeaterSubsection.ts} | 4 +- libs/application/types/src/lib/Fields.ts | 13 ------ 9 files changed, 71 insertions(+), 28 deletions(-) rename libs/application/templates/reference-template/src/forms/exampleForm/{staticTableSection/StaticTableSection.ts => tablesAndRepeatersSection/StaticTableSubsection.ts} (90%) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/index.ts rename libs/application/templates/reference-template/src/forms/exampleForm/{tableRepeaterSection/tableRepeaterSection.ts => tablesAndRepeatersSection/tableRepeaterSubsection.ts} (96%) diff --git a/libs/application/core/src/lib/fieldBuilders.ts b/libs/application/core/src/lib/fieldBuilders.ts index 09338c56193a..5a66d6c8e7bf 100644 --- a/libs/application/core/src/lib/fieldBuilders.ts +++ b/libs/application/core/src/lib/fieldBuilders.ts @@ -843,7 +843,6 @@ export const buildFieldsRepeaterField = ( ): FieldsRepeaterField => { const { fields, - table, title, titleVariant, formTitle, @@ -864,7 +863,6 @@ export const buildFieldsRepeaterField = ( type: FieldTypes.FIELDS_REPEATER, component: FieldComponents.FIELDS_REPEATER, fields, - table, title, titleVariant, formTitle, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 113136c02ad4..81f5e0d66504 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -12,14 +12,13 @@ import { m } from '../../lib/messages' import { ApiActions } from '../../shared' import { introSection } from './introSection/introSection' import { simpleInputsSection } from './simpleInputsSection' -import { tableRepeaterSection } from './tableRepeaterSection/tableRepeaterSection' -import { staticTableSection } from './staticTableSection/StaticTableSection' import { compositeFieldsSection } from './compositeFieldsSection' import { commonActionsSection } from './commonActionsSection' import { customSection } from './customSection/customSection' import { overviewSection } from './overviewSection/overviewSection' import { noInputFieldsSection } from './noInputFieldsSection' import { Logo } from '../../components/Logo/Logo' +import { tablesAndRepeatersSection } from './tablesAndRepeatersSection' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', @@ -37,8 +36,7 @@ export const ExampleForm: Form = buildForm({ noInputFieldsSection, simpleInputsSection, compositeFieldsSection, - tableRepeaterSection, - staticTableSection, + tablesAndRepeatersSection, customSection, overviewSection, buildSection({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts index 3b3ad42fa004..c8dbbe772c9a 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts @@ -9,7 +9,7 @@ export const actionCardSubsection = buildSubSection({ children: [ buildActionCardListField({ id: 'actionCardList', - title: 'Action card list', + title: 'Spjöld með takka', items: (application, lang) => { return [ { diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts index 57a111407982..6068f5f7fb17 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/textInputSubsection.ts @@ -31,7 +31,7 @@ export const textInputSubsection = buildSubSection({ rightAlign: true, }), buildTextField({ - id: 'readOnlydTextInput', + id: 'readOnlyTextInput', title: '', defaultValue: 'Read only', width: 'half', @@ -85,7 +85,7 @@ export const textInputSubsection = buildSubSection({ width: 'half', }), buildTextField({ - id: 'currencyTextInput', + id: 'currencyTextInput2', title: '', placeholder: 'Variant currency ($)', variant: 'currency', @@ -93,7 +93,7 @@ export const textInputSubsection = buildSubSection({ suffix: ' $', }), buildTextField({ - id: 'currencyTextInput', + id: 'currencyTextInput3', title: '', placeholder: 'Variant currency (€)', variant: 'currency', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/StaticTableSubsection.ts similarity index 90% rename from libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/StaticTableSubsection.ts index 2661ca6e5766..2f74e254c30e 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/staticTableSection/StaticTableSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/StaticTableSubsection.ts @@ -1,10 +1,10 @@ import { - buildSection, + buildSubSection, buildStaticTableField, } from '@island.is/application/core' -export const staticTableSection = buildSection({ - id: 'staticTableSection', +export const staticTableSubsection = buildSubSection({ + id: 'staticTableSubsection', title: 'Static table', children: [ buildStaticTableField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts new file mode 100644 index 000000000000..96b8e682f1ff --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts @@ -0,0 +1,46 @@ +import { + buildDescriptionField, + buildFieldsRepeaterField, + buildMultiField, + buildSubSection, + buildTextField, +} from '@island.is/application/core' + +export const fieldsRepeaterSubsection = buildSubSection({ + id: 'fieldsRepeaterSubsection', + title: 'Fields Repeater Field', + children: [ + buildMultiField({ + id: 'fieldsRepeater', + title: 'Fields Repeater', + children: [ + buildDescriptionField({ + id: 'fieldsRepeaterDescription', + title: '', + description: + 'FieldsRepeater virkar svipað og tableRepeater, að því leiti að inni í honum er skilgreint eitthvað sett af field-um til að fylla út í og þetta sett er hægt að endurtaka eins oft og þarf. Munurinn er að í tableRepeater fara gildin inn í töflu en í fieldsRepeater þá sjást alltaf öll field sem búið er að búa til.', + }), + buildFieldsRepeaterField({ + id: 'fieldsRepeater', + title: 'Fields Repeater', + formTitle: 'Title for each form', + fields: { + nationalId: { + component: 'input', + label: 'National ID', + width: 'half', + type: 'text', + format: '######-####', + }, + fullName: { + component: 'input', + label: 'Full name', + width: 'half', + type: 'text', + }, + }, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/index.ts new file mode 100644 index 000000000000..3345edd8491e --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/index.ts @@ -0,0 +1,14 @@ +import { buildSection } from '@island.is/application/core' +import { tableRepeaterSubsection } from './tableRepeaterSubsection' +import { staticTableSubsection } from './StaticTableSubsection' +import { fieldsRepeaterSubsection } from './fieldsRepeaterSubsection' + +export const tablesAndRepeatersSection = buildSection({ + id: 'tablesAndRepeatersSection', + title: 'Tables and repeaters', + children: [ + staticTableSubsection, + tableRepeaterSubsection, + fieldsRepeaterSubsection, + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts similarity index 96% rename from libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts rename to libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts index 936f79feaeb6..3961056d679e 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tableRepeaterSection/tableRepeaterSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts @@ -1,10 +1,10 @@ import { - buildSection, + buildSubSection, buildTableRepeaterField, } from '@island.is/application/core' import { selectOptions } from '../../../utils/options' -export const tableRepeaterSection = buildSection({ +export const tableRepeaterSubsection = buildSubSection({ id: 'repeater', title: 'Table Repeater', children: [ diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts index 4a4dc73e47b3..e45a38352730 100644 --- a/libs/application/types/src/lib/Fields.ts +++ b/libs/application/types/src/lib/Fields.ts @@ -670,19 +670,6 @@ export type FieldsRepeaterField = BaseField & { */ minRows?: number maxRows?: number - table?: { - /** - * List of strings to render, - * if not provided it will be auto generated from the fields - */ - header?: StaticText[] - /** - * List of field id's to render, - * if not provided it will be auto generated from the fields - */ - rows?: string[] - format?: Record string | StaticText> - } } export type AccordionItem = { From f4d043f5f07921e78db9c9c558e06e8f4c96961c Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 14:14:31 +0000 Subject: [PATCH 13/32] feat: display field and repeaters --- .../displayFieldSubsection.ts | 104 ++++++++++ .../exampleForm/simpleInputsSection/index.ts | 2 + .../fieldsRepeaterSubsection.ts | 47 ++++- .../tableRepeaterSubsection.ts | 181 ++++++++++++------ .../FieldsRepeaterFormField.tsx | 2 +- .../FieldsRepeaterItem.tsx | 6 +- .../src/components/FormMultiField.tsx | 6 +- .../CheckboxController/CheckboxController.tsx | 2 +- 8 files changed, 281 insertions(+), 69 deletions(-) create mode 100644 libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts new file mode 100644 index 000000000000..009ea9ffeb5f --- /dev/null +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts @@ -0,0 +1,104 @@ +import { + buildSubSection, + buildDisplayField, + buildMultiField, + buildDescriptionField, + buildTextField, + getValueViaPath, + buildRadioField, +} from '@island.is/application/core' + +export const displayFieldSubsection = buildSubSection({ + id: 'displayFieldSubsection', + title: 'Display Field', + children: [ + buildMultiField({ + id: 'displayField', + title: 'Display Field', + children: [ + buildDescriptionField({ + id: 'displayFieldDescription', + title: '', + description: + 'Display field er bara read only input field bak við tjöldin. Það sem er sérstakt við display field fram yfir input er að value tekur við falli sem hlustar á breytingar í answers og uppfærist því jafn óðum og fyllt er inn í aðra reiti. ', + }), + buildTextField({ + id: 'input1', + title: 'Input 1', + variant: 'currency', + width: 'half', + rightAlign: true, + }), + buildTextField({ + id: 'input2', + title: 'Input 2', + variant: 'currency', + width: 'half', + rightAlign: true, + }), + buildTextField({ + id: 'input3', + title: 'Input 3', + variant: 'currency', + width: 'half', + rightAlign: true, + }), + buildDisplayField({ + id: 'displayField', + title: 'Display Field', + variant: 'currency', + label: 'Sum of inputs 1, 2 and 3', + rightAlign: true, + value: (answers) => { + const value1 = Number(getValueViaPath(answers, 'input1')) + const value2 = Number(getValueViaPath(answers, 'input2')) + const value3 = Number(getValueViaPath(answers, 'input3')) + return `${value1 + value2 + value3}` + }, + }), + + buildTextField({ + id: 'input4', + title: 'Upphæð leigu', + variant: 'currency', + width: 'half', + rightAlign: true, + }), + buildRadioField({ + id: 'radioFieldForDisplayField', + title: 'Trygging fyrir íbúð', + width: 'half', + options: [ + { label: 'Einföld leiga', value: '1' }, + { label: 'Tvöföld leiga', value: '2' }, + { label: 'Þreföld leiga', value: '3' }, + { label: 'Önnur upphæð', value: 'other' }, + ], + }), + buildDisplayField({ + id: 'displayField2', + title: 'Upphæð leigu', + variant: 'currency', + rightAlign: true, + value: (answers) => { + const value4 = Number(getValueViaPath(answers, 'input4')) + const value5 = getValueViaPath( + answers, + 'radioFieldForDisplayField', + ) + + if (!value4 || !value5) { + return '' + } + + if (value5 === 'other') { + return 'Önnur upphæð' + } + + return `${value4 * Number(value5)}` + }, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts index 180a28ea74f0..d4f165e3fb9f 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/index.ts @@ -9,12 +9,14 @@ import { fileUploadSubsection } from './fileUploadSubsection' import { sliderSubsection } from './sliderSubsection' import { companySearchSubsection } from './companySearchSubsection' import { asyncSelectSubsection } from './asyncSelectSubsection' +import { displayFieldSubsection } from './displayFieldSubsection' export const simpleInputsSection = buildSection({ id: 'simpleInputsSection', title: 'Simple inputs', children: [ textInputSubsection, + displayFieldSubsection, checkboxSubsection, radioSubsection, selectSubsection, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts index 96b8e682f1ff..08b5adfbf5ea 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts @@ -3,7 +3,6 @@ import { buildFieldsRepeaterField, buildMultiField, buildSubSection, - buildTextField, } from '@island.is/application/core' export const fieldsRepeaterSubsection = buildSubSection({ @@ -24,19 +23,53 @@ export const fieldsRepeaterSubsection = buildSubSection({ id: 'fieldsRepeater', title: 'Fields Repeater', formTitle: 'Title for each form', + width: 'half', fields: { - nationalId: { + input: { component: 'input', - label: 'National ID', + label: 'Regular input', width: 'half', type: 'text', format: '######-####', }, - fullName: { - component: 'input', - label: 'Full name', + select: { + component: 'select', + label: 'Select', + width: 'half', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + ], + }, + radio: { + component: 'radio', + width: 'half', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + { label: 'Option 3', value: 'option3' }, + ], + }, + checkbox: { + component: 'checkbox', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + ], + }, + date: { + component: 'date', + label: 'Date', + width: 'half', + }, + nationalIdWithName: { + component: 'nationalIdWithName', + label: 'National ID with name', + }, + phone: { + component: 'phone', + label: 'Phone', width: 'half', - type: 'text', }, }, }), diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts index 3961056d679e..609c8b66e006 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts @@ -1,73 +1,142 @@ import { + buildDescriptionField, + buildMultiField, buildSubSection, buildTableRepeaterField, } from '@island.is/application/core' import { selectOptions } from '../../../utils/options' +import { input } from 'libs/island-ui/core/src/lib/Input/Input.mixins' +import { name } from 'libs/island-ui/core/src/lib/FormStepper/FormStepperSection.css' export const tableRepeaterSubsection = buildSubSection({ id: 'repeater', title: 'Table Repeater', children: [ - buildTableRepeaterField({ + buildMultiField({ id: 'tableRepeater', title: 'Table Repeater Field', - formTitle: 'Table Repeater Form Title', // Todo: doesn't work - addItemButtonText: 'Custom Add item text', - saveItemButtonText: 'Custom Save item text', - removeButtonTooltipText: 'Custom Remove item text', - editButtonTooltipText: 'Custom Edit item text', - editField: true, - maxRows: 10, - getStaticTableData: (_application) => { - // Possibility to populate the table with data from the answers or external data - // Populated data will not be editable or deletable - return [ - { - fullName: 'John Doe', - nationalId: '000000-0000', - relation: 'select1', + children: [ + buildDescriptionField({ + id: 'tableRepeaterDescription', + title: '', + description: + 'Í table repeater smíðar þú lítið form sem notandinn fyllir út og svörunum er síðan raðað inn í töflu. Aðeins eitt eintak af þessu formi er sýnilegt á hverjum tímapunkti. Í töflunni er hægt að eyða línum og breyta, hægt er að afvirkja þessa möguleika. Einnig er hægt að setja gögn inn í töfluna út frá answers eða external data svipað og í staticTable.', + marginBottom: 2, + }), + buildDescriptionField({ + id: 'tableRepeaterDescription2', + title: '', + description: + 'Í table repeater er í boði að nota input, select, radio, checkbox, date, nationalIdWithName og phone.', + }), + buildTableRepeaterField({ + id: 'tableRepeater', + title: 'Table Repeater Field', + formTitle: 'Table Repeater Form Title', // Todo: doesn't work + addItemButtonText: 'Custom Add item text', + saveItemButtonText: 'Custom Save item text', + removeButtonTooltipText: 'Custom Remove item text', + editButtonTooltipText: 'Custom Edit item text', + editField: true, + maxRows: 10, + getStaticTableData: (_application) => { + // Possibility to populate the table with data from the answers or external data + // Populated data will not be editable or deletable + return [ + { + input: 'John Doe', + select: 'option 1', + radio: 'option 2', + checkbox: 'option 3', + date: '2024-01-01', + name: 'Test Name', + nationalId: '000000-0000', + phone: '6666666', + }, + { + input: 'Jane Doe', + select: 'option 1', + radio: 'option 2', + checkbox: 'option 3', + date: '2024-01-01', + name: 'Test Name 2', + nationalId: '100000-0000', + phone: '6666666', + }, + ] }, - { - fullName: 'Jane Doe', - nationalId: '000000-0001', - relation: 'select2', + // Possible fields: input, select, radio, checkbox, date, nationalIdWithName + fields: { + input: { + component: 'input', + label: 'Regular input', + width: 'half', + required: true, + type: 'text', + }, + select: { + component: 'select', + label: 'Select', + width: 'half', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + ], + }, + radio: { + component: 'radio', + width: 'half', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + { label: 'Option 3', value: 'option3' }, + ], + }, + checkbox: { + component: 'checkbox', + options: [ + { label: 'Option 1', value: 'option1' }, + { label: 'Option 2', value: 'option2' }, + ], + }, + date: { + component: 'date', + label: 'Date', + width: 'half', + }, + nationalIdWithName: { + component: 'nationalIdWithName', + label: 'National ID with name', + }, + phone: { + component: 'phone', + label: 'Phone', + width: 'half', + }, }, - ] - }, - // Possible fields: input, select, radio, checkbox, date, nationalIdWithName - fields: { - fullName: { - component: 'input', - label: 'Input label', - width: 'half', - type: 'text', - dataTestId: 'sibling-full-name', - }, - nationalId: { - component: 'input', - label: 'National ID label', - width: 'half', - type: 'text', - format: '######-####', - placeholder: '000000-0000', - dataTestId: 'sibling-national-id', - }, - relation: { - component: 'select', - label: 'Select label', - placeholder: 'Select placeholder', - options: selectOptions, - dataTestId: 'sibling-relation', - }, - }, - table: { - // Format values for display in the table - format: { - fullName: (value) => `${value} - custom format`, - }, - // Overwrite header for the table. If not provided, the labels from the fields will be used - header: ['Full name', 'National ID', 'Relation'], - }, + table: { + // Format values for display in the table + format: { + input: (value) => `${value} - custom format`, + nationalIdWithName: (value) => { + console.log(value) + return `${value} - custom format` + }, + }, + // Overwrite header for the table. If not provided, the labels from the fields will be used + header: [ + 'Input', + 'Select', + 'Radio', + 'Checkbox', + 'Date', + 'Name', + 'NationalId', + 'Phone', + ], + }, + }), + ], }), ], }) diff --git a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterFormField.tsx b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterFormField.tsx index 9edc6dd1890e..7504599709ac 100644 --- a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterFormField.tsx +++ b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterFormField.tsx @@ -148,7 +148,7 @@ export const FieldsRepeaterFormField = ({ {Array.from({ length: numberOfItems }).map((_i, i) => ( {(formTitleNumbering !== 'none' || formTitle) && ( - + {formTitleNumbering === 'prefix' ? `${i + 1}. ` : ''} {formTitle && diff --git a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx index 4fd041e97550..9f22d8dd6d75 100644 --- a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx +++ b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx @@ -172,17 +172,17 @@ export const Item = ({ } if (component === 'radio') { DefaultValue = - (getValueViaPath(application.answers, id) as string[]) ?? + getValueViaPath>(application.answers, id) ?? getDefaultValue(item, application, activeValues) } if (component === 'checkbox') { DefaultValue = - (getValueViaPath(application.answers, id) as string[]) ?? + getValueViaPath>(application.answers, id) ?? getDefaultValue(item, application, activeValues) } if (component === 'date') { DefaultValue = - (getValueViaPath(application.answers, id) as string) ?? + getValueViaPath(application.answers, id) ?? getDefaultValue(item, application, activeValues) } diff --git a/libs/application/ui-shell/src/components/FormMultiField.tsx b/libs/application/ui-shell/src/components/FormMultiField.tsx index f8575bee8bdc..974f397865e2 100644 --- a/libs/application/ui-shell/src/components/FormMultiField.tsx +++ b/libs/application/ui-shell/src/components/FormMultiField.tsx @@ -18,7 +18,11 @@ import ConditionHandler from './ConditionHandler' import FormField from './FormField' import { FieldDef, MultiFieldScreen } from '../types' -const IGNORED_HALF_TYPES: FieldTypes[] = [FieldTypes.RADIO, FieldTypes.CHECKBOX] +const IGNORED_HALF_TYPES: FieldTypes[] = [ + FieldTypes.RADIO, + FieldTypes.CHECKBOX, + FieldTypes.FIELDS_REPEATER, +] const FormMultiField: FC< React.PropsWithChildren<{ diff --git a/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx b/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx index 9ba60f83e90b..3ec09734b58c 100644 --- a/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx +++ b/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx @@ -44,7 +44,7 @@ export const CheckboxController: FC< error, id, name = id, - large, + large = true, strong, options = [], split = '1/1', From 7c80bf4c9d61141c15149a12c8284e08cd317938 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 14:20:47 +0000 Subject: [PATCH 14/32] chore: move large to the repeaterItems --- .../src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx | 1 + .../src/lib/TableRepeaterFormField/TableRepeaterItem.tsx | 1 + .../src/lib/CheckboxController/CheckboxController.tsx | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx index 9f22d8dd6d75..df4f221ff91e 100644 --- a/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx +++ b/libs/application/ui-fields/src/lib/FieldsRepeaterFormField/FieldsRepeaterItem.tsx @@ -216,6 +216,7 @@ export const Item = ({ }} application={application} defaultValue={DefaultValue} + large={true} {...props} /> diff --git a/libs/application/ui-fields/src/lib/TableRepeaterFormField/TableRepeaterItem.tsx b/libs/application/ui-fields/src/lib/TableRepeaterFormField/TableRepeaterItem.tsx index 5388065f176f..a65e25164f5b 100644 --- a/libs/application/ui-fields/src/lib/TableRepeaterFormField/TableRepeaterItem.tsx +++ b/libs/application/ui-fields/src/lib/TableRepeaterFormField/TableRepeaterItem.tsx @@ -216,6 +216,7 @@ export const Item = ({ }} application={application} defaultValue={DefaultValue} + large={true} {...props} /> diff --git a/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx b/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx index 3ec09734b58c..9ba60f83e90b 100644 --- a/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx +++ b/libs/shared/form-fields/src/lib/CheckboxController/CheckboxController.tsx @@ -44,7 +44,7 @@ export const CheckboxController: FC< error, id, name = id, - large = true, + large, strong, options = [], split = '1/1', From 99e953a5af93b29ed21089beb691f33d17688c3a Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 14:43:05 +0000 Subject: [PATCH 15/32] chore: update readme files --- .../templates/reference-template/README.md | 3 +++ .../reference-template/src/assets/README.md | 4 ++++ .../src/dataProviders/README.md | 3 +++ .../src/dataProviders/index.ts | 5 +---- .../reference-template/src/fields/README.md | 2 +- .../reference-template/src/fields/index.ts | 2 +- .../reference-template/src/graphql/README.md | 3 +++ .../reference-template/src/lib/README.md | 17 +++++++++++++++++ .../reference-template/src/utils/README.md | 5 +++++ 9 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 libs/application/templates/reference-template/src/assets/README.md create mode 100644 libs/application/templates/reference-template/src/dataProviders/README.md create mode 100644 libs/application/templates/reference-template/src/graphql/README.md create mode 100644 libs/application/templates/reference-template/src/lib/README.md create mode 100644 libs/application/templates/reference-template/src/utils/README.md diff --git a/libs/application/templates/reference-template/README.md b/libs/application/templates/reference-template/README.md index 028f936a0606..62901a5a29e7 100644 --- a/libs/application/templates/reference-template/README.md +++ b/libs/application/templates/reference-template/README.md @@ -81,10 +81,13 @@ The aim is to have all applications to be coded in a similar way, so that every ## Folder structure +|-- assets - optional folder for assets like images, icons, etc. |-- components - optional folder for React components that are used by custom components. |-- dataProviders - folder for data providers. |-- fields - optional folder for custom components if the application needs any. |-- forms - folder for forms. +|-- graphql - optional folder for graphql queries and mutations. |-- lib - folder for data schema, messages, and the main template file. +| |-- messages - optional folder for messages if there is a need to have the messages more organized. |-- shared - optional folder for code that might be needed in the template-api-modules or other places outside the template. |-- utils - folder for utility functions, constants, enums and types. diff --git a/libs/application/templates/reference-template/src/assets/README.md b/libs/application/templates/reference-template/src/assets/README.md new file mode 100644 index 000000000000..2355070ab130 --- /dev/null +++ b/libs/application/templates/reference-template/src/assets/README.md @@ -0,0 +1,4 @@ +# Assets + +This folder is optional and can be used to store assets like images, icons, etc. +Organization within this folder id up to the developer. diff --git a/libs/application/templates/reference-template/src/dataProviders/README.md b/libs/application/templates/reference-template/src/dataProviders/README.md new file mode 100644 index 000000000000..3f47dfa8bfa2 --- /dev/null +++ b/libs/application/templates/reference-template/src/dataProviders/README.md @@ -0,0 +1,3 @@ +# Data Providers + +This folder is for all the data providers that are run in the prerequisites form. diff --git a/libs/application/templates/reference-template/src/dataProviders/index.ts b/libs/application/templates/reference-template/src/dataProviders/index.ts index 29a2b6528729..e60ea65b2a39 100644 --- a/libs/application/templates/reference-template/src/dataProviders/index.ts +++ b/libs/application/templates/reference-template/src/dataProviders/index.ts @@ -1,9 +1,6 @@ import { defineTemplateApi } from '@island.is/application/types' import { MockProviderApi } from '@island.is/application/types' -import { - NationalRegistryUserApi, - UserProfileApi, -} from '@island.is/application/types' +import { NationalRegistryUserApi } from '@island.is/application/types' export interface MyParameterType { id: number } diff --git a/libs/application/templates/reference-template/src/fields/README.md b/libs/application/templates/reference-template/src/fields/README.md index c0f2d54fb2bf..2bb8efcb7efd 100644 --- a/libs/application/templates/reference-template/src/fields/README.md +++ b/libs/application/templates/reference-template/src/fields/README.md @@ -7,7 +7,7 @@ This folder contains all custom components that are used by the application. - All components should be in a folder that holds all files for that component. This includes the .tsx file, possibly a .css.ts file and maybe others. The folders should be named like the component, but with the first letter in lowercase (camelCase), and then the .tsx and .css.ts files should be capitalized (PascalCase). - The folder should have an index.ts file that re-exports all the components. -- The index.ts file in the /src folder should then re-export the components in the /fields folder. +- The index.ts file in the /src folder should then re-export the components in the /fields folder for the template loader. ## Useage of custom components diff --git a/libs/application/templates/reference-template/src/fields/index.ts b/libs/application/templates/reference-template/src/fields/index.ts index 849894504a49..b22c5c5abe35 100644 --- a/libs/application/templates/reference-template/src/fields/index.ts +++ b/libs/application/templates/reference-template/src/fields/index.ts @@ -1,4 +1,4 @@ export { default as ExampleCountryField } from './ExampleCountryField' export { default as CustomRepeater } from './CustomRepeater' -export { TestCustomComponent } from './TestCustomComponent/TestCustomComponent' +export { TestCustomComponent } from './testCustomComponent/TestCustomComponent' export { Overview } from './Overview/Overview' diff --git a/libs/application/templates/reference-template/src/graphql/README.md b/libs/application/templates/reference-template/src/graphql/README.md new file mode 100644 index 000000000000..a9bcbd3f5a95 --- /dev/null +++ b/libs/application/templates/reference-template/src/graphql/README.md @@ -0,0 +1,3 @@ +# Graphql + +This folder is optional and can be used for all the graphql queries and mutations that are used by the application. diff --git a/libs/application/templates/reference-template/src/lib/README.md b/libs/application/templates/reference-template/src/lib/README.md new file mode 100644 index 000000000000..538841b09b22 --- /dev/null +++ b/libs/application/templates/reference-template/src/lib/README.md @@ -0,0 +1,17 @@ +# The lib folder + +This folder contains all the data schema, messages, and the main template file. + +## Data schema + +The data schema defines what the answer object should look like. All validation is done with zod. + +## Messages + +Messages can either be one single file with all messages needed for the application. If more organization is needed, /messages can also be a folder with the messages split up into multiple files. + +## Main template file + +The main template file holds the state machine for the application. It defines how the application should flow from one state to the next and which form to load in each state. Here you can also leverage the `mapUserToRole` function to define which role the user has in the application. This allows you to display different forms to different users even if the application is in the same state. This can be usefull for applications that can both be done as an individual and as a procurer. + +The state machine also holds the actions that are run when the application is in a certain state. diff --git a/libs/application/templates/reference-template/src/utils/README.md b/libs/application/templates/reference-template/src/utils/README.md new file mode 100644 index 000000000000..1de70d5a8989 --- /dev/null +++ b/libs/application/templates/reference-template/src/utils/README.md @@ -0,0 +1,5 @@ +# Utils + +This folder is for all the utility functions, constants, enums and types. + +The organization of this folder is up to the developer. Try to aim for a happy medium between small focused files and too many files that bloat the folder. The aim is that a developer can enter this folder and understand what the utils are for and have a nice overview of the utils. From 4f43bc2fce6770f4e3083d18798322b5643ae85a Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 14:57:10 +0000 Subject: [PATCH 16/32] chore: remove unused import --- .../templates/reference-template/src/components/Logo/Logo.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/application/templates/reference-template/src/components/Logo/Logo.tsx b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx index e3ff03fa7c07..375ce16ce50f 100644 --- a/libs/application/templates/reference-template/src/components/Logo/Logo.tsx +++ b/libs/application/templates/reference-template/src/components/Logo/Logo.tsx @@ -1,6 +1,5 @@ import { useEffect, useState } from 'react' import { Application } from '@island.is/application/types' -import { getValueViaPath } from '@island.is/application/core' type Props = { application: Application From ce7304a2abacb984cfd7e927cce8348c971ead47 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 14:59:49 +0000 Subject: [PATCH 17/32] chore: remove fieldsRepeater from ignored half types --- libs/application/ui-shell/src/components/FormMultiField.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libs/application/ui-shell/src/components/FormMultiField.tsx b/libs/application/ui-shell/src/components/FormMultiField.tsx index 974f397865e2..f8575bee8bdc 100644 --- a/libs/application/ui-shell/src/components/FormMultiField.tsx +++ b/libs/application/ui-shell/src/components/FormMultiField.tsx @@ -18,11 +18,7 @@ import ConditionHandler from './ConditionHandler' import FormField from './FormField' import { FieldDef, MultiFieldScreen } from '../types' -const IGNORED_HALF_TYPES: FieldTypes[] = [ - FieldTypes.RADIO, - FieldTypes.CHECKBOX, - FieldTypes.FIELDS_REPEATER, -] +const IGNORED_HALF_TYPES: FieldTypes[] = [FieldTypes.RADIO, FieldTypes.CHECKBOX] const FormMultiField: FC< React.PropsWithChildren<{ From 3ccc972601694935a69da10dc2d329ce619f1f68 Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 15:00:25 +0000 Subject: [PATCH 18/32] chore: add space to comment --- .../forms/exampleForm/simpleInputsSection/checkboxSubsection.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts index 0cb98c321334..e6c7230dbd83 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/checkboxSubsection.ts @@ -16,7 +16,7 @@ export const checkboxSubsection = buildSubSection({ buildCheckboxField({ id: 'checkbox', title: 'Full width checkboxes', - options: checkboxOptions, // Importing options from utils makes the templatemuch more readable + options: checkboxOptions, // Importing options from utils makes the template much more readable }), buildCheckboxField({ id: 'checkboxHalf', From dd74772b998becbbc95d1074328c912d0e02c99c Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 15:08:46 +0000 Subject: [PATCH 19/32] chore: update folder structure --- .../templates/reference-template/src/forms/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/README.md b/libs/application/templates/reference-template/src/forms/README.md index 4a39d8668337..604eb5bf96cf 100644 --- a/libs/application/templates/reference-template/src/forms/README.md +++ b/libs/application/templates/reference-template/src/forms/README.md @@ -19,10 +19,10 @@ Example folder structure: | /applicationForm | |-- index.ts (This file has a buildForm function) | |-- /section1 -| | |-- index.ts (This file has a buildSection function) -| | |-- /subsection1.ts (This file has a buildSubSection function) -| | |-- /subsection2.ts (This file has a buildSubSection function) -| | |-- /subsection3.ts (This file has a buildSubSection function) +| | |-- index.ts (This file has a buildSection function and imports the subsection childs) +| | |-- subsection1.ts (This file has a buildSubSection function) +| | |-- subsection2.ts (This file has a buildSubSection function) +| | |-- subsection3.ts (This file has a buildSubSection function) | |-- /section2 | | |-- index.ts (This file has a buildSection function) | |-- /section3 From 5aa66eb25d3e05b82c887fade419d198e91dbe1a Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 15:22:14 +0000 Subject: [PATCH 20/32] chore: document tabtitle --- .../src/forms/prerequisitesForm/prerequisitesForm.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts index b57d83e26973..fafd26110db1 100644 --- a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts +++ b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts @@ -36,6 +36,7 @@ export const Prerequisites: Form = buildForm({ buildSection({ id: 'conditions', title: '', // If this is empty, we will not have a visible stepper on the right side of the screen. + tabTitle: 'Forkröfur', // If there is no stepper, add tabTitle to have a title on the browser tab. children: [ buildExternalDataProvider({ id: 'approveExternalData', From 355d230090af6231d73e2cada8da56036f984a4f Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 15:56:17 +0000 Subject: [PATCH 21/32] chore: update readme --- .../src/assets/plate-110-510.tsx | 6 +++--- .../src/assets/plate-155-305.tsx | 6 +++--- .../src/assets/plate-200-280.tsx | 6 +++--- .../src/fields/Overview/Overview.tsx | 2 +- .../reference-template/src/forms/README.md | 16 ++++++++++++++++ 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/libs/application/templates/reference-template/src/assets/plate-110-510.tsx b/libs/application/templates/reference-template/src/assets/plate-110-510.tsx index 0fb47c525126..f27f9a43737a 100644 --- a/libs/application/templates/reference-template/src/assets/plate-110-510.tsx +++ b/libs/application/templates/reference-template/src/assets/plate-110-510.tsx @@ -1,12 +1,12 @@ -import { FC } from 'react' - -export const plate110: FC> = () => ( +export const plate110 = () => ( > = () => ( +export const plate155 = () => ( > = () => ( +export const plate200 = () => ( Date: Tue, 17 Dec 2024 16:00:37 +0000 Subject: [PATCH 22/32] chore: unique ids --- .../descriptionSubsection.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts index d547b188363e..43dab73b1328 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/descriptionSubsection.ts @@ -10,11 +10,11 @@ export const descriptionSubsection = buildSubSection({ title: 'Description', children: [ buildMultiField({ - id: 'description', + id: 'descriptionMultiField', title: 'Textar með buildDescriptionField', children: [ buildDescriptionField({ - id: 'description', + id: 'description1', title: '', description: m.descriptionFieldDescription, marginBottom: [2], @@ -27,7 +27,7 @@ export const descriptionSubsection = buildSubSection({ }), buildDescriptionField({ - id: 'description', + id: 'description3', title: 'Default title size ', description: 'Description inserted as a regular string', marginBottom: [2], @@ -35,35 +35,35 @@ export const descriptionSubsection = buildSubSection({ titleTooltip: 'Title tooltip text', }), buildDescriptionField({ - id: 'description', + id: 'description4', title: 'h1 title size', titleVariant: 'h1', description: m.regularTextExample, marginBottom: [2], }), buildDescriptionField({ - id: 'description', + id: 'description5', title: 'h2 title size (same as default)', titleVariant: 'h2', description: m.markdownHeadingExample, marginBottom: [2], }), buildDescriptionField({ - id: 'description', + id: 'description6', title: 'h3 title size', titleVariant: 'h3', description: m.markdownBulletListExample, marginBottom: [2], }), buildDescriptionField({ - id: 'description', + id: 'description7', title: 'h4 title size', titleVariant: 'h4', description: m.markdownNumberedListExample, marginBottom: [2], }), buildDescriptionField({ - id: 'description', + id: 'description8', title: 'h5 title size', titleVariant: 'h5', description: { @@ -73,7 +73,7 @@ export const descriptionSubsection = buildSubSection({ marginBottom: [2], }), buildDescriptionField({ - id: 'description', + id: 'description9', title: '', description: m.markdownCodeExample, marginBottom: [2], From 67877173d145b287933fac6d0927780c5fb08e0a Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 16:22:34 +0000 Subject: [PATCH 23/32] chore: update readme --- .../templates/reference-template/README.md | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/libs/application/templates/reference-template/README.md b/libs/application/templates/reference-template/README.md index 62901a5a29e7..85b75745395d 100644 --- a/libs/application/templates/reference-template/README.md +++ b/libs/application/templates/reference-template/README.md @@ -81,13 +81,36 @@ The aim is to have all applications to be coded in a similar way, so that every ## Folder structure -|-- assets - optional folder for assets like images, icons, etc. -|-- components - optional folder for React components that are used by custom components. -|-- dataProviders - folder for data providers. -|-- fields - optional folder for custom components if the application needs any. -|-- forms - folder for forms. -|-- graphql - optional folder for graphql queries and mutations. -|-- lib - folder for data schema, messages, and the main template file. -| |-- messages - optional folder for messages if there is a need to have the messages more organized. -|-- shared - optional folder for code that might be needed in the template-api-modules or other places outside the template. -|-- utils - folder for utility functions, constants, enums and types. +|-- assets/--------------------------------# optional folder for assets like images, icons, etc. +| +|-- components/----------------------------# optional folder for React components that are used by custom components. +| +|-- dataProviders/-------------------------# folder for data providers. +| +|-- fields/--------------------------------# optional folder for custom components if the application needs any. +|-- |-- index.ts---------------------------# Exports all fields from the folder. +|-- |-- myCustomComponent/-----------------# Folder for a custom component, camelCase. +|-- |-- |-- MyCustomComponent.tsx----------# React component file, PascalCase. +|-- |-- |-- MyCustomComponent.css.ts-------# CSS file, PascalCase. +| +|-- forms/---------------------------------# folder for forms. More about form folder structure in the form folder README. +|-- |-- prerequisitesForm/ +|-- |-- mainForm/ +|-- |-- conclusionForm/--------------------# More forms if needed +| +|-- graphql/-------------------------------# optional folder for graphql queries and mutations. +| +|-- lib/-----------------------------------# folder for data schema, messages, and the main template file. +|-- |-- dataScema.ts-----------------------# Validation for the application. +|-- |-- mainTemplate.ts--------------------# Main template file. State machine for the application, mapUsersToRole and more +|-- |-- messages.ts------------------------# File for all text that appears on the screen, synced with Contentful. +|-- |-- messages/--------------------------# optional folder for messages if there is a need to have the messages more organized. +| +|-- shared/--------------------------------# optional folder for code that might be needed in the template-api-modules or +|------------------------------------------# other places outside the template. +| +|-- utils/---------------------------------# folder for utility functions, constants, enums and types. +|-- |-- constants.ts-----------------------# Constants for the application. +|-- |-- enums.ts---------------------------# Enums for the application. +|-- |-- types.ts---------------------------# Types for the application. +|-- |-- helperFunctions.ts-----------------# Helper functions for the application, this can be many files. From 264a281a8e976d9b039ef3212b3f63eecd4e0ddf Mon Sep 17 00:00:00 2001 From: Jonni Date: Tue, 17 Dec 2024 16:35:26 +0000 Subject: [PATCH 24/32] fix: build --- .../ExampleCustomComponent.css.ts} | 0 .../ExampleCustomComponent.tsx} | 4 ++-- .../templates/reference-template/src/fields/index.ts | 2 +- .../src/forms/exampleForm/customSection/customSection.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename libs/application/templates/reference-template/src/fields/{TestCustomComponent/TestCustomComponent.css.ts => exampleCustomComponent/ExampleCustomComponent.css.ts} (100%) rename libs/application/templates/reference-template/src/fields/{TestCustomComponent/TestCustomComponent.tsx => exampleCustomComponent/ExampleCustomComponent.tsx} (90%) diff --git a/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts b/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.css.ts similarity index 100% rename from libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.css.ts rename to libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.css.ts diff --git a/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx b/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx similarity index 90% rename from libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx rename to libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx index dc45de845b17..11d96f127265 100644 --- a/libs/application/templates/reference-template/src/fields/TestCustomComponent/TestCustomComponent.tsx +++ b/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx @@ -1,6 +1,6 @@ import { FieldBaseProps } from '@island.is/application/types' import { useLocale } from '@island.is/localization' -import * as styles from './TestCustomComponent.css' +import * as styles from './ExampleCustomComponent.css' import { Box, Text } from '@island.is/island-ui/core' import { m } from '../../lib/messages' @@ -12,7 +12,7 @@ interface Props { } } -export const TestCustomComponent = ({ +export const ExampleCustomComponent = ({ application, field, }: Props & FieldBaseProps) => { diff --git a/libs/application/templates/reference-template/src/fields/index.ts b/libs/application/templates/reference-template/src/fields/index.ts index b22c5c5abe35..03cac91d34b8 100644 --- a/libs/application/templates/reference-template/src/fields/index.ts +++ b/libs/application/templates/reference-template/src/fields/index.ts @@ -1,4 +1,4 @@ export { default as ExampleCountryField } from './ExampleCountryField' export { default as CustomRepeater } from './CustomRepeater' -export { TestCustomComponent } from './testCustomComponent/TestCustomComponent' +export { ExampleCustomComponent } from './exampleCustomComponent/ExampleCustomComponent' export { Overview } from './Overview/Overview' diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts index c98dd2f0e95b..bbf89d7f9240 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/customSection/customSection.ts @@ -30,7 +30,7 @@ export const customSection = buildSection({ { id: 'customComponent', title: 'The custom component', - component: 'TestCustomComponent', + component: 'ExampleCustomComponent', }, { someData: ['foo', 'bar', 'baz'], From 5c4030d4cf084727a60369d1bc53056d140ce3eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3nas=20G=2E=20Sigur=C3=B0sson?= Date: Wed, 18 Dec 2024 11:34:21 +0000 Subject: [PATCH 25/32] Update libs/application/templates/reference-template/src/forms/README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Þórarinn Gunnar Árnason --- .../templates/reference-template/src/forms/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/application/templates/reference-template/src/forms/README.md b/libs/application/templates/reference-template/src/forms/README.md index a2f942b85c73..27ec67b4d251 100644 --- a/libs/application/templates/reference-template/src/forms/README.md +++ b/libs/application/templates/reference-template/src/forms/README.md @@ -3,7 +3,7 @@ This folder contains all the forms that are used by the application. At minimum there should be a prerequisites form, application form and a confirmation form to reflect the possible states of an application. -For more complecated applications you could have different forms depending on the user type and you could have more states like approved, rejected, waiting to assign... +For more complicated applications you could have different forms depending on the user type and you could have more states like approved, rejected, waiting to assign... ## Organization From 5503e0cdee0d588d8236544a4af9ac414c062938 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 12:27:47 +0000 Subject: [PATCH 26/32] chore: remove console.log --- .../tablesAndRepeatersSection/tableRepeaterSubsection.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts index 609c8b66e006..a2dfcad88b05 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts @@ -119,7 +119,6 @@ export const tableRepeaterSubsection = buildSubSection({ format: { input: (value) => `${value} - custom format`, nationalIdWithName: (value) => { - console.log(value) return `${value} - custom format` }, }, From 9222a2dd3470259683880c69386e9d7433518e69 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 12:32:32 +0000 Subject: [PATCH 27/32] chore: use destructed values in slider field --- .../lib/SliderFormField/SliderFormField.tsx | 53 ++++++++----------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx index a33b9b8b1980..06d6431bf173 100644 --- a/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx +++ b/libs/application/ui-fields/src/lib/SliderFormField/SliderFormField.tsx @@ -24,7 +24,6 @@ export const SliderFormField: FC< id, min, max, - title, trackStyle, calculateCellStyle, showLabel, @@ -39,6 +38,8 @@ export const SliderFormField: FC< snap, step, saveAsString, + marginTop, + marginBottom, } = field const { clearErrors, setValue } = useFormContext() const { formatMessage } = useLocale() @@ -64,49 +65,41 @@ export const SliderFormField: FC< ) return ( - + ( { - clearErrors(field.id) - const value = field.saveAsString ? String(val) : val + clearErrors(id) + const value = saveAsString ? String(val) : val onChange(value) - setValue(field.id, value) + setValue(id, value) }} - onChangeEnd={field.onChangeEnd} - labelMultiplier={field.labelMultiplier} + onChangeEnd={onChangeEnd} + labelMultiplier={labelMultiplier} /> )} /> From b38d59724f5ce7958db55c24039424bf1877f7d6 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 12:36:40 +0000 Subject: [PATCH 28/32] chore: remove unused import --- .../exampleCustomComponent/ExampleCustomComponent.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx b/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx index 11d96f127265..cdb92ea3e1fc 100644 --- a/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx +++ b/libs/application/templates/reference-template/src/fields/exampleCustomComponent/ExampleCustomComponent.tsx @@ -7,15 +7,12 @@ import { m } from '../../lib/messages' interface Props { field: { props: { - someData: string[] + someData: Array } } } -export const ExampleCustomComponent = ({ - application, - field, -}: Props & FieldBaseProps) => { +export const ExampleCustomComponent = ({ field }: Props & FieldBaseProps) => { const { formatMessage } = useLocale() const { someData } = field.props if (!someData) return null From adf14a53cfb1abb3d035126a061774cb7d569b1c Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 13:25:52 +0000 Subject: [PATCH 29/32] chore: transleat all to english --- .../conditions2Subsection.ts | 6 +- .../conditionsSubsection.ts | 10 +- .../getDataFromExternalDataSection.ts | 12 +- .../exampleForm/commonActionsSection/index.ts | 2 +- .../validadionSubsection.ts | 4 +- .../src/forms/exampleForm/index.ts | 6 +- .../actionCardSubsection.ts | 2 +- .../exampleForm/noInputFieldsSection/index.ts | 2 +- .../displayFieldSubsection.ts | 2 +- .../fieldsRepeaterSubsection.ts | 2 +- .../tableRepeaterSubsection.ts | 4 +- .../forms/pendingReviewForm/pendingReview.ts | 4 +- .../prerequisitesForm/prerequisitesForm.ts | 6 +- .../src/forms/rejectedForm/rejectedForm.ts | 4 +- .../reviewApplication.ts | 12 +- .../waitingToAssignForm.ts | 10 +- .../reference-template/src/lib/messages.ts | 108 +++++------------- 17 files changed, 70 insertions(+), 126 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts index 38634d1f3e5d..1ecda91a53d1 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditions2Subsection.ts @@ -15,13 +15,13 @@ export const conditions2Subsection = buildSubSection({ return checkbox2Value ? checkbox2Value[0] === YES : false }, id: 'condition2Subsection', - title: 'Þetta section er skilyrt', + title: 'This section is conditional', children: [ buildDescriptionField({ id: 'condition2Description', - title: 'Þessi skjár sést byggt á fyrri svörum', + title: 'This screens visibility is based in previous answers', description: - 'Með þessari virkni getur umsóknin greinst í sundur og safnað mismunandi gögnum fyrir mismunandi svör notenda', + 'With this functionality, the application can branch and collect different data for different users', }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts index 6086e7228436..7456d5b66dfd 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/conditionsSubsection.ts @@ -22,7 +22,7 @@ export const conditionsSubsection = buildSubSection({ id: 'conditionsDescription', title: '', description: - 'Hægt er að skilyrða bæði staka reiti og texta eða heil section/subsection', + 'It is possible to condition both single fields and text or an entire section/subsection', marginBottom: 2, }), buildDescriptionField({ @@ -35,7 +35,7 @@ export const conditionsSubsection = buildSubSection({ id: 'conditionsDescription3', title: '', description: - 'Birting á hverju sem er getur því verið háð svörum frá notanda í umsókninni eða eftir utanaðkomandi gögnum sem eru sótt og sett í external data', + 'The visibility of everything can be dependent on the users answers in the application or data that has been fetched and placed in externalData.', marginBottom: 2, }), buildCheckboxField({ @@ -43,7 +43,7 @@ export const conditionsSubsection = buildSubSection({ title: 'Skilyrði fyrir staka reiti', options: [ { - label: 'Hakaðu í þetta box til að sjá auka reit bistast', + label: 'Check this box to see an extra field appear', value: YES, }, ], @@ -60,7 +60,7 @@ export const conditionsSubsection = buildSubSection({ id: 'conditionsTextField', variant: 'textarea', rows: 8, - title: 'Þessi reitur er bara í boði ef hakað er í boxið hér að ofan', + title: 'This field is only available if the box above is checked', }), buildCheckboxField({ id: 'conditions2Checkbox', @@ -68,7 +68,7 @@ export const conditionsSubsection = buildSubSection({ options: [ { label: - 'Hakaðu í þetta box til að sjá nýtt subsection birtast í stepper ------>', + 'Check this box to see a new subsection appear in the stepper ------>', value: YES, }, ], diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts index 535832296c8c..b922ca75751a 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/getDataFromExternalDataSection.ts @@ -16,12 +16,12 @@ export const getDataFromExternalDataSubsection = buildSubSection({ children: [ buildDescriptionField({ id: 'externalDataSuccessTitle', - title: 'Dæmi um að gögn séu sótt úr external data', + title: 'Example of data being fetched from external data', marginBottom: [4], }), buildDescriptionField({ id: 'externalDataSuccessDescription', - title: 'Gildi frá data provider', + title: 'Value from data provider', titleVariant: 'h4', description: (application: Application) => { const value = getValueViaPath( @@ -29,7 +29,7 @@ export const getDataFromExternalDataSubsection = buildSubSection({ 'getReferenceData.data.referenceData.applicantName', ) - return value ?? 'Fannst ekki' + return value ?? 'Not found' }, }), buildDescriptionField({ @@ -41,20 +41,20 @@ export const getDataFromExternalDataSubsection = buildSubSection({ 'getReferenceData.data.referenceData.numbers', ) - return value ? `${value}` : 'Fannst ekki' + return value ? `${value}` : 'Not found' }, marginBottom: [2], }), buildDescriptionField({ id: 'externalDataSuccessDescriptionMock', - title: 'Gildi frá mock data provider', + title: 'Value from mock data provider', titleVariant: 'h4', description: (application: Application) => { const value = getValueViaPath( application.externalData, 'referenceMock.data.mockObject.mockString', ) - return value ?? 'Fannst ekki' + return value ?? 'Not found' }, }), ], diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts index fcbb9bdc73e9..f58a19aa98d8 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/index.ts @@ -6,7 +6,7 @@ import { validationSubsection } from './validadionSubsection' export const commonActionsSection = buildSection({ id: 'commonActions', - title: 'Algengar aðgerðir', + title: 'Common actions', children: [ getDataFromExternalDataSubsection, validationSubsection, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts index 6a599baa6b1f..c40b13340bef 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/commonActionsSection/validadionSubsection.ts @@ -26,11 +26,11 @@ export const validationSubsection = buildSubSection({ id: 'validationDescriptionField2', title: '', description: - 'Allir reitir á þessari síðu eru með validation sem verður að fylla út til að halda áfram', + 'All fields on this page have validation that must be filled out to continue', }), buildTextField({ id: 'validation.validationTextField', - title: 'Verður að vera 3 stafir eða meira', + title: 'Must be 3 characters or more', required: true, // Adds the red star to the field }), buildDescriptionField({ diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts index 81f5e0d66504..3ae9601aad80 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/index.ts @@ -8,7 +8,6 @@ import { buildRedirectToServicePortalField, } from '@island.is/application/core' import { Application, Form, FormModes } from '@island.is/application/types' -import { m } from '../../lib/messages' import { ApiActions } from '../../shared' import { introSection } from './introSection/introSection' import { simpleInputsSection } from './simpleInputsSection' @@ -19,6 +18,7 @@ import { overviewSection } from './overviewSection/overviewSection' import { noInputFieldsSection } from './noInputFieldsSection' import { Logo } from '../../components/Logo/Logo' import { tablesAndRepeatersSection } from './tablesAndRepeatersSection' +import { m } from '../../lib/messages' export const ExampleForm: Form = buildForm({ id: 'ExampleFormDraft', @@ -56,9 +56,9 @@ export const ExampleForm: Form = buildForm({ }), buildDescriptionField({ id: 'overview', - title: 'Takk fyrir að sækja um', + title: 'Thank you for applying', description: - 'Með því að smella á "Senda" hér að neðan, þá sendist umsóknin inn til úrvinnslu. Við látum þig vita þegar hún er samþykkt eða henni er hafnað.', + 'By clicking "Submit" below, the application will be sent for processing. We will let you know when it is accepted or rejected.', }), ], }), diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts index c8dbbe772c9a..9c8716473b04 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/actionCardSubsection.ts @@ -9,7 +9,7 @@ export const actionCardSubsection = buildSubSection({ children: [ buildActionCardListField({ id: 'actionCardList', - title: 'Spjöld með takka', + title: 'Action cards with buttons', items: (application, lang) => { return [ { diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts index 0689b55068b1..08fc70f9ad47 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/noInputFieldsSection/index.ts @@ -6,7 +6,7 @@ import { actionCardSubsection } from './actionCardSubsection' import { keyValueSubsection } from './keyValueSubsection' export const noInputFieldsSection = buildSection({ id: 'noInputFieldsSection', - title: 'Fields með engin input', + title: 'Fields without inputs', children: [ descriptionSubsection, dividerSubsection, diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts index 009ea9ffeb5f..13bce1204a8e 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/displayFieldSubsection.ts @@ -20,7 +20,7 @@ export const displayFieldSubsection = buildSubSection({ id: 'displayFieldDescription', title: '', description: - 'Display field er bara read only input field bak við tjöldin. Það sem er sérstakt við display field fram yfir input er að value tekur við falli sem hlustar á breytingar í answers og uppfærist því jafn óðum og fyllt er inn í aðra reiti. ', + 'Display field is just a read only input field behind the scenes. What is special about the display field is that the value takes a function that listens to changes in answers and updates the value accordingly. This is useful for displaying sums, multiples or anything else that is calculated from other fields.', }), buildTextField({ id: 'input1', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts index 08b5adfbf5ea..a38927bf858a 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/fieldsRepeaterSubsection.ts @@ -17,7 +17,7 @@ export const fieldsRepeaterSubsection = buildSubSection({ id: 'fieldsRepeaterDescription', title: '', description: - 'FieldsRepeater virkar svipað og tableRepeater, að því leiti að inni í honum er skilgreint eitthvað sett af field-um til að fylla út í og þetta sett er hægt að endurtaka eins oft og þarf. Munurinn er að í tableRepeater fara gildin inn í töflu en í fieldsRepeater þá sjást alltaf öll field sem búið er að búa til.', + 'FieldsRepeater works similarly to tableRepeater, in that it contains a set of fields to fill out and this set can be repeated as many times as needed. The difference is that in tableRepeater, the values go into a table, while in fieldsRepeater, all fields created are always visible.', }), buildFieldsRepeaterField({ id: 'fieldsRepeater', diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts index a2dfcad88b05..22dc4428a3fb 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts @@ -20,14 +20,14 @@ export const tableRepeaterSubsection = buildSubSection({ id: 'tableRepeaterDescription', title: '', description: - 'Í table repeater smíðar þú lítið form sem notandinn fyllir út og svörunum er síðan raðað inn í töflu. Aðeins eitt eintak af þessu formi er sýnilegt á hverjum tímapunkti. Í töflunni er hægt að eyða línum og breyta, hægt er að afvirkja þessa möguleika. Einnig er hægt að setja gögn inn í töfluna út frá answers eða external data svipað og í staticTable.', + 'In the table repeater, you create a small form that the user fills out and the answers are then sorted into a table. Only one instance of this form is visible at a time. In the table, you can delete and edit rows, and you can disable this functionality. You can also insert data into the table from answers or external data, similar to staticTable.', marginBottom: 2, }), buildDescriptionField({ id: 'tableRepeaterDescription2', title: '', description: - 'Í table repeater er í boði að nota input, select, radio, checkbox, date, nationalIdWithName og phone.', + 'In the table repeater, you can use input, select, radio, checkbox, date, nationalIdWithName and phone.', }), buildTableRepeaterField({ id: 'tableRepeater', diff --git a/libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts b/libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts index 4ae331750e1e..23830ee5fd0e 100644 --- a/libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts +++ b/libs/application/templates/reference-template/src/forms/pendingReviewForm/pendingReview.ts @@ -8,8 +8,8 @@ export const PendingReview: Form = buildForm({ children: [ buildDescriptionField({ id: 'inReview', - title: 'Í vinnslu', - description: 'Umsókn þín um ökunám er nú í vinnslu. ', + title: 'In review', + description: 'Your application is now in review. ', }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts index fafd26110db1..7918bc4f5f8d 100644 --- a/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts +++ b/libs/application/templates/reference-template/src/forms/prerequisitesForm/prerequisitesForm.ts @@ -40,7 +40,7 @@ export const Prerequisites: Form = buildForm({ children: [ buildExternalDataProvider({ id: 'approveExternalData', - title: 'Utanaðkomandi gögn', + title: 'External data', dataProviders: [ buildDataProviderItem({ provider: UserProfileApi, @@ -54,8 +54,8 @@ export const Prerequisites: Form = buildForm({ }), buildDataProviderItem({ provider: NationalRegistryApi, - title: 'Þjóðskrá', - subTitle: 'Upplýsingar um þig í Þjóðskrá.', + title: 'National Registry', + subTitle: 'Information about you in the National Registry.', }), buildDataProviderItem({ provider: MyMockProvider, diff --git a/libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts b/libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts index 9e0a4b189554..c3149752b103 100644 --- a/libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts +++ b/libs/application/templates/reference-template/src/forms/rejectedForm/rejectedForm.ts @@ -8,8 +8,8 @@ export const Rejected: Form = buildForm({ children: [ buildDescriptionField({ id: 'rejected', - title: 'Því miður...', - description: 'Umsókn þinni verið hafnað! Það er frekar leiðinlegt.', + title: 'Sorry...', + description: 'Your application has been rejected! It is pretty sad.', }), ], }) diff --git a/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts b/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts index fc71730a02e8..57bc24e5e6af 100644 --- a/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts +++ b/libs/application/templates/reference-template/src/forms/reviewApplicationForm/reviewApplication.ts @@ -58,7 +58,7 @@ export const ReviewApplication: Form = buildForm({ buildDividerField({ title: 'Atvinna' }), buildRadioField({ id: 'careerHistory', - title: m.careerHistory, + title: 'def', width: 'half', disabled: true, options: [ @@ -68,7 +68,7 @@ export const ReviewApplication: Form = buildForm({ }), buildCheckboxField({ id: 'careerHistoryDetails.careerHistoryCompanies', - title: m.careerHistoryCompanies, + title: 'abc', disabled: true, width: 'half', options: [ @@ -81,17 +81,17 @@ export const ReviewApplication: Form = buildForm({ buildTextField({ id: 'careerHistoryDetails.careerHistoryOther', disabled: true, - title: m.careerHistoryOther, + title: 'ghi', }), buildTextField({ id: 'dreamJob', - title: m.dreamJob, + title: 'jkl', disabled: true, }), buildSubmitField({ id: 'approvedByReviewer', placement: 'screen', - title: 'Samþykkirðu þessa umsókn?', + title: 'Do yo uapprove this application?', actions: [ { event: 'APPROVE', name: 'Samþykkja', type: 'primary' }, { event: 'REJECT', name: 'Hafna', type: 'reject' }, @@ -103,7 +103,7 @@ export const ReviewApplication: Form = buildForm({ id: 'final', title: 'Takk fyrir', description: - 'Úrvinnslu þinni er lokið. Umsókn er komin áfram í ferlinu.', + 'Your processing is complete. The application has been forwarded to the next step.', }), ], }), diff --git a/libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts b/libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts index e92b2e0a9cb3..06c29afc238b 100644 --- a/libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts +++ b/libs/application/templates/reference-template/src/forms/waitingToAssignForm/waitingToAssignForm.ts @@ -8,7 +8,7 @@ import { Form, FormModes } from '@island.is/application/types' export const PendingReview: Form = buildForm({ id: 'ExamplePending', - title: 'Í vinnslu', + title: 'In review', mode: FormModes.IN_PROGRESS, children: [ buildMultiField({ @@ -16,15 +16,15 @@ export const PendingReview: Form = buildForm({ children: [ buildDescriptionField({ id: 'waitingToAssign', - title: 'Í bið', - description: 'Beðið eftir umsjón.', + title: 'In review', + description: 'Waiting for review.', }), buildSubmitField({ id: 'submitWaiting', placement: 'footer', - title: 'Halda áfram', + title: 'Continue', refetchApplicationAfterSubmit: true, - actions: [{ event: 'SUBMIT', name: 'Halda áfram', type: 'primary' }], + actions: [{ event: 'SUBMIT', name: 'Continue', type: 'primary' }], }), ], }), diff --git a/libs/application/templates/reference-template/src/lib/messages.ts b/libs/application/templates/reference-template/src/lib/messages.ts index d85814deffac..9b332c340cf1 100644 --- a/libs/application/templates/reference-template/src/lib/messages.ts +++ b/libs/application/templates/reference-template/src/lib/messages.ts @@ -3,7 +3,7 @@ import { defineMessages } from 'react-intl' export const m = defineMessages({ conditionsSection: { id: 'example.application:conditions.section', - defaultMessage: 'Skilyrði', + defaultMessage: 'Conditions', description: 'Some description', }, institutionName: { @@ -13,124 +13,79 @@ export const m = defineMessages({ }, name: { id: 'example.application:name', - defaultMessage: 'Umsókn', - description: `Application's name`, - }, - nameApplicationNeverWorkedBefore: { - id: 'example.application:name.application.never.worked.before', - defaultMessage: 'Umsókn - Aldrei unnið áður', + defaultMessage: 'Application', description: `Application's name`, }, nameApplicationWithValue: { id: 'example.application:name.application.with.value', - defaultMessage: 'Umsókn {value}', + defaultMessage: 'Application {value}', description: `Application's name with value`, }, draftTitle: { id: 'example.application:draft.title', - defaultMessage: 'Drög', + defaultMessage: 'Draft', description: 'First state title', }, draftDescription: { id: 'example.application:draft.description', - defaultMessage: 'Notendur hafa ekkert að gera á þessu stigi', + defaultMessage: 'Users have nothing to do at this stage', description: 'Description of the state', }, introSection: { id: 'example.application:intro.section', - defaultMessage: 'Upplýsingar', + defaultMessage: 'Information', description: 'Some description', }, introTitle: { id: 'example.application:intro.title', - defaultMessage: 'Velkomin', + defaultMessage: 'Welcome', description: 'Some description', }, introDescription: { id: 'example.application:intro.description', defaultMessage: - 'Þessi umsókn sýnir hvernig á að smíða umsókn. Hver umsókn skiptist niður í nokkur form og eru mismunandi form sýnd eftir stöðu umsóknarinnar og/eða hlutverki notandans. Formið sem umsóknin er að birta núna er "exampleForm" og núna er umsóknin í stöðunni "draft" og merkir það að þú hafir komist í gegnum fyrsta formið "prerequisitesForm" þar sem staðan var "prerequisites".', + 'This application shows how to build an application and what components are available. Each application is split into a few different forms that are loaded depending on the application state and/or the user role. Right now the application is showing the "exampleForm" and the application state is "draft". This means that you got through the first form "prerequisitesForm" where the state was "prerequisites".', description: 'Some description', }, introDescription2: { id: 'example.application:intro.description2', defaultMessage: - 'Í Þessu formi er farið yfir allar mögulegar einingar sem kerfið býður upp á og sýndar eru mismunandi stillingar sem að láta einingarnar birtast eða hegða sér á mismunandi vegu.', + 'This form covers all possible components that the application system offers and they are shown with different settings that results in the components appearing or behaving in different ways.', description: 'Some description', }, about: { id: 'example.application:about', - defaultMessage: 'Um þig', + defaultMessage: 'About you', description: 'Some description', }, personName: { id: 'example.application:person.name', - defaultMessage: 'Nafn', + defaultMessage: 'Name', description: 'Some description', }, nationalId: { id: 'example.application:person.nationalId', - defaultMessage: 'Kennitala', + defaultMessage: 'National ID', description: 'Some description', }, age: { id: 'example.application:person.age', - defaultMessage: 'Aldur', + defaultMessage: 'Age', description: 'Some description', }, email: { id: 'example.application:person.email', - defaultMessage: 'Netfang', + defaultMessage: 'Email', description: 'Some description', }, phoneNumber: { id: 'example.application:person.phoneNumber', - defaultMessage: 'Símanúmer', - description: 'Some description', - }, - career: { - id: 'example.application:career', - defaultMessage: 'Starfsferill', - description: 'Some description', - }, - history: { - id: 'example.application:history', - defaultMessage: 'Hvar hefur þú unnið áður?', - description: 'Some description', - }, - careerIndustry: { - id: 'example.application:career.industry', - defaultMessage: 'Starfsgeiri', - description: 'Some description', - }, - careerIndustryDescription: { - id: 'example.application:career.industryDescription', - defaultMessage: 'Í hvaða geira hefur þú unnið?', - description: 'Some description', - }, - careerHistory: { - id: 'example.application:careerHistory', - defaultMessage: 'Hefurðu unnið yfir höfuð einhvern tímann áður?', - description: 'Some description', - }, - careerHistoryCompanies: { - id: 'example.application:careerHistoryCompanies', - defaultMessage: 'Hefurðu unnið fyrir eftirfarandi aðila?', - description: 'Some description', - }, - future: { - id: 'example.application:future', - defaultMessage: 'Hvar langar þig að vinna?', - description: 'Some description', - }, - dreamJob: { - id: 'example.application:dreamJob', - defaultMessage: 'Einhver draumavinnustaður?', + defaultMessage: 'Phone number', description: 'Some description', }, assigneeTitle: { id: 'example.application:assigneeTitle', - defaultMessage: 'Hver á að fara yfir?', + defaultMessage: 'Who should review?', description: 'Some description', }, assignee: { @@ -140,12 +95,12 @@ export const m = defineMessages({ }, yesOptionLabel: { id: 'example.application:yes.option.label', - defaultMessage: 'Já', + defaultMessage: 'Yes', description: 'Some description', }, noOptionLabel: { id: 'example.application:no.option.label', - defaultMessage: 'Nei', + defaultMessage: 'No', description: 'Some description', }, governmentOptionLabel: { @@ -161,29 +116,18 @@ export const m = defineMessages({ }, dataSchemePhoneNumber: { id: 'example.application:dataSchema.phoneNumber', - defaultMessage: 'Símanúmerið þarf að vera gilt.', + defaultMessage: 'Phone number must be valid.', description: 'Error message when phone number is invalid.', }, dataSchemeNationalId: { id: 'example.application:dataSchema.national.id', - defaultMessage: 'Kennitala þarf að vera gild.', + defaultMessage: 'National ID must be valid.', description: 'Error message when the kennitala is invalid.', }, - careerHistoryOther: { - id: 'example.application:careerHistory.other', - defaultMessage: 'Hvern hefur þú unnið fyrir áður?', - description: 'Some description', - }, - careerHistoryOtherError: { - id: 'example.application:careerHistory.othertError', - defaultMessage: - 'Vinsamlegast tilgreindu fyrir hvern þú hefur unnið fyrir áður?', - description: 'Some description', - }, approvedByReviewerError: { id: 'example.application:approvedByReviewerError', defaultMessage: - 'Vinsamlegast tilgreindu hvort umsóknin sé samþykkt eða ekki', + 'Please indicate whether the application is approved or not', description: 'Some description', }, regularTextExample: { @@ -259,31 +203,31 @@ export const m = defineMessages({ validationDescription: { id: 'example.application:validation.description#markdown', defaultMessage: - 'Einhver field bjóða upp á að setja gildið `required: true`, sem nýtir innbyggða virkni í `html` og getur verið afvirkjað með því að skoða DOM-ið fyrir síðuna.\n\n Almennt er best að setja allt sem verður að vera fyllt út eða verður að vera fyllt út á ákveðinn hátt í `/lib/dataSchema.ts`. Fyrir validation skal nota *zod*.', + 'Any field can have the value `required: true`, which uses the built-in functionality of `html` and can be disabled by inspecting the DOM for the page.\n\n Generally, it is best to put everything that needs to be filled out or needs to be filled out in a certain way in `/lib/dataSchema.ts`. For validation, use *zod*.', description: 'Validation description', }, validationDescription3: { id: 'example.application:validation.description3#markdown', defaultMessage: - 'Ef valkostir í field eru allir í einu `enum`, þá skal nota `z.nativeEnum()` í zod validation til að sleppa við að lista upp alla hvern valkost í enum-inu eins og þarf að gera ef stuðst er við `z.enum()` ', + 'If the options in a field are all in one `enum`, then use `z.nativeEnum()` in zod validation to skip listing all the options in the enum as is required when using `z.enum()`.', description: 'Validation description', }, conditionsDescription2: { id: 'example.application:conditions.description2#markdown', defaultMessage: - 'Þetta er gert á sama hátt í báðum tilvikum. Allt ætti að geta tekið inn `condition` sem parameter og condition tekur inn fall `(answers, externalData) => { ... }` sem skilar `true` eða `false`', + 'This is done in the same way in both cases. Everything should be able to take in `condition` as a parameter and condition takes in a function `(answers, externalData) => { ... }` that returns `true` or `false`.', description: 'Validation description', }, descriptionFieldDescription: { id: 'example.application:descriptionFieldDescription', defaultMessage: - 'Allur texti sem birtist í umsóknum ætti að koma úr `lib/messages.ts`. Þessum texta er svo hlaðið upp í contentful með því að keyra `yarn nx run :extract-strings`, þar sem `` er nafnið á umsókninni eins og það er skrifað í `project.json` í viðeigandi template. Fyrir þessa umsókn er þetta `yarn nx run application-templates-reference-template:extract-strings`. Í contentfull sér skilastjóri eða starfsmaður stofnunar um að setja inn enskar þýðingar og uppfæra textan frá því sem forritari setur inn í defaultMessage.', + 'All text that appears in applications should come from `lib/messages.ts`. This text is then loaded into contentful by running `yarn nx run :extract-strings`, where `` is the name of the application as it is written in `project.json` in the relevant template. For this application it is `yarn nx run application-templates-reference-template:extract-strings`. In contentful, the content manager or administrator of the organization is responsible for adding English translations and updating the text from what the developer puts in `defaultMessage`.', description: 'Description field description', }, descriptionFieldDescription2: { id: 'example.application:descriptionFieldDescription2', defaultMessage: - 'Hér eru listaðir upp allir möguleikar á texta frá buildDescriptionField. Flestir þeirra tengjast því að bæta við `#markdown` í id-ið til að geta notað markdown í textanum. Einnig er hægt að setja breytur inn í texta og stýra fyrirsagnastærð', + 'Here is a list of all the options for text from buildDescriptionField. Most of them are related to adding `#markdown` to the id to be able to use markdown in the text. It is also possible to put variables into the text and control title font sizes.', description: 'Description field description', }, }) From c2113258ec568f2359e31f46a5bcb8d42f49a75c Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 13:51:08 +0000 Subject: [PATCH 30/32] chore: remove unused imports --- .../tablesAndRepeatersSection/tableRepeaterSubsection.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts index 22dc4428a3fb..06c95a4d4e12 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/tablesAndRepeatersSection/tableRepeaterSubsection.ts @@ -4,9 +4,6 @@ import { buildSubSection, buildTableRepeaterField, } from '@island.is/application/core' -import { selectOptions } from '../../../utils/options' -import { input } from 'libs/island-ui/core/src/lib/Input/Input.mixins' -import { name } from 'libs/island-ui/core/src/lib/FormStepper/FormStepperSection.css' export const tableRepeaterSubsection = buildSubSection({ id: 'repeater', From 56e5b1d580ca3166aedf33f8f427c0e1ac01ef28 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 14:01:26 +0000 Subject: [PATCH 31/32] chore: fix imports --- .../exampleForm/simpleInputsSection/asyncSelectSubsection.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts index e49e3064e68a..8ebd875bb2c4 100644 --- a/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts +++ b/libs/application/templates/reference-template/src/forms/exampleForm/simpleInputsSection/asyncSelectSubsection.ts @@ -1,9 +1,8 @@ -import { buildAsyncSelectField } from '@island.is/application/core' -import { Context, Option } from '@island.is/application/types' import { + buildAsyncSelectField, buildMultiField, buildSubSection, -} from 'libs/application/core/src/lib/formBuilders' +} from '@island.is/application/core' import { FriggSchoolsByMunicipality } from '../../../utils/types' import { friggSchoolsByMunicipalityQuery } from '../../../graphql/sampleQuery' From 928765f2b47c148dc853d6ac6846c62fff377e30 Mon Sep 17 00:00:00 2001 From: Jonni Date: Wed, 18 Dec 2024 14:24:36 +0000 Subject: [PATCH 32/32] fix: errors --- .../reference-template/src/lib/ReferenceApplicationTemplate.ts | 2 +- .../templates/reference-template/src/lib/dataSchema.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts index 9b308d213c2d..c4cd3c8b8fd3 100644 --- a/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts +++ b/libs/application/templates/reference-template/src/lib/ReferenceApplicationTemplate.ts @@ -65,7 +65,7 @@ const determineMessageFromApplicationAnswers = (application: Application) => { ) if (careerHistory === 'no') { - return m.nameApplicationNeverWorkedBefore + return 'abcdef' } if (careerIndustry) { return { diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index 9bbebc6adb3c..88387124a8c7 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -100,7 +100,7 @@ const careerHistoryDetailsSchema = z }) .partial() .refine((data) => careerHistoryCompaniesValidation(data), { - params: m.careerHistoryOtherError, + params: m.regularTextExample, path: ['careerHistoryOther'], })