From 167a4cafab04eb93988300f9bc8be79710a81e5a Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Thu, 1 Feb 2024 15:46:43 +0000 Subject: [PATCH 01/72] form builder 'init' --- .gitignore | 4 +- apps/form-builder-e2e/.eslintrc.json | 10 + apps/form-builder-e2e/cypress.config.ts | 6 + apps/form-builder-e2e/project.json | 30 + apps/form-builder-e2e/src/e2e/app.cy.ts | 13 + .../src/fixtures/example.json | 4 + apps/form-builder-e2e/src/support/app.po.ts | 1 + apps/form-builder-e2e/src/support/commands.ts | 33 + apps/form-builder-e2e/src/support/e2e.ts | 17 + apps/form-builder-e2e/tsconfig.json | 10 + apps/form-builder/.eslintrc.json | 40 + apps/form-builder/.vscode/settings.json | 1 + .../components/Layout/Layout.css.ts | 21 + .../form-builder/components/Layout/Layout.tsx | 76 ++ .../LicenseProviderDropdown.tsx | 40 + .../MainContent/MainContent.css.tsx | 10 + .../components/MainContent/MainContent.tsx | 120 +++ .../components/BaseSettings/BaseSettings.tsx | 162 ++++ .../components/InputContent/InputContent.tsx | 116 +++ .../InputContent/components/BaseInput.tsx | 192 +++++ .../components/FileUpload/FileUpload.tsx | 131 +++ .../components/FileUpload/fileSizes.json | 44 + .../components/MessageWithLink.tsx | 133 +++ .../InputContent/components/NumberInput.tsx | 105 +++ .../InputContent/components/TimeInput.tsx | 36 + .../components/ListBuilder/ListBuilder.tsx | 202 +++++ .../ListBuilder/components/ListItem.tsx | 343 ++++++++ .../components/ListContent/ListContent.tsx | 98 +++ .../components/Payments/Payments.css.ts | 8 + .../components/Payments/Payments.tsx | 55 ++ .../components/Premises/Premises.tsx | 55 ++ .../components/Preview/Preview.tsx | 111 +++ .../Preview/components/Banknumber.tsx | 90 ++ .../Preview/components/Currency.tsx | 30 + .../components/Preview/components/Email.tsx | 32 + .../Preview/components/FileUpload.tsx | 118 +++ .../components/Preview/components/List.tsx | 29 + .../components/MessageWithLinkButton.tsx | 64 ++ .../Preview/components/NumberInput.tsx | 45 + .../Preview/components/PhoneInput.tsx | 20 + .../components/Preview/components/Radio.tsx | 57 ++ .../components/Preview/components/Ssn.tsx | 21 + .../Preview/components/TimeSelect.tsx | 217 +++++ .../UtilizationSummary/UtilizationSummary.tsx | 11 + .../PreviewStepOrGroup/MultiSet/MultiSet.tsx | 62 ++ .../PreviewStepOrGroup/PreviewStepOrGroup.tsx | 109 +++ .../RelevantParties/RelevantParties.tsx | 155 ++++ .../components/SingleParty.tsx | 84 ++ .../form-builder/components/Navbar/Navbar.tsx | 342 ++++++++ .../NavComponent/NavComponent.css.ts | 93 +++ .../components/NavComponent/NavComponent.tsx | 183 +++++ .../NavComponent/components/NavButtons.tsx | 46 ++ .../components/NavbarTab/NavbarTab.css.tsx | 20 + .../Navbar/components/NavbarTab/NavbarTab.tsx | 57 ++ .../components/NavbarSelect/NavbarSelect.tsx | 64 ++ .../components/SelectNavComponent.tsx | 148 ++++ .../components/selectNavComponent.css.ts | 93 +++ .../components/TableRow/TableRow.css.tsx | 8 + .../components/TableRow/TableRow.tsx | 203 +++++ apps/form-builder/components/Tabs/index.tsx | 51 ++ apps/form-builder/components/Tabs/tabs.css.ts | 14 + .../TranslationTag/TranslationTag.tsx | 12 + .../context/FormBuilderContext.tsx | 60 ++ apps/form-builder/context/LayoutContext.tsx | 14 + apps/form-builder/environments/environment.ts | 9 + apps/form-builder/hooks/fileUploadReducer.ts | 43 + apps/form-builder/hooks/formReducer.tsx | 183 +++++ apps/form-builder/hooks/headerInfoReducer.tsx | 29 + apps/form-builder/hooks/listsReducer.tsx | 772 ++++++++++++++++++ apps/form-builder/index.d.ts | 6 + apps/form-builder/jest.config.ts | 11 + apps/form-builder/lib/fileTypes.json | 15 + apps/form-builder/next-env.d.ts | 5 + apps/form-builder/next.config.js | 39 + apps/form-builder/pages/Form/[id]/index.tsx | 29 + apps/form-builder/pages/Form/index.tsx | 22 + apps/form-builder/pages/_app.tsx | 25 + apps/form-builder/pages/forms.tsx | 22 + apps/form-builder/pages/index.tsx | 23 + apps/form-builder/project.json | 108 +++ apps/form-builder/proxy.config.json | 6 + apps/form-builder/public/.gitkeep | 0 apps/form-builder/public/favicon.ico | Bin 0 -> 15086 bytes apps/form-builder/screens/Form.tsx | 214 +++++ apps/form-builder/screens/Forms.tsx | 78 ++ apps/form-builder/screens/index.tsx | 2 + apps/form-builder/server.ts | 12 + apps/form-builder/services/apiService.tsx | 268 ++++++ .../services/translationStation.tsx | 62 ++ apps/form-builder/tsconfig.json | 54 ++ apps/form-builder/tsconfig.server.json | 11 + apps/form-builder/tsconfig.spec.json | 21 + apps/form-builder/types/enums/index.tsx | 91 +++ apps/form-builder/types/interfaces.tsx | 224 +++++ apps/form-builder/utils/defaultStep.tsx | 20 + apps/form-builder/utils/formatDate.tsx | 8 + .../utils/getBaseSettingsStep.tsx | 19 + package.json | 5 +- yarn.lock | 153 ++-- 99 files changed, 7302 insertions(+), 66 deletions(-) create mode 100644 apps/form-builder-e2e/.eslintrc.json create mode 100644 apps/form-builder-e2e/cypress.config.ts create mode 100644 apps/form-builder-e2e/project.json create mode 100644 apps/form-builder-e2e/src/e2e/app.cy.ts create mode 100644 apps/form-builder-e2e/src/fixtures/example.json create mode 100644 apps/form-builder-e2e/src/support/app.po.ts create mode 100644 apps/form-builder-e2e/src/support/commands.ts create mode 100644 apps/form-builder-e2e/src/support/e2e.ts create mode 100644 apps/form-builder-e2e/tsconfig.json create mode 100644 apps/form-builder/.eslintrc.json create mode 100644 apps/form-builder/.vscode/settings.json create mode 100644 apps/form-builder/components/Layout/Layout.css.ts create mode 100644 apps/form-builder/components/Layout/Layout.tsx create mode 100644 apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx create mode 100644 apps/form-builder/components/MainContent/MainContent.css.tsx create mode 100644 apps/form-builder/components/MainContent/MainContent.tsx create mode 100644 apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx create mode 100644 apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx create mode 100644 apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx create mode 100644 apps/form-builder/components/MainContent/components/Payments/Payments.css.ts create mode 100644 apps/form-builder/components/MainContent/components/Payments/Payments.tsx create mode 100644 apps/form-builder/components/MainContent/components/Premises/Premises.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/Preview.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Email.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/List.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/NumberInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Ssn.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx create mode 100644 apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx create mode 100644 apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx create mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx create mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx create mode 100644 apps/form-builder/components/Navbar/Navbar.tsx create mode 100644 apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts create mode 100644 apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx create mode 100644 apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx create mode 100644 apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx create mode 100644 apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx create mode 100644 apps/form-builder/components/NavbarSelect/NavbarSelect.tsx create mode 100644 apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx create mode 100644 apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts create mode 100644 apps/form-builder/components/TableRow/TableRow.css.tsx create mode 100644 apps/form-builder/components/TableRow/TableRow.tsx create mode 100644 apps/form-builder/components/Tabs/index.tsx create mode 100644 apps/form-builder/components/Tabs/tabs.css.ts create mode 100644 apps/form-builder/components/TranslationTag/TranslationTag.tsx create mode 100644 apps/form-builder/context/FormBuilderContext.tsx create mode 100644 apps/form-builder/context/LayoutContext.tsx create mode 100644 apps/form-builder/environments/environment.ts create mode 100644 apps/form-builder/hooks/fileUploadReducer.ts create mode 100644 apps/form-builder/hooks/formReducer.tsx create mode 100644 apps/form-builder/hooks/headerInfoReducer.tsx create mode 100644 apps/form-builder/hooks/listsReducer.tsx create mode 100644 apps/form-builder/index.d.ts create mode 100644 apps/form-builder/jest.config.ts create mode 100644 apps/form-builder/lib/fileTypes.json create mode 100644 apps/form-builder/next-env.d.ts create mode 100644 apps/form-builder/next.config.js create mode 100644 apps/form-builder/pages/Form/[id]/index.tsx create mode 100644 apps/form-builder/pages/Form/index.tsx create mode 100644 apps/form-builder/pages/_app.tsx create mode 100644 apps/form-builder/pages/forms.tsx create mode 100644 apps/form-builder/pages/index.tsx create mode 100644 apps/form-builder/project.json create mode 100644 apps/form-builder/proxy.config.json create mode 100644 apps/form-builder/public/.gitkeep create mode 100644 apps/form-builder/public/favicon.ico create mode 100644 apps/form-builder/screens/Form.tsx create mode 100644 apps/form-builder/screens/Forms.tsx create mode 100644 apps/form-builder/screens/index.tsx create mode 100644 apps/form-builder/server.ts create mode 100644 apps/form-builder/services/apiService.tsx create mode 100644 apps/form-builder/services/translationStation.tsx create mode 100644 apps/form-builder/tsconfig.json create mode 100644 apps/form-builder/tsconfig.server.json create mode 100644 apps/form-builder/tsconfig.spec.json create mode 100644 apps/form-builder/types/enums/index.tsx create mode 100644 apps/form-builder/types/interfaces.tsx create mode 100644 apps/form-builder/utils/defaultStep.tsx create mode 100644 apps/form-builder/utils/formatDate.tsx create mode 100644 apps/form-builder/utils/getBaseSettingsStep.tsx diff --git a/.gitignore b/.gitignore index a2b2cd1ed287..df03af67a6dc 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,4 @@ apps/**/index.html # Next.js .next -.nx/ - - +.nx/ \ No newline at end of file diff --git a/apps/form-builder-e2e/.eslintrc.json b/apps/form-builder-e2e/.eslintrc.json new file mode 100644 index 000000000000..696cb8b12127 --- /dev/null +++ b/apps/form-builder-e2e/.eslintrc.json @@ -0,0 +1,10 @@ +{ + "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/form-builder-e2e/cypress.config.ts b/apps/form-builder-e2e/cypress.config.ts new file mode 100644 index 000000000000..1ff4098804c6 --- /dev/null +++ b/apps/form-builder-e2e/cypress.config.ts @@ -0,0 +1,6 @@ +import { defineConfig } from 'cypress' +import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset' + +export default defineConfig({ + e2e: nxE2EPreset(__dirname), +}) diff --git a/apps/form-builder-e2e/project.json b/apps/form-builder-e2e/project.json new file mode 100644 index 000000000000..e686b2390f4a --- /dev/null +++ b/apps/form-builder-e2e/project.json @@ -0,0 +1,30 @@ +{ + "name": "form-builder-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/form-builder-e2e/src", + "projectType": "application", + "targets": { + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/form-builder-e2e/cypress.config.ts", + "devServerTarget": "form-builder:serve:development", + "testingType": "e2e" + }, + "configurations": { + "production": { + "devServerTarget": "form-builder:serve:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/form-builder-e2e/**/*.{js,ts}"] + } + } + }, + "tags": [], + "implicitDependencies": ["form-builder"] +} diff --git a/apps/form-builder-e2e/src/e2e/app.cy.ts b/apps/form-builder-e2e/src/e2e/app.cy.ts new file mode 100644 index 000000000000..9b3f1c3ef43b --- /dev/null +++ b/apps/form-builder-e2e/src/e2e/app.cy.ts @@ -0,0 +1,13 @@ +import { getGreeting } from '../support/app.po' + +describe('form-builder', () => { + beforeEach(() => cy.visit('/')) + + it('should display welcome message', () => { + // Custom command example, see `../support/commands.ts` file + cy.login('my-email@something.com', 'myPassword') + + // Function helper example, see `../support/app.po.ts` file + getGreeting().contains('Welcome form-builder') + }) +}) diff --git a/apps/form-builder-e2e/src/fixtures/example.json b/apps/form-builder-e2e/src/fixtures/example.json new file mode 100644 index 000000000000..294cbed6ce9e --- /dev/null +++ b/apps/form-builder-e2e/src/fixtures/example.json @@ -0,0 +1,4 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io" +} diff --git a/apps/form-builder-e2e/src/support/app.po.ts b/apps/form-builder-e2e/src/support/app.po.ts new file mode 100644 index 000000000000..00f556e10333 --- /dev/null +++ b/apps/form-builder-e2e/src/support/app.po.ts @@ -0,0 +1 @@ +export const getGreeting = () => cy.get('h1') diff --git a/apps/form-builder-e2e/src/support/commands.ts b/apps/form-builder-e2e/src/support/commands.ts new file mode 100644 index 000000000000..270f023ff512 --- /dev/null +++ b/apps/form-builder-e2e/src/support/commands.ts @@ -0,0 +1,33 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** + +// eslint-disable-next-line @typescript-eslint/no-namespace +declare namespace Cypress { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface Chainable { + login(email: string, password: string): void + } +} +// +// -- This is a parent command -- +Cypress.Commands.add('login', (email, password) => { + console.log('Custom command example: Login', email, password) +}) +// +// -- This is a child command -- +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/form-builder-e2e/src/support/e2e.ts b/apps/form-builder-e2e/src/support/e2e.ts new file mode 100644 index 000000000000..185d654ec609 --- /dev/null +++ b/apps/form-builder-e2e/src/support/e2e.ts @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' diff --git a/apps/form-builder-e2e/tsconfig.json b/apps/form-builder-e2e/tsconfig.json new file mode 100644 index 000000000000..cc509a730e12 --- /dev/null +++ b/apps/form-builder-e2e/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "sourceMap": false, + "outDir": "../../dist/out-tsc", + "allowJs": true, + "types": ["cypress", "node"] + }, + "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] +} diff --git a/apps/form-builder/.eslintrc.json b/apps/form-builder/.eslintrc.json new file mode 100644 index 000000000000..f653743bfa98 --- /dev/null +++ b/apps/form-builder/.eslintrc.json @@ -0,0 +1,40 @@ +{ + "extends": [ + "plugin:@nx/react-typescript", + "next", + "next/core-web-vitals", + "../../.eslintrc.json" + ], + "ignorePatterns": ["!**/*", ".next/**/*"], + "overrides": [ + { + "files": ["*.*"], + "rules": { + "@next/next/no-html-link-for-pages": "off" + } + }, + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": { + "@next/next/no-html-link-for-pages": [ + "error", + "apps/form-builder/pages" + ] + } + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], + "env": { + "jest": true + } + } + ] +} diff --git a/apps/form-builder/.vscode/settings.json b/apps/form-builder/.vscode/settings.json new file mode 100644 index 000000000000..0967ef424bce --- /dev/null +++ b/apps/form-builder/.vscode/settings.json @@ -0,0 +1 @@ +{} diff --git a/apps/form-builder/components/Layout/Layout.css.ts b/apps/form-builder/components/Layout/Layout.css.ts new file mode 100644 index 000000000000..eb82ed5aa329 --- /dev/null +++ b/apps/form-builder/components/Layout/Layout.css.ts @@ -0,0 +1,21 @@ +import { style } from '@vanilla-extract/css' + +export const processContainer = style({ + minHeight: '100vh', +}) + +export const contentContainer = style({ + maxWidth: '100vw', +}) + +export const container = style({ + display: 'flex', + justifyContent: 'center', + height: '100vh', +}) + +export const contentWrapper = style({ + //maxWidth: '1140px', + width: '100%', + padding: '1rem 1rem', +}) diff --git a/apps/form-builder/components/Layout/Layout.tsx b/apps/form-builder/components/Layout/Layout.tsx new file mode 100644 index 000000000000..d89004441be6 --- /dev/null +++ b/apps/form-builder/components/Layout/Layout.tsx @@ -0,0 +1,76 @@ +import { + Header, + Box, + Divider, + GridContainer as Grid, + GridColumn as Column, +} from '@island.is/island-ui/core' +import Head from 'next/head' +import React, { FC, useReducer } from 'react' +import * as styles from './Layout.css' +import { useRouter } from 'next/router' +import { headerInfoReducer } from '../../hooks/headerInfoReducer' +import LayoutContext from '../../context/LayoutContext' + +type LayoutProps = { + children: React.ReactNode +} + +const Layout: FC = ({ children }: LayoutProps) => { + const route = useRouter() + //useContext(LayoutContext) + + const initialInfo = { + organization: '', + applicationName: '', + } + const [info, dispatch] = useReducer(headerInfoReducer, initialInfo) + const layoutContext = { + info: info, + infoDispatch: dispatch, + } + + return ( + + + + Welcome to licensing-portal! + + + + route.push('/Forms')} + > +
+ + + + + + + + + {children} + + + + + + ) +} /* */ + +export default Layout diff --git a/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx b/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx new file mode 100644 index 000000000000..a58125ee0200 --- /dev/null +++ b/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx @@ -0,0 +1,40 @@ +import { Box, Select } from '@island.is/island-ui/core' +import { ILicenseProvider } from '../../types/interfaces' + +interface LicenseProviderDropdownProps { + licenseProviders: ILicenseProvider[] + setSelectProvider: (value: number) => void +} + +function mappedProviders(licenseProviders: ILicenseProvider[]) { + const lp = licenseProviders + .filter((lp) => lp.name.length > 0 && lp.language === 'is') + .map((lp) => ({ + label: lp.name, + value: lp.licenseProviderID, + })) + return lp.sort((a, b) => a.label.localeCompare(b.label)) +} + +export default function LicenseProviderDropdown({ + licenseProviders, + setSelectProvider, +}: LicenseProviderDropdownProps) { + const handleChange = (e: { value: number }) => { + setSelectProvider(e.value) + } + return ( + + changeHandler(e, 'name')} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + /> + + + + + changeHandler(e, 'nameEn')} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + activeItem.data.name.is, + ) + listsDispatch({ + type: 'changeName', + lang: 'en', + newValue: translation.translations[0].translatedText, + }) + }, + }, + ]} + /> + + + {activeItem.type === 'Group' && ( + + + + listsDispatch({ + type: 'setMultiSet', + payload: { + checked: e.target.checked, + }, + }) + } + /> + + + )} + + + + + + + )} + + ) +} diff --git a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx new file mode 100644 index 000000000000..3343605da60f --- /dev/null +++ b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -0,0 +1,162 @@ +import { useContext, useState, FocusEvent } from 'react' +import { + Stack, + GridRow as Row, + GridColumn as Column, + Input, + DatePicker, + Checkbox, +} from '@island.is/island-ui/core' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import LayoutContext from '../../../../context/LayoutContext' +import { saveFormSettings } from '../../../../services/apiService' + +export default function BaseSettings() { + const { formBuilder, formDispatch, setIsTyping } = + useContext(FormBuilderContext) + const { infoDispatch } = useContext(LayoutContext) + const [focus, setFocus] = useState(null) + const { + id, + name, + applicationsDaysToRemove, + invalidationDate, + stopProgressOnValidatingStep, + } = formBuilder.form + return ( + + + + setFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => { + setIsTyping(true) + formDispatch({ + type: 'changeName', + payload: { + lang: 'is', + newName: e.target.value, + }, + }) + infoDispatch({ + type: 'changeApplicationName', + data: e.target.value, + }) + }} + /> + + + setFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => { + setIsTyping(true) + formDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newName: e.target.value, + }, + }) + }} + /> + + + + + setFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => { + setIsTyping(true) + formDispatch({ + type: 'applicationsDaysToRemove', + payload: { value: e.target.value }, + }) + }} + /> + + + + + {formBuilder.form.invalidationDate ? ( + { + formDispatch({ + type: 'invalidationDate', + payload: { value: e.toJSON() }, + }) + }} + /> + ) : ( + { + formDispatch({ + type: 'invalidationDate', + payload: { value: e.toJSON() }, + }) + }} + /> + )} + + + + + { + formDispatch({ + type: 'stopProgressOnValidatingStep', + payload: { value: e.target.checked }, + }) + }} + /> + + + + ) + + function blur(e: FocusEvent) { + if (focus !== e.target.value) { + setFocus(null) + const toSave = { + id: id, + name: name, + applicationsDaysToRemove: applicationsDaysToRemove, + invalidationDate: invalidationDate, + stopProgressOnValidatingStep: stopProgressOnValidatingStep, + } + saveFormSettings(id, toSave) + } + setIsTyping(false) + } +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx b/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx new file mode 100644 index 000000000000..799b0af5a06d --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx @@ -0,0 +1,116 @@ +import { useContext, useState } from 'react' +import { + GridRow as Row, + GridColumn as Column, + Stack, + Input, + Checkbox, + ToggleSwitchCheckbox, + Text, + Button, +} from '@island.is/island-ui/core' +import ListContent from '../ListContent/ListContent' +import Preview from '../Preview/Preview' +import ListBuilder from '../ListBuilder/ListBuilder' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { IInput, NavbarSelectStatus } from '../../../../types/interfaces' +import BaseInput from './components/BaseInput' +import TimeInput from './components/TimeInput' +import MessageWithLink from './components/MessageWithLink' +import FileUpload from './components/FileUpload/FileUpload' +import NumberInput from './components/NumberInput' + +export default function InputContent() { + const { formBuilder, lists, selectStatus, setSelectStatus } = + useContext(FormBuilderContext) + + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const { inputSettings } = currentItem + const [inListBuilder, setInListBuilder] = useState(false) + const [isLarge, setIsLarge] = useState(false) + + const hasConnections = + formBuilder.form.dependencies[activeItem.data.guid] !== undefined && + formBuilder.form.dependencies[activeItem.data.guid].length > 0 + + if ( + (inListBuilder && currentItem.type === 'Fellilisti') || + (inListBuilder && currentItem.type === 'Valhnappar') + ) { + return + } + return ( + + + + {/* Additional settings depending on chosen input type */} + {['Hakbox'].includes(currentItem.type) && ( + + + + setSelectStatus( + e ? NavbarSelectStatus.NORMAL : NavbarSelectStatus.OFF, + ) + } + /> + + {hasConnections && ( + + Hefur tengingar + + )} + + )} + {/* List */} + {currentItem.type === 'Fellilisti' && ( + <> + + + )} + {/* Radio buttons */} + {currentItem.type === 'Valhnappar' && ( + + )} + {/* Textlinubox */} + {currentItem.type === 'Textalínubox' && ( + setIsLarge(e.target.checked)} + /> + )} + {/* "Klukkuinnsláttur" */} + {currentItem.type === 'Klukkuinnsláttur' && } + {/* Heimagistingarnúmer */} + {currentItem.type === 'Heimagistingarnúmer' && ( + + + + + + )} + {/* Testing text with linked button */} + {currentItem.type === 'Textalýsing' && } + {/* File upload */} + {currentItem.type === 'Skjal' && } + {currentItem.type === 'Tölustafir' && } + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx new file mode 100644 index 000000000000..703728fccc10 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -0,0 +1,192 @@ +import { + GridRow as Row, + GridColumn as Column, + Select, + Stack, + Input, + Checkbox, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../types/interfaces' +import { translationStation } from '../../../../../services/translationStation' + +export default function BaseInput() { + const { + formBuilder, + lists, + listsDispatch, + changeHandler, + changeSelectHandler, + onFocus, + blur, + } = useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + + const options = formBuilder.inputTypes + .map((it) => { + return { + label: it.type, + value: it.type, + } + }) + .sort((a, b) => a.label.localeCompare(b.label)) + + const defaultOption = + currentItem.type === '' + ? null + : options.find((o) => o.value === currentItem.type) + + return ( + + {defaultOption !== undefined && ( + + + changeHandler(e, 'name')} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + /> + + + + {/* Name en */} + + changeHandler(e, 'nameEn')} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + currentItem.name.is, + ) + listsDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newValue: translation.translations[0].translatedText, + }, + }) + }, + }, + ]} + /> + + + {/* Description */} + {['Textalýsing'].includes(currentItem.type) && ( + <> + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setDescription', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } + /> + + + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setDescription', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + currentItem.description.is, + ) + listsDispatch({ + type: 'setDescription', + payload: { + lang: 'en', + newValue: translation.translations[0].translatedText, + }, + }) + }, + }, + ]} + /> + + + + )} + + {/* Required checkbox */} + + + listsDispatch({ + type: 'setIsRequired', + payload: { + guid: currentItem.guid, + isRequired: e.target.checked, + }, + }) + } + /> + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx new file mode 100644 index 000000000000..1d53de937b4a --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx @@ -0,0 +1,131 @@ +import { + GridRow as Row, + GridColumn as Column, + Checkbox, + Stack, + Box, + Select, + Text, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../../types/interfaces' +import fileSizes from './fileSizes.json' +import * as fileTypes from '../../../../../../lib/fileTypes.json' + +export default function FileUpload() { + const { lists, listsDispatch } = useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const { inputSettings } = currentItem + + const fileSizeOptions = fileSizes.fileSizes.map((size) => ({ + label: size.label, + value: size.value, + })) + + const fileAmountOptions = () => { + const arr = [] + for (let i = 1; i < 11; i++) { + arr.push({ label: i, value: i }) + } + return arr + } + + return ( + + + + + listsDispatch({ + type: 'setFileUploadSettings', + payload: { + property: 'erFjolval', + value: e.target.checked, + }, + }) + } + /> + + + + + f.value === inputSettings.fjoldi, + )} + options={fileAmountOptions()} + onChange={(e: { label; value }) => { + listsDispatch({ + type: 'setFileUploadSettings', + payload: { + property: 'fjoldi', + value: e.value, + }, + }) + }} + /> + + )} + + + + Leyfa eftirfarandi skjalatýpur + + + + {Object.entries(fileTypes).map(([key, value], i) => ( + + {key !== 'default' && ( + + listsDispatch({ + type: 'setFileUploadSettings', + payload: { + property: 'tegundir', + checked: e.target.checked, + value: key, + }, + }) + } + /> + )} + + ))} + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json new file mode 100644 index 000000000000..8cc59c37fe35 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json @@ -0,0 +1,44 @@ +{ + "fileSizes": [ + { + "label": "1 mb", + "value": 1048576 + }, + { + "label": "2 mb", + "value": 2097152 + }, + { + "label": "3 mb", + "value": 3145728 + }, + { + "label": "4 mb", + "value": 4194304 + }, + { + "label": "5 mb", + "value": 5242880 + }, + { + "label": "6 mb", + "value": 6291456 + }, + { + "label": "7 mb", + "value": 7340032 + }, + { + "label": "8 mb", + "value": 8388608 + }, + { + "label": "9 mb", + "value": 9437184 + }, + { + "label": "10 mb", + "value": 10485760 + } + ] +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx new file mode 100644 index 000000000000..524e95b89aaa --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx @@ -0,0 +1,133 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, + Checkbox, + Stack, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../types/interfaces' +import { translationStation } from '../../../../../services/translationStation' + +export default function MessageWithLink() { + const { lists, listsDispatch, setIsTyping, onFocus, blur } = + useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const { inputSettings } = currentItem + return ( + + + + + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'erHlekkur', + checked: e.target.checked, + }, + }) + } + /> + + + {inputSettings !== undefined ? ( + inputSettings.erHlekkur && ( + + + + { + setIsTyping(true) + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'hnapptexti', + lang: 'is', + value: e.target.value, + }, + }) + }} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + /> + + + { + setIsTyping(true) + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'hnapptexti', + lang: 'en', + value: e.target.value, + }, + }) + }} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + inputSettings?.hnapptexti?.is, + ) + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'hnapptexti', + lang: 'en', + value: translation.translations[0].translatedText, + }, + }) + }, + }, + ]} + /> + + + + + + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'url', + value: e.target.value, + }, + }) + } + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + /> + + + + ) + ) : ( + <> + )} + + ) +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx new file mode 100644 index 000000000000..dd52b5bd43b1 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx @@ -0,0 +1,105 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, + Stack, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../types/interfaces' + +export default function NumberInput() { + const { lists, listsDispatch, onFocus, blur } = useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const { inputSettings } = currentItem + + return ( + + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setNumberInputSettings', + payload: { + property: 'lagmarkslengd', + value: e.target.value, + }, + }) + } + /> + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setNumberInputSettings', + payload: { + property: 'hamarkslengd', + value: e.target.value, + }, + }) + } + /> + + + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setNumberInputSettings', + payload: { + property: 'laggildi', + value: e.target.value, + }, + }) + } + /> + + + onFocus(e.target.value)} + onBlur={(e) => blur(e)} + onChange={(e) => + listsDispatch({ + type: 'setNumberInputSettings', + payload: { + property: 'hagildi', + value: e.target.value, + }, + }) + } + /> + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx new file mode 100644 index 000000000000..311e864ddf21 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx @@ -0,0 +1,36 @@ +import { + GridRow as Row, + GridColumn as Column, + Select, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' + +export default function TimeInput() { + const { listsDispatch } = useContext(FormBuilderContext) + return ( + + + {}} + /> + + + {}} + /> + + + + ) + } + + return ( + + + + { + setConnect(e) + setSelectStatus(() => + e + ? NavbarSelectStatus.LIST_ITEM + : NavbarSelectStatus.ON_WITHOUT_SELECT, + ) + setConnecting((prev) => + prev.map((l, i) => (i === index ? e : false)), + ) + setActiveListItem(e ? listItem : null) + }} + /> + + listsDispatch({ + type: 'setListItemSelected', + payload: { + guid: listItem.guid, + checked: e, + }, + }) + } + /> + + + + listsDispatch({ + type: 'removeListItem', + payload: { + guid: listItem.guid, + }, + }) + } + > + + + + + + + + + + , + ) => onFocus(event.target.value)} + onChange={(e) => + listsDispatch({ + type: 'setListItem', + payload: { + property: 'label', + lang: 'is', + value: e.target.value, + listItemGuid: listItem.guid, + }, + }) + } + /> + + + , + ) => onFocus(event.target.value)} + onChange={(e) => + listsDispatch({ + type: 'setListItem', + payload: { + property: 'label', + lang: 'en', + value: e.target.value, + listItemGuid: listItem.guid, + }, + }) + } + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + listItem.label.is, + ) + listsDispatch({ + type: 'setListItem', + payload: { + property: 'label', + lang: 'en', + value: translation, + listItemGuid: listItem.guid, + }, + }) + }, + }, + ]} + /> + + + + {isRadio && ( + + + , + ) => onFocus(event.target.value)} + onChange={(e) => + listsDispatch({ + type: 'setListItem', + payload: { + property: 'description', + lang: 'is', + value: e.target.value, + listItemGuid: listItem.guid, + }, + }) + } + /> + + + , + ) => onFocus(event.target.value)} + onChange={(e) => + listsDispatch({ + type: 'setListItem', + payload: { + property: 'description', + lang: 'en', + value: e.target.value, + listItemGuid: listItem.guid, + }, + }) + } + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + listItem.description.is, + ) + listsDispatch({ + type: 'setListItem', + payload: { + property: 'description', + lang: 'en', + value: translation, + listItemGuid: listItem.guid, + }, + }) + }, + }, + ]} + /> + + + )} + {/* + + + + */} + + ) +} diff --git a/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx b/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx new file mode 100644 index 000000000000..a09cb2e15515 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx @@ -0,0 +1,98 @@ +import { + GridColumn as Column, + GridRow as Row, + Select, + Stack, + Box, + Button, + RadioButton, +} from '@island.is/island-ui/core' +import { Dispatch, SetStateAction, useContext, useState } from 'react' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { getList } from '../../../../services/apiService' +import { IInput } from '../../../../types/interfaces' + +type Props = { + setInListBuilder: Dispatch> +} + +const predeterminedLists = [ + { + label: 'Sveitarfélög', + value: 'Sveitarfelog', + }, + { + label: 'Lönd', + value: 'Lond', + }, + { + label: 'Póstnúmer', + value: 'Postnumer', + }, + { + label: 'Iðngreinarmeistara', + value: 'Idngreinarmeistara', + }, +] + +export default function ListContent({ setInListBuilder }: Props) { + const [radio, setRadio] = useState([true, false, false]) + const { lists, listsDispatch } = useContext(FormBuilderContext) + const { activeItem } = lists + return ( + + + + radioHandler(0)}> + + + + + + + radioHandler(1)}> + + + + + {radio[0] && ( + + )} + {radio[1] && ( + + + ) + // + } + {data.type === 'Klukkuinnsláttur' && ( + + + + )} + {data.type === 'Krónutölubox' && ( + + {/* {title(data.name.is)} */} + + + + + )} + {data.type === 'Heimagistingarnúmer' && ( + + + + )} + {data.type === 'Textalýsing' && ( + + )} + {data.type === 'Netfang' && } + {data.type === 'Skjal' && } + {data.type === 'Símanúmer' && ( + + )} + {data.type === 'Tölustafir' && ( + + )} + {data.type === 'Fellilisti' && } + {data.type === 'Valhnappar' && } + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx new file mode 100644 index 000000000000..cfaf1b6c280a --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx @@ -0,0 +1,90 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, +} from '@island.is/island-ui/core' +import { useRef, useState } from 'react' + +export default function Banknumber() { + const [banki, setBanki] = useState() + const [hb, setHb] = useState() + const [reikningur, setReikningur] = useState() + const inputRefs = [ + useRef(), + useRef(), + useRef(), + ] + + const handleChange = (index: number, value) => { + if (index === 0) { + setBanki(value) + if (value.length === 4) { + inputRefs[1]?.current.focus() + } + } else if (index === 1) { + setHb(value) + if (value.length === 2) { + inputRefs[2]?.current.focus() + } + } else if (index === 2) { + if (value.length <= 6) { + setReikningur(value) + } + if (value.length === 6) { + inputRefs[2]?.current.blur() + } + } + } + + const addLeadingZeros = (originalNumber, total) => { + const zerosToAdd = total - originalNumber.length + if (zerosToAdd <= 0) { + return originalNumber + } + if (originalNumber.length === 0) { + return originalNumber + } + const leadingZeros = '0'.repeat(zerosToAdd) + return leadingZeros + originalNumber + } + + return ( + + + handleChange(0, e.target.value)} + onBlur={(e) => setBanki(addLeadingZeros(e.target.value, 4))} + /> + + + handleChange(1, e.target.value)} + onBlur={(e) => setHb(addLeadingZeros(e.target.value, 2))} + /> + + + handleChange(2, e.target.value)} + onBlur={(e) => setReikningur(addLeadingZeros(e.target.value, 6))} + /> + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx new file mode 100644 index 000000000000..02d283c0c5b0 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx @@ -0,0 +1,30 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, +} from '@island.is/island-ui/core' +import { useState } from 'react' + +export default function Currency({ label }) { + const [currency, setCurrency] = useState('') + const handleCurrencyChange = (e) => { + // Remove any non-digit characters from the input value + const inputValue = e.target.value.replace(/\D/g, '') + + // Split the input value into groups of three characters + const formattedValue = inputValue.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + setCurrency(formattedValue) + } + return ( + + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx new file mode 100644 index 000000000000..406f738ab013 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx @@ -0,0 +1,32 @@ +import { useContext, useState } from 'react' +import { Input, Stack, Text } from '@island.is/island-ui/core' +import FormBuilderContext from '../../../../../context/FormBuilderContext' + +export default function Email() { + const { lists } = useContext(FormBuilderContext) + const { activeItem } = lists + const [email, setEmail] = useState('') + const [hasError, setHasError] = useState(false) + + return ( + + {activeItem.data.name.is} + setEmail(e.target.value)} + onBlur={() => setHasError(isValidEmail())} + errorMessage="Ekki gilt netfang" + hasError={hasError} + /> + + ) + + function isValidEmail(): boolean { + const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ + const res = pattern.test(email) + return !res + } +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx b/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx new file mode 100644 index 000000000000..0e34577b0ca2 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx @@ -0,0 +1,118 @@ +import { + InputFileUpload, + UploadFile, + fileToObject, +} from '@island.is/island-ui/core' +import { useState } from 'react' +import { uuid } from 'uuidv4' +import * as fileTypes from '../../../../../lib/fileTypes.json' +import { IInput } from '../../../../../types/interfaces' + +// enum ActionTypes { +// add = 'add', +// remove = 'remove', +// update = 'update', +// } + +type Props = { + currentItem: IInput +} + +export default function FileUpload({ currentItem }: Props) { + const [error, setError] = useState(undefined) + const [fileList, setFileList] = useState>([]) + + // const uploadFile = async (file: UploadFile, response) => { + // return new Promise((resolve, reject) => { + // const request = new XMLHttpRequest() + // // request.withCredentials = true + // // request.responseType = 'json' + + // request.upload.addEventListener('progress', (event) => { + // if (event.lengthComputable) { + // file.percent = (event.loaded / event.total) * 100 + // file.status = 'uploading' + + // const withoutThisFile = fileList.filter((f) => f.key !== file.key) + // const newFileList = [...withoutThisFile, file] + // setFileList(newFileList) + // } + // }) + + // request.upload.addEventListener('error', () => { + // file.percent = 0 + // file.status = 'error' + + // const withoutThisFile = fileList.filter((f) => f.key !== file.key) + // const newFileList = [...withoutThisFile, file] + // setFileList(newFileList) + // reject() + // }) + // request.open('POST', response.url) + + // const formData = new FormData() + + // Object.keys(response.fields).forEach((key) => + // formData.append(key, response.fields[key]), + // ) + // formData.append('file', file.originalFileObj as File) + + // request.setRequestHeader('x-amz-acl', 'bucket-owner-full-control') + + // request.onload = () => { + // resolve(request.response) + // } + + // request.onerror = () => { + // reject() + // } + // request.send(formData) + // }) + // } + + const onChange = (files: File[]) => { + const uploadFiles = files.map((file) => fileToObject(file)) + const uploadFilesWithKey = uploadFiles.map((f) => ({ + ...f, + key: uuid(), + })) + + // Check whether upload will exceed limit and if so, prevent it + if ( + fileList.length + uploadFilesWithKey.length > + currentItem.inputSettings.fjoldi + ) { + setError(`Hámarksfjöldi skjala er ${currentItem.inputSettings.fjoldi}`) + return + } + setError('') + const newFileList = [...fileList, ...uploadFilesWithKey] + setFileList(newFileList) + } + + const onRemove = (fileToRemove: UploadFile) => { + const newFileList = fileList.filter((file) => file.key !== fileToRemove.key) + setFileList(newFileList) + } + + return ( + <> + `${f} `, + )}`} + buttonLabel="Veldu skjöl til að hlaða upp" + onChange={onChange} + onRemove={onRemove} + errorMessage={fileList.length > 0 ? error : undefined} + accept={currentItem.inputSettings.tegundir.map((t) => fileTypes[t])} + showFileSize + maxSize={currentItem.inputSettings.hamarksstaerd} + multiple={currentItem.inputSettings.erFjolval} + /> + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/List.tsx b/apps/form-builder/components/MainContent/components/Preview/components/List.tsx new file mode 100644 index 000000000000..abc77985f0ec --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/List.tsx @@ -0,0 +1,29 @@ +import { Select } from '@island.is/island-ui/core' +import { useEffect, useState } from 'react' +import { IInput } from '../../../../../types/interfaces' + +interface Props { + currentItem: IInput +} + +type ListItem = { + label: string + value: string | number +} + +export default function List({ currentItem }: Props) { + const [listItems, setListItems] = useState([]) + useEffect(() => { + setListItems( + currentItem.inputSettings.listi.map((l) => ({ + label: l.label.is, + value: l.label.is, + })), + ) + }, [currentItem.inputSettings.listi]) + return ( + <> + changeHandler(parseInt(e.target.value))} + errorMessage={error} + /> + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx new file mode 100644 index 000000000000..fbad4ea8fea8 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx @@ -0,0 +1,20 @@ +import { + GridRow as Row, + GridColumn as Column, + PhoneInput as Phone, +} from '@island.is/island-ui/core' +import { IInput } from '../../../../../types/interfaces' + +interface Props { + currentItem: IInput +} + +export default function PhoneInput({ currentItem }: Props) { + return ( + + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx new file mode 100644 index 000000000000..005f0a66cc04 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx @@ -0,0 +1,57 @@ +import { RadioButton, Text, Box } from '@island.is/island-ui/core' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { useContext, useEffect, useState } from 'react' +import { IInput } from '../../../../../types/interfaces' + +export default function Radio() { + const { lists } = useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const radioButtons = currentItem.inputSettings.listi + const [radioChecked, setRadioChecked] = useState([]) + + useEffect(() => { + setRadioChecked(radioButtons.map(() => false)) + }, [radioButtons]) + + const radioButton = (rb, index) => ( + + setRadioChecked((prev) => + prev.map((rb, i) => (i === index ? true : false)), + ) + } + > + + + ) + + return ( + <> + + {currentItem.name.is} + + + {radioButtons.map((rb, index) => radioButton(rb, index))} + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Ssn.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Ssn.tsx new file mode 100644 index 000000000000..a74431890a0d --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/Ssn.tsx @@ -0,0 +1,21 @@ +import { + Box, + Input, + Stack, + GridColumn as Column, +} from '@island.is/island-ui/core' + +export default function Ssn() { + return ( + + + + + + + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx b/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx new file mode 100644 index 000000000000..7722e7a8284b --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx @@ -0,0 +1,217 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, + Select, + Box, +} from '@island.is/island-ui/core' +import { ChangeEvent, useContext, useState } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../types/interfaces' + +type Option = { label: string; value: string } + +export default function TimeSelect() { + const { lists } = useContext(FormBuilderContext) + const { activeItem } = lists + const inputItem = activeItem.data as IInput + + const [timeInput, setTimeInput] = useState('') + + // 0: Minute + // 1: Hourly + // 2: Half hour + // 3: Quarter + const chosenMinuteList = (): Option[] => { + const min = minuteList.minuteList.map((t) => { + return { + label: t, + value: t, + } + }) + + if (inputItem?.inputSettings === undefined) { + return min + } else { + const interval = inputItem.inputSettings.interval + + if (interval === 0) { + return min + } else if (interval === 1) { + return [{ label: '00', value: '00' }] + } else if (interval === 2) { + return halfList.minuteList.map((m) => { + return { + label: m, + value: m, + } + }) + } else if (interval === 3) { + return quarterList.minuteList.map((m) => { + return { + label: m, + value: m, + } + }) + } else { + // Handle other cases if needed + return min + } + } + } + + const handleTimeInput = ( + e: ChangeEvent, + ) => { + const inputValue = e.target.value + console.log(inputValue) + + const isValidTime = + /^(?:[01]?[0-9]|2[0-3]):[0-5]?[0-9](?::[0-5]?[0-9])?$/.test(inputValue) + setTimeInput(inputValue) + console.log(isValidTime) + if (isValidTime || inputValue === '') { + setTimeInput(inputValue) + } + } + + return ( + <> + + + + + + handleTimeInput(e)} + /> + + ) +} + +const hourList = { + hourList: [ + '00', + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + '21', + '22', + '23', + ], +} + +const minuteList = { + minuteList: [ + '00', + '01', + '02', + '03', + '04', + '05', + '06', + '07', + '08', + '09', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + '18', + '19', + '20', + '21', + '22', + '23', + '24', + '25', + '26', + '27', + '28', + '29', + '30', + '31', + '32', + '33', + '34', + '35', + '36', + '37', + '38', + '39', + '40', + '41', + '42', + '43', + '44', + '45', + '46', + '47', + '48', + '49', + '50', + '51', + '52', + '53', + '54', + '55', + '56', + '57', + '58', + '59', + ], +} + +const quarterList = { + minuteList: ['00', '15', '30', '45'], +} + +const halfList = { + minuteList: ['00', '30'], +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx b/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx new file mode 100644 index 000000000000..9660d754e7b7 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx @@ -0,0 +1,11 @@ +import ReactDatePicker from 'react-datepicker' + +export default function UtilizationSummary() { + return ( + console.log(date)} + dateFormat="dd.MM.yyyy" + /> + ) +} diff --git a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx new file mode 100644 index 000000000000..df6e2a7149ec --- /dev/null +++ b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx @@ -0,0 +1,62 @@ +import { useContext, useEffect, useState } from 'react' +import { Box, Icon } from '@island.is/island-ui/core' +import Preview from '../../Preview/Preview' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IGroup, IInput } from '../../../../../types/interfaces' + +interface Props { + group: IGroup +} +export default function MultiSet({ group }: Props) { + const [multiInput, setMultiInput] = useState([]) + const { lists } = useContext(FormBuilderContext) + const { inputs } = lists + const originalInput = inputs.filter((i) => i.groupGuid === group.guid) + console.log('inMultiSet') + useEffect(() => { + setMultiInput([originalInput]) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + return ( + + {multiInput.map((inputArray, index) => ( +
+ {inputArray.map((i) => ( + + ))} +
+ ))} + + + + + +
+ ) + + function add() { + setMultiInput((prev) => [...prev, originalInput]) + } +} diff --git a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx new file mode 100644 index 000000000000..c56c54f0e023 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx @@ -0,0 +1,109 @@ +import { + Dispatch, + SetStateAction, + useContext, + useEffect, + useState, +} from 'react' +import { Box, Button, Text } from '@island.is/island-ui/core' +import Preview from '../Preview/Preview' +import MultiSet from './MultiSet/MultiSet' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { IGroup, NavbarSelectStatus } from '../../../../types/interfaces' + +interface Props { + setOpenPreview: Dispatch> +} + +export default function PreviewStepOrGroup({ setOpenPreview }: Props) { + const { lists, setSelectStatus } = useContext(FormBuilderContext) + const { activeItem, groups, inputs } = lists + const { type } = activeItem + const [groups2DArr, setGroups2DArr] = useState([]) + + useEffect(() => { + setSelectStatus(NavbarSelectStatus.ON_WITHOUT_SELECT) + groups.forEach((g) => { + if (g.multiSet !== 0) { + setGroups2DArr((prev) => [...prev, [g]]) + } + }) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + + useEffect(() => { + console.log(groups2DArr) + }, [groups2DArr]) + + return ( + + {type === 'Step' && ( + <> + + {activeItem.data.name.is} + + {groups + .filter((g) => g.stepGuid === activeItem.data.guid) + .map((g) => ( + + + {g.name.is} + + {g.multiSet !== 0 ? ( + + ) : ( + inputs + .filter((i) => i.groupGuid === g.guid) + .map((i) => ( + + )) + )} + + ))} + + )} + {type === 'Group' && ( + + + {activeItem.data.name.is} + + {(activeItem.data as IGroup).multiSet !== 0 ? ( + + ) : ( + inputs + .filter((i) => i.groupGuid === activeItem.data.guid) + .map((i) => ( + + )) + )} + + )} + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx new file mode 100644 index 000000000000..448cc77366ff --- /dev/null +++ b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx @@ -0,0 +1,155 @@ +import React, { useContext, useEffect, useState } from 'react' +import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { IInput } from '../../../../types/interfaces' +import { addInput, deleteItem } from '../../../../services/apiService' +import SingleParty from './components/SingleParty' + +const applicantTypeLabel = [ + 'Einstaklingur (innskráður)', + 'Einstaklingur í umboði annars einstaklings', + 'Einstaklingur í umboði lögaðila', + 'Einstaklingur með prókúru', +] + +const applicantTypes = [ + 'Einstaklingur', + 'Einstaklingur_með_umboð_annars_einstaklings', + 'Einstaklingur_með_umboð_lögaðila', + 'Einstaklingur_með_prókúru', +] + +export default function RelevantParties() { + const { lists, formBuilder, listsDispatch } = useContext(FormBuilderContext) + const { activeItem } = lists + const [relevantParties, setRelevantParties] = useState([]) + const groupId = lists.groups.find( + (g) => g.stepGuid === activeItem.data.guid, + ).id + + useEffect(() => { + setRelevantParties(() => { + const groupGuid = lists.groups.find( + (g) => g.stepGuid === activeItem.data.guid, + ).guid + return lists.inputs.filter((i) => i.groupGuid === groupGuid) + }) + }, [lists, activeItem.data.guid]) + + useEffect(() => { + console.log(relevantParties) + }, [relevantParties]) + + const handleCheckboxChange = async (checked: boolean, index: number) => { + if (checked) { + const newInput = await addInput(relevantParties.length, groupId) + const { label: is, value: en } = getOptions(applicantTypes[index])[0] + listsDispatch({ + type: 'addInputRelevantParty', + payload: { + data: newInput, + type: applicantTypes[index], + name: { + is, + en, + }, + }, + }) + } else { + const toDelete = relevantParties.find( + (i) => i.inputSettings.type === applicantTypes[index], + ) + deleteItem('Input', toDelete.id) + listsDispatch({ + type: 'removeInput', + payload: { + guid: toDelete.guid, + }, + }) + } + } + + const getOptions = (type: string) => { + return formBuilder.applicantTypes + .find((at) => at.type === type) + .nameSuggestions.map((n) => ({ + label: n.is, + value: n.en, + })) + } + + return ( + + + + Veldu þá einstaklinga sem mega opna þessa umsókn + + + + + {applicantTypeLabel.map((label, index) => ( + i.inputSettings.type === applicantTypes[index], + )} + onChange={(e) => { + handleCheckboxChange(e.target.checked, index) + }} + /> + ))} + + + {relevantParties.filter((i) => i.type === 'Aðili').length > 0 && ( // TODO: During lag, an input type with text input gets stored in the array + + * Skilgreindu hlutaðeigandi aðila + + )} + {relevantParties.some( + (i) => i.inputSettings.type === applicantTypes[0], + ) && ( + i.inputSettings.type === applicantTypes[0], + )} + /> + )} + {relevantParties.some( + (i) => i.inputSettings.type === applicantTypes[1], + ) && ( + i.inputSettings.type === applicantTypes[1], + )} + /> + )} + {relevantParties.some( + (i) => i.inputSettings.type === applicantTypes[2], + ) && ( + i.inputSettings.type === applicantTypes[2], + )} + /> + )} + {relevantParties.some( + (i) => i.inputSettings.type === applicantTypes[3], + ) && ( + i.inputSettings.type === applicantTypes[3], + )} + /> + )} + + ) +} diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx new file mode 100644 index 000000000000..d817efeae7cb --- /dev/null +++ b/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx @@ -0,0 +1,84 @@ +import { + Stack, + Text, + GridRow as Row, + GridColumn as Column, + Select, + Input, + Box, +} from '@island.is/island-ui/core' +import { IInput } from '../../../../../types/interfaces' +import { useState } from 'react' + + +interface Props { + title: string + options: { + label: string + value: string + }[] + input: IInput +} +export default function SingleParty({ title, options, input }: Props) { + // const { formDispatch } = useContext(FormBuilderContext) + // const { applicantTypes } = formBuilder + const [_focus, setFocus] = useState('') + return ( + + + + {title} + + + + setFocus(e.target.value)} + // onChange={(e) => { + // listsDispatch({ + // type: 'changeName', + // payload: { + // guid: input.guid, + // lang: 'is', + // newName: e.target.value + // } + // }) + // }} + /> + + + setFocus(e.target.value)} + /> + + + + + ) +} diff --git a/apps/form-builder/components/Navbar/Navbar.tsx b/apps/form-builder/components/Navbar/Navbar.tsx new file mode 100644 index 000000000000..5e73b6b34aa7 --- /dev/null +++ b/apps/form-builder/components/Navbar/Navbar.tsx @@ -0,0 +1,342 @@ +import { + useSensors, + useSensor, + PointerSensor, + DndContext, + DragOverlay, + UniqueIdentifier, + DragStartEvent, + DragOverEvent, +} from '@dnd-kit/core' +import { SortableContext } from '@dnd-kit/sortable' +import { useContext, useMemo } from 'react' +import { createPortal } from 'react-dom' +import { Box, Button } from '@island.is/island-ui/core' +import FormBuilderContext from '../../context/FormBuilderContext' +import { baseSettingsStep } from '../../utils/getBaseSettingsStep' +import { IFormBuilderContext, ItemType } from '../../types/interfaces' +import { + addGroup, + addInput, + addStep, + deleteItem, +} from '../../services/apiService' +import NavbarTab from './components/NavbarTab/NavbarTab' +import NavComponent from './components/NavComponent/NavComponent' + +export default function Navbar() { + const { + formBuilder, + lists, + listsDispatch, + formUpdate, + inSettings, + setInSettings, + } = useContext(FormBuilderContext) + + const { activeItem, steps, groups, inputs } = lists + const stepsIds = useMemo(() => steps?.map((s) => s.guid), [steps]) + const groupsIds = useMemo(() => groups?.map((g) => g.guid), [groups]) + const inputsIds = useMemo(() => inputs?.map((i) => i.guid), [inputs]) + + const sensors = useSensors( + useSensor(PointerSensor, { + activationConstraint: { + distance: 10, + }, + }), + ) + if (inSettings) { + return ( + + + + + + + + {steps + ?.filter((s) => s.type !== 'Innsláttur') + .map((s) => ( + + + + ))} + + + + + ) + } else if (formBuilder && activeItem) { + return ( + + + + + + + {steps + ?.filter((s) => s.type === 'Innsláttur') + .map((s, i) => ( + + + + {groups + ?.filter((g) => g.stepGuid === s.guid) + .map((g) => ( + + + + + {inputs + ?.filter((i) => i.groupGuid === g.guid) + .map((i) => ( + + ))} + + + ))} + + + ))} + + + {/* Only render client side */} + {typeof window === 'object' && + createPortal( + + {activeItem && ( + + )} + , + document.body, + )} + + + + + + ) + } + return null + + async function addNewStep() { + try { + const data = await addStep( + formBuilder.form.id, + { is: '', en: '' }, + lists.steps.length, + 2, + { is: '', en: '' }, + false, + ) + + if (data !== undefined) { + listsDispatch({ type: 'addStep', payload: { data: data } }) + } + } catch (error) { + console.error('Error adding new step:', error) + // Handle error as needed + } + } + + async function addItem(parentType: 'Step' | 'Group', parentId: number) { + try { + let data + + if (parentType === 'Step') { + data = await addGroup(lists.groups.length, parentId) + listsDispatch({ type: 'addGroup', payload: { data: data } }) + } + + if (parentType === 'Group') { + data = await addInput(lists.inputs.length, parentId) + listsDispatch({ type: 'addInput', payload: { data: data } }) + } + } catch (error) { + console.error('Error adding item:', error) + } + } + + function removeItem(type: ItemType, guid: UniqueIdentifier, id: number) { + const actionTypes: { [key: string]: string } = { + Step: 'removeStep', + Group: 'removeGroup', + Input: 'removeInput', + } + listsDispatch({ + type: actionTypes[type], + payload: { + guid: guid, + }, + }) + deleteItem(type, id) + } + + function focusComponent(type: ItemType, id: UniqueIdentifier) { + const dataTypes = { + Step: lists.steps, + Group: lists.groups, + Input: lists.inputs, + } + + const data = dataTypes[type]?.find((item) => item.guid === id) + console.log('focusComponent data: ', data) + if (id === baseSettingsStep.guid) { + listsDispatch({ + type: 'setActiveItem', + payload: { + type: 'Step', + data: baseSettingsStep, + }, + }) + } else { + listsDispatch({ + type: 'setActiveItem', + payload: { + type: type, + data: data, + }, + }) + } + } + + function onDragStart(event: DragStartEvent) { + listsDispatch({ + type: 'setActiveItem', + payload: { + type: event.active.data.current?.type, + data: event.active.data.current?.data ?? null, + }, + }) + } + + function onDragEnd() { + formUpdate() + } + + function onDragOver(event: DragOverEvent) { + const { active, over } = event + + if (!over) return + + const activeId = active.id + const overId = over.id + + if (activeId === overId) return + + const getType = (data, targetType) => data?.current?.type === targetType + + const activeStep = getType(active.data, 'Step') + const activeGroup = getType(active.data, 'Group') + const activeInput = getType(active.data, 'Input') + const overStep = getType(over.data, 'Step') + const overGroup = getType(over.data, 'Group') + const overInput = getType(over.data, 'Input') + + const dispatchDragAction = (type: string) => + listsDispatch({ type, payload: { activeId, overId } }) + + // Dragging step + if (activeStep && overStep) { + dispatchDragAction('stepOverStep') + } + + // Dragging Group + if (activeGroup) { + if (overStep) { + dispatchDragAction('groupOverStep') + } + if (overGroup) { + dispatchDragAction('groupOverGroup') + } + } + + // Dragging Input + if (activeInput) { + if (overGroup) { + dispatchDragAction('inputOverGroup') + } + if (overInput) { + dispatchDragAction('inputOverInput') + } + } + } +} diff --git a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts new file mode 100644 index 000000000000..b5087ff5fa49 --- /dev/null +++ b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts @@ -0,0 +1,93 @@ +import { style, styleVariants } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +const base = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + marginLeft: 'auto', + backgroundColor: theme.color.blue100, + lineHeight: '46px', + ':hover': { + fontWeight: 'bolder', + }, + cursor: 'grab', +}) + +export const step = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + width: '100%', +}) + +export const navComponent = styleVariants({ + step: [ + base, + { + width: '100%', + }, + ], + group: [ + base, + { + width: '90%', + }, + ], + input: [ + base, + { + width: '80%', + }, + ], +}) + +const baseBackground = style({ + width: '25px', + height: '44px', + /* top-left | top-right | bottom-right | bottom-left */ + borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, + textAlign: 'center', +}) + +export const navBackgroundActive = styleVariants({ + step: [ + baseBackground, + { + backgroundColor: theme.color.blue600, + lineHeight: '45px', + //textAlign: 'center', + color: theme.color.white, + }, + ], + group: [ + baseBackground, + { + backgroundColor: theme.color.roseTinted400, + }, + ], + input: [ + baseBackground, + { + backgroundColor: theme.color.purple400, + }, + ], +}) + +export const navBackgroundDefault = styleVariants({ + step: [ + baseBackground, + { + lineHeight: '45px', + //textAlign: 'center', + }, + ], + group: [baseBackground, {}], + input: [baseBackground, {}], +}) + +export const customBackgroundDropdown = style({ + background: theme.color.blue100, +}) diff --git a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx new file mode 100644 index 000000000000..e79a5e2b00b8 --- /dev/null +++ b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx @@ -0,0 +1,183 @@ +import { useState } from 'react' +import { ItemType, IGroup, IInput, IStep } from '../../../../types/interfaces' +import { useSortable } from '@dnd-kit/sortable' +import { Box } from '@island.is/island-ui/core' +import cn from 'classnames' +import * as styles from './NavComponent.css' +import { UniqueIdentifier } from '@dnd-kit/core' +import NavButtons from './components/NavButtons' +//import NavButtons from "./components/navButtons" + +type Props = { + type: ItemType + data: IStep | IGroup | IInput + active: boolean + index?: number + focusComponent(type: ItemType, id: UniqueIdentifier): void + add(type: 'Step' | 'Group', parentId: number): void + remove( + type: 'Step' | 'Group' | 'Input', + guid: UniqueIdentifier, + id: number, + ): void +} + +export default function NavComponent({ + type, + data, + active, + index, + focusComponent, + add, + remove, +}: Props) { + const [editMode] = useState(false) + + const { setNodeRef, attributes, listeners, isDragging } = useSortable({ + id: data.guid, + data: { + type: type, + data, + }, + disabled: editMode, + }) + + if (isDragging) { + return ( +
+
+
+ ) + } + + return ( + focusComponent(type, data.guid)} + > + {active ? ( + // Active + + + {index} + + + {truncateName(data.name.is)} + + + {!(type === 'Step' && (data as IStep).type !== 'Innsláttur') && ( + + )} + + + ) : ( + // Default + + + {index} + + + {truncateName(data.name.is)} + + + )} + + ) + + function truncateText(text, maxLength) { + return text.length > maxLength ? text.slice(0, maxLength) + '...' : text + } + + function truncateName(name) { + let maxLength + + if (active) { + switch (type) { + case 'Step': + maxLength = 23 + break + case 'Group': + maxLength = 16 + break + case 'Input': + maxLength = 12 + break + default: + maxLength = 26 + } + } else { + switch (type) { + case 'Step': + maxLength = 26 + break + case 'Group': + maxLength = 19 + break + case 'Input': + maxLength = 16 + break + default: + maxLength = 26 + } + } + + return truncateText(name, maxLength) + } +} diff --git a/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx b/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx new file mode 100644 index 000000000000..9625c9b7f658 --- /dev/null +++ b/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx @@ -0,0 +1,46 @@ +import { Box, Icon } from '@island.is/island-ui/core' +import { useContext } from 'react' +import { UniqueIdentifier } from '@dnd-kit/core' +import FormBuilderContext from '../../../../../context/FormBuilderContext' + +type Props = { + add(type: 'Step' | 'Group', parentId: number): void + remove( + type: 'Step' | 'Group' | 'Input', + guid: UniqueIdentifier, + id: number, + ): void +} + +export default function NavButtons({ add, remove }: Props) { + const { lists } = useContext(FormBuilderContext) + const { activeItem } = lists + return ( + + {activeItem.type !== 'Input' && ( + { + add( + activeItem.type == 'Group' || activeItem.type === 'Step' + ? activeItem.type + : null, + activeItem.data.id, + ) + }} + > + + + )} + { + remove(activeItem.type, activeItem.data.guid, activeItem.data.id) + }} + > + + + + ) +} diff --git a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx new file mode 100644 index 000000000000..3dd7d13a1cfa --- /dev/null +++ b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx @@ -0,0 +1,20 @@ +import { style } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const selected = style({ + cursor: 'pointer', + fontWeight: 'bolder', + textDecoration: 'underline', + color: theme.color.blue400, + // border: `1px solid ${theme.color.blue400}`, + // padding: '10px', + // borderRadius: '9px' +}) + +export const notSelected = style({ + cursor: 'pointer', + ':hover': { + fontWeight: 'bolder', + textDecoration: 'underline', + }, +}) diff --git a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx new file mode 100644 index 000000000000..509ae6bc8bda --- /dev/null +++ b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx @@ -0,0 +1,57 @@ +import { Box, Inline } from '@island.is/island-ui/core' +import cn from 'classnames' +import * as styles from './NavbarTab.css' +import { Dispatch, SetStateAction, useContext } from 'react' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { baseSettingsStep } from '../../../../utils/getBaseSettingsStep' + +type Props = { + inSettings: boolean + setInSettings: Dispatch> +} + +export default function NavbarTab({ inSettings, setInSettings }: Props) { + const { lists, listsDispatch } = useContext(FormBuilderContext) + return ( + + + { + listsDispatch({ + type: 'setActiveItem', + payload: { + type: 'Step', + data: lists.steps[2], + }, + }) + setInSettings(false) + }} + > + Skref + + { + listsDispatch({ + type: 'setActiveItem', + payload: { + type: 'Step', + data: baseSettingsStep, + }, + }) + setInSettings(true) + }} + > + Grunnstillingar + + + + ) +} diff --git a/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx b/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx new file mode 100644 index 000000000000..0a0e14b1debb --- /dev/null +++ b/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx @@ -0,0 +1,64 @@ +import { useContext } from 'react' +import { Box, Text } from '@island.is/island-ui/core' +import SelectNavComponent from './components/SelectNavComponent' +import FormBuilderContext from '../../context/FormBuilderContext' +import { NavbarSelectStatus } from '../../types/interfaces' + +export default function NavbarSelect() { + const { lists, selectStatus } = useContext(FormBuilderContext) + const { activeItem, steps, groups, inputs } = lists + //const [selectable, setSelectable] = useState(false) + console.log(selectStatus) + let selectable = false + return ( + + + Skref + + {steps + .filter((s) => s.type === 'Innsláttur') + .map((s) => ( + + + {groups + .filter((g) => g.stepGuid === s.guid) + .map((g) => ( + + + {inputs + .filter((i) => i.groupGuid === g.guid) + .map((i) => { + if (activeItem.data.guid === i.guid) { + if ( + selectStatus !== NavbarSelectStatus.ON_WITHOUT_SELECT + ) { + selectable = true + } + } + return ( + + ) + })} + + ))} + + ))} + + ) +} diff --git a/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx b/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx new file mode 100644 index 000000000000..346228c616e6 --- /dev/null +++ b/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx @@ -0,0 +1,148 @@ +import cn from 'classnames' +import * as styles from './selectNavComponent.css' +import { Box, Checkbox } from '@island.is/island-ui/core' +import { useContext } from 'react' +import { + IGroup, + IInput, + IStep, + ItemType, + NavbarSelectStatus, +} from '../../../types/interfaces' +import FormBuilderContext from '../../../context/FormBuilderContext' + +type Props = { + type: ItemType + data: IStep | IGroup | IInput + active: boolean + selectable: boolean +} + +export default function SelectNavComponent({ + type, + data, + active, + selectable, +}: Props) { + const { formBuilder, formDispatch, lists, selectStatus, activeListItem } = + useContext(FormBuilderContext) + const { activeItem } = lists + const { form } = formBuilder + const activeGuid = + selectStatus === NavbarSelectStatus.LIST_ITEM + ? activeListItem?.guid + : activeItem.data.guid + const connected = + form.dependencies[activeGuid]?.includes(data.guid as string) || + !form.dependencies + return ( + + {active ? ( + + + {/* Index */} + + + {truncateName(data.name.is)} + + + ) : ( + + + {/* {index} */} + + + {truncateName(data.name.is)} + + {selectable && ( + + { + formDispatch({ + type: 'addRemoveConnection', + payload: { + active: activeGuid, + item: data.guid, + }, + }) + }} + /> + + )} + + )} + + ) + + function truncateText(text, maxLength) { + return text.length > maxLength ? text.slice(0, maxLength) + '...' : text + } + + function truncateName(name) { + let maxLength + + if (active) { + switch (type) { + case 'Step': + maxLength = 23 + break + case 'Group': + maxLength = 16 + break + case 'Input': + maxLength = 12 + break + default: + maxLength = 26 + } + } else { + switch (type) { + case 'Step': + maxLength = 26 + break + case 'Group': + maxLength = 19 + break + case 'Input': + maxLength = 16 + break + default: + maxLength = 26 + } + } + + return truncateText(name, maxLength) + } +} diff --git a/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts b/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts new file mode 100644 index 000000000000..e4f29759eebc --- /dev/null +++ b/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts @@ -0,0 +1,93 @@ +import { style, styleVariants } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +const base = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + marginLeft: 'auto', + backgroundColor: theme.color.white, + lineHeight: '46px', + ':hover': { + fontWeight: 'bolder', + }, + cursor: 'grab', +}) + +export const step = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + width: '100%', +}) + +export const navComponent = styleVariants({ + step: [ + base, + { + width: '100%', + }, + ], + group: [ + base, + { + width: '90%', + }, + ], + input: [ + base, + { + width: '80%', + }, + ], +}) + +const baseBackground = style({ + width: '25px', + height: '44px', + /* top-left | top-right | bottom-right | bottom-left */ + borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, + textAlign: 'center', +}) + +export const navBackgroundActive = styleVariants({ + step: [ + baseBackground, + { + backgroundColor: theme.color.blue600, + lineHeight: '45px', + //textAlign: 'center', + color: theme.color.white, + }, + ], + group: [ + baseBackground, + { + backgroundColor: theme.color.roseTinted400, + }, + ], + input: [ + baseBackground, + { + backgroundColor: theme.color.purple400, + }, + ], +}) + +export const navBackgroundDefault = styleVariants({ + step: [ + baseBackground, + { + lineHeight: '45px', + //textAlign: 'center', + }, + ], + group: [baseBackground, {}], + input: [baseBackground, {}], +}) + +export const customBackgroundDropdown = style({ + background: theme.color.blue100, +}) diff --git a/apps/form-builder/components/TableRow/TableRow.css.tsx b/apps/form-builder/components/TableRow/TableRow.css.tsx new file mode 100644 index 000000000000..130bb8609ecc --- /dev/null +++ b/apps/form-builder/components/TableRow/TableRow.css.tsx @@ -0,0 +1,8 @@ +import { style } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const header = style({ + padding: '10px 0 10px 0', + backgroundColor: theme.color.blue100, + borderBottom: `1px solid ${theme.border.color.blue200}`, +}) diff --git a/apps/form-builder/components/TableRow/TableRow.tsx b/apps/form-builder/components/TableRow/TableRow.tsx new file mode 100644 index 000000000000..a6534187323b --- /dev/null +++ b/apps/form-builder/components/TableRow/TableRow.tsx @@ -0,0 +1,203 @@ +import { + GridRow as Row, + GridColumn as Column, + Text, + Divider, + Box, + DropdownMenu, + Button, +} from '@island.is/island-ui/core' +import * as styles from './TableRow.css' +import { useState } from 'react' +import { AnimatePresence, motion } from 'framer-motion' +import { useRouter } from 'next/router' +import TranslationTag from '../TranslationTag/TranslationTag' +import { formatDate } from '../../utils/formatDate' +import { + ApplicationTemplateStatus, + LicenseProviderEnum, +} from '../../types/enums' + +interface Props { + id?: number + name?: string + created?: Date + lastModified?: Date + org?: number + state?: number + options?: string + isHeader: boolean + translated?: boolean +} + +interface ColumnTextProps { + text: string | number +} + +const ColumnText = ({ text }: ColumnTextProps) => ( + + {text} + +) + +const TableRow = ({ + id, + name, + lastModified, + org, + state, + isHeader, + translated, +}: Props) => { + const [isOpen, setIsOpen] = useState(false) + const router = useRouter() + if (isHeader) return header() + return ( + setIsOpen(!isOpen)} + style={{ cursor: '' }} + > + + + + + + + + + + + + + + + + + + + + + + + + + } + items={[ + { + title: 'Breyta', + onClick: () => { + router.push(`/Form/${id}`) + }, + }, + { + title: 'Afrita', + onClick: () => { + console.log('Afrita') + }, + }, + { + title: 'Þýðing enska', + onClick: () => { + console.log('Þýðing enska') + }, + }, + { + title: 'Sækja slóð', + onClick: () => { + console.log('Sækja slóð') + }, + }, + { + title: 'Export', + onClick: () => { + console.log('Export') + }, + }, + { + title: 'Sækja json', + onClick: () => { + console.log('Sækja json') + }, + }, + ]} + /> + + + + + {isOpen === true ? ( + + + + + + ) : null} + + + + ) +} + +export default TableRow + +const header = () => ( + <> + + + + Númer + + + Heiti + + + Síðast breytt + + + Þýðingar + + + Stofnun + + + Staða + + + Aðgerðir + + + + +) diff --git a/apps/form-builder/components/Tabs/index.tsx b/apps/form-builder/components/Tabs/index.tsx new file mode 100644 index 000000000000..138e44bb64dc --- /dev/null +++ b/apps/form-builder/components/Tabs/index.tsx @@ -0,0 +1,51 @@ +import { Box, Inline, FocusableBox } from '@island.is/island-ui/core' +import { Dispatch, SetStateAction } from 'react' +import * as styles from './tabs.css' + +interface Props { + selectedTab: number + setSelectedTab: Dispatch> + // allTemp: IApplicationTemplate[] +} + +export default function Tabs({ selectedTab, setSelectedTab }: Props) { + return ( + + + setSelectedTab(0)} + > + {/* {`Óútgefið (${allTemp.filter(t => t.status == 0).length})`} */} + Óútgefið + + setSelectedTab(1)} + > + {/* {`Útgefið í breytingu (${allTemp.filter(t => t.status == 1).length})`} */} + Útgefið + + setSelectedTab(2)} + > + {/* {`Útgefið (${allTemp.filter(t => t.status == 2).length})`} */} + Útgefið + + + + ) +} diff --git a/apps/form-builder/components/Tabs/tabs.css.ts b/apps/form-builder/components/Tabs/tabs.css.ts new file mode 100644 index 000000000000..8ea98181e27d --- /dev/null +++ b/apps/form-builder/components/Tabs/tabs.css.ts @@ -0,0 +1,14 @@ +import { style } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const tab = style({ + padding: '10px', + width: '100%', + cursor: 'pointer', +}) + +export const selected = style({ + color: theme.color.blue400, + borderBottom: `1px solid ${theme.border.color.blue400}`, + fontWeight: 'bolder', +}) diff --git a/apps/form-builder/components/TranslationTag/TranslationTag.tsx b/apps/form-builder/components/TranslationTag/TranslationTag.tsx new file mode 100644 index 000000000000..b452797ce9b6 --- /dev/null +++ b/apps/form-builder/components/TranslationTag/TranslationTag.tsx @@ -0,0 +1,12 @@ +import { Tag } from '@island.is/island-ui/core' +interface Props { + translated: boolean +} + +export default function TranslationTag({ translated }: Props) { + if (translated) { + return Þýdd + } else { + return Óþýdd + } +} diff --git a/apps/form-builder/context/FormBuilderContext.tsx b/apps/form-builder/context/FormBuilderContext.tsx new file mode 100644 index 000000000000..fe2fda0e97b2 --- /dev/null +++ b/apps/form-builder/context/FormBuilderContext.tsx @@ -0,0 +1,60 @@ +import { ChangeEvent, FocusEvent, SetStateAction, createContext } from 'react' +import { + ActiveItem, + IFormBuilder, + IFormBuilderContext, + IListItem, + NavbarSelectStatus, +} from '../types/interfaces' + +const FormBuilderContext = createContext({ + formBuilder: {} as IFormBuilder, + formDispatch: function (_value: unknown): void { + throw new Error('Function not implemented.') + }, + lists: { + activeItem: {} as ActiveItem, + steps: [], + groups: [], + inputs: [], + }, + listsDispatch: function (_value: unknown): void { + throw new Error('Function not implemented.') + }, + formUpdate: async function (): Promise { + throw new Error('Function not implemented.') + }, + setIsTyping: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + inSettings: false, + setInSettings: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + setSelectStatus: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + selectStatus: NavbarSelectStatus.OFF, + setActiveListItem: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + changeSelectHandler: function (_e: unknown): void { + throw new Error('Function not implemented.') + }, + changeHandler: function ( + _e: ChangeEvent, + _propertyName: string, + ): void { + throw new Error('Function not implemented.') + }, + blur: function ( + _e: FocusEvent, + ): void { + throw new Error('Function not implemented.') + }, + onFocus: function (_e: string): void { + throw new Error('Function not implemented.') + }, +}) + +export default FormBuilderContext diff --git a/apps/form-builder/context/LayoutContext.tsx b/apps/form-builder/context/LayoutContext.tsx new file mode 100644 index 000000000000..82bed301b7aa --- /dev/null +++ b/apps/form-builder/context/LayoutContext.tsx @@ -0,0 +1,14 @@ +import { createContext } from 'react' +import { ILayoutContext } from '../types/interfaces' + +const LayoutContext = createContext({ + info: { + organization: '', + applicationName: '', + }, + infoDispatch: function (_value: unknown): void { + throw new Error('Function not implemented.') + }, +}) + +export default LayoutContext diff --git a/apps/form-builder/environments/environment.ts b/apps/form-builder/environments/environment.ts new file mode 100644 index 000000000000..53f69e76d4c9 --- /dev/null +++ b/apps/form-builder/environments/environment.ts @@ -0,0 +1,9 @@ +const devConfig = { + production: false, +} + +const prodConfig = { + production: true, +} + +export default process.env.NODE_ENV === 'production' ? prodConfig : devConfig diff --git a/apps/form-builder/hooks/fileUploadReducer.ts b/apps/form-builder/hooks/fileUploadReducer.ts new file mode 100644 index 000000000000..4e8c480714b1 --- /dev/null +++ b/apps/form-builder/hooks/fileUploadReducer.ts @@ -0,0 +1,43 @@ +import { UploadFile, UploadFileStatus } from '@island.is/island-ui/core' + +enum ActionTypes { + add = 'add', + remove = 'remove', + update = 'update', +} + +type FileUploadActions = + | { type: 'add'; payload: { newFiles: UploadFile[] } } + | { type: 'remove'; payload: { fileToRemove: UploadFile } } + | { + type: 'update' + payload: { file: UploadFile; status: UploadFileStatus; percent: number } + } + +export default function fileUploadReducer( + state: UploadFile[], + action: FileUploadActions, +) { + switch (action.type) { + case ActionTypes.add: + return state.concat(action.payload.newFiles) + + case ActionTypes.remove: + return state.filter( + (file) => file.name !== action.payload.fileToRemove.name, + ) + + case ActionTypes.update: + return [ + ...state.map((file: UploadFile) => { + if (file.name === action.payload.file.name) { + file.status = action.payload.status + file.percent = action.payload.percent + } + return file + }), + ] + default: + throw new Error() + } +} diff --git a/apps/form-builder/hooks/formReducer.tsx b/apps/form-builder/hooks/formReducer.tsx new file mode 100644 index 000000000000..b730b57b47b3 --- /dev/null +++ b/apps/form-builder/hooks/formReducer.tsx @@ -0,0 +1,183 @@ +import { UniqueIdentifier } from '@dnd-kit/core' +import { IFormBuilder, ILanguage, ITenging } from '../types/interfaces' +import { saveFormSettings } from '../services/apiService' + +type ChangeNameAction = { + type: 'changeName' + payload: { + lang: string + newName: string + } +} + +type ApplicationsDaysToRemoveAction = { + type: 'applicationsDaysToRemove' + payload: { + value: number + } +} + +type InvalidationDateAction = { + type: 'invalidationDate' + payload: { + value: Date + } +} + +type StopProgressOnValidatingStepAction = { + type: 'stopProgressOnValidatingStep' + payload: { + value: boolean + } +} + +type AddRemoveConnectionAction = { + type: 'addRemoveConnection' + payload: { + active: UniqueIdentifier + item: UniqueIdentifier + } +} + +type AddRemoveDocuments = { + type: 'addRemoveDocuments' + payload: { + documents: string[] + } +} + +type FormSettingsPayload = + | { property: 'invalidationDate'; value: Date } + | { property: 'dependencies'; value: ITenging } + | { property: 'stopProgressOnValidatingStep'; value: boolean } + | { property: 'applicationsDaysToRemove'; value: number } + | { property: 'documents'; value: string[] } + | { property: 'adilar'; value: string[] } + | { property: 'completedMessage'; value: ILanguage } + | { property: 'isTranslated'; value: boolean } + +type FormSettingsAction = { + type: 'formSettings' + payload: FormSettingsPayload +} + +type Action = + | ChangeNameAction + | ApplicationsDaysToRemoveAction + | InvalidationDateAction + | StopProgressOnValidatingStepAction + | AddRemoveConnectionAction + | FormSettingsAction + | AddRemoveDocuments + +export function formReducer(formBuilder: IFormBuilder, action: Action) { + switch (action.type) { + case 'changeName': { + const { lang, newName } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + name: { + ...formBuilder.form.name, + [lang]: newName, + }, + }, + } + } + case 'applicationsDaysToRemove': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + applicationsDaysToRemove: value, + }, + } + } + case 'invalidationDate': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + invalidationDate: value, + }, + } + } + case 'stopProgressOnValidatingStep': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + stopProgressOnValidatingStep: value, + }, + } + } + case 'addRemoveConnection': { + const { active, item } = action.payload + const itemAsString = String(item) + const dependencies = { ...formBuilder.form.dependencies } + + if (active in dependencies) { + if (!dependencies[active].includes(itemAsString)) { + dependencies[active] = [...dependencies[active], itemAsString] + } else { + dependencies[active] = dependencies[active].filter((t) => t !== item) + if (dependencies[active].length === 0) { + delete dependencies[active] + } + } + } else { + dependencies[active] = [itemAsString] + } + return { + ...formBuilder, + form: { + ...formBuilder.form, + dependencies, + }, + } + } + + case 'formSettings': { + console.log('formReducer formSettings') + const { property, value } = action.payload + const { id } = formBuilder.form + saveFormSettings(id, { + id: id, + [property]: value, + }) + return { + ...formBuilder, + form: { + ...formBuilder.form, + [property]: value, + }, + } + } + + case 'addRemoveDocuments': { + const { documents } = action.payload + console.log('dasdsa') + saveFormSettings(formBuilder.form.id, { + id: formBuilder.form.id, + documents: documents, + }) + return { + ...formBuilder, + form: { + ...formBuilder.form, + documents: documents, + }, + } + } + default: + return formBuilder + } +} + +// function saveSettings(form: IFormBuilder, property: string, value: unknown) { + +// } diff --git a/apps/form-builder/hooks/headerInfoReducer.tsx b/apps/form-builder/hooks/headerInfoReducer.tsx new file mode 100644 index 000000000000..65ba48e76c61 --- /dev/null +++ b/apps/form-builder/hooks/headerInfoReducer.tsx @@ -0,0 +1,29 @@ +type Action = + | { type: 'changeOrganization'; payload: { value: string } } + | { type: 'changeApplicationName'; payload: { value: string } } + +export function headerInfoReducer( + info: { + organization: string + applicationName: string + }, + action: Action, +) { + switch (action.type) { + case 'changeOrganization': { + return { + ...info, + organization: action.payload?.value ? action.payload.value : '', + } + } + case 'changeApplicationName': { + return { + ...info, + applicationName: action.payload?.value ? action.payload.value : '', + } + } + default: { + return info + } + } +} diff --git a/apps/form-builder/hooks/listsReducer.tsx b/apps/form-builder/hooks/listsReducer.tsx new file mode 100644 index 000000000000..e8ded74a3bb2 --- /dev/null +++ b/apps/form-builder/hooks/listsReducer.tsx @@ -0,0 +1,772 @@ +import { arrayMove } from '@dnd-kit/sortable' +import { + ItemType, + IGroup, + IInput, + IInputSettings, + IListItem, + ILists, + IStep, + ActiveItem, + ILanguage, +} from '../types/interfaces' +import { UniqueIdentifier } from '@dnd-kit/core' +import { uuid } from 'uuidv4' +import { updateItem } from '../services/apiService' + +export type ILang = 'is' | 'en' + +type DndAction = + | { + type: 'stepOverStep' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'groupOverStep' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'groupOverGroup' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'inputOverGroup' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'inputOverInput' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'listItemOverListItem' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + +type AddRemoveAction = + | { type: 'addStep'; payload: { data: IStep } } + | { type: 'addGroup'; payload: { data: IGroup } } + | { type: 'addInput'; payload: { data: IInput } } + | { type: 'removeStep'; payload: { guid: UniqueIdentifier } } + | { type: 'removeGroup'; payload: { guid: UniqueIdentifier } } + | { type: 'removeInput'; payload: { guid: UniqueIdentifier } } + | { type: 'addListItem' } + | { type: 'removeListItem'; payload: { guid: UniqueIdentifier } } + | { + type: 'addInputRelevantParty' + payload: { data: IInput; type: string; name: ILanguage } + } + +type ChangeAction = + | { + type: 'changeName' + payload: { + activeType: ItemType + index: number + lang: ILang + newValue: string + } + } + | { + type: 'changeInputType' + payload: { + index: number + newValue: string | number + inputSettings: unknown + } + } + | { + type: 'setIsRequired' + payload: { guid: UniqueIdentifier; isRequired: boolean } + } + | { type: 'setDescription'; payload: { lang: ILang; newValue: string } } + | { + type: 'changeInputName' + payload: { guid: UniqueIdentifier; lang: ILang; newValue: string } + } + +type ControlAction = + | { + type: 'setActiveItem' + payload: { type: ItemType; data: IStep | IGroup | IInput } + } + | { type: 'setActiveListItem'; payload: { listItem: IListItem } } + +type InputSettingsAction = + | { type: 'timeInterval'; payload: { data: number } } + | { type: 'setInputSettings'; payload: { inputSettings: IInputSettings } } + | { + type: 'setMessageWithLinkSettings' + payload: { + property: 'hnapptexti' | 'url' | 'erHlekkur' + value?: string + checked?: boolean + lang: ILang + } + } + | { + type: 'setFileUploadSettings' + payload: { + property: 'erFjolval' | 'fjoldi' | 'hamarksstaerd' | 'tegundir' + checked?: boolean + value: number | string + } + } + | { + type: 'setNumberInputSettings' + payload: { + property: 'lagmarkslengd' | 'hamarkslengd' | 'laggildi' | 'hagildi' + value: number + } + } + | { + type: 'setListItemSelected' + payload: { guid: UniqueIdentifier; checked: boolean } + } + | { + type: 'setListItem' + payload: { + property: 'text' | 'description' + lang: ILang + value: string + listItemGuid: UniqueIdentifier + } + } + | { type: 'setMultiSet'; payload: { checked: boolean } } + | { + type: 'setRelevantPartiesSettings' + payload: { property: 'type' | 'name'; lang?: ILang; type: string } + } + +export type Action = + | DndAction + | AddRemoveAction + | ChangeAction + | ControlAction + | InputSettingsAction + +export const listsReducer = (lists: ILists, action: Action): ILists => { + const types = { + Step: 'steps', + Group: 'groups', + Input: 'inputs', + } + const { activeItem, steps, groups, inputs } = lists + //const activeIndex = lists[types[activeItem.type]].findIndex((e) => e.guid === activeItem.data.guid) + + const addNewInput = (newInput: IInput, toSave: boolean) => { + toSave && updateItem('Input', newInput) + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => + i.guid === activeItem.data.guid ? newInput : i, + ), + } + } + + switch (action.type) { + // case actions.initialize: { + // return action.payload + // } + + // DnD control + case 'stepOverStep': { + const activeIndex = steps.findIndex( + (s) => s.guid === action.payload.activeId, + ) + const overIndex = steps.findIndex((s) => s.guid === action.payload.overId) + const updatedSteps = arrayMove(steps, activeIndex, overIndex) + return { + ...lists, + steps: updatedSteps, + } + } + case 'groupOverStep': { + const activeIndex = groups.findIndex( + (g) => g.guid === action.payload.activeId, + ) + const overIndex = steps.findIndex((s) => s.guid === action.payload.overId) + + const updatedGroup = groups + updatedGroup[activeIndex].stepGuid = action.payload.overId + updatedGroup[activeIndex].stepId = steps[overIndex].id + + return { + ...lists, + groups: arrayMove(updatedGroup, activeIndex, activeIndex), + } + } + case 'groupOverGroup': { + const activeIndex = groups.findIndex( + (g) => g.guid === action.payload.activeId, + ) + const overIndex = groups.findIndex( + (g) => g.guid === action.payload.overId, + ) + + const updatedGroup = groups + if ( + updatedGroup[activeIndex].stepGuid !== updatedGroup[overIndex].stepGuid + ) { + updatedGroup[activeIndex].stepGuid = updatedGroup[overIndex].stepGuid + updatedGroup[activeIndex].stepId = updatedGroup[overIndex].stepId + return { + ...lists, + groups: arrayMove(updatedGroup, activeIndex, overIndex - 1), + } + } + return { + ...lists, + groups: arrayMove(updatedGroup, activeIndex, overIndex), + } + } + case 'inputOverGroup': { + const activeIndex = inputs.findIndex( + (i) => i.guid === action.payload.activeId, + ) + const overIndex = groups.findIndex( + (g) => g.guid === action.payload.overId, + ) + + const updatedInput = inputs + updatedInput[activeIndex].groupGuid = action.payload.overId + updatedInput[activeIndex].groupId = groups[overIndex].id + return { + ...lists, + inputs: arrayMove(updatedInput, activeIndex, activeIndex), + } + } + case 'inputOverInput': { + const activeIndex = inputs.findIndex( + (i) => i.guid === action.payload.activeId, + ) + const overIndex = inputs.findIndex( + (i) => i.guid === action.payload.overId, + ) + + const updatedInput = inputs + if ( + updatedInput[activeIndex].groupGuid !== + updatedInput[overIndex].groupGuid + ) { + updatedInput[activeIndex].groupGuid = updatedInput[overIndex].groupGuid + updatedInput[activeIndex].groupId = updatedInput[overIndex].groupId + return { + ...lists, + inputs: arrayMove(updatedInput, activeIndex, overIndex - 1), + } + } + return { + ...lists, + inputs: arrayMove(updatedInput, activeIndex, overIndex), + } + } + case 'listItemOverListItem': { + const input = activeItem.data as IInput + const { listi: list } = input.inputSettings + if (list === undefined) { + return lists + } + const activeIndex = list.findIndex( + (l) => l.guid === action.payload.activeId, + ) + const overIndex = list.findIndex((l) => l.guid === action.payload.overId) + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + listi: arrayMove(list, activeIndex, overIndex).map((l, i) => ({ + ...l, + displayOrder: i, + })), + }, + } + return addNewInput(newInput, false) + } + + // DnD control - end + // Add + case 'addStep': { + return { + ...lists, + activeItem: { + type: 'Step', + data: action.payload.data, + }, + steps: [...steps, action.payload.data], + } + } + case 'addGroup': { + return { + ...lists, + activeItem: { + type: 'Group', + data: action.payload.data, + }, + groups: [...groups, action.payload.data], + } + } + case 'addInput': { + return { + ...lists, + activeItem: { + type: 'Input', + data: action.payload.data, + }, + inputs: [...inputs, action.payload.data], + } + } + case 'addInputRelevantParty': { + const newInput = { + ...action.payload.data, + name: action.payload.name, + type: 'Aðili', + inputSettings: { + $type: 'adili', + type: action.payload.type, + }, + } + updateItem('Input', newInput) + return { + ...lists, + inputs: [...inputs, newInput], + } + } + //Add - end + // Remove + case 'removeStep': { + return { + ...lists, + steps: steps.filter((s) => s.guid !== action.payload.guid), + } + } + case 'removeGroup': { + return { + ...lists, + groups: groups.filter((g) => g.guid !== action.payload.guid), + } + } + case 'removeInput': { + return { + ...lists, + inputs: inputs.filter((i) => i.guid !== action.payload.guid), + } + } + // Remove - end + + // ChangeHandlers + case 'changeName': { + const updatedList = [...lists[types[activeItem.type]]] + const activeIndex = lists[types[activeItem.type]].findIndex( + (e: { guid: UniqueIdentifier }) => e.guid === activeItem.data.guid, + ) + updatedList[activeIndex] = { + ...lists[types[activeItem.type]][activeIndex], + name: { + ...lists[types[activeItem.type]][activeIndex].name, + [action.payload.lang]: action.payload.newValue, + }, + } + + const newActive = { + type: activeItem.type, + data: updatedList[activeIndex], + } + return { + ...lists, + activeItem: newActive, + [types[activeItem.type]]: updatedList, + } + } + case 'changeInputType': { + const activeIndex = lists[types[activeItem.type]].findIndex( + (e: { guid: UniqueIdentifier }) => e.guid === activeItem.data.guid, + ) + const newInputs = [...inputs] + + newInputs[activeIndex] = { + ...inputs[activeIndex], + type: action.payload.newValue as string, + inputSettings: action.payload.inputSettings, + } + + const newActive: ActiveItem = { + type: 'Input', + data: newInputs[activeIndex], + } + + updateItem(newActive.type, newActive.data) + + return { + ...lists, + activeItem: newActive, + inputs: newInputs, + } + } + case 'setDescription': { + const input = activeItem.data as IInput + const newInput = { + ...input, + description: { + ...input.description, + [action.payload.lang]: action.payload.newValue, + }, + } + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => { + if (i.guid === input.guid) { + return newInput + } + return i + }), + } + } + case 'changeInputName': { + const { guid, lang, newValue } = action.payload + const currentInput = inputs.find((i) => i.guid === guid) + const newInput = { + ...currentInput, + name: { + ...currentInput.name, + [lang]: newValue, + }, + } + return { + ...lists, + inputs: inputs.map((i) => { + if (i.guid === guid) { + return newInput + } + return i + }), + } + } + + case 'setActiveItem': { + return { + ...lists, + activeItem: { + type: action.payload.type, + data: action.payload.data, + }, + } + } + case 'setIsRequired': { + return { + ...lists, + activeItem: { + ...activeItem, + data: { + ...activeItem.data, + isRequired: action.payload.isRequired, + }, + }, + inputs: inputs.map((i) => { + if (i.guid === action.payload.guid) { + const newInput = { + ...i, + isRequired: action.payload.isRequired, + } + updateItem('Input', newInput) + return newInput + } + return i + }), + } + } + case 'timeInterval': { + if (activeItem.type === 'Input') { + const inputItem = activeItem.data as IInput + return { + ...lists, + activeItem: { + ...activeItem, + data: { + ...activeItem.data, + inputSettings: { + ...inputItem.inputSettings, + interval: action.payload.data, + }, + }, + }, + inputs: inputs.map((i) => { + if (i.guid === activeItem.data.guid) { + const newInput = { + ...i, + inputSettings: { + ...i.inputSettings, + interval: action.payload.data, + }, + } + updateItem('Input', newInput) + return newInput + } + return i + }), + } + } + break + } + case 'setMessageWithLinkSettings': { + const input: IInput = activeItem.data as IInput + + const { payload } = action + if ('property' in payload) { + // dont know why but typescript was inferring payload : {data: number;} + const { property, lang, value, checked } = payload + + const updateMessageLink = ( + property: string, + value: string | undefined, + ) => { + return { + ...input.inputSettings, + [property]: { + ...input.inputSettings[property], + [lang]: value, + }, + } + } + + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [property]: property === 'erHlekkur' ? checked : value, + ...(property === 'hnapptexti' + ? updateMessageLink(property, value) + : {}), + }, + } + if (property === 'erHlekkur') { + updateItem('Input', newInput) + } + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => + i.guid === activeItem.data.guid ? newInput : i, + ), + } + } + break + } + + // "inputSettings": { + // "$type": "skjal", + // "tegundir": [], + // "hamarksstaerd": 10, + // "erFjolval": false, + // "fjoldi": 20 + // } + case 'setFileUploadSettings': { + const input = activeItem.data as IInput + const { payload } = action + + if ( + !payload || + !('property' in payload) || + !('checked' in payload) || + !('value' in payload) + ) { + throw new Error('Invalid payload') + } + + const { property, checked, value } = payload + + const updateFileTypesArray = () => { + const currentTegundir = input.inputSettings.tegundir || [] + if (checked) { + return [...currentTegundir, value as string] + } else { + return currentTegundir.filter((t) => t !== value) + } + } + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [property]: property === 'tegundir' ? updateFileTypesArray() : value, + }, + } + updateItem('Input', newInput) + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => + i.guid === activeItem.data.guid ? newInput : i, + ), + } + } + + case 'setNumberInputSettings': { + const input = activeItem.data as IInput + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [action.payload.property]: action.payload.value, + }, + } + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => + i.guid === activeItem.data.guid ? newInput : i, + ), + } + } + + case 'addListItem': { + const input = activeItem.data as IInput + const list = input.inputSettings.listi || [] + const newListItem = { + guid: uuid(), + label: { + is: '', + en: '', + }, + description: { + is: '', + en: '', + }, + isSelected: false, + displayOrder: list.length, + } + + const newInput: IInput = { + ...input, + inputSettings: { + ...input.inputSettings, + listi: [...list, newListItem], + }, + } + return addNewInput(newInput, true) + } + + case 'setListItemSelected': { + const input = activeItem.data as IInput + const list = input.inputSettings.listi || [] + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + listi: list.map((l) => + l.guid === action.payload.guid + ? { ...l, isSelected: !l.isSelected } + : { ...l, isSelected: false }, + ), + }, + } + return addNewInput(newInput, true) + } + + case 'removeListItem': { + const input = activeItem.data as IInput + const list = input.inputSettings.listi || [] + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + listi: list.filter((l) => l.guid !== action.payload.guid), + }, + } + return addNewInput(newInput, true) + } + + case 'setListItem': { + const input = activeItem.data as IInput + const { payload } = action + const { property, lang, value, listItemGuid } = payload + const list = input.inputSettings.listi || [] + + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + listi: list.map((l) => { + if (l.guid === listItemGuid) { + return { + ...l, + [property]: { + ...l[property], + [lang]: value, + }, + } + } + return l + }), + }, + } + console.log('newInput', newInput) + return addNewInput(newInput, false) + } + + case 'setActiveListItem': { + return { + ...lists, + activeListItem: action.payload.listItem, + } + } + + // MultiSet boolean?? + case 'setMultiSet': { + const group = activeItem.data as IGroup + const newGroup = { + ...group, + multiSet: action.payload.checked ? 10 : 0, + } + updateItem('Group', newGroup) + return { + ...lists, + activeItem: { + ...activeItem, + data: newGroup, + }, + groups: lists.groups.map((g) => + g.guid === activeItem.data.guid ? newGroup : g, + ), + } + } + + case 'setInputSettings': { + const { inputSettings } = action.payload + const input = activeItem.data as IInput + const newInput = { + ...input, + inputSettings: inputSettings, + } + updateItem('Input', newInput) + return { + ...lists, + activeItem: { + ...activeItem, + data: newInput, + }, + inputs: inputs.map((i) => + i.guid === activeItem.data.guid ? newInput : i, + ), + } + } + + default: + return lists + } +} diff --git a/apps/form-builder/index.d.ts b/apps/form-builder/index.d.ts new file mode 100644 index 000000000000..a9ab53489c7f --- /dev/null +++ b/apps/form-builder/index.d.ts @@ -0,0 +1,6 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +declare module '*.svg' { + const content: any + export const ReactComponent: any + export default content +} diff --git a/apps/form-builder/jest.config.ts b/apps/form-builder/jest.config.ts new file mode 100644 index 000000000000..f205af440342 --- /dev/null +++ b/apps/form-builder/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'form-builder', + preset: '../../jest.preset.js', + transform: { + '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', + '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }], + }, + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], + coverageDirectory: '../../coverage/apps/form-builder', +} diff --git a/apps/form-builder/lib/fileTypes.json b/apps/form-builder/lib/fileTypes.json new file mode 100644 index 000000000000..a066e60198cf --- /dev/null +++ b/apps/form-builder/lib/fileTypes.json @@ -0,0 +1,15 @@ +{ + ".pdf": "application/pdf", + ".doc": "application/msword", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".txt": "text/plain", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".xls": "application/vnd.ms-excel", + ".csv": "text/csv", + ".zip": "application/zip", + "*": "application/octet-stream" +} diff --git a/apps/form-builder/next-env.d.ts b/apps/form-builder/next-env.d.ts new file mode 100644 index 000000000000..4f11a03dc6cc --- /dev/null +++ b/apps/form-builder/next-env.d.ts @@ -0,0 +1,5 @@ +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/form-builder/next.config.js b/apps/form-builder/next.config.js new file mode 100644 index 000000000000..a3c0782fba37 --- /dev/null +++ b/apps/form-builder/next.config.js @@ -0,0 +1,39 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const withNx = require('@nx/next/plugins/with-nx') +const { createVanillaExtractPlugin } = require('@vanilla-extract/next-plugin') +const withVanillaExtract = createVanillaExtractPlugin() + +/** + * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions} + **/ + +const nextConfig = { + nx: { + svgr: false, + }, +} + +module.exports = withNx(withVanillaExtract(nextConfig)) + +//@ts-check + +// eslint-disable-next-line @typescript-eslint/no-var-requires +// const { composePlugins, withNx } = require('@nx/next') + +// /** +// * @type {import('@nx/next/plugins/with-nx').WithNxOptions} +// **/ +// const nextConfig = { +// nx: { +// // Set this to true if you would like to use SVGR +// // See: https://github.com/gregberge/svgr +// svgr: false, +// }, +// } + +// const plugins = [ +// // Add more Next.js plugins to this list if needed. +// withNx, +// ] + +// module.exports = composePlugins(...plugins)(nextConfig) diff --git a/apps/form-builder/pages/Form/[id]/index.tsx b/apps/form-builder/pages/Form/[id]/index.tsx new file mode 100644 index 000000000000..582a15fdc397 --- /dev/null +++ b/apps/form-builder/pages/Form/[id]/index.tsx @@ -0,0 +1,29 @@ +import { GetServerSidePropsContext } from 'next' +import Form from '../../../screens/Form' +import { getForm } from '../../../services/apiService' +import { IFormBuilder } from '../../../types/interfaces' + +interface Props { + form: IFormBuilder +} + +const Index = ({ form }: Props) => { + return
+} + +export default Index + +export async function getServerSideProps(context: GetServerSidePropsContext) { + const formId = context.params?.id as unknown + if (!formId) { + return { + notFound: true, + } + } + const form: IFormBuilder = await getForm(formId as number) + return { + props: { + form: form, + }, + } +} diff --git a/apps/form-builder/pages/Form/index.tsx b/apps/form-builder/pages/Form/index.tsx new file mode 100644 index 000000000000..2ea7400769ce --- /dev/null +++ b/apps/form-builder/pages/Form/index.tsx @@ -0,0 +1,22 @@ +import Form from '../../screens/Form' +import { getNewForm } from '../../services/apiService' +import { IFormBuilder } from '../../types/interfaces' + +interface Props { + form: IFormBuilder +} + +const Index = ({ form }: Props) => { + return +} + +export default Index + +export async function getServerSideProps() { + const form: IFormBuilder = await getNewForm(1) + return { + props: { + form: form, + }, + } +} diff --git a/apps/form-builder/pages/_app.tsx b/apps/form-builder/pages/_app.tsx new file mode 100644 index 000000000000..39f4f73e5355 --- /dev/null +++ b/apps/form-builder/pages/_app.tsx @@ -0,0 +1,25 @@ +import { AppProps } from 'next/app' +import { IntlProvider } from 'react-intl' +import Layout from '../components/Layout/Layout' + +const FormBuilderProviderApp: unknown = ({ + Component, + pageProps, +}: AppProps) => { + return ( + undefined} + > + +
+ +
+
+
+ ) +} + +export default FormBuilderProviderApp diff --git a/apps/form-builder/pages/forms.tsx b/apps/form-builder/pages/forms.tsx new file mode 100644 index 000000000000..5afed5abf66a --- /dev/null +++ b/apps/form-builder/pages/forms.tsx @@ -0,0 +1,22 @@ +import { Forms } from '../screens' +import { getAllFormsFromOrganisation } from '../services/apiService' +import { IFormBuilder } from '../types/interfaces' + +interface Props { + formBuilder: IFormBuilder +} + +const Index = ({ formBuilder }: Props) => { + return +} + +export default Index + +export async function getServerSideProps() { + const allForms: IFormBuilder = await getAllFormsFromOrganisation(1) + return { + props: { + formBuilder: allForms, + }, + } +} diff --git a/apps/form-builder/pages/index.tsx b/apps/form-builder/pages/index.tsx new file mode 100644 index 000000000000..b46c74eee8d0 --- /dev/null +++ b/apps/form-builder/pages/index.tsx @@ -0,0 +1,23 @@ +import { Forms } from '../screens' +import { getAllFormsFromOrganisation } from '../services/apiService' +import { IFormBuilder } from '../types/interfaces' + +interface Props { + formBuilder: IFormBuilder +} + +const Index = ({ formBuilder }: Props) => { + return +} + +export default Index + +export async function getServerSideProps() { + const allForms: IFormBuilder = await getAllFormsFromOrganisation(1) + console.log(allForms) + return { + props: { + formBuilder: allForms, + }, + } +} diff --git a/apps/form-builder/project.json b/apps/form-builder/project.json new file mode 100644 index 000000000000..73c5c0878a43 --- /dev/null +++ b/apps/form-builder/project.json @@ -0,0 +1,108 @@ +{ + "name": "form-builder", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/form-builder", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/next:build", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/apps/form-builder" + }, + "configurations": { + "development": { + "outputPath": "apps/form-builder" + }, + "production": {} + } + }, + "build-custom-server": { + "executor": "@nx/webpack:webpack", + "defaultConfiguration": "production", + "options": { + "outputPath": "dist/apps/form-builder", + "main": "apps/form-builder/server.ts", + "tsConfig": "apps/form-builder/tsconfig.server.json", + "maxWorkers": 2, + "assets": [], + "compiler": "tsc", + "target": "node" + }, + "configurations": { + "development": {}, + "production": { + "optimization": true, + "extractLicenses": true, + "inspect": false + } + } + }, + "serve": { + "executor": "@nx/next:server", + "defaultConfiguration": "development", + "options": { + "buildTarget": "form-builder:build", + "dev": true, + "customServerTarget": "form-builder:serve-custom-server" + }, + "configurations": { + "development": { + "buildTarget": "form-builder:build:development", + "dev": true, + "customServerTarget": "form-builder:serve-custom-server:development" + }, + "production": { + "buildTarget": "form-builder:build:production", + "dev": false, + "customServerTarget": "form-builder:serve-custom-server:production" + } + } + }, + "serve-custom-server": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "form-builder:build-custom-server" + }, + "configurations": { + "development": { + "buildTarget": "form-builder:build-custom-server:development" + }, + "production": { + "buildTarget": "form-builder:build-custom-server:production" + } + } + }, + "export": { + "executor": "@nx/next:export", + "options": { + "buildTarget": "form-builder:build:production" + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/form-builder/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/form-builder/**/*.{ts,tsx,js,jsx}"] + } + }, + "docker-next": {} + }, + "tags": [] +} diff --git a/apps/form-builder/proxy.config.json b/apps/form-builder/proxy.config.json new file mode 100644 index 000000000000..1ec1f59e0a1a --- /dev/null +++ b/apps/form-builder/proxy.config.json @@ -0,0 +1,6 @@ +{ + "/api/graphql": { + "target": "http://localhost:4444", + "secure": false + } +} diff --git a/apps/form-builder/public/.gitkeep b/apps/form-builder/public/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/form-builder/public/favicon.ico b/apps/form-builder/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..317ebcb2336e0833a22dddf0ab287849f26fda57 GIT binary patch literal 15086 zcmeI332;U^%p|z7g|#(P)qFEA@4f!_@qOK2 z_lJl}!lhL!VT_U|uN7%8B2iKH??xhDa;*`g{yjTFWHvXn;2s{4R7kH|pKGdy(7z!K zgftM+Ku7~24TLlh(!g)gz|foI94G^t2^IO$uvX$3(OR0<_5L2sB)lMAMy|+`xodJ{ z_Uh_1m)~h?a;2W{dmhM;u!YGo=)OdmId_B<%^V^{ovI@y`7^g1_V9G}*f# zNzAtvou}I!W1#{M^@ROc(BZ! z+F!!_aR&Px3_reO(EW+TwlW~tv*2zr?iP7(d~a~yA|@*a89IUke+c472NXM0wiX{- zl`UrZC^1XYyf%1u)-Y)jj9;MZ!SLfd2Hl?o|80Su%Z?To_=^g_Jt0oa#CT*tjx>BI z16wec&AOWNK<#i0Qd=1O$fymLRoUR*%;h@*@v7}wApDl^w*h}!sYq%kw+DKDY)@&A z@9$ULEB3qkR#85`lb8#WZw=@})#kQig9oqy^I$dj&k4jU&^2(M3q{n1AKeGUKPFbr z1^<)aH;VsG@J|B&l>UtU#Ejv3GIqERzYgL@UOAWtW<{p#zy`WyJgpCy8$c_e%wYJL zyGHRRx38)HyjU3y{-4z6)pzb>&Q1pR)B&u01F-|&Gx4EZWK$nkUkOI|(D4UHOXg_- zw{OBf!oWQUn)Pe(=f=nt=zkmdjpO^o8ZZ9o_|4tW1ni+Un9iCW47*-ut$KQOww!;u z`0q)$s6IZO!~9$e_P9X!hqLxu`fpcL|2f^I5d4*a@Dq28;@2271v_N+5HqYZ>x;&O z05*7JT)mUe&%S0@UD)@&8SmQrMtsDfZT;fkdA!r(S=}Oz>iP)w=W508=Rc#nNn7ym z1;42c|8($ALY8#a({%1#IXbWn9-Y|0eDY$_L&j{63?{?AH{);EzcqfydD$@-B`Y3<%IIj7S7rK_N}je^=dEk%JQ4c z!tBdTPE3Tse;oYF>cnrapWq*o)m47X1`~6@(!Y29#>-#8zm&LXrXa(3=7Z)ElaQqj z-#0JJy3Fi(C#Rx(`=VXtJ63E2_bZGCz+QRa{W0e2(m3sI?LOcUBx)~^YCqZ{XEPX)C>G>U4tfqeH8L(3|pQR*zbL1 zT9e~4Tb5p9_G}$y4t`i*4t_Mr9QYvL9C&Ah*}t`q*}S+VYh0M6GxTTSXI)hMpMpIq zD1ImYqJLzbj0}~EpE-aH#VCH_udYEW#`P2zYmi&xSPs_{n6tBj=MY|-XrA;SGA_>y zGtU$?HXm$gYj*!N)_nQ59%lQdXtQZS3*#PC-{iB_sm+ytD*7j`D*k(P&IH2GHT}Eh z5697eQECVIGQAUe#eU2I!yI&%0CP#>%6MWV z@zS!p@+Y1i1b^QuuEF*13CuB zu69dve5k7&Wgb+^s|UB08Dr3u`h@yM0NTj4h7MnHo-4@xmyr7(*4$rpPwsCDZ@2be zRz9V^GnV;;?^Lk%ynzq&K(Aix`mWmW`^152Hoy$CTYVehpD-S1-W^#k#{0^L`V6CN+E z!w+xte;2vu4AmVNEFUOBmrBL>6MK@!O2*N|2=d|Y;oN&A&qv=qKn73lDD zI(+oJAdgv>Yr}8(&@ZuAZE%XUXmX(U!N+Z_sjL<1vjy1R+1IeHt`79fnYdOL{$ci7 z%3f0A*;Zt@ED&Gjm|OFTYBDe%bbo*xXAQsFz+Q`fVBH!N2)kaxN8P$c>sp~QXnv>b zwq=W3&Mtmih7xkR$YA)1Yi?avHNR6C99!u6fh=cL|KQ&PwF!n@ud^n(HNIImHD!h87!i*t?G|p0o+eelJ?B@A64_9%SBhNaJ64EvKgD&%LjLCYnNfc; znj?%*p@*?dq#NqcQFmmX($wms@CSAr9#>hUR^=I+=0B)vvGX%T&#h$kmX*s=^M2E!@N9#m?LhMvz}YB+kd zG~mbP|D(;{s_#;hsKK9lbVK&Lo734x7SIFJ9V_}2$@q?zm^7?*XH94w5Qae{7zOMUF z^?%F%)c1Y)Q?Iy?I>knw*8gYW#ok|2gdS=YYZLiD=CW|Nj;n^x!=S#iJ#`~Ld79+xXpVmUK^B(xO_vO!btA9y7w3L3-0j-y4 z?M-V{%z;JI`bk7yFDcP}OcCd*{Q9S5$iGA7*E1@tfkyjAi!;wP^O71cZ^Ep)qrQ)N z#wqw0_HS;T7x3y|`P==i3hEwK%|>fZ)c&@kgKO1~5<5xBSk?iZV?KI6&i72H6S9A* z=U(*e)EqEs?Oc04)V-~K5AUmh|62H4*`UAtItO$O(q5?6jj+K^oD!04r=6#dsxp?~}{`?&sXn#q2 zGuY~7>O2=!u@@Kfu7q=W*4egu@qPMRM>(eyYyaIE<|j%d=iWNdGsx%c!902v#ngNg z@#U-O_4xN$s_9?(`{>{>7~-6FgWpBpqXb`Ydc3OFL#&I}Irse9F_8R@4zSS*Y*o*B zXL?6*Aw!AfkNCgcr#*yj&p3ZDe2y>v$>FUdKIy_2N~}6AbHc7gA3`6$g@1o|dE>vz z4pl(j9;kyMsjaw}lO?(?Xg%4k!5%^t#@5n=WVc&JRa+XT$~#@rldvN3S1rEpU$;XgxVny7mki3 z-Hh|jUCHrUXuLr!)`w>wgO0N%KTB-1di>cj(x3Bav`7v z3G7EIbU$z>`Nad7Rk_&OT-W{;qg)-GXV-aJT#(ozdmnA~Rq3GQ_3mby(>q6Ocb-RgTUhTN)))x>m&eD;$J5Bg zo&DhY36Yg=J=$Z>t}RJ>o|@hAcwWzN#r(WJ52^g$lh^!63@hh+dR$&_dEGu&^CR*< z!oFqSqO@>xZ*nC2oiOd0eS*F^IL~W-rsrO`J`ej{=ou_q^_(<$&-3f^J z&L^MSYWIe{&pYq&9eGaArA~*kA( + NavbarSelectStatus.OFF, + ) + console.log('THE FORM: ', form) + const [activeListItem, setActiveListItem] = useState(null) + const { infoDispatch } = useContext(LayoutContext) + const initialNavbar: ILists = { + activeItem: inSettings + ? { type: 'Step', data: baseSettingsStep } + : { + type: 'Step', + data: + form.form.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, + steps: form.form.stepsList, + groups: form.form.groupsList, + inputs: form.form.inputsList, + } + + const [formBuilder, formDispatch] = useReducer(formReducer, form) + const [list, listsDispatch] = useReducer( + listsReducer, + initialNavbar, + undefined, + ) + const lists = list as ILists + const { activeItem } = lists + + const isMounted = useRef(false) + useEffect(() => { + if (isMounted.current) { + if (!isTyping) { + //formUpdate() + } + } else { + isMounted.current = true + infoDispatch({ + type: 'changeOrganization', + data: formBuilder?.form?.organization.name.is, + }) + infoDispatch({ + type: 'changeApplicationName', + data: formBuilder.form.name.is, + }) + } + }, [formBuilder, infoDispatch, isTyping]) + + const context: IFormBuilderContext = { + formBuilder: formBuilder, + formDispatch: formDispatch, + lists: lists, + listsDispatch: listsDispatch, + formUpdate: formUpdate, + setIsTyping: setIsTyping, + inSettings: inSettings, + setInSettings: setInSettings, + setSelectStatus: setSelectStatus, + selectStatus: selectStatus, + activeListItem: activeListItem, + setActiveListItem: setActiveListItem, + changeHandler: changeHandler, + changeSelectHandler: changeSelectHandler, + blur: blur, + onFocus: onFocus, + } + + if (formBuilder.form && activeItem) { + return ( + + + + {selectStatus !== NavbarSelectStatus.OFF ? ( + + ) : ( + + )} + + + + {activeItem?.data && } + + + + + ) + } + return <>Loading + async function formUpdate() { + updateForm(formBuilder.form, lists.steps, lists.groups, lists.inputs) + } + + function changeHandler( + e: ChangeEvent, + propertyName: string, + ) { + if (!isTyping) setIsTyping(true) + if (propertyName === 'name' || propertyName === 'nameEn') { + const lang = propertyName === 'name' ? 'is' : 'en' + const index = getIndex() + listsDispatch({ + type: 'changeName', + payload: { + activeType: activeItem.type, + index: index, + lang: lang, + newValue: e.target.value, + }, + }) + } + } + + function changeSelectHandler(e) { + if ('value' in e) { + const index = getIndex() + listsDispatch({ + type: 'changeInputType', + payload: { + index: index, + newValue: e.value, + inputSettings: + formBuilder?.inputTypes?.find( + (inputType) => inputType?.type === e.value, + )?.inputSettings ?? null, + }, + }) + } + //updateItem(activeItem.type, activeItem.data) + } + + function blur(e: FocusEvent) { + // Check whether value has changed + if (e.target.value !== focus) { + //saveItem() + setOnFocus(null) + //formUpdate() + updateItem(activeItem.type, activeItem.data) + } + setIsTyping(false) + } + + function onFocus(value: string) { + setIsTyping(true) + setOnFocus(value) + } + + function getIndex(): number { + if (activeItem.type === 'Step') { + const index = lists.steps.findIndex( + (s) => s.guid === activeItem.data.guid, + ) + return index ? index : -1 + } + if (activeItem.type === 'Group') { + const index = lists.groups.findIndex( + (g) => g.guid === activeItem.data.guid, + ) + return index ? index : -1 + } + if (activeItem.type === 'Input') { + const index = lists.inputs.findIndex( + (i) => i.guid === activeItem.data.guid, + ) + return index ? index : -1 + } + return -1 + } +} diff --git a/apps/form-builder/screens/Forms.tsx b/apps/form-builder/screens/Forms.tsx new file mode 100644 index 000000000000..8234a091bce8 --- /dev/null +++ b/apps/form-builder/screens/Forms.tsx @@ -0,0 +1,78 @@ +import { Box, Button, Inline, Text } from '@island.is/island-ui/core' +import router from 'next/router' +import TableRow from '../components/TableRow/TableRow' +import { IFormBuilder } from '../types/interfaces' + +interface Props { + formBuilder: IFormBuilder +} +export default function Forms({ formBuilder }: Props) { + if (formBuilder) { + return ( + + {/* Title and buttons */} + + Forskriftir + + + + + + + + + + {/* Warning: Did not expect server HTML to contain a in
. */} + {/* */} + + + + + {/* */} + + + + + {formBuilder.forms && + formBuilder.forms?.map((f) => { + return ( + // + + // + ) + })} + + ) + } + return <> +} diff --git a/apps/form-builder/screens/index.tsx b/apps/form-builder/screens/index.tsx new file mode 100644 index 000000000000..3112d3ade954 --- /dev/null +++ b/apps/form-builder/screens/index.tsx @@ -0,0 +1,2 @@ +export { default as Forms } from './Forms' +export { default as Form } from './Form' diff --git a/apps/form-builder/server.ts b/apps/form-builder/server.ts new file mode 100644 index 000000000000..3f65dc718369 --- /dev/null +++ b/apps/form-builder/server.ts @@ -0,0 +1,12 @@ +import { bootstrap } from '@island.is/infra-next-server' +import proxyConfig from './proxy.config.json' + +bootstrap({ + name: 'form-builder', + appDir: 'apps/form-builder', + proxyConfig, + externalEndpointDependencies: (nextConfig) => { + const { graphqlEndpoint } = nextConfig.serverRuntimeConfig + return [graphqlEndpoint] + }, +}) diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx new file mode 100644 index 000000000000..0c8e28b73875 --- /dev/null +++ b/apps/form-builder/services/apiService.tsx @@ -0,0 +1,268 @@ +import axios from 'axios' +import { + IForm, + IFormBuilder, + IGroup, + IInput, + ILanguage, + IStep, + ItemType, +} from '../types/interfaces' + +const BASEURL = 'https://profun.island.is/umsoknarkerfi/api' + +export async function getForm(id: number) { + try { + const response = await axios.get(`${BASEURL}/Forms/${id}`) + return response.data + } catch (error) { + console.error(error) + throw error + } +} + +export async function updateForm( + form: IForm, + steps: IStep[], + groups: IGroup[], + inputs: IInput[], +) { + const updatedForm: IForm = { + ...form, + stepsList: steps.map((s, i) => { + return { + ...s, + displayOrder: i, + } + }), + groupsList: groups.map((g, i) => { + return { + ...g, + displayOrder: i, + } + }), + inputsList: inputs.map((i, index) => { + return { + ...i, + displayOrder: index, + } + }), + } + + try { + const response = await axios.put( + `${BASEURL}/Forms/${form.id}`, + updatedForm, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + + console.log('Update complete') + return response + } catch (error) { + console.error('Error in updateNavbar:', error) + throw error + } +} + +export async function updateItem(type: string, data: IStep | IGroup | IInput) { + const url = `${BASEURL}/${type}s/${data.id}` + + try { + const response = await axios.put(url, data, { + headers: { + 'Content-Type': 'application/json', + }, + }) + + console.log('response', response) + console.log(`saving ${type}`, data) + + return response + } catch (error) { + console.error('Error in updateItem: ', error) + throw error + } +} + +export async function getNewForm(organisationId: number) { + try { + const response = await axios.post(`${BASEURL}/Forms/${organisationId}`) + + console.log('api', response.data) + + return response.data + } catch (error) { + console.error('Error in getNewForm: ', error) + throw error + } +} + +export async function getAllFormsFromOrganisation( + organisationId: number, +): Promise { + try { + const response = await axios.get( + `${BASEURL}/Forms/Organization/${organisationId}`, + ) + console.log('allForms api: ', response.data) + return response.data + } catch (error) { + console.error('Error in getAllFormsFromOrganisation: ', error) + throw error + } +} + +export async function addStep( + formId: number, + name: ILanguage, + displayOrder: number, + stepType: number, + waitingText: ILanguage, + callRuleset: boolean, +): Promise { + // const schema = zod.object({ + // formId: zod.number(), + // name: zod.object({ + // is: zod.string(), + // en: zod.string() + // }), + // displayOrder: zod.number(), + // stepType: zod.number(), + // waitingText: zod.object({ + // is: zod.string(), + // en: zod.string() + // }), + // callRuleset: zod.boolean() + // }) + + try { + const response = await axios.post(`${BASEURL}/Steps`, { + formId, + name, + displayOrder, + stepType, + waitingText, + callRuleset, + }) + + // const data = schema.parse(response.data) + const data = response.data + console.log('addStep data: ', data) + + return data + } catch (error) { + console.error('Error in addStep: ', error) + throw error + } +} + +export async function addGroup( + displayOrder: number, + parentId: number, +): Promise { + // const schema = zod.object({ + // name: zod.object({ + // is: zod.string(), + // en: zod.string() + // }), + // displayOrder: zod.number(), + // multiSet: zod.number(), + // parentId: zod.number() + // }) + + try { + const response = await axios.post(`${BASEURL}/Groups`, { + displayOrder: displayOrder, + stepId: parentId, + }) + + // const data = schema.parse(response.data) + const data = response.data + console.log('addGroup data: ', data) + + return data + } catch (error) { + console.error('Error in addGroup: ', error) + throw error + } +} + +export async function addInput( + displayOrder: number, + parentId: number, +): Promise { + // const schema = zod.object({ + // displayOrder: zod.number(), + // parentId: zod.number(), + // inputTypeId: zod.number() + // }) + + const requestBody = { + displayOrder: displayOrder, + groupId: parentId, + } + + try { + const response = await axios.post(`${BASEURL}/Inputs`, requestBody, { + headers: { + 'Content-Type': 'application/json', + }, + }) + + // const data = schema.parse(response.data) + const data = response.data + console.log('addInput data: ', data) + + return data + } catch (error) { + console.error('Error in addInput: ', error) + throw error + } +} + +export async function deleteItem(type: ItemType, id: number) { + try { + const response = await axios.delete(`${BASEURL}/${type}s/${id}`) + console.log('deleteItem response: ', response) + return response + } catch (error) { + console.error('Error in deleteItem: ', error) + throw error + } +} + +export async function saveFormSettings(formId: number, settings: object) { + console.log(settings) + try { + const response = await axios.put( + `${BASEURL}/Forms/${formId}/Settings`, + settings, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + + console.log('saveFormSettings response: ', response) + return response + } catch (error) { + console.error('Error in saveFormSettings: ', error) + throw error + } +} + +export async function getList(type: string) { + try { + const response = await axios.get(`${BASEURL}/Services/${type}`) + console.log('getList response: ', response) + return response.data + } catch (error) { + console.error('Error in getList: ', error) + throw error + } +} diff --git a/apps/form-builder/services/translationStation.tsx b/apps/form-builder/services/translationStation.tsx new file mode 100644 index 000000000000..abdca24710e1 --- /dev/null +++ b/apps/form-builder/services/translationStation.tsx @@ -0,0 +1,62 @@ +import { ITranslationResponse } from '../types/interfaces' +import axios from 'axios' +import dotenv from 'dotenv' + +dotenv.config() + +export const translationStation = async ( + input: string, +): Promise => { + const apiUrl = process.env.MIDEIND_API + const apiKey = process.env.MIDEIND_KEY + + if (!apiUrl || !apiKey) { + throw new Error('API URL or API key is not defined.') + } + + try { + const response = await axios.post( + apiUrl, + { + contents: [input], + sourceLanguageCode: 'is', + targetLanguageCode: 'en', + model: '', + domain: '', + }, + { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + 'X-API-Key': apiKey, + }, + }, + ) + + return response.data + } catch (error) { + console.error('Error in translationStation: ', error) + throw error + } +} +// export const translationStation = async (input: string): Promise => { +// console.log('translationStation', input) +// return await fetch("https://stafraentisland.greynir.is/translate/", { +// method: 'POST', +// headers: { +// 'content-type': 'application/json', +// 'accept': 'application/json', +// 'X-API-Key': 'jtn1QACg.jCxAuvopgqplC5i38Nav1BubiSik6tDK' +// }, +// body: JSON.stringify({ +// "contents": [input], +// "sourceLanguageCode": "is", +// "targetLanguageCode": "en", +// "model": "", +// "domain": "" +// }) +// }).then(res => { +// console.log(res) +// return res.json() +// }) +// } diff --git a/apps/form-builder/tsconfig.json b/apps/form-builder/tsconfig.json new file mode 100644 index 000000000000..1caed9d6b561 --- /dev/null +++ b/apps/form-builder/tsconfig.json @@ -0,0 +1,54 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "jsx": "preserve", + "allowJs": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "strict": false, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "resolveJsonModule": true, + "isolatedModules": true, + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "types": ["jest", "node"] + }, + "include": [ + "**/*.ts", + "**/*.tsx", + "**/*.js", + "**/*.jsx", + "../../apps/form-builder/.next/types/**/*.ts", + "../../dist/apps/form-builder/.next/types/**/*.ts", + "next-env.d.ts" + ], + "exclude": [ + "node_modules", + "jest.config.ts", + "src/**/*.spec.ts", + "src/**/*.test.ts" + ] +} +// { +// "extends": "../../tsconfig.base.json", +// "compilerOptions": { +// "jsx": "preserve", +// "allowJs": true, +// "esModuleInterop": true, +// "allowSyntheticDefaultImports": true, +// "types": ["node", "jest"], +// "strict": false, +// "forceConsistentCasingInFileNames": true, +// "noEmit": true, +// "resolveJsonModule": true, +// "isolatedModules": true, +// "incremental": true, +// }, +// "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "next-env.d.ts", "pages/FormBuilder/components/NewAttribute/index.2tsx"], +// "exclude": ["node_modules"] +// } diff --git a/apps/form-builder/tsconfig.server.json b/apps/form-builder/tsconfig.server.json new file mode 100644 index 000000000000..35605d15229c --- /dev/null +++ b/apps/form-builder/tsconfig.server.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "noEmit": false, + "incremental": true, + "tsBuildInfoFile": "../../tmp/buildcache/apps/form-builder/server", + "types": ["node"] + }, + "include": ["server.ts"] +} diff --git a/apps/form-builder/tsconfig.spec.json b/apps/form-builder/tsconfig.spec.json new file mode 100644 index 000000000000..214b2cc208c1 --- /dev/null +++ b/apps/form-builder/tsconfig.spec.json @@ -0,0 +1,21 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"], + "jsx": "react" + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.test.tsx", + "src/**/*.spec.tsx", + "src/**/*.test.js", + "src/**/*.spec.js", + "src/**/*.test.jsx", + "src/**/*.spec.jsx", + "src/**/*.d.ts" + ] +} diff --git a/apps/form-builder/types/enums/index.tsx b/apps/form-builder/types/enums/index.tsx new file mode 100644 index 000000000000..70b74cdae3c0 --- /dev/null +++ b/apps/form-builder/types/enums/index.tsx @@ -0,0 +1,91 @@ +export enum ApplicationTemplateStatus { + Þýðing = -2, + Kerfi = -1, + Óútgefið = 0, + Útgefið = 2, + tekiðÚrNotkun = 4, +} + +export enum LicenseProviderEnum { + sýslumannsembættið = 1, + leyfisveitanEhf = 2, + leyfisveitanEhf2 = 9, + þjóðskráÍslands = 3, + ferðamálastofa = 4, + ferðamálastofa2 = 52, + menntamálastofnun = 5, + hallaBjörgBaldursdóttir = 6, + fiskistofa = 7, + officeOfDistrictMagistrate = 8, + registersIceland = 10, + icelandicTouristBoard = 11, + directorateOfEducation = 12, + hallaBjorgBaldursdottir = 13, + directorateOfFisheries = 14, + fjármálaOgEfnahagsráðuneytið = 15, + ministryOfFinanceAndEconomicAffairs = 16, + ríkisskattstjóri = 17, + ríkiskaup = 18, + sýslumaðurinnÁHöfuðborgarsvæðinu = 19, + sýslumaðurinnÁHöfuðborgarsvæðinu2 = 50, + theDistrictMagistrateCapitalRegion = 20, + centralPublicProcurement = 21, + directorateOfInternalRevenue = 22, + sýslumaðurinnÁVestfjörðum = 23, + theDistrictMagistrateWestfjords = 24, + útlendingastofnun = 37, + útlendingastofnun2 = 49, + icelandicDirectorateOfImmigration = 38, + utanríkisráðuneytið = 39, + ministryForForeignAffairs = 40, + ríkislögreglustjóri = 41, + ríkislögreglustjóri2 = 71, + sjúkratryggingarÍslands = 42, + sjúkratryggingarÍslands2 = 51, + þjóðskjalasafnÍslands = 43, + þjóðskjalasafnÍslands2 = 44, + sýslumenn = 53, + fjölskylduOgHúsdýragarðurinn = 59, + menntamálastofnun2 = 61, + umhverfisstofnun = 62, + héraðsdómurReykjavíkur = 63, + minjastofnunÍslands = 64, + náttúruhamfaratryggingarÍslands = 65, +} + +export enum FileTypeEnum { + PDF, + Image, + Xls, + ALL, +} + +export enum EInputType { + Textalínubox = 1, + TextaboxStórt = 2, + Tölustafir = 3, + Textalýsing = 4, + Hakbox = 5, + Dagssetning = 6, + Fellilisti = 7, + Valhnappar = 8, + Heimagistingarnúmer = 9, + FasteignanúmerInnslegið = 10, + FasteignanúmerValiðÚrLista = 11, + Bankareikningsnúmer = 13, + Kennitala = 14, + Greiðandi = 15, + Krónutala = 16, + Krónutölusamtala = 17, + Netfang = 18, + Símanúmer = 19, + FalinnStrengur = 20, + Tími = 21, + Sveitarfélög = 22, + Landalisti = 23, + Póstnúmer = 24, + KennitalaDánarbús = 25, + KennitalaAllt = 26, + Vottorð = 28, + Aðili = 29, +} diff --git a/apps/form-builder/types/interfaces.tsx b/apps/form-builder/types/interfaces.tsx new file mode 100644 index 000000000000..8dd7b6468d73 --- /dev/null +++ b/apps/form-builder/types/interfaces.tsx @@ -0,0 +1,224 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ChangeEvent, Dispatch, SetStateAction, FocusEvent } from 'react' +import { UniqueIdentifier } from '@dnd-kit/core' + +export interface IFormBuilderContext { + formBuilder: IFormBuilder + formDispatch: Dispatch + lists: { + activeItem: ActiveItem + steps: IStep[] + groups: IGroup[] + inputs: IInput[] + } + listsDispatch: Dispatch + formUpdate: () => Promise + setIsTyping: Dispatch> + inSettings: boolean + setInSettings: Dispatch> + setSelectStatus: Dispatch> + selectStatus: NavbarSelectStatus + activeListItem?: IListItem | null + setActiveListItem: Dispatch> + changeSelectHandler(e: unknown): void + changeHandler( + e: ChangeEvent, + propertyName: string, + ): void + blur(e: FocusEvent): void + onFocus(e: string): void +} + +export interface IInputSettings { + $type?: string + isLarge?: boolean + size?: Sizes + interval?: number + erHlekkur?: boolean + url?: string + hnapptexti?: ILanguage + tegundir?: string[] + hamarksstaerd?: number + erFjolval?: boolean + fjoldi?: number + header?: string + hamarkslengd?: number + lagmarkslengd?: number + laggildi?: number + hagildi?: number + listi?: IListItem[] + type?: string + name?: ILanguage + [key: string]: any +} + +export interface IForm { + id: number + name: ILanguage + created: Date + lastChanged: Date + organization: { + id: number + name: ILanguage + kennitala: string + scope: string + xroadBaseUrl: string + } + dependencies: ITenging + stepsList: IStep[] + groupsList: IGroup[] + inputsList: IInput[] + stopProgressOnValidatingStep: boolean + applicationsDaysToRemove: number + invalidationDate?: Date + isTranslated: boolean + documentTypes: string[] + adilar: string[] +} + +export interface IStep { + id: number + guid: UniqueIdentifier + displayOrder: number + name: ILanguage + type: string + waitingText: ILanguage + callRuleset: boolean + isHidden: boolean + isCompleted: boolean +} + +export interface IGroup { + id: number + name: ILanguage + guid: UniqueIdentifier + displayOrder: number + isHidden: boolean + multiSet: number + stepId: number + stepGuid: UniqueIdentifier + inputs?: IInput[] +} + +export interface IInput { + id: number + name: ILanguage + description: ILanguage + isRequired: boolean + displayOrder: number + groupId: number + groupGuid: UniqueIdentifier + isHidden: boolean + type: string + guid: UniqueIdentifier + inputFields: object + inputSettings: IInputSettings + isPartOfMultiSet: boolean +} + +export type ILists = { + activeItem: ActiveItem + steps: IStep[] + groups: IGroup[] + inputs: IInput[] + [key: string]: any // index signature for reducer +} + +export interface ActiveItem { + type: ItemType + data: IStep | IGroup | IInput +} + +export interface ISelectOption { + label: string | number + value: string | number +} + +export interface ITenging { + [key: string]: string[] +} + +export interface IFormBuilder { + form: IForm + forms?: IForm[] + documentTypes: ICertificate[] + inputTypes: IInputTypes[] + applicantTypes: IApplicantType[] +} + +export interface IListItem { + guid: UniqueIdentifier + label: ILanguage + description: ILanguage + displayOrder: number + isSelected: boolean +} + +export interface ICertificate { + type: string + name: ILanguage + description: ILanguage +} + +export interface IApplicantType { + type: string + name: string + nameSuggestions: ILanguage[] +} + +export interface IInputTypes { + type: string + name: string + description: string + organizations?: [] // + inputFields?: object + inputMetadata?: object + ruleset?: object + inputSettings: object +} + +export interface ILayoutContext { + info: { + organization: any + applicationName: string + } + infoDispatch: React.Dispatch +} + +export interface ILicenseProvider { + licenseProviderID: number + kennitala: string + name: string + email: string + phone: string + enabled: boolean + parentId?: number + language: string +} + +export interface ITranslationResponse { + translations: ITranslation[] + sourceLanguageCode: string + targetLanguageCode: string + model: string +} + +export interface ITranslation { + translatedText: string + translatedTextStructured: [string, string][] +} +export enum NavbarSelectStatus { + OFF = 'Off', + NORMAL = 'Normal', + LIST_ITEM = 'ListItem', + ON_WITHOUT_SELECT = 'OnWithoutSelect', +} + +export type ItemType = 'Step' | 'Group' | 'Input' + +export type ILanguage = { + is: string + en: string +} + +type Sizes = 'xs' | 'sm' | 'md' diff --git a/apps/form-builder/utils/defaultStep.tsx b/apps/form-builder/utils/defaultStep.tsx new file mode 100644 index 000000000000..6130a25964f1 --- /dev/null +++ b/apps/form-builder/utils/defaultStep.tsx @@ -0,0 +1,20 @@ +import { uuid } from 'uuidv4' +import { IStep } from '../types/interfaces' + +export const defaultStep: IStep = { + id: 0, + guid: uuid(), + displayOrder: 0, + name: { + is: '', + en: '', + }, + type: 'Innsláttur', + waitingText: { + is: '', + en: '', + }, + callRuleset: false, + isHidden: false, + isCompleted: false, +} diff --git a/apps/form-builder/utils/formatDate.tsx b/apps/form-builder/utils/formatDate.tsx new file mode 100644 index 000000000000..7b16496029e6 --- /dev/null +++ b/apps/form-builder/utils/formatDate.tsx @@ -0,0 +1,8 @@ +export const formatDate = (date: Date) => { + const newDate = new Date(date) + const day = newDate.getDate().toString().padStart(2, '0') + const month = (newDate.getMonth() + 1).toString().padStart(2, '0') + const year = newDate.getFullYear() + + return `${day}.${month}.${year}` //${hours}:${minutes}`; +} diff --git a/apps/form-builder/utils/getBaseSettingsStep.tsx b/apps/form-builder/utils/getBaseSettingsStep.tsx new file mode 100644 index 000000000000..004f0f8af86a --- /dev/null +++ b/apps/form-builder/utils/getBaseSettingsStep.tsx @@ -0,0 +1,19 @@ +import { uuid } from 'uuidv4' + +export const baseSettingsStep = { + id: 99999, + guid: uuid(), + displayOrder: -1, + name: { + is: 'Grunnstillingar', + en: 'Base settings', + }, + type: 'BaseSetting', + waitingText: { + is: '', + en: '', + }, + callRuleset: false, + isHidden: false, + isCompleted: false, +} diff --git a/package.json b/package.json index f5e3ccf6d92f..91806ae93fd1 100644 --- a/package.json +++ b/package.json @@ -213,7 +213,7 @@ "mobx": "6.3.7", "msw": "0.21.3", "nest-winston": "1.4.0", - "next": "13.3.0", + "next": "13.4.1", "next-auth": "3.29.10", "next-cookies": "2.0.3", "next-usequerystate": "1.8.4", @@ -419,7 +419,7 @@ "dotenv": "16.3.1", "esbuild": "0.15.7", "eslint": "8.46.0", - "eslint-config-next": "13.1.1", + "eslint-config-next": "13.4.1", "eslint-config-prettier": "8.1.0", "eslint-plugin-cypress": "2.14.0", "eslint-plugin-import": "2.27.5", @@ -441,6 +441,7 @@ "next-secure-headers": "2.1.0", "nx": "16.9.0", "prettier": "2.6.2", + "sass": "1.62.1", "sequelize-cli": "6.4.1", "sort-paths": "1.1.1", "sqlite3": "5.1.6", diff --git a/yarn.lock b/yarn.lock index 2656fcf190ac..f61cb734401f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11712,81 +11712,81 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:13.3.0": - version: 13.3.0 - resolution: "@next/env@npm:13.3.0" - checksum: 17dbea6d019df98f8abebadcaed635d792c69368389c7869ca023acfba240294368a58eda761fb8047403b84e82edf25ea2af45afe06cc1807a25de42e256dd3 +"@next/env@npm:13.4.1": + version: 13.4.1 + resolution: "@next/env@npm:13.4.1" + checksum: 4736c9c6f75d80b16d3ca0ad3ddb3fcaa171f2144fccf516a67110e3bfcd9121d076e838faad46f815e41ee32e9be0ab68591359de06af13be6cbb860eda3639 languageName: node linkType: hard -"@next/eslint-plugin-next@npm:13.1.1": - version: 13.1.1 - resolution: "@next/eslint-plugin-next@npm:13.1.1" +"@next/eslint-plugin-next@npm:13.4.1": + version: 13.4.1 + resolution: "@next/eslint-plugin-next@npm:13.4.1" dependencies: glob: 7.1.7 - checksum: 27e49ef988db3203d494930ad1fcdc270761a61a41e6925c0eadf1e2b1ebd6648722a3aaec7f0c0266eea8771797e06d52f041d33c93d21ba3b361ffe696c36c + checksum: fff59da7aa7838e6cb1f19f33b1c5265f0e4ea5a910a7702f2fadbf76c3387dceb388230cd7f9ce810db73c3b78b2342e77a0dbf77f4560eecf85905adb5f671 languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-darwin-arm64@npm:13.3.0" +"@next/swc-darwin-arm64@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-darwin-arm64@npm:13.4.1" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-darwin-x64@npm:13.3.0" +"@next/swc-darwin-x64@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-darwin-x64@npm:13.4.1" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-linux-arm64-gnu@npm:13.3.0" +"@next/swc-linux-arm64-gnu@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-linux-arm64-gnu@npm:13.4.1" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-linux-arm64-musl@npm:13.3.0" +"@next/swc-linux-arm64-musl@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-linux-arm64-musl@npm:13.4.1" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-linux-x64-gnu@npm:13.3.0" +"@next/swc-linux-x64-gnu@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-linux-x64-gnu@npm:13.4.1" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-linux-x64-musl@npm:13.3.0" +"@next/swc-linux-x64-musl@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-linux-x64-musl@npm:13.4.1" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-win32-arm64-msvc@npm:13.3.0" +"@next/swc-win32-arm64-msvc@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-win32-arm64-msvc@npm:13.4.1" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-win32-ia32-msvc@npm:13.3.0" +"@next/swc-win32-ia32-msvc@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-win32-ia32-msvc@npm:13.4.1" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@next/swc-win32-x64-msvc@npm:13.3.0": - version: 13.3.0 - resolution: "@next/swc-win32-x64-msvc@npm:13.3.0" +"@next/swc-win32-x64-msvc@npm:13.4.1": + version: 13.4.1 + resolution: "@next/swc-win32-x64-msvc@npm:13.4.1" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -16448,12 +16448,12 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:0.4.14, @swc/helpers@npm:^0.4.2": - version: 0.4.14 - resolution: "@swc/helpers@npm:0.4.14" +"@swc/helpers@npm:0.5.1": + version: 0.5.1 + resolution: "@swc/helpers@npm:0.5.1" dependencies: tslib: ^2.4.0 - checksum: 273fd3f3fc461a92f3790cc551ea054745c6d6959afbe1232e6d7aa1c722bbc114d308aab96bef5c78fc0303c85c7b472ef00e2253251cc89737f3b1af56e5a5 + checksum: 71e0e27234590435e4c62b97ef5e796f88e786841a38c7116a5e27a3eafa7b9ead7cdec5249b32165902076de78446945311c973e59bddf77c1e24f33a8f272a languageName: node linkType: hard @@ -16466,6 +16466,15 @@ __metadata: languageName: node linkType: hard +"@swc/helpers@npm:^0.4.2": + version: 0.4.14 + resolution: "@swc/helpers@npm:0.4.14" + dependencies: + tslib: ^2.4.0 + checksum: 273fd3f3fc461a92f3790cc551ea054745c6d6959afbe1232e6d7aa1c722bbc114d308aab96bef5c78fc0303c85c7b472ef00e2253251cc89737f3b1af56e5a5 + languageName: node + linkType: hard + "@swc/types@npm:^0.1.4": version: 0.1.4 resolution: "@swc/types@npm:0.1.4" @@ -27920,11 +27929,11 @@ __metadata: languageName: node linkType: hard -"eslint-config-next@npm:13.1.1": - version: 13.1.1 - resolution: "eslint-config-next@npm:13.1.1" +"eslint-config-next@npm:13.4.1": + version: 13.4.1 + resolution: "eslint-config-next@npm:13.4.1" dependencies: - "@next/eslint-plugin-next": 13.1.1 + "@next/eslint-plugin-next": 13.4.1 "@rushstack/eslint-patch": ^1.1.3 "@typescript-eslint/parser": ^5.42.0 eslint-import-resolver-node: ^0.3.6 @@ -27939,7 +27948,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 098465b42e277433e4f815465b49ab655fc35a62ac016a47f60d7e44248f1b87a70b2dfd2ef090ffbb4cb1a694d409ff0811d2eb64028ce61f535403c7a0f27a + checksum: 232fb7a3dcc2b4674d9b0e3b03e76121d0dd7bea921bfd3320f3ac0a21ca7080f67a6cee0ceeb06c3a7386b854e9449da6a9fdd81f5d441a2e8d4a7237e94f59 languageName: node linkType: hard @@ -33916,7 +33925,7 @@ __metadata: esbuild: 0.15.7 escape-html: 1.0.3 eslint: 8.46.0 - eslint-config-next: 13.1.1 + eslint-config-next: 13.4.1 eslint-config-prettier: 8.1.0 eslint-plugin-cypress: 2.14.0 eslint-plugin-import: 2.27.5 @@ -33985,7 +33994,7 @@ __metadata: mobx: 6.3.7 msw: 0.21.3 nest-winston: 1.4.0 - next: 13.3.0 + next: 13.4.1 next-auth: 3.29.10 next-cookies: 2.0.3 next-secure-headers: 2.1.0 @@ -34044,6 +34053,7 @@ __metadata: rosetta: 1.0.0 rxjs: 7.8.1 sanitize-html: 2.10.0 + sass: 1.62.1 sequelize: 6.19.0 sequelize-cli: 6.4.1 sequelize-replace-enum-postgres: 1.6.0 @@ -40135,25 +40145,26 @@ __metadata: languageName: node linkType: hard -"next@npm:13.3.0": - version: 13.3.0 - resolution: "next@npm:13.3.0" +"next@npm:13.4.1": + version: 13.4.1 + resolution: "next@npm:13.4.1" dependencies: - "@next/env": 13.3.0 - "@next/swc-darwin-arm64": 13.3.0 - "@next/swc-darwin-x64": 13.3.0 - "@next/swc-linux-arm64-gnu": 13.3.0 - "@next/swc-linux-arm64-musl": 13.3.0 - "@next/swc-linux-x64-gnu": 13.3.0 - "@next/swc-linux-x64-musl": 13.3.0 - "@next/swc-win32-arm64-msvc": 13.3.0 - "@next/swc-win32-ia32-msvc": 13.3.0 - "@next/swc-win32-x64-msvc": 13.3.0 - "@swc/helpers": 0.4.14 + "@next/env": 13.4.1 + "@next/swc-darwin-arm64": 13.4.1 + "@next/swc-darwin-x64": 13.4.1 + "@next/swc-linux-arm64-gnu": 13.4.1 + "@next/swc-linux-arm64-musl": 13.4.1 + "@next/swc-linux-x64-gnu": 13.4.1 + "@next/swc-linux-x64-musl": 13.4.1 + "@next/swc-win32-arm64-msvc": 13.4.1 + "@next/swc-win32-ia32-msvc": 13.4.1 + "@next/swc-win32-x64-msvc": 13.4.1 + "@swc/helpers": 0.5.1 busboy: 1.6.0 caniuse-lite: ^1.0.30001406 postcss: 8.4.14 styled-jsx: 5.1.1 + zod: 3.21.4 peerDependencies: "@opentelemetry/api": ^1.1.0 fibers: ">= 3.1.0" @@ -40191,7 +40202,7 @@ __metadata: optional: true bin: next: dist/bin/next - checksum: 24e0e013e867a825ff7d1f49587e696147ea8f9ff42946121fe0dce25f9bcc9b1d5941425fa7cef3b8c0e6f1c3daa7f09f758ac5a8aa15aa66c3b31a07465081 + checksum: 169e3fbbf713fad791a9b016c83d396bce628bb0ddf716c5fe50104a21cbc37af7df1586cbe05ae4ae6a090f4e1107211189cfbeeeab8345fe54e11cfefce87f languageName: node linkType: hard @@ -47178,6 +47189,19 @@ __metadata: languageName: node linkType: hard +"sass@npm:1.62.1": + version: 1.62.1 + resolution: "sass@npm:1.62.1" + dependencies: + chokidar: ">=3.0.0 <4.0.0" + immutable: ^4.0.0 + source-map-js: ">=0.6.2 <2.0.0" + bin: + sass: sass.js + checksum: 1b1b3584b38a63dd94156b65f13b90e3f84b170a38c3d5e3fa578b7a32a37aeb349b4926b0eaf9448d48e955e86b1ee01b13993f19611dad8068af07a607c13b + languageName: node + linkType: hard + "sass@npm:^1.42.1": version: 1.63.2 resolution: "sass@npm:1.63.2" @@ -53900,6 +53924,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:3.21.4": + version: 3.21.4 + resolution: "zod@npm:3.21.4" + checksum: f185ba87342ff16f7a06686767c2b2a7af41110c7edf7c1974095d8db7a73792696bcb4a00853de0d2edeb34a5b2ea6a55871bc864227dace682a0a28de33e1f + languageName: node + linkType: hard + "zod@npm:3.22.4": version: 3.22.4 resolution: "zod@npm:3.22.4" From 4615d906a688690c1c594803a4cad570ec36f6bc Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Mon, 5 Feb 2024 13:59:53 +0000 Subject: [PATCH 02/72] Added functionality for relevant parties --- .../components/Premises/Premises.tsx | 4 +- .../RelevantParties/RelevantParties.tsx | 318 ++++++++++++------ .../components/FormApplicantType.tsx | 143 ++++++++ .../components/SingleParty.tsx | 84 ----- apps/form-builder/hooks/formReducer.tsx | 6 +- apps/form-builder/pages/index.tsx | 1 - apps/form-builder/screens/Form.tsx | 13 +- apps/form-builder/services/apiService.tsx | 31 +- apps/form-builder/types/enums/index.tsx | 9 + apps/form-builder/types/interfaces.tsx | 20 +- 10 files changed, 420 insertions(+), 209 deletions(-) create mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx delete mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx diff --git a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx index 0e0054861873..0380adbf5780 100644 --- a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx +++ b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx @@ -7,6 +7,7 @@ export default function Premises() { const newDocuments = (type: string) => { const { documentTypes } = formBuilder.form + console.log('documentTypes', documentTypes) if (documentTypes?.includes(type)) { if (documentTypes.length === 1) { return [] @@ -34,7 +35,7 @@ export default function Premises() { label={d.name.is} subLabel={d.description.is} value={d.type} - //large + large checked={formBuilder.form.documentTypes?.includes(d.type)} onChange={() => formDispatch({ @@ -49,7 +50,6 @@ export default function Premises() { ) })} - ) : null } diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx index 448cc77366ff..552ebbcb65cd 100644 --- a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx +++ b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx @@ -1,15 +1,21 @@ -import React, { useContext, useEffect, useState } from 'react' +import React, { useContext, useState } from 'react' import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' import FormBuilderContext from '../../../../context/FormBuilderContext' -import { IInput } from '../../../../types/interfaces' -import { addInput, deleteItem } from '../../../../services/apiService' -import SingleParty from './components/SingleParty' +import { + IApplicantType, + IFormApplicantType, +} from '../../../../types/interfaces' +import { saveApplicantTypes } from '../../../../services/apiService' +import { EFormApplicantTypes } from '../../../../types/enums' +import { FormApplicantType } from './components/FormApplicantType' const applicantTypeLabel = [ 'Einstaklingur (innskráður)', 'Einstaklingur í umboði annars einstaklings', 'Einstaklingur í umboði lögaðila', 'Einstaklingur með prókúru', + 'Umboðsveitandi (einstaklingur)', + 'Lögaðili', ] const applicantTypes = [ @@ -17,65 +23,154 @@ const applicantTypes = [ 'Einstaklingur_með_umboð_annars_einstaklings', 'Einstaklingur_með_umboð_lögaðila', 'Einstaklingur_með_prókúru', + 'Einstaklingur_umboðsveitandi', + 'Lögaðili', ] export default function RelevantParties() { - const { lists, formBuilder, listsDispatch } = useContext(FormBuilderContext) - const { activeItem } = lists - const [relevantParties, setRelevantParties] = useState([]) - const groupId = lists.groups.find( - (g) => g.stepGuid === activeItem.data.guid, - ).id + const { formBuilder } = useContext(FormBuilderContext) + const applicantTypeTemplates = formBuilder.applicantTypes + const [formApplicantTypes, setFormApplicantTypes] = useState< + IFormApplicantType[] + >(formBuilder.form.formApplicantTypes) + const { id: formId } = formBuilder.form - useEffect(() => { - setRelevantParties(() => { - const groupGuid = lists.groups.find( - (g) => g.stepGuid === activeItem.data.guid, - ).guid - return lists.inputs.filter((i) => i.groupGuid === groupGuid) - }) - }, [lists, activeItem.data.guid]) + const [focus, setOnFocus] = useState('') - useEffect(() => { - console.log(relevantParties) - }, [relevantParties]) + const createFormApplicantType = ( + type: EFormApplicantTypes, + template: IApplicantType, + ): IFormApplicantType => { + return { + formId: formId, + type: type, + applicantTypeId: template.id, + name: template.nameSuggestions[0].nameSuggestion, + } + } - const handleCheckboxChange = async (checked: boolean, index: number) => { - if (checked) { - const newInput = await addInput(relevantParties.length, groupId) - const { label: is, value: en } = getOptions(applicantTypes[index])[0] - listsDispatch({ - type: 'addInputRelevantParty', - payload: { - data: newInput, - type: applicantTypes[index], - name: { - is, - en, - }, - }, - }) - } else { - const toDelete = relevantParties.find( - (i) => i.inputSettings.type === applicantTypes[index], + const handleCheckboxChange = (checked: boolean, index: number) => { + const updateFormApplicantTypes = ( + newFormApplicantTypes: IFormApplicantType[], + ) => { + const hasLegalEntity = formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.logadili, ) - deleteItem('Input', toDelete.id) - listsDispatch({ - type: 'removeInput', - payload: { - guid: toDelete.guid, - }, - }) + const newTypes = hasLegalEntity + ? newFormApplicantTypes.filter( + (f) => f.type !== EFormApplicantTypes.logadili, + ) + : newFormApplicantTypes + const newList = [...formApplicantTypes, ...newTypes] + saveApplicantTypes(formId, newList) + setFormApplicantTypes([...formApplicantTypes, ...newTypes]) } - } - const getOptions = (type: string) => { - return formBuilder.applicantTypes - .find((at) => at.type === type) - .nameSuggestions.map((n) => ({ - label: n.is, - value: n.en, - })) + const removeFormApplicantTypes = (types: EFormApplicantTypes[]) => { + const newList = formApplicantTypes.filter((f) => !types.includes(f.type)) + saveApplicantTypes(formId, newList) + setFormApplicantTypes(newList) + } + + if (checked) { + if (index === 0) { + const template = applicantTypeTemplates.find( + (at) => at.type === applicantTypes[index], + ) + const newFormApplicantType: IFormApplicantType = + createFormApplicantType(EFormApplicantTypes.einstaklingur, template) + saveApplicantTypes(formId, [newFormApplicantType]) + setFormApplicantTypes([...formApplicantTypes, newFormApplicantType]) + } else if (index === 1) { + const delegatorTemplate = applicantTypeTemplates.find( + (at) => at.id === 2, + ) + const delegateeTemplate = applicantTypeTemplates.find( + (at) => at.id === 5, + ) + const newFormApplicantTypes: IFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, + delegatorTemplate, + ), + createFormApplicantType( + EFormApplicantTypes.einstaklingurUmbodsveitandi, + delegateeTemplate, + ), + ] + setFormApplicantTypes([...formApplicantTypes, ...newFormApplicantTypes]) + } else if (index === 2) { + const delegatorTemplate = applicantTypeTemplates.find( + (at) => at.id === 6, + ) + const delegateeTemplate = applicantTypeTemplates.find( + (at) => at.id === 3, + ) + const newFormApplicantTypes: IFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + delegateeTemplate, + ), + createFormApplicantType( + EFormApplicantTypes.logadili, + delegatorTemplate, + ), + ] + updateFormApplicantTypes(newFormApplicantTypes) + } else if (index === 3) { + const procurationHolder = applicantTypeTemplates.find( + (at) => at.id === 4, + ) + const legalEntity = applicantTypeTemplates.find((at) => at.id === 6) + const newFormApplicantTypes: IFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedProkuru, + procurationHolder, + ), + createFormApplicantType(EFormApplicantTypes.logadili, legalEntity), + ] + updateFormApplicantTypes(newFormApplicantTypes) + } + } else { + if (index === 0) { + removeFormApplicantTypes([EFormApplicantTypes.einstaklingur]) + } else if (index === 1) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, + EFormApplicantTypes.einstaklingurUmbodsveitandi, + ]) + } else if (index === 2) { + if ( + formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.einstaklingurMedProkuru, + ) + ) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + ]) + } else { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + EFormApplicantTypes.logadili, + ]) + } + } else if (index === 3) { + if ( + formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.einstaklingurMedUmbodLogadila, + ) + ) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedProkuru, + ]) + } else { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedProkuru, + EFormApplicantTypes.logadili, + ]) + } + } + } } return ( @@ -87,69 +182,82 @@ export default function RelevantParties() { - {applicantTypeLabel.map((label, index) => ( + {applicantTypeLabel.slice(0, 4).map((label, index) => ( i.inputSettings.type === applicantTypes[index], + checked={formApplicantTypes.some( + (f) => f.type === applicantTypes[index], )} - onChange={(e) => { - handleCheckboxChange(e.target.checked, index) - }} + onChange={(e) => handleCheckboxChange(e.target.checked, index)} /> ))} - {relevantParties.filter((i) => i.type === 'Aðili').length > 0 && ( // TODO: During lag, an input type with text input gets stored in the array + {formApplicantTypes.length > 0 && ( - * Skilgreindu hlutaðeigandi aðila + Skilgreindu hlutaðeigandi aðila )} - {relevantParties.some( - (i) => i.inputSettings.type === applicantTypes[0], - ) && ( - i.inputSettings.type === applicantTypes[0], - )} - /> - )} - {relevantParties.some( - (i) => i.inputSettings.type === applicantTypes[1], - ) && ( - i.inputSettings.type === applicantTypes[1], - )} - /> - )} - {relevantParties.some( - (i) => i.inputSettings.type === applicantTypes[2], - ) && ( - i.inputSettings.type === applicantTypes[2], - )} + {formApplicantTypes.map((f, i) => ( + at.id === f.applicantTypeId) + .nameSuggestions.map((ns) => ns.nameSuggestion)} + formApplicantType={f} + index={i} + handleSelect={handleSelect} + blur={blur} + setOnFocus={onFocus} + setFormApplicantTypes={setFormApplicantTypes} + isOther={isOther(f)} /> - )} - {relevantParties.some( - (i) => i.inputSettings.type === applicantTypes[3], - ) && ( - i.inputSettings.type === applicantTypes[3], - )} - /> - )} + ))} ) + + function isOther(applicant: IFormApplicantType) { + const template = applicantTypeTemplates.find( + (at) => at.id === applicant.applicantTypeId, + ) + if ( + template.nameSuggestions.some( + (ns) => ns.nameSuggestion.is === applicant.name.is, + ) + ) { + return false + } + return true + } + + function handleSelect(e: { label: string; value: string }, index) { + const newApplicantTypes = formApplicantTypes.map((f, i) => { + if (i === index) { + return { + ...f, + name: { + is: e.label, + en: e.value, + }, + } + } + return f + }) + saveApplicantTypes(formId, newApplicantTypes) + setFormApplicantTypes(newApplicantTypes) + } + + function onFocus(value: string) { + setOnFocus(value) + } + + function blur(value: string) { + if (focus !== value) { + saveApplicantTypes(formId, formApplicantTypes) + } + setOnFocus('') + } } diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx new file mode 100644 index 000000000000..5141a82009f8 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx @@ -0,0 +1,143 @@ +import React, { useState } from 'react' +import { + Box, + GridColumn as Column, + GridRow as Row, + Input, + Select, + Stack, + Text, +} from '@island.is/island-ui/core' +import { IFormApplicantType, ILanguage } from '../../../../../types/interfaces' + +interface Props { + title: string + nameSuggestions: ILanguage[] + name: ILanguage + formApplicantType: IFormApplicantType + handleSelect( + e: { + label: string + value: string + }, + index: number, + ): void + index: number + blur(value: string): void + setOnFocus(value: string): void + setFormApplicantTypes: React.Dispatch< + React.SetStateAction + > + isOther: boolean +} + +export function FormApplicantType({ + title, + name, + nameSuggestions, + handleSelect, + index, + blur, + setOnFocus, + setFormApplicantTypes, + isOther, +}: Props) { + const [inputEnabled, setInputEnabled] = useState(isOther) + + const other = { label: 'Annað', value: 'Annað' } + + function getOptions() { + const options = nameSuggestions.map((suggestion) => { + return { + label: suggestion.is, + value: suggestion.en, + } + }) + options.push(other) + return options + } + + function handleSelectChange(e: { label: string; value: string }) { + if (e.label === 'Annað') { + setInputEnabled(true) + } else { + setInputEnabled(false) + handleSelect(e, index) + } + } + + function handleInputChange( + e: React.ChangeEvent, + language: 'is' | 'en', + ) { + setFormApplicantTypes((prev: IFormApplicantType[]) => { + const newApplicantTypes = prev.map((f: IFormApplicantType, i: number) => { + if (i === index) { + return { + ...f, + name: { + ...f.name, + [language]: e.target.value, + }, + } + } + return f + }) + return newApplicantTypes + }) + } + + return ( + + + + + + {title} + + + + + + setOnFocus(e.target.value)} + onBlur={(e) => blur(e.target.value)} + onChange={(e) => handleInputChange(e, 'is')} + /> + + + setOnFocus(e.target.value)} + onBlur={(e) => blur(e.target.value)} + onChange={(e) => handleInputChange(e, 'en')} + /> + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx deleted file mode 100644 index d817efeae7cb..000000000000 --- a/apps/form-builder/components/MainContent/components/RelevantParties/components/SingleParty.tsx +++ /dev/null @@ -1,84 +0,0 @@ -import { - Stack, - Text, - GridRow as Row, - GridColumn as Column, - Select, - Input, - Box, -} from '@island.is/island-ui/core' -import { IInput } from '../../../../../types/interfaces' -import { useState } from 'react' - - -interface Props { - title: string - options: { - label: string - value: string - }[] - input: IInput -} -export default function SingleParty({ title, options, input }: Props) { - // const { formDispatch } = useContext(FormBuilderContext) - // const { applicantTypes } = formBuilder - const [_focus, setFocus] = useState('') - return ( - - - - {title} - - - - setFocus(e.target.value)} - // onChange={(e) => { - // listsDispatch({ - // type: 'changeName', - // payload: { - // guid: input.guid, - // lang: 'is', - // newName: e.target.value - // } - // }) - // }} - /> - - - setFocus(e.target.value)} - /> - - - - - ) -} diff --git a/apps/form-builder/hooks/formReducer.tsx b/apps/form-builder/hooks/formReducer.tsx index b730b57b47b3..d4d71719bb0a 100644 --- a/apps/form-builder/hooks/formReducer.tsx +++ b/apps/form-builder/hooks/formReducer.tsx @@ -132,6 +132,10 @@ export function formReducer(formBuilder: IFormBuilder, action: Action) { } else { dependencies[active] = [itemAsString] } + saveFormSettings(formBuilder.form.id, { + id: formBuilder.form.id, + dependencies: dependencies, + }) return { ...formBuilder, form: { @@ -142,7 +146,6 @@ export function formReducer(formBuilder: IFormBuilder, action: Action) { } case 'formSettings': { - console.log('formReducer formSettings') const { property, value } = action.payload const { id } = formBuilder.form saveFormSettings(id, { @@ -173,6 +176,7 @@ export function formReducer(formBuilder: IFormBuilder, action: Action) { }, } } + default: return formBuilder } diff --git a/apps/form-builder/pages/index.tsx b/apps/form-builder/pages/index.tsx index b46c74eee8d0..5afed5abf66a 100644 --- a/apps/form-builder/pages/index.tsx +++ b/apps/form-builder/pages/index.tsx @@ -14,7 +14,6 @@ export default Index export async function getServerSideProps() { const allForms: IFormBuilder = await getAllFormsFromOrganisation(1) - console.log(allForms) return { props: { formBuilder: allForms, diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index 769471bb44eb..dc9c567ca7bd 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -41,9 +41,9 @@ export default function Form({ form }: Props) { const [selectStatus, setSelectStatus] = useState( NavbarSelectStatus.OFF, ) - console.log('THE FORM: ', form) const [activeListItem, setActiveListItem] = useState(null) const { infoDispatch } = useContext(LayoutContext) + const initialNavbar: ILists = { activeItem: inSettings ? { type: 'Step', data: baseSettingsStep } @@ -57,14 +57,9 @@ export default function Form({ form }: Props) { groups: form.form.groupsList, inputs: form.form.inputsList, } - + console.log('FORM', form) const [formBuilder, formDispatch] = useReducer(formReducer, form) - const [list, listsDispatch] = useReducer( - listsReducer, - initialNavbar, - undefined, - ) - const lists = list as ILists + const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) const { activeItem } = lists const isMounted = useRef(false) @@ -177,9 +172,7 @@ export default function Form({ form }: Props) { function blur(e: FocusEvent) { // Check whether value has changed if (e.target.value !== focus) { - //saveItem() setOnFocus(null) - //formUpdate() updateItem(activeItem.type, activeItem.data) } setIsTyping(false) diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx index 0c8e28b73875..f7cfa9b62612 100644 --- a/apps/form-builder/services/apiService.tsx +++ b/apps/form-builder/services/apiService.tsx @@ -1,6 +1,7 @@ import axios from 'axios' import { IForm, + IFormApplicantType, IFormBuilder, IGroup, IInput, @@ -235,11 +236,11 @@ export async function deleteItem(type: ItemType, id: number) { } } -export async function saveFormSettings(formId: number, settings: object) { +export async function saveFormSettings(id: number, settings: object) { console.log(settings) try { const response = await axios.put( - `${BASEURL}/Forms/${formId}/Settings`, + `${BASEURL}/Forms/${id}/Settings`, settings, { headers: { @@ -256,6 +257,32 @@ export async function saveFormSettings(formId: number, settings: object) { } } +export async function saveApplicantTypes( + id: number, + types: IFormApplicantType[], +) { + const requestData = { + id: id, + formApplicantTypes: types, + } + try { + const response = await axios.put( + `${BASEURL}/Forms/${id}/Settings`, + requestData, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + + console.log('saveApplicantTypes response: ', response) + return response + } catch (error) { + console.error('Error in saveApplicantTypes: ', error) + throw error + } +} export async function getList(type: string) { try { const response = await axios.get(`${BASEURL}/Services/${type}`) diff --git a/apps/form-builder/types/enums/index.tsx b/apps/form-builder/types/enums/index.tsx index 70b74cdae3c0..fadfab2e4e4a 100644 --- a/apps/form-builder/types/enums/index.tsx +++ b/apps/form-builder/types/enums/index.tsx @@ -89,3 +89,12 @@ export enum EInputType { Vottorð = 28, Aðili = 29, } + +export enum EFormApplicantTypes { + einstaklingur = 'Einstaklingur', + einstaklingurMedUmbodAnnarsEinstaklings = 'Einstaklingur_með_umboð_annars_einstaklings', + einstaklingurMedUmbodLogadila = 'Einstaklingur_með_umboð_lögaðila', + einstaklingurMedProkuru = 'Einstaklingur_með_prókúru', + einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', + logadili = 'Lögaðili', +} diff --git a/apps/form-builder/types/interfaces.tsx b/apps/form-builder/types/interfaces.tsx index 8dd7b6468d73..fbf0fe315579 100644 --- a/apps/form-builder/types/interfaces.tsx +++ b/apps/form-builder/types/interfaces.tsx @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import { ChangeEvent, Dispatch, SetStateAction, FocusEvent } from 'react' import { UniqueIdentifier } from '@dnd-kit/core' +import { EFormApplicantTypes } from './enums' export interface IFormBuilderContext { formBuilder: IFormBuilder @@ -73,7 +74,7 @@ export interface IForm { invalidationDate?: Date isTranslated: boolean documentTypes: string[] - adilar: string[] + formApplicantTypes: IFormApplicantType[] } export interface IStep { @@ -161,9 +162,20 @@ export interface ICertificate { } export interface IApplicantType { - type: string - name: string - nameSuggestions: ILanguage[] + id: number + name: ILanguage + type: EFormApplicantTypes + nameSuggestions: { + applicantTypeId: number + nameSuggestion: ILanguage + }[] +} + +export type IFormApplicantType = { + formId: number //formID + applicantTypeId: number + name: ILanguage + type: EFormApplicantTypes } export interface IInputTypes { From f795053244ed7a24531d7ce43183b7e6d5cc3eed Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Mon, 5 Feb 2024 14:14:04 +0000 Subject: [PATCH 03/72] redirect to the correct url when creating a new form --- apps/form-builder/pages/Form/index.tsx | 14 +++++++++++++- apps/form-builder/screens/Form.tsx | 11 +++++------ apps/form-builder/services/apiService.tsx | 3 --- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/form-builder/pages/Form/index.tsx b/apps/form-builder/pages/Form/index.tsx index 2ea7400769ce..2362d796dbbf 100644 --- a/apps/form-builder/pages/Form/index.tsx +++ b/apps/form-builder/pages/Form/index.tsx @@ -1,3 +1,5 @@ +import { useRouter } from 'next/router' +import { useEffect } from 'react' import Form from '../../screens/Form' import { getNewForm } from '../../services/apiService' import { IFormBuilder } from '../../types/interfaces' @@ -7,7 +9,17 @@ interface Props { } const Index = ({ form }: Props) => { - return + const router = useRouter() + + useEffect(() => { + router.replace(`/Form/${form.form.id}`) + }, [form.form.id, router]) + + return ( +
+ +
+ ) } export default Index diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index dc9c567ca7bd..c77e7c81a4d6 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -48,16 +48,15 @@ export default function Form({ form }: Props) { activeItem: inSettings ? { type: 'Step', data: baseSettingsStep } : { - type: 'Step', - data: - form.form.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, + type: 'Step', + data: + form.form.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, steps: form.form.stepsList, groups: form.form.groupsList, inputs: form.form.inputsList, } - console.log('FORM', form) const [formBuilder, formDispatch] = useReducer(formReducer, form) const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) const { activeItem } = lists diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx index f7cfa9b62612..db8166a92a41 100644 --- a/apps/form-builder/services/apiService.tsx +++ b/apps/form-builder/services/apiService.tsx @@ -92,9 +92,6 @@ export async function updateItem(type: string, data: IStep | IGroup | IInput) { export async function getNewForm(organisationId: number) { try { const response = await axios.post(`${BASEURL}/Forms/${organisationId}`) - - console.log('api', response.data) - return response.data } catch (error) { console.error('Error in getNewForm: ', error) From fc7f69db363f46e52dc7c59306f763fd814f7147 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Mon, 5 Feb 2024 14:39:47 +0000 Subject: [PATCH 04/72] removed secret from comment --- .../services/translationStation.tsx | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/apps/form-builder/services/translationStation.tsx b/apps/form-builder/services/translationStation.tsx index abdca24710e1..19be4bae56f2 100644 --- a/apps/form-builder/services/translationStation.tsx +++ b/apps/form-builder/services/translationStation.tsx @@ -39,24 +39,3 @@ export const translationStation = async ( throw error } } -// export const translationStation = async (input: string): Promise => { -// console.log('translationStation', input) -// return await fetch("https://stafraentisland.greynir.is/translate/", { -// method: 'POST', -// headers: { -// 'content-type': 'application/json', -// 'accept': 'application/json', -// 'X-API-Key': 'jtn1QACg.jCxAuvopgqplC5i38Nav1BubiSik6tDK' -// }, -// body: JSON.stringify({ -// "contents": [input], -// "sourceLanguageCode": "is", -// "targetLanguageCode": "en", -// "model": "", -// "domain": "" -// }) -// }).then(res => { -// console.log(res) -// return res.json() -// }) -// } From f8818bd5e684354feba5c29a9683d16fef6a41e9 Mon Sep 17 00:00:00 2001 From: andes-it Date: Mon, 5 Feb 2024 15:01:40 +0000 Subject: [PATCH 05/72] chore: nx format:write update dirty files --- apps/form-builder/screens/Form.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index c77e7c81a4d6..5e1a1c9949b1 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -48,11 +48,11 @@ export default function Form({ form }: Props) { activeItem: inSettings ? { type: 'Step', data: baseSettingsStep } : { - type: 'Step', - data: - form.form.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, + type: 'Step', + data: + form.form.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, steps: form.form.stepsList, groups: form.form.groupsList, inputs: form.form.inputsList, From e1f667b48e1d09270ff3519549874673e560d947 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Tue, 13 Feb 2024 14:05:44 +0000 Subject: [PATCH 06/72] Property number component --- .../components/InputContent/InputContent.tsx | 2 + .../InputContent/components/BaseInput.tsx | 33 +++++----- .../PropertyNumberInputSettings.tsx | 61 +++++++++++++++++++ .../components/ListBuilder/ListBuilder.tsx | 6 +- .../components/Premises/Premises.tsx | 51 +++++++++------- .../components/Preview/Preview.tsx | 4 ++ .../PropertyNumber/PropertyNumber.tsx | 27 ++++++++ .../components/PropertyNumberCombined.tsx | 22 +++++++ .../components/PropertyNumberInput.tsx | 42 +++++++++++++ .../components/PropertyNumberList.tsx | 54 ++++++++++++++++ .../PropertyNumber/components/index.ts | 3 + .../RelevantParties/RelevantParties.tsx | 2 +- .../components/NavbarSelect/NavbarSelect.tsx | 1 - apps/form-builder/gql/client.ts | 42 +++++++++++++ apps/form-builder/gql/httpLink.ts | 14 +++++ apps/form-builder/gql/retryLink.ts | 9 +++ .../hooks/{formReducer.tsx => formReducer.ts} | 33 +++++++--- ...erInfoReducer.tsx => headerInfoReducer.ts} | 0 .../{listsReducer.tsx => listsReducer.ts} | 16 ++--- apps/form-builder/screens/Form.tsx | 12 ++-- apps/form-builder/types/interfaces.tsx | 10 ++- 21 files changed, 374 insertions(+), 70 deletions(-) create mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx create mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts create mode 100644 apps/form-builder/gql/client.ts create mode 100644 apps/form-builder/gql/httpLink.ts create mode 100644 apps/form-builder/gql/retryLink.ts rename apps/form-builder/hooks/{formReducer.tsx => formReducer.ts} (87%) rename apps/form-builder/hooks/{headerInfoReducer.tsx => headerInfoReducer.ts} (100%) rename apps/form-builder/hooks/{listsReducer.tsx => listsReducer.ts} (98%) diff --git a/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx b/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx index 799b0af5a06d..338a031a45d4 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx @@ -19,6 +19,7 @@ import TimeInput from './components/TimeInput' import MessageWithLink from './components/MessageWithLink' import FileUpload from './components/FileUpload/FileUpload' import NumberInput from './components/NumberInput' +import PropertyNumberInputSettings from './components/PropertyNumberInputSettings' export default function InputContent() { const { formBuilder, lists, selectStatus, setSelectStatus } = @@ -106,6 +107,7 @@ export default function InputContent() { {/* File upload */} {currentItem.type === 'Skjal' && } {currentItem.type === 'Tölustafir' && } + {currentItem.type === 'Fasteignanúmer' && } { return { @@ -40,22 +40,21 @@ export default function BaseInput() { return ( - {defaultOption !== undefined && ( - - - changeSelectHandler(e)} + /> + + + {/* Name */} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx new file mode 100644 index 000000000000..83c23d1df331 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx @@ -0,0 +1,61 @@ +import { + GridRow as Row, + GridColumn as Column, + Checkbox, + Stack, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import FormBuilderContext from '../../../../../context/FormBuilderContext' +import { IInput } from '../../../../../types/interfaces' + +export default function PropertyNumberInputSettings() { + const { lists, listsDispatch } = useContext(FormBuilderContext) + const { activeItem } = lists + const currentItem = activeItem.data as IInput + const { inputSettings: settings } = currentItem + + return ( + + + + + listsDispatch({ + type: 'setInputSettings', + payload: { + inputSettings: { + ...settings, + erListi: e.target.checked, + }, + }, + }) + } + /> + + + + + + listsDispatch({ + type: 'setInputSettings', + payload: { + inputSettings: { + ...settings, + erInnslattur: e.target.checked, + }, + }, + }) + } + /> + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx index 715860605c11..ecbeb9b7cd85 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx @@ -163,7 +163,7 @@ export default function ListBuilder({ setInListBuilder }: Props) { } function onDragStart(event: DragStartEvent) { - console.log('DRAG START', event.active.data.current.listItem) + // console.log('DRAG START', event.active.data.current.listItem) listsDispatch({ type: 'setActiveListItem', payload: { @@ -176,8 +176,8 @@ export default function ListBuilder({ setInListBuilder }: Props) { const { active, over } = event if (!over) return - console.log('Active: ', active.data.current.listItem.text.is) - console.log('Over: ', over.data.current.listItem.text.is) + // console.log('Active: ', active.data.current.listItem.text.is) + // console.log('Over: ', over.data.current.listItem.text.is) const activeId = active.id const overId = over.id listsDispatch({ diff --git a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx index 0380adbf5780..394907b503cf 100644 --- a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx +++ b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx @@ -1,22 +1,15 @@ -import React, { useContext } from 'react' +import React, { useContext, useState } from 'react' import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' import FormBuilderContext from '../../../../context/FormBuilderContext' +import { ICertificate } from '../../../../types/interfaces' export default function Premises() { const { formBuilder, formDispatch } = useContext(FormBuilderContext) + const { documentTypes } = formBuilder + const [formDocumentTypes, setFormDocumentTypes] = useState( + formBuilder.form.documentTypes, + ) - const newDocuments = (type: string) => { - const { documentTypes } = formBuilder.form - console.log('documentTypes', documentTypes) - if (documentTypes?.includes(type)) { - if (documentTypes.length === 1) { - return [] - } else { - return documentTypes.filter((item) => item !== type) - } - } - return [...documentTypes, type] - } return formBuilder ? ( @@ -33,23 +26,35 @@ export default function Premises() { - formDispatch({ - type: 'formSettings', - payload: { - property: 'documents', - value: newDocuments(d.type), - }, - }) - } + checked={formDocumentTypes.some((f) => f?.id === d.id)} + onChange={() => handleCheckboxChange(d.id)} /> ) })} ) : null + + function handleCheckboxChange(documentTypeId: number) { + const newDocumentTypes = formDocumentTypes.some( + (f) => f.id === documentTypeId, + ) + ? formDocumentTypes.filter((f) => f.id !== documentTypeId) + : [ + ...formDocumentTypes, + documentTypes.find((d) => d.id === documentTypeId), + ] + setFormDocumentTypes(newDocumentTypes) + formDispatch({ + type: 'updateDocuments', + payload: { + documents: newDocumentTypes, + }, + }) + } } diff --git a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx index a6435224da7c..d74332da12ca 100644 --- a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx @@ -19,6 +19,7 @@ import { IInputSettings, IInput } from '../../../../types/interfaces' import Ssn from './components/Ssn' import Radio from './components/Radio' import UtilizationSummary from './components/UtilizationSummary/UtilizationSummary' +import PropertyNumber from './components/PropertyNumber/PropertyNumber' type Props = { data?: IInput @@ -105,6 +106,9 @@ export default function Preview({ data, isLarge, inputSettings }: Props) { )} {data.type === 'Fellilisti' && } {data.type === 'Valhnappar' && } + {data.type === 'Fasteignanúmer' && ( + + )} ) diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx new file mode 100644 index 000000000000..2564264febb6 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx @@ -0,0 +1,27 @@ +import { IInput } from '../../../../../../types/interfaces' +import { + PropertyNumberCombined, + PropertyNumberInput, + PropertyNumberList, +} from './components' + +interface Props { + currentItem: IInput +} + +export default function PropertyNumber({ currentItem }: Props) { + const { inputSettings: settings } = currentItem + const { erListi: hasList, erInnslattur: hasInput } = settings + + return ( + <> + {hasList && !hasInput ? ( + + ) : !hasList && hasInput ? ( + + ) : hasList && hasInput ? ( + + ) : null} + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx new file mode 100644 index 000000000000..55a549a24809 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx @@ -0,0 +1,22 @@ +import { Tabs } from '@island.is/island-ui/core' +import PropertyNumberList from './PropertyNumberList' +import PropertyNumberInput from './PropertyNumberInput' + +export default function PropertyNumberCombined() { + return ( + , + }, + { + label: 'Fasteignanúmerinnsláttur', + content: , + }, + ]} + contentBackground="blue100" + /> + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx new file mode 100644 index 000000000000..9d3eb0c0c2f5 --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx @@ -0,0 +1,42 @@ +import { + GridRow as Row, + GridColumn as Column, + Stack, + Input, + Box, +} from '@island.is/island-ui/core' +import { useState } from 'react' + +export default function PropertyNumberInput() { + const [propertyNumber, setPropertyNumber] = useState('') + return ( + + + + + setPropertyNumber(e.target.value)} + /> + + + + + + + + + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx new file mode 100644 index 000000000000..6de9e63bf2fa --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx @@ -0,0 +1,54 @@ +import { + GridRow as Row, + GridColumn as Column, + Stack, + Select, + Input, + Box, +} from '@island.is/island-ui/core' + +const dummyList = [ + { + label: 'Fasteign 1', + value: '1', + }, + { + label: 'Fasteign 2', + value: '2', + }, + { + label: 'Fasteign 3', + value: '3', + }, +] + +export default function PropertyNumberList() { + return ( + + + + + + + + + + + + + ) +} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts new file mode 100644 index 000000000000..a1b1b4d6c4ac --- /dev/null +++ b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts @@ -0,0 +1,3 @@ +export { default as PropertyNumberList } from './PropertyNumberList' +export { default as PropertyNumberInput } from './PropertyNumberInput' +export { default as PropertyNumberCombined } from './PropertyNumberCombined' diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx index 552ebbcb65cd..837b5cf105ac 100644 --- a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx +++ b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx @@ -34,7 +34,7 @@ export default function RelevantParties() { IFormApplicantType[] >(formBuilder.form.formApplicantTypes) const { id: formId } = formBuilder.form - + console.log('applicantTypeTemplates: ', applicantTypeTemplates) const [focus, setOnFocus] = useState('') const createFormApplicantType = ( diff --git a/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx b/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx index 0a0e14b1debb..c9a0500816e0 100644 --- a/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx +++ b/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx @@ -8,7 +8,6 @@ export default function NavbarSelect() { const { lists, selectStatus } = useContext(FormBuilderContext) const { activeItem, steps, groups, inputs } = lists //const [selectable, setSelectable] = useState(false) - console.log(selectStatus) let selectable = false return ( diff --git a/apps/form-builder/gql/client.ts b/apps/form-builder/gql/client.ts new file mode 100644 index 000000000000..991867338fbe --- /dev/null +++ b/apps/form-builder/gql/client.ts @@ -0,0 +1,42 @@ +import { + ApolloClient, + ApolloLink, + InMemoryCache, + NormalizedCacheObject, +} from '@apollo/client' +import httpLink from './httpLink' +import retryLink from './retryLink' + +const isBrowser: boolean = process.browser + +let apolloClient: ApolloClient | null = null + +function create(initialState?: any) { + const link = ApolloLink.from([retryLink, httpLink]) // Add retry, error, auth and httpLink here + + return new ApolloClient({ + name: 'form-builder', + version: '0.1', + connectToDevTools: isBrowser, + ssrMode: !isBrowser, + link, + cache: new InMemoryCache().restore(initialState || {}), + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Credentials': 'true', + }, + }) +} + +export default function initApollo(initialState?: any) { + if (!isBrowser) { + return create(initialState) + } + + if (!apolloClient) { + apolloClient = create(initialState) + } + + return apolloClient +} diff --git a/apps/form-builder/gql/httpLink.ts b/apps/form-builder/gql/httpLink.ts new file mode 100644 index 000000000000..91670e5233e0 --- /dev/null +++ b/apps/form-builder/gql/httpLink.ts @@ -0,0 +1,14 @@ +import { createHttpLink } from '@apollo/client' +import fetch from 'isomorphic-unfetch' + +// Polyfill fetch() on the server (used by apollo-client) +if (!process.browser) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(global as any).fetch = fetch +} + +export default createHttpLink({ + uri: 'https://profun.island.is/umsoknarkerfi/api/graphql', // Should be in next.config.js + credentials: 'include', + fetch, +}) diff --git a/apps/form-builder/gql/retryLink.ts b/apps/form-builder/gql/retryLink.ts new file mode 100644 index 000000000000..e77250676e4a --- /dev/null +++ b/apps/form-builder/gql/retryLink.ts @@ -0,0 +1,9 @@ +import { ServerError } from '@apollo/client' +import { RetryLink } from '@apollo/client/link/retry' + +export default new RetryLink({ + attempts: { + max: 2, + retryIf: (error: ServerError) => error && true, + }, +}) diff --git a/apps/form-builder/hooks/formReducer.tsx b/apps/form-builder/hooks/formReducer.ts similarity index 87% rename from apps/form-builder/hooks/formReducer.tsx rename to apps/form-builder/hooks/formReducer.ts index d4d71719bb0a..92db61dfdf0c 100644 --- a/apps/form-builder/hooks/formReducer.tsx +++ b/apps/form-builder/hooks/formReducer.ts @@ -1,5 +1,10 @@ import { UniqueIdentifier } from '@dnd-kit/core' -import { IFormBuilder, ILanguage, ITenging } from '../types/interfaces' +import { + ICertificate, + IFormBuilder, + ILanguage, + ITenging, +} from '../types/interfaces' import { saveFormSettings } from '../services/apiService' type ChangeNameAction = { @@ -39,10 +44,10 @@ type AddRemoveConnectionAction = { } } -type AddRemoveDocuments = { - type: 'addRemoveDocuments' +type UpdateDocuments = { + type: 'updateDocuments' payload: { - documents: string[] + documents: ICertificate[] } } @@ -51,7 +56,10 @@ type FormSettingsPayload = | { property: 'dependencies'; value: ITenging } | { property: 'stopProgressOnValidatingStep'; value: boolean } | { property: 'applicationsDaysToRemove'; value: number } - | { property: 'documents'; value: string[] } + | { + property: 'formDocumentTypes' + value: { formId: number; documentTypeId: number }[] + } | { property: 'adilar'; value: string[] } | { property: 'completedMessage'; value: ILanguage } | { property: 'isTranslated'; value: boolean } @@ -68,7 +76,7 @@ type Action = | StopProgressOnValidatingStepAction | AddRemoveConnectionAction | FormSettingsAction - | AddRemoveDocuments + | UpdateDocuments export function formReducer(formBuilder: IFormBuilder, action: Action) { switch (action.type) { @@ -161,18 +169,23 @@ export function formReducer(formBuilder: IFormBuilder, action: Action) { } } - case 'addRemoveDocuments': { + case 'updateDocuments': { const { documents } = action.payload - console.log('dasdsa') + const saveDocuments = documents.map((d) => { + return { + formId: formBuilder.form.id, + documentTypeId: d.id, + } + }) saveFormSettings(formBuilder.form.id, { id: formBuilder.form.id, - documents: documents, + formDocumentTypes: saveDocuments, }) return { ...formBuilder, form: { ...formBuilder.form, - documents: documents, + documentTypes: documents, }, } } diff --git a/apps/form-builder/hooks/headerInfoReducer.tsx b/apps/form-builder/hooks/headerInfoReducer.ts similarity index 100% rename from apps/form-builder/hooks/headerInfoReducer.tsx rename to apps/form-builder/hooks/headerInfoReducer.ts diff --git a/apps/form-builder/hooks/listsReducer.tsx b/apps/form-builder/hooks/listsReducer.ts similarity index 98% rename from apps/form-builder/hooks/listsReducer.tsx rename to apps/form-builder/hooks/listsReducer.ts index e8ded74a3bb2..012483d600c0 100644 --- a/apps/form-builder/hooks/listsReducer.tsx +++ b/apps/form-builder/hooks/listsReducer.ts @@ -574,14 +574,14 @@ export const listsReducer = (lists: ILists, action: Action): ILists => { const input = activeItem.data as IInput const { payload } = action - if ( - !payload || - !('property' in payload) || - !('checked' in payload) || - !('value' in payload) - ) { - throw new Error('Invalid payload') - } + // if ( + // !payload || + // !('property' in payload) || + // !('checked' in payload) || + // !('value' in payload) + // ) { + // throw new Error('Invalid payload') + // } const { property, checked, value } = payload diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index c77e7c81a4d6..735d28e515b1 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -48,11 +48,11 @@ export default function Form({ form }: Props) { activeItem: inSettings ? { type: 'Step', data: baseSettingsStep } : { - type: 'Step', - data: - form.form.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, + type: 'Step', + data: + form.form.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, steps: form.form.stepsList, groups: form.form.groupsList, inputs: form.form.inputsList, @@ -60,7 +60,7 @@ export default function Form({ form }: Props) { const [formBuilder, formDispatch] = useReducer(formReducer, form) const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) const { activeItem } = lists - + console.log('FORM: ', form) const isMounted = useRef(false) useEffect(() => { if (isMounted.current) { diff --git a/apps/form-builder/types/interfaces.tsx b/apps/form-builder/types/interfaces.tsx index fbf0fe315579..25173b4c7592 100644 --- a/apps/form-builder/types/interfaces.tsx +++ b/apps/form-builder/types/interfaces.tsx @@ -50,6 +50,8 @@ export interface IInputSettings { listi?: IListItem[] type?: string name?: ILanguage + erListi?: boolean + erInnslattur?: boolean [key: string]: any } @@ -73,7 +75,7 @@ export interface IForm { applicationsDaysToRemove: number invalidationDate?: Date isTranslated: boolean - documentTypes: string[] + documentTypes: ICertificate[] formApplicantTypes: IFormApplicantType[] } @@ -156,6 +158,7 @@ export interface IListItem { } export interface ICertificate { + id: number type: string name: ILanguage description: ILanguage @@ -178,6 +181,11 @@ export type IFormApplicantType = { type: EFormApplicantTypes } +export interface IFormDocumentType { + formId: number + documentTypeId: number +} + export interface IInputTypes { type: string name: string From 74464ffe1158bfd024a4f43077c74ab249bbefe9 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Tue, 13 Feb 2024 16:32:14 +0000 Subject: [PATCH 07/72] Fixed the header --- apps/form-builder/gql/queries.graphql.ts | 14 +++++++++ apps/form-builder/pages/Form/[id]/index.tsx | 2 +- apps/form-builder/pages/_app.tsx | 34 ++++++++++++++++++--- apps/form-builder/screens/Form.tsx | 31 +++++++++---------- apps/form-builder/services/apiService.tsx | 3 +- 5 files changed, 61 insertions(+), 23 deletions(-) create mode 100644 apps/form-builder/gql/queries.graphql.ts diff --git a/apps/form-builder/gql/queries.graphql.ts b/apps/form-builder/gql/queries.graphql.ts new file mode 100644 index 000000000000..c1cffc22d993 --- /dev/null +++ b/apps/form-builder/gql/queries.graphql.ts @@ -0,0 +1,14 @@ +import { gql } from '@apollo/client' + +export const ADD_STEP = gql` + mutation AddStep($input: AddStepInput!) { + addStep(input: $input) { + id + name { + is + en + } + type + } + } +` diff --git a/apps/form-builder/pages/Form/[id]/index.tsx b/apps/form-builder/pages/Form/[id]/index.tsx index 582a15fdc397..6bdfb0dc1621 100644 --- a/apps/form-builder/pages/Form/[id]/index.tsx +++ b/apps/form-builder/pages/Form/[id]/index.tsx @@ -20,7 +20,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { notFound: true, } } - const form: IFormBuilder = await getForm(formId as number) + const form: IFormBuilder = await getForm(formId) return { props: { form: form, diff --git a/apps/form-builder/pages/_app.tsx b/apps/form-builder/pages/_app.tsx index 39f4f73e5355..85f8a6bbe74f 100644 --- a/apps/form-builder/pages/_app.tsx +++ b/apps/form-builder/pages/_app.tsx @@ -1,12 +1,16 @@ -import { AppProps } from 'next/app' +import { ApolloProvider } from '@apollo/client' +import { AppContext, AppProps } from 'next/app' +import { getSession, Provider } from 'next-auth/client' import { IntlProvider } from 'react-intl' import Layout from '../components/Layout/Layout' +import initApollo from '../gql/client' -const FormBuilderProviderApp: unknown = ({ - Component, - pageProps, -}: AppProps) => { +const FormBuilderProviderApp: any = ({ Component, pageProps }: AppProps) => { return ( + // + // + // + // ) } +// FormBuilderProviderApp.getInitialProps = async (appContext: AppContext) => { +// const { ctx } = appContext +// const apolloClient = initApollo({}) +// const customContext = { +// ...ctx, +// apolloClient, +// } +// const apolloState = apolloClient.cache.extract() +// const session = await getSession(customContext) + +// return { +// pageProps: { +// session: session, +// apolloState: apolloState +// } +// } +// } + export default FormBuilderProviderApp diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index 735d28e515b1..64d4a56eebaa 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -25,6 +25,7 @@ import { GridRow as Row, GridColumn as Column, Box, + Button, } from '@island.is/island-ui/core' import Navbar from '../components/Navbar/Navbar' import NavbarSelect from '../components/NavbarSelect/NavbarSelect' @@ -63,22 +64,20 @@ export default function Form({ form }: Props) { console.log('FORM: ', form) const isMounted = useRef(false) useEffect(() => { - if (isMounted.current) { - if (!isTyping) { - //formUpdate() - } - } else { - isMounted.current = true - infoDispatch({ - type: 'changeOrganization', - data: formBuilder?.form?.organization.name.is, - }) - infoDispatch({ - type: 'changeApplicationName', - data: formBuilder.form.name.is, - }) - } - }, [formBuilder, infoDispatch, isTyping]) + isMounted.current = true + infoDispatch({ + type: 'changeOrganization', + payload: { + value: formBuilder?.form?.organization.name.is, + }, + }) + infoDispatch({ + type: 'changeApplicationName', + payload: { + value: formBuilder.form.name.is, + }, + }) + }, [formBuilder, infoDispatch]) const context: IFormBuilderContext = { formBuilder: formBuilder, diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx index db8166a92a41..7b07b4d53ba6 100644 --- a/apps/form-builder/services/apiService.tsx +++ b/apps/form-builder/services/apiService.tsx @@ -12,9 +12,10 @@ import { const BASEURL = 'https://profun.island.is/umsoknarkerfi/api' -export async function getForm(id: number) { +export async function getForm(id: unknown) { try { const response = await axios.get(`${BASEURL}/Forms/${id}`) + console.log('getForm response: ', response.data) return response.data } catch (error) { console.error(error) From d7b708d4b8cc22c4a77e3b04b4089091034d4904 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Mon, 19 Feb 2024 16:45:27 +0000 Subject: [PATCH 08/72] Reverted to next 13.3.0 --- package.json | 2 +- yarn.lock | 121 ++++++++++++++++++++++----------------------------- 2 files changed, 53 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index a752071fed34..f7171c955fa2 100644 --- a/package.json +++ b/package.json @@ -213,7 +213,7 @@ "mobx": "6.3.7", "msw": "0.21.3", "nest-winston": "1.4.0", - "next": "13.4.1", + "next": "13.3.0", "next-auth": "3.29.10", "next-cookies": "2.0.3", "next-usequerystate": "1.8.4", diff --git a/yarn.lock b/yarn.lock index 0f1962fc3d0e..e9594ada5e54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11712,10 +11712,10 @@ __metadata: languageName: node linkType: hard -"@next/env@npm:13.4.1": - version: 13.4.1 - resolution: "@next/env@npm:13.4.1" - checksum: 4736c9c6f75d80b16d3ca0ad3ddb3fcaa171f2144fccf516a67110e3bfcd9121d076e838faad46f815e41ee32e9be0ab68591359de06af13be6cbb860eda3639 +"@next/env@npm:13.3.0": + version: 13.3.0 + resolution: "@next/env@npm:13.3.0" + checksum: 17dbea6d019df98f8abebadcaed635d792c69368389c7869ca023acfba240294368a58eda761fb8047403b84e82edf25ea2af45afe06cc1807a25de42e256dd3 languageName: node linkType: hard @@ -11728,65 +11728,65 @@ __metadata: languageName: node linkType: hard -"@next/swc-darwin-arm64@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-darwin-arm64@npm:13.4.1" +"@next/swc-darwin-arm64@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-darwin-arm64@npm:13.3.0" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@next/swc-darwin-x64@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-darwin-x64@npm:13.4.1" +"@next/swc-darwin-x64@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-darwin-x64@npm:13.3.0" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@next/swc-linux-arm64-gnu@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-linux-arm64-gnu@npm:13.4.1" +"@next/swc-linux-arm64-gnu@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-linux-arm64-gnu@npm:13.3.0" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-arm64-musl@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-linux-arm64-musl@npm:13.4.1" +"@next/swc-linux-arm64-musl@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-linux-arm64-musl@npm:13.3.0" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@next/swc-linux-x64-gnu@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-linux-x64-gnu@npm:13.4.1" +"@next/swc-linux-x64-gnu@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-linux-x64-gnu@npm:13.3.0" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@next/swc-linux-x64-musl@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-linux-x64-musl@npm:13.4.1" +"@next/swc-linux-x64-musl@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-linux-x64-musl@npm:13.3.0" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@next/swc-win32-arm64-msvc@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-win32-arm64-msvc@npm:13.4.1" +"@next/swc-win32-arm64-msvc@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-win32-arm64-msvc@npm:13.3.0" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@next/swc-win32-ia32-msvc@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-win32-ia32-msvc@npm:13.4.1" +"@next/swc-win32-ia32-msvc@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-win32-ia32-msvc@npm:13.3.0" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@next/swc-win32-x64-msvc@npm:13.4.1": - version: 13.4.1 - resolution: "@next/swc-win32-x64-msvc@npm:13.4.1" +"@next/swc-win32-x64-msvc@npm:13.3.0": + version: 13.3.0 + resolution: "@next/swc-win32-x64-msvc@npm:13.3.0" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -16448,12 +16448,12 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:0.5.1": - version: 0.5.1 - resolution: "@swc/helpers@npm:0.5.1" +"@swc/helpers@npm:0.4.14, @swc/helpers@npm:^0.4.2": + version: 0.4.14 + resolution: "@swc/helpers@npm:0.4.14" dependencies: tslib: ^2.4.0 - checksum: 71e0e27234590435e4c62b97ef5e796f88e786841a38c7116a5e27a3eafa7b9ead7cdec5249b32165902076de78446945311c973e59bddf77c1e24f33a8f272a + checksum: 273fd3f3fc461a92f3790cc551ea054745c6d6959afbe1232e6d7aa1c722bbc114d308aab96bef5c78fc0303c85c7b472ef00e2253251cc89737f3b1af56e5a5 languageName: node linkType: hard @@ -16466,15 +16466,6 @@ __metadata: languageName: node linkType: hard -"@swc/helpers@npm:^0.4.2": - version: 0.4.14 - resolution: "@swc/helpers@npm:0.4.14" - dependencies: - tslib: ^2.4.0 - checksum: 273fd3f3fc461a92f3790cc551ea054745c6d6959afbe1232e6d7aa1c722bbc114d308aab96bef5c78fc0303c85c7b472ef00e2253251cc89737f3b1af56e5a5 - languageName: node - linkType: hard - "@swc/types@npm:^0.1.4": version: 0.1.4 resolution: "@swc/types@npm:0.1.4" @@ -33994,7 +33985,7 @@ __metadata: mobx: 6.3.7 msw: 0.21.3 nest-winston: 1.4.0 - next: 13.4.1 + next: 13.3.0 next-auth: 3.29.10 next-cookies: 2.0.3 next-secure-headers: 2.1.0 @@ -40145,26 +40136,25 @@ __metadata: languageName: node linkType: hard -"next@npm:13.4.1": - version: 13.4.1 - resolution: "next@npm:13.4.1" - dependencies: - "@next/env": 13.4.1 - "@next/swc-darwin-arm64": 13.4.1 - "@next/swc-darwin-x64": 13.4.1 - "@next/swc-linux-arm64-gnu": 13.4.1 - "@next/swc-linux-arm64-musl": 13.4.1 - "@next/swc-linux-x64-gnu": 13.4.1 - "@next/swc-linux-x64-musl": 13.4.1 - "@next/swc-win32-arm64-msvc": 13.4.1 - "@next/swc-win32-ia32-msvc": 13.4.1 - "@next/swc-win32-x64-msvc": 13.4.1 - "@swc/helpers": 0.5.1 +"next@npm:13.3.0": + version: 13.3.0 + resolution: "next@npm:13.3.0" + dependencies: + "@next/env": 13.3.0 + "@next/swc-darwin-arm64": 13.3.0 + "@next/swc-darwin-x64": 13.3.0 + "@next/swc-linux-arm64-gnu": 13.3.0 + "@next/swc-linux-arm64-musl": 13.3.0 + "@next/swc-linux-x64-gnu": 13.3.0 + "@next/swc-linux-x64-musl": 13.3.0 + "@next/swc-win32-arm64-msvc": 13.3.0 + "@next/swc-win32-ia32-msvc": 13.3.0 + "@next/swc-win32-x64-msvc": 13.3.0 + "@swc/helpers": 0.4.14 busboy: 1.6.0 caniuse-lite: ^1.0.30001406 postcss: 8.4.14 styled-jsx: 5.1.1 - zod: 3.21.4 peerDependencies: "@opentelemetry/api": ^1.1.0 fibers: ">= 3.1.0" @@ -40202,7 +40192,7 @@ __metadata: optional: true bin: next: dist/bin/next - checksum: 169e3fbbf713fad791a9b016c83d396bce628bb0ddf716c5fe50104a21cbc37af7df1586cbe05ae4ae6a090f4e1107211189cfbeeeab8345fe54e11cfefce87f + checksum: 24e0e013e867a825ff7d1f49587e696147ea8f9ff42946121fe0dce25f9bcc9b1d5941425fa7cef3b8c0e6f1c3daa7f09f758ac5a8aa15aa66c3b31a07465081 languageName: node linkType: hard @@ -53924,13 +53914,6 @@ __metadata: languageName: node linkType: hard -"zod@npm:3.21.4": - version: 3.21.4 - resolution: "zod@npm:3.21.4" - checksum: f185ba87342ff16f7a06686767c2b2a7af41110c7edf7c1974095d8db7a73792696bcb4a00853de0d2edeb34a5b2ea6a55871bc864227dace682a0a28de33e1f - languageName: node - linkType: hard - "zod@npm:3.22.4": version: 3.22.4 resolution: "zod@npm:3.22.4" From 9666db4c96011e071ca50e17d6cfb0d556281596 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Wed, 21 Feb 2024 12:04:43 +0000 Subject: [PATCH 09/72] Deleted the e2e project, updated to project to adhere to strict typescript, removed all console.logs and removed all code that was commented out --- apps/form-builder-e2e/.eslintrc.json | 10 - apps/form-builder-e2e/cypress.config.ts | 6 - apps/form-builder-e2e/project.json | 30 --- apps/form-builder-e2e/src/e2e/app.cy.ts | 13 - .../src/fixtures/example.json | 4 - apps/form-builder-e2e/src/support/app.po.ts | 1 - apps/form-builder-e2e/src/support/commands.ts | 33 --- apps/form-builder-e2e/src/support/e2e.ts | 17 -- apps/form-builder-e2e/tsconfig.json | 10 - .../form-builder/components/Layout/Layout.tsx | 2 - .../LicenseProviderDropdown.tsx | 6 +- .../components/MainContent/MainContent.tsx | 152 ++++++----- .../components/BaseSettings/BaseSettings.tsx | 54 ++-- .../InputContent/components/BaseInput.tsx | 24 +- .../components/FileUpload/FileUpload.tsx | 36 +-- .../components/MessageWithLink.tsx | 6 +- .../InputContent/components/NumberInput.tsx | 8 +- .../InputContent/components/TimeInput.tsx | 6 +- .../components/ListBuilder/ListBuilder.tsx | 10 +- .../ListBuilder/components/ListItem.tsx | 25 +- .../components/ListContent/ListContent.tsx | 7 +- .../components/Premises/Premises.tsx | 13 +- .../components/Preview/Preview.tsx | 15 +- .../Preview/components/Banknumber.tsx | 44 +++- .../Preview/components/Currency.tsx | 12 +- .../Preview/components/FileUpload.tsx | 66 +---- .../components/Preview/components/List.tsx | 3 +- .../components/MessageWithLinkButton.tsx | 7 +- .../components/{Ssn.tsx => NationalId.tsx} | 2 +- .../Preview/components/NumberInput.tsx | 14 +- .../components/Preview/components/Radio.tsx | 8 +- .../Preview/components/TimeSelect.tsx | 2 - .../PreviewStepOrGroup/MultiSet/MultiSet.tsx | 11 +- .../PreviewStepOrGroup/PreviewStepOrGroup.tsx | 23 +- .../RelevantParties/RelevantParties.tsx | 40 ++- .../components/FormApplicantType.tsx | 2 +- .../form-builder/components/Navbar/Navbar.tsx | 73 ++---- .../NavComponent/NavComponent.css.ts | 3 - .../components/NavComponent/NavComponent.tsx | 13 +- .../NavComponent/components/NavButtons.tsx | 36 +-- .../components/NavbarTab/NavbarTab.css.tsx | 3 - .../components/NavbarSelect/NavbarSelect.tsx | 1 - .../components/SelectNavComponent.tsx | 8 +- .../components/selectNavComponent.css.ts | 3 - .../components/TableRow/TableRow.tsx | 23 +- apps/form-builder/components/Tabs/index.tsx | 4 - .../TranslationTag/TranslationTag.tsx | 10 +- apps/form-builder/gql/client.ts | 2 + apps/form-builder/gql/retryLink.ts | 6 +- apps/form-builder/hooks/formReducer.ts | 17 +- apps/form-builder/hooks/headerInfoReducer.ts | 4 +- apps/form-builder/hooks/listsReducer.ts | 245 +++++++++--------- apps/form-builder/pages/_app.tsx | 34 +-- apps/form-builder/screens/Form.tsx | 49 +--- apps/form-builder/screens/Forms.tsx | 18 -- apps/form-builder/services/apiService.tsx | 53 +--- apps/form-builder/tsconfig.json | 20 +- apps/form-builder/types/interfaces.tsx | 28 +- 58 files changed, 510 insertions(+), 865 deletions(-) delete mode 100644 apps/form-builder-e2e/.eslintrc.json delete mode 100644 apps/form-builder-e2e/cypress.config.ts delete mode 100644 apps/form-builder-e2e/project.json delete mode 100644 apps/form-builder-e2e/src/e2e/app.cy.ts delete mode 100644 apps/form-builder-e2e/src/fixtures/example.json delete mode 100644 apps/form-builder-e2e/src/support/app.po.ts delete mode 100644 apps/form-builder-e2e/src/support/commands.ts delete mode 100644 apps/form-builder-e2e/src/support/e2e.ts delete mode 100644 apps/form-builder-e2e/tsconfig.json rename apps/form-builder/components/MainContent/components/Preview/components/{Ssn.tsx => NationalId.tsx} (90%) diff --git a/apps/form-builder-e2e/.eslintrc.json b/apps/form-builder-e2e/.eslintrc.json deleted file mode 100644 index 696cb8b12127..000000000000 --- a/apps/form-builder-e2e/.eslintrc.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": ["plugin:cypress/recommended", "../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/apps/form-builder-e2e/cypress.config.ts b/apps/form-builder-e2e/cypress.config.ts deleted file mode 100644 index 1ff4098804c6..000000000000 --- a/apps/form-builder-e2e/cypress.config.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { defineConfig } from 'cypress' -import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset' - -export default defineConfig({ - e2e: nxE2EPreset(__dirname), -}) diff --git a/apps/form-builder-e2e/project.json b/apps/form-builder-e2e/project.json deleted file mode 100644 index e686b2390f4a..000000000000 --- a/apps/form-builder-e2e/project.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "form-builder-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/form-builder-e2e/src", - "projectType": "application", - "targets": { - "e2e": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/form-builder-e2e/cypress.config.ts", - "devServerTarget": "form-builder:serve:development", - "testingType": "e2e" - }, - "configurations": { - "production": { - "devServerTarget": "form-builder:serve:production" - } - } - }, - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/form-builder-e2e/**/*.{js,ts}"] - } - } - }, - "tags": [], - "implicitDependencies": ["form-builder"] -} diff --git a/apps/form-builder-e2e/src/e2e/app.cy.ts b/apps/form-builder-e2e/src/e2e/app.cy.ts deleted file mode 100644 index 9b3f1c3ef43b..000000000000 --- a/apps/form-builder-e2e/src/e2e/app.cy.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getGreeting } from '../support/app.po' - -describe('form-builder', () => { - beforeEach(() => cy.visit('/')) - - it('should display welcome message', () => { - // Custom command example, see `../support/commands.ts` file - cy.login('my-email@something.com', 'myPassword') - - // Function helper example, see `../support/app.po.ts` file - getGreeting().contains('Welcome form-builder') - }) -}) diff --git a/apps/form-builder-e2e/src/fixtures/example.json b/apps/form-builder-e2e/src/fixtures/example.json deleted file mode 100644 index 294cbed6ce9e..000000000000 --- a/apps/form-builder-e2e/src/fixtures/example.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io" -} diff --git a/apps/form-builder-e2e/src/support/app.po.ts b/apps/form-builder-e2e/src/support/app.po.ts deleted file mode 100644 index 00f556e10333..000000000000 --- a/apps/form-builder-e2e/src/support/app.po.ts +++ /dev/null @@ -1 +0,0 @@ -export const getGreeting = () => cy.get('h1') diff --git a/apps/form-builder-e2e/src/support/commands.ts b/apps/form-builder-e2e/src/support/commands.ts deleted file mode 100644 index 270f023ff512..000000000000 --- a/apps/form-builder-e2e/src/support/commands.ts +++ /dev/null @@ -1,33 +0,0 @@ -// *********************************************** -// This example commands.js shows you how to -// create various custom commands and overwrite -// existing commands. -// -// For more comprehensive examples of custom -// commands please read more here: -// https://on.cypress.io/custom-commands -// *********************************************** - -// eslint-disable-next-line @typescript-eslint/no-namespace -declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void - } -} -// -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password) -}) -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) diff --git a/apps/form-builder-e2e/src/support/e2e.ts b/apps/form-builder-e2e/src/support/e2e.ts deleted file mode 100644 index 185d654ec609..000000000000 --- a/apps/form-builder-e2e/src/support/e2e.ts +++ /dev/null @@ -1,17 +0,0 @@ -// *********************************************************** -// This example support/index.js is processed and -// loaded automatically before your test files. -// -// This is a great place to put global configuration and -// behavior that modifies Cypress. -// -// You can change the location of this file or turn off -// automatically serving support files with the -// 'supportFile' configuration option. -// -// You can read more here: -// https://on.cypress.io/configuration -// *********************************************************** - -// Import commands.js using ES2015 syntax: -import './commands' diff --git a/apps/form-builder-e2e/tsconfig.json b/apps/form-builder-e2e/tsconfig.json deleted file mode 100644 index cc509a730e12..000000000000 --- a/apps/form-builder-e2e/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "sourceMap": false, - "outDir": "../../dist/out-tsc", - "allowJs": true, - "types": ["cypress", "node"] - }, - "include": ["src/**/*.ts", "src/**/*.js", "cypress.config.ts"] -} diff --git a/apps/form-builder/components/Layout/Layout.tsx b/apps/form-builder/components/Layout/Layout.tsx index d89004441be6..29987465d433 100644 --- a/apps/form-builder/components/Layout/Layout.tsx +++ b/apps/form-builder/components/Layout/Layout.tsx @@ -18,8 +18,6 @@ type LayoutProps = { const Layout: FC = ({ children }: LayoutProps) => { const route = useRouter() - //useContext(LayoutContext) - const initialInfo = { organization: '', applicationName: '', diff --git a/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx b/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx index a58125ee0200..3e133bb81afe 100644 --- a/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx +++ b/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx @@ -20,8 +20,8 @@ export default function LicenseProviderDropdown({ licenseProviders, setSelectProvider, }: LicenseProviderDropdownProps) { - const handleChange = (e: { value: number }) => { - setSelectProvider(e.value) + const handleChange = (e: { label: string; value: number }) => { + setSelectProvider(e.value as number) } return ( @@ -32,7 +32,7 @@ export default function LicenseProviderDropdown({ noOptionsMessage="Veldu stofnun" placeholder="Veldu stofnun" options={mappedProviders(licenseProviders)} - onChange={handleChange} + onChange={(e) => e && handleChange(e)} size={'sm'} /> diff --git a/apps/form-builder/components/MainContent/MainContent.tsx b/apps/form-builder/components/MainContent/MainContent.tsx index 089bf3169cdf..0cd84faa94a0 100644 --- a/apps/form-builder/components/MainContent/MainContent.tsx +++ b/apps/form-builder/components/MainContent/MainContent.tsx @@ -19,7 +19,7 @@ import FormBuilderContext from '../../context/FormBuilderContext' import { translationStation } from '../../services/translationStation' export default function MainContent() { - const { lists, listsDispatch, changeHandler, blur, onFocus } = + const { lists, listsDispatch, blur, onFocus } = useContext(FormBuilderContext) const { activeItem } = lists const [openPreview, setOpenPreview] = useState(false) @@ -41,80 +41,94 @@ export default function MainContent() { (activeItem.data as IStep).type === 'Greiðsla' ? ( // Payment step ) : // Input step or group - openPreview ? ( - - ) : ( - - - - changeHandler(e, 'name')} - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - /> - - - - - changeHandler(e, 'nameEn')} - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - activeItem.data.name.is, - ) + openPreview ? ( + + ) : ( + + + + listsDispatch({ + type: 'changeName', + payload: { + lang: 'is', + newValue: e.target.value, + } + })} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + /> + + + + + listsDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newValue: e.target.value, + } + })} + onFocus={(e) => onFocus(e.target.value)} + onBlur={(e) => blur(e)} + buttons={[ + { + label: 'translate', + name: 'reader', + onClick: async () => { + const translation = await translationStation( + activeItem.data.name.is, + ) + listsDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newValue: translation.translations[0].translatedText, + }, + }) + }, + }, + ]} + /> + + + {activeItem.type === 'Group' && ( + + + listsDispatch({ - type: 'changeName', - lang: 'en', - newValue: translation.translations[0].translatedText, + type: 'setMultiSet', + payload: { + checked: e.target.checked, + }, }) - }, - }, - ]} - /> - - - {activeItem.type === 'Group' && ( + } + /> + + + )} - - listsDispatch({ - type: 'setMultiSet', - payload: { - checked: e.target.checked, - }, - }) - } - /> + - )} - - - - - - - )} + + )} ) } diff --git a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx index 3343605da60f..b7c150a5727c 100644 --- a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -12,10 +12,10 @@ import LayoutContext from '../../../../context/LayoutContext' import { saveFormSettings } from '../../../../services/apiService' export default function BaseSettings() { - const { formBuilder, formDispatch, setIsTyping } = + const { formBuilder, formDispatch } = useContext(FormBuilderContext) const { infoDispatch } = useContext(LayoutContext) - const [focus, setFocus] = useState(null) + const [focus, setFocus] = useState('') const { id, name, @@ -36,7 +36,6 @@ export default function BaseSettings() { onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => blur(e)} onChange={(e) => { - setIsTyping(true) formDispatch({ type: 'changeName', payload: { @@ -46,7 +45,9 @@ export default function BaseSettings() { }) infoDispatch({ type: 'changeApplicationName', - data: e.target.value, + payload: { + value: e.target.value + } }) }} /> @@ -61,7 +62,6 @@ export default function BaseSettings() { onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => blur(e)} onChange={(e) => { - setIsTyping(true) formDispatch({ type: 'changeName', payload: { @@ -89,10 +89,9 @@ export default function BaseSettings() { onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => blur(e)} onChange={(e) => { - setIsTyping(true) formDispatch({ type: 'applicationsDaysToRemove', - payload: { value: e.target.value }, + payload: { value: e.target.value as unknown as number }, }) }} /> @@ -100,32 +99,18 @@ export default function BaseSettings() { - {formBuilder.form.invalidationDate ? ( - { - formDispatch({ - type: 'invalidationDate', - payload: { value: e.toJSON() }, - }) - }} - /> - ) : ( - { - formDispatch({ - type: 'invalidationDate', - payload: { value: e.toJSON() }, - }) - }} - /> - )} + { + formDispatch({ + type: 'invalidationDate', + payload: { value: e }, + }) + }} + /> @@ -147,7 +132,7 @@ export default function BaseSettings() { function blur(e: FocusEvent) { if (focus !== e.target.value) { - setFocus(null) + setFocus('') const toSave = { id: id, name: name, @@ -157,6 +142,5 @@ export default function BaseSettings() { } saveFormSettings(id, toSave) } - setIsTyping(false) } } diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx index 47cc5fc16dfb..3c709c5974f4 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -16,15 +16,13 @@ export default function BaseInput() { formBuilder, lists, listsDispatch, - changeHandler, changeSelectHandler, onFocus, blur, } = useContext(FormBuilderContext) const { activeItem } = lists const currentItem = activeItem.data as IInput - console.log('formBuilder.inputTypes', formBuilder.inputTypes) - const options = formBuilder.inputTypes + const createAndSortOptions = formBuilder.inputTypes .map((it) => { return { label: it.type, @@ -36,7 +34,7 @@ export default function BaseInput() { const defaultOption = currentItem.type === '' ? null - : options.find((o) => o.value === currentItem.type) + : createAndSortOptions.find((o) => o.value === currentItem.type) return ( @@ -45,7 +43,7 @@ export default function BaseInput() { { + onChange={(e) => { listsDispatch({ type: 'timeInterval', - data: e.value, + payload: { data: e ? e.value : '0' } }) }} /> diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx index ecbeb9b7cd85..8685573174a4 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx @@ -44,7 +44,10 @@ export default function ListBuilder({ setInListBuilder }: Props) { } = useContext(FormBuilderContext) const { activeItem } = lists const currentItem = activeItem.data as IInput - const listItems = currentItem.inputSettings.listi + const listItems = useMemo( + () => currentItem.inputSettings.listi ?? [], + [currentItem.inputSettings.listi], + ) const listItemIds = useMemo(() => listItems.map((li) => li.guid), [listItems]) const [connecting, setConnecting] = useState([false]) @@ -163,11 +166,10 @@ export default function ListBuilder({ setInListBuilder }: Props) { } function onDragStart(event: DragStartEvent) { - // console.log('DRAG START', event.active.data.current.listItem) listsDispatch({ type: 'setActiveListItem', payload: { - listItem: event.active.data.current.listItem, + listItem: event.active.data.current?.listItem, }, }) } @@ -176,8 +178,6 @@ export default function ListBuilder({ setInListBuilder }: Props) { const { active, over } = event if (!over) return - // console.log('Active: ', active.data.current.listItem.text.is) - // console.log('Over: ', over.data.current.listItem.text.is) const activeId = active.id const overId = over.id listsDispatch({ diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx index 755bedbcca4b..0b7344fc3ed8 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx @@ -61,13 +61,13 @@ export default function ListItem({ label="Tengja" checked={connect} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => {}} + onChange={() => { }} /> {}} + onChange={() => { }} /> @@ -75,7 +75,7 @@ export default function ListItem({ marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => {}} + onClick={() => { }} > @@ -93,7 +93,7 @@ export default function ListItem({ size="sm" value={listItem.label.is} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => {}} + onChange={() => { }} /> @@ -104,7 +104,7 @@ export default function ListItem({ size="sm" value={listItem.label.en} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => {}} + onChange={() => { }} /> @@ -181,11 +181,7 @@ export default function ListItem({ > - + @@ -250,7 +246,7 @@ export default function ListItem({ payload: { property: 'label', lang: 'en', - value: translation, + value: translation.translations[0].translatedText, listItemGuid: listItem.guid, }, }) @@ -322,7 +318,7 @@ export default function ListItem({ payload: { property: 'description', lang: 'en', - value: translation, + value: translation.translations[0].translatedText, listItemGuid: listItem.guid, }, }) @@ -333,11 +329,6 @@ export default function ListItem({ )} - {/* - - - - */} ) } diff --git a/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx b/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx index a09cb2e15515..6f2b386c1e3e 100644 --- a/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx +++ b/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx @@ -6,11 +6,13 @@ import { Box, Button, RadioButton, + Option, } from '@island.is/island-ui/core' import { Dispatch, SetStateAction, useContext, useState } from 'react' import FormBuilderContext from '../../../../context/FormBuilderContext' import { getList } from '../../../../services/apiService' import { IInput } from '../../../../types/interfaces' +import { SingleValue } from 'react-select' type Props = { setInListBuilder: Dispatch> @@ -68,9 +70,8 @@ export default function ListContent({ setInListBuilder }: Props) { label="Tilbúnir fellilistar" options={predeterminedLists} backgroundColor="blue" - onChange={async (e: { label: string; value: string }) => { - const newList = await getList(e.value) - console.log(newList) + onChange={async (e: SingleValue>) => { + const newList = e && (await getList(e.value)) listsDispatch({ type: 'setInputSettings', payload: { diff --git a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx index 394907b503cf..f952f72dfb8c 100644 --- a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx +++ b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx @@ -42,18 +42,19 @@ export default function Premises() { function handleCheckboxChange(documentTypeId: number) { const newDocumentTypes = formDocumentTypes.some( - (f) => f.id === documentTypeId, + (f) => f?.id === documentTypeId, ) - ? formDocumentTypes.filter((f) => f.id !== documentTypeId) + ? formDocumentTypes.filter((f) => f?.id !== documentTypeId) : [ - ...formDocumentTypes, - documentTypes.find((d) => d.id === documentTypeId), - ] + ...formDocumentTypes, + documentTypes.find((d) => d?.id === documentTypeId), + ].filter((d) => d !== undefined) as ICertificate[] + setFormDocumentTypes(newDocumentTypes) formDispatch({ type: 'updateDocuments', payload: { - documents: newDocumentTypes, + documents: newDocumentTypes.filter((d) => d !== undefined) as ICertificate[], }, }) } diff --git a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx index d74332da12ca..a9f64d08dc5a 100644 --- a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx @@ -16,23 +16,23 @@ import PhoneInput from './components/PhoneInput' import NumberInput from './components/NumberInput' import List from './components/List' import { IInputSettings, IInput } from '../../../../types/interfaces' -import Ssn from './components/Ssn' +import NationalId from './components/NationalId' import Radio from './components/Radio' import UtilizationSummary from './components/UtilizationSummary/UtilizationSummary' import PropertyNumber from './components/PropertyNumber/PropertyNumber' type Props = { - data?: IInput + data: IInput isLarge?: boolean inputSettings?: IInputSettings } -export default function Preview({ data, isLarge, inputSettings }: Props) { - const title = (title) => {title} +export default function Preview({ data, isLarge }: Props) { + const { inputSettings } = data + const title = (title: string) => {title} return ( <> )} {/* Kennitala */} - {data.type === 'Kennitala' && } + {data.type === 'Kennitala' && } {/* Hakbox */} {data.type === 'Hakbox' && } {/* Textalinubox */} { data.type === 'Textalínubox' && ( - // ) - // } {data.type === 'Klukkuinnsláttur' && ( @@ -82,7 +80,6 @@ export default function Preview({ data, isLarge, inputSettings }: Props) { )} {data.type === 'Krónutölubox' && ( - {/* {title(data.name.is)} */} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx index cfaf1b6c280a..c66027643cec 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx @@ -6,38 +6,44 @@ import { import { useRef, useState } from 'react' export default function Banknumber() { - const [banki, setBanki] = useState() - const [hb, setHb] = useState() - const [reikningur, setReikningur] = useState() + const [banki, setBanki] = useState() + const [hb, setHb] = useState() + const [reikningur, setReikningur] = useState() const inputRefs = [ useRef(), useRef(), useRef(), ] - const handleChange = (index: number, value) => { + const handleChange = (index: number, value: string) => { if (index === 0) { setBanki(value) if (value.length === 4) { - inputRefs[1]?.current.focus() + if (inputRefs[1]?.current) { + inputRefs[1]?.current.focus() + } } } else if (index === 1) { setHb(value) if (value.length === 2) { - inputRefs[2]?.current.focus() + if (inputRefs[2]?.current) { + inputRefs[2]?.current.focus() + } } } else if (index === 2) { if (value.length <= 6) { setReikningur(value) } if (value.length === 6) { - inputRefs[2]?.current.blur() + if (inputRefs[2]?.current) { + inputRefs[2]?.current.blur() + } } } } - const addLeadingZeros = (originalNumber, total) => { - const zerosToAdd = total - originalNumber.length + const addLeadingZeros = (originalNumber: string, max: number) => { + const zerosToAdd = max - originalNumber.length if (zerosToAdd <= 0) { return originalNumber } @@ -52,19 +58,27 @@ export default function Banknumber() { + } label="Banki" type="number" value={banki} maxLength={4} name="" - onChange={(e) => handleChange(0, e.target.value)} + onChange={(e) => console.log(typeof e.target.value)} //handleChange(0, e.target.value)} onBlur={(e) => setBanki(addLeadingZeros(e.target.value, 4))} /> + } label="Hb" maxLength={2} type="number" @@ -76,7 +90,11 @@ export default function Banknumber() { + } label="Reikningsnúmer" type="number" value={reikningur} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx index 02d283c0c5b0..e1b9743587f3 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx @@ -3,11 +3,17 @@ import { GridColumn as Column, Input, } from '@island.is/island-ui/core' -import { useState } from 'react' +import { ChangeEvent, useState } from 'react' -export default function Currency({ label }) { +interface Props { + label: string +} + +export default function Currency({ label }: Props) { const [currency, setCurrency] = useState('') - const handleCurrencyChange = (e) => { + const handleCurrencyChange = ( + e: ChangeEvent, + ) => { // Remove any non-digit characters from the input value const inputValue = e.target.value.replace(/\D/g, '') diff --git a/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx b/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx index 0e34577b0ca2..fa972769d3b8 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx @@ -8,12 +8,6 @@ import { uuid } from 'uuidv4' import * as fileTypes from '../../../../../lib/fileTypes.json' import { IInput } from '../../../../../types/interfaces' -// enum ActionTypes { -// add = 'add', -// remove = 'remove', -// update = 'update', -// } - type Props = { currentItem: IInput } @@ -22,54 +16,6 @@ export default function FileUpload({ currentItem }: Props) { const [error, setError] = useState(undefined) const [fileList, setFileList] = useState>([]) - // const uploadFile = async (file: UploadFile, response) => { - // return new Promise((resolve, reject) => { - // const request = new XMLHttpRequest() - // // request.withCredentials = true - // // request.responseType = 'json' - - // request.upload.addEventListener('progress', (event) => { - // if (event.lengthComputable) { - // file.percent = (event.loaded / event.total) * 100 - // file.status = 'uploading' - - // const withoutThisFile = fileList.filter((f) => f.key !== file.key) - // const newFileList = [...withoutThisFile, file] - // setFileList(newFileList) - // } - // }) - - // request.upload.addEventListener('error', () => { - // file.percent = 0 - // file.status = 'error' - - // const withoutThisFile = fileList.filter((f) => f.key !== file.key) - // const newFileList = [...withoutThisFile, file] - // setFileList(newFileList) - // reject() - // }) - // request.open('POST', response.url) - - // const formData = new FormData() - - // Object.keys(response.fields).forEach((key) => - // formData.append(key, response.fields[key]), - // ) - // formData.append('file', file.originalFileObj as File) - - // request.setRequestHeader('x-amz-acl', 'bucket-owner-full-control') - - // request.onload = () => { - // resolve(request.response) - // } - - // request.onerror = () => { - // reject() - // } - // request.send(formData) - // }) - // } - const onChange = (files: File[]) => { const uploadFiles = files.map((file) => fileToObject(file)) const uploadFilesWithKey = uploadFiles.map((f) => ({ @@ -78,10 +24,8 @@ export default function FileUpload({ currentItem }: Props) { })) // Check whether upload will exceed limit and if so, prevent it - if ( - fileList.length + uploadFilesWithKey.length > - currentItem.inputSettings.fjoldi - ) { + const currentAmount = currentItem.inputSettings.fjoldi ?? 0 + if (fileList.length + uploadFilesWithKey.length > currentAmount) { setError(`Hámarksfjöldi skjala er ${currentItem.inputSettings.fjoldi}`) return } @@ -108,7 +52,11 @@ export default function FileUpload({ currentItem }: Props) { onChange={onChange} onRemove={onRemove} errorMessage={fileList.length > 0 ? error : undefined} - accept={currentItem.inputSettings.tegundir.map((t) => fileTypes[t])} + accept={ + currentItem.inputSettings.tegundir?.map( + (t) => fileTypes[t as keyof typeof fileTypes], + ) ?? [] + } showFileSize maxSize={currentItem.inputSettings.hamarksstaerd} multiple={currentItem.inputSettings.erFjolval} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/List.tsx b/apps/form-builder/components/MainContent/components/Preview/components/List.tsx index abc77985f0ec..a5cdf3497d6a 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/List.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/List.tsx @@ -14,8 +14,9 @@ type ListItem = { export default function List({ currentItem }: Props) { const [listItems, setListItems] = useState([]) useEffect(() => { + const currentList = currentItem.inputSettings.listi ?? [] setListItems( - currentItem.inputSettings.listi.map((l) => ({ + currentList.map((l) => ({ label: l.label.is, value: l.label.is, })), diff --git a/apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx b/apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx index 53321d6a2b04..b9a01b9b8b5d 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx @@ -1,6 +1,4 @@ import { Box, Button, Text } from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' import { ILanguage, IInput } from '../../../../../types/interfaces' interface Props { @@ -13,9 +11,6 @@ interface Props { } export function MessageWithLinkButton({ settings, data }: Props) { - const { lists } = useContext(FormBuilderContext) - const { activeItem } = lists - console.log(activeItem) return ( + + listsDispatch({ + type: 'setMultiSet', + payload: { + checked: e.target.checked, + }, + }) + } + /> - - )} + )} + + + + + + + )} ) } diff --git a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx index b7c150a5727c..151dd6e493d8 100644 --- a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -12,8 +12,7 @@ import LayoutContext from '../../../../context/LayoutContext' import { saveFormSettings } from '../../../../services/apiService' export default function BaseSettings() { - const { formBuilder, formDispatch } = - useContext(FormBuilderContext) + const { formBuilder, formDispatch } = useContext(FormBuilderContext) const { infoDispatch } = useContext(LayoutContext) const [focus, setFocus] = useState('') const { @@ -46,8 +45,8 @@ export default function BaseSettings() { infoDispatch({ type: 'changeApplicationName', payload: { - value: e.target.value - } + value: e.target.value, + }, }) }} /> @@ -103,7 +102,11 @@ export default function BaseSettings() { label="Umsóknarfrestur" placeholderText="Veldu dagsetningu" backgroundColor="blue" - selected={formBuilder.form.invalidationDate ? new Date(formBuilder.form.invalidationDate) : null} + selected={ + formBuilder.form.invalidationDate + ? new Date(formBuilder.form.invalidationDate) + : null + } handleChange={(e) => { formDispatch({ type: 'invalidationDate', diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx index 3c709c5974f4..a48b70df5d47 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -61,13 +61,15 @@ export default function BaseInput() { name="name" value={currentItem.name.is} backgroundColor="blue" - onChange={(e) => listsDispatch({ - type: 'changeName', - payload: { - lang: 'is', - newValue: e.target.value, - } - })} + onChange={(e) => + listsDispatch({ + type: 'changeName', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } onFocus={(e) => onFocus(e.target.value)} onBlur={(e) => blur(e)} /> @@ -81,13 +83,15 @@ export default function BaseInput() { name="nameEn" value={currentItem.name.en} backgroundColor="blue" - onChange={(e) => listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: e.target.value, - } - })} + onChange={(e) => + listsDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } onFocus={(e) => onFocus(e.target.value)} onBlur={(e) => blur(e)} buttons={[ diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx index c95d43eafa2f..fab2b2c45a30 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx @@ -11,8 +11,7 @@ import { IInput } from '../../../../../types/interfaces' import { translationStation } from '../../../../../services/translationStation' export default function MessageWithLink() { - const { lists, listsDispatch, onFocus, blur } = - useContext(FormBuilderContext) + const { lists, listsDispatch, onFocus, blur } = useContext(FormBuilderContext) const { activeItem } = lists const currentItem = activeItem.data as IInput const { inputSettings } = currentItem diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx index ec5a0b75fb7c..b047f8c71ed6 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx @@ -26,7 +26,7 @@ export default function TimeInput() { onChange={(e) => { listsDispatch({ type: 'timeInterval', - payload: { data: e ? e.value : '0' } + payload: { data: e ? e.value : '0' }, }) }} /> diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx index 0b7344fc3ed8..24cfa252d8b6 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx @@ -61,13 +61,13 @@ export default function ListItem({ label="Tengja" checked={connect} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> { }} + onChange={() => {}} /> @@ -75,7 +75,7 @@ export default function ListItem({ marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => { }} + onClick={() => {}} > @@ -93,7 +93,7 @@ export default function ListItem({ size="sm" value={listItem.label.is} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> @@ -104,7 +104,7 @@ export default function ListItem({ size="sm" value={listItem.label.en} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> diff --git a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx index f952f72dfb8c..0e240bbf27b1 100644 --- a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx +++ b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx @@ -45,16 +45,18 @@ export default function Premises() { (f) => f?.id === documentTypeId, ) ? formDocumentTypes.filter((f) => f?.id !== documentTypeId) - : [ - ...formDocumentTypes, - documentTypes.find((d) => d?.id === documentTypeId), - ].filter((d) => d !== undefined) as ICertificate[] + : ([ + ...formDocumentTypes, + documentTypes.find((d) => d?.id === documentTypeId), + ].filter((d) => d !== undefined) as ICertificate[]) setFormDocumentTypes(newDocumentTypes) formDispatch({ type: 'updateDocuments', payload: { - documents: newDocumentTypes.filter((d) => d !== undefined) as ICertificate[], + documents: newDocumentTypes.filter( + (d) => d !== undefined, + ) as ICertificate[], }, }) } diff --git a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx index a9f64d08dc5a..32acdabe0085 100644 --- a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx @@ -63,16 +63,14 @@ export default function Preview({ data, isLarge }: Props) { {/* Hakbox */} {data.type === 'Hakbox' && } {/* Textalinubox */} - { - data.type === 'Textalínubox' && ( - - ) - } + {data.type === 'Textalínubox' && ( + + )} {data.type === 'Klukkuinnsláttur' && ( diff --git a/apps/form-builder/components/Navbar/Navbar.tsx b/apps/form-builder/components/Navbar/Navbar.tsx index 1894b555ef30..cf7497bf04f3 100644 --- a/apps/form-builder/components/Navbar/Navbar.tsx +++ b/apps/form-builder/components/Navbar/Navbar.tsx @@ -75,8 +75,8 @@ export default function Navbar() { variant="ghost" size="small" onClick={() => { - setInSettings(false); - const step = lists.steps.find((s) => s.type === 'Innsláttur'); + setInSettings(false) + const step = lists.steps.find((s) => s.type === 'Innsláttur') if (step) { listsDispatch({ type: 'setActiveItem', @@ -84,7 +84,7 @@ export default function Navbar() { type: 'Step', data: step, }, - }); + }) } }} > @@ -209,7 +209,7 @@ export default function Navbar() { } } - type ActionType = 'removeStep' | 'removeGroup' | 'removeInput'; + type ActionType = 'removeStep' | 'removeGroup' | 'removeInput' function removeItem(type: ItemType, guid: UniqueIdentifier, id: number) { const actionTypes: Record = { @@ -221,7 +221,7 @@ export default function Navbar() { listsDispatch({ type: actionTypes[type], payload: { - guid: guid + guid: guid, }, }) deleteItem(type, id) @@ -268,7 +268,12 @@ export default function Navbar() { formUpdate() } - type DndAction = 'stepOverStep' | 'groupOverStep' | 'groupOverGroup' | 'inputOverGroup' | 'inputOverInput'; + type DndAction = + | 'stepOverStep' + | 'groupOverStep' + | 'groupOverGroup' + | 'inputOverGroup' + | 'inputOverInput' function onDragOver(event: DragOverEvent) { const { active, over } = event diff --git a/apps/form-builder/components/TableRow/TableRow.tsx b/apps/form-builder/components/TableRow/TableRow.tsx index 31f3102f1dd0..ae90e8ab818a 100644 --- a/apps/form-builder/components/TableRow/TableRow.tsx +++ b/apps/form-builder/components/TableRow/TableRow.tsx @@ -72,9 +72,7 @@ const TableRow = ({ /> - + @@ -90,7 +88,6 @@ const TableRow = ({ menuLabel={`Aðgerðir ${name}`} disclosure={ + + listsDispatch({ + type: 'setMultiSet', + payload: { + checked: e.target.checked, + }, + }) + } + /> - - )} + )} + + + + + + + )} ) } diff --git a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx index b7c150a5727c..151dd6e493d8 100644 --- a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -12,8 +12,7 @@ import LayoutContext from '../../../../context/LayoutContext' import { saveFormSettings } from '../../../../services/apiService' export default function BaseSettings() { - const { formBuilder, formDispatch } = - useContext(FormBuilderContext) + const { formBuilder, formDispatch } = useContext(FormBuilderContext) const { infoDispatch } = useContext(LayoutContext) const [focus, setFocus] = useState('') const { @@ -46,8 +45,8 @@ export default function BaseSettings() { infoDispatch({ type: 'changeApplicationName', payload: { - value: e.target.value - } + value: e.target.value, + }, }) }} /> @@ -103,7 +102,11 @@ export default function BaseSettings() { label="Umsóknarfrestur" placeholderText="Veldu dagsetningu" backgroundColor="blue" - selected={formBuilder.form.invalidationDate ? new Date(formBuilder.form.invalidationDate) : null} + selected={ + formBuilder.form.invalidationDate + ? new Date(formBuilder.form.invalidationDate) + : null + } handleChange={(e) => { formDispatch({ type: 'invalidationDate', diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx index 3c709c5974f4..2fec7e5b5292 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -5,21 +5,21 @@ import { Stack, Input, Checkbox, + Option, } from '@island.is/island-ui/core' import { useContext } from 'react' import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../types/interfaces' +import { + IInput, + IInputSettings, + IInputType, +} from '../../../../../types/interfaces' import { translationStation } from '../../../../../services/translationStation' +import { SingleValue } from 'react-select' export default function BaseInput() { - const { - formBuilder, - lists, - listsDispatch, - changeSelectHandler, - onFocus, - blur, - } = useContext(FormBuilderContext) + const { formBuilder, lists, listsDispatch, onFocus, blur } = + useContext(FormBuilderContext) const { activeItem } = lists const currentItem = activeItem.data as IInput const createAndSortOptions = formBuilder.inputTypes @@ -48,7 +48,18 @@ export default function BaseInput() { backgroundColor="blue" isSearchable value={defaultOption} - onChange={(e) => changeSelectHandler(e)} + onChange={(e: SingleValue>) => + listsDispatch({ + type: 'changeInputType', + payload: { + newValue: e?.value ?? 'Default', + inputSettings: + (formBuilder?.inputTypes?.find( + (inputType: IInputType) => inputType?.type === e?.value, + )?.inputSettings as IInputSettings) ?? {}, + }, + }) + } /> @@ -61,13 +72,15 @@ export default function BaseInput() { name="name" value={currentItem.name.is} backgroundColor="blue" - onChange={(e) => listsDispatch({ - type: 'changeName', - payload: { - lang: 'is', - newValue: e.target.value, - } - })} + onChange={(e) => + listsDispatch({ + type: 'changeName', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } onFocus={(e) => onFocus(e.target.value)} onBlur={(e) => blur(e)} /> @@ -81,13 +94,15 @@ export default function BaseInput() { name="nameEn" value={currentItem.name.en} backgroundColor="blue" - onChange={(e) => listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: e.target.value, - } - })} + onChange={(e) => + listsDispatch({ + type: 'changeName', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } onFocus={(e) => onFocus(e.target.value)} onBlur={(e) => blur(e)} buttons={[ diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx index c95d43eafa2f..fab2b2c45a30 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx @@ -11,8 +11,7 @@ import { IInput } from '../../../../../types/interfaces' import { translationStation } from '../../../../../services/translationStation' export default function MessageWithLink() { - const { lists, listsDispatch, onFocus, blur } = - useContext(FormBuilderContext) + const { lists, listsDispatch, onFocus, blur } = useContext(FormBuilderContext) const { activeItem } = lists const currentItem = activeItem.data as IInput const { inputSettings } = currentItem diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx index ec5a0b75fb7c..b047f8c71ed6 100644 --- a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx +++ b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx @@ -26,7 +26,7 @@ export default function TimeInput() { onChange={(e) => { listsDispatch({ type: 'timeInterval', - payload: { data: e ? e.value : '0' } + payload: { data: e ? e.value : '0' }, }) }} /> diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx index 0b7344fc3ed8..24cfa252d8b6 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx @@ -61,13 +61,13 @@ export default function ListItem({ label="Tengja" checked={connect} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> { }} + onChange={() => {}} /> @@ -75,7 +75,7 @@ export default function ListItem({ marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => { }} + onClick={() => {}} > @@ -93,7 +93,7 @@ export default function ListItem({ size="sm" value={listItem.label.is} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> @@ -104,7 +104,7 @@ export default function ListItem({ size="sm" value={listItem.label.en} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> diff --git a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx index f952f72dfb8c..0e240bbf27b1 100644 --- a/apps/form-builder/components/MainContent/components/Premises/Premises.tsx +++ b/apps/form-builder/components/MainContent/components/Premises/Premises.tsx @@ -45,16 +45,18 @@ export default function Premises() { (f) => f?.id === documentTypeId, ) ? formDocumentTypes.filter((f) => f?.id !== documentTypeId) - : [ - ...formDocumentTypes, - documentTypes.find((d) => d?.id === documentTypeId), - ].filter((d) => d !== undefined) as ICertificate[] + : ([ + ...formDocumentTypes, + documentTypes.find((d) => d?.id === documentTypeId), + ].filter((d) => d !== undefined) as ICertificate[]) setFormDocumentTypes(newDocumentTypes) formDispatch({ type: 'updateDocuments', payload: { - documents: newDocumentTypes.filter((d) => d !== undefined) as ICertificate[], + documents: newDocumentTypes.filter( + (d) => d !== undefined, + ) as ICertificate[], }, }) } diff --git a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx index a9f64d08dc5a..32acdabe0085 100644 --- a/apps/form-builder/components/MainContent/components/Preview/Preview.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/Preview.tsx @@ -63,16 +63,14 @@ export default function Preview({ data, isLarge }: Props) { {/* Hakbox */} {data.type === 'Hakbox' && } {/* Textalinubox */} - { - data.type === 'Textalínubox' && ( - - ) - } + {data.type === 'Textalínubox' && ( + + )} {data.type === 'Klukkuinnsláttur' && ( diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx index c66027643cec..f2e49d1954fd 100644 --- a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx +++ b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx @@ -68,7 +68,7 @@ export default function Banknumber() { value={banki} maxLength={4} name="" - onChange={(e) => console.log(typeof e.target.value)} //handleChange(0, e.target.value)} + onChange={(e) => handleChange(0, e.target.value)} onBlur={(e) => setBanki(addLeadingZeros(e.target.value, 4))} /> diff --git a/apps/form-builder/components/Navbar/Navbar.tsx b/apps/form-builder/components/Navbar/Navbar.tsx index 1894b555ef30..cf7497bf04f3 100644 --- a/apps/form-builder/components/Navbar/Navbar.tsx +++ b/apps/form-builder/components/Navbar/Navbar.tsx @@ -75,8 +75,8 @@ export default function Navbar() { variant="ghost" size="small" onClick={() => { - setInSettings(false); - const step = lists.steps.find((s) => s.type === 'Innsláttur'); + setInSettings(false) + const step = lists.steps.find((s) => s.type === 'Innsláttur') if (step) { listsDispatch({ type: 'setActiveItem', @@ -84,7 +84,7 @@ export default function Navbar() { type: 'Step', data: step, }, - }); + }) } }} > @@ -209,7 +209,7 @@ export default function Navbar() { } } - type ActionType = 'removeStep' | 'removeGroup' | 'removeInput'; + type ActionType = 'removeStep' | 'removeGroup' | 'removeInput' function removeItem(type: ItemType, guid: UniqueIdentifier, id: number) { const actionTypes: Record = { @@ -221,7 +221,7 @@ export default function Navbar() { listsDispatch({ type: actionTypes[type], payload: { - guid: guid + guid: guid, }, }) deleteItem(type, id) @@ -268,7 +268,12 @@ export default function Navbar() { formUpdate() } - type DndAction = 'stepOverStep' | 'groupOverStep' | 'groupOverGroup' | 'inputOverGroup' | 'inputOverInput'; + type DndAction = + | 'stepOverStep' + | 'groupOverStep' + | 'groupOverGroup' + | 'inputOverGroup' + | 'inputOverInput' function onDragOver(event: DragOverEvent) { const { active, over } = event diff --git a/apps/form-builder/components/TableRow/TableRow.tsx b/apps/form-builder/components/TableRow/TableRow.tsx index 31f3102f1dd0..ae90e8ab818a 100644 --- a/apps/form-builder/components/TableRow/TableRow.tsx +++ b/apps/form-builder/components/TableRow/TableRow.tsx @@ -72,9 +72,7 @@ const TableRow = ({ /> - + @@ -90,7 +88,6 @@ const TableRow = ({ menuLabel={`Aðgerðir ${name}`} disclosure={ + + + + - return ( - <> - ) + + + + + + {formBuilder.forms && + formBuilder.forms?.map((f) => { + return ( + + ) + })} + + ) + } + return <> } export default Forms diff --git a/libs/portals/admin/form-system/src/types/enums/index.tsx b/libs/portals/admin/form-system/src/types/enums/index.tsx new file mode 100644 index 000000000000..fadfab2e4e4a --- /dev/null +++ b/libs/portals/admin/form-system/src/types/enums/index.tsx @@ -0,0 +1,100 @@ +export enum ApplicationTemplateStatus { + Þýðing = -2, + Kerfi = -1, + Óútgefið = 0, + Útgefið = 2, + tekiðÚrNotkun = 4, +} + +export enum LicenseProviderEnum { + sýslumannsembættið = 1, + leyfisveitanEhf = 2, + leyfisveitanEhf2 = 9, + þjóðskráÍslands = 3, + ferðamálastofa = 4, + ferðamálastofa2 = 52, + menntamálastofnun = 5, + hallaBjörgBaldursdóttir = 6, + fiskistofa = 7, + officeOfDistrictMagistrate = 8, + registersIceland = 10, + icelandicTouristBoard = 11, + directorateOfEducation = 12, + hallaBjorgBaldursdottir = 13, + directorateOfFisheries = 14, + fjármálaOgEfnahagsráðuneytið = 15, + ministryOfFinanceAndEconomicAffairs = 16, + ríkisskattstjóri = 17, + ríkiskaup = 18, + sýslumaðurinnÁHöfuðborgarsvæðinu = 19, + sýslumaðurinnÁHöfuðborgarsvæðinu2 = 50, + theDistrictMagistrateCapitalRegion = 20, + centralPublicProcurement = 21, + directorateOfInternalRevenue = 22, + sýslumaðurinnÁVestfjörðum = 23, + theDistrictMagistrateWestfjords = 24, + útlendingastofnun = 37, + útlendingastofnun2 = 49, + icelandicDirectorateOfImmigration = 38, + utanríkisráðuneytið = 39, + ministryForForeignAffairs = 40, + ríkislögreglustjóri = 41, + ríkislögreglustjóri2 = 71, + sjúkratryggingarÍslands = 42, + sjúkratryggingarÍslands2 = 51, + þjóðskjalasafnÍslands = 43, + þjóðskjalasafnÍslands2 = 44, + sýslumenn = 53, + fjölskylduOgHúsdýragarðurinn = 59, + menntamálastofnun2 = 61, + umhverfisstofnun = 62, + héraðsdómurReykjavíkur = 63, + minjastofnunÍslands = 64, + náttúruhamfaratryggingarÍslands = 65, +} + +export enum FileTypeEnum { + PDF, + Image, + Xls, + ALL, +} + +export enum EInputType { + Textalínubox = 1, + TextaboxStórt = 2, + Tölustafir = 3, + Textalýsing = 4, + Hakbox = 5, + Dagssetning = 6, + Fellilisti = 7, + Valhnappar = 8, + Heimagistingarnúmer = 9, + FasteignanúmerInnslegið = 10, + FasteignanúmerValiðÚrLista = 11, + Bankareikningsnúmer = 13, + Kennitala = 14, + Greiðandi = 15, + Krónutala = 16, + Krónutölusamtala = 17, + Netfang = 18, + Símanúmer = 19, + FalinnStrengur = 20, + Tími = 21, + Sveitarfélög = 22, + Landalisti = 23, + Póstnúmer = 24, + KennitalaDánarbús = 25, + KennitalaAllt = 26, + Vottorð = 28, + Aðili = 29, +} + +export enum EFormApplicantTypes { + einstaklingur = 'Einstaklingur', + einstaklingurMedUmbodAnnarsEinstaklings = 'Einstaklingur_með_umboð_annars_einstaklings', + einstaklingurMedUmbodLogadila = 'Einstaklingur_með_umboð_lögaðila', + einstaklingurMedProkuru = 'Einstaklingur_með_prókúru', + einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', + logadili = 'Lögaðili', +} diff --git a/libs/portals/admin/form-system/src/types/interfaces.tsx b/libs/portals/admin/form-system/src/types/interfaces.tsx new file mode 100644 index 000000000000..891c44c723ad --- /dev/null +++ b/libs/portals/admin/form-system/src/types/interfaces.tsx @@ -0,0 +1,253 @@ +import { Dispatch, SetStateAction, FocusEvent } from 'react' +import { UniqueIdentifier } from '@dnd-kit/core' +import { EFormApplicantTypes } from './enums' +import { Action as ListsAction } from '../hooks/listsReducer' +import { FormAction } from '../hooks/formReducer' +import { FormHeaderAction } from '../hooks/headerInfoReducer' + +export type IFormBuilderContext = { + formBuilder: IFormBuilder + formDispatch: Dispatch + lists: { + activeItem: ActiveItem + steps: IStep[] + groups: IGroup[] + inputs: IInput[] + } + listsDispatch: Dispatch + formUpdate: () => Promise + inSettings: boolean + setInSettings: Dispatch> + setSelectStatus: Dispatch> + selectStatus: NavbarSelectStatus + activeListItem?: IListItem | null + setActiveListItem: Dispatch> + blur(e: FocusEvent): void + onFocus(e: string): void +} + +export interface IInputSettings { + $type?: string + isLarge?: boolean + size?: Sizes + interval?: string + erHlekkur?: boolean + url?: string + hnapptexti?: ILanguage + tegundir?: string[] + hamarksstaerd?: number + erFjolval?: boolean + fjoldi?: number + header?: string + hamarkslengd?: number + lagmarkslengd?: number + laggildi?: number + hagildi?: number + listi?: IListItem[] + type?: string + name?: ILanguage + erListi?: boolean + erInnslattur?: boolean + [key: string]: unknown +} + +export interface IForm { + id: number + name: ILanguage + created: Date + lastChanged: Date + organization: { + id: number + name: ILanguage + kennitala: string + scope: string + xroadBaseUrl: string + } + dependencies: ITenging + stepsList: IStep[] + groupsList: IGroup[] + inputsList: IInput[] + stopProgressOnValidatingStep: boolean + applicationsDaysToRemove: number + invalidationDate?: Date + isTranslated: boolean + documentTypes: ICertificate[] + formApplicantTypes: IFormApplicantType[] +} + +export interface IStep { + id: number + guid: UniqueIdentifier + displayOrder: number + name: ILanguage + type: string + waitingText: ILanguage + callRuleset: boolean + isHidden: boolean + isCompleted: boolean + groups: IGroup[] +} + +export interface IGroup { + id: number + name: ILanguage + guid: UniqueIdentifier + displayOrder: number + isHidden: boolean + multiSet: number + stepId: number + stepGuid: UniqueIdentifier + inputs?: IInput[] +} + +export interface IInput { + id: number + name: ILanguage + description: ILanguage + isRequired: boolean + displayOrder: number + groupId: number + groupGuid: UniqueIdentifier + isHidden: boolean + type: string + guid: UniqueIdentifier + inputFields: object + inputSettings: IInputSettings + isPartOfMultiSet: boolean +} + +export type ILists = { + activeItem: ActiveItem + steps: IStep[] + groups: IGroup[] + inputs: IInput[] + [key: string]: unknown +} + +export interface ActiveItem { + type: ItemType + data: IStep | IGroup | IInput +} + +export interface ISelectOption { + label: string | number + value: string | number +} + +export interface ITenging { + [key: string]: string[] +} + +export interface IFormBuilder { + form: IForm + forms?: IForm[] | null + documentTypes: ICertificate[] + inputTypes: IInputType[] + applicantTypes: IApplicantType[] + listTypes: IListType[] +} + +export interface IListType { + id: number + type: string + name: ILanguage + description: ILanguage +} + +export interface IListItem { + guid: UniqueIdentifier + label: ILanguage + description: ILanguage + displayOrder: number + isSelected: boolean +} + +export interface ICertificate { + id: number + type: string + name: ILanguage + description: ILanguage +} + +export interface IApplicantType { + id: number + name: ILanguage + type: EFormApplicantTypes + nameSuggestions: { + applicantTypeId: number + nameSuggestion: ILanguage + }[] +} + +export type IFormApplicantType = { + formId: number + applicantTypeId: number + name: ILanguage + type: EFormApplicantTypes +} + +export interface IFormDocumentType { + formId: number + documentTypeId: number +} + +export interface IInputType { + type: string + name: string + description: string + organizations?: [] + inputFields?: object + inputMetadata?: object + ruleset?: object + inputSettings: object +} + +export interface ILayoutContext { + info: { + organization: string + applicationName: string + } + infoDispatch: React.Dispatch +} + +export interface ILicenseProvider { + licenseProviderID: number + kennitala: string + name: string + email: string + phone: string + enabled: boolean + parentId?: number + language: string +} + +export interface ITranslationResponse { + translations: ITranslation[] + sourceLanguageCode: string + targetLanguageCode: string + model: string +} + +export interface ITranslation { + translatedText: string + translatedTextStructured: [string, string][] +} +export enum NavbarSelectStatus { + OFF = 'Off', + NORMAL = 'Normal', + LIST_ITEM = 'ListItem', + ON_WITHOUT_SELECT = 'OnWithoutSelect', +} + +export type ItemType = 'Step' | 'Group' | 'Input' + +export type ILanguage = { + is: string + en: string +} +export interface User { + name?: string + email?: string + image?: string +} +type Sizes = 'xs' | 'sm' | 'md' diff --git a/libs/portals/admin/form-system/src/utils/defaultStep.tsx b/libs/portals/admin/form-system/src/utils/defaultStep.tsx new file mode 100644 index 000000000000..6130a25964f1 --- /dev/null +++ b/libs/portals/admin/form-system/src/utils/defaultStep.tsx @@ -0,0 +1,20 @@ +import { uuid } from 'uuidv4' +import { IStep } from '../types/interfaces' + +export const defaultStep: IStep = { + id: 0, + guid: uuid(), + displayOrder: 0, + name: { + is: '', + en: '', + }, + type: 'Innsláttur', + waitingText: { + is: '', + en: '', + }, + callRuleset: false, + isHidden: false, + isCompleted: false, +} diff --git a/libs/portals/admin/form-system/src/utils/formatDate.tsx b/libs/portals/admin/form-system/src/utils/formatDate.tsx new file mode 100644 index 000000000000..7b16496029e6 --- /dev/null +++ b/libs/portals/admin/form-system/src/utils/formatDate.tsx @@ -0,0 +1,8 @@ +export const formatDate = (date: Date) => { + const newDate = new Date(date) + const day = newDate.getDate().toString().padStart(2, '0') + const month = (newDate.getMonth() + 1).toString().padStart(2, '0') + const year = newDate.getFullYear() + + return `${day}.${month}.${year}` //${hours}:${minutes}`; +} diff --git a/libs/portals/admin/form-system/src/utils/getBaseSettingsStep.tsx b/libs/portals/admin/form-system/src/utils/getBaseSettingsStep.tsx new file mode 100644 index 000000000000..12844cbd9dbc --- /dev/null +++ b/libs/portals/admin/form-system/src/utils/getBaseSettingsStep.tsx @@ -0,0 +1,20 @@ +import { uuid } from 'uuidv4' + +export const baseSettingsStep = { + id: 99999, + guid: uuid(), + displayOrder: -1, + name: { + is: 'Grunnstillingar', + en: 'Base settings', + }, + type: 'BaseSetting', + waitingText: { + is: '', + en: '', + }, + callRuleset: false, + isHidden: false, + isCompleted: false, + groups: [], +} From 323ad383f4ff27139a0d2b45a8d354d0eb229ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A6var=20M=C3=A1r=20Atlason?= Date: Tue, 12 Mar 2024 23:23:50 +0000 Subject: [PATCH 21/72] Fixng typing erros in form system graphql domain --- .../src/models/externalEndpoints.model.ts | 17 +++++++---- .../form-system/src/models/form.model.ts | 19 ++++++------ .../src/models/formResponse.model.ts | 21 +++++++------ .../form-system/src/models/input.model.ts | 5 ++-- .../src/models/inputSettings.model.ts | 10 +++---- .../src/models/organization.model.ts | 30 +++++++++---------- 6 files changed, 53 insertions(+), 49 deletions(-) diff --git a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts index 7d92268d8f30..2983385e2d6f 100644 --- a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts +++ b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts @@ -1,15 +1,22 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; +import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql' enum Type { - SUBMIT = 'submit', - VALIDATION = 'validation', + submit = 'submit', + validation = 'validation', } +registerEnumType(Type, { + name: 'FormSystemType', +}) + enum Environment { - PRODUCTION = 'production', - DEVELOPMENT = 'development', + production = 'production', + development = 'development', } +registerEnumType(Environment, { + name: 'FormSystemEnvironment', +}) @ObjectType('FormSystemExternalEndpoints') export class ExternalEndpoints { diff --git a/libs/api/domains/form-system/src/models/form.model.ts b/libs/api/domains/form-system/src/models/form.model.ts index 84398df3d212..ef2e825e5014 100644 --- a/libs/api/domains/form-system/src/models/form.model.ts +++ b/libs/api/domains/form-system/src/models/form.model.ts @@ -1,12 +1,11 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; -import { ApplicantType } from "./applicantType.model"; -import { Group } from "./group.model"; -import { Input } from "./input.model"; -import { Step } from "./step.model"; -import { Organization } from "./organization.model"; -import { DocumentType } from "./documentType.model"; - +import { Field, ID, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' +import { ApplicantType } from './applicantType.model' +import { Group } from './group.model' +import { Input } from './input.model' +import { Step } from './step.model' +import { Organization } from './organization.model' +import { DocumentType } from './documentType.model' export type Dependencies = { [key: string]: string[] @@ -38,7 +37,7 @@ export class Form { @Field(() => DocumentType, { nullable: true }) documentTypes?: DocumentType[] | null - @Field(() => [ApplicantType], { nullable: true }) + @Field(() => [ApplicantType]) formApplicantTypes?: ApplicantType[] | null @Field(() => LanguageType, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/formResponse.model.ts b/libs/api/domains/form-system/src/models/formResponse.model.ts index 9a02bac8b81d..de9c294e955d 100644 --- a/libs/api/domains/form-system/src/models/formResponse.model.ts +++ b/libs/api/domains/form-system/src/models/formResponse.model.ts @@ -1,26 +1,25 @@ -import { Field, ObjectType } from "@nestjs/graphql"; -import { Form } from "./form.model"; -import { DocumentType } from "./documentType.model"; -import { Input } from "./input.model"; -import { ApplicantType } from "./applicantType.model"; -import { ListType } from "./listType.model"; +import { Field, ObjectType } from '@nestjs/graphql' +import { Form } from './form.model' +import { DocumentType } from './documentType.model' +import { Input } from './input.model' +import { ApplicantType } from './applicantType.model' +import { ListType } from './listType.model' import { DocumentTypeDto } from '@island.is/clients/form-system' - @ObjectType('FormSystemFormResponse') export class FormResponse { @Field(() => Form, { nullable: true }) form?: Form - @Field(() => [DocumentType], { nullable: true }) + @Field(() => [DocumentType]) documentTypes?: DocumentType[] | null - @Field(() => [Input], { nullable: true }) + @Field(() => [Input]) inputTypes?: Input[] | null - @Field(() => [ApplicantType], { nullable: true }) + @Field(() => [ApplicantType]) applicantTypes?: ApplicantType[] | null - @Field(() => [ListType], { nullable: true }) + @Field(() => [ListType]) listTypes?: ListType[] | null } diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index 585e2ba9d42a..0281dfcbccc0 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -1,4 +1,6 @@ import { Field, ID, ObjectType } from '@nestjs/graphql' +import graphqlTypeJson from 'graphql-type-json' + import { InputSettings } from './inputSettings.model' import { LanguageType } from './global.model' @@ -40,7 +42,7 @@ export class Input { @Field(() => InputSettings, { nullable: true }) inputSettings?: InputSettings - @Field(() => Object, { nullable: true }) + @Field(() => graphqlTypeJson, { nullable: true }) inputFields?: object } @@ -82,4 +84,3 @@ export class UpdateInput { @Field(() => Boolean, { nullable: true }) isPartOfMultiSet?: boolean } - diff --git a/libs/api/domains/form-system/src/models/inputSettings.model.ts b/libs/api/domains/form-system/src/models/inputSettings.model.ts index f92eeec414cd..59d21b0bb9a1 100644 --- a/libs/api/domains/form-system/src/models/inputSettings.model.ts +++ b/libs/api/domains/form-system/src/models/inputSettings.model.ts @@ -1,7 +1,7 @@ -import { ObjectType, Field } from "@nestjs/graphql" -import { LanguageType } from "./global.model" +import { ObjectType, Field } from '@nestjs/graphql' +import { LanguageType } from './global.model' -ObjectType('FormSystemListItem') +@ObjectType('FormSystemListItem') export class ListItem { @Field(() => String, { nullable: true }) guid?: string @@ -24,8 +24,8 @@ export class ListItem { @ObjectType('FormSystemInputSettings') export class InputSettings { - @Field(() => String, { nullable: true }) - $type?: string + // @Field(() => String, { nullable: true }) + // $type?: string @Field(() => Boolean, { nullable: true }) isLarge?: boolean diff --git a/libs/api/domains/form-system/src/models/organization.model.ts b/libs/api/domains/form-system/src/models/organization.model.ts index f920c8296ec4..34209e1a2b9a 100644 --- a/libs/api/domains/form-system/src/models/organization.model.ts +++ b/libs/api/domains/form-system/src/models/organization.model.ts @@ -1,13 +1,11 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; -import { Input } from "./input.model"; -import { ApplicantType } from "./applicantType.model"; -import { ListType } from "./listType.model"; -import { ExternalEndpoints } from "./externalEndpoints.model"; -import { DocumentType } from "./documentType.model"; -import { Form } from "./form.model"; - - +import { Field, ID, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' +import { Input } from './input.model' +import { ApplicantType } from './applicantType.model' +import { ListType } from './listType.model' +import { ExternalEndpoints } from './externalEndpoints.model' +import { DocumentType } from './documentType.model' +import { Form } from './form.model' @ObjectType('FormSystemOrganization') export class Organization { @@ -20,22 +18,22 @@ export class Organization { @Field(() => String, { nullable: true }) nationalId?: string | null - @Field(() => [Input], { nullable: true }) + @Field(() => [Input]) inputTypes?: Input[] | null - @Field(() => [DocumentType], { nullable: true }) + @Field(() => [DocumentType]) documentTypes?: DocumentType[] | null - @Field(() => [ApplicantType], { nullable: true }) + @Field(() => [ApplicantType]) applicantTypes?: ApplicantType[] | null - @Field(() => [ListType], { nullable: true }) + @Field(() => [ListType]) listTypes?: ListType[] | null - @Field(() => [Form], { nullable: true }) + @Field(() => [Form]) forms?: Form[] | null - @Field(() => [ExternalEndpoints], { nullable: true }) + @Field(() => [ExternalEndpoints]) externalEndpoints?: ExternalEndpoints[] | null } From 61a8469bd16173aac125c2e996d1973af2238f40 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Wed, 13 Mar 2024 15:09:55 +0000 Subject: [PATCH 22/72] Added another Object type and a bunch of inputTypes in order for codegen to work --- .../src/dto/applicantType.input.ts | 41 ++++++++ .../dto/applicantTypeNameSuggestion.input.ts | 11 +++ .../form-system/src/dto/documentType.input.ts | 19 ++++ .../src/dto/externalEndpoints.input.ts | 25 +++++ .../form-system/src/dto/forms.input.ts | 69 ++++++++++++- .../form-system/src/dto/global.input.ts | 10 ++ .../form-system/src/dto/groups.input.ts | 62 +++++++++++- .../src/dto/inputSettings.input.ts | 67 +++++++++++++ .../form-system/src/dto/inputs.input.ts | 98 +++++++++++++++++-- .../form-system/src/dto/listItem.input.ts | 23 +++++ .../form-system/src/dto/listType.input.ts | 17 ++++ .../form-system/src/dto/organization.input.ts | 52 +++++++++- .../form-system/src/dto/steps.input.ts | 67 ++++++++++++- .../src/lib/forms/forms.service.ts | 5 +- .../organizations/organizations.services.ts | 18 +--- .../src/models/applicantType.model.ts | 4 +- .../src/models/applicantTypeNameSuggestion.ts | 2 +- .../src/models/externalEndpoints.model.ts | 29 ++---- .../form-system/src/models/form.model.ts | 27 ++--- .../src/models/formApplicantType.model.ts | 18 ++++ .../src/models/formListResponse.model.ts | 2 +- .../src/models/formResponse.model.ts | 9 +- .../form-system/src/models/group.model.ts | 32 +----- .../form-system/src/models/input.model.ts | 45 +-------- .../form-system/src/models/listType.model.ts | 4 +- .../src/models/organization.model.ts | 19 ++-- .../form-system/src/models/services.model.ts | 2 +- .../form-system/src/models/step.model.ts | 35 +------ 28 files changed, 616 insertions(+), 196 deletions(-) create mode 100644 libs/api/domains/form-system/src/dto/applicantType.input.ts create mode 100644 libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts create mode 100644 libs/api/domains/form-system/src/dto/documentType.input.ts create mode 100644 libs/api/domains/form-system/src/dto/externalEndpoints.input.ts create mode 100644 libs/api/domains/form-system/src/dto/global.input.ts create mode 100644 libs/api/domains/form-system/src/dto/inputSettings.input.ts create mode 100644 libs/api/domains/form-system/src/dto/listItem.input.ts create mode 100644 libs/api/domains/form-system/src/dto/listType.input.ts create mode 100644 libs/api/domains/form-system/src/models/formApplicantType.model.ts diff --git a/libs/api/domains/form-system/src/dto/applicantType.input.ts b/libs/api/domains/form-system/src/dto/applicantType.input.ts new file mode 100644 index 000000000000..b1c2d46c759d --- /dev/null +++ b/libs/api/domains/form-system/src/dto/applicantType.input.ts @@ -0,0 +1,41 @@ +import { Field, InputType } from "@nestjs/graphql"; +import { LanguageTypeInput } from "./global.input"; +import { ApplicantTypeNameSuggestionInput } from "./applicantTypeNameSuggestion.input"; + + +@InputType('FormSystemApplicantTypeInput') +export class ApplicantTypeInput { + @Field(() => Number, { nullable: true }) + id?: number + + @Field(() => Number, { nullable: true }) + applicantTypeId?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => ApplicantTypeNameSuggestionInput, { nullable: true }) + nameSuggestion?: ApplicantTypeNameSuggestionInput +} + +@InputType('FormSystemFormApplicantTypeInput') +export class FormApplicantTypeInput { + @Field(() => Number, { nullable: true }) + formId?: number + + @Field(() => Number, { nullable: true }) + applicantTypeId?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String) + type?: string | null +} + diff --git a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts new file mode 100644 index 000000000000..626bee98d348 --- /dev/null +++ b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts @@ -0,0 +1,11 @@ +import { InputType, Field } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" + +@InputType('FormSystemApplicantTypeNameSuggestionInput') +export class ApplicantTypeNameSuggestionInput { + @Field(() => LanguageTypeInput, { nullable: true }) + nameSuggestion?: LanguageTypeInput + + @Field(() => Number, { nullable: true }) + applicantTypeId?: number +} diff --git a/libs/api/domains/form-system/src/dto/documentType.input.ts b/libs/api/domains/form-system/src/dto/documentType.input.ts new file mode 100644 index 000000000000..742fd4a1aa5b --- /dev/null +++ b/libs/api/domains/form-system/src/dto/documentType.input.ts @@ -0,0 +1,19 @@ +import { Field, ID, InputType } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" + + + +@InputType('FormSystemDocumentTypeInput') +export class DocumentTypeInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput +} diff --git a/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts new file mode 100644 index 000000000000..34dd0c34381d --- /dev/null +++ b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts @@ -0,0 +1,25 @@ +import { Field, ID, InputType, registerEnumType } from '@nestjs/graphql' +import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' + +registerEnumType(EExternalEndpointType, { + name: 'FormSystemExternalEndpointType', +}) + +registerEnumType(EExternalEndpointEnvironment, { + name: 'FormSystemExternalEndpointEnvironment', +}) + +@InputType('FormSystemExternalEndpointsInput') +export class ExternalEndpointsInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => String, { nullable: true }) + url?: string | null + + @Field(() => EExternalEndpointType) + type?: EExternalEndpointType + + @Field(() => EExternalEndpointEnvironment, { nullable: true }) + environment?: EExternalEndpointEnvironment +} diff --git a/libs/api/domains/form-system/src/dto/forms.input.ts b/libs/api/domains/form-system/src/dto/forms.input.ts index e228767d9ef2..19d7971e995d 100644 --- a/libs/api/domains/form-system/src/dto/forms.input.ts +++ b/libs/api/domains/form-system/src/dto/forms.input.ts @@ -1,5 +1,12 @@ -import { Field, InputType, Int } from "@nestjs/graphql"; -import { Form } from "../models/form.model"; +import { Field, ID, InputType, Int } from "@nestjs/graphql" +import graphqlTypeJson from 'graphql-type-json' +import { LanguageTypeInput } from "./global.input" +import { InputInput } from "./inputs.input" +import { GroupInput } from "./groups.input" +import { StepInput } from "./steps.input" +import { FormApplicantTypeInput } from "./applicantType.input" +import { DocumentTypeInput } from "./documentType.input" +import { OrganizationInput } from "./organization.input" @InputType('FormSystemGetFormInput') @@ -26,11 +33,65 @@ export class DeleteFormInput { id!: number } +@InputType('FormSystemFormInput') +export class FormInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => OrganizationInput, { nullable: true }) + organization?: OrganizationInput + + @Field(() => Date, { nullable: true }) + created?: Date + + @Field(() => Date, { nullable: true }) + lastChanged?: Date + + @Field(() => Date, { nullable: true }) + invalidationDate?: Date | null + + @Field(() => graphqlTypeJson) + dependencies?: { [key: string]: string[] } | null + + @Field(() => [DocumentTypeInput], { nullable: 'itemsAndList' }) + documentTypes?: DocumentTypeInput[] | null + + @Field(() => [FormApplicantTypeInput], { nullable: 'itemsAndList' }) + formApplicantTypes?: FormApplicantTypeInput[] | null + + @Field(() => LanguageTypeInput, { nullable: true }) + completedMessage?: LanguageTypeInput + + @Field() + isTranslated?: boolean + + @Field() + stopProgressOnValidatingStep?: boolean + + @Field(() => Number, { nullable: true }) + applicationsDaysToRemove?: number + + @Field(() => [StepInput], { nullable: 'itemsAndList' }) + steps?: StepInput[] | null + + @Field(() => [StepInput], { nullable: 'itemsAndList' }) + stepsList?: StepInput[] | null + + @Field(() => [GroupInput], { nullable: 'itemsAndList' }) + groupsList?: GroupInput[] | null + + @Field(() => [InputInput], { nullable: 'itemsAndList' }) + inputsList?: InputInput[] | null +} + @InputType('FormSystemUpdateFormInput') export class UpdateFormInput { @Field(() => Int, { nullable: true }) formId!: number - @Field(() => Form, { nullable: true }) - form?: Form + @Field(() => FormInput, { nullable: true }) + form?: FormInput } diff --git a/libs/api/domains/form-system/src/dto/global.input.ts b/libs/api/domains/form-system/src/dto/global.input.ts new file mode 100644 index 000000000000..5d7c1e8856d5 --- /dev/null +++ b/libs/api/domains/form-system/src/dto/global.input.ts @@ -0,0 +1,10 @@ +import { Field, InputType } from "@nestjs/graphql"; + +@InputType('FormSystemGlobalInput') +export class LanguageTypeInput { + @Field(() => String, { nullable: true }) + is?: string | null + + @Field(() => String, { nullable: true }) + en?: string | null +} diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index 9426fbe3ab3f..cd7c6a72cd63 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -1,7 +1,35 @@ -import { Field, InputType, Int } from "@nestjs/graphql"; -import { CreateGroup, UpdateGroup } from "../models/group.model"; +import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" +import { InputInput } from "./inputs.input" +@InputType('FormSystemGroupCreation') +export class CreateGroup { + @Field(() => ID, { nullable: true }) + stepId?: number + + @Field(() => Number, { nullable: true }) + displayOrder?: number +} + +@InputType('FormSystemGroupUpdate') +export class UpdateGroup { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + guid?: string + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => Number, { nullable: true }) + multiSet?: number +} + @InputType('FormSystemGetGroupInput') export class GetGroupInput { @Field(() => Int) @@ -28,3 +56,33 @@ export class UpdateGroupInput { @Field(() => UpdateGroup, { nullable: true }) groupUpdateDto?: UpdateGroup } + +@InputType('FormSystemGroupInput') +export class GroupInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + guid?: string + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => Boolean, { nullable: true }) + isHidden?: boolean + + @Field(() => [InputInput]) + InputInputInputs?: InputInput[] | null + + @Field(() => Number, { nullable: true }) + stepId?: number + + @Field(() => Number, { nullable: true }) + multiSet?: number + + @Field(() => String, { nullable: true }) + stepGuid?: string +} diff --git a/libs/api/domains/form-system/src/dto/inputSettings.input.ts b/libs/api/domains/form-system/src/dto/inputSettings.input.ts new file mode 100644 index 000000000000..24388897481e --- /dev/null +++ b/libs/api/domains/form-system/src/dto/inputSettings.input.ts @@ -0,0 +1,67 @@ +import { InputType, Field } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" +import { ListItemInput } from "./listItem.input" + + +@InputType('FormSystemInputSettingsInput') +export class InputSettingsInput { + @Field(() => Boolean, { nullable: true }) + isLarge?: boolean + + @Field(() => String, { nullable: true }) + size?: string + + @Field(() => String, { nullable: true }) + interval?: string + + @Field(() => Boolean, { nullable: true }) + hasLink?: boolean + + @Field(() => String, { nullable: true }) + url?: string + + @Field(() => LanguageTypeInput, { nullable: true }) + buttonText?: LanguageTypeInput + + @Field(() => [String], { nullable: true }) + types?: string[] + + @Field(() => Number, { nullable: true }) + maxSize?: number + + @Field(() => Boolean, { nullable: true }) + isMulti?: boolean + + @Field(() => Number, { nullable: true }) + amount?: number + + @Field(() => String, { nullable: true }) + header?: string + + @Field(() => Number, { nullable: true }) + maxLength?: number + + @Field(() => Number, { nullable: true }) + minLength?: number + + @Field(() => Number, { nullable: true }) + min?: number + + @Field(() => Number, { nullable: true }) + max?: number + + @Field(() => [ListItemInput], { nullable: true }) + list?: ListItemInput[] + + @Field(() => String, { nullable: true }) + type?: string + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => Boolean, { nullable: true }) + isList?: boolean + + @Field(() => Boolean, { nullable: true }) + hasInput?: boolean +} diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index a807fcd776f5..2427625733a7 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -1,25 +1,68 @@ -import { Field, InputType, Int } from "@nestjs/graphql" -import { CreateInput, UpdateInput } from "../models/input.model" +import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" +import graphqlTypeJson from 'graphql-type-json' +import { InputSettingsInput } from "./inputSettings.input" -@InputType('FormSystemGetGroupInput') +@InputType('FormSystemInputCreation') +export class CreateInput { + @Field(() => Number, { nullable: true }) + groupId?: number + + @Field(() => Number, { nullable: true }) + displayOrder?: number +} + +@InputType('FormSystemInputUpdate') +export class UpdateInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput + + @Field() + isRequired?: boolean + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field() + isHidden?: boolean + + @Field(() => String, { nullable: true }) + type?: string + + @Field(() => InputSettingsInput, { nullable: true }) + inputSettings?: InputSettingsInput + + @Field() + isPartOfMultiSet?: boolean +} + + + +@InputType('FormSystemGetInputInput') export class GetInputInput { @Field(() => Int) id!: number } -@InputType('FormSystemCreateGroupInput') +@InputType('FormSystemCreateInputInput') export class CreateInputInput { @Field(() => CreateInput, { nullable: true }) inputCreationDto?: CreateInput } -@InputType('FormSystemDeleteGroupInput') +@InputType('FormSystemDeleteInputInput') export class DeleteInputInput { @Field(() => Int) inputId!: number } -@InputType('FormSystemUpdateGroupInput') +@InputType('FormSystemUpdateInputInput') export class UpdateInputInput { @Field(() => Int, { nullable: true }) inputId!: number @@ -27,3 +70,46 @@ export class UpdateInputInput { @Field(() => UpdateInput, { nullable: true }) inputUpdateDto?: UpdateInput } + +@InputType('FormSystemInputInput') +export class InputInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput + + @Field() + isRequired?: boolean + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => Number, { nullable: true }) + groupId?: number + + @Field() + isHidden?: boolean + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => String, { nullable: true }) + guid?: string + + @Field() + isPartOfMultiSet?: boolean + + @Field(() => String, { nullable: true }) + groupGuid?: string + + @Field(() => InputSettingsInput, { nullable: true }) + inputSettings?: InputSettingsInput + + @Field(() => graphqlTypeJson, { nullable: true }) + inputFields?: object +} + diff --git a/libs/api/domains/form-system/src/dto/listItem.input.ts b/libs/api/domains/form-system/src/dto/listItem.input.ts new file mode 100644 index 000000000000..382cb261c61f --- /dev/null +++ b/libs/api/domains/form-system/src/dto/listItem.input.ts @@ -0,0 +1,23 @@ +import { InputType, Field } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" + +@InputType('FormSystemListItemInput') +export class ListItemInput { + @Field(() => String, { nullable: true }) + guid?: string + + @Field(() => LanguageTypeInput, { nullable: true }) + label?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => Boolean, { nullable: true }) + isSelected?: boolean + + @Field(() => String, { nullable: true }) + value?: string +} diff --git a/libs/api/domains/form-system/src/dto/listType.input.ts b/libs/api/domains/form-system/src/dto/listType.input.ts new file mode 100644 index 000000000000..837ee4373398 --- /dev/null +++ b/libs/api/domains/form-system/src/dto/listType.input.ts @@ -0,0 +1,17 @@ +import { Field, ID, InputType } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" + +@InputType('FormSystemListTypeInput') +export class ListTypeInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => LanguageTypeInput, { nullable: true }) + description?: LanguageTypeInput +} diff --git a/libs/api/domains/form-system/src/dto/organization.input.ts b/libs/api/domains/form-system/src/dto/organization.input.ts index acb0648b34d5..17d0fa0a3613 100644 --- a/libs/api/domains/form-system/src/dto/organization.input.ts +++ b/libs/api/domains/form-system/src/dto/organization.input.ts @@ -1,12 +1,56 @@ -import { Field, InputType } from "@nestjs/graphql"; -import { LanguageType } from "../models/global.model"; +import { Field, ID, InputType } from "@nestjs/graphql" +import { InputInput } from "./inputs.input" +import { DocumentTypeInput } from "./documentType.input" +import { FormInput } from "./forms.input" +import { ApplicantTypeInput } from "./applicantType.input" +import { ListTypeInput } from "./listType.input" +import { ExternalEndpointsInput } from "./externalEndpoints.input" +import { LanguageTypeInput } from "./global.input" +@InputType('FormSystemOrganizationCreation') +export class CreateOrganization { + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + nationalId?: string +} @InputType('FormSystemCreateOrganizationInput') export class CreateOrganizationInput { - @Field(() => LanguageType, { nullable: true }) - name?: LanguageType + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput @Field(() => String, { nullable: true }) nationalId?: string } + +@InputType('FormSystemOrganizationInput') +export class OrganizationInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + nationalId?: string | null + + @Field(() => [InputInput], { nullable: 'itemsAndList' }) + inputTypes?: InputInput[] | null + + @Field(() => [DocumentTypeInput], { nullable: 'itemsAndList' }) + documentTypes?: DocumentTypeInput[] | null + + @Field(() => [ApplicantTypeInput], { nullable: true }) + applicantTypes?: ApplicantTypeInput[] | null + + @Field(() => [ListTypeInput], { nullable: 'itemsAndList' }) + listTypes?: ListTypeInput[] | null + + @Field(() => [FormInput], { nullable: 'itemsAndList' }) + forms?: FormInput[] | null + + @Field(() => [ExternalEndpointsInput], { nullable: 'itemsAndList' }) + externalEndpoints?: ExternalEndpointsInput[] | null +} diff --git a/libs/api/domains/form-system/src/dto/steps.input.ts b/libs/api/domains/form-system/src/dto/steps.input.ts index e7a7f36bc763..55fc3e9e02ea 100644 --- a/libs/api/domains/form-system/src/dto/steps.input.ts +++ b/libs/api/domains/form-system/src/dto/steps.input.ts @@ -1,6 +1,36 @@ -import { Field, InputType, Int } from "@nestjs/graphql"; -import { CreateStep, UpdateStep } from "../models/step.model"; +import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { LanguageTypeInput } from "./global.input" +import { GroupInput } from "./groups.input" +@InputType('FormSystemStepCreation') +export class CreateStep { + @Field(() => Int, { nullable: true }) + formId?: number + + @Field(() => Int, { nullable: true }) + displayOrder?: number +} + +@InputType('FormSystemStepUpdate') +export class UpdateStep { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + waitingText?: LanguageTypeInput + + @Field(() => Boolean, { nullable: true }) + callRuleset?: boolean +} @InputType('FormSystemGetStepInput') export class GetStepInput { @@ -28,3 +58,36 @@ export class UpdateStepInput { @Field(() => UpdateStep, { nullable: true }) stepUpdateDto?: UpdateStep } + +@InputType('FormSystemStepInput') +export class StepInput { + @Field(() => ID, { nullable: true }) + id?: number + + @Field(() => String, { nullable: true }) + guid?: string + + @Field(() => Number, { nullable: true }) + displayOrder?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => String, { nullable: true }) + type?: string | null + + @Field(() => LanguageTypeInput, { nullable: true }) + waitingText?: LanguageTypeInput + + @Field(() => Boolean, { nullable: true }) + callRulest?: boolean + + @Field(() => Boolean, { nullable: true }) + isHidden?: boolean + + @Field(() => Boolean, { nullable: true }) + isCompleted?: boolean + + @Field(() => [GroupInput], { nullable: 'itemsAndList' }) + groups?: GroupInput[] | null +} diff --git a/libs/api/domains/form-system/src/lib/forms/forms.service.ts b/libs/api/domains/form-system/src/lib/forms/forms.service.ts index 1b169a49a085..39e8cb57e0a6 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.service.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.service.ts @@ -7,6 +7,8 @@ import { CreateFormInput, DeleteFormInput, GetFormInput, GetFormsInput, UpdateFo import { FormResponse } from "../../models/formResponse.model" import { FormListResponse } from "../../models/formListResponse.model" import { GraphqlToRestInputSettings, RESTInputSettings, RestToGraphqlInputSettings } from "../utils/helperFunctions" +import { Form } from "../../models/form.model" +import { Input } from "../../models/input.model" @@ -91,7 +93,8 @@ export class FormsService { if (!response || response instanceof ApolloError) { return {} } - return response as FormResponse + + return response } async deleteForm(auth: User, input: DeleteFormInput): Promise { diff --git a/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts b/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts index 1e9e986e9879..b624ac511d98 100644 --- a/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts +++ b/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts @@ -5,10 +5,6 @@ import { AuthMiddleware, User } from '@island.is/auth-nest-tools' import { ApiOrganizationsPostRequest, OrganizationsApi } from "@island.is/clients/form-system" import { CreateOrganizationInput } from "../../dto/organization.input" import { Organization } from "../../models/organization.model" -import { Input } from "../../models/input.model" -import { ListType } from "../../models/listType.model" -import { Form } from "../../models/form.model" -import { ExternalEndpoints } from "../../models/externalEndpoints.model" @Injectable() export class OrganizationsService { @@ -55,18 +51,6 @@ export class OrganizationsService { return {} } - const newOrg: Organization = { - id: response.id, - name: response.name, - nationalId: response.kennitala, - inputTypes: response.inputTypes as Input[], - documentTypes: response.documentTypes, - applicantTypes: response.applicantTypes, - listTypes: response.listTypes as ListType[], - externalEndpoints: response.externalEndpoints as ExternalEndpoints[], - forms: response.forms as Form[], - } - - return newOrg + return response } } diff --git a/libs/api/domains/form-system/src/models/applicantType.model.ts b/libs/api/domains/form-system/src/models/applicantType.model.ts index ca4acd1938f7..87e5f72bf0d6 100644 --- a/libs/api/domains/form-system/src/models/applicantType.model.ts +++ b/libs/api/domains/form-system/src/models/applicantType.model.ts @@ -2,10 +2,10 @@ import { Field, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; import { ApplicantTypeNameSuggestion } from "./applicantTypeNameSuggestion"; -ObjectType('FormSystemApplicantType') +@ObjectType('FormSystemApplicantType') export class ApplicantType { @Field(() => Number, { nullable: true }) - formId?: number + id?: number @Field(() => Number, { nullable: true }) applicantTypeId?: number diff --git a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts index 63232935d18f..d94ac42ba8b6 100644 --- a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts +++ b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts @@ -2,7 +2,7 @@ import { Field, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; -ObjectType('FormSystemApplicantTypeNameSuggestion') +@ObjectType('FormSystemApplicantTypeNameSuggestion') export class ApplicantTypeNameSuggestion { @Field(() => LanguageType, { nullable: true }) nameSuggestion?: LanguageType diff --git a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts index 2983385e2d6f..7b9a5d185494 100644 --- a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts +++ b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts @@ -1,21 +1,12 @@ import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql' +import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' -enum Type { - submit = 'submit', - validation = 'validation', -} - -registerEnumType(Type, { - name: 'FormSystemType', +registerEnumType(EExternalEndpointType, { + name: 'FormSystemExternalEndpointType', }) -enum Environment { - production = 'production', - development = 'development', -} - -registerEnumType(Environment, { - name: 'FormSystemEnvironment', +registerEnumType(EExternalEndpointEnvironment, { + name: 'FormSystemExternalEndpointEnvironment', }) @ObjectType('FormSystemExternalEndpoints') @@ -24,11 +15,11 @@ export class ExternalEndpoints { id?: number @Field(() => String, { nullable: true }) - url?: string + url?: string | null - @Field(() => Type, { nullable: true }) - type?: Type + @Field(() => EExternalEndpointType) + type?: EExternalEndpointType - @Field(() => Environment, { nullable: true }) - environment?: Environment + @Field(() => EExternalEndpointEnvironment, { nullable: true }) + environment?: EExternalEndpointEnvironment } diff --git a/libs/api/domains/form-system/src/models/form.model.ts b/libs/api/domains/form-system/src/models/form.model.ts index ef2e825e5014..681a53ad74ec 100644 --- a/libs/api/domains/form-system/src/models/form.model.ts +++ b/libs/api/domains/form-system/src/models/form.model.ts @@ -1,11 +1,12 @@ import { Field, ID, ObjectType } from '@nestjs/graphql' import { LanguageType } from './global.model' -import { ApplicantType } from './applicantType.model' import { Group } from './group.model' import { Input } from './input.model' import { Step } from './step.model' import { Organization } from './organization.model' import { DocumentType } from './documentType.model' +import graphqlTypeJson from 'graphql-type-json' +import { FormApplicantType } from './formApplicantType.model' export type Dependencies = { [key: string]: string[] @@ -31,36 +32,36 @@ export class Form { @Field(() => Date, { nullable: true }) invalidationDate?: Date | null - @Field(() => Object, { nullable: true }) - dependencies?: Dependencies[] | null + @Field(() => graphqlTypeJson) + dependencies?: { [key: string]: string[] } | null - @Field(() => DocumentType, { nullable: true }) + @Field(() => [DocumentType], { nullable: 'itemsAndList' }) documentTypes?: DocumentType[] | null - @Field(() => [ApplicantType]) - formApplicantTypes?: ApplicantType[] | null + @Field(() => [FormApplicantType], { nullable: 'itemsAndList' }) + formApplicantTypes?: FormApplicantType[] | null @Field(() => LanguageType, { nullable: true }) completedMessage?: LanguageType - @Field(() => LanguageType, { nullable: true }) - isTranslated?: LanguageType + @Field() + isTranslated?: boolean - @Field(() => Boolean, { nullable: true }) + @Field() stopProgressOnValidatingStep?: boolean @Field(() => Number, { nullable: true }) applicationsDaysToRemove?: number - @Field(() => Step, { nullable: true }) + @Field(() => [Step], { nullable: 'itemsAndList' }) steps?: Step[] | null - @Field(() => Step, { nullable: true }) + @Field(() => [Step], { nullable: 'itemsAndList' }) stepsList?: Step[] | null - @Field(() => Group, { nullable: true }) + @Field(() => [Group], { nullable: 'itemsAndList' }) groupsList?: Group[] | null - @Field(() => Input, { nullable: true }) + @Field(() => [Input], { nullable: 'itemsAndList' }) inputsList?: Input[] | null } diff --git a/libs/api/domains/form-system/src/models/formApplicantType.model.ts b/libs/api/domains/form-system/src/models/formApplicantType.model.ts new file mode 100644 index 000000000000..9bee9bdc5727 --- /dev/null +++ b/libs/api/domains/form-system/src/models/formApplicantType.model.ts @@ -0,0 +1,18 @@ +import { ObjectType, Field } from "@nestjs/graphql"; +import { LanguageType } from "./global.model"; + + +@ObjectType('FormSystemFormApplicantType') +export class FormApplicantType { + @Field(() => Number, { nullable: true }) + formId?: number + + @Field(() => Number, { nullable: true }) + applicantTypeId?: number + + @Field(() => LanguageType, { nullable: true }) + name?: LanguageType + + @Field(() => String) + type?: string | null +} diff --git a/libs/api/domains/form-system/src/models/formListResponse.model.ts b/libs/api/domains/form-system/src/models/formListResponse.model.ts index d593ab42ae96..b293420430f0 100644 --- a/libs/api/domains/form-system/src/models/formListResponse.model.ts +++ b/libs/api/domains/form-system/src/models/formListResponse.model.ts @@ -3,6 +3,6 @@ import { Form } from "./form.model"; @ObjectType('FormSystemFormListResponse') export class FormListResponse { - @Field(() => [Form], { nullable: true }) + @Field(() => [Form], { nullable: 'itemsAndList' }) forms?: Form[] | null } diff --git a/libs/api/domains/form-system/src/models/formResponse.model.ts b/libs/api/domains/form-system/src/models/formResponse.model.ts index de9c294e955d..52705ec47fd5 100644 --- a/libs/api/domains/form-system/src/models/formResponse.model.ts +++ b/libs/api/domains/form-system/src/models/formResponse.model.ts @@ -4,22 +4,21 @@ import { DocumentType } from './documentType.model' import { Input } from './input.model' import { ApplicantType } from './applicantType.model' import { ListType } from './listType.model' -import { DocumentTypeDto } from '@island.is/clients/form-system' @ObjectType('FormSystemFormResponse') export class FormResponse { @Field(() => Form, { nullable: true }) form?: Form - @Field(() => [DocumentType]) + @Field(() => [DocumentType], { nullable: 'itemsAndList' }) documentTypes?: DocumentType[] | null - @Field(() => [Input]) + @Field(() => [Input], { nullable: 'itemsAndList' }) inputTypes?: Input[] | null - @Field(() => [ApplicantType]) + @Field(() => [ApplicantType], { nullable: 'itemsAndList' }) applicantTypes?: ApplicantType[] | null - @Field(() => [ListType]) + @Field(() => [ListType], { nullable: 'itemsAndList' }) listTypes?: ListType[] | null } diff --git a/libs/api/domains/form-system/src/models/group.model.ts b/libs/api/domains/form-system/src/models/group.model.ts index 85e6329a0404..9b26cf0aad9f 100644 --- a/libs/api/domains/form-system/src/models/group.model.ts +++ b/libs/api/domains/form-system/src/models/group.model.ts @@ -19,8 +19,8 @@ export class Group { @Field(() => Boolean, { nullable: true }) isHidden?: boolean - @Field(() => [Input], { nullable: true }) - inputs?: Input[] + @Field(() => [Input]) + inputs?: Input[] | null @Field(() => Number, { nullable: true }) stepId?: number @@ -32,31 +32,3 @@ export class Group { stepGuid?: string } -@ObjectType('FormSystemGroupCreation') -export class CreateGroup { - @Field(() => ID, { nullable: true }) - stepId?: number - - @Field(() => Number, { nullable: true }) - displayOrder?: number -} - -@ObjectType('FormSystemGroupUpdate') -export class UpdateGroup { - @Field(() => ID, { nullable: true }) - id?: number - - @Field(() => LanguageType, { nullable: true }) - name?: LanguageType - - @Field(() => String, { nullable: true }) - guid?: string - - @Field(() => Number, { nullable: true }) - displayOrder?: number - - @Field(() => Number, { nullable: true }) - multiSet?: number - -} - diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index 0281dfcbccc0..3e7a5f2d1c01 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -15,7 +15,7 @@ export class Input { @Field(() => LanguageType, { nullable: true }) description?: LanguageType - @Field(() => Boolean, { nullable: true }) + @Field() isRequired?: boolean @Field(() => Number, { nullable: true }) @@ -24,16 +24,16 @@ export class Input { @Field(() => Number, { nullable: true }) groupId?: number - @Field(() => Boolean, { nullable: true }) + @Field() isHidden?: boolean @Field(() => String, { nullable: true }) - type?: string + type?: string | null @Field(() => String, { nullable: true }) guid?: string - @Field(() => Boolean, { nullable: true }) + @Field() isPartOfMultiSet?: boolean @Field(() => String, { nullable: true }) @@ -46,41 +46,4 @@ export class Input { inputFields?: object } -@ObjectType('FormSystemInputCreation') -export class CreateInput { - @Field(() => Number, { nullable: true }) - groupId?: number - - @Field(() => Number, { nullable: true }) - displayOrder?: number -} - -@ObjectType('FormSystemInputUpdate') -export class UpdateInput { - @Field(() => ID, { nullable: true }) - id?: number - - @Field(() => LanguageType, { nullable: true }) - name?: LanguageType - - @Field(() => LanguageType, { nullable: true }) - description?: LanguageType - @Field(() => Boolean, { nullable: true }) - isRequired?: boolean - - @Field(() => Number, { nullable: true }) - displayOrder?: number - - @Field(() => Boolean, { nullable: true }) - isHidden?: boolean - - @Field(() => String, { nullable: true }) - type?: string - - @Field(() => InputSettings, { nullable: true }) - inputSettings?: InputSettings - - @Field(() => Boolean, { nullable: true }) - isPartOfMultiSet?: boolean -} diff --git a/libs/api/domains/form-system/src/models/listType.model.ts b/libs/api/domains/form-system/src/models/listType.model.ts index 058fb87ee990..5a751e549899 100644 --- a/libs/api/domains/form-system/src/models/listType.model.ts +++ b/libs/api/domains/form-system/src/models/listType.model.ts @@ -2,13 +2,13 @@ import { Field, ID, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; -ObjectType('FormSystemListType') +@ObjectType('FormSystemListType') export class ListType { @Field(() => ID, { nullable: true }) id?: number @Field(() => String, { nullable: true }) - type?: string + type?: string | null @Field(() => LanguageType, { nullable: true }) name?: LanguageType diff --git a/libs/api/domains/form-system/src/models/organization.model.ts b/libs/api/domains/form-system/src/models/organization.model.ts index 34209e1a2b9a..e29ff62f7c2e 100644 --- a/libs/api/domains/form-system/src/models/organization.model.ts +++ b/libs/api/domains/form-system/src/models/organization.model.ts @@ -18,30 +18,23 @@ export class Organization { @Field(() => String, { nullable: true }) nationalId?: string | null - @Field(() => [Input]) + @Field(() => [Input], { nullable: 'itemsAndList' }) inputTypes?: Input[] | null - @Field(() => [DocumentType]) + @Field(() => [DocumentType], { nullable: 'itemsAndList' }) documentTypes?: DocumentType[] | null - @Field(() => [ApplicantType]) + @Field(() => [ApplicantType], { nullable: true }) applicantTypes?: ApplicantType[] | null - @Field(() => [ListType]) + @Field(() => [ListType], { nullable: 'itemsAndList' }) listTypes?: ListType[] | null - @Field(() => [Form]) + @Field(() => [Form], { nullable: 'itemsAndList' }) forms?: Form[] | null - @Field(() => [ExternalEndpoints]) + @Field(() => [ExternalEndpoints], { nullable: 'itemsAndList' }) externalEndpoints?: ExternalEndpoints[] | null } -@ObjectType('FormSystemOrganizationCreation') -export class CreateOrganization { - @Field(() => LanguageType, { nullable: true }) - name?: LanguageType - @Field(() => String, { nullable: true }) - nationalId?: string -} diff --git a/libs/api/domains/form-system/src/models/services.model.ts b/libs/api/domains/form-system/src/models/services.model.ts index 87b0b008a97f..89fe7f21329a 100644 --- a/libs/api/domains/form-system/src/models/services.model.ts +++ b/libs/api/domains/form-system/src/models/services.model.ts @@ -7,6 +7,6 @@ export class List { @Field(() => String, { nullable: true }) listType?: string - @Field(() => [ListItem], { nullable: true }) + @Field(() => [ListItem], { nullable: 'itemsAndList' }) listi?: ListItem[] } diff --git a/libs/api/domains/form-system/src/models/step.model.ts b/libs/api/domains/form-system/src/models/step.model.ts index d3616a45db0c..0aa1587da5ce 100644 --- a/libs/api/domains/form-system/src/models/step.model.ts +++ b/libs/api/domains/form-system/src/models/step.model.ts @@ -17,7 +17,7 @@ export class Step { name?: LanguageType @Field(() => String, { nullable: true }) - type?: string + type?: string | null @Field(() => LanguageType, { nullable: true }) waitingText?: LanguageType @@ -31,36 +31,7 @@ export class Step { @Field(() => Boolean, { nullable: true }) isCompleted?: boolean - @Field(() => [Group], { nullable: true }) - groups?: Group[] + @Field(() => [Group], { nullable: 'itemsAndList' }) + groups?: Group[] | null } -@ObjectType('FormSystemStepCreation') -export class CreateStep { - @Field(() => Int, { nullable: true }) - formId?: number - - @Field(() => Int, { nullable: true }) - displayOrder?: number -} - -@ObjectType('FormSystemStepUpdate') -export class UpdateStep { - @Field(() => ID, { nullable: true }) - id?: number; - - @Field(() => LanguageType, { nullable: true }) - name?: LanguageType; - - @Field(() => String, { nullable: true }) - type?: string | null; - - @Field(() => Number, { nullable: true }) - displayOrder?: number; - - @Field(() => LanguageType, { nullable: true }) - waitingText?: LanguageType; - - @Field(() => Boolean, { nullable: true }) - callRuleset?: boolean; -} From 8a5e6375c467b51aa8d5d436b532d38b3c6e0c48 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Thu, 14 Mar 2024 12:39:16 +0000 Subject: [PATCH 23/72] Update import statements for LanguageTypeInput --- .../api/domains/form-system/src/dto/applicantType.input.ts | 2 +- .../src/dto/applicantTypeNameSuggestion.input.ts | 2 +- libs/api/domains/form-system/src/dto/documentType.input.ts | 2 +- libs/api/domains/form-system/src/dto/forms.input.ts | 2 +- libs/api/domains/form-system/src/dto/groups.input.ts | 2 +- .../api/domains/form-system/src/dto/inputSettings.input.ts | 2 +- libs/api/domains/form-system/src/dto/inputs.input.ts | 2 +- .../src/dto/{global.input.ts => language.input.ts} | 0 libs/api/domains/form-system/src/dto/listItem.input.ts | 2 +- libs/api/domains/form-system/src/dto/listType.input.ts | 2 +- libs/api/domains/form-system/src/dto/organization.input.ts | 2 +- libs/api/domains/form-system/src/dto/steps.input.ts | 2 +- .../admin/form-system/src/screens/Forms/CreateForm.graphql | 7 +++++++ .../admin/form-system/src/screens/Forms/Forms.loader.ts | 1 + 14 files changed, 19 insertions(+), 11 deletions(-) rename libs/api/domains/form-system/src/dto/{global.input.ts => language.input.ts} (100%) create mode 100644 libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql diff --git a/libs/api/domains/form-system/src/dto/applicantType.input.ts b/libs/api/domains/form-system/src/dto/applicantType.input.ts index b1c2d46c759d..f98807be8dc9 100644 --- a/libs/api/domains/form-system/src/dto/applicantType.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantType.input.ts @@ -1,5 +1,5 @@ import { Field, InputType } from "@nestjs/graphql"; -import { LanguageTypeInput } from "./global.input"; +import { LanguageTypeInput } from "./language.input"; import { ApplicantTypeNameSuggestionInput } from "./applicantTypeNameSuggestion.input"; diff --git a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts index 626bee98d348..2e7ce30c5610 100644 --- a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts @@ -1,5 +1,5 @@ import { InputType, Field } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" @InputType('FormSystemApplicantTypeNameSuggestionInput') export class ApplicantTypeNameSuggestionInput { diff --git a/libs/api/domains/form-system/src/dto/documentType.input.ts b/libs/api/domains/form-system/src/dto/documentType.input.ts index 742fd4a1aa5b..8fb308f1e23a 100644 --- a/libs/api/domains/form-system/src/dto/documentType.input.ts +++ b/libs/api/domains/form-system/src/dto/documentType.input.ts @@ -1,5 +1,5 @@ import { Field, ID, InputType } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" diff --git a/libs/api/domains/form-system/src/dto/forms.input.ts b/libs/api/domains/form-system/src/dto/forms.input.ts index 19d7971e995d..71e3686401c2 100644 --- a/libs/api/domains/form-system/src/dto/forms.input.ts +++ b/libs/api/domains/form-system/src/dto/forms.input.ts @@ -1,6 +1,6 @@ import { Field, ID, InputType, Int } from "@nestjs/graphql" import graphqlTypeJson from 'graphql-type-json' -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" import { InputInput } from "./inputs.input" import { GroupInput } from "./groups.input" import { StepInput } from "./steps.input" diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index cd7c6a72cd63..3e57d176c82f 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -1,5 +1,5 @@ import { Field, ID, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" import { InputInput } from "./inputs.input" diff --git a/libs/api/domains/form-system/src/dto/inputSettings.input.ts b/libs/api/domains/form-system/src/dto/inputSettings.input.ts index 24388897481e..de2bb64dbfa5 100644 --- a/libs/api/domains/form-system/src/dto/inputSettings.input.ts +++ b/libs/api/domains/form-system/src/dto/inputSettings.input.ts @@ -1,5 +1,5 @@ import { InputType, Field } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" import { ListItemInput } from "./listItem.input" diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index 2427625733a7..76a79386e704 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -1,5 +1,5 @@ import { Field, ID, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" import graphqlTypeJson from 'graphql-type-json' import { InputSettingsInput } from "./inputSettings.input" diff --git a/libs/api/domains/form-system/src/dto/global.input.ts b/libs/api/domains/form-system/src/dto/language.input.ts similarity index 100% rename from libs/api/domains/form-system/src/dto/global.input.ts rename to libs/api/domains/form-system/src/dto/language.input.ts diff --git a/libs/api/domains/form-system/src/dto/listItem.input.ts b/libs/api/domains/form-system/src/dto/listItem.input.ts index 382cb261c61f..5ea06da5abd2 100644 --- a/libs/api/domains/form-system/src/dto/listItem.input.ts +++ b/libs/api/domains/form-system/src/dto/listItem.input.ts @@ -1,5 +1,5 @@ import { InputType, Field } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" @InputType('FormSystemListItemInput') export class ListItemInput { diff --git a/libs/api/domains/form-system/src/dto/listType.input.ts b/libs/api/domains/form-system/src/dto/listType.input.ts index 837ee4373398..cb2ceda8672d 100644 --- a/libs/api/domains/form-system/src/dto/listType.input.ts +++ b/libs/api/domains/form-system/src/dto/listType.input.ts @@ -1,5 +1,5 @@ import { Field, ID, InputType } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" @InputType('FormSystemListTypeInput') export class ListTypeInput { diff --git a/libs/api/domains/form-system/src/dto/organization.input.ts b/libs/api/domains/form-system/src/dto/organization.input.ts index 17d0fa0a3613..e2a6a9c95d93 100644 --- a/libs/api/domains/form-system/src/dto/organization.input.ts +++ b/libs/api/domains/form-system/src/dto/organization.input.ts @@ -5,7 +5,7 @@ import { FormInput } from "./forms.input" import { ApplicantTypeInput } from "./applicantType.input" import { ListTypeInput } from "./listType.input" import { ExternalEndpointsInput } from "./externalEndpoints.input" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" @InputType('FormSystemOrganizationCreation') export class CreateOrganization { diff --git a/libs/api/domains/form-system/src/dto/steps.input.ts b/libs/api/domains/form-system/src/dto/steps.input.ts index 55fc3e9e02ea..0a29112d9237 100644 --- a/libs/api/domains/form-system/src/dto/steps.input.ts +++ b/libs/api/domains/form-system/src/dto/steps.input.ts @@ -1,5 +1,5 @@ import { Field, ID, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./global.input" +import { LanguageTypeInput } from "./language.input" import { GroupInput } from "./groups.input" @InputType('FormSystemStepCreation') diff --git a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql new file mode 100644 index 000000000000..c97949bd52c6 --- /dev/null +++ b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql @@ -0,0 +1,7 @@ +mutation formSystemCreateForm( + $input: FormSystemCreateFormInput! +) { + formSystemCreateForm(input: $input) { + form +} +} diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts index 9dc83e89ca12..819ea04fe666 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts @@ -1,4 +1,5 @@ import { WrappedLoaderFn } from '@island.is/portals/core' +import { FormSystemGetFormsQuery } from './Forms.generated' export const formsLoader: WrappedLoaderFn = ({ client }) => { From 59ca682a5bfec28bf0b26f4f133fcdb3985d4d2c Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Tue, 19 Mar 2024 11:05:16 +0000 Subject: [PATCH 24/72] Update form system module and related files --- apps/portals/admin/src/lib/modules.ts | 2 + .../caseSubscription.resolver.ts | 6 +- .../src/dto/applicantType.input.ts | 10 +- .../dto/applicantTypeNameSuggestion.input.ts | 4 +- .../form-system/src/dto/documentType.input.ts | 4 +- .../src/dto/externalEndpoints.input.ts | 4 +- .../form-system/src/dto/forms.input.ts | 6 +- .../form-system/src/dto/groups.input.ts | 14 +- .../src/dto/inputSettings.input.ts | 14 +- .../form-system/src/dto/inputs.input.ts | 16 +- .../form-system/src/dto/listType.input.ts | 4 +- .../form-system/src/dto/organization.input.ts | 4 +- .../form-system/src/dto/steps.input.ts | 6 +- .../src/lib/forms/forms.resolver.ts | 5 +- .../src/lib/groups/groups.resolver.ts | 4 +- .../src/lib/inputs/inputs.resolver.ts | 4 +- .../organizations/organizations.resolver.ts | 4 +- .../src/lib/services/services.resolver.ts | 6 +- .../src/lib/steps/steps.resolver.ts | 4 +- .../src/models/applicantType.model.ts | 6 +- .../src/models/applicantTypeNameSuggestion.ts | 4 +- .../src/models/documentType.model.ts | 4 +- .../src/models/externalEndpoints.model.ts | 4 +- .../form-system/src/models/form.model.ts | 6 +- .../src/models/formApplicantType.model.ts | 6 +- .../form-system/src/models/group.model.ts | 6 +- .../form-system/src/models/input.model.ts | 8 +- .../form-system/src/models/listType.model.ts | 4 +- .../src/models/organization.model.ts | 4 +- .../form-system/src/models/step.model.ts | 4 +- .../src/components/TableRow/TableRow.tsx | 4 +- .../admin/form-system/src/lib/messages.ts | 8 +- libs/portals/admin/form-system/src/module.ts | 5 - libs/portals/admin/form-system/src/module.tsx | 32 ++++ .../form-system/src/screens/Form/Form.tsx | 137 ++++++++++++++++++ .../src/screens/Forms/CreateForm.graphql | 2 +- .../src/screens/Forms/Forms.graphql | 15 +- .../src/screens/Forms/Forms.loader.ts | 19 ++- .../screens/Forms/{index.tsx => Forms.tsx} | 39 ++--- 39 files changed, 323 insertions(+), 115 deletions(-) delete mode 100644 libs/portals/admin/form-system/src/module.ts create mode 100644 libs/portals/admin/form-system/src/module.tsx create mode 100644 libs/portals/admin/form-system/src/screens/Form/Form.tsx rename libs/portals/admin/form-system/src/screens/Forms/{index.tsx => Forms.tsx} (66%) diff --git a/apps/portals/admin/src/lib/modules.ts b/apps/portals/admin/src/lib/modules.ts index 08d8e5d28291..f3ec19c5a14a 100644 --- a/apps/portals/admin/src/lib/modules.ts +++ b/apps/portals/admin/src/lib/modules.ts @@ -9,6 +9,7 @@ import { idsAdminModule } from '@island.is/portals/admin/ids-admin' import { petitionModule } from '@island.is/portals/admin/petition' import { serviceDeskModule } from '@island.is/portals/admin/service-desk' import { signatureCollectionModule } from '@island.is/portals/admin/signature-collection' +import { formSystemModule } from '@island.is/form-system' /** * NOTE: @@ -28,4 +29,5 @@ export const modules: PortalModule[] = [ petitionModule, serviceDeskModule, signatureCollectionModule, + formSystemModule ] diff --git a/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts b/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts index e57767de9a17..cecd0a466aa4 100644 --- a/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts +++ b/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts @@ -25,9 +25,9 @@ import { Audit } from '@island.is/nest/audit' @FeatureFlag(Features.consultationPortalApplication) @Audit({ namespace: '@island.is/samradsgatt' }) export class CaseSubscriptionResolver { - constructor(private caseSubscriptionService: CaseSubscriptionService) {} + constructor(private caseSubscriptionService: CaseSubscriptionService) { } - @Mutation(() => Boolean!, { + @Mutation(() => Boolean, { nullable: true, name: 'consultationPortalDeleteSubscriptionType', }) @@ -52,7 +52,7 @@ export class CaseSubscriptionResolver { return this.caseSubscriptionService.getCaseSubscriptionType(user, input) } - @Mutation(() => Boolean!, { + @Mutation(() => Boolean, { nullable: true, name: 'consultationPortalPostSubscriptionType', }) diff --git a/libs/api/domains/form-system/src/dto/applicantType.input.ts b/libs/api/domains/form-system/src/dto/applicantType.input.ts index f98807be8dc9..10448a1ec726 100644 --- a/libs/api/domains/form-system/src/dto/applicantType.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantType.input.ts @@ -1,14 +1,14 @@ -import { Field, InputType } from "@nestjs/graphql"; +import { Field, InputType, Int } from "@nestjs/graphql"; import { LanguageTypeInput } from "./language.input"; import { ApplicantTypeNameSuggestionInput } from "./applicantTypeNameSuggestion.input"; @InputType('FormSystemApplicantTypeInput') export class ApplicantTypeInput { - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -26,10 +26,10 @@ export class ApplicantTypeInput { @InputType('FormSystemFormApplicantTypeInput') export class FormApplicantTypeInput { - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) formId?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number @Field(() => LanguageTypeInput, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts index 2e7ce30c5610..9d2c163327f9 100644 --- a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts @@ -1,4 +1,4 @@ -import { InputType, Field } from "@nestjs/graphql" +import { InputType, Field, Int } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" @InputType('FormSystemApplicantTypeNameSuggestionInput') @@ -6,6 +6,6 @@ export class ApplicantTypeNameSuggestionInput { @Field(() => LanguageTypeInput, { nullable: true }) nameSuggestion?: LanguageTypeInput - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number } diff --git a/libs/api/domains/form-system/src/dto/documentType.input.ts b/libs/api/domains/form-system/src/dto/documentType.input.ts index 8fb308f1e23a..ed28232bb545 100644 --- a/libs/api/domains/form-system/src/dto/documentType.input.ts +++ b/libs/api/domains/form-system/src/dto/documentType.input.ts @@ -1,11 +1,11 @@ -import { Field, ID, InputType } from "@nestjs/graphql" +import { Field, Int, InputType } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" @InputType('FormSystemDocumentTypeInput') export class DocumentTypeInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts index 34dd0c34381d..79a6c486d569 100644 --- a/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts +++ b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts @@ -1,4 +1,4 @@ -import { Field, ID, InputType, registerEnumType } from '@nestjs/graphql' +import { Field, Int, InputType, registerEnumType } from '@nestjs/graphql' import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' registerEnumType(EExternalEndpointType, { @@ -11,7 +11,7 @@ registerEnumType(EExternalEndpointEnvironment, { @InputType('FormSystemExternalEndpointsInput') export class ExternalEndpointsInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/forms.input.ts b/libs/api/domains/form-system/src/dto/forms.input.ts index 71e3686401c2..640cf6f9c211 100644 --- a/libs/api/domains/form-system/src/dto/forms.input.ts +++ b/libs/api/domains/form-system/src/dto/forms.input.ts @@ -1,4 +1,4 @@ -import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { Field, InputType, Int } from "@nestjs/graphql" import graphqlTypeJson from 'graphql-type-json' import { LanguageTypeInput } from "./language.input" import { InputInput } from "./inputs.input" @@ -35,7 +35,7 @@ export class DeleteFormInput { @InputType('FormSystemFormInput') export class FormInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -71,7 +71,7 @@ export class FormInput { @Field() stopProgressOnValidatingStep?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicationsDaysToRemove?: number @Field(() => [StepInput], { nullable: 'itemsAndList' }) diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index 3e57d176c82f..2158946c0811 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -1,11 +1,11 @@ -import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { Field, InputType, Int } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" import { InputInput } from "./inputs.input" @InputType('FormSystemGroupCreation') export class CreateGroup { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) stepId?: number @Field(() => Number, { nullable: true }) @@ -14,7 +14,7 @@ export class CreateGroup { @InputType('FormSystemGroupUpdate') export class UpdateGroup { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -59,7 +59,7 @@ export class UpdateGroupInput { @InputType('FormSystemGroupInput') export class GroupInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -68,16 +68,16 @@ export class GroupInput { @Field(() => String, { nullable: true }) guid?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number @Field(() => Boolean, { nullable: true }) isHidden?: boolean @Field(() => [InputInput]) - InputInputInputs?: InputInput[] | null + inputs?: InputInput[] | null - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) stepId?: number @Field(() => Number, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/inputSettings.input.ts b/libs/api/domains/form-system/src/dto/inputSettings.input.ts index de2bb64dbfa5..d35bf57506a0 100644 --- a/libs/api/domains/form-system/src/dto/inputSettings.input.ts +++ b/libs/api/domains/form-system/src/dto/inputSettings.input.ts @@ -1,4 +1,4 @@ -import { InputType, Field } from "@nestjs/graphql" +import { InputType, Field, Int, Float } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" import { ListItemInput } from "./listItem.input" @@ -26,28 +26,28 @@ export class InputSettingsInput { @Field(() => [String], { nullable: true }) types?: string[] - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) maxSize?: number @Field(() => Boolean, { nullable: true }) isMulti?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Float, { nullable: true }) amount?: number @Field(() => String, { nullable: true }) header?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) maxLength?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) minLength?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) min?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) max?: number @Field(() => [ListItemInput], { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index 76a79386e704..d582fca058d5 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -1,20 +1,20 @@ -import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { Field, InputType, Int } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" import graphqlTypeJson from 'graphql-type-json' import { InputSettingsInput } from "./inputSettings.input" @InputType('FormSystemInputCreation') export class CreateInput { - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) groupId?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number } @InputType('FormSystemInputUpdate') export class UpdateInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -26,7 +26,7 @@ export class UpdateInput { @Field() isRequired?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number @Field() @@ -73,7 +73,7 @@ export class UpdateInputInput { @InputType('FormSystemInputInput') export class InputInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -85,10 +85,10 @@ export class InputInput { @Field() isRequired?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) groupId?: number @Field() diff --git a/libs/api/domains/form-system/src/dto/listType.input.ts b/libs/api/domains/form-system/src/dto/listType.input.ts index cb2ceda8672d..9f1aff48b853 100644 --- a/libs/api/domains/form-system/src/dto/listType.input.ts +++ b/libs/api/domains/form-system/src/dto/listType.input.ts @@ -1,9 +1,9 @@ -import { Field, ID, InputType } from "@nestjs/graphql" +import { Field, Int, InputType } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" @InputType('FormSystemListTypeInput') export class ListTypeInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/organization.input.ts b/libs/api/domains/form-system/src/dto/organization.input.ts index e2a6a9c95d93..c8ed7c23be1a 100644 --- a/libs/api/domains/form-system/src/dto/organization.input.ts +++ b/libs/api/domains/form-system/src/dto/organization.input.ts @@ -1,4 +1,4 @@ -import { Field, ID, InputType } from "@nestjs/graphql" +import { Field, Int, InputType } from "@nestjs/graphql" import { InputInput } from "./inputs.input" import { DocumentTypeInput } from "./documentType.input" import { FormInput } from "./forms.input" @@ -27,7 +27,7 @@ export class CreateOrganizationInput { @InputType('FormSystemOrganizationInput') export class OrganizationInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/steps.input.ts b/libs/api/domains/form-system/src/dto/steps.input.ts index 0a29112d9237..0a207b29a231 100644 --- a/libs/api/domains/form-system/src/dto/steps.input.ts +++ b/libs/api/domains/form-system/src/dto/steps.input.ts @@ -1,4 +1,4 @@ -import { Field, ID, InputType, Int } from "@nestjs/graphql" +import { Field, InputType, Int } from "@nestjs/graphql" import { LanguageTypeInput } from "./language.input" import { GroupInput } from "./groups.input" @@ -13,7 +13,7 @@ export class CreateStep { @InputType('FormSystemStepUpdate') export class UpdateStep { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageTypeInput, { nullable: true }) @@ -61,7 +61,7 @@ export class UpdateStepInput { @InputType('FormSystemStepInput') export class StepInput { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts index e434f349fb97..05902b4e7fb5 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts @@ -2,12 +2,15 @@ import { Args, Mutation, Query, Resolver } from "@nestjs/graphql" import { FormsService } from "./forms.service" import { FormResponse } from "../../models/formResponse.model" import { CreateFormInput, GetFormInput, GetFormsInput, UpdateFormInput, DeleteFormInput } from "../../dto/forms.input" -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { FormListResponse } from "../../models/formListResponse.model" import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common" + @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class FormsResolver { constructor(private readonly formsService: FormsService) { } diff --git a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts index 7c0e260d2591..a6c4262069f9 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts @@ -1,11 +1,13 @@ import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { GroupsService } from "./groups.service"; import { GetGroupInput, CreateGroupInput, DeleteGroupInput, UpdateGroupInput } from "../../dto/groups.input"; import { Group } from "../../models/group.model"; import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common"; @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class GroupsResolver { constructor(private readonly groupsService: GroupsService) { } diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts index 8d38a4c5d4dd..6c51f3ade530 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts @@ -1,11 +1,13 @@ import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { GetInputInput, CreateInputInput, DeleteInputInput, UpdateInputInput } from "../../dto/inputs.input"; import { Input } from "../../models/input.model"; import { InputsService } from "./inputs.service"; import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common"; @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class InputsResolver { constructor(private readonly inputsService: InputsService) { } diff --git a/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts b/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts index 175b3054d611..7f09f5d93364 100644 --- a/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts +++ b/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts @@ -1,13 +1,15 @@ import { Args, Mutation, Resolver } from "@nestjs/graphql"; import { OrganizationsService } from "./organizations.services"; import { CreateOrganizationInput } from "../../dto/organization.input"; -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { Organization } from "../../models/organization.model"; import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common"; @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class OrganizationsResolver { constructor(private readonly organizationsService: OrganizationsService) { } diff --git a/libs/api/domains/form-system/src/lib/services/services.resolver.ts b/libs/api/domains/form-system/src/lib/services/services.resolver.ts index 19b508a4bbc6..8eb9648ff03b 100644 --- a/libs/api/domains/form-system/src/lib/services/services.resolver.ts +++ b/libs/api/domains/form-system/src/lib/services/services.resolver.ts @@ -1,12 +1,14 @@ -import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { Query, Args, Resolver } from "@nestjs/graphql"; +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { FormSystemService } from "./services.service"; import { List } from "../../models/services.model"; import { GetPropertyInput } from "../../dto/services.input"; import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common"; @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class FormSystemServicesResolver { constructor(private readonly formSystemServices: FormSystemService) { } diff --git a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts index 965a6497ec49..792fda128b73 100644 --- a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts +++ b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts @@ -1,12 +1,14 @@ import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, type User } from '@island.is/auth-nest-tools' +import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' import { CreateStepInput, DeleteStepInput, GetStepInput, UpdateStepInput } from "../../dto/steps.input"; import { Step } from "../../models/step.model"; import { StepsService } from "./steps.service"; import { Audit } from '@island.is/nest/audit' +import { UseGuards } from "@nestjs/common"; @Resolver() +@UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class StepsResolver { constructor(private readonly stepsService: StepsService) { } diff --git a/libs/api/domains/form-system/src/models/applicantType.model.ts b/libs/api/domains/form-system/src/models/applicantType.model.ts index 87e5f72bf0d6..9e94e068804a 100644 --- a/libs/api/domains/form-system/src/models/applicantType.model.ts +++ b/libs/api/domains/form-system/src/models/applicantType.model.ts @@ -1,13 +1,13 @@ -import { Field, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; import { ApplicantTypeNameSuggestion } from "./applicantTypeNameSuggestion"; @ObjectType('FormSystemApplicantType') export class ApplicantType { - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number @Field(() => LanguageType, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts index d94ac42ba8b6..2d7c4d2d195a 100644 --- a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts +++ b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts @@ -1,4 +1,4 @@ -import { Field, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; @@ -7,6 +7,6 @@ export class ApplicantTypeNameSuggestion { @Field(() => LanguageType, { nullable: true }) nameSuggestion?: LanguageType - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number } diff --git a/libs/api/domains/form-system/src/models/documentType.model.ts b/libs/api/domains/form-system/src/models/documentType.model.ts index 94fe5bdac467..8fa4a045c200 100644 --- a/libs/api/domains/form-system/src/models/documentType.model.ts +++ b/libs/api/domains/form-system/src/models/documentType.model.ts @@ -1,9 +1,9 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; @ObjectType('FormSystemDocumentType') export class DocumentType { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts index 7b9a5d185494..abbdf6065268 100644 --- a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts +++ b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts @@ -1,4 +1,4 @@ -import { Field, ID, ObjectType, registerEnumType } from '@nestjs/graphql' +import { Field, Int, ObjectType, registerEnumType } from '@nestjs/graphql' import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' registerEnumType(EExternalEndpointType, { @@ -11,7 +11,7 @@ registerEnumType(EExternalEndpointEnvironment, { @ObjectType('FormSystemExternalEndpoints') export class ExternalEndpoints { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/form.model.ts b/libs/api/domains/form-system/src/models/form.model.ts index 681a53ad74ec..6a888c4bf0ac 100644 --- a/libs/api/domains/form-system/src/models/form.model.ts +++ b/libs/api/domains/form-system/src/models/form.model.ts @@ -1,4 +1,4 @@ -import { Field, ID, ObjectType } from '@nestjs/graphql' +import { Field, Int, ObjectType } from '@nestjs/graphql' import { LanguageType } from './global.model' import { Group } from './group.model' import { Input } from './input.model' @@ -14,7 +14,7 @@ export type Dependencies = { @ObjectType('FormSystemForm') export class Form { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageType, { nullable: true }) @@ -50,7 +50,7 @@ export class Form { @Field() stopProgressOnValidatingStep?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicationsDaysToRemove?: number @Field(() => [Step], { nullable: 'itemsAndList' }) diff --git a/libs/api/domains/form-system/src/models/formApplicantType.model.ts b/libs/api/domains/form-system/src/models/formApplicantType.model.ts index 9bee9bdc5727..8264b7f434d9 100644 --- a/libs/api/domains/form-system/src/models/formApplicantType.model.ts +++ b/libs/api/domains/form-system/src/models/formApplicantType.model.ts @@ -1,13 +1,13 @@ -import { ObjectType, Field } from "@nestjs/graphql"; +import { ObjectType, Field, Int } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; @ObjectType('FormSystemFormApplicantType') export class FormApplicantType { - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) formId?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) applicantTypeId?: number @Field(() => LanguageType, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/group.model.ts b/libs/api/domains/form-system/src/models/group.model.ts index 9b26cf0aad9f..8cd3a15ab84f 100644 --- a/libs/api/domains/form-system/src/models/group.model.ts +++ b/libs/api/domains/form-system/src/models/group.model.ts @@ -1,10 +1,10 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; import { Input } from "./input.model"; @ObjectType('FormSystemGroup') export class Group { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageType, { nullable: true }) @@ -22,7 +22,7 @@ export class Group { @Field(() => [Input]) inputs?: Input[] | null - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) stepId?: number @Field(() => Number, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index 3e7a5f2d1c01..2d243765a0c5 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -1,4 +1,4 @@ -import { Field, ID, ObjectType } from '@nestjs/graphql' +import { Field, Int, ObjectType } from '@nestjs/graphql' import graphqlTypeJson from 'graphql-type-json' import { InputSettings } from './inputSettings.model' @@ -6,7 +6,7 @@ import { LanguageType } from './global.model' @ObjectType('FormSystemInput') export class Input { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageType, { nullable: true }) @@ -18,10 +18,10 @@ export class Input { @Field() isRequired?: boolean - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) groupId?: number @Field() diff --git a/libs/api/domains/form-system/src/models/listType.model.ts b/libs/api/domains/form-system/src/models/listType.model.ts index 5a751e549899..c89a60f9b02d 100644 --- a/libs/api/domains/form-system/src/models/listType.model.ts +++ b/libs/api/domains/form-system/src/models/listType.model.ts @@ -1,10 +1,10 @@ -import { Field, ID, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; @ObjectType('FormSystemListType') export class ListType { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/organization.model.ts b/libs/api/domains/form-system/src/models/organization.model.ts index e29ff62f7c2e..59f890027be3 100644 --- a/libs/api/domains/form-system/src/models/organization.model.ts +++ b/libs/api/domains/form-system/src/models/organization.model.ts @@ -1,4 +1,4 @@ -import { Field, ID, ObjectType } from '@nestjs/graphql' +import { Field, Int, ObjectType } from '@nestjs/graphql' import { LanguageType } from './global.model' import { Input } from './input.model' import { ApplicantType } from './applicantType.model' @@ -9,7 +9,7 @@ import { Form } from './form.model' @ObjectType('FormSystemOrganization') export class Organization { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => LanguageType, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/step.model.ts b/libs/api/domains/form-system/src/models/step.model.ts index 0aa1587da5ce..d6ae6625d194 100644 --- a/libs/api/domains/form-system/src/models/step.model.ts +++ b/libs/api/domains/form-system/src/models/step.model.ts @@ -1,10 +1,10 @@ -import { Field, ID, Int, ObjectType } from "@nestjs/graphql"; +import { Field, Int, ObjectType } from "@nestjs/graphql"; import { LanguageType } from "./global.model"; import { Group } from "./group.model"; @ObjectType('FormSystemStep') export class Step { - @Field(() => ID, { nullable: true }) + @Field(() => Int, { nullable: true }) id?: number @Field(() => String, { nullable: true }) diff --git a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx index d60595cb51bc..5775fc118431 100644 --- a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx +++ b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx @@ -20,11 +20,11 @@ import { import { FormSystemPaths } from '../../lib/paths' interface Props { - id?: number + id?: number | null name?: string created?: Date lastModified?: Date - org?: number + org?: number | null state?: number options?: string isHeader: boolean diff --git a/libs/portals/admin/form-system/src/lib/messages.ts b/libs/portals/admin/form-system/src/lib/messages.ts index c48cf2156067..7db8d5c3d174 100644 --- a/libs/portals/admin/form-system/src/lib/messages.ts +++ b/libs/portals/admin/form-system/src/lib/messages.ts @@ -2,13 +2,13 @@ import { defineMessages } from "react-intl"; export const m = defineMessages({ - formSystemTitle: { - id: 'admin-portal.form-system:formSystemTitle', + formSystemIntro: { + id: 'admin-portal.form-system:formSystemIntro', defaultMessage: 'Umsóknakerfi', description: '' }, - formSystemIntro: { - id: 'admin-portal.form-system:intro', + formSystemTitle: { + id: 'admin-portal.form-system:Title', defaultMessage: 'Umsóknarsmiður fyrir stofnanir', description: '' } diff --git a/libs/portals/admin/form-system/src/module.ts b/libs/portals/admin/form-system/src/module.ts deleted file mode 100644 index f870e9037041..000000000000 --- a/libs/portals/admin/form-system/src/module.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { PortalModule } from '@island.is/portals/core' -import { lazy } from 'react' -import { m } from './lib/messages' -import { FormSystemPaths } from './lib/paths' -import { AdminPortalScope } from '@island.is/auth/scopes' diff --git a/libs/portals/admin/form-system/src/module.tsx b/libs/portals/admin/form-system/src/module.tsx new file mode 100644 index 000000000000..4ffd77dfc62c --- /dev/null +++ b/libs/portals/admin/form-system/src/module.tsx @@ -0,0 +1,32 @@ +import { lazy } from 'react'; +import { AdminPortalScope } from '@island.is/auth/scopes' +import { m } from './lib/messages'; +import { PortalModule } from '@island.is/portals/core' +import { FormSystemPaths } from './lib/paths' +import { formsLoader } from './screens/Forms/Forms.loader'; + +const Forms = lazy(() => + import('./screens/Forms/Forms') +) + +const allowedScopes: string[] = [ + AdminPortalScope.formSystem, + AdminPortalScope.formSystemSuperUser +] + +export const formSystemModule: PortalModule = { + name: m.formSystemIntro, + layout: 'full', + enabled: ({ userInfo }) => + userInfo.scopes.some((scope) => allowedScopes.includes(scope)), + routes: (props) => { + return [ + { + name: m.formSystemTitle, + path: FormSystemPaths.FormSystemRoot, + element: , + loader: formsLoader(props) + } + ] + } +} diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.tsx b/libs/portals/admin/form-system/src/screens/Form/Form.tsx new file mode 100644 index 000000000000..0a975f0d4415 --- /dev/null +++ b/libs/portals/admin/form-system/src/screens/Form/Form.tsx @@ -0,0 +1,137 @@ +import { + useState, + useContext, + useReducer, + useRef, + useEffect, + FocusEvent, +} from 'react' +import FormBuilderContext from '../context/FormBuilderContext' +import LayoutContext from '../context/LayoutContext' +import { formReducer } from '../hooks/formReducer' +import { listsReducer } from '../hooks/listsReducer' +import { updateForm, updateItem } from '../services/apiService' +import { + IFormBuilder, + IFormBuilderContext, + IListItem, + ILists, + NavbarSelectStatus, +} from '../types/interfaces' +import { defaultStep } from '../utils/defaultStep' +import { baseSettingsStep } from '../utils/getBaseSettingsStep' +import { + GridRow as Row, + GridColumn as Column, + Box, +} from '@island.is/island-ui/core' +import Navbar from '../components/Navbar/Navbar' +import NavbarSelect from '../components/NavbarSelect/NavbarSelect' +import MainContent from '../components/MainContent/MainContent' + +type Props = { + form: IFormBuilder +} + +export default function Form({ form }: Props) { + const [focus, setOnFocus] = useState('') + const [inSettings, setInSettings] = useState(form.form.name.is === '') + const [selectStatus, setSelectStatus] = useState( + NavbarSelectStatus.OFF, + ) + const [activeListItem, setActiveListItem] = useState(null) + const { infoDispatch } = useContext(LayoutContext) + const initialNavbar: ILists = { + activeItem: inSettings + ? { type: 'Step', data: baseSettingsStep } + : { + type: 'Step', + data: + form?.form?.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, + steps: form.form.stepsList ?? [], + groups: form.form.groupsList ?? [], + inputs: form.form.inputsList ?? [], + } + const [formBuilder, formDispatch] = useReducer(formReducer, form) + const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) + const { activeItem } = lists + + const isMounted = useRef(false) + + useEffect(() => { + isMounted.current = true + infoDispatch({ + type: 'changeOrganization', + payload: { + value: formBuilder?.form?.organization.name.is, + }, + }) + infoDispatch({ + type: 'changeApplicationName', + payload: { + value: formBuilder.form.name.is, + }, + }) + }, [formBuilder, infoDispatch]) + + const context: IFormBuilderContext = { + formBuilder: formBuilder, + formDispatch: formDispatch, + lists: lists, + listsDispatch: listsDispatch, + formUpdate: formUpdate, + inSettings: inSettings, + setInSettings: setInSettings, + setSelectStatus: setSelectStatus, + selectStatus: selectStatus, + activeListItem: activeListItem, + setActiveListItem: setActiveListItem, + blur: blur, + onFocus: onFocus, + } + + if (formBuilder.form && activeItem) { + return ( + + + + {selectStatus !== NavbarSelectStatus.OFF ? ( + + ) : ( + + )} + + + + {activeItem?.data && } + + + + + ) + } + return <>Loading + + async function formUpdate() { + updateForm(formBuilder.form, lists.steps, lists.groups, lists.inputs) + } + + function blur(e: FocusEvent) { + if (e.target.value !== focus) { + setOnFocus('') + updateItem(activeItem.type, activeItem.data) + } + } + + function onFocus(value: string) { + setOnFocus(value) + } +} diff --git a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql index c97949bd52c6..496ad9a13fc7 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql @@ -3,5 +3,5 @@ mutation formSystemCreateForm( ) { formSystemCreateForm(input: $input) { form -} + } } diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql b/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql index 8bd38de16ee4..62f00817c0eb 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql @@ -2,6 +2,19 @@ query formSystemGetForms( $input: FormSystemGetFormsInput! ) { formSystemGetForms(input: $input) { - forms + forms { + id + name { + is + en + } + created + lastChanged + organization { + id + } + isTranslated + } } } + diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts index 819ea04fe666..142a62ecd866 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts @@ -1,12 +1,25 @@ import { WrappedLoaderFn } from '@island.is/portals/core' -import { FormSystemGetFormsQuery } from './Forms.generated' +import { FormSystemGetFormsDocument, FormSystemGetFormsQuery } from './Forms.generated' +import { FormSystemForm } from '@island.is/api/schema' export const formsLoader: WrappedLoaderFn = ({ client }) => { - return async ()/*: Promise*/ => { + return async (): Promise> => { const { data, error } = await client.query({ - + query: FormSystemGetFormsDocument, + variables: { + input: { + organizationId: 1 + } + } }) + if (error) { + throw error + } + if (!data) { + throw new Error('No forms were found') + } + return data.formSystemGetForms.forms?.filter((form) => form !== null) as FormSystemForm[]; } } diff --git a/libs/portals/admin/form-system/src/screens/Forms/index.tsx b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx similarity index 66% rename from libs/portals/admin/form-system/src/screens/Forms/index.tsx rename to libs/portals/admin/form-system/src/screens/Forms/Forms.tsx index 364c55ab831b..9ccf13011295 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/index.tsx +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx @@ -7,18 +7,21 @@ import { import { useNavigate } from 'react-router-dom' import { FormSystemPaths } from '../../lib/paths' import TableRow from '../../components/TableRow/TableRow' +import { useFormSystemGetFormsQuery } from './Forms.generated' + const Forms = () => { const navigate = useNavigate() - // const {data: formBuilder, loading} = useGetFormBuilderQuery({ - // variables: { - // input: 1 - // } - // }) - const formBuilder: any = { - forms: [] - } + const { data, loading, error } = useFormSystemGetFormsQuery({ + variables: { + input: { + organizationId: 1 + } + } + }) - if (navigate) { + const forms = data?.formSystemGetForms.forms + console.log(data) + if (!loading && !error) { return ( {/* Title and buttons */} @@ -49,18 +52,18 @@ const Forms = () => { - {formBuilder.forms && - formBuilder.forms?.map((f) => { + {forms && + forms?.map((f) => { return ( ) })} From af195c6b240671f7fc0ac38d71d8c736f227c6e5 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Wed, 20 Mar 2024 12:21:37 +0000 Subject: [PATCH 25/72] Update FormSystemClient.config and Forms component --- libs/clients/form-system/src/lib/FormSystemClient.config.ts | 2 +- libs/portals/admin/form-system/src/module.tsx | 4 ++-- libs/portals/admin/form-system/src/screens/Forms/Forms.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/clients/form-system/src/lib/FormSystemClient.config.ts b/libs/clients/form-system/src/lib/FormSystemClient.config.ts index 5f35df3842ee..19b9da808e20 100644 --- a/libs/clients/form-system/src/lib/FormSystemClient.config.ts +++ b/libs/clients/form-system/src/lib/FormSystemClient.config.ts @@ -10,7 +10,7 @@ export const FormSystemClientConfig = defineConfig({ schema, load(env) { return { - basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'http://localhost:4200'), + basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://profun.island.is/umsoknarkerfi'), } } }) diff --git a/libs/portals/admin/form-system/src/module.tsx b/libs/portals/admin/form-system/src/module.tsx index 4ffd77dfc62c..407fe3ce6a0c 100644 --- a/libs/portals/admin/form-system/src/module.tsx +++ b/libs/portals/admin/form-system/src/module.tsx @@ -19,13 +19,13 @@ export const formSystemModule: PortalModule = { layout: 'full', enabled: ({ userInfo }) => userInfo.scopes.some((scope) => allowedScopes.includes(scope)), - routes: (props) => { + routes: () => { return [ { name: m.formSystemTitle, path: FormSystemPaths.FormSystemRoot, element: , - loader: formsLoader(props) + // loader: formsLoader(props) } ] } diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx index 9ccf13011295..9c3058c80702 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx @@ -70,7 +70,7 @@ const Forms = () => { ) } - return <> + return <>AAAAA } export default Forms From 1767ba633396eab8c31009f8f986359aa2637f48 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Mon, 8 Apr 2024 15:06:49 +0000 Subject: [PATCH 26/72] Saving progress --- .../form-system/src/dto/forms.input.ts | 10 +- .../form-system/src/dto/groups.input.ts | 4 +- .../form-system/src/dto/language.input.ts | 2 +- .../form-system/src/dto/steps.input.ts | 2 +- .../src/lib/forms/forms.resolver.ts | 8 +- .../src/lib/forms/forms.service.ts | 11 +- .../src/lib/groups/groups.resolver.ts | 10 +- .../src/lib/groups/groups.service.ts | 8 +- .../src/lib/inputs/inputs.resolver.ts | 11 +- .../src/lib/inputs/inputs.service.ts | 10 +- .../src/lib/steps/steps.resolver.ts | 10 +- .../src/lib/steps/steps.service.ts | 10 +- .../src/lib/utils/helperFunctions.ts | 4 +- .../form-system/src/models/form.model.ts | 10 +- .../form-system/src/models/group.model.ts | 6 +- .../form-system/src/models/input.model.ts | 6 +- .../form-system/src/models/step.model.ts | 2 +- .../MainContent/MainContent.css.tsx | 10 + .../components/MainContent/MainContent.tsx | 106 ++ .../components/BaseSettings/BaseSettings.tsx | 99 ++ .../components/InputContent/InputContent.tsx | 22 + .../InputContent/components/BaseInput.tsx | 162 +++ .../InputSettings/InputSettings.tsx | 0 .../components/MessageWithLinkSettings.tsx | 93 ++ .../components/Premises/Premises.tsx | 55 + .../components/Preview/Preveiw.tsx | 22 + .../Preview/components/MessageWithLink.tsx | 60 + .../src/components/Navbar/Navbar.tsx | 325 +++++ .../NavComponent/NavComponent.css.ts | 90 ++ .../components/NavComponent/NavComponent.tsx | 175 +++ .../NavComponent/components/NavButtons.tsx | 113 ++ .../components/NavbarTab/NavbarTab.css.tsx | 17 + .../Navbar/components/NavbarTab/NavbarTab.tsx | 60 + .../components/NavbarSelect/NavbarSelect.tsx | 65 + .../components/SelectNavComponent.tsx | 146 +++ .../components/selectNavComponent.css.ts | 90 ++ .../src/components/TableRow/TableRow.tsx | 7 +- .../form-system/src/context/ControlContext.ts | 60 + .../src/context/FormBuilderContext.tsx | 50 + .../form-system/src/context/LayoutContext.tsx | 14 + .../form-system/src/context/UserContext.tsx | 13 + .../admin/form-system/src/gql/Form.graphql | 1150 +++++++++++++++++ .../admin/form-system/src/gql/Group.graphql | 90 ++ .../admin/form-system/src/gql/Input.graphql | 77 ++ .../admin/form-system/src/gql/Step.graphql | 107 ++ .../form-system/src/hooks/controlReducer.ts | 370 ++++++ .../src/hooks/fileUploadReducer.ts | 43 + .../form-system/src/hooks/formReducer.ts | 199 +++ .../src/hooks/headerInfoReducer.ts | 29 + .../form-system/src/hooks/settingsReducer.ts | 18 + .../admin/form-system/src/hooks/useUser.ts | 40 + .../admin/form-system/src/lib/messages.ts | 4 +- .../admin/form-system/src/lib/navigation.ts | 2 +- .../form-system/src/lib/utils/interfaces.ts | 16 + .../src/lib/utils/updateActiveItem.ts | 85 ++ .../form-system/src/lib/utils/updateDnd.ts | 97 ++ .../form-system/src/lib/utils/updateForm.ts | 33 + libs/portals/admin/form-system/src/module.tsx | 13 +- .../src/screens/Form/Form.loader.ts | 39 + .../form-system/src/screens/Form/Form.tsx | 219 ++-- .../src/screens/Forms/CreateForm.graphql | 565 +++++++- .../src/screens/Forms/Forms.loader.ts | 9 +- .../form-system/src/screens/Forms/Forms.tsx | 23 +- .../form-system/src/services/apiService.tsx | 248 ++++ .../src/services/translationStation.tsx | 41 + .../form-system/src/services/zodValidation.ts | 193 +++ .../form-system/src/types/interfaces.tsx | 40 +- .../form-system/src/utils/defaultStep.tsx | 4 +- .../admin/form-system/src/utils/fileTypes.ts | 58 + libs/portals/admin/form-system/tsconfig.json | 3 +- package.json | 2 + yarn.lock | 17 +- 72 files changed, 5598 insertions(+), 214 deletions(-) create mode 100644 libs/portals/admin/form-system/src/components/MainContent/MainContent.css.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx create mode 100644 libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx create mode 100644 libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.css.ts create mode 100644 libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx create mode 100644 libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx create mode 100644 libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.css.tsx create mode 100644 libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx create mode 100644 libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx create mode 100644 libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx create mode 100644 libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts create mode 100644 libs/portals/admin/form-system/src/context/ControlContext.ts create mode 100644 libs/portals/admin/form-system/src/context/FormBuilderContext.tsx create mode 100644 libs/portals/admin/form-system/src/context/LayoutContext.tsx create mode 100644 libs/portals/admin/form-system/src/context/UserContext.tsx create mode 100644 libs/portals/admin/form-system/src/gql/Form.graphql create mode 100644 libs/portals/admin/form-system/src/gql/Group.graphql create mode 100644 libs/portals/admin/form-system/src/gql/Input.graphql create mode 100644 libs/portals/admin/form-system/src/gql/Step.graphql create mode 100644 libs/portals/admin/form-system/src/hooks/controlReducer.ts create mode 100644 libs/portals/admin/form-system/src/hooks/fileUploadReducer.ts create mode 100644 libs/portals/admin/form-system/src/hooks/formReducer.ts create mode 100644 libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts create mode 100644 libs/portals/admin/form-system/src/hooks/settingsReducer.ts create mode 100644 libs/portals/admin/form-system/src/hooks/useUser.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/interfaces.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/updateDnd.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/updateForm.ts create mode 100644 libs/portals/admin/form-system/src/screens/Form/Form.loader.ts create mode 100644 libs/portals/admin/form-system/src/services/apiService.tsx create mode 100644 libs/portals/admin/form-system/src/services/translationStation.tsx create mode 100644 libs/portals/admin/form-system/src/services/zodValidation.ts create mode 100644 libs/portals/admin/form-system/src/utils/fileTypes.ts diff --git a/libs/api/domains/form-system/src/dto/forms.input.ts b/libs/api/domains/form-system/src/dto/forms.input.ts index 640cf6f9c211..ad1cf2ab265c 100644 --- a/libs/api/domains/form-system/src/dto/forms.input.ts +++ b/libs/api/domains/form-system/src/dto/forms.input.ts @@ -53,7 +53,7 @@ export class FormInput { @Field(() => Date, { nullable: true }) invalidationDate?: Date | null - @Field(() => graphqlTypeJson) + @Field(() => graphqlTypeJson, { nullable: true }) dependencies?: { [key: string]: string[] } | null @Field(() => [DocumentTypeInput], { nullable: 'itemsAndList' }) @@ -65,11 +65,11 @@ export class FormInput { @Field(() => LanguageTypeInput, { nullable: true }) completedMessage?: LanguageTypeInput - @Field() - isTranslated?: boolean + @Field(() => Boolean, { nullable: true }) + isTranslated?: boolean | null - @Field() - stopProgressOnValidatingStep?: boolean + @Field(() => Boolean, { nullable: true }) + stopProgressOnValidatingStep?: boolean | null @Field(() => Int, { nullable: true }) applicationsDaysToRemove?: number diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index 2158946c0811..1ff558b4f8ec 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -74,13 +74,13 @@ export class GroupInput { @Field(() => Boolean, { nullable: true }) isHidden?: boolean - @Field(() => [InputInput]) + @Field(() => [InputInput], { nullable: 'itemsAndList' }) inputs?: InputInput[] | null @Field(() => Int, { nullable: true }) stepId?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) multiSet?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/dto/language.input.ts b/libs/api/domains/form-system/src/dto/language.input.ts index 5d7c1e8856d5..bd282bf0bc68 100644 --- a/libs/api/domains/form-system/src/dto/language.input.ts +++ b/libs/api/domains/form-system/src/dto/language.input.ts @@ -1,6 +1,6 @@ import { Field, InputType } from "@nestjs/graphql"; -@InputType('FormSystemGlobalInput') +@InputType('FormSystemLanguageTypeInput') export class LanguageTypeInput { @Field(() => String, { nullable: true }) is?: string | null diff --git a/libs/api/domains/form-system/src/dto/steps.input.ts b/libs/api/domains/form-system/src/dto/steps.input.ts index 0a207b29a231..7b9da446ce88 100644 --- a/libs/api/domains/form-system/src/dto/steps.input.ts +++ b/libs/api/domains/form-system/src/dto/steps.input.ts @@ -80,7 +80,7 @@ export class StepInput { waitingText?: LanguageTypeInput @Field(() => Boolean, { nullable: true }) - callRulest?: boolean + callRuleset?: boolean @Field(() => Boolean, { nullable: true }) isHidden?: boolean diff --git a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts index 05902b4e7fb5..b6249a7a74cf 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts @@ -45,7 +45,8 @@ export class FormsResolver { return this.formsService.postForm(user, input) } - @Mutation(() => FormResponse, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemUpdateForm' }) async updateForm( @@ -55,14 +56,15 @@ export class FormsResolver { return this.formsService.updateForm(user, input) } - @Mutation(() => FormResponse, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemDeleteForm' }) async deleteForm( @Args('input', { type: () => DeleteFormInput }) input: DeleteFormInput, @CurrentUser() user: User ): Promise { - return this.formsService.deleteForm(user, input) + return await this.formsService.deleteForm(user, input) } diff --git a/libs/api/domains/form-system/src/lib/forms/forms.service.ts b/libs/api/domains/form-system/src/lib/forms/forms.service.ts index 39e8cb57e0a6..ae0a03ced213 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.service.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.service.ts @@ -6,7 +6,7 @@ import { AuthMiddleware, User } from '@island.is/auth-nest-tools' import { CreateFormInput, DeleteFormInput, GetFormInput, GetFormsInput, UpdateFormInput } from "../../dto/forms.input" import { FormResponse } from "../../models/formResponse.model" import { FormListResponse } from "../../models/formListResponse.model" -import { GraphqlToRestInputSettings, RESTInputSettings, RestToGraphqlInputSettings } from "../utils/helperFunctions" +import { graphqlToRestInputSettings, RESTInputSettings, restToGraphqlInputSettings } from "../utils/helperFunctions" import { Form } from "../../models/form.model" import { Input } from "../../models/input.model" @@ -59,7 +59,7 @@ export class FormsService { inputsList: response.form?.inputsList?.map((input) => { return { ...input, - inputSettings: RestToGraphqlInputSettings(input.inputSettings as RESTInputSettings) + inputSettings: restToGraphqlInputSettings(input.inputSettings as RESTInputSettings) } }) } @@ -114,10 +114,11 @@ export class FormsService { async updateForm(auth: User, input: UpdateFormInput): Promise { const formattedForm = { ...input.form, + id: input.formId, inputsList: input.form?.inputsList?.map((input) => { return { ...input, - inputSettings: GraphqlToRestInputSettings(input.inputSettings) + inputSettings: graphqlToRestInputSettings(input.inputSettings) } }) } @@ -126,11 +127,11 @@ export class FormsService { formId: input.formId, formUpdateDto: formattedForm as FormUpdateDto, } - + console.log('request: ', request) const response = await this.formsApiWithAuth(auth) .apiFormsFormIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update form')) - + console.log('response: ', response) if (!response || response instanceof ApolloError) { return void 0 } diff --git a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts index a6c4262069f9..3d71b5e3aaff 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts @@ -32,23 +32,25 @@ export class GroupsResolver { return this.groupsService.postGroup(user, input) } - @Mutation(() => Group, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemDeleteGroup' }) async deleteGroup( @Args('input', { type: () => DeleteGroupInput }) input: DeleteGroupInput, @CurrentUser() user: User ): Promise { - return this.groupsService.deleteGroup(user, input) + return await this.groupsService.deleteGroup(user, input) } - @Mutation(() => Group, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemUpdateGroup' }) async updateGroup( @Args('input', { type: () => UpdateGroupInput }) input: UpdateGroupInput, @CurrentUser() user: User - ): Promise { + ): Promise { return this.groupsService.updateGroup(user, input) } } diff --git a/libs/api/domains/form-system/src/lib/groups/groups.service.ts b/libs/api/domains/form-system/src/lib/groups/groups.service.ts index f5cf98fe5ff2..91b0da53aae3 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.service.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.service.ts @@ -72,12 +72,12 @@ export class GroupsService { .catch((e) => this.handle4xx(e, 'failed to delete group')) if (!response || response instanceof ApolloError) { - return + return void 0 } - return response as void + return response } - async updateGroup(auth: User, input: UpdateGroupInput): Promise { + async updateGroup(auth: User, input: UpdateGroupInput): Promise { const request: ApiGroupsGroupIdPutRequest = { groupId: input.groupId, groupUpdateDto: input.groupUpdateDto as GroupUpdateDto @@ -88,7 +88,7 @@ export class GroupsService { .catch((e) => this.handle4xx(e, 'failed to update group')) if (!response || response instanceof ApolloError) { - return {} + return void 0 } return response } diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts index 6c51f3ade530..e45945ad0122 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts @@ -32,23 +32,26 @@ export class InputsResolver { return this.inputsService.postInput(user, input) } - @Mutation(() => Input, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemDeleteInput' }) async deleteInput( @Args('input', { type: () => DeleteInputInput }) input: DeleteInputInput, @CurrentUser() user: User ): Promise { - return this.inputsService.deleteInput(user, input) + const response = await this.inputsService.deleteInput(user, input) + return response } - @Mutation(() => Input, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemUpdateInput' }) async updateInput( @Args('input', { type: () => UpdateInputInput }) input: UpdateInputInput, @CurrentUser() user: User - ): Promise { + ): Promise { return this.inputsService.updateInput(user, input) } } diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts index 631a3086140f..8d298e87c607 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts @@ -72,12 +72,12 @@ export class InputsService { .catch((e) => this.handle4xx(e, 'failed to delete input')) if (!response || response instanceof ApolloError) { - return + return void 0 } - return response as void + return response } - async updateInput(auth: User, input: UpdateInputInput): Promise { + async updateInput(auth: User, input: UpdateInputInput): Promise { const request: ApiInputsInputIdPutRequest = { inputId: input.inputId, inputUpdateDto: input.inputUpdateDto as InputUpdateDto, @@ -88,8 +88,8 @@ export class InputsService { .catch((e) => this.handle4xx(e, 'failed to update input')) if (!response || response instanceof ApolloError) { - return {} + return void 0 } - return response as Input + return response } } diff --git a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts index 792fda128b73..edfd08429eb7 100644 --- a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts +++ b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts @@ -33,23 +33,25 @@ export class StepsResolver { return this.stepsService.postStep(user, input) } - @Mutation(() => Step, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemDeleteStep' }) async deleteStep( @Args('input', { type: () => DeleteStepInput }) input: DeleteStepInput, @CurrentUser() user: User ): Promise { - return this.stepsService.deleteStep(user, input) + return await this.stepsService.deleteStep(user, input) } - @Mutation(() => Step, { + @Mutation(() => Boolean, { + nullable: true, name: 'formSystemUpdateStep' }) async updateStep( @Args('input', { type: () => UpdateStepInput }) input: UpdateStepInput, @CurrentUser() user: User - ): Promise { + ): Promise { return this.stepsService.updateStep(user, input) } } diff --git a/libs/api/domains/form-system/src/lib/steps/steps.service.ts b/libs/api/domains/form-system/src/lib/steps/steps.service.ts index 3a8ac2af463f..6b46bc31740a 100644 --- a/libs/api/domains/form-system/src/lib/steps/steps.service.ts +++ b/libs/api/domains/form-system/src/lib/steps/steps.service.ts @@ -72,12 +72,12 @@ export class StepsService { .catch((e) => this.handle4xx(e, 'failed to delete step')) if (!response || response instanceof ApolloError) { - return + return void 0 } - return response as void + return response } - async updateStep(auth: User, input: UpdateStepInput): Promise { + async updateStep(auth: User, input: UpdateStepInput): Promise { const request: ApiStepsStepIdPutRequest = { stepId: input.stepId, stepUpdateDto: input.stepUpdateDto @@ -88,8 +88,8 @@ export class StepsService { .catch((e) => this.handle4xx(e, 'failed to update step')) if (!response || response instanceof ApolloError) { - return {} + return void 0 } - return response as Step + return response } } diff --git a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts b/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts index 93d2cb5b7ade..a6dcd01c792a 100644 --- a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts +++ b/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts @@ -47,7 +47,7 @@ interface GraphQLInputSettings { [key: string]: unknown } -export function RestToGraphqlInputSettings(input?: RESTInputSettings): GraphQLInputSettings { +export function restToGraphqlInputSettings(input?: RESTInputSettings): GraphQLInputSettings { return { hasInput: input?.erInnslattur, isList: input?.erListi, @@ -70,7 +70,7 @@ export function RestToGraphqlInputSettings(input?: RESTInputSettings): GraphQLIn } } -export function GraphqlToRestInputSettings(input?: InputSettings): RESTInputSettings { +export function graphqlToRestInputSettings(input?: InputSettings): RESTInputSettings { return { erInnslattur: input?.hasInput, erListi: input?.isList, diff --git a/libs/api/domains/form-system/src/models/form.model.ts b/libs/api/domains/form-system/src/models/form.model.ts index 6a888c4bf0ac..27b3c61c19f3 100644 --- a/libs/api/domains/form-system/src/models/form.model.ts +++ b/libs/api/domains/form-system/src/models/form.model.ts @@ -32,7 +32,7 @@ export class Form { @Field(() => Date, { nullable: true }) invalidationDate?: Date | null - @Field(() => graphqlTypeJson) + @Field(() => graphqlTypeJson, { nullable: true }) dependencies?: { [key: string]: string[] } | null @Field(() => [DocumentType], { nullable: 'itemsAndList' }) @@ -44,11 +44,11 @@ export class Form { @Field(() => LanguageType, { nullable: true }) completedMessage?: LanguageType - @Field() - isTranslated?: boolean + @Field(() => Boolean, { nullable: true }) + isTranslated?: boolean | null - @Field() - stopProgressOnValidatingStep?: boolean + @Field(() => Boolean, { nullable: true }) + stopProgressOnValidatingStep?: boolean | null @Field(() => Int, { nullable: true }) applicationsDaysToRemove?: number diff --git a/libs/api/domains/form-system/src/models/group.model.ts b/libs/api/domains/form-system/src/models/group.model.ts index 8cd3a15ab84f..e742b2bc7e63 100644 --- a/libs/api/domains/form-system/src/models/group.model.ts +++ b/libs/api/domains/form-system/src/models/group.model.ts @@ -13,19 +13,19 @@ export class Group { @Field(() => String, { nullable: true }) guid?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) displayOrder?: number @Field(() => Boolean, { nullable: true }) isHidden?: boolean - @Field(() => [Input]) + @Field(() => [Input], { nullable: 'itemsAndList' }) inputs?: Input[] | null @Field(() => Int, { nullable: true }) stepId?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) multiSet?: number @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index 2d243765a0c5..a7d41e0f70cb 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -15,7 +15,7 @@ export class Input { @Field(() => LanguageType, { nullable: true }) description?: LanguageType - @Field() + @Field(() => Boolean, { nullable: true }) isRequired?: boolean @Field(() => Int, { nullable: true }) @@ -24,7 +24,7 @@ export class Input { @Field(() => Int, { nullable: true }) groupId?: number - @Field() + @Field(() => Boolean, { nullable: true }) isHidden?: boolean @Field(() => String, { nullable: true }) @@ -33,7 +33,7 @@ export class Input { @Field(() => String, { nullable: true }) guid?: string - @Field() + @Field(() => Boolean, { nullable: true }) isPartOfMultiSet?: boolean @Field(() => String, { nullable: true }) diff --git a/libs/api/domains/form-system/src/models/step.model.ts b/libs/api/domains/form-system/src/models/step.model.ts index d6ae6625d194..078b28382eb7 100644 --- a/libs/api/domains/form-system/src/models/step.model.ts +++ b/libs/api/domains/form-system/src/models/step.model.ts @@ -23,7 +23,7 @@ export class Step { waitingText?: LanguageType @Field(() => Boolean, { nullable: true }) - callRulest?: boolean + callRuleset?: boolean @Field(() => Boolean, { nullable: true }) isHidden?: boolean diff --git a/libs/portals/admin/form-system/src/components/MainContent/MainContent.css.tsx b/libs/portals/admin/form-system/src/components/MainContent/MainContent.css.tsx new file mode 100644 index 000000000000..876de2545582 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/MainContent.css.tsx @@ -0,0 +1,10 @@ +import { style } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const mainContent = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + width: '100%', + height: '100%', + marginTop: '50px', +}) diff --git a/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx new file mode 100644 index 000000000000..eb0930a10b0c --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx @@ -0,0 +1,106 @@ +import { + Box, + Input, + Stack, + GridRow as Row, + GridColumn as Column, + Button, + Checkbox, +} from '@island.is/island-ui/core' +import { useContext, useState } from 'react' +import ControlContext from '../../context/ControlContext' +import { FormSystemGroup, FormSystemStep } from '@island.is/api/schema' +import BaseSettings from './components/BaseSettings/BaseSettings' +import Premises from './components/Premises/Premises' +import InputContent from './components/InputContent/InputContent' + +export default function MainContent() { + const { control, controlDispatch, updateActiveItem, setFocus, focus } = useContext(ControlContext) + const { activeItem, form, } = control + const [openPreview, setOpenPreview] = useState(false) + + + + return ( + + + {activeItem.type === 'Input' ? () + : activeItem.type === 'Step' && + (activeItem.data as FormSystemStep).type === 'BaseSetting' ? () + : activeItem.type === 'Step' && + (activeItem.data as FormSystemStep).type === 'Forsendur' ? () + : + < Stack space={2}> + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'en', + newValue: e.target.value, + }, + + })} + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + {activeItem.type === 'Group' && ( + + + + // listsDispatch({ + // type: 'setMultiSet', + // payload: { + // checked: e.target.checked, + // }, + // }) + // } + /> + + + )} + + + + + + + } + + ) +} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx new file mode 100644 index 000000000000..73a4769de037 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -0,0 +1,99 @@ + +import { + Stack, + GridRow as Row, + GridColumn as Column, + Input, + DatePicker, + Checkbox, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import ControlContext from '../../../../context/ControlContext' + +export const BaseSettings = () => { + const { control, controlDispatch, setFocus, focus, formSettingsUpdate } = useContext(ControlContext) + const { form } = control + console.log('BaseSettings form', form) + return ( + + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'is', newValue: e.target.value } })} + /> + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'en', newValue: e.target.value } })} + /> + + + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onChange={(e) => controlDispatch({ type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', payload: { value: parseInt(e.target.value) } })} + /> + + + + + { + controlDispatch({ type: 'CHANGE_INVALIDATION_DATE', payload: { value: e } }) + }} + handleCloseCalendar={() => formSettingsUpdate()} + /> + + + + + { + console.log('stopProgressOnValidatingStep', e.target.checked) + formSettingsUpdate({ ...form, stopProgressOnValidatingStep: e.target.checked }) + }} + + /> + + + + ) +} + +export default BaseSettings diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx new file mode 100644 index 000000000000..71bb0bea6e35 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx @@ -0,0 +1,22 @@ +import { useContext } from "react" +import ControlContext from "../../../../context/ControlContext" +import { Stack } from "@island.is/island-ui/core" +import BaseInput from "./components/BaseInput" +import Preview from "../Preview/Preveiw" +import { FormSystemInput } from "@island.is/api/schema" + + + +const InputContent = () => { + const { control, selectStatus, setSelectStatus } = useContext(ControlContext) + const currentItem = control.activeItem.data as FormSystemInput + return ( + + + + + + ) +} + +export default InputContent diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx new file mode 100644 index 000000000000..9035f0f3bcbd --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -0,0 +1,162 @@ +import { useContext } from "react" +import ControlContext from "../../../../../context/ControlContext" +import { FormSystemInput } from "@island.is/api/schema" +import { + Stack, + GridRow as Row, + GridColumn as Column, + Select, + Option, + Input, + Checkbox +} from "@island.is/island-ui/core" +import { SingleValue } from "react-select" + + +const BaseInput = () => { + const { control, controlDispatch, setFocus, focus, inputTypes, updateActiveItem } = useContext(ControlContext) + const { activeItem } = control + const currentItem = activeItem.data as FormSystemInput + + const sortedInputTypes = inputTypes?.map(i => ({ + label: i?.type ?? '', + value: i?.type ?? '', + })).sort((a, b) => (a?.label ?? '').localeCompare(b?.label ?? '')) + + const defaultOption = + currentItem.type === '' + ? null + : sortedInputTypes?.find((o) => o.value === currentItem.type) + + return ( + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'is', + newValue: e.target.value, + }, + })} + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + {/* Name en */} + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'en', + newValue: e.target.value, + }, + })} + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + {/* Description */} + {['Textalýsing'].includes(currentItem?.type ?? '') && ( + <> + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => controlDispatch({ + type: 'CHANGE_DESCRIPTION', + payload: { + lang: 'is', + newValue: e.target.value, + }, + })} + /> + + + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => controlDispatch({ + type: 'CHANGE_DESCRIPTION', + payload: { + lang: 'en', + newValue: e.target.value, + }, + })} + /> + + + + )} + + {/* Required checkbox */} + + + controlDispatch({ + type: 'CHANGE_IS_REQUIRED', + payload: { + update: updateActiveItem, + } + }) + } + /> + + + + ) +} + +export default BaseInput diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx new file mode 100644 index 000000000000..218d1b85247d --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx @@ -0,0 +1,93 @@ +import { useContext } from "react" +import ControlContext from "../../../../../../../context/ControlContext" +import { + GridRow as Row, + GridColumn as Column, + Input, + Checkbox, + Stack, +} from '@island.is/island-ui/core' +import { FormSystemInput } from "@island.is/api/schema" + +const MessageWithLinkSettings = () => { + const { control, controlDispatch, setFocus, updateActiveItem } = useContext(ControlContext) + const currentItem = control.activeItem.data as FormSystemInput + const { inputSettings } = currentItem + return ( + + + + + + + {inputSettings !== undefined && ( + inputSettings?.hasLink && ( + + + + { + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'hnapptexti', + lang: 'is', + value: e.target.value, + }, + }) + }} + /> + + + { + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'hnapptexti', + lang: 'en', + value: e.target.value, + }, + }) + }} + /> + + + + + + listsDispatch({ + type: 'setMessageWithLinkSettings', + payload: { + property: 'url', + value: e.target.value, + }, + }) + } + /> + + + + ) + )} + + ) +} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx new file mode 100644 index 000000000000..907bf7291d67 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx @@ -0,0 +1,55 @@ +import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' +import { useContext, useState } from 'react' +import ControlContext from '../../../../context/ControlContext' +import { FormSystemDocumentType } from '@island.is/api/schema' + + +const Premises = () => { + const { control, documentTypes, formSettingsUpdate } = useContext(ControlContext) + const [formDocumentTypes, setFormDocumentTypes] = useState(control.form?.documentTypes?.filter((d): d is FormSystemDocumentType => d !== null) ?? []) + + const handleCheckboxChange = (documentTypeId: number) => { + if (documentTypeId === -1) return + const newDocumentTypes = formDocumentTypes.some( + (f) => f?.id === documentTypeId, + ) + ? formDocumentTypes.filter((f) => f?.id !== documentTypeId) + : ([ + ...formDocumentTypes, + documentTypes?.find((d) => d?.id === documentTypeId), + ].filter((d) => d !== undefined) as FormSystemDocumentType[]) + setFormDocumentTypes(newDocumentTypes) + formSettingsUpdate({ ...control.form, documentTypes: newDocumentTypes }) + } + + return ( + + + + Í þessu skrefi óskum við eftir samþykki fyrir því að upplýsingar um + hlutaðeigandi aðila verði sóttar af Mínum síðum. Að auki er hægt að + óska eftir heimild fyrir því að einhver af eftirfarandi vottorðum + verði sótt í viðeigandi vefþjónustur + + + + {documentTypes?.map((d, i) => { + return ( + f?.id === d?.id)} + onChange={() => handleCheckboxChange(d?.id ?? -1)} + /> + ) + })} + + ) +} + +export default Premises diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx new file mode 100644 index 000000000000..50668f66827e --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx @@ -0,0 +1,22 @@ +import { FormSystemInput } from "@island.is/api/schema" +import { Box } from "@island.is/island-ui/core" +import MessageWithLink from "./components/MessageWithLink" + +interface Props { + data: FormSystemInput +} + +const Preview = ({ data }: Props) => { + return ( + + {data.type === 'Textalýsing' && ( + + )} + + ) +} + +export default Preview diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx new file mode 100644 index 000000000000..f1662a756687 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx @@ -0,0 +1,60 @@ +import { FormSystemInput } from "@island.is/api/schema" +import { + Box, + Button, + Text +} from "@island.is/island-ui/core" + +interface Props { + data: FormSystemInput + +} + +const MessageWithLink = ({ data }: Props) => { + const formatUrl = (url: string): string => { + if (url.startsWith('http://')) { + url = url.replace('http://', 'https://') + } else if (!url.startsWith('https://')) { + url = 'https://' + url + } + return url + } + return ( + + + + {data?.name?.is} + + + {data?.description?.is} + + + {data.inputSettings?.hasLink && ( + + + + )} + + ) +} + +export default MessageWithLink diff --git a/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx new file mode 100644 index 000000000000..dbae94dcdc2a --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx @@ -0,0 +1,325 @@ +import { + useSensors, + useSensor, + PointerSensor, + DndContext, + DragOverlay, + UniqueIdentifier, + DragStartEvent, + DragOverEvent, + DataRef, + DragEndEvent, +} from '@dnd-kit/core' +import { SortableContext } from '@dnd-kit/sortable' +import { useContext, useMemo } from 'react' +import { createPortal } from 'react-dom' +import { Box, Button } from '@island.is/island-ui/core' +import { baseSettingsStep } from '../../utils/getBaseSettingsStep' +import NavbarTab from './components/NavbarTab/NavbarTab' +import NavComponent from './components/NavComponent/NavComponent' +import { FormSystemFormInput, FormSystemGroup, FormSystemInput, FormSystemStep, FormSystemUpdateFormInput, Maybe } from '@island.is/api/schema' +import ControlContext, { IControlContext } from '../../context/ControlContext' +import { useFormSystemCreateStepMutation } from '../../gql/Step.generated' +import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' +import { ItemType } from '../../lib/utils/interfaces' + +type ActionType = 'removeStep' | 'removeGroup' | 'removeInput' + +type DndAction = + | 'STEP_OVER_STEP' + | 'GROUP_OVER_STEP' + | 'GROUP_OVER_GROUP' + | 'INPUT_OVER_GROUP' + | 'INPUT_OVER_INPUT' + +export default function Navbar() { + const { + control, + controlDispatch, + setInSettings, + inSettings, + updateDnD + } = useContext(ControlContext) as IControlContext + + const { activeItem, form } = control + const { stepsList: steps, groupsList: groups, inputsList: inputs } = form + const stepsIds = useMemo(() => steps?.filter((s): s is FormSystemStep => s !== null && s !== undefined).map((s) => s?.guid as UniqueIdentifier), [steps]) + const groupsIds = useMemo(() => groups?.filter((g): g is FormSystemGroup => g !== null && g !== undefined).map((g) => g?.guid as UniqueIdentifier), [groups]) + const inputsIds = useMemo(() => inputs?.filter((i): i is FormSystemInput => i !== null && i !== undefined).map((i) => i?.guid as UniqueIdentifier), [inputs]) + + const sensors = useSensors( + useSensor(PointerSensor, { + activationConstraint: { + distance: 10, + }, + }), + ) + const [createStep, { data, loading, error }] = useFormSystemCreateStepMutation({ + variables: { + input: { + stepCreationDto: { + formId: form?.id as number, + displayOrder: steps?.length + } + } + } + }) + + const [updateForm, { data: formData, loading: formLoading, error: formError }] = useFormSystemUpdateFormMutation() + + const addStep = () => { + createStep() + if (!loading && !error && data) { + controlDispatch({ + type: 'ADD_STEP', + payload: { + step: data?.formSystemCreateStep as FormSystemStep + } + }) + } + } + + const focusComponent = (type: ItemType, id: UniqueIdentifier) => { + const data = type === "Step" + ? steps?.find((item: Maybe | undefined) => item?.guid === id) : type === "Group" + ? groups?.find((item: Maybe | undefined) => item?.guid === id) + : inputs?.find((item: Maybe | undefined) => item?.guid === id) + if (id === baseSettingsStep.guid) { + controlDispatch({ + type: 'SET_ACTIVE_ITEM', + payload: { + activeItem: { + type: 'Step', + data: baseSettingsStep, + } + }, + }) + } else if (data) { + controlDispatch({ + type: 'SET_ACTIVE_ITEM', + payload: { + activeItem: { + type: type, + data: data, + } + }, + }) + } + } + + const onDragStart = (event: DragStartEvent) => { + controlDispatch({ + type: 'SET_ACTIVE_ITEM', + payload: { + activeItem: { + type: event.active.data.current?.type, + data: event.active.data.current?.data ?? null, + } + } + }) + } + + const onDragOver = (event: DragOverEvent) => { + const { active, over } = event + + if (!over) return + + const activeId = active.id + const overId = over.id + + if (activeId === overId) return + + const getType = ( + data: DataRef<{ [x: string]: unknown }>, + targetType: ItemType, + ) => data?.current?.type === targetType + + const activeStep = getType(active.data, 'Step') + const activeGroup = getType(active.data, 'Group') + const activeInput = getType(active.data, 'Input') + const overStep = getType(over.data, 'Step') + const overGroup = getType(over.data, 'Group') + const overInput = getType(over.data, 'Input') + + const dispatchDragAction = (type: DndAction) => + controlDispatch({ type, payload: { activeId: activeId, overId: overId } }) + + //Dragging step + if (activeStep && overStep) { + dispatchDragAction('STEP_OVER_STEP') + } + + // // Dragging Group + if (activeGroup) { + if (overStep) { + dispatchDragAction('GROUP_OVER_STEP') + } + if (overGroup) { + dispatchDragAction('GROUP_OVER_GROUP') + } + } + + // // Dragging Input + if (activeInput) { + if (overGroup) { + dispatchDragAction('INPUT_OVER_GROUP') + } + if (overInput) { + dispatchDragAction('INPUT_OVER_INPUT') + } + } + } + + const onDragEnd = () => { + updateDnD(activeItem.type) + } + + if (inSettings) { + return ( + + + + + + + + {steps + ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) + .filter((s) => s.type !== 'Innsláttur') + .map((s) => ( + + + + ))} + + + + + ) + } else if (activeItem) { + return ( + + + + + + + {steps + ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) + .filter((s) => s.type === 'Innsláttur') + .map((s, i) => ( + + + + {groups + ?.filter((g): g is FormSystemGroup => g !== null && g !== undefined) + .filter((g) => g.stepGuid === s.guid) + .map((g) => ( + + + + + {inputs + ?.filter((i): i is FormSystemInput => i !== null && i !== undefined) + .filter((i) => i.groupGuid === g.guid) + .map((i) => ( + + ))} + + + ))} + + + ))} + + + {/* Only render client side */} + {typeof window === 'object' && + createPortal( + + {activeItem && ( + + )} + , + document.body, + )} + + + + + + ) + } + return null + +} diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.css.ts b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.css.ts new file mode 100644 index 000000000000..ffee12eb1162 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.css.ts @@ -0,0 +1,90 @@ +import { style, styleVariants } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +const base = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + marginLeft: 'auto', + backgroundColor: theme.color.blue100, + lineHeight: '46px', + ':hover': { + fontWeight: 'bolder', + }, + cursor: 'grab', +}) + +export const step = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + width: '100%', +}) + +export const navComponent = styleVariants({ + step: [ + base, + { + width: '100%', + }, + ], + group: [ + base, + { + width: '90%', + }, + ], + input: [ + base, + { + width: '80%', + }, + ], +}) + +const baseBackground = style({ + width: '25px', + height: '44px', + borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, + textAlign: 'center', +}) + +export const navBackgroundActive = styleVariants({ + step: [ + baseBackground, + { + backgroundColor: theme.color.blue600, + lineHeight: '45px', + color: theme.color.white, + }, + ], + group: [ + baseBackground, + { + backgroundColor: theme.color.roseTinted400, + }, + ], + input: [ + baseBackground, + { + backgroundColor: theme.color.purple400, + }, + ], +}) + +export const navBackgroundDefault = styleVariants({ + step: [ + baseBackground, + { + lineHeight: '45px', + }, + ], + group: [baseBackground, {}], + input: [baseBackground, {}], +}) + +export const customBackgroundDropdown = style({ + background: theme.color.blue100, +}) diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx new file mode 100644 index 000000000000..1cfac242be11 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx @@ -0,0 +1,175 @@ +import { useState } from 'react' +import { ItemType, IGroup, IInput, IStep } from '../../../../types/interfaces' +import { useSortable } from '@dnd-kit/sortable' +import { Box } from '@island.is/island-ui/core' +import cn from 'classnames' +import * as styles from './NavComponent.css' +import { UniqueIdentifier } from '@dnd-kit/core' +import NavButtons from './components/NavButtons' +import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' + +type Props = { + type: ItemType + data: FormSystemStep | FormSystemGroup | FormSystemInput + active: boolean + index?: number + focusComponent(type: ItemType, id: UniqueIdentifier): void +} + +export default function NavComponent({ + type, + data, + active, + index, + focusComponent, +}: Props) { + const [editMode] = useState(false) + + const truncateText = (text: string, maxLength: number) => { + return text.length > maxLength ? text.slice(0, maxLength) + '...' : text + } + + const truncateName = (name: string) => { + let maxLength; + + if (active) { + switch (type) { + case 'Step': + maxLength = 23; + break; + case 'Group': + maxLength = 16; + break; + case 'Input': + maxLength = 12; + break; + default: + maxLength = 26; + } + } else { + switch (type) { + case 'Step': + maxLength = 26; + break; + case 'Group': + maxLength = 19; + break; + case 'Input': + maxLength = 16; + break; + default: + maxLength = 26; + } + } + + return truncateText(name, maxLength); + } + + const { setNodeRef, attributes, listeners, isDragging } = useSortable({ + id: data.guid as UniqueIdentifier, + data: { + type: type, + data, + }, + disabled: editMode, + }) + + if (isDragging) { + return ( +
+
+
+ ) + } + + return ( + focusComponent(type, data.guid as UniqueIdentifier)} + > + {active ? ( + + + {index} + + + {truncateName(data?.name?.is as string)} + + + {!(type === 'Step' && (data as FormSystemStep).type !== 'Innsláttur') && ( + + )} + + + ) : ( + + + {index} + + + {truncateName(data?.name?.is as string)} + + + )} + + ) + + + + +} diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx new file mode 100644 index 000000000000..10663bf5b418 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx @@ -0,0 +1,113 @@ +import { Box, Icon } from '@island.is/island-ui/core' +import { useContext } from 'react' +import ControlContext from '../../../../../context/ControlContext' +import { FormSystemGroup, FormSystemInput } from '@island.is/api/schema' +import { useFormSystemCreateGroupMutation, useFormSystemDeleteGroupMutation } from '../../../../../gql/Group.generated' +import { useFormSystemCreateInputMutation, useFormSystemDeleteInputMutation } from '../../../../../gql/Input.generated' +import { useFormSystemDeleteStepMutation } from '../../../../../gql/Step.generated' + + +export default function NavButtons() { + const { control, controlDispatch, apolloClient } = useContext(ControlContext) + const { activeItem, form } = control + const { groupsList: groups, inputsList: inputs } = form + + const [addGroup, groupStatus] = useFormSystemCreateGroupMutation() + const [addInput, inputStatus] = useFormSystemCreateInputMutation() + const [removeStep, removeStepStatus] = useFormSystemDeleteStepMutation() + const [removeGroup, removeGroupStatus] = useFormSystemDeleteGroupMutation() + const [removeInput, removeInputStatus] = useFormSystemDeleteInputMutation() + + const addItem = async () => { + if (activeItem.type === 'Step') { + const newGroup = await addGroup({ + variables: { + input: { + groupCreationDto: { + stepId: activeItem?.data?.id, + displayOrder: groups?.length + } + } + } + }) + if (newGroup) { + controlDispatch({ type: 'ADD_GROUP', payload: { group: newGroup.data?.formSystemCreateGroup as FormSystemGroup } }) + } + } else if (activeItem.type === 'Group') { + const newInput = await addInput({ + variables: { + input: { + inputCreationDto: { + groupId: activeItem?.data?.id, + displayOrder: inputs?.length + } + } + } + }) + if (newInput) { + controlDispatch({ type: 'ADD_INPUT', payload: { input: newInput.data?.formSystemCreateInput as FormSystemInput } }) + } + } + } + + const remove = async () => { + const id = activeItem?.data?.id as number + if (activeItem.type === 'Step') { + await removeStep({ + variables: { + input: { + stepId: id + } + } + }) + if (!removeStepStatus.loading) { + controlDispatch({ type: 'REMOVE_STEP', payload: { stepId: id } }) + } + } else if (activeItem.type === 'Group') { + await removeGroup({ + variables: { + input: { + groupId: id + } + } + }) + if (!removeGroupStatus.loading) { + controlDispatch({ type: 'REMOVE_GROUP', payload: { groupId: id } }) + } + } else if (activeItem.type === 'Input') { + await removeInput({ + variables: { + input: { + inputId: id + } + } + }) + if (!removeInputStatus.loading) { + controlDispatch({ type: 'REMOVE_INPUT', payload: { inputId: id } }) + } + + } + } + + return ( + + {activeItem.type !== 'Input' && ( + + + + )} + + + + + ) + + +} diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.css.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.css.tsx new file mode 100644 index 000000000000..c6a1b1bc3068 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.css.tsx @@ -0,0 +1,17 @@ +import { style } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const selected = style({ + cursor: 'pointer', + fontWeight: 'bolder', + textDecoration: 'underline', + color: theme.color.blue400, +}) + +export const notSelected = style({ + cursor: 'pointer', + ':hover': { + fontWeight: 'bolder', + textDecoration: 'underline', + }, +}) diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx new file mode 100644 index 000000000000..f8084e4a89e2 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx @@ -0,0 +1,60 @@ +import { Box, Inline } from '@island.is/island-ui/core' +import cn from 'classnames' +import * as styles from './NavbarTab.css' +import { Dispatch, SetStateAction, useContext } from 'react' +import FormBuilderContext from '../../../../context/FormBuilderContext' +import { baseSettingsStep } from '../../../../utils/getBaseSettingsStep' +import ControlContext from '../../../../context/ControlContext' + + +export default function NavbarTab() { + const { control, controlDispatch, inSettings, setInSettings } = useContext(ControlContext) + const { stepsList: steps } = control.form + return ( + + + { + const step = steps?.find(s => s?.type === 'Innsláttur') + controlDispatch({ + type: 'SET_ACTIVE_ITEM', + payload: { + activeItem: { + type: 'Step', + data: step, + } + }, + }) + setInSettings(false) + }} + > + Skref + + { + controlDispatch({ + type: 'SET_ACTIVE_ITEM', + payload: { + activeItem: { + type: 'Step', + data: baseSettingsStep, + } + }, + }) + setInSettings(true) + }} + > + Grunnstillingar + + + + ) +} diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx new file mode 100644 index 000000000000..ab6e162945bc --- /dev/null +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx @@ -0,0 +1,65 @@ +// import { useContext } from 'react' +// import { Box, Text } from '@island.is/island-ui/core' +// import SelectNavComponent from './components/SelectNavComponent' +// import FormBuilderContext from '../../context/FormBuilderContext' +// import { NavbarSelectStatus } from '../../types/interfaces' +// import ControlContext from '../../context/ControlContext' +// import { FormSystemStep } from '@island.is/api/schema' + +// export default function NavbarSelect() { +// const { control } = useContext(ControlContext) +// const { activeItem, steps, groups, inputs } = control +// let selectable = false +// return ( +// +// +// Skref +// +// {steps +// ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) +// .filter((s) => s.type === 'Innsláttur') +// .map((s) => ( +// +// +// {groups +// .filter((g) => g.stepGuid === s.guid) +// .map((g) => ( +// +// +// {inputs +// .filter((i) => i.groupGuid === g.guid) +// .map((i) => { +// if (activeItem.data.guid === i.guid) { +// if ( +// selectStatus !== NavbarSelectStatus.ON_WITHOUT_SELECT +// ) { +// selectable = true +// } +// } +// return ( +// +// ) +// })} +// +// ))} +// +// ))} +// +// ) +// } diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx new file mode 100644 index 000000000000..6076614ec4ba --- /dev/null +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx @@ -0,0 +1,146 @@ +// import cn from 'classnames' +// import * as styles from './selectNavComponent.css' +// import { Box, Checkbox } from '@island.is/island-ui/core' +// import { useContext } from 'react' +// import { +// ItemType, +// NavbarSelectStatus, +// } from '../../../types/interfaces' +// import FormBuilderContext from '../../../context/FormBuilderContext' +// import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' + +// type Props = { +// type: ItemType +// data: FormSystemStep | FormSystemGroup | FormSystemInput +// active: boolean +// selectable: boolean +// } + +// export default function SelectNavComponent({ +// type, +// data, +// active, +// selectable, +// }: Props) { +// const { formBuilder, formDispatch, lists, selectStatus, activeListItem } = +// useContext(FormBuilderContext) +// const { activeItem } = lists +// const { form } = formBuilder +// const activeGuid = +// selectStatus === NavbarSelectStatus.LIST_ITEM +// ? activeListItem?.guid ?? '' +// : activeItem.data.guid +// const connected = +// form.dependencies[activeGuid]?.includes(data.guid as string) || +// !form.dependencies +// return ( +// +// {active ? ( +// +// +// {/* Index */} +// +// +// {truncateName(data.name.is)} +// +// +// ) : ( +// +// +// {/* {index} */} +// +// +// {truncateName(data.name.is)} +// +// {selectable && ( +// +// { +// formDispatch({ +// type: 'addRemoveConnection', +// payload: { +// active: activeGuid, +// item: data.guid, +// }, +// }) +// }} +// /> +// +// )} +// +// )} +// +// ) + +// function truncateText(text: string, maxLength: number) { +// return text.length > maxLength ? text.slice(0, maxLength) + '...' : text +// } + +// function truncateName(name: string) { +// let maxLength: number + +// if (active) { +// switch (type) { +// case 'Step': +// maxLength = 23 +// break +// case 'Group': +// maxLength = 16 +// break +// case 'Input': +// maxLength = 12 +// break +// default: +// maxLength = 26 +// } +// } else { +// switch (type) { +// case 'Step': +// maxLength = 26 +// break +// case 'Group': +// maxLength = 19 +// break +// case 'Input': +// maxLength = 16 +// break +// default: +// maxLength = 26 +// } +// } + +// return truncateText(name, maxLength) +// } +// } diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts b/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts new file mode 100644 index 000000000000..8db4cbdbcc55 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts @@ -0,0 +1,90 @@ +import { style, styleVariants } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +const base = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + marginLeft: 'auto', + backgroundColor: theme.color.white, + lineHeight: '46px', + ':hover': { + fontWeight: 'bolder', + }, + cursor: 'grab', +}) + +export const step = style({ + border: `1px solid ${theme.border.color.blue200}`, + borderRadius: theme.border.radius.standard, + marginBottom: '2px', + height: '46px', + width: '100%', +}) + +export const navComponent = styleVariants({ + step: [ + base, + { + width: '100%', + }, + ], + group: [ + base, + { + width: '90%', + }, + ], + input: [ + base, + { + width: '80%', + }, + ], +}) + +const baseBackground = style({ + width: '25px', + height: '44px', + borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, + textAlign: 'center', +}) + +export const navBackgroundActive = styleVariants({ + step: [ + baseBackground, + { + backgroundColor: theme.color.blue600, + lineHeight: '45px', + color: theme.color.white, + }, + ], + group: [ + baseBackground, + { + backgroundColor: theme.color.roseTinted400, + }, + ], + input: [ + baseBackground, + { + backgroundColor: theme.color.purple400, + }, + ], +}) + +export const navBackgroundDefault = styleVariants({ + step: [ + baseBackground, + { + lineHeight: '45px', + }, + ], + group: [baseBackground, {}], + input: [baseBackground, {}], +}) + +export const customBackgroundDropdown = style({ + background: theme.color.blue100, +}) diff --git a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx index 5775fc118431..9f64f486cfd4 100644 --- a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx +++ b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx @@ -101,7 +101,12 @@ const TableRow = ({ { title: 'Breyta', onClick: () => { - navigate(FormSystemPaths.Form.replace(':formId', String(id))) + navigate(FormSystemPaths.Form.replace(':formId', String(id)), + { + state: { + formId: id + } + }) }, }, { diff --git a/libs/portals/admin/form-system/src/context/ControlContext.ts b/libs/portals/admin/form-system/src/context/ControlContext.ts new file mode 100644 index 000000000000..d9896f4f15f0 --- /dev/null +++ b/libs/portals/admin/form-system/src/context/ControlContext.ts @@ -0,0 +1,60 @@ +import { Dispatch, createContext } from "react" +import { ControlAction, ControlState } from "../hooks/controlReducer" +import { ApolloClient, NormalizedCacheObject } from "@apollo/client" +import { Maybe } from "graphql/jsutils/Maybe" +import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemInput, FormSystemListType } from "@island.is/api/schema" +import { ActiveItem, ItemType, NavbarSelectStatus } from "../lib/utils/interfaces" + +export interface IControlContext { + control: ControlState + controlDispatch: Dispatch + apolloClient: ApolloClient + applicantTypes: Maybe[]> | undefined + documentTypes: Maybe[]> | undefined + inputTypes: Maybe[]> | undefined + listTypes: Maybe[]> | undefined + setInSettings: Dispatch + inSettings: boolean + updateActiveItem: (updatedActiveItem?: ActiveItem) => void + focus: string + setFocus: Dispatch + updateDnD: (type: ItemType) => void + formSettingsUpdate: (updatedForm?: FormSystemForm) => void + selectStatus: NavbarSelectStatus + setSelectStatus: Dispatch +} + +const ControlContext = createContext({ + control: {} as ControlState, + controlDispatch: function (_value: unknown): void { + throw new Error('Function not implemented.') + }, + apolloClient: {} as ApolloClient, + applicantTypes: [] as Maybe[]>, + documentTypes: [] as Maybe[]>, + inputTypes: [] as Maybe[]>, + listTypes: [] as Maybe[]>, + setInSettings: function (_value: boolean): void { + throw new Error('Function not implemented.') + }, + inSettings: false, + updateActiveItem: function (_updatedActiveItem?: ActiveItem): void { + throw new Error('Function not implemented.') + }, + focus: '', + setFocus: function (_value: string): void { + throw new Error('Function not implemented.') + }, + updateDnD: function (_type: ItemType): void { + throw new Error('Function not implemented.') + }, + formSettingsUpdate: function (_updatedForm?: FormSystemForm): void { + throw new Error('Function not implemented.') + }, + selectStatus: NavbarSelectStatus.OFF, + setSelectStatus: function (_value: NavbarSelectStatus): void { + throw new Error('Function not implemented.') + }, +}) + +export default ControlContext diff --git a/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx b/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx new file mode 100644 index 000000000000..0cef53037510 --- /dev/null +++ b/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx @@ -0,0 +1,50 @@ +import { FocusEvent, SetStateAction, createContext } from 'react' +import { + ActiveItem, + IFormBuilder, + IFormBuilderContext, + IGroup, + IInput, + IListItem, + IStep, + NavbarSelectStatus, + ILists +} from '../types/interfaces' + +const FormBuilderContext = createContext({ + // formBuilder: {} as IFormBuilder, + // formDispatch: function (_value: unknown): void { + // throw new Error('Function not implemented.') + // }, + // lists: { + // activeItem: {} as ActiveItem, + // steps: [] as IStep[], + // groups: [] as IGroup[], + // inputs: [] as IInput[], + // }, + lists: {} as ILists, + formUpdate: async function (): Promise { + throw new Error('Function not implemented.') + }, + inSettings: false, + setInSettings: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + setSelectStatus: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + selectStatus: NavbarSelectStatus.OFF, + setActiveListItem: function (_value: SetStateAction): void { + throw new Error('Function not implemented.') + }, + blur: function ( + _e: FocusEvent, + ): void { + throw new Error('Function not implemented.') + }, + onFocus: function (_e: string): void { + throw new Error('Function not implemented.') + }, +}) + +export default FormBuilderContext diff --git a/libs/portals/admin/form-system/src/context/LayoutContext.tsx b/libs/portals/admin/form-system/src/context/LayoutContext.tsx new file mode 100644 index 000000000000..82bed301b7aa --- /dev/null +++ b/libs/portals/admin/form-system/src/context/LayoutContext.tsx @@ -0,0 +1,14 @@ +import { createContext } from 'react' +import { ILayoutContext } from '../types/interfaces' + +const LayoutContext = createContext({ + info: { + organization: '', + applicationName: '', + }, + infoDispatch: function (_value: unknown): void { + throw new Error('Function not implemented.') + }, +}) + +export default LayoutContext diff --git a/libs/portals/admin/form-system/src/context/UserContext.tsx b/libs/portals/admin/form-system/src/context/UserContext.tsx new file mode 100644 index 000000000000..b59d839d23b2 --- /dev/null +++ b/libs/portals/admin/form-system/src/context/UserContext.tsx @@ -0,0 +1,13 @@ +import { createContext } from "react"; +import { User } from "../types/interfaces"; + + +const UserContext = createContext({ + isAuthenticated: false, + setIsAuthenticated: (_: boolean) => undefined, + user: null as unknown as User, + setUser: (_: User) => undefined, + userLoading: false, +}) + +export default UserContext diff --git a/libs/portals/admin/form-system/src/gql/Form.graphql b/libs/portals/admin/form-system/src/gql/Form.graphql new file mode 100644 index 000000000000..2f67ba80eb9e --- /dev/null +++ b/libs/portals/admin/form-system/src/gql/Form.graphql @@ -0,0 +1,1150 @@ +mutation formSystemUpdateForm( + $input: FormSystemUpdateFormInput! +) { + formSystemUpdateForm(input: $input) +} + +query formSystemGetForm( + $input: FormSystemGetFormInput! +) { + formSystemGetForm(input: $input) { + form { + id + name { + is + en + } + applicationsDaysToRemove + completedMessage { + is + en + } + created + dependencies + documentTypes { + id + name { + is + en + } + description { + is + en + } + type + } + formApplicantTypes { + applicantTypeId + formId + name { + is + en + } + type + } + groupsList { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + inputsList { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + invalidationDate + isTranslated + lastChanged + organization { + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + id + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + listTypes { + id + name { + is + en + } + description { + is + en + } + type + } + name { + is + en + } + nationalId + } + steps { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stepsList { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stopProgressOnValidatingStep + } + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + } +} + + +mutation formSystemCreateForm( + $input: FormSystemCreateFormInput! +) { + formSystemCreateForm(input: $input) { + form { + id + name { + is + en + } + applicationsDaysToRemove + completedMessage { + is + en + } + created + dependencies + documentTypes { + id + name { + is + en + } + description { + is + en + } + type + } + formApplicantTypes { + applicantTypeId + formId + name { + is + en + } + type + } + groupsList { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + inputsList { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + invalidationDate + isTranslated + lastChanged + organization { + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + id + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + listTypes { + id + name { + is + en + } + description { + is + en + } + type + } + name { + is + en + } + nationalId + } + steps { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stepsList { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stopProgressOnValidatingStep + } + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + } +} + +mutation formSystemDeleteForm( + $input: FormSystemDeleteFormInput! +) { + formSystemDeleteForm(input: $input) +} diff --git a/libs/portals/admin/form-system/src/gql/Group.graphql b/libs/portals/admin/form-system/src/gql/Group.graphql new file mode 100644 index 000000000000..3574a586c703 --- /dev/null +++ b/libs/portals/admin/form-system/src/gql/Group.graphql @@ -0,0 +1,90 @@ +mutation formSystemCreateGroup( + $input: FormSystemCreateGroupInput! +) { + formSystemCreateGroup(input: $input) { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } +} + +mutation formSystemDeleteGroup( + $input: FormSystemDeleteGroupInput! +) { + formSystemDeleteGroup(input: $input) +} + +mutation formSystemUpdateGroup( + $input: FormSystemUpdateGroupInput! +) { + formSystemUpdateGroup(input: $input) +} diff --git a/libs/portals/admin/form-system/src/gql/Input.graphql b/libs/portals/admin/form-system/src/gql/Input.graphql new file mode 100644 index 000000000000..ea5b8a839529 --- /dev/null +++ b/libs/portals/admin/form-system/src/gql/Input.graphql @@ -0,0 +1,77 @@ +mutation formSystemCreateInput( + $input: FormSystemCreateInputInput! + ) { + formSystemCreateInput(input: $input) { + id + name { + is + en + } + description { + is + en + } + isRequired + displayOrder + groupId + isHidden + type + guid + isPartOfMultiSet + groupGuid + inputSettings { + isLarge + size + interval + hasLink + url + buttonText { + is + en + } + types + maxSize + isMulti + amount + header + maxLength + minLength + min + max + list { + guid + label { + is + en + } + description { + is + en + } + displayOrder + isSelected + value + } + type + name { + is + en + } + isList + hasInput + } + inputFields + } +} + +mutation formSystemDeleteInput( + $input: FormSystemDeleteInputInput! +) { + formSystemDeleteInput(input: $input) +} + +mutation formSystemUpdateInput( + $input: FormSystemUpdateInputInput! +) { + formSystemUpdateInput(input: $input) +} diff --git a/libs/portals/admin/form-system/src/gql/Step.graphql b/libs/portals/admin/form-system/src/gql/Step.graphql new file mode 100644 index 000000000000..29fe5c61ea09 --- /dev/null +++ b/libs/portals/admin/form-system/src/gql/Step.graphql @@ -0,0 +1,107 @@ +mutation formSystemCreateStep( + $input: FormSystemCreateStepInput! +) { + formSystemCreateStep(input: $input) { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } +} + +mutation formSystemDeleteStep( + $input: FormSystemDeleteStepInput! +) { + formSystemDeleteStep(input: $input) +} + +mutation formSystemUpdateStep( + $input: FormSystemUpdateStepInput! +) { + formSystemUpdateStep(input: $input) +} diff --git a/libs/portals/admin/form-system/src/hooks/controlReducer.ts b/libs/portals/admin/form-system/src/hooks/controlReducer.ts new file mode 100644 index 000000000000..d94d3afecd61 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/controlReducer.ts @@ -0,0 +1,370 @@ +import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemInputSettings, FormSystemStep } from "@island.is/api/schema" +import { ActiveItem } from "../types/interfaces" +import { UniqueIdentifier } from "@dnd-kit/core" +import { arrayMove } from "@dnd-kit/sortable" + +type ActiveItemActions = + | { type: 'SET_ACTIVE_ITEM', payload: { activeItem: ActiveItem } } + +type GroupActions = + | { type: 'ADD_GROUP', payload: { group: FormSystemGroup } } + | { type: 'REMOVE_GROUP', payload: { groupId: number } } + +type InputActions = + | { type: 'ADD_INPUT', payload: { input: FormSystemInput } } + | { type: 'REMOVE_INPUT', payload: { inputId: number } } + | { type: 'CHANGE_INPUT_TYPE', payload: { newValue: string, inputSettings: FormSystemInputSettings, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'CHANGE_DESCRIPTION', payload: { lang: 'en' | 'is', newValue: string } } + | { type: 'CHANGE_IS_REQUIRED', payload: { update: (updatedActiveItem?: ActiveItem) => void } } + + +type StepActions = + | { type: 'ADD_STEP', payload: { step: FormSystemStep } } + | { type: 'REMOVE_STEP', payload: { stepId: number } } + +type DndActions = + | { type: 'STEP_OVER_STEP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { type: 'GROUP_OVER_STEP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { type: 'GROUP_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { type: 'INPUT_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { type: 'INPUT_OVER_INPUT', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + +type ChangeActions = + | { type: 'CHANGE_NAME', payload: { lang: 'en' | 'is', newValue: string } } + | { type: 'CHANGE_FORM_NAME', payload: { lang: 'en' | 'is', newValue: string } } + | { type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', payload: { value: number } } + | { type: 'CHANGE_INVALIDATION_DATE', payload: { value: Date } } + | { type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', payload: { value: boolean } } + | { type: 'CHANGE_FORM_SETTINGS', payload: { newForm: FormSystemForm } } + +export type ControlAction = ActiveItemActions | GroupActions | InputActions | StepActions | DndActions | ChangeActions + +export interface ControlState { + activeItem: ActiveItem + form: FormSystemForm +} + +export const controlReducer = (state: ControlState, action: ControlAction): ControlState => { + const { form, activeItem } = state + const { stepsList: steps, groupsList: groups, inputsList: inputs } = form + switch (action.type) { + case 'SET_ACTIVE_ITEM': + return { + ...state, + activeItem: action.payload.activeItem + } + + // Steps + case 'ADD_STEP': + return { + ...state, + activeItem: { + type: 'Step', + data: action.payload.step + }, + form: { + ...form, + stepsList: [...(steps || []), action.payload.step] + } + } + case 'REMOVE_STEP': { + const newSteps = state.form.stepsList?.filter((step) => step?.id !== action.payload.stepId) + return { + ...state, + form: { + ...form, + stepsList: newSteps + } + } + } + + // Groups + case 'ADD_GROUP': + return { + ...state, + activeItem: { + type: 'Group', + data: action.payload.group + }, + form: { + ...form, + groupsList: [...(groups || []), action.payload.group] + } + } + case 'REMOVE_GROUP': { + const newGroups = state.form.groupsList?.filter((group) => group?.id !== action.payload.groupId) + const currentItem = state.activeItem.data as FormSystemGroup + const newActiveItem = state.form.stepsList?.find((step) => step?.guid === currentItem.stepGuid) + return { + ...state, + activeItem: { + type: 'Step', + data: newActiveItem + }, + form: { + ...form, + groupsList: newGroups + } + } + } + + // Inputs + case 'ADD_INPUT': + return { + ...state, + activeItem: { + type: 'Input', + data: action.payload.input + }, + form: { + ...form, + inputsList: [...(inputs || []), action.payload.input] + } + } + case 'REMOVE_INPUT': { + const newInputs = state.form.inputsList?.filter((input) => input?.id !== action.payload.inputId) + const currentItem = state.activeItem.data as FormSystemInput + const newActiveItem = state.form.groupsList?.find((group) => group?.guid === currentItem.groupGuid) + return { + ...state, + activeItem: { + type: 'Group', + data: newActiveItem + }, + form: { + ...form, + inputsList: newInputs + } + } + } + case 'CHANGE_INPUT_TYPE': { + const { newValue, inputSettings, update } = action.payload; + const newActive = { + ...activeItem, + data: { + ...activeItem.data, + type: newValue, + inputSettings: inputSettings + } + } + update(newActive) + return { + activeItem: newActive, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === activeItem.data?.guid ? newActive.data : i) + } + } + } + case 'CHANGE_DESCRIPTION': { + const { lang, newValue } = action.payload + const currentData = activeItem.data as FormSystemInput + const newActive = { + ...activeItem, + data: { + ...currentData, + description: { + ...currentData?.description, + [lang]: newValue + } + } + }; + return { + activeItem: newActive, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === currentData?.guid ? newActive.data : i) + } + } + } + case 'CHANGE_IS_REQUIRED': { + const currentData = activeItem.data as FormSystemInput + console.log(currentData) + const newActive = { + ...activeItem, + data: { + ...currentData, + isRequired: !currentData?.isRequired + } + } + action.payload.update(newActive) + return { + activeItem: newActive, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === currentData?.guid ? newActive.data : i) + } + } + } + + // Change + case 'CHANGE_NAME': { + const { lang, newValue } = action.payload; + const newActive = { + ...activeItem, + data: { + ...activeItem.data, + name: { + ...activeItem.data?.name, + [lang]: newValue + } + } + }; + const { type } = activeItem; + let updatedList; + if (type === 'Step') { + updatedList = steps?.map(s => s?.guid === activeItem.data?.guid ? newActive.data : s); + } else if (type === 'Group') { + updatedList = groups?.map(g => g?.guid === activeItem.data?.guid ? newActive.data : g); + } else if (type === 'Input') { + updatedList = inputs?.map(i => i?.guid === activeItem.data?.guid ? newActive.data : i); + } + return { + activeItem: newActive, + form: { + ...form, + stepsList: type === 'Step' ? updatedList as FormSystemStep[] : form.stepsList, + groupsList: type === 'Group' ? updatedList as FormSystemGroup[] : form.groupsList, + inputsList: type === 'Input' ? updatedList as FormSystemInput[] : form.inputsList + } + } + } + case 'CHANGE_FORM_NAME': { + const { lang, newValue } = action.payload; + return { + ...state, + form: { + ...form, + name: { + ...form.name, + [lang]: newValue + } + } + } + } + case 'CHANGE_APPLICATION_DAYS_TO_REMOVE': { + return { + ...state, + form: { + ...form, + applicationsDaysToRemove: action.payload.value + } + } + } + case 'CHANGE_INVALIDATION_DATE': { + return { + ...state, + form: { + ...form, + invalidationDate: action.payload.value + } + } + } + case 'CHANGE_FORM_SETTINGS': { + return { + ...state, + form: action.payload.newForm + } + } + // Drag and Drop + case 'STEP_OVER_STEP': { + const activeIndex = steps?.findIndex((step) => step?.guid === action.payload.activeId) as number + const overIndex = steps?.findIndex((step) => step?.guid === action.payload.overId) as number + const updatedSteps = arrayMove(steps || [], activeIndex, overIndex) + return { + ...state, + form: { + ...form, + stepsList: updatedSteps.map((s, i) => ({ ...s, displayOrder: i })) + } + } + } + case 'GROUP_OVER_STEP': { + const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number + const overIndex = steps?.findIndex((step) => step?.guid === action.payload.overId) as number + const updatedGroups = groups?.map(group => ({ ...group })) as FormSystemGroup[] + if (steps && steps[overIndex]) { + updatedGroups[activeIndex].stepGuid = action.payload.overId as string + updatedGroups[activeIndex].stepId = steps[overIndex]?.id as number + } + return { + ...state, + form: { + ...form, + groupsList: arrayMove(updatedGroups, activeIndex, overIndex).map((g, i) => ({ ...g, displayOrder: i })) + } + } + } + case 'GROUP_OVER_GROUP': { + const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number + const overIndex = groups?.findIndex((group) => group?.guid === action.payload.overId) as number + const updatedGroups = groups?.map(group => ({ ...group })) as FormSystemGroup[] + if (updatedGroups[activeIndex] && updatedGroups[overIndex]) { + if (updatedGroups[activeIndex].stepGuid !== updatedGroups[overIndex].stepGuid) { + updatedGroups[activeIndex].stepGuid = updatedGroups[overIndex].stepGuid + updatedGroups[activeIndex].stepId = updatedGroups[overIndex].stepId + return { + ...state, + form: { + ...form, + groupsList: arrayMove(updatedGroups, activeIndex, overIndex - 1).map((g, i) => ({ ...g, displayOrder: i })) + } + } + } + return { + ...state, + form: { + ...form, + groupsList: arrayMove(updatedGroups, activeIndex, overIndex).map((g, i) => ({ ...g, displayOrder: i })) + } + } + } + return state + } + case 'INPUT_OVER_GROUP': { + const activeIndex = inputs?.findIndex((input) => input?.guid === action.payload.activeId) as number + const overIndex = groups?.findIndex((group) => group?.guid === action.payload.overId) as number + const updatedInputs = inputs?.map(input => ({ ...input })) as FormSystemInput[] + if (groups && groups[overIndex]) { + updatedInputs[activeIndex].groupGuid = action.payload.overId as string + updatedInputs[activeIndex].groupId = groups[overIndex]?.id as number + } + return { + ...state, + form: { + ...form, + inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map((i, index) => ({ ...i, displayOrder: index })) + } + } + } + case 'INPUT_OVER_INPUT': { + const activeIndex = inputs?.findIndex((input) => input?.guid === action.payload.activeId) as number + const overIndex = inputs?.findIndex((input) => input?.guid === action.payload.overId) as number + const updatedInputs = inputs?.map(input => ({ ...input })) as FormSystemInput[] + if (updatedInputs[activeIndex] && updatedInputs[overIndex]) { + if (updatedInputs[activeIndex].groupGuid !== updatedInputs[overIndex].groupGuid) { + updatedInputs[activeIndex].groupGuid = updatedInputs[overIndex].groupGuid + updatedInputs[activeIndex].groupId = updatedInputs[overIndex].groupId + return { + ...state, + form: { + ...form, + inputsList: arrayMove(updatedInputs, activeIndex, overIndex - 1).map((i, index) => ({ ...i, displayOrder: index })) + } + } + } + return { + ...state, + form: { + ...form, + inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map((i, index) => ({ ...i, displayOrder: index })) + } + } + } + return state + } + default: + return state + } +} + diff --git a/libs/portals/admin/form-system/src/hooks/fileUploadReducer.ts b/libs/portals/admin/form-system/src/hooks/fileUploadReducer.ts new file mode 100644 index 000000000000..4e8c480714b1 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/fileUploadReducer.ts @@ -0,0 +1,43 @@ +import { UploadFile, UploadFileStatus } from '@island.is/island-ui/core' + +enum ActionTypes { + add = 'add', + remove = 'remove', + update = 'update', +} + +type FileUploadActions = + | { type: 'add'; payload: { newFiles: UploadFile[] } } + | { type: 'remove'; payload: { fileToRemove: UploadFile } } + | { + type: 'update' + payload: { file: UploadFile; status: UploadFileStatus; percent: number } + } + +export default function fileUploadReducer( + state: UploadFile[], + action: FileUploadActions, +) { + switch (action.type) { + case ActionTypes.add: + return state.concat(action.payload.newFiles) + + case ActionTypes.remove: + return state.filter( + (file) => file.name !== action.payload.fileToRemove.name, + ) + + case ActionTypes.update: + return [ + ...state.map((file: UploadFile) => { + if (file.name === action.payload.file.name) { + file.status = action.payload.status + file.percent = action.payload.percent + } + return file + }), + ] + default: + throw new Error() + } +} diff --git a/libs/portals/admin/form-system/src/hooks/formReducer.ts b/libs/portals/admin/form-system/src/hooks/formReducer.ts new file mode 100644 index 000000000000..1a1fd6e1a371 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/formReducer.ts @@ -0,0 +1,199 @@ +/* eslint-disable func-style */ +import { UniqueIdentifier } from '@dnd-kit/core' +import { + ICertificate, + IFormBuilder, + ILanguage, + ITenging, +} from '../types/interfaces' +import { saveFormSettings } from '../services/apiService' + +type ILang = 'is' | 'en' + +type ChangeNameAction = { + type: 'changeName' + payload: { + lang: ILang + newName: string + } +} + +type ApplicationsDaysToRemoveAction = { + type: 'applicationsDaysToRemove' + payload: { + value: number + } +} + +type InvalidationDateAction = { + type: 'invalidationDate' + payload: { + value: Date + } +} + +type StopProgressOnValidatingStepAction = { + type: 'stopProgressOnValidatingStep' + payload: { + value: boolean + } +} + +type AddRemoveConnectionAction = { + type: 'addRemoveConnection' + payload: { + active: UniqueIdentifier + item: UniqueIdentifier + } +} + +type UpdateDocuments = { + type: 'updateDocuments' + payload: { + documents: ICertificate[] + } +} + +type FormSettingsPayload = + | { property: 'invalidationDate'; value: Date } + | { property: 'dependencies'; value: ITenging } + | { property: 'stopProgressOnValidatingStep'; value: boolean } + | { property: 'applicationsDaysToRemove'; value: number } + | { + property: 'formDocumentTypes' + value: { formId: number; documentTypeId: number }[] + } + | { property: 'adilar'; value: string[] } + | { property: 'completedMessage'; value: ILanguage } + | { property: 'isTranslated'; value: boolean } + +type FormSettingsAction = { + type: 'formSettings' + payload: FormSettingsPayload +} + +export type FormAction = + | ChangeNameAction + | ApplicationsDaysToRemoveAction + | InvalidationDateAction + | StopProgressOnValidatingStepAction + | AddRemoveConnectionAction + | FormSettingsAction + | UpdateDocuments + +export function formReducer(formBuilder: IFormBuilder, action: FormAction) { + switch (action.type) { + case 'changeName': { + const { lang, newName } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + name: { + ...formBuilder.form?.name, + [lang]: newName, + }, + }, + } + } + case 'applicationsDaysToRemove': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + applicationsDaysToRemove: value, + }, + } + } + case 'invalidationDate': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + invalidationDate: value, + }, + } + } + case 'stopProgressOnValidatingStep': { + const { value } = action.payload + return { + ...formBuilder, + form: { + ...formBuilder.form, + stopProgressOnValidatingStep: value, + }, + } + } + case 'addRemoveConnection': { + const { active, item } = action.payload + const itemAsString = String(item) + const dependencies = { ...formBuilder.form?.dependencies } + + if (active in dependencies) { + if (!dependencies[active].includes(itemAsString)) { + dependencies[active] = [...dependencies[active], itemAsString] + } else { + dependencies[active] = dependencies[active].filter((t: UniqueIdentifier) => t !== item) + if (dependencies[active].length === 0) { + delete dependencies[active] + } + } + } else { + dependencies[active] = [itemAsString] + } + saveFormSettings(formBuilder.form?.id ?? 0, { + id: formBuilder.form?.id ?? 0, + dependencies: dependencies, + }) + return { + ...formBuilder, + form: { + ...formBuilder.form, + dependencies, + }, + } + } + + case 'formSettings': { + const { property, value } = action.payload + const id = formBuilder.form?.id ?? 0 + saveFormSettings(id, { + id: id, + [property]: value, + }) + return { + ...formBuilder, + form: { + ...formBuilder.form, + [property]: value, + }, + } + } + + case 'updateDocuments': { + const { documents } = action.payload + const saveDocuments = documents.map((d) => { + return { + formId: formBuilder.form?.id ?? 0, + documentTypeId: d.id, + } + }) + saveFormSettings(formBuilder.form?.id ?? 0, { + id: formBuilder.form?.id ?? 0, + formDocumentTypes: saveDocuments, + }) + return { + ...formBuilder, + form: { + ...formBuilder.form, + documentTypes: documents, + }, + } + } + + default: + return formBuilder + } +} diff --git a/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts b/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts new file mode 100644 index 000000000000..a92d3484df39 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts @@ -0,0 +1,29 @@ +export type FormHeaderAction = + | { type: 'changeOrganization'; payload: { value: string } } + | { type: 'changeApplicationName'; payload: { value: string } } + +export function headerInfoReducer( + info: { + organization: string + applicationName: string + }, + action: FormHeaderAction, +) { + switch (action.type) { + case 'changeOrganization': { + return { + ...info, + organization: action.payload?.value ? action.payload.value : '', + } + } + case 'changeApplicationName': { + return { + ...info, + applicationName: action.payload?.value ? action.payload.value : '', + } + } + default: { + return info + } + } +} diff --git a/libs/portals/admin/form-system/src/hooks/settingsReducer.ts b/libs/portals/admin/form-system/src/hooks/settingsReducer.ts new file mode 100644 index 000000000000..2b1e82a977d9 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/settingsReducer.ts @@ -0,0 +1,18 @@ +import { FormSystemApplicantType, FormSystemDocumentType, FormSystemInput, FormSystemListType } from "@island.is/api/schema" +import { Maybe } from "graphql/jsutils/Maybe" + + +export type SettingsState = { + applicantTypes: Maybe[]> | undefined + documentTypes: Maybe[]> | undefined + inputTypes: Maybe[]> | undefined + listTypes: Maybe[]> | undefined +} + +export type SettingsAction = + | { type: 'something', payload: 'something' } + +export const settingsReducer = (state: SettingsState, action: SettingsAction): SettingsState => { + + return state +} diff --git a/libs/portals/admin/form-system/src/hooks/useUser.ts b/libs/portals/admin/form-system/src/hooks/useUser.ts new file mode 100644 index 000000000000..bee6280737f9 --- /dev/null +++ b/libs/portals/admin/form-system/src/hooks/useUser.ts @@ -0,0 +1,40 @@ +import { useSession } from 'next-auth/client' +import { useEffect, useState } from 'react' +import { User } from '../types/interfaces' + +export default function useUser() { + const [user, setUser] = useState() + const [session, loading] = useSession() + + const timeNow = Math.floor(Date.now() / 1000) + const expiryStr = session?.expires ? new Date(session.expires.replace(/['"]+/g, '')).getTime() : undefined + const expiry = Math.floor((expiryStr ?? 0) / 1000) + + const hasNotExpired = timeNow < expiry + + const [isAuthenticated, setIsAuthenticated] = useState( + Boolean(hasNotExpired), + ) + + useEffect(() => { + if (!hasNotExpired) { + setUser(undefined) + setIsAuthenticated(false) + sessionStorage.clear() + } else { + if (!user && session?.user) { + const { name = '', email, image } = session.user || {} + setUser({ name: name || '', email: email || '', image: image || '' }) + setIsAuthenticated(true); + } + } + }, [setUser, session, user]) + + return { + isAuthenticated, + setIsAuthenticated, + user, + setUser, + userLoading: loading, + } +} diff --git a/libs/portals/admin/form-system/src/lib/messages.ts b/libs/portals/admin/form-system/src/lib/messages.ts index 7db8d5c3d174..c1124066891f 100644 --- a/libs/portals/admin/form-system/src/lib/messages.ts +++ b/libs/portals/admin/form-system/src/lib/messages.ts @@ -4,12 +4,12 @@ import { defineMessages } from "react-intl"; export const m = defineMessages({ formSystemIntro: { id: 'admin-portal.form-system:formSystemIntro', - defaultMessage: 'Umsóknakerfi', + defaultMessage: 'Umsóknarsmiður', description: '' }, formSystemTitle: { id: 'admin-portal.form-system:Title', - defaultMessage: 'Umsóknarsmiður fyrir stofnanir', + defaultMessage: 'Umsóknarsmiður', description: '' } }) diff --git a/libs/portals/admin/form-system/src/lib/navigation.ts b/libs/portals/admin/form-system/src/lib/navigation.ts index 05f27ae1da78..9d54beeff3b8 100644 --- a/libs/portals/admin/form-system/src/lib/navigation.ts +++ b/libs/portals/admin/form-system/src/lib/navigation.ts @@ -12,7 +12,7 @@ export const formSystemNavigation: PortalNavigationItem = { children: [ { name: m.formSystemTitle, - path: FormSystemPaths.FormSystemRoot, + path: FormSystemPaths.Form, activeIfExact: true } ] diff --git a/libs/portals/admin/form-system/src/lib/utils/interfaces.ts b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts new file mode 100644 index 000000000000..69d9ad8e0632 --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts @@ -0,0 +1,16 @@ +import { FormSystemStep, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" + + +export enum NavbarSelectStatus { + OFF = 'Off', + NORMAL = 'Normal', + LIST_ITEM = 'ListItem', + ON_WITHOUT_SELECT = 'OnWithoutSelect', +} + +export type ItemType = 'Step' | 'Group' | 'Input' + +export interface ActiveItem { + type: ItemType + data?: FormSystemStep | FormSystemGroup | FormSystemInput | null +} diff --git a/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts new file mode 100644 index 000000000000..74e10cdcb0e5 --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts @@ -0,0 +1,85 @@ +import { ActiveItem } from "./interfaces" +import { useFormSystemUpdateStepMutation } from "../../gql/Step.generated" +import { useFormSystemUpdateGroupMutation } from "../../gql/Group.generated" +import { useFormSystemUpdateInputMutation } from "../../gql/Input.generated" +import { FormSystemStep, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" + +export const updateActiveItemFn = ( + activeItem: ActiveItem, + updateStep = useFormSystemUpdateStepMutation()[0], + updateGroup = useFormSystemUpdateGroupMutation()[0], + updateInput = useFormSystemUpdateInputMutation()[0], + currentActiveItem?: ActiveItem +) => { + const { type } = activeItem + console.log('updating: ', type) + if (type === 'Step') { + const { id, name, type, displayOrder, waitingText, callRuleset } = currentActiveItem ? currentActiveItem.data as FormSystemStep : activeItem.data as FormSystemStep + + updateStep({ + variables: { + input: { + stepId: id, + stepUpdateDto: { + id: id, + name: name?.__typename ? { ...name, __typename: undefined } : name, + type: type, + displayOrder: displayOrder, + waitingText: waitingText?.__typename ? { ...waitingText, __typename: undefined } : waitingText, + callRuleset: callRuleset + } + } + } + }) + } else if (type === 'Group') { + const { id, name, guid, displayOrder, multiSet } = currentActiveItem ? currentActiveItem.data as FormSystemGroup : activeItem.data as FormSystemGroup + updateGroup({ + variables: { + input: { + groupId: activeItem?.data?.id, + groupUpdateDto: { + id, + name: name?.__typename ? { ...name, __typename: undefined } : name, + guid, + displayOrder, + multiSet, + }, + }, + }, + }) + } else if (type === 'Input') { + const { + id, + name, + description, + isRequired, + displayOrder, + isHidden, + type, + inputSettings, + isPartOfMultiSet, + } = currentActiveItem ? currentActiveItem.data as FormSystemInput : activeItem.data as FormSystemInput + updateInput({ + variables: { + input: { + inputId: activeItem?.data?.id, + inputUpdateDto: { + id, + name: name?.__typename ? { ...name, __typename: undefined } : name, + description: description?.__typename + ? { ...description, __typename: undefined } + : description, + isRequired: isRequired ?? false, + displayOrder, + isHidden: isHidden ?? false, + type, + inputSettings: inputSettings?.__typename + ? { ...inputSettings, __typename: undefined } + : inputSettings, + isPartOfMultiSet: isPartOfMultiSet ?? false, + }, + }, + }, + }); + } +}; diff --git a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts new file mode 100644 index 000000000000..395e0a7e3a82 --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts @@ -0,0 +1,97 @@ +import { FormSystemGroup, FormSystemGroupInput, FormSystemInput } from "@island.is/api/schema" +import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" +import { ControlState } from "../../hooks/controlReducer" +import { ItemType } from "./interfaces" + + +export const updateDnd = ( + type: ItemType, + control: ControlState, + updateForm = useFormSystemUpdateFormMutation()[0] +) => { + console.log('updating: ', type) + const formId = control.form.id + if (type === 'Step') { + const steps = control.form.stepsList + const { form } = control + updateForm({ + variables: { + input: { + formId: formId, + form: { + stepsList: steps?.map(s => ({ + id: s?.id, + guid: s?.guid, + displayOrder: s?.displayOrder, + name: s?.name?.__typename ? { ...s?.name, __typename: undefined } : s?.name, + type: s?.type, + waitingText: s?.waitingText?.__typename ? { ...s?.waitingText, __typename: undefined } : s?.waitingText, + callRuleset: s?.callRuleset, + isHidden: s?.isHidden, + isCompleted: s?.isCompleted, + })) + } + } + } + }) + } else if (type === 'Group') { + const { groupsList } = control.form + const updatedGroup = groupsList?.map(g => ({ + id: g?.id, + name: g?.name?.__typename ? { ...g?.name, __typename: undefined } : g?.name, + guid: g?.guid, + displayOrder: g?.displayOrder, + isHidden: g?.isHidden ?? false, + stepId: g?.stepId, + multiSet: g?.multiSet, + stepGuid: g?.stepGuid, + })) + console.log('updatedGroup', updatedGroup) + updateForm({ + variables: { + input: { + formId: formId, + form: { + groupsList: groupsList?.map(g => ({ + id: g?.id, + name: g?.name?.__typename ? { ...g?.name, __typename: undefined } : g?.name, + guid: g?.guid, + displayOrder: g?.displayOrder, + isHidden: g?.isHidden ?? false, + stepId: g?.stepId, + multiSet: g?.multiSet, + stepGuid: g?.stepGuid, + } as FormSystemGroupInput), + ) + } + } + } + }) + } else if (type === 'Input') { + const { inputsList } = control.form + updateForm({ + variables: { + input: { + formId: formId, + form: { + inputsList: inputsList?.filter((i): i is FormSystemInput => i !== null && i !== undefined).map(i => ({ + id: i.id, + name: i.name?.__typename ? { ...i.name, __typename: undefined } : i.name, + description: i.description?.__typename ? { ...i.description, __typename: undefined } : i.description, + isRequired: i.isRequired ?? false, + displayOrder: i.displayOrder, + isHidden: i.isHidden ?? false, + type: i.type, + inputSettings: i.inputSettings?.__typename ? { ...i.inputSettings, __typename: undefined } : i.inputSettings, + isPartOfMultiSet: i.isPartOfMultiSet ?? false, + groupId: i.groupId, + groupGuid: i.groupGuid, + guid: i.guid + }), + ) + } + } + } + }) + } +} diff --git a/libs/portals/admin/form-system/src/lib/utils/updateForm.ts b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts new file mode 100644 index 000000000000..b82824087219 --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts @@ -0,0 +1,33 @@ +import { FormSystemForm } from "@island.is/api/schema" +import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" +import { ControlState } from "../../hooks/controlReducer" + + +export const partialFormUpdate = ( + control: ControlState, + updateForm = useFormSystemUpdateFormMutation()[0], + updatedForm?: FormSystemForm +) => { + const form = updatedForm ? updatedForm : control.form + console.log('updating form: ', form) + updateForm({ + variables: { + input: { + formId: form.id, + form: { + invalidationDate: form.invalidationDate, + name: form.name?.__typename ? { ...form.name, __typename: undefined } : form.name, + stopProgressOnValidatingStep: form.stopProgressOnValidatingStep ?? false, // doesnt save....whyyyy + applicationsDaysToRemove: form.applicationsDaysToRemove, + documentTypes: form.documentTypes?.map(d => ({ + __typename: undefined, + id: d?.id, + type: d?.type, + name: d?.name?.__typename ? { ...d?.name, __typename: undefined } : d?.name, + description: d?.description?.__typename ? { ...d?.description, __typename: undefined } : d?.description, + })), + } + } + } + }) +} diff --git a/libs/portals/admin/form-system/src/module.tsx b/libs/portals/admin/form-system/src/module.tsx index 407fe3ce6a0c..e775a327c911 100644 --- a/libs/portals/admin/form-system/src/module.tsx +++ b/libs/portals/admin/form-system/src/module.tsx @@ -4,11 +4,14 @@ import { m } from './lib/messages'; import { PortalModule } from '@island.is/portals/core' import { FormSystemPaths } from './lib/paths' import { formsLoader } from './screens/Forms/Forms.loader'; +import { formLoader } from './screens/Form/Form.loader'; const Forms = lazy(() => import('./screens/Forms/Forms') ) +const Form = lazy(() => import('./screens/Form/Form')) + const allowedScopes: string[] = [ AdminPortalScope.formSystem, AdminPortalScope.formSystemSuperUser @@ -19,13 +22,19 @@ export const formSystemModule: PortalModule = { layout: 'full', enabled: ({ userInfo }) => userInfo.scopes.some((scope) => allowedScopes.includes(scope)), - routes: () => { + routes: (props) => { return [ { name: m.formSystemTitle, path: FormSystemPaths.FormSystemRoot, element: , - // loader: formsLoader(props) + loader: formsLoader(props) + }, + { + name: m.formSystemIntro, + path: FormSystemPaths.Form, + element: , + loader: formLoader(props) } ] } diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts new file mode 100644 index 000000000000..602283ff041d --- /dev/null +++ b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts @@ -0,0 +1,39 @@ +import type { WrappedLoaderFn } from '@island.is/portals/core' +import { FormSystemFormResponse } from '@island.is/api/schema' + +import { ApolloClient, NormalizedCacheObject } from '@apollo/client' +import { FormSystemGetFormDocument, FormSystemGetFormQuery } from '../../gql/Form.generated' + +export interface FormLoaderResponse { + formBuilder: FormSystemFormResponse, + client: ApolloClient +} + + +export const formLoader: WrappedLoaderFn = ({ client }) => { + return async ({ params }): Promise => { + if (!params.formId) { + throw new Error('FormId not provided in parameters') + } + const { data: formData, error: formError } = + await client.query({ + query: FormSystemGetFormDocument, + fetchPolicy: 'network-only', + variables: { + input: { + id: Number(params.formId), + }, + } + }) + if (formError) { + throw formError + } + if (!formData) { + throw new Error(`No form data found for ${params.formId}`) + } + return { + formBuilder: formData.formSystemGetForm, + client + } + } +} diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.tsx b/libs/portals/admin/form-system/src/screens/Form/Form.tsx index 0a975f0d4415..067b72ca56b7 100644 --- a/libs/portals/admin/form-system/src/screens/Form/Form.tsx +++ b/libs/portals/admin/form-system/src/screens/Form/Form.tsx @@ -1,137 +1,120 @@ -import { - useState, - useContext, - useReducer, - useRef, - useEffect, - FocusEvent, -} from 'react' -import FormBuilderContext from '../context/FormBuilderContext' -import LayoutContext from '../context/LayoutContext' -import { formReducer } from '../hooks/formReducer' -import { listsReducer } from '../hooks/listsReducer' -import { updateForm, updateItem } from '../services/apiService' -import { - IFormBuilder, - IFormBuilderContext, - IListItem, - ILists, - NavbarSelectStatus, -} from '../types/interfaces' -import { defaultStep } from '../utils/defaultStep' -import { baseSettingsStep } from '../utils/getBaseSettingsStep' +import { useLoaderData } from "react-router-dom" +import { useEffect, useReducer, useState } from "react" +import { NavbarSelectStatus } from "../../lib/utils/interfaces" +import { FormLoaderResponse } from "./Form.loader" +import { ControlState, controlReducer } from "../../hooks/controlReducer" +import { baseSettingsStep } from "../../utils/getBaseSettingsStep" +import { defaultStep } from "../../utils/defaultStep" +import ControlContext, { IControlContext } from "../../context/ControlContext" import { GridRow as Row, GridColumn as Column, Box, } from '@island.is/island-ui/core' -import Navbar from '../components/Navbar/Navbar' -import NavbarSelect from '../components/NavbarSelect/NavbarSelect' -import MainContent from '../components/MainContent/MainContent' +import Navbar from "../../components/Navbar/Navbar" +import { FormSystemForm, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" +import MainContent from "../../components/MainContent/MainContent" +import { useFormSystemUpdateGroupMutation } from "../../gql/Group.generated" +import { useFormSystemUpdateStepMutation } from "../../gql/Step.generated" +import { useFormSystemUpdateInputMutation } from "../../gql/Input.generated" +import { updateActiveItemFn } from "../../lib/utils/updateActiveItem" +import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" +import { ActiveItem, ItemType } from "../../lib/utils/interfaces" +import { updateDnd } from "../../lib/utils/updateDnd" +import { SettingsState, settingsReducer } from "../../hooks/settingsReducer" +import { partialFormUpdate } from "../../lib/utils/updateForm" -type Props = { - form: IFormBuilder -} -export default function Form({ form }: Props) { - const [focus, setOnFocus] = useState('') - const [inSettings, setInSettings] = useState(form.form.name.is === '') - const [selectStatus, setSelectStatus] = useState( - NavbarSelectStatus.OFF, - ) - const [activeListItem, setActiveListItem] = useState(null) - const { infoDispatch } = useContext(LayoutContext) - const initialNavbar: ILists = { - activeItem: inSettings - ? { type: 'Step', data: baseSettingsStep } - : { - type: 'Step', - data: - form?.form?.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, - steps: form.form.stepsList ?? [], - groups: form.form.groupsList ?? [], - inputs: form.form.inputsList ?? [], - } - const [formBuilder, formDispatch] = useReducer(formReducer, form) - const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) - const { activeItem } = lists - const isMounted = useRef(false) +const Form = () => { + const { formBuilder, client } = useLoaderData() as FormLoaderResponse + const { form, applicantTypes, documentTypes, inputTypes, listTypes } = formBuilder + const [focus, setFocus] = useState('') + const [inSettings, setInSettings] = useState(form?.name?.is === '') + const [selectStatus, setSelectStatus] = useState(NavbarSelectStatus.OFF) - useEffect(() => { - isMounted.current = true - infoDispatch({ - type: 'changeOrganization', - payload: { - value: formBuilder?.form?.organization.name.is, - }, - }) - infoDispatch({ - type: 'changeApplicationName', - payload: { - value: formBuilder.form.name.is, - }, - }) - }, [formBuilder, infoDispatch]) + const [updateStep] = useFormSystemUpdateStepMutation() + const [updateGroup] = useFormSystemUpdateGroupMutation() + const [updateInput] = useFormSystemUpdateInputMutation() + const [updateForm] = useFormSystemUpdateFormMutation() - const context: IFormBuilderContext = { - formBuilder: formBuilder, - formDispatch: formDispatch, - lists: lists, - listsDispatch: listsDispatch, - formUpdate: formUpdate, - inSettings: inSettings, - setInSettings: setInSettings, - setSelectStatus: setSelectStatus, - selectStatus: selectStatus, - activeListItem: activeListItem, - setActiveListItem: setActiveListItem, - blur: blur, - onFocus: onFocus, + const initialControl: ControlState = { + activeItem: { + type: 'Step', + data: inSettings ? baseSettingsStep : form?.stepsList?.find((s) => s?.type === 'Innsláttur') ?? defaultStep + }, + form: form as FormSystemForm } - if (formBuilder.form && activeItem) { - return ( - - - - {selectStatus !== NavbarSelectStatus.OFF ? ( - - ) : ( - - )} - - - - {activeItem?.data && } - - - - - ) + const initialSettings: SettingsState = { + applicantTypes, + documentTypes, + inputTypes, + listTypes } - return <>Loading - - async function formUpdate() { - updateForm(formBuilder.form, lists.steps, lists.groups, lists.inputs) + const [settings, settingsDispatch] = useReducer(settingsReducer, initialSettings) + const [control, controlDispatch] = useReducer(controlReducer, initialControl) + const updateActiveItem = (updatedActiveItem?: ActiveItem) => updateActiveItemFn(control.activeItem, updateStep, updateGroup, updateInput, updatedActiveItem) + const updateDragAndDrop = (type: ItemType) => updateDnd(type, control, updateForm) + const formSettingsUpdate = (updatedForm?: FormSystemForm) => { + if (updatedForm) { + controlDispatch({ type: 'CHANGE_FORM_SETTINGS', payload: { newForm: updatedForm } }) + } + return partialFormUpdate(control, updateForm, updatedForm) } - function blur(e: FocusEvent) { - if (e.target.value !== focus) { - setOnFocus('') - updateItem(activeItem.type, activeItem.data) - } + const context: IControlContext = { + control, + controlDispatch, + apolloClient: client, + applicantTypes, + documentTypes, + inputTypes, + listTypes, + setInSettings, + inSettings, + updateActiveItem, + focus, + setFocus, + updateDnD: updateDragAndDrop, + formSettingsUpdate, + selectStatus, + setSelectStatus } - function onFocus(value: string) { - setOnFocus(value) + + useEffect(() => { + console.log('loaderData form: ', form) + console.log('loaderData client: ', client) + console.log('control: ', control) + }, []) + + if (!form) { + return
Loading...
} + return ( + + + + {/* {selectStatus !== NavbarSelectStatus.OFF ? : } */} + + + + + + + + + + ) } + +export default Form + + diff --git a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql index 496ad9a13fc7..58304d77e5ff 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql @@ -1,7 +1,570 @@ + mutation formSystemCreateForm( $input: FormSystemCreateFormInput! ) { formSystemCreateForm(input: $input) { - form + form { + id + name { + is + en + } + applicationsDaysToRemove + completedMessage { + is + en + } + created + dependencies + documentTypes { + id + name { + is + en + } + description { + is + en + } + type + } + formApplicantTypes { + applicantTypeId + formId + name { + is + en + } + type + } + groupsList { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + inputsList { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + invalidationDate + isTranslated + lastChanged + organization { + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + id + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + listTypes { + id + name { + is + en + } + description { + is + en + } + type + } + name { + is + en + } + nationalId + } + steps { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stepsList { + callRuleset + displayOrder + groups { + displayOrder + guid + id + inputs { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } + isHidden + multiSet + name { + is + en + } + stepGuid + stepId + } + guid + id + isCompleted + isHidden + name { + is + en + } + type + waitingText { + is + en + } + } + stopProgressOnValidatingStep + } + applicantTypes { + applicantTypeId + description { + is + en + } + id + name { + is + en + } + nameSuggestion { + applicantTypeId + nameSuggestion { + is + en + } + } + type + } + documentTypes { + description { + is + en + } + id + name { + is + en + } + type + } + inputTypes { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings { + amount + buttonText { + is + en + } + hasInput + hasLink + header + interval + isLarge + isList + isMulti + list { + description { + is + en + } + displayOrder + guid + isSelected + label { + is + en + } + value + } + max + maxLength + maxSize + min + minLength + name { + is + en + } + size + type + types + url + } + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } } } + diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts index 142a62ecd866..e91078d96c05 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts @@ -2,9 +2,12 @@ import { WrappedLoaderFn } from '@island.is/portals/core' import { FormSystemGetFormsDocument, FormSystemGetFormsQuery } from './Forms.generated' import { FormSystemForm } from '@island.is/api/schema' +export interface FormsLoaderResponse { + forms: FormSystemForm[] +} export const formsLoader: WrappedLoaderFn = ({ client }) => { - return async (): Promise> => { + return async (): Promise => { const { data, error } = await client.query({ query: FormSystemGetFormsDocument, @@ -20,6 +23,8 @@ export const formsLoader: WrappedLoaderFn = ({ client }) => { if (!data) { throw new Error('No forms were found') } - return data.formSystemGetForms.forms?.filter((form) => form !== null) as FormSystemForm[]; + return { + forms: data.formSystemGetForms.forms?.filter((form) => form !== null) as FormSystemForm[] + } } } diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx index 9c3058c80702..5386ccb28aff 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx @@ -4,13 +4,16 @@ import { Text, Inline } from '@island.is/island-ui/core' -import { useNavigate } from 'react-router-dom' +import { useLoaderData, useNavigate } from 'react-router-dom' import { FormSystemPaths } from '../../lib/paths' import TableRow from '../../components/TableRow/TableRow' import { useFormSystemGetFormsQuery } from './Forms.generated' +import { useFormSystemCreateFormMutation } from './CreateForm.generated' +import { FormsLoaderResponse } from './Forms.loader' const Forms = () => { const navigate = useNavigate() + const { data, loading, error } = useFormSystemGetFormsQuery({ variables: { input: { @@ -19,6 +22,14 @@ const Forms = () => { } }) + const [formSystemCreateFormMutation, { data: newData, loading: newLoading, error: newError }] = useFormSystemCreateFormMutation({ + variables: { + input: { + organizationId: 1 + } + } + }) + const forms = data?.formSystemGetForms.forms console.log(data) if (!loading && !error) { @@ -33,9 +44,11 @@ const Forms = () => { @@ -63,7 +76,7 @@ const Forms = () => { // lastModified={f?.lastChanged} org={f?.organization?.id} isHeader={false} - translated={f?.isTranslated} + translated={f?.isTranslated ?? false} /> ) })} diff --git a/libs/portals/admin/form-system/src/services/apiService.tsx b/libs/portals/admin/form-system/src/services/apiService.tsx new file mode 100644 index 000000000000..fbdc0f1dd490 --- /dev/null +++ b/libs/portals/admin/form-system/src/services/apiService.tsx @@ -0,0 +1,248 @@ +import axios from 'axios' + +import { + IForm, + IFormApplicantType, + IFormBuilder, + IGroup, + IInput, + IInputSettings, + ILanguage, + IStep, + ItemType, +} from '../types/interfaces' +import { groupSchema, stepSchema } from './zodValidation' + +const BASEURL = 'https://profun.island.is/umsoknarkerfi/api' + +export async function getForm(id: unknown): Promise { + try { + const response = await axios.get(`${BASEURL}/Forms/${id}`) + // const validatedFormData: IFormBuilder = formFormBuilderSchema.parse(response.data) + // return validatedFormData + return response.data + } catch (error) { + console.error(error) + throw error + } +} + +export async function updateForm( + form: IForm, + steps: IStep[], + groups: IGroup[], + inputs: IInput[], +) { + const updatedForm: IForm = { + ...form, + stepsList: steps.map((s, i) => { + return { + ...s, + displayOrder: i, + } + }), + groupsList: groups.map((g, i) => { + return { + ...g, + displayOrder: i, + } + }), + inputsList: inputs.map((i, index) => { + return { + ...i, + displayOrder: index, + } + }), + } + + try { + const response = await axios.put( + `${BASEURL}/Forms/${form.id}`, + updatedForm, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + + return response + } catch (error) { + console.error('Error in updateNavbar:', error) + throw error + } +} + +export async function updateItem(type: string, data: IStep | IGroup | IInput) { + const url = `${BASEURL}/${type}s/${data.id}` + + try { + const response = await axios.put(url, data, { + headers: { + 'Content-Type': 'application/json', + }, + }) + + return response + } catch (error) { + console.error('Error in updateItem: ', error) + throw error + } +} + +export async function getNewForm(organisationId: number): Promise { + try { + const response = await axios.post(`${BASEURL}/Forms/${organisationId}`) + return response.data + } catch (error) { + console.error('Error in getNewForm: ', error) + throw error + } +} + +export async function getAllFormsFromOrganisation( + organisationId: number, +): Promise { + try { + const response = await axios.get( + `${BASEURL}/Forms/Organization/${organisationId}`, + ) + return response.data + } catch (error) { + console.error('Error in getAllFormsFromOrganisation: ', error) + throw error + } +} + +export async function addStep( + formId: number, + name: ILanguage, + displayOrder: number, + stepType: number, + waitingText: ILanguage, + callRuleset: boolean, +): Promise { + try { + const response = await axios.post(`${BASEURL}/Steps`, { + formId, + name, + displayOrder, + stepType, + waitingText, + callRuleset, + }) + + const validatedStep: IStep = stepSchema.parse(response.data) + return validatedStep + } catch (error) { + console.error('Error in addStep: ', error) + throw error + } +} + +export async function addGroup( + displayOrder: number, + parentId: number, +): Promise { + try { + const response = await axios.post(`${BASEURL}/Groups`, { + displayOrder: displayOrder, + stepId: parentId, + }) + + const validatedGroup: IGroup = groupSchema.parse(response.data) + + return validatedGroup + } catch (error) { + console.error('Error in addGroup: ', error) + throw error + } +} + +export async function addInput( + displayOrder: number, + parentId: number, +): Promise { + const requestBody = { + displayOrder: displayOrder, + groupId: parentId, + } + + try { + const response = await axios.post(`${BASEURL}/Inputs`, requestBody, { + headers: { + 'Content-Type': 'application/json', + }, + }) + + const data = response.data + + return data + } catch (error) { + console.error('Error in addInput: ', error) + throw error + } +} + +export async function deleteItem(type: ItemType, id: number) { + try { + const response = await axios.delete(`${BASEURL}/${type}s/${id}`) + return response + } catch (error) { + console.error('Error in deleteItem: ', error) + throw error + } +} + +export async function saveFormSettings(id: number, settings: IInputSettings) { + try { + const response = await axios.put( + `${BASEURL}/Forms/${id}/Settings`, + settings, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + return response + } catch (error) { + console.error('Error in saveFormSettings: ', error) + throw error + } +} + +export async function saveApplicantTypes( + id: number, + types: IFormApplicantType[], +) { + const requestData = { + id: id, + formApplicantTypes: types, + } + try { + const response = await axios.put( + `${BASEURL}/Forms/${id}/Settings`, + requestData, + { + headers: { + 'Content-Type': 'application/json', + }, + }, + ) + + return response + } catch (error) { + console.error('Error in saveApplicantTypes: ', error) + throw error + } +} +export async function getList(type: string) { + try { + const response = await axios.get(`${BASEURL}/Services/${type}`) + return response.data + } catch (error) { + console.error('Error in getList: ', error) + throw error + } +} diff --git a/libs/portals/admin/form-system/src/services/translationStation.tsx b/libs/portals/admin/form-system/src/services/translationStation.tsx new file mode 100644 index 000000000000..19be4bae56f2 --- /dev/null +++ b/libs/portals/admin/form-system/src/services/translationStation.tsx @@ -0,0 +1,41 @@ +import { ITranslationResponse } from '../types/interfaces' +import axios from 'axios' +import dotenv from 'dotenv' + +dotenv.config() + +export const translationStation = async ( + input: string, +): Promise => { + const apiUrl = process.env.MIDEIND_API + const apiKey = process.env.MIDEIND_KEY + + if (!apiUrl || !apiKey) { + throw new Error('API URL or API key is not defined.') + } + + try { + const response = await axios.post( + apiUrl, + { + contents: [input], + sourceLanguageCode: 'is', + targetLanguageCode: 'en', + model: '', + domain: '', + }, + { + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + 'X-API-Key': apiKey, + }, + }, + ) + + return response.data + } catch (error) { + console.error('Error in translationStation: ', error) + throw error + } +} diff --git a/libs/portals/admin/form-system/src/services/zodValidation.ts b/libs/portals/admin/form-system/src/services/zodValidation.ts new file mode 100644 index 000000000000..bc94f18f8e08 --- /dev/null +++ b/libs/portals/admin/form-system/src/services/zodValidation.ts @@ -0,0 +1,193 @@ +import { z } from 'zod' +import { EFormApplicantTypes } from '../types/enums' +import { + IApplicantType, + ICertificate, + IForm, + IFormApplicantType, + IFormBuilder, + IGroup, + IInput, + IInputSettings, + IInputType, + IListType, + IStep, + ITenging, +} from '../types/interfaces' + +const languageSchema = z.object({ + is: z.string(), + en: z.string(), +}) + +const dependencySchema = z.record(z.array(z.string())) as z.ZodSchema + +const inputSettingsSchema = z.object({ + $type: z.string().optional(), + isLarge: z.boolean().optional(), + size: z.enum(['xs', 'sm', 'md']), + interval: z.string().optional(), + erHlekkur: z.boolean().optional(), + url: z.string().optional(), + hnapptexti: languageSchema.optional(), + tegundir: z.array(z.string()).optional(), + hamarksstaerd: z.number().optional(), + erFjolval: z.boolean().optional(), + fjoldi: z.number().optional(), + header: z.string().optional(), + hamarkslengd: z.number().optional(), + lagmarkslengd: z.number().optional(), + laggildi: z.number().optional(), + hagildi: z.number().optional(), + listi: z + .array( + z.object({ + guid: z.string(), + label: languageSchema, + description: languageSchema, + displayOrder: z.number(), + isSelected: z.boolean(), + }), + ) + .optional(), + type: z.string().optional(), + name: languageSchema.optional(), + erListi: z.boolean().optional(), + erInnslattur: z.boolean().optional(), +}) as z.ZodSchema + +export const inputSchema = z.object({ + id: z.number(), + name: languageSchema, + description: languageSchema, + isRequired: z.boolean(), + displayOrder: z.number(), + groupId: z.number(), + groupGuid: z.string(), + isHidden: z.boolean(), + type: z.string(), + guid: z.string(), + inputFields: z.record(z.any()), + inputSettings: inputSettingsSchema, + isPartOfMultiSet: z.boolean(), +}) as z.ZodSchema + +export const groupSchema = z.object({ + id: z.number(), + name: languageSchema, + guid: z.string(), + displayOrder: z.number(), + isHidden: z.boolean(), + multiSet: z.number(), + stepId: z.number(), + stepGuid: z.string(), + inputs: z.array(inputSchema), +}) as z.ZodSchema + +export const stepSchema = z.object({ + id: z.number(), + guid: z.string(), + displayOrder: z.number(), + name: languageSchema, + type: z.string(), + waitingText: languageSchema, + callRuleset: z.boolean(), + isHidden: z.boolean(), + isCompleted: z.boolean(), + groups: z.array(groupSchema), +}) as z.ZodSchema + +const certificateSchema = z.object({ + id: z.number(), + type: z.string(), + name: languageSchema, + description: languageSchema, +}) as z.ZodSchema + +const applicantTypesSchema = z.enum([ + EFormApplicantTypes.einstaklingur, + EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + EFormApplicantTypes.einstaklingurMedProkuru, + EFormApplicantTypes.einstaklingurUmbodsveitandi, + EFormApplicantTypes.logadili, +]) + +const formApplicantSchema = z.object({ + formId: z.number(), + applicantTypeId: z.number(), + name: languageSchema, + type: applicantTypesSchema, +}) as z.ZodSchema + +export const formSchema = z.object({ + id: z.number(), + name: languageSchema, + organization: z.object({ + id: z.number(), + name: languageSchema, + kennitala: z.string(), + scope: z.string(), + xroadBaseUrl: z.string(), + }), + created: z.date(), + lastChanged: z.date(), + invalidationDate: z.date().optional(), + dependencies: dependencySchema, + stepsList: z.array(stepSchema).default([]), + groupsList: z.array(groupSchema).default([]), + inputsList: z.array(inputSchema).default([]), + stopProgressOnValidatingStep: z.boolean(), + applicationsDaysToRemove: z.number(), + isTranslated: z.boolean(), + documentTypes: z.array(certificateSchema), + formApplicantTypes: z.array(formApplicantSchema), +}) as z.ZodSchema + +const inputTypeSchema = z.object({ + type: z.string(), + name: z.string(), + description: z.string(), + organizations: z.array(z.number()).optional(), + inputFields: z.object({}).optional(), + inputMetadata: z.object({}).optional(), + ruleset: z.object({}).optional(), + inputSettings: inputSettingsSchema, +}) as z.ZodSchema + +const applicantTypeSchema = z.object({ + id: z.number(), + name: languageSchema, + type: applicantTypesSchema, + nameSuggestions: z.array( + z.object({ + applicantTypeId: z.number(), + nameSuggestion: languageSchema, + }), + ), +}) as z.ZodSchema + +const listTypeSchema = z.object({ + id: z.number(), + type: z.string(), + name: languageSchema, + description: languageSchema, +}) as z.ZodSchema + +export const formsFormBuilderSchema = z.object({ + forms: z.array(formSchema), + form: formSchema.optional(), + documentTypes: z.array(certificateSchema).optional(), + inputTypes: z.array(inputTypeSchema).optional(), + applicantTypes: z.array(applicantTypeSchema).optional(), + listTypes: z.array(listTypeSchema).optional(), +}) as z.ZodSchema + +export const formFormBuilderSchema = z.object({ + forms: z.null(), + form: formSchema, + documentTypes: z.array(certificateSchema), + inputTypes: z.array(inputTypeSchema), + applicantTypes: z.array(applicantTypeSchema), + listTypes: z.array(listTypeSchema), +}) as z.ZodSchema diff --git a/libs/portals/admin/form-system/src/types/interfaces.tsx b/libs/portals/admin/form-system/src/types/interfaces.tsx index 891c44c723ad..54ae668c1144 100644 --- a/libs/portals/admin/form-system/src/types/interfaces.tsx +++ b/libs/portals/admin/form-system/src/types/interfaces.tsx @@ -1,20 +1,15 @@ import { Dispatch, SetStateAction, FocusEvent } from 'react' import { UniqueIdentifier } from '@dnd-kit/core' import { EFormApplicantTypes } from './enums' -import { Action as ListsAction } from '../hooks/listsReducer' import { FormAction } from '../hooks/formReducer' import { FormHeaderAction } from '../hooks/headerInfoReducer' +import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemListType, FormSystemStep } from '@island.is/api/schema' +import { Maybe } from 'graphql/jsutils/Maybe' export type IFormBuilderContext = { - formBuilder: IFormBuilder - formDispatch: Dispatch - lists: { - activeItem: ActiveItem - steps: IStep[] - groups: IGroup[] - inputs: IInput[] - } - listsDispatch: Dispatch + // formBuilder: IFormBuilder + // formDispatch: Dispatch + lists: ILists formUpdate: () => Promise inSettings: boolean setInSettings: Dispatch> @@ -118,15 +113,15 @@ export interface IInput { export type ILists = { activeItem: ActiveItem - steps: IStep[] - groups: IGroup[] - inputs: IInput[] + steps?: Maybe[] + groups?: Maybe[] + inputs?: Maybe[] [key: string]: unknown } export interface ActiveItem { type: ItemType - data: IStep | IGroup | IInput + data: Maybe | Maybe | Maybe } export interface ISelectOption { @@ -139,12 +134,12 @@ export interface ITenging { } export interface IFormBuilder { - form: IForm - forms?: IForm[] | null - documentTypes: ICertificate[] - inputTypes: IInputType[] - applicantTypes: IApplicantType[] - listTypes: IListType[] + form?: Maybe + forms?: Maybe[] | null + documentTypes?: Maybe[]> + inputTypes?: Maybe[]> + applicantTypes?: Maybe[]> + listTypes?: Maybe[]> } export interface IListType { @@ -232,6 +227,7 @@ export interface ITranslation { translatedText: string translatedTextStructured: [string, string][] } + export enum NavbarSelectStatus { OFF = 'Off', NORMAL = 'Normal', @@ -239,8 +235,6 @@ export enum NavbarSelectStatus { ON_WITHOUT_SELECT = 'OnWithoutSelect', } -export type ItemType = 'Step' | 'Group' | 'Input' - export type ILanguage = { is: string en: string @@ -251,3 +245,5 @@ export interface User { image?: string } type Sizes = 'xs' | 'sm' | 'md' + +export type ItemType = 'Step' | 'Group' | 'Input' diff --git a/libs/portals/admin/form-system/src/utils/defaultStep.tsx b/libs/portals/admin/form-system/src/utils/defaultStep.tsx index 6130a25964f1..03d9bb43d8b5 100644 --- a/libs/portals/admin/form-system/src/utils/defaultStep.tsx +++ b/libs/portals/admin/form-system/src/utils/defaultStep.tsx @@ -1,7 +1,8 @@ import { uuid } from 'uuidv4' import { IStep } from '../types/interfaces' +import { FormSystemStep } from '@island.is/api/schema' -export const defaultStep: IStep = { +export const defaultStep: FormSystemStep = { id: 0, guid: uuid(), displayOrder: 0, @@ -17,4 +18,5 @@ export const defaultStep: IStep = { callRuleset: false, isHidden: false, isCompleted: false, + groups: [] } diff --git a/libs/portals/admin/form-system/src/utils/fileTypes.ts b/libs/portals/admin/form-system/src/utils/fileTypes.ts new file mode 100644 index 000000000000..1012723154a6 --- /dev/null +++ b/libs/portals/admin/form-system/src/utils/fileTypes.ts @@ -0,0 +1,58 @@ +export const fileTypes = { + ".pdf": "application/pdf", + ".doc": "application/msword", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".txt": "text/plain", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".xls": "application/vnd.ms-excel", + ".csv": "text/csv", + ".zip": "application/zip", + "*": "application/octet-stream" +} + +export const fileSizes = [ + { + "label": "1 mb", + "value": 1048576 + }, + { + "label": "2 mb", + "value": 2097152 + }, + { + "label": "3 mb", + "value": 3145728 + }, + { + "label": "4 mb", + "value": 4194304 + }, + { + "label": "5 mb", + "value": 5242880 + }, + { + "label": "6 mb", + "value": 6291456 + }, + { + "label": "7 mb", + "value": 7340032 + }, + { + "label": "8 mb", + "value": 8388608 + }, + { + "label": "9 mb", + "value": 9437184 + }, + { + "label": "10 mb", + "value": 10485760 + } +] diff --git a/libs/portals/admin/form-system/tsconfig.json b/libs/portals/admin/form-system/tsconfig.json index e5981a9141a5..e0b49829e8f6 100644 --- a/libs/portals/admin/form-system/tsconfig.json +++ b/libs/portals/admin/form-system/tsconfig.json @@ -3,7 +3,8 @@ "compilerOptions": { //"module": "commonjs" "jsx": "react-jsx", - "allowJs": true + "allowJs": true, + "resolveJsonModule": true, }, "files": [], "include": [], diff --git a/package.json b/package.json index 7b9cc2e4c5d2..ed3ca0413b9a 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,8 @@ "@contentful/rich-text-react-renderer": "15.16.5", "@contentful/rich-text-types": "16.2.0", "@datadog/browser-rum": "4.36.0", + "@dnd-kit/core": "6.1.0", + "@dnd-kit/sortable": "8.0.0", "@elastic/elasticsearch": "7.7.1", "@formatjs/cli": "4.2.27", "@formatjs/intl-datetimeformat": "4.1.6", diff --git a/yarn.lock b/yarn.lock index 62e8808639eb..c1ccf9d5c072 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7558,7 +7558,7 @@ __metadata: languageName: node linkType: hard -"@dnd-kit/core@npm:^6.0.8": +"@dnd-kit/core@npm:6.1.0, @dnd-kit/core@npm:^6.0.8": version: 6.1.0 resolution: "@dnd-kit/core@npm:6.1.0" dependencies: @@ -7585,6 +7585,19 @@ __metadata: languageName: node linkType: hard +"@dnd-kit/sortable@npm:8.0.0": + version: 8.0.0 + resolution: "@dnd-kit/sortable@npm:8.0.0" + dependencies: + "@dnd-kit/utilities": ^3.2.2 + tslib: ^2.0.0 + peerDependencies: + "@dnd-kit/core": ^6.1.0 + react: ">=16.8.0" + checksum: 26589fd23c18d930a949489b232a7345c0bee4abb6be91d3673232bc79085f13cb5d82087c2068edbc51cbdd3d47c2fe386bada92dc7f2d0dcde13d6be379daa + languageName: node + linkType: hard + "@dnd-kit/sortable@npm:^7.0.2": version: 7.0.2 resolution: "@dnd-kit/sortable@npm:7.0.2" @@ -33743,6 +33756,8 @@ __metadata: "@contentful/rich-text-react-renderer": 15.16.5 "@contentful/rich-text-types": 16.2.0 "@datadog/browser-rum": 4.36.0 + "@dnd-kit/core": 6.1.0 + "@dnd-kit/sortable": 8.0.0 "@elastic/elasticsearch": 7.7.1 "@formatjs/cli": 4.2.27 "@formatjs/intl-datetimeformat": 4.1.6 From 27aa9ab79ce05e5f965f8e4dca0b2a77808c42fc Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Tue, 23 Apr 2024 14:50:44 +0000 Subject: [PATCH 27/72] Working version. Current issue: inputsettings are not being saved due to graphql not handling type discriminators --- .vscode/settings.json | 4 +- .../ListBuilder/components/ListItem.tsx | 12 +- .../form-builder/components/Navbar/Navbar.tsx | 7 +- apps/form-builder/services/apiService.tsx | 2 +- .../domains/form-system/.vscode/settings.json | 3 + .../src/dto/applicantType.input.ts | 4 +- .../form-system/src/dto/documentType.input.ts | 9 + .../form-system/src/dto/groups.input.ts | 3 + .../form-system/src/dto/inputs.input.ts | 4 + .../src/dto/updateFormSettings.input.ts | 51 +++ .../src/lib/forms/forms.resolver.ts | 12 + .../src/lib/forms/forms.service.ts | 58 ++-- .../src/lib/groups/groups.service.ts | 2 +- .../src/lib/inputs/inputs.service.ts | 26 +- .../src/lib/utils/helperFunctions.ts | 210 +++++++------ .../src/models/applicantType.model.ts | 4 +- .../src/models/inputSettings.model.ts | 2 +- libs/clients/form-system/project.json | 2 +- .../clients/form-system/src/clientConfig.json | 21 +- .../src/lib/FormSystemApiProvider.ts | 8 + .../src/lib/FormSystemClient.config.ts | 3 +- .../components/MainContent/MainContent.tsx | 145 ++++----- .../components/BaseSettings/BaseSettings.tsx | 14 +- .../components/InputContent/InputContent.tsx | 10 +- .../InputSettings/InputSettings.tsx | 28 ++ .../components/FIleUploadSettings.tsx | 179 +++++++++++ .../InputSettings/components/ListSettings.tsx | 100 ++++++ .../components/MessageWithLinkSettings.tsx | 71 +++-- .../components/TextInputSettings.tsx | 29 ++ .../components/ListBuilder/ListBuilder.tsx | 182 +++++++++++ .../ListBuilder/components/ListItem.tsx | 285 +++++++++++++++++ .../components/Premises/Premises.tsx | 4 +- .../components/Preview/Preveiw.tsx | 34 +- .../Preview/components/Banknumber.tsx | 113 +++++++ .../Preview/components/Currency.tsx | 38 +++ .../components/Preview/components/Email.tsx | 33 ++ .../Preview/components/FileUpload.tsx | 69 ++++ .../components/Preview/components/List.tsx | 34 ++ .../Preview/components/NationalId.tsx | 22 ++ .../components/Preview/components/Radio.tsx | 59 ++++ .../Preview/components/TextInput.tsx | 20 ++ .../PreviewStepOrGroup/PreviewStepOrGroup.tsx | 91 ++++++ .../components/MultiSet.tsx | 59 ++++ .../RelevantParties/RevelantParties.tsx | 291 +++++++++++++++++ .../components/FormApplicantType.tsx | 144 +++++++++ .../src/components/Navbar/Navbar.tsx | 58 ++-- .../NavComponent/components/NavButtons.tsx | 8 +- .../components/NavbarSelect/NavbarSelect.tsx | 128 ++++---- .../components/SelectNavComponent.tsx | 281 ++++++++--------- .../form-system/src/context/ControlContext.ts | 19 +- .../admin/form-system/src/gql/Form.graphql | 143 +-------- .../form-system/src/gql/FormSettings.graphql | 5 + .../admin/form-system/src/gql/Input.graphql | 66 ++++ .../form-system/src/hooks/controlReducer.ts | 294 +++++++++++++++++- .../form-system/src/lib/utils/fileTypes.ts | 15 + .../form-system/src/lib/utils/interfaces.ts | 20 +- .../src/lib/utils/removeTypename.ts | 15 + .../src/lib/utils/updateActiveItem.ts | 129 ++++---- .../form-system/src/lib/utils/updateDnd.ts | 37 +-- .../form-system/src/lib/utils/updateForm.ts | 54 +++- .../src/lib/utils/updateFormSettings.ts | 38 +++ .../src/screens/Form/Form.loader.ts | 33 +- .../form-system/src/screens/Form/Form.tsx | 48 +-- .../src/screens/Forms/CreateForm.graphql | 4 +- 64 files changed, 3143 insertions(+), 753 deletions(-) create mode 100644 libs/api/domains/form-system/.vscode/settings.json create mode 100644 libs/api/domains/form-system/src/dto/updateFormSettings.input.ts create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/TextInputSettings.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/components/ListItem.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/NationalId.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx create mode 100644 libs/portals/admin/form-system/src/gql/FormSettings.graphql create mode 100644 libs/portals/admin/form-system/src/lib/utils/fileTypes.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/removeTypename.ts create mode 100644 libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 0967ef424bce..d68c91333c4b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1 +1,3 @@ -{} +{ + "workbench.colorTheme": "Default High Contrast" +} diff --git a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx index 24cfa252d8b6..f5aee4ff2520 100644 --- a/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx +++ b/apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx @@ -59,15 +59,15 @@ export default function ListItem({ > {}} + onChange={() => { }} /> {}} + onChange={() => { }} /> @@ -75,7 +75,7 @@ export default function ListItem({ marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => {}} + onClick={() => { }} > @@ -93,7 +93,7 @@ export default function ListItem({ size="sm" value={listItem.label.is} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => {}} + onChange={() => { }} /> @@ -104,7 +104,7 @@ export default function ListItem({ size="sm" value={listItem.label.en} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => {}} + onChange={() => { }} /> diff --git a/apps/form-builder/components/Navbar/Navbar.tsx b/apps/form-builder/components/Navbar/Navbar.tsx index cf7497bf04f3..6a02863759e2 100644 --- a/apps/form-builder/components/Navbar/Navbar.tsx +++ b/apps/form-builder/components/Navbar/Navbar.tsx @@ -1,3 +1,4 @@ +/* eslint-disable func-style */ import { useSensors, useSensor, @@ -304,9 +305,8 @@ export default function Navbar() { if (activeStep && overStep) { dispatchDragAction('stepOverStep') } - // Dragging Group - if (activeGroup) { + else if (activeGroup) { if (overStep) { dispatchDragAction('groupOverStep') } @@ -314,9 +314,8 @@ export default function Navbar() { dispatchDragAction('groupOverGroup') } } - // Dragging Input - if (activeInput) { + else if (activeInput) { if (overGroup) { dispatchDragAction('inputOverGroup') } diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx index fbdc0f1dd490..182f89bb3aa7 100644 --- a/apps/form-builder/services/apiService.tsx +++ b/apps/form-builder/services/apiService.tsx @@ -54,7 +54,7 @@ export async function updateForm( } }), } - + console.log('updatedForm', updatedForm) try { const response = await axios.put( `${BASEURL}/Forms/${form.id}`, diff --git a/libs/api/domains/form-system/.vscode/settings.json b/libs/api/domains/form-system/.vscode/settings.json new file mode 100644 index 000000000000..e82e18462638 --- /dev/null +++ b/libs/api/domains/form-system/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "workbench.colorTheme": "Default Dark+" +} diff --git a/libs/api/domains/form-system/src/dto/applicantType.input.ts b/libs/api/domains/form-system/src/dto/applicantType.input.ts index 10448a1ec726..49c0decdc602 100644 --- a/libs/api/domains/form-system/src/dto/applicantType.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantType.input.ts @@ -20,8 +20,8 @@ export class ApplicantTypeInput { @Field(() => String, { nullable: true }) type?: string | null - @Field(() => ApplicantTypeNameSuggestionInput, { nullable: true }) - nameSuggestion?: ApplicantTypeNameSuggestionInput + @Field(() => [ApplicantTypeNameSuggestionInput], { nullable: 'itemsAndList' }) + nameSuggestions?: ApplicantTypeNameSuggestionInput[] | null } @InputType('FormSystemFormApplicantTypeInput') diff --git a/libs/api/domains/form-system/src/dto/documentType.input.ts b/libs/api/domains/form-system/src/dto/documentType.input.ts index ed28232bb545..3be1e25d546e 100644 --- a/libs/api/domains/form-system/src/dto/documentType.input.ts +++ b/libs/api/domains/form-system/src/dto/documentType.input.ts @@ -17,3 +17,12 @@ export class DocumentTypeInput { @Field(() => LanguageTypeInput, { nullable: true }) description?: LanguageTypeInput } + +@InputType('FormSystemDocumentTypeUpdateInput') +export class DocumentTypeUpdateInput { + @Field(() => Int, { nullable: true }) + formId?: number + + @Field(() => Int, { nullable: true }) + documentTypeId?: number +} diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index 1ff558b4f8ec..d9957894ec5f 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -28,6 +28,9 @@ export class UpdateGroup { @Field(() => Number, { nullable: true }) multiSet?: number + + @Field(() => Int, { nullable: true }) + stepId?: number } @InputType('FormSystemGetGroupInput') diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index d582fca058d5..2d17aba12824 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -40,6 +40,10 @@ export class UpdateInput { @Field() isPartOfMultiSet?: boolean + + @Field(() => Int, { nullable: true }) + groupId?: number + } diff --git a/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts b/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts new file mode 100644 index 000000000000..50b5f6f50fb0 --- /dev/null +++ b/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts @@ -0,0 +1,51 @@ +import { Field, InputType, Int } from "@nestjs/graphql" +import { LanguageTypeInput } from "./language.input" +import graphqlTypeJson from 'graphql-type-json' +import { DocumentTypeUpdateInput } from "./documentType.input" +import { FormApplicantTypeInput } from "./applicantType.input" + + +@InputType('FormSystemFormSettingsInput') +export class FormSettingsInput { + @Field(() => Int, { nullable: true }) + id?: number + + @Field(() => LanguageTypeInput, { nullable: true }) + name?: LanguageTypeInput + + @Field(() => Date, { nullable: true }) + lastChanged?: Date + + @Field(() => Date, { nullable: true }) + invalidationDate?: Date | null + + @Field(() => graphqlTypeJson, { nullable: true }) + dependencies?: { [key: string]: string[] } | null + + @Field(() => [DocumentTypeUpdateInput], { nullable: 'itemsAndList' }) + formDocumentTypes?: DocumentTypeUpdateInput[] | null + + @Field(() => [FormApplicantTypeInput], { nullable: 'itemsAndList' }) + formApplicantTypes?: FormApplicantTypeInput[] | null + + @Field(() => LanguageTypeInput, { nullable: true }) + completedMessage?: LanguageTypeInput + + @Field(() => Boolean, { nullable: true }) + isTranslated?: boolean | null + + @Field(() => Boolean, { nullable: true }) + stopProgressOnValidatingStep?: boolean | null + + @Field(() => Int, { nullable: true }) + applicationsDaysToRemove?: number +} + +@InputType('FormSystemUpdateFormSettingsInput') +export class UpdateFormSettingsInput { + @Field(() => Int) + id!: number + + @Field(() => FormSettingsInput) + formSettingsUpdateDto!: FormSettingsInput +} diff --git a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts index b6249a7a74cf..51baab83d7e3 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts @@ -6,6 +6,7 @@ import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools import { FormListResponse } from "../../models/formListResponse.model" import { Audit } from '@island.is/nest/audit' import { UseGuards } from "@nestjs/common" +import { UpdateFormSettingsInput } from "../../dto/updateFormSettings.input" @@ -56,6 +57,17 @@ export class FormsResolver { return this.formsService.updateForm(user, input) } + @Mutation(() => Boolean, { + nullable: true, + name: 'formSystemUpdateFormSettings' + }) + async updateFormSettings( + @Args('input', { type: () => UpdateFormSettingsInput }) input: UpdateFormSettingsInput, + @CurrentUser() user: User + ): Promise { + return this.formsService.updateFormSettings(user, input) + } + @Mutation(() => Boolean, { nullable: true, name: 'formSystemDeleteForm' diff --git a/libs/api/domains/form-system/src/lib/forms/forms.service.ts b/libs/api/domains/form-system/src/lib/forms/forms.service.ts index ae0a03ced213..68a30c1e459d 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.service.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.service.ts @@ -1,14 +1,13 @@ import { Inject, Injectable } from "@nestjs/common" import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApiFormsFormIdDeleteRequest, ApiFormsFormIdGetRequest, ApiFormsFormIdPutRequest, ApiFormsOrganizationOrganizationIdGetRequest, FormUpdateDto, FormsApi } from "@island.is/clients/form-system" +import { ApiFormsFormIdDeleteRequest, ApiFormsFormIdGetRequest, ApiFormsFormIdPutRequest, ApiFormsOrganizationOrganizationIdGetRequest, FormUpdateDto, FormsApi, ApiFormsFormIdSettingsPutRequest, FormSettingsUpdateDto } from "@island.is/clients/form-system" import { ApolloError } from "@apollo/client" import { AuthMiddleware, User } from '@island.is/auth-nest-tools' import { CreateFormInput, DeleteFormInput, GetFormInput, GetFormsInput, UpdateFormInput } from "../../dto/forms.input" import { FormResponse } from "../../models/formResponse.model" import { FormListResponse } from "../../models/formListResponse.model" -import { graphqlToRestInputSettings, RESTInputSettings, restToGraphqlInputSettings } from "../utils/helperFunctions" -import { Form } from "../../models/form.model" -import { Input } from "../../models/input.model" +import { UpdateFormSettingsInput } from "../../dto/updateFormSettings.input" +import { InputSettings } from "../../models/inputSettings.model" @@ -54,16 +53,20 @@ export class FormsService { if (!response || response instanceof ApolloError) { return {} } - const formattedResponse = { - ...response, - inputsList: response.form?.inputsList?.map((input) => { - return { - ...input, - inputSettings: restToGraphqlInputSettings(input.inputSettings as RESTInputSettings) - } - }) - } - return formattedResponse as FormResponse + // const formattedResponse = { + // ...response, + // inputsList: response.form?.inputsList?.map((input) => { + // const { type, ...newInputSettings } = input.inputSettings as InputSettings + // return { + // ...input, + // inputSettings: { + // ...newInputSettings, + // $type: type + // } + // } + // }) + // } + return response as FormResponse } async getForms(auth: User, input: GetFormsInput): Promise { @@ -116,10 +119,7 @@ export class FormsService { ...input.form, id: input.formId, inputsList: input.form?.inputsList?.map((input) => { - return { - ...input, - inputSettings: graphqlToRestInputSettings(input.inputSettings) - } + return input }) } @@ -127,11 +127,29 @@ export class FormsService { formId: input.formId, formUpdateDto: formattedForm as FormUpdateDto, } - console.log('request: ', request) + // const request: ApiFormsFormIdPutRequest = { + // formId: input.formId, + // formUpdateDto: input.form as FormUpdateDto + // } const response = await this.formsApiWithAuth(auth) .apiFormsFormIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update form')) - console.log('response: ', response) + if (!response || response instanceof ApolloError) { + return void 0 + } + return response + } + + async updateFormSettings(auth: User, input: UpdateFormSettingsInput): Promise { + const request: ApiFormsFormIdSettingsPutRequest = { + formId: input.id, + formSettingsUpdateDto: input.formSettingsUpdateDto as FormSettingsUpdateDto + } + console.log('updateFormSettings request', request) + const response = await this.formsApiWithAuth(auth) + .apiFormsFormIdSettingsPut(request) + .catch((e) => this.handle4xx(e, 'failed to update form settings')) + if (!response || response instanceof ApolloError) { return void 0 } diff --git a/libs/api/domains/form-system/src/lib/groups/groups.service.ts b/libs/api/domains/form-system/src/lib/groups/groups.service.ts index 91b0da53aae3..bd791b5045c7 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.service.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.service.ts @@ -82,7 +82,7 @@ export class GroupsService { groupId: input.groupId, groupUpdateDto: input.groupUpdateDto as GroupUpdateDto } - + console.log('groups update request: ', request) const response = await this.groupsApiWithAuth(auth) .apiGroupsGroupIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update group')) diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts index 8d298e87c607..bf7d12c63704 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts @@ -5,6 +5,9 @@ import { AuthMiddleware, User } from '@island.is/auth-nest-tools' import { InputsApi, ApiInputsInputIdGetRequest, ApiInputsPostRequest, ApiInputsInputIdDeleteRequest, ApiInputsInputIdPutRequest, InputCreationDto, InputUpdateDto } from "@island.is/clients/form-system" import { GetInputInput, CreateInputInput, DeleteInputInput, UpdateInputInput } from "../../dto/inputs.input" import { Input } from "../../models/input.model" +// import { graphql } from "graphql" +// import { RESTInputSettings, graphqlToRestInputSettings, restToGraphqlInputSettings } from "../utils/helperFunctions" +// import { InputSettings } from "../../models/inputSettings.model" @Injectable() export class InputsService { @@ -45,6 +48,10 @@ export class InputsService { if (!response || response instanceof ApolloError) { return {} } + // return { + // ...response, + // inputSettings: restToGraphqlInputSettings(response.inputSettings as RESTInputSettings) + // } as Input return response as Input } @@ -59,6 +66,7 @@ export class InputsService { if (!response || response instanceof ApolloError) { return {} } + console.log('Post input response', response) return response as Input } @@ -78,11 +86,25 @@ export class InputsService { } async updateInput(auth: User, input: UpdateInputInput): Promise { - const request: ApiInputsInputIdPutRequest = { + // const request: ApiInputsInputIdPutRequest = { + // inputId: input.inputId, + // inputUpdateDto: { + // ...input.inputUpdateDto, + // inputSettings: graphqlToRestInputSettings(input.inputUpdateDto?.inputSettings as InputSettings) + // } as InputUpdateDto, + // } + let request: ApiInputsInputIdPutRequest = { inputId: input.inputId, - inputUpdateDto: input.inputUpdateDto as InputUpdateDto, + inputUpdateDto: input.inputUpdateDto as InputUpdateDto + } + if (input.inputUpdateDto) { + request = { + inputId: input.inputId, + inputUpdateDto: input.inputUpdateDto + } } + console.log('request Input update', request) const response = await this.inputsApiWithAuth(auth) .apiInputsInputIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update input')) diff --git a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts b/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts index a6dcd01c792a..6bc41d718526 100644 --- a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts +++ b/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts @@ -1,94 +1,124 @@ -import { LanguageType } from "../../models/global.model" -import { InputSettings, ListItem } from "../../models/inputSettings.model" +// import { LanguageType } from "../../models/global.model" +// import { InputSettings, ListItem } from "../../models/inputSettings.model" +import { InputUpdateDto } from "@island.is/clients/form-system" +import { Input } from "../../models/input.model"; -export interface RESTInputSettings { - isLarge?: boolean - size?: string - interval?: string - erHlekkur?: boolean - url?: string - hnapptexti?: LanguageType - tegundir?: string[] - hamarksstaerd?: number - erFjolval?: boolean - fjoldi?: number - header?: string - hamarkslengd?: number - lagmarkslengd?: number - laggildi?: number - hagildi?: number - listi?: ListItem[] - type?: string - name?: LanguageType - erListi?: boolean - erInnslattur?: boolean - [key: string]: unknown -} +// export interface RESTInputSettings { +// isLarge?: boolean +// size?: string +// interval?: string +// erHlekkur?: boolean +// url?: string +// hnapptexti?: LanguageType +// tegundir?: string[] +// hamarksstaerd?: number +// erFjolval?: boolean +// fjoldi?: number +// header?: string +// hamarkslengd?: number +// lagmarkslengd?: number +// laggildi?: number +// hagildi?: number +// listi?: ListItem[] +// $type?: string +// name?: LanguageType +// erListi?: boolean +// erInnslattur?: boolean +// [key: string]: unknown +// } -interface GraphQLInputSettings { - hasInput?: boolean - isList?: boolean - isLarge?: boolean - size?: string - interval?: string - list?: ListItem[] - max?: number - min?: number - maxLength?: number - minLength?: number - amount?: number - isMulti?: boolean - maxSize?: number - types?: string[] - buttonText?: LanguageType - hasLink?: boolean - type?: string - name?: LanguageType - [key: string]: unknown -} +// interface GraphQLInputSettings { +// hasInput?: boolean +// isList?: boolean +// isLarge?: boolean +// size?: string +// interval?: string +// list?: ListItem[] +// max?: number +// min?: number +// maxLength?: number +// minLength?: number +// amount?: number +// isMulti?: boolean +// maxSize?: number +// types?: string[] +// buttonText?: LanguageType +// hasLink?: boolean +// $type?: string +// name?: LanguageType +// [key: string]: unknown +// } -export function restToGraphqlInputSettings(input?: RESTInputSettings): GraphQLInputSettings { - return { - hasInput: input?.erInnslattur, - isList: input?.erListi, - isLarge: input?.isLarge, - size: input?.size, - interval: input?.interval, - list: input?.listi, - max: input?.hagildi, - min: input?.laggildi, - maxLength: input?.hamarkslengd, - minLength: input?.lagmarkslengd, - amount: input?.fjoldi, - isMulti: input?.erFjolval, - maxSize: input?.hamarksstaerd, - types: input?.tegundir, - buttonText: input?.hnapptexti, - hasLink: input?.erHlekkur, - type: input?.type, - name: input?.name, - } -} +// export const restToGraphqlInputSettings = (input?: RESTInputSettings): GraphQLInputSettings => { +// return { +// hasInput: input?.erInnslattur, +// isList: input?.erListi, +// isLarge: input?.isLarge, +// size: input?.size, +// interval: input?.interval, +// list: input?.listi, +// max: input?.hagildi, +// min: input?.laggildi, +// maxLength: input?.hamarkslengd, +// minLength: input?.lagmarkslengd, +// amount: input?.fjoldi, +// isMulti: input?.erFjolval, +// maxSize: input?.hamarksstaerd, +// types: input?.tegundir, +// buttonText: input?.hnapptexti, +// hasLink: input?.erHlekkur, +// type: input?.type, +// name: input?.name, +// } +// } -export function graphqlToRestInputSettings(input?: InputSettings): RESTInputSettings { - return { - erInnslattur: input?.hasInput, - erListi: input?.isList, - isLarge: input?.isLarge, - size: input?.size, - interval: input?.interval, - listi: input?.list, - hagildi: input?.max, - laggildi: input?.min, - hamarkslengd: input?.maxLength, - lagmarkslengd: input?.minLength, - fjoldi: input?.amount, - erFjolval: input?.isMulti, - hamarksstaerd: input?.maxSize, - tegundir: input?.types, - hnapptexti: input?.buttonText, - erHlekkur: input?.hasLink, - type: input?.type, - name: input?.name, - } -} +// export const graphqlToRestInputSettings = (input?: InputSettings): RESTInputSettings => { +// return { +// erInnslattur: input?.hasInput, +// erListi: input?.isList, +// isLarge: input?.isLarge, +// size: input?.size, +// interval: input?.interval, +// listi: input?.list, +// hagildi: input?.max, +// laggildi: input?.min, +// hamarkslengd: input?.maxLength, +// lagmarkslengd: input?.minLength, +// fjoldi: input?.amount, +// erFjolval: input?.isMulti, +// hamarksstaerd: input?.maxSize, +// tegundir: input?.types, +// hnapptexti: input?.buttonText, +// erHlekkur: input?.hasLink, +// type: input?.type, +// name: input?.name, +// } +// } + +// export const addType = (input: Input | InputUpdateDto) => { +// const types = ['TextaInnsláttur', 'Textalýsing', 'Fellilisti', 'Valhnappar', 'Skjal', 'Tölustafir', 'Fasteignanúmer', 'Klukkinnsláttur', 'Dagssetningarval'] +// const type = { +// TextaInnsláttur: 'texti', +// Textalýsing: 'textalysing', +// Fellilisti: 'fellilisti', +// Valhnappar: 'valhnappar', +// Skjal: 'skjal', +// Tölustafir: 'tolustafir', +// Fasteignanúmer: 'fasteignanumer', +// Klukkinnsláttur: 'klukkinnslattur', +// Dagssetningarval: 'dagssetningarval', +// } +// if (input.type !== null && input.type !== undefined) { +// if (types.includes(input.type)) { +// const newInputSettings = { +// ...input.inputSettings, +// $type: type[input.type as keyof typeof type] +// } +// return { +// ...input, +// inputSettings: newInputSettings, +// } +// } +// } +// return input +// } diff --git a/libs/api/domains/form-system/src/models/applicantType.model.ts b/libs/api/domains/form-system/src/models/applicantType.model.ts index 9e94e068804a..9e480c74bf84 100644 --- a/libs/api/domains/form-system/src/models/applicantType.model.ts +++ b/libs/api/domains/form-system/src/models/applicantType.model.ts @@ -19,6 +19,6 @@ export class ApplicantType { @Field(() => String, { nullable: true }) type?: string | null - @Field(() => ApplicantTypeNameSuggestion, { nullable: true }) - nameSuggestion?: ApplicantTypeNameSuggestion + @Field(() => [ApplicantTypeNameSuggestion], { nullable: 'itemsAndList' }) + nameSuggestions?: ApplicantTypeNameSuggestion[] | null } diff --git a/libs/api/domains/form-system/src/models/inputSettings.model.ts b/libs/api/domains/form-system/src/models/inputSettings.model.ts index 59d21b0bb9a1..174a5cb93049 100644 --- a/libs/api/domains/form-system/src/models/inputSettings.model.ts +++ b/libs/api/domains/form-system/src/models/inputSettings.model.ts @@ -40,7 +40,7 @@ export class InputSettings { hasLink?: boolean @Field(() => String, { nullable: true }) - url?: string + url?: string | null @Field(() => LanguageType, { nullable: true }) buttonText?: LanguageType diff --git a/libs/clients/form-system/project.json b/libs/clients/form-system/project.json index 0c091ae7ec4b..6d206e0f4078 100644 --- a/libs/clients/form-system/project.json +++ b/libs/clients/form-system/project.json @@ -43,7 +43,7 @@ "update-openapi-document": { "executor": "nx:run-commands", "options": { - "command": "curl https://profun.island.is/umsoknarkerfi/swagger/v1/swagger.json > libs/clients/form-system/src/clientConfig.json" + "command": "curl https://localhost:51345/swagger/v1/swagger.json > libs/clients/form-system/src/clientConfig.json" } } }, diff --git a/libs/clients/form-system/src/clientConfig.json b/libs/clients/form-system/src/clientConfig.json index 21815ad240fe..dcb5c1be4c8d 100644 --- a/libs/clients/form-system/src/clientConfig.json +++ b/libs/clients/form-system/src/clientConfig.json @@ -4,11 +4,6 @@ "title": "UmsóknarkerfiWebAPI", "version": "1.0" }, - "servers": [ - { - "url": "/umsoknarkerfi" - } - ], "paths": { "/api/Files": { "post": { @@ -1124,7 +1119,7 @@ "type": "string", "nullable": true }, - "listi": { + "list": { "type": "array", "items": { "$ref": "#/components/schemas/Listagildi" @@ -1409,21 +1404,21 @@ "stepsList": { "type": "array", "items": { - "$ref": "#/components/schemas/StepDto" + "$ref": "#/components/schemas/StepUpdateDto" }, "nullable": true }, "groupsList": { "type": "array", "items": { - "$ref": "#/components/schemas/GroupDto" + "$ref": "#/components/schemas/GroupUpdateDto" }, "nullable": true }, "inputsList": { "type": "array", "items": { - "$ref": "#/components/schemas/InputDto" + "$ref": "#/components/schemas/InputUpdateDto" }, "nullable": true } @@ -1508,6 +1503,10 @@ "multiSet": { "type": "integer", "format": "int32" + }, + "stepId": { + "type": "integer", + "format": "int32" } }, "additionalProperties": false @@ -1635,6 +1634,10 @@ }, "inputSettings": { "$ref": "#/components/schemas/BaseInputSettings" + }, + "groupId": { + "type": "integer", + "format": "int32" } }, "additionalProperties": false diff --git a/libs/clients/form-system/src/lib/FormSystemApiProvider.ts b/libs/clients/form-system/src/lib/FormSystemApiProvider.ts index e752526b0f64..3882e867fbb6 100644 --- a/libs/clients/form-system/src/lib/FormSystemApiProvider.ts +++ b/libs/clients/form-system/src/lib/FormSystemApiProvider.ts @@ -6,7 +6,14 @@ import { } from '@island.is/nest/config' import { FormSystemClientConfig } from './FormSystemClient.config' import { Configuration, FilesApi, FormsApi, GroupsApi, InputsApi, OrganizationsApi, ServicesApi, StepsApi } from '../../gen/fetch' +import * as https from 'https'; +import fetch, { RequestInfo, RequestInit } from 'node-fetch'; +const httpsAgent = new https.Agent({ // remove + rejectUnauthorized: false, // This will ignore SSL certificates +}); + +const fetchWithHttpsAgent = (url: RequestInfo, options: RequestInit | undefined) => fetch(url, { ...options, agent: httpsAgent }); //remove const provideApi = ( Api: new (configuration: Configuration) => T, @@ -22,6 +29,7 @@ const provideApi = ( name: 'form-system', organizationSlug: 'stafraent-island', logErrorResponseBody: true, + fetch: fetchWithHttpsAgent // remove }), basePath: config.basePath, headers: { diff --git a/libs/clients/form-system/src/lib/FormSystemClient.config.ts b/libs/clients/form-system/src/lib/FormSystemClient.config.ts index 19b9da808e20..6be8509b597a 100644 --- a/libs/clients/form-system/src/lib/FormSystemClient.config.ts +++ b/libs/clients/form-system/src/lib/FormSystemClient.config.ts @@ -10,7 +10,8 @@ export const FormSystemClientConfig = defineConfig({ schema, load(env) { return { - basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://profun.island.is/umsoknarkerfi'), + //basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://profun.island.is/umsoknarkerfi'), + basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://localhost:51345') } } }) diff --git a/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx index eb0930a10b0c..dc5e9a3c99fa 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx @@ -13,6 +13,8 @@ import { FormSystemGroup, FormSystemStep } from '@island.is/api/schema' import BaseSettings from './components/BaseSettings/BaseSettings' import Premises from './components/Premises/Premises' import InputContent from './components/InputContent/InputContent' +import PreviewStepOrGroup from './components/PreviewStepOrGroup/PreviewStepOrGroup' +import RelevantParties from './components/RelevantParties/RevelantParties' export default function MainContent() { const { control, controlDispatch, updateActiveItem, setFocus, focus } = useContext(ControlContext) @@ -29,77 +31,80 @@ export default function MainContent() { (activeItem.data as FormSystemStep).type === 'BaseSetting' ? () : activeItem.type === 'Step' && (activeItem.data as FormSystemStep).type === 'Forsendur' ? () - : - < Stack space={2}> - - - - controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'is', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - - - - controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'en', - newValue: e.target.value, - }, + : activeItem.type === 'Step' && (activeItem.data as FormSystemStep).type === 'Aðilar' ? + : openPreview ? ( + + ) : + < Stack space={2}> + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'en', + newValue: e.target.value, + }, - })} - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - {activeItem.type === 'Group' && ( - - - - // listsDispatch({ - // type: 'setMultiSet', - // payload: { - // checked: e.target.checked, - // }, - // }) - // } - /> - - - )} - - - - - - + })} + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + {activeItem.type === 'Group' && ( + + + + // listsDispatch({ + // type: 'setMultiSet', + // payload: { + // checked: e.target.checked, + // }, + // }) + // } + /> + + + )} + + + + + + } ) diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx index 73a4769de037..1bf4e1597bc6 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -11,7 +11,7 @@ import { useContext } from 'react' import ControlContext from '../../../../context/ControlContext' export const BaseSettings = () => { - const { control, controlDispatch, setFocus, focus, formSettingsUpdate } = useContext(ControlContext) + const { control, controlDispatch, setFocus, focus, formSettingsUpdate, formUpdate } = useContext(ControlContext) const { form } = control console.log('BaseSettings form', form) return ( @@ -25,7 +25,7 @@ export const BaseSettings = () => { value={form?.name?.is ?? ''} backgroundColor={'blue'} onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onBlur={(e) => e.target.value !== focus && formUpdate()} onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'is', newValue: e.target.value } })} /> @@ -37,7 +37,7 @@ export const BaseSettings = () => { value={form?.name?.en ?? ''} backgroundColor="blue" onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onBlur={(e) => e.target.value !== focus && formUpdate()} onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'en', newValue: e.target.value } })} /> @@ -56,7 +56,7 @@ export const BaseSettings = () => { backgroundColor="blue" type="number" onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && formSettingsUpdate()} + onBlur={(e) => e.target.value !== focus && formUpdate()} onChange={(e) => controlDispatch({ type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', payload: { value: parseInt(e.target.value) } })} /> @@ -75,7 +75,7 @@ export const BaseSettings = () => { handleChange={(e) => { controlDispatch({ type: 'CHANGE_INVALIDATION_DATE', payload: { value: e } }) }} - handleCloseCalendar={() => formSettingsUpdate()} + handleCloseCalendar={() => formUpdate()} /> @@ -85,8 +85,8 @@ export const BaseSettings = () => { label="Leyfa notanda að halda áfram í umsókninni með ógild/óútfyllt gildi" checked={form.stopProgressOnValidatingStep ?? false} onChange={(e) => { - console.log('stopProgressOnValidatingStep', e.target.checked) - formSettingsUpdate({ ...form, stopProgressOnValidatingStep: e.target.checked }) + controlDispatch({ type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', payload: { value: e.target.checked } }) + formUpdate({ ...form, stopProgressOnValidatingStep: e.target.checked }) }} /> diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx index 71bb0bea6e35..5e9a2ac87e6c 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx @@ -4,16 +4,22 @@ import { Stack } from "@island.is/island-ui/core" import BaseInput from "./components/BaseInput" import Preview from "../Preview/Preveiw" import { FormSystemInput } from "@island.is/api/schema" +import InputSettings from "./components/InputSettings/InputSettings" +import ListBuilder from "./components/ListBuilder/ListBuilder" const InputContent = () => { - const { control, selectStatus, setSelectStatus } = useContext(ControlContext) + const { control, selectStatus, setSelectStatus, inListBuilder } = useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput + + if (inListBuilder) { + return + } return ( - + ) diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx index e69de29bb2d1..f0b125c11ac1 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx @@ -0,0 +1,28 @@ +import { useContext } from "react" +import ControlContext from "../../../../../../context/ControlContext" +import { FormSystemInput } from "@island.is/api/schema" +import MessageWithLinkSettings from "./components/MessageWithLinkSettings" +import FileUploadSettings from "./components/FIleUploadSettings" +import TextInputSettings from "./components/TextInputSettings" +import ListSettings from "./components/ListSettings" + + +const InputSettings = () => { + const { control } = useContext(ControlContext) + const currentItem = control.activeItem.data as FormSystemInput + return ( + <> + {currentItem.type === 'Textalýsing' && ( + + )} + {currentItem.type === 'Skjal' && ( + + )} + {currentItem.type === 'Textalínubox' || currentItem.type === 'TextaInnsláttur' && } + {currentItem.type === 'Fellilisti' && } + {currentItem.type === 'Valhnappar' && } + + ) +} + +export default InputSettings diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx new file mode 100644 index 000000000000..b1b8bdeca672 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx @@ -0,0 +1,179 @@ +import { + GridRow as Row, + GridColumn as Column, + Checkbox, + Stack, + Box, + Select, + Text, + Option, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import { fileTypes } from '../../../../../../../utils/fileTypes' +import ControlContext from '../../../../../../../context/ControlContext' +import { FormSystemInput } from '@island.is/api/schema' + +const fileSizes = { + "fileSizes": [ + { + "label": "1 mb", + "value": 1048576 + }, + { + "label": "2 mb", + "value": 2097152 + }, + { + "label": "3 mb", + "value": 3145728 + }, + { + "label": "4 mb", + "value": 4194304 + }, + { + "label": "5 mb", + "value": 5242880 + }, + { + "label": "6 mb", + "value": 6291456 + }, + { + "label": "7 mb", + "value": 7340032 + }, + { + "label": "8 mb", + "value": 8388608 + }, + { + "label": "9 mb", + "value": 9437184 + }, + { + "label": "10 mb", + "value": 10485760 + } + ] +} + +const FileUploadSettings = () => { + const { control, controlDispatch, updateActiveItem } = useContext(ControlContext) + const { activeItem } = control + const currentItem = activeItem.data as FormSystemInput + const { inputSettings } = currentItem + + const fileSizeOptions = fileSizes.fileSizes.map((size) => ({ + label: size.label, + value: size.value, + })) + + const fileAmountOptions: Option[] = [ + { label: '1', value: 1 }, + { label: '2', value: 2 }, + { label: '3', value: 3 }, + { label: '4', value: 4 }, + { label: '5', value: 5 }, + { label: '6', value: 6 }, + { label: '7', value: 7 }, + { label: '8', value: 8 }, + { label: '9', value: 9 }, + { label: '10', value: 10 }, + ] + + return ( + + + + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'isMulti', + checked: e.target.checked, + update: updateActiveItem + } + })} + /> + + + + + f.value === inputSettings.amount, + )} + options={fileAmountOptions} + onChange={(e) => controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'amount', + value: e?.value, + update: updateActiveItem + } + })} + /> + + )} + + + + Leyfa eftirfarandi skjalatýpur + + + + {Object.entries(fileTypes).map(([key, value], i) => ( + + {key !== 'default' && ( + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'types', + checked: e.target.checked, + value: key, + update: updateActiveItem + } + })} + /> + )} + + ))} + + + ) +} + +export default FileUploadSettings diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx new file mode 100644 index 000000000000..c713a00ed796 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx @@ -0,0 +1,100 @@ +import { useContext, useState } from "react" +import ControlContext from "../../../../../../../context/ControlContext" +import { + GridColumn as Column, + GridRow as Row, + Select, + Stack, + Box, + Button, + RadioButton, + Option, +} from '@island.is/island-ui/core' +import { FormSystemInput } from "@island.is/api/schema" + +const predeterminedLists = [ + { + label: 'Sveitarfélög', + value: 'Sveitarfelog', + }, + { + label: 'Lönd', + value: 'Lond', + }, + { + label: 'Póstnúmer', + value: 'Postnumer', + }, + { + label: 'Iðngreinarmeistara', + value: 'Idngreinarmeistara', + }, +] + +// Need to fix the radio buttons +const ListSettings = () => { + const { control, controlDispatch, setInListBuilder } = useContext(ControlContext) + const { activeItem } = control + const currentItem = activeItem.data as FormSystemInput + const [radio, setRadio] = useState([true, false, false]) + + const radioHandler = (index: number) => { + if (!radio[index]) + setRadio((prev) => + prev.map((_, i) => { + return index === i + }), + ) + } + + return ( + + {currentItem.type === 'Fellilisti' && ( + <> + + + radioHandler(0)}> + { console.log() }} checked={radio[0]} /> + + + + + + { console.log() }} checked={radio[1]} /> + + + + )} + {radio[0] && ( + + )} + {radio[1] && ( + + { }} + /> + + + { }} + /> + + + + ) + } + + return ( + + + + { + setSelectStatus( + e + ? NavbarSelectStatus.LIST_ITEM + : NavbarSelectStatus.ON_WITHOUT_SELECT + ) + setConnecting((prev) => + prev.map((_, i) => (i === index ? e : false)) + ) + controlDispatch({ type: 'SET_ACTIVE_LIST_ITEM', payload: { listItem: e ? listItem : null } }) + }} + /> + + controlDispatch({ + type: 'SET_LIST_ITEM_SELECTED', + payload: { + guid: listItem.guid ?? '', + update: updateActiveItem, + } + }) + } + /> + + + + controlDispatch({ + type: 'REMOVE_LIST_ITEM', + payload: { + guid: listItem.guid ?? '', + update: updateActiveItem, + }, + }) + } + > + + + + + + + + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_LIST_ITEM', + payload: { + property: 'label', + lang: 'is', + value: e.target.value, + guid: listItem.guid ?? '', + update: updateActiveItem, + }, + }) + } + /> + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_LIST_ITEM', + payload: { + property: 'label', + lang: 'en', + value: e.target.value, + guid: listItem.guid ?? '', + update: updateActiveItem, + }, + }) + } + /> + + + + {isRadio && ( + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_LIST_ITEM', + payload: { + property: 'description', + lang: 'is', + value: e.target.value, + guid: listItem.guid ?? '', + update: updateActiveItem, + }, + }) + } + /> + + + setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_LIST_ITEM', + payload: { + property: 'description', + lang: 'en', + value: e.target.value, + guid: listItem.guid ?? '', + update: updateActiveItem, + }, + }) + } + /> + + + )} + + ) +} + + +export default ListItem diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx index 907bf7291d67..48be875ba766 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx @@ -5,7 +5,7 @@ import { FormSystemDocumentType } from '@island.is/api/schema' const Premises = () => { - const { control, documentTypes, formSettingsUpdate } = useContext(ControlContext) + const { control, documentTypes, updateSettings } = useContext(ControlContext) const [formDocumentTypes, setFormDocumentTypes] = useState(control.form?.documentTypes?.filter((d): d is FormSystemDocumentType => d !== null) ?? []) const handleCheckboxChange = (documentTypeId: number) => { @@ -19,7 +19,7 @@ const Premises = () => { documentTypes?.find((d) => d?.id === documentTypeId), ].filter((d) => d !== undefined) as FormSystemDocumentType[]) setFormDocumentTypes(newDocumentTypes) - formSettingsUpdate({ ...control.form, documentTypes: newDocumentTypes }) + updateSettings({ ...control.form, documentTypes: newDocumentTypes }) } return ( diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx index 50668f66827e..3e350876914a 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx @@ -1,20 +1,50 @@ import { FormSystemInput } from "@island.is/api/schema" -import { Box } from "@island.is/island-ui/core" +import { Box, DatePicker, Text } from "@island.is/island-ui/core" import MessageWithLink from "./components/MessageWithLink" +import Banknumber from "./components/Banknumber" +import Email from "./components/Email" +import NationalId from "./components/NationalId" +import FileUpload from "./components/FileUpload" +import TextInput from "./components/TextInput" +import List from "./components/List" +import Radio from "./components/Radio" +import Currency from "./components/Currency" interface Props { data: FormSystemInput } const Preview = ({ data }: Props) => { + const { type } = data return ( - {data.type === 'Textalýsing' && ( + {type === 'Textalýsing' && ( )} + {type === 'Bankareikningur' && ( + + {data?.name?.is} + + + )} + {type === 'Netfang' && } + {type === 'Dagssetningarval' && ( + + + + )} + {type === 'Kennitala' && } + {type === 'Skjal' && } + {type === 'Textalínubox' || type === 'TextaInnsláttur' && } + {type === 'Fellilisti' && } + {type === 'Valhnappar' && } + {type === 'Krónutölubox' && } ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx new file mode 100644 index 000000000000..c54284c02d3a --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx @@ -0,0 +1,113 @@ +import { + GridRow as Row, + GridColumn as Column, + Input, + Box, +} from '@island.is/island-ui/core' +import { useRef, useState } from 'react' + +const Banknumber = () => { + const [banki, setBanki] = useState('') + const [hb, setHb] = useState('') + const [reikningur, setReikningur] = useState('') + const inputRefs = [ + useRef(), + useRef(), + useRef(), + ] + + const handleChange = (index: number, value: string) => { + if (index === 0) { + setBanki(value) + if (value.length === 4) { + if (inputRefs[1]?.current) { + inputRefs[1]?.current.focus() + } + } + } else if (index === 1) { + setHb(value) + if (value.length === 2) { + if (inputRefs[2]?.current) { + inputRefs[2]?.current.focus() + } + } + } else if (index === 2) { + if (value.length <= 6) { + setReikningur(value) + } + if (value.length === 6) { + if (inputRefs[2]?.current) { + inputRefs[2]?.current.blur() + } + } + } + } + + const addLeadingZeros = (originalNumber: string, max: number) => { + const zerosToAdd = max - originalNumber.length + if (zerosToAdd <= 0) { + return originalNumber + } + if (originalNumber.length === 0) { + return originalNumber + } + const leadingZeros = '0'.repeat(zerosToAdd) + return leadingZeros + originalNumber + } + + return ( + + + + + } + label="Banki" + type="number" + value={banki} + maxLength={4} + name="" + onChange={(e) => handleChange(0, e.target.value)} + onBlur={(e) => setBanki(addLeadingZeros(e.target.value, 4))} + /> + + + + } + label="Hb" + maxLength={2} + type="number" + value={hb} + name="" + onChange={(e) => handleChange(1, e.target.value)} + onBlur={(e) => setHb(addLeadingZeros(e.target.value, 2))} + /> + + + + } + label="Reikningsnúmer" + type="number" + value={reikningur} + name="" + onChange={(e) => handleChange(2, e.target.value)} + onBlur={(e) => setReikningur(addLeadingZeros(e.target.value, 6))} + /> + + + + ) +} + +export default Banknumber diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx new file mode 100644 index 000000000000..759c8b483d66 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx @@ -0,0 +1,38 @@ + +import { + GridRow as Row, + GridColumn as Column, + Input, +} from '@island.is/island-ui/core' +import { ChangeEvent, useContext, useState } from 'react' +import ControlContext from '../../../../../context/ControlContext' + +const Currency = () => { + const [currency, setCurrency] = useState('') + const { control } = useContext(ControlContext) + const label = control.activeItem?.data?.name?.is + const handleCurrencyChange = ( + e: ChangeEvent, + ) => { + // Remove any non-digit characters from the input value + const inputValue = e.target.value.replace(/\D/g, '') + + // Split the input value into groups of three characters + const formattedValue = inputValue.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + setCurrency(formattedValue) + } + return ( + + + + + + ) +} + +export default Currency diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx new file mode 100644 index 000000000000..8d52b21dca8c --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx @@ -0,0 +1,33 @@ +import { useContext, useState } from 'react' +import { Input, Stack, Text } from '@island.is/island-ui/core' +import ControlContext from '../../../../../context/ControlContext' + + +export const Email = () => { + const { control } = useContext(ControlContext) + const { activeItem } = control + const [email, setEmail] = useState('') + const [hasError, setHasError] = useState(false) + const isValidEmail = (): boolean => { + const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ + const res = pattern.test(email) + return !res + } + return ( + + {activeItem?.data?.name?.is} + setEmail(e.target.value)} + onBlur={() => setHasError(isValidEmail())} + errorMessage="Ekki gilt netfang" + hasError={hasError} + /> + + ) +} + +export default Email diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx new file mode 100644 index 000000000000..3d4a32d532cc --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx @@ -0,0 +1,69 @@ +import { + InputFileUpload, + UploadFile, + fileToObject, +} from '@island.is/island-ui/core' +import { useState } from 'react' +import { uuid } from 'uuidv4' +import { FormSystemInput } from '@island.is/api/schema' +import { fileTypes } from '../../../../../utils/fileTypes' + +type Props = { + currentItem: FormSystemInput +} + +const FileUpload = ({ currentItem }: Props) => { + const [error, setError] = useState(undefined) + const [fileList, setFileList] = useState>([]) + + + const onChange = (files: File[]) => { + const uploadFiles = files.map((file) => fileToObject(file)) + const uploadFilesWithKey = uploadFiles.map((f) => ({ + ...f, + key: uuid(), + })) + + // Check whether upload will exceed limit and if so, prevent it + const currentAmount = currentItem?.inputSettings?.amount ?? 0 + if (fileList.length + uploadFilesWithKey.length > currentAmount) { + setError(`Hámarksfjöldi skjala er ${currentItem.inputSettings?.amount}`) + return + } + setError('') + const newFileList = [...fileList, ...uploadFilesWithKey] + setFileList(newFileList) + } + + const onRemove = (fileToRemove: UploadFile) => { + const newFileList = fileList.filter((file) => file.key !== fileToRemove.key) + setFileList(newFileList) + } + + return ( + <> + `${f} `, + )}`} + buttonLabel="Veldu skjöl til að hlaða upp" + onChange={onChange} + onRemove={onRemove} + errorMessage={fileList.length > 0 ? error : undefined} + accept={ + currentItem?.inputSettings?.types?.map( + (t) => fileTypes[t as keyof typeof fileTypes], + ) ?? [] + } + showFileSize + maxSize={currentItem?.inputSettings?.maxSize ?? 1} + multiple={currentItem?.inputSettings?.isMulti ?? false} + /> + + ) +} + +export default FileUpload diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx new file mode 100644 index 000000000000..0c09856669f5 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx @@ -0,0 +1,34 @@ +import { FormSystemInput, FormSystemListItem } from "@island.is/api/schema" +import { useEffect, useState } from "react" +import { Select } from '@island.is/island-ui/core' + +interface Props { + currentItem: FormSystemInput +} + +type ListItem = { + label: string + value: string | number +} + +const List = ({ currentItem }: Props) => { + const [listItems, setListItems] = useState([]) + + useEffect(() => { + const currentList = currentItem.inputSettings?.list ?? [] + setListItems( + currentList.map((l) => ({ + label: l?.label?.is ?? '', + value: l?.label?.is ?? '', + })), + ) + }, [currentItem.inputSettings?.list]) + + return ( + <> + + + + + + + + ) +} +export default NationalId diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx new file mode 100644 index 000000000000..98ec59caa935 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx @@ -0,0 +1,59 @@ +import { FormSystemInput, FormSystemListItem } from "@island.is/api/schema" +import { RadioButton, Text, Box } from '@island.is/island-ui/core' +import { useEffect, useState } from "react" + +interface Props { + currentItem: FormSystemInput +} + +const Radio = ({ currentItem }: Props) => { + const radioButtons = currentItem.inputSettings?.list + const [radioChecked, setRadioChecked] = useState([]) + + useEffect(() => { + setRadioChecked(radioButtons?.map(() => false) ?? []) + }, [radioButtons]) + + const radioButton = (rb: FormSystemListItem, index: number) => ( + + setRadioChecked((prev) => + prev.map((rb, i) => (i === index ? true : false)), + ) + } + > + + + ) + + return ( + <> + + {currentItem?.name?.is} + + + {radioButtons?.map((rb, index) => radioButton(rb, index))} + + + ) +} + +export default Radio diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx new file mode 100644 index 000000000000..e0ecbf451678 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx @@ -0,0 +1,20 @@ +import { FormSystemInput } from "@island.is/api/schema" +import { Input } from "@island.is/island-ui/core" + +interface Props { + data: FormSystemInput +} + +const TextInput = ({ data }: Props) => { + const { inputSettings } = data + + return ( + + ) +} + +export default TextInput diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx new file mode 100644 index 000000000000..48d00f321957 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx @@ -0,0 +1,91 @@ +import { Dispatch, SetStateAction, useContext, useEffect } from "react" +import { Box, Button, Text } from '@island.is/island-ui/core' +import ControlContext from "../../../../context/ControlContext" +import { FormSystemGroup, FormSystemInput } from "@island.is/api/schema" +import { NavbarSelectStatus } from "../../../../lib/utils/interfaces" +import Preview from "../Preview/Preveiw" +import MultiSet from "./components/MultiSet" + +interface Props { + setOpenPreview: Dispatch> +} + +const PreviewStepOrGroup = ({ setOpenPreview }: Props) => { + const { control, setSelectStatus } = useContext(ControlContext) + const { activeItem, form } = control + const { groupsList: groups, inputsList: inputs } = form + const { type } = activeItem + + useEffect(() => { + setSelectStatus(NavbarSelectStatus.ON_WITHOUT_SELECT) + }, []) + return ( + + {type === 'Step' && ( + <> + + {activeItem?.data?.name?.is} + + {groups + ?.filter((g) => g?.stepGuid === activeItem?.data?.guid) + .map((g) => ( + + + {g?.name?.is} + + {g?.multiSet !== 0 ? ( + + ) : ( + inputs + ?.filter((i) => i?.groupGuid === g?.guid) + .map((i) => ( + + )) + )} + + ))} + + )} + {type === 'Group' && ( + + + {activeItem?.data?.name?.is} + + {(activeItem.data as FormSystemGroup).multiSet !== 0 ? ( + + ) : ( + inputs + ?.filter((i) => i?.groupGuid === activeItem?.data?.guid) + .map((i) => ( + + )) + )} + + )} + + + + + ) +} + +export default PreviewStepOrGroup diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx new file mode 100644 index 000000000000..c92d6f466e23 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx @@ -0,0 +1,59 @@ +import { useContext, useState } from 'react' +import { Box, Icon } from '@island.is/island-ui/core' +import { FormSystemGroup, FormSystemInput } from '@island.is/api/schema' +import ControlContext from '../../../../../context/ControlContext' +import Preview from '../../Preview/Preveiw' + +interface Props { + group: FormSystemGroup +} +const MultiSet = ({ group }: Props) => { + const { control } = useContext(ControlContext) + const { inputsList: inputs } = control.form + const originalInput = inputs?.filter((i) => i?.groupGuid === group.guid) + const [multiInput, setMultiInput] = useState([ + (inputs?.filter((i) => i?.groupGuid === group.guid) || []) as FormSystemInput[], + ]) + const add = () => { + if (originalInput) { + setMultiInput((prev) => [...prev, originalInput as FormSystemInput[]]) + } + } + return ( + + {multiInput.map((inputArray, index) => ( +
+ {inputArray.map((i) => ( + + ))} +
+ ))} + + + + + +
+ ) +} + +export default MultiSet diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx new file mode 100644 index 000000000000..3d475571972d --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx @@ -0,0 +1,291 @@ +import { useContext, useState } from "react" +import ControlContext from "../../../../context/ControlContext" +import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' +import { FormSystemApplicantType, FormSystemFormApplicantType, FormSystemLanguageType } from "@island.is/api/schema" +import { EFormApplicantTypes } from "../../../../lib/utils/interfaces" +import FormApplicantType from "./components/FormApplicantType" + +const applicantTypeLabel = [ + 'Einstaklingur (innskráður)', + 'Einstaklingur í umboði annars einstaklings', + 'Einstaklingur í umboði lögaðila', + 'Einstaklingur með prókúru', + 'Umboðsveitandi (einstaklingur)', + 'Lögaðili', +] + +const applicantTypes = [ + 'Einstaklingur', + 'Einstaklingur_með_umboð_annars_einstaklings', + 'Einstaklingur_með_umboð_lögaðila', + 'Einstaklingur_með_prókúru', + 'Einstaklingur_umboðsveitandi', + 'Lögaðili', +] + + +export const RelevantParties = () => { + const { applicantTypes: applicantTypeTemplates, control, updateSettings } = useContext(ControlContext) + const { form } = control + const { id: formId } = form + const [formApplicantTypes, setFormApplicantTypes] = useState( + (form.formApplicantTypes ?? []).filter(Boolean) as FormSystemFormApplicantType[] + ) + const [focus, setOnFocus] = useState('') + + const createFormApplicantType = ( + type: string, + template: FormSystemApplicantType + ): FormSystemFormApplicantType => { + return { + __typename: undefined, + type, + name: template?.nameSuggestions?.[0]?.nameSuggestion ?? { + __typename: undefined, + is: '', + en: '' + }, + applicantTypeId: template.id, + formId, + } + } + + const isOther = (applicant: FormSystemFormApplicantType) => { + const template = applicantTypeTemplates?.find( + (at) => at?.id === applicant.applicantTypeId, + ) + if (!template) { + return true + } + if ( + template?.nameSuggestions?.some( + (ns) => ns?.nameSuggestion?.is === applicant?.name?.is, + ) + ) { + return false + } + return true + } + + const handleSelect = (e: { label: string; value: string }, index: number) => { + const newApplicantTypes = formApplicantTypes.map((f, i) => { + if (i === index) { + return { + ...f, + name: { + __typename: undefined, + is: e.label, + en: e.value, + }, + } + } + return f + }) + updateSettings({ ...form, formApplicantTypes: newApplicantTypes }) + setFormApplicantTypes(newApplicantTypes) + } + + const onFocus = (value: string) => { + setOnFocus(value) + } + + const blur = (value: string) => { + if (focus !== value) { + updateSettings({ ...form, formApplicantTypes: formApplicantTypes }) + } + setOnFocus('') + } + + const handleCheckboxChange = (checked: boolean, index: number) => { + const updateFormApplicantTypes = ( + newFormApplicantTypes: FormSystemFormApplicantType[], + ) => { + const hasLegalEntity = formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.logadili, + ) + const newTypes = hasLegalEntity + ? newFormApplicantTypes.filter( + (f) => f.type !== EFormApplicantTypes.logadili, + ) + : newFormApplicantTypes + const newList = [...formApplicantTypes, ...newTypes] + updateSettings({ ...form, formApplicantTypes: newList }) + setFormApplicantTypes([...formApplicantTypes, ...newTypes]) + } + + const removeFormApplicantTypes = (types: EFormApplicantTypes[]) => { + const newList = formApplicantTypes.filter((f) => !types.includes(f.type as EFormApplicantTypes)) + updateSettings({ ...form, formApplicantTypes: newList }) + setFormApplicantTypes(newList) + } + + if (checked) { + if (index === 0) { + const template = applicantTypeTemplates?.find( + (at) => at?.type === applicantTypes[index], + ) + if (template !== undefined && template !== null) { + const newFormApplicantType: FormSystemFormApplicantType = + createFormApplicantType(EFormApplicantTypes.einstaklingur, template) + updateSettings({ ...form, formApplicantTypes: [...formApplicantTypes, newFormApplicantType] }) + setFormApplicantTypes([...formApplicantTypes, newFormApplicantType]) + } + } else if (index === 1) { + const delegatorTemplate = applicantTypeTemplates?.find( + (at) => at?.id === 2, + ) + const delegateeTemplate = applicantTypeTemplates?.find( + (at) => at?.id === 5, + ) + if ( + delegatorTemplate === undefined || delegatorTemplate === null || + delegateeTemplate === undefined || delegateeTemplate === null + ) { + return + } + const newFormApplicantTypes: FormSystemFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, + delegatorTemplate, + ), + createFormApplicantType( + EFormApplicantTypes.einstaklingurUmbodsveitandi, + delegateeTemplate, + ), + ] + setFormApplicantTypes([...formApplicantTypes, ...newFormApplicantTypes]) + } else if (index === 2) { + const delegatorTemplate = applicantTypeTemplates?.find( + (at) => at?.id === 6, + ) + const delegateeTemplate = applicantTypeTemplates?.find( + (at) => at?.id === 3, + ) + if ( + delegatorTemplate === undefined || delegatorTemplate === null || + delegateeTemplate === undefined || delegateeTemplate === null + ) { + return + } + const newFormApplicantTypes: FormSystemFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + delegateeTemplate, + ), + createFormApplicantType( + EFormApplicantTypes.logadili, + delegatorTemplate, + ), + ] + updateFormApplicantTypes(newFormApplicantTypes) + } else if (index === 3) { + const procurationHolder = applicantTypeTemplates?.find( + (at) => at?.id === 4, + ) + const legalEntity = applicantTypeTemplates?.find((at) => at?.id === 6) + if (procurationHolder === undefined || procurationHolder === null || legalEntity === undefined || legalEntity === null) { + return + } + + const newFormApplicantTypes: FormSystemFormApplicantType[] = [ + createFormApplicantType( + EFormApplicantTypes.einstaklingurMedProkuru, + procurationHolder, + ), + createFormApplicantType(EFormApplicantTypes.logadili, legalEntity), + ] + updateFormApplicantTypes(newFormApplicantTypes) + } + } else { + if (index === 0) { + removeFormApplicantTypes([EFormApplicantTypes.einstaklingur]) + } else if (index === 1) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, + EFormApplicantTypes.einstaklingurUmbodsveitandi, + ]) + } else if (index === 2) { + if ( + formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.einstaklingurMedProkuru, + ) + ) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + ]) + } else { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedUmbodLogadila, + EFormApplicantTypes.logadili, + ]) + } + } else if (index === 3) { + if ( + formApplicantTypes.some( + (f) => f.type === EFormApplicantTypes.einstaklingurMedUmbodLogadila, + ) + ) { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedProkuru, + ]) + } else { + removeFormApplicantTypes([ + EFormApplicantTypes.einstaklingurMedProkuru, + EFormApplicantTypes.logadili, + ]) + } + } + } + } + + return ( + + + + Veldu þá einstaklinga sem mega opna þessa umsókn + + + + + {applicantTypeLabel.slice(0, 4).map((label, index) => ( + f.type === applicantTypes?.[index], + )} + onChange={(e) => handleCheckboxChange(e.target.checked, index)} + /> + ))} + + + {formApplicantTypes.length > 0 && ( + + Skilgreindu hlutaðeigandi aðila + + )} + {formApplicantTypes.map((f, i) => ( + at?.id === f.applicantTypeId) + ?.nameSuggestions?.map((ns) => ns?.nameSuggestion) ?? []) as FormSystemLanguageType[] + } + formApplicantType={f} + index={i} + handleSelect={handleSelect} + blur={blur} + setOnFocus={onFocus} + setFormApplicantTypes={setFormApplicantTypes} + isOther={isOther(f)} + /> + ))} + + ) +} + +export default RelevantParties + diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx new file mode 100644 index 000000000000..d6615e51b531 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx @@ -0,0 +1,144 @@ +import React, { useState } from 'react' +import { + Box, + GridColumn as Column, + GridRow as Row, + Input, + Select, + Stack, + Text, +} from '@island.is/island-ui/core' +import { FormSystemFormApplicantType, FormSystemLanguageType } from '@island.is/api/schema' + +interface Props { + title: string + nameSuggestions?: FormSystemLanguageType[] + name: FormSystemLanguageType + formApplicantType: FormSystemFormApplicantType + handleSelect( + e: { + label: string + value: string + }, + index: number, + ): void + index: number + blur(value: string): void + setOnFocus(value: string): void + setFormApplicantTypes: React.Dispatch< + React.SetStateAction + > + isOther: boolean +} + +const FormApplicantType = ({ + title, + name, + nameSuggestions, + handleSelect, + index, + blur, + setOnFocus, + setFormApplicantTypes, + isOther, +}: Props) => { + const [inputEnabled, setInputEnabled] = useState(false) + const other = { label: 'Annað', value: 'Annað' } + + const getOptions = () => { + const options = nameSuggestions?.map((suggestion) => { + return { + label: suggestion?.is ?? '', + value: suggestion?.en ?? '', + } + }) || [] + options.push(other); + return options + } + + const handleSelectChange = (e: { label: string; value: string }) => { + if (e.label === 'Annað') { + setInputEnabled(true) + } else { + setInputEnabled(false) + handleSelect(e, index) + } + } + + const handleInputChange = ( + e: React.ChangeEvent, + language: 'is' | 'en', + ) => { + setFormApplicantTypes((prev: FormSystemFormApplicantType[]) => { + const newApplicantTypes = prev.map((f: FormSystemFormApplicantType, i: number) => { + if (i === index) { + return { + ...f, + name: { + ...f.name, + [language]: e.target.value, + }, + } + } + return f + }) + return newApplicantTypes + }) + } + + return ( + + + + + + {title} + + + + + + setOnFocus(e.target.value)} + onBlur={(e) => blur(e.target.value)} + onChange={(e) => handleInputChange(e, 'is')} + /> + + + setOnFocus(e.target.value)} + onBlur={(e) => blur(e.target.value)} + onChange={(e) => handleInputChange(e, 'en')} + /> + + + + + ) +} + +export default FormApplicantType diff --git a/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx index dbae94dcdc2a..87186ffc21b3 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx @@ -22,8 +22,8 @@ import ControlContext, { IControlContext } from '../../context/ControlContext' import { useFormSystemCreateStepMutation } from '../../gql/Step.generated' import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' import { ItemType } from '../../lib/utils/interfaces' +import { removeTypename } from '../../lib/utils/removeTypename' -type ActionType = 'removeStep' | 'removeGroup' | 'removeInput' type DndAction = | 'STEP_OVER_STEP' @@ -38,7 +38,8 @@ export default function Navbar() { controlDispatch, setInSettings, inSettings, - updateDnD + updateDnD, + formUpdate } = useContext(ControlContext) as IControlContext const { activeItem, form } = control @@ -54,26 +55,24 @@ export default function Navbar() { }, }), ) - const [createStep, { data, loading, error }] = useFormSystemCreateStepMutation({ - variables: { - input: { - stepCreationDto: { - formId: form?.id as number, - displayOrder: steps?.length + const [createStep, { data, loading, error }] = useFormSystemCreateStepMutation() + + const addStep = async () => { + const newStep = await createStep({ + variables: { + input: { + stepCreationDto: { + formId: form?.id as number, + displayOrder: steps?.length + } } } - } - }) - - const [updateForm, { data: formData, loading: formLoading, error: formError }] = useFormSystemUpdateFormMutation() - - const addStep = () => { - createStep() - if (!loading && !error && data) { + }) + if (newStep) { controlDispatch({ type: 'ADD_STEP', payload: { - step: data?.formSystemCreateStep as FormSystemStep + step: removeTypename(newStep.data?.formSystemCreateStep) as FormSystemStep } }) } @@ -129,17 +128,12 @@ export default function Navbar() { if (activeId === overId) return - const getType = ( - data: DataRef<{ [x: string]: unknown }>, - targetType: ItemType, - ) => data?.current?.type === targetType - - const activeStep = getType(active.data, 'Step') - const activeGroup = getType(active.data, 'Group') - const activeInput = getType(active.data, 'Input') - const overStep = getType(over.data, 'Step') - const overGroup = getType(over.data, 'Group') - const overInput = getType(over.data, 'Input') + const activeStep = active.data?.current?.type === 'Step' + const activeGroup = active.data?.current?.type === 'Group' + const activeInput = active.data?.current?.type === 'Input' + const overStep = over.data?.current?.type === 'Step' + const overGroup = over.data?.current?.type === 'Group' + const overInput = over.data?.current?.type === 'Input' const dispatchDragAction = (type: DndAction) => controlDispatch({ type, payload: { activeId: activeId, overId: overId } }) @@ -171,7 +165,8 @@ export default function Navbar() { } const onDragEnd = () => { - updateDnD(activeItem.type) + // updateDnD(activeItem.type) + formUpdate() } if (inSettings) { @@ -317,6 +312,11 @@ export default function Navbar() { + Bæta við skrefi + + + ) } diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx index 10663bf5b418..0cdf8fcda401 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx @@ -5,10 +5,11 @@ import { FormSystemGroup, FormSystemInput } from '@island.is/api/schema' import { useFormSystemCreateGroupMutation, useFormSystemDeleteGroupMutation } from '../../../../../gql/Group.generated' import { useFormSystemCreateInputMutation, useFormSystemDeleteInputMutation } from '../../../../../gql/Input.generated' import { useFormSystemDeleteStepMutation } from '../../../../../gql/Step.generated' +import { removeTypename } from '../../../../../lib/utils/removeTypename' export default function NavButtons() { - const { control, controlDispatch, apolloClient } = useContext(ControlContext) + const { control, controlDispatch } = useContext(ControlContext) const { activeItem, form } = control const { groupsList: groups, inputsList: inputs } = form @@ -31,7 +32,7 @@ export default function NavButtons() { } }) if (newGroup) { - controlDispatch({ type: 'ADD_GROUP', payload: { group: newGroup.data?.formSystemCreateGroup as FormSystemGroup } }) + controlDispatch({ type: 'ADD_GROUP', payload: { group: removeTypename(newGroup.data?.formSystemCreateGroup) as FormSystemGroup } }) } } else if (activeItem.type === 'Group') { const newInput = await addInput({ @@ -45,7 +46,8 @@ export default function NavButtons() { } }) if (newInput) { - controlDispatch({ type: 'ADD_INPUT', payload: { input: newInput.data?.formSystemCreateInput as FormSystemInput } }) + console.log('newInput', newInput) + controlDispatch({ type: 'ADD_INPUT', payload: { input: removeTypename(newInput.data?.formSystemCreateInput) as FormSystemInput } }) } } } diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx index ab6e162945bc..409a2252b447 100644 --- a/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx @@ -1,65 +1,65 @@ -// import { useContext } from 'react' -// import { Box, Text } from '@island.is/island-ui/core' -// import SelectNavComponent from './components/SelectNavComponent' -// import FormBuilderContext from '../../context/FormBuilderContext' -// import { NavbarSelectStatus } from '../../types/interfaces' -// import ControlContext from '../../context/ControlContext' -// import { FormSystemStep } from '@island.is/api/schema' +import { useContext } from 'react' +import { Box, Text } from '@island.is/island-ui/core' +import SelectNavComponent from './components/SelectNavComponent' +import { NavbarSelectStatus } from '../../types/interfaces' +import ControlContext from '../../context/ControlContext' +import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' -// export default function NavbarSelect() { -// const { control } = useContext(ControlContext) -// const { activeItem, steps, groups, inputs } = control -// let selectable = false -// return ( -// -// -// Skref -// -// {steps -// ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) -// .filter((s) => s.type === 'Innsláttur') -// .map((s) => ( -// -// -// {groups -// .filter((g) => g.stepGuid === s.guid) -// .map((g) => ( -// -// -// {inputs -// .filter((i) => i.groupGuid === g.guid) -// .map((i) => { -// if (activeItem.data.guid === i.guid) { -// if ( -// selectStatus !== NavbarSelectStatus.ON_WITHOUT_SELECT -// ) { -// selectable = true -// } -// } -// return ( -// -// ) -// })} -// -// ))} -// -// ))} -// -// ) -// } +export default function NavbarSelect() { + const { control, selectStatus } = useContext(ControlContext) + const { activeItem, form } = control + const { stepsList: steps, groupsList: groups, inputsList: inputs } = form + let selectable = false + return ( + + + Skref + + {steps + ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) + .filter((s) => s.type === 'Innsláttur') + .map((s) => ( + + + {groups + ?.filter((g) => g?.stepGuid === s.guid) + .map((g) => ( + + + {inputs + ?.filter((i) => i?.groupGuid === g?.guid) + .map((i) => { + if (activeItem?.data?.guid === i?.guid) { + if ( + selectStatus !== NavbarSelectStatus.ON_WITHOUT_SELECT + ) { + selectable = true + } + } + return ( + + ) + })} + + ))} + + ))} + + ) +} diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx index 6076614ec4ba..06b75540195a 100644 --- a/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx @@ -1,146 +1,147 @@ -// import cn from 'classnames' -// import * as styles from './selectNavComponent.css' -// import { Box, Checkbox } from '@island.is/island-ui/core' -// import { useContext } from 'react' -// import { -// ItemType, -// NavbarSelectStatus, -// } from '../../../types/interfaces' -// import FormBuilderContext from '../../../context/FormBuilderContext' -// import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' +import cn from 'classnames' +import * as styles from './selectNavComponent.css' +import { Box, Checkbox } from '@island.is/island-ui/core' +import { useContext } from 'react' +import { + ItemType, + NavbarSelectStatus, +} from '../../../types/interfaces' +import FormBuilderContext from '../../../context/FormBuilderContext' +import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' +import ControlContext from '../../../context/ControlContext' -// type Props = { -// type: ItemType -// data: FormSystemStep | FormSystemGroup | FormSystemInput -// active: boolean -// selectable: boolean -// } +type Props = { + type: ItemType + data: FormSystemStep | FormSystemGroup | FormSystemInput + active: boolean + selectable: boolean +} -// export default function SelectNavComponent({ -// type, -// data, -// active, -// selectable, -// }: Props) { -// const { formBuilder, formDispatch, lists, selectStatus, activeListItem } = -// useContext(FormBuilderContext) -// const { activeItem } = lists -// const { form } = formBuilder -// const activeGuid = -// selectStatus === NavbarSelectStatus.LIST_ITEM -// ? activeListItem?.guid ?? '' -// : activeItem.data.guid -// const connected = -// form.dependencies[activeGuid]?.includes(data.guid as string) || -// !form.dependencies -// return ( -// -// {active ? ( -// -// -// {/* Index */} -// -// -// {truncateName(data.name.is)} -// -// -// ) : ( -// -// -// {/* {index} */} -// -// -// {truncateName(data.name.is)} -// -// {selectable && ( -// -// { -// formDispatch({ -// type: 'addRemoveConnection', -// payload: { -// active: activeGuid, -// item: data.guid, -// }, -// }) -// }} -// /> -// -// )} -// -// )} -// -// ) +export default function SelectNavComponent({ + type, + data, + active, + selectable, +}: Props) { + const { control, controlDispatch, selectStatus } = useContext(ControlContext) + const { activeItem, activeListItem, form } = control + const activeGuid = + selectStatus === NavbarSelectStatus.LIST_ITEM + ? activeListItem?.guid ?? '' + : activeItem?.data?.guid ?? '' + const connected = + form.dependencies[activeGuid]?.includes(data.guid as string) || + !form.dependencies -// function truncateText(text: string, maxLength: number) { -// return text.length > maxLength ? text.slice(0, maxLength) + '...' : text -// } + const truncateText = (text: string, maxLength: number) => { + return text.length > maxLength ? text.slice(0, maxLength) + '...' : text + } -// function truncateName(name: string) { -// let maxLength: number + const truncateName = (name: string) => { + let maxLength: number -// if (active) { -// switch (type) { -// case 'Step': -// maxLength = 23 -// break -// case 'Group': -// maxLength = 16 -// break -// case 'Input': -// maxLength = 12 -// break -// default: -// maxLength = 26 -// } -// } else { -// switch (type) { -// case 'Step': -// maxLength = 26 -// break -// case 'Group': -// maxLength = 19 -// break -// case 'Input': -// maxLength = 16 -// break -// default: -// maxLength = 26 -// } -// } + if (active) { + switch (type) { + case 'Step': + maxLength = 23 + break + case 'Group': + maxLength = 16 + break + case 'Input': + maxLength = 12 + break + default: + maxLength = 26 + } + } else { + switch (type) { + case 'Step': + maxLength = 26 + break + case 'Group': + maxLength = 19 + break + case 'Input': + maxLength = 16 + break + default: + maxLength = 26 + } + } -// return truncateText(name, maxLength) -// } -// } + return truncateText(name, maxLength) + } + return ( + + {active ? ( + + + {/* Index */} + + + {truncateName(data?.name?.is ?? '')} + + + ) : ( + + + {/* {index} */} + + + {truncateName(data?.name?.is ?? '')} + + {selectable && ( + + { + // formDispatch({ + // type: 'addRemoveConnection', + // payload: { + // active: activeGuid, + // item: data.guid, + // }, + // }) + // }} + /> + + )} + + )} + + ) + + +} diff --git a/libs/portals/admin/form-system/src/context/ControlContext.ts b/libs/portals/admin/form-system/src/context/ControlContext.ts index d9896f4f15f0..94eba4db0f17 100644 --- a/libs/portals/admin/form-system/src/context/ControlContext.ts +++ b/libs/portals/admin/form-system/src/context/ControlContext.ts @@ -1,14 +1,12 @@ import { Dispatch, createContext } from "react" import { ControlAction, ControlState } from "../hooks/controlReducer" -import { ApolloClient, NormalizedCacheObject } from "@apollo/client" import { Maybe } from "graphql/jsutils/Maybe" -import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemInput, FormSystemListType } from "@island.is/api/schema" +import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemInput, FormSystemListItem, FormSystemListType } from "@island.is/api/schema" import { ActiveItem, ItemType, NavbarSelectStatus } from "../lib/utils/interfaces" export interface IControlContext { control: ControlState controlDispatch: Dispatch - apolloClient: ApolloClient applicantTypes: Maybe[]> | undefined documentTypes: Maybe[]> | undefined inputTypes: Maybe[]> | undefined @@ -22,6 +20,10 @@ export interface IControlContext { formSettingsUpdate: (updatedForm?: FormSystemForm) => void selectStatus: NavbarSelectStatus setSelectStatus: Dispatch + formUpdate: (updatedForm?: FormSystemForm) => void + inListBuilder: boolean + setInListBuilder: Dispatch, + updateSettings: (updatedForm?: FormSystemForm) => void } const ControlContext = createContext({ @@ -29,7 +31,6 @@ const ControlContext = createContext({ controlDispatch: function (_value: unknown): void { throw new Error('Function not implemented.') }, - apolloClient: {} as ApolloClient, applicantTypes: [] as Maybe[]>, documentTypes: [] as Maybe[]>, inputTypes: [] as Maybe[]>, @@ -55,6 +56,16 @@ const ControlContext = createContext({ setSelectStatus: function (_value: NavbarSelectStatus): void { throw new Error('Function not implemented.') }, + formUpdate: function (_updatedForm?: FormSystemForm): void { + throw new Error('Function not implemented.') + }, + inListBuilder: false, + setInListBuilder: function (_value: boolean): void { + throw new Error('Function not implemented.') + }, + updateSettings: function (_updatedForm?: FormSystemForm): void { + throw new Error('Function not implemented.') + } }) export default ControlContext diff --git a/libs/portals/admin/form-system/src/gql/Form.graphql b/libs/portals/admin/form-system/src/gql/Form.graphql index 2f67ba80eb9e..d4dc5032d9bc 100644 --- a/libs/portals/admin/form-system/src/gql/Form.graphql +++ b/libs/portals/admin/form-system/src/gql/Form.graphql @@ -46,67 +46,6 @@ query formSystemGetForm( displayOrder guid id - inputs { - description { - is - en - } - displayOrder - groupGuid - groupId - guid - id - inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } - isHidden - isPartOfMultiSet - isRequired - name { - is - en - } - type - } isHidden multiSet name { @@ -192,7 +131,7 @@ query formSystemGetForm( is en } - nameSuggestion { + nameSuggestions { applicantTypeId nameSuggestion { is @@ -387,80 +326,6 @@ query formSystemGetForm( stepsList { callRuleset displayOrder - groups { - displayOrder - guid - id - inputs { - description { - is - en - } - displayOrder - groupGuid - groupId - guid - id - inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } - isHidden - isPartOfMultiSet - isRequired - name { - is - en - } - type - } - isHidden - multiSet - name { - is - en - } - stepGuid - stepId - } guid id isCompleted @@ -488,7 +353,7 @@ query formSystemGetForm( is en } - nameSuggestion { + nameSuggestions { applicantTypeId nameSuggestion { is @@ -762,7 +627,7 @@ mutation formSystemCreateForm( is en } - nameSuggestion { + nameSuggestions { applicantTypeId nameSuggestion { is @@ -1058,7 +923,7 @@ mutation formSystemCreateForm( is en } - nameSuggestion { + nameSuggestions { applicantTypeId nameSuggestion { is diff --git a/libs/portals/admin/form-system/src/gql/FormSettings.graphql b/libs/portals/admin/form-system/src/gql/FormSettings.graphql new file mode 100644 index 000000000000..9285db59a7ec --- /dev/null +++ b/libs/portals/admin/form-system/src/gql/FormSettings.graphql @@ -0,0 +1,5 @@ +mutation formSystemUpdateFormSettings( + $input: FormSystemUpdateFormSettingsInput! +) { + formSystemUpdateFormSettings(input: $input) +} diff --git a/libs/portals/admin/form-system/src/gql/Input.graphql b/libs/portals/admin/form-system/src/gql/Input.graphql index ea5b8a839529..224d71019472 100644 --- a/libs/portals/admin/form-system/src/gql/Input.graphql +++ b/libs/portals/admin/form-system/src/gql/Input.graphql @@ -75,3 +75,69 @@ mutation formSystemUpdateInput( ) { formSystemUpdateInput(input: $input) } + +query formSystemGetInput( + $input: FormSystemGetInputInput! +) { + formSystemGetInput(input: $input) { + id + name { + is + en + } + description { + is + en + } + isRequired + displayOrder + groupId + isHidden + type + guid + isPartOfMultiSet + groupGuid + inputSettings { + isLarge + size + interval + hasLink + url + buttonText { + is + en + } + types + maxSize + isMulti + amount + header + maxLength + minLength + min + max + list { + guid + label { + is + en + } + description { + is + en + } + displayOrder + isSelected + value + } + type + name { + is + en + } + isList + hasInput + } + inputFields + } +} diff --git a/libs/portals/admin/form-system/src/hooks/controlReducer.ts b/libs/portals/admin/form-system/src/hooks/controlReducer.ts index d94d3afecd61..61dfe3d3d49b 100644 --- a/libs/portals/admin/form-system/src/hooks/controlReducer.ts +++ b/libs/portals/admin/form-system/src/hooks/controlReducer.ts @@ -1,10 +1,13 @@ -import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemInputSettings, FormSystemStep } from "@island.is/api/schema" +import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemInputSettings, FormSystemListItem, FormSystemStep } from "@island.is/api/schema" import { ActiveItem } from "../types/interfaces" import { UniqueIdentifier } from "@dnd-kit/core" import { arrayMove } from "@dnd-kit/sortable" +import { removeTypename } from "../lib/utils/removeTypename" +import { uuid } from "uuidv4" type ActiveItemActions = | { type: 'SET_ACTIVE_ITEM', payload: { activeItem: ActiveItem } } + | { type: 'SET_ACTIVE_LIST_ITEM', payload: { listItem: FormSystemListItem | null } } type GroupActions = | { type: 'ADD_GROUP', payload: { group: FormSystemGroup } } @@ -28,6 +31,7 @@ type DndActions = | { type: 'GROUP_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } | { type: 'INPUT_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } | { type: 'INPUT_OVER_INPUT', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { type: 'LIST_ITEM_OVER_LIST_ITEM', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } type ChangeActions = | { type: 'CHANGE_NAME', payload: { lang: 'en' | 'is', newValue: string } } @@ -37,10 +41,21 @@ type ChangeActions = | { type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', payload: { value: boolean } } | { type: 'CHANGE_FORM_SETTINGS', payload: { newForm: FormSystemForm } } -export type ControlAction = ActiveItemActions | GroupActions | InputActions | StepActions | DndActions | ChangeActions +type InputSettingsActions = + | { type: 'SET_MESSAGE_WITH_LINK_SETTINGS', payload: { property: 'buttonText' | 'url' | 'hasLink', value?: string, checked?: boolean, lang?: 'is' | 'en', update?: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'SET_FILE_UPLOAD_SETTINGS', payload: { property: 'isMulti' | 'maxSize' | 'amount' | 'types', checked?: boolean, value?: string | number, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'SET_INPUT_SETTINGS', payload: { property: 'isLarge', value: boolean, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'SET_LIST_ITEM_SELECTED', payload: { guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'REMOVE_LIST_ITEM', payload: { guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'CHANGE_LIST_ITEM', payload: { property: 'label' | 'description', lang: 'is' | 'en', value: string, guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'ADD_LIST_ITEM' } + + +export type ControlAction = ActiveItemActions | GroupActions | InputActions | StepActions | DndActions | ChangeActions | InputSettingsActions export interface ControlState { activeItem: ActiveItem + activeListItem: FormSystemListItem | null form: FormSystemForm } @@ -49,11 +64,17 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont const { stepsList: steps, groupsList: groups, inputsList: inputs } = form switch (action.type) { case 'SET_ACTIVE_ITEM': + console.log('current active item', action.payload.activeItem) return { ...state, activeItem: action.payload.activeItem } - + case 'SET_ACTIVE_LIST_ITEM': { + return { + ...state, + activeListItem: action.payload.listItem + } + } // Steps case 'ADD_STEP': return { @@ -110,6 +131,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont // Inputs case 'ADD_INPUT': + console.log('adding input reducer', action.payload.input) return { ...state, activeItem: { @@ -144,11 +166,12 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont data: { ...activeItem.data, type: newValue, - inputSettings: inputSettings + inputSettings: removeTypename(inputSettings) } } update(newActive) return { + ...state, activeItem: newActive, form: { ...form, @@ -170,6 +193,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont } }; return { + ...state, activeItem: newActive, form: { ...form, @@ -189,6 +213,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont } action.payload.update(newActive) return { + ...state, activeItem: newActive, form: { ...form, @@ -220,6 +245,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont updatedList = inputs?.map(i => i?.guid === activeItem.data?.guid ? newActive.data : i); } return { + ...state, activeItem: newActive, form: { ...form, @@ -266,6 +292,228 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont form: action.payload.newForm } } + case 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP': { + return { + ...state, + form: { + ...form, + stopProgressOnValidatingStep: action.payload.value + } + } + } + // Input settings + case 'SET_MESSAGE_WITH_LINK_SETTINGS': { + const input = activeItem.data as FormSystemInput + const { property, lang: langg, value, checked, update } = action.payload + const lang = langg ?? 'is' + + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [property]: property === 'hasLink' ? checked : value, + ...(property === 'buttonText' + ? { + buttonText: { + ...input.inputSettings?.buttonText, + [lang]: value + } + } + : {}) + }, + } + if (property === 'hasLink' && update) { + update({ type: 'Input', data: newInput }) + } + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } + case 'SET_FILE_UPLOAD_SETTINGS': { + const input = activeItem.data as FormSystemInput + const { property, checked, value, update } = action.payload + + const updateFileTypesArray = (): string[] => { + const newFileTypes = input.inputSettings?.types ?? [] + if (checked) { + return [...newFileTypes, value as string] + } else { + return newFileTypes.filter((type) => type !== value) + } + } + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [property]: property === 'types' ? updateFileTypesArray() : property === 'isMulti' ? checked : value + } + } + console.log('property', property, 'value', value, 'checked', checked) + console.log('new input: ', newInput) + update({ type: 'Input', data: newInput }) + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } + case 'SET_INPUT_SETTINGS': { + const input = activeItem.data as FormSystemInput + const { property, value, update } = action.payload + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + [property]: value + } + } + update({ type: 'Input', data: newInput }) + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } + case 'SET_LIST_ITEM_SELECTED': { + const { guid, update } = action.payload + const input = activeItem.data as FormSystemInput + const list = input.inputSettings?.list ?? [] + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + list: list.map((l) => + l.guid === guid + ? { ...l, isSelected: !l.isSelected } + : { ...l, isSelected: false }, + ) + } + } + update({ type: 'Input', data: newInput }) + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + + } + } + case 'REMOVE_LIST_ITEM': { + const { guid, update } = action.payload + const input = activeItem.data as FormSystemInput + const list = input.inputSettings?.list ?? [] + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + list: list.filter((l) => l.guid !== guid) + } + } + update({ type: 'Input', data: newInput }) + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } + case 'ADD_LIST_ITEM': { + const input = activeItem.data as FormSystemInput + const list = input.inputSettings?.list ?? [] + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + list: [ + ...list, + { + guid: uuid(), + label: { is: '', en: '' }, + description: { is: '', en: '' }, + displayOrder: list.length, + isSelected: false + } + ] + } + } + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } + case 'CHANGE_LIST_ITEM': { + const input = activeItem.data as FormSystemInput + const list = input.inputSettings?.list + const { property, lang, value, guid, update } = action.payload + if (!list) return state + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + list: list.map((l) => { + if (l.guid === guid) { + return { + ...l, + [property]: { + ...l[property], + [lang]: value, + }, + } + } + return l + }), + }, + } + update({ type: 'Input', data: newInput }) + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } // Drag and Drop case 'STEP_OVER_STEP': { const activeIndex = steps?.findIndex((step) => step?.guid === action.payload.activeId) as number @@ -282,7 +530,10 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont case 'GROUP_OVER_STEP': { const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number const overIndex = steps?.findIndex((step) => step?.guid === action.payload.overId) as number - const updatedGroups = groups?.map(group => ({ ...group })) as FormSystemGroup[] + if (groups && steps) { + console.log('active: ', groups[activeIndex], 'over: ', steps[overIndex]) + } + const updatedGroups = groups as FormSystemGroup[] if (steps && steps[overIndex]) { updatedGroups[activeIndex].stepGuid = action.payload.overId as string updatedGroups[activeIndex].stepId = steps[overIndex]?.id as number @@ -291,14 +542,14 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - groupsList: arrayMove(updatedGroups, activeIndex, overIndex).map((g, i) => ({ ...g, displayOrder: i })) + groupsList: arrayMove(updatedGroups, activeIndex, activeIndex).map((g, i) => ({ ...g, displayOrder: i })) } } } case 'GROUP_OVER_GROUP': { const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number const overIndex = groups?.findIndex((group) => group?.guid === action.payload.overId) as number - const updatedGroups = groups?.map(group => ({ ...group })) as FormSystemGroup[] + const updatedGroups = groups as FormSystemGroup[] if (updatedGroups[activeIndex] && updatedGroups[overIndex]) { if (updatedGroups[activeIndex].stepGuid !== updatedGroups[overIndex].stepGuid) { updatedGroups[activeIndex].stepGuid = updatedGroups[overIndex].stepGuid @@ -363,6 +614,35 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont } return state } + case 'LIST_ITEM_OVER_LIST_ITEM': { + const input = activeItem.data as FormSystemInput + const list = input.inputSettings?.list + const { activeId, overId } = action.payload + if (!list) { + return state + } + const activeIndex = list.findIndex((item) => item.guid === activeId) + const overIndex = list.findIndex((item) => item.guid === overId) + + const newInput = { + ...input, + inputSettings: { + ...input.inputSettings, + list: arrayMove(list, activeIndex, overIndex).map((l, i) => ({ ...l, displayOrder: i })) + } + } + return { + ...state, + activeItem: { + type: 'Input', + data: newInput + }, + form: { + ...form, + inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) + } + } + } default: return state } diff --git a/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts b/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts new file mode 100644 index 000000000000..95269f5716be --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts @@ -0,0 +1,15 @@ +export const fileTypes = { + ".pdf": "application/pdf", + ".doc": "application/msword", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ".txt": "text/plain", + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + ".xls": "application/vnd.ms-excel", + ".csv": "text/csv", + ".zip": "application/zip", + "*": "application/octet-stream" +} diff --git a/libs/portals/admin/form-system/src/lib/utils/interfaces.ts b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts index 69d9ad8e0632..3a814ab8ec3f 100644 --- a/libs/portals/admin/form-system/src/lib/utils/interfaces.ts +++ b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts @@ -1,4 +1,5 @@ -import { FormSystemStep, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" +import { UniqueIdentifier } from "@dnd-kit/core" +import { FormSystemStep, FormSystemGroup, FormSystemInput, FormSystemLanguageType, FormSystemLanguageTypeInput } from "@island.is/api/schema" export enum NavbarSelectStatus { @@ -14,3 +15,20 @@ export interface ActiveItem { type: ItemType data?: FormSystemStep | FormSystemGroup | FormSystemInput | null } + +export interface IListItem { + guid: UniqueIdentifier + label: FormSystemLanguageType | FormSystemLanguageTypeInput + description: FormSystemLanguageType | FormSystemLanguageTypeInput + displayOrder: number + isSelected: boolean +} + +export enum EFormApplicantTypes { + einstaklingur = 'Einstaklingur', + einstaklingurMedUmbodAnnarsEinstaklings = 'Einstaklingur_með_umboð_annars_einstaklings', + einstaklingurMedUmbodLogadila = 'Einstaklingur_með_umboð_lögaðila', + einstaklingurMedProkuru = 'Einstaklingur_með_prókúru', + einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', + logadili = 'Lögaðili', +} diff --git a/libs/portals/admin/form-system/src/lib/utils/removeTypename.ts b/libs/portals/admin/form-system/src/lib/utils/removeTypename.ts new file mode 100644 index 000000000000..6348a90c8015 --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/removeTypename.ts @@ -0,0 +1,15 @@ +export const removeTypename = (obj: any): any => { + if (typeof obj !== 'object' || obj == null) { + return obj + } + if (Array.isArray(obj)) { + return obj.map(removeTypename) + } + const newObj: { [key: string]: any } = {} + for (const [key, value] of Object.entries(obj)) { + if (key !== '__typename') { + newObj[key] = removeTypename(value) + } + } + return newObj +} diff --git a/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts index 74e10cdcb0e5..144d72b52e65 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts @@ -12,74 +12,75 @@ export const updateActiveItemFn = ( currentActiveItem?: ActiveItem ) => { const { type } = activeItem - console.log('updating: ', type) - if (type === 'Step') { - const { id, name, type, displayOrder, waitingText, callRuleset } = currentActiveItem ? currentActiveItem.data as FormSystemStep : activeItem.data as FormSystemStep - - updateStep({ - variables: { - input: { - stepId: id, - stepUpdateDto: { - id: id, - name: name?.__typename ? { ...name, __typename: undefined } : name, - type: type, - displayOrder: displayOrder, - waitingText: waitingText?.__typename ? { ...waitingText, __typename: undefined } : waitingText, - callRuleset: callRuleset + try { + if (type === 'Step') { + const { id, name, type, displayOrder, waitingText, callRuleset } = currentActiveItem ? currentActiveItem.data as FormSystemStep : activeItem.data as FormSystemStep + updateStep({ + variables: { + input: { + stepId: id, + stepUpdateDto: { + id: id, + name: name, + type: type, + displayOrder: displayOrder, + waitingText: waitingText, + callRuleset: callRuleset + } } } - } - }) - } else if (type === 'Group') { - const { id, name, guid, displayOrder, multiSet } = currentActiveItem ? currentActiveItem.data as FormSystemGroup : activeItem.data as FormSystemGroup - updateGroup({ - variables: { - input: { - groupId: activeItem?.data?.id, - groupUpdateDto: { - id, - name: name?.__typename ? { ...name, __typename: undefined } : name, - guid, - displayOrder, - multiSet, + }) + } else if (type === 'Group') { + const { id, name, guid, displayOrder, multiSet, stepId } = currentActiveItem ? currentActiveItem.data as FormSystemGroup : activeItem.data as FormSystemGroup + updateGroup({ + variables: { + input: { + groupId: activeItem?.data?.id, + groupUpdateDto: { + id, + name: name, + guid, + displayOrder, + multiSet, + stepId + }, }, }, - }, - }) - } else if (type === 'Input') { - const { - id, - name, - description, - isRequired, - displayOrder, - isHidden, - type, - inputSettings, - isPartOfMultiSet, - } = currentActiveItem ? currentActiveItem.data as FormSystemInput : activeItem.data as FormSystemInput - updateInput({ - variables: { - input: { - inputId: activeItem?.data?.id, - inputUpdateDto: { - id, - name: name?.__typename ? { ...name, __typename: undefined } : name, - description: description?.__typename - ? { ...description, __typename: undefined } - : description, - isRequired: isRequired ?? false, - displayOrder, - isHidden: isHidden ?? false, - type, - inputSettings: inputSettings?.__typename - ? { ...inputSettings, __typename: undefined } - : inputSettings, - isPartOfMultiSet: isPartOfMultiSet ?? false, + }) + } else if (type === 'Input') { + const { + id, + name, + description, + isRequired, + displayOrder, + isHidden, + type, + inputSettings, + isPartOfMultiSet, + groupId + } = currentActiveItem ? currentActiveItem.data as FormSystemInput : activeItem.data as FormSystemInput + updateInput({ + variables: { + input: { + inputId: id, + inputUpdateDto: { + id, + name: name, + description: description, + isRequired: isRequired ?? false, + displayOrder, + isHidden: isHidden ?? false, + type, + inputSettings: inputSettings, + isPartOfMultiSet: isPartOfMultiSet ?? false, + groupId: groupId ?? null, + }, }, }, - }, - }); + }); + } + } catch (e) { + console.error('Error updating active item: ', e) } -}; +} diff --git a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts index 395e0a7e3a82..d6c6faed6fcc 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts @@ -1,4 +1,4 @@ -import { FormSystemGroup, FormSystemGroupInput, FormSystemInput } from "@island.is/api/schema" +import { FormSystemFormInput, FormSystemGroup, FormSystemGroupInput, FormSystemInput, FormSystemInputInput, FormSystemOrganizationInput, FormSystemStepInput, InputMaybe } from "@island.is/api/schema" import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" import { ControlState } from "../../hooks/controlReducer" import { ItemType } from "./interfaces" @@ -11,9 +11,10 @@ export const updateDnd = ( ) => { console.log('updating: ', type) const formId = control.form.id + if (type === 'Step') { const steps = control.form.stepsList - const { form } = control + console.log('steps: ', steps) updateForm({ variables: { input: { @@ -23,9 +24,9 @@ export const updateDnd = ( id: s?.id, guid: s?.guid, displayOrder: s?.displayOrder, - name: s?.name?.__typename ? { ...s?.name, __typename: undefined } : s?.name, + name: s?.name, type: s?.type, - waitingText: s?.waitingText?.__typename ? { ...s?.waitingText, __typename: undefined } : s?.waitingText, + waitingText: s?.waitingText, callRuleset: s?.callRuleset, isHidden: s?.isHidden, isCompleted: s?.isCompleted, @@ -35,32 +36,23 @@ export const updateDnd = ( } }) } else if (type === 'Group') { - const { groupsList } = control.form - const updatedGroup = groupsList?.map(g => ({ - id: g?.id, - name: g?.name?.__typename ? { ...g?.name, __typename: undefined } : g?.name, - guid: g?.guid, - displayOrder: g?.displayOrder, - isHidden: g?.isHidden ?? false, - stepId: g?.stepId, - multiSet: g?.multiSet, - stepGuid: g?.stepGuid, - })) - console.log('updatedGroup', updatedGroup) + const groups = control.form.groupsList + console.log('groups: ', groups) updateForm({ variables: { input: { formId: formId, form: { - groupsList: groupsList?.map(g => ({ + groupsList: groups?.map(g => ({ id: g?.id, - name: g?.name?.__typename ? { ...g?.name, __typename: undefined } : g?.name, + name: g?.name, guid: g?.guid, displayOrder: g?.displayOrder, - isHidden: g?.isHidden ?? false, + isHidden: (g?.isHidden ?? false) as boolean, stepId: g?.stepId, multiSet: g?.multiSet, stepGuid: g?.stepGuid, + inputs: null } as FormSystemGroupInput), ) } @@ -69,6 +61,7 @@ export const updateDnd = ( }) } else if (type === 'Input') { const { inputsList } = control.form + console.log('inputs: ', inputsList) updateForm({ variables: { input: { @@ -76,13 +69,13 @@ export const updateDnd = ( form: { inputsList: inputsList?.filter((i): i is FormSystemInput => i !== null && i !== undefined).map(i => ({ id: i.id, - name: i.name?.__typename ? { ...i.name, __typename: undefined } : i.name, - description: i.description?.__typename ? { ...i.description, __typename: undefined } : i.description, + name: i.name, + description: i.description, isRequired: i.isRequired ?? false, displayOrder: i.displayOrder, isHidden: i.isHidden ?? false, type: i.type, - inputSettings: i.inputSettings?.__typename ? { ...i.inputSettings, __typename: undefined } : i.inputSettings, + inputSettings: i.inputSettings, isPartOfMultiSet: i.isPartOfMultiSet ?? false, groupId: i.groupId, groupGuid: i.groupGuid, diff --git a/libs/portals/admin/form-system/src/lib/utils/updateForm.ts b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts index b82824087219..871c167b0d72 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateForm.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts @@ -1,4 +1,4 @@ -import { FormSystemForm } from "@island.is/api/schema" +import { FormSystemForm, FormSystemFormInput, FormSystemGroupInput, FormSystemInputInput, FormSystemOrganizationInput, FormSystemStepInput, InputMaybe } from "@island.is/api/schema" import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" import { ControlState } from "../../hooks/controlReducer" @@ -17,7 +17,7 @@ export const partialFormUpdate = ( form: { invalidationDate: form.invalidationDate, name: form.name?.__typename ? { ...form.name, __typename: undefined } : form.name, - stopProgressOnValidatingStep: form.stopProgressOnValidatingStep ?? false, // doesnt save....whyyyy + stopProgressOnValidatingStep: (form.stopProgressOnValidatingStep ?? false) as boolean, // doesnt save....whyyyy applicationsDaysToRemove: form.applicationsDaysToRemove, documentTypes: form.documentTypes?.map(d => ({ __typename: undefined, @@ -31,3 +31,53 @@ export const partialFormUpdate = ( } }) } + +export const entireFormUpdate = ( + control: ControlState, + updateForm = useFormSystemUpdateFormMutation()[0], + updatedForm?: FormSystemForm +) => { + const form = updatedForm ? updatedForm : control.form + const organiaztionInput: FormSystemOrganizationInput = { + ...(form.organization as FormSystemOrganizationInput), + } + + const inputs: InputMaybe[] = form.inputsList?.filter(input => input !== undefined && input !== null).map(i => ({ + ...i, + isHidden: i?.isHidden ?? false, + isPartOfMultiSet: i?.isPartOfMultiSet ?? false, + isRequired: i?.isRequired ?? false, + })) ?? [] + + const groups: InputMaybe[] = form.groupsList?.filter(group => group !== undefined && group !== null).map(g => ({ + ...g, + inputs: null + })) ?? [] + + const steps: InputMaybe[] = form.stepsList?.filter(step => step !== undefined && step !== null).map(s => ({ + ...s, + groups: null + })) ?? [] + + const formInput: FormSystemFormInput = { + ...form, + organization: organiaztionInput, + inputsList: inputs, + groupsList: groups, + stepsList: steps, + steps: null + } + console.log('updating form: ', formInput) + updateForm({ + variables: { + input: { + formId: form.id, + form: formInput + } + } + }) +} + + + + diff --git a/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts b/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts new file mode 100644 index 000000000000..18e6a3d33b4e --- /dev/null +++ b/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts @@ -0,0 +1,38 @@ +import { FormSystemForm } from "@island.is/api/schema" +import { useFormSystemUpdateFormSettingsMutation } from "../../gql/FormSettings.generated" +import { ControlState } from "../../hooks/controlReducer" +import { removeTypename } from "./removeTypename" + + +export const updateSettings = ( + control: ControlState, + updatedForm?: FormSystemForm, + updateFormSettings = useFormSystemUpdateFormSettingsMutation()[0] +) => { + const form = updatedForm ? updatedForm : control.form + const documentTypesInput = form?.documentTypes?.map((dt) => ({ + formId: form.id, + documentTypeId: dt?.id, + })) + console.log('updating form settings: ', form.formApplicantTypes) + updateFormSettings({ + variables: { + input: { + id: form.id!, + formSettingsUpdateDto: { + id: form.id, + name: form.name, + lastChanged: form.lastChanged, + invalidationDate: form.invalidationDate, + dependencies: form.dependencies, + formDocumentTypes: documentTypesInput, + formApplicantTypes: removeTypename(form.formApplicantTypes), + completedMessage: form.completedMessage, + isTranslated: form.isTranslated, + stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, + applicationsDaysToRemove: form.applicationsDaysToRemove, + } + } + } + }) +} diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts index 602283ff041d..e4176ee7aacf 100644 --- a/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts @@ -3,6 +3,7 @@ import { FormSystemFormResponse } from '@island.is/api/schema' import { ApolloClient, NormalizedCacheObject } from '@apollo/client' import { FormSystemGetFormDocument, FormSystemGetFormQuery } from '../../gql/Form.generated' +import { FormSystemGetInputDocument, FormSystemGetInputQuery } from '../../gql/Input.generated' export interface FormLoaderResponse { formBuilder: FormSystemFormResponse, @@ -31,8 +32,38 @@ export const formLoader: WrappedLoaderFn = ({ client }) => { if (!formData) { throw new Error(`No form data found for ${params.formId}`) } + + //Inputs had null values thus I need to fetch them again for some reason... + const formBuilder = formData.formSystemGetForm + const updatedInputs = formBuilder.form?.inputsList?.length + ? await Promise.all( + formBuilder.form.inputsList.map(async (input) => { + const { data: updatedInput, error: inputError } = + await client.query({ + query: FormSystemGetInputDocument, + fetchPolicy: 'network-only', + variables: { + input: { + id: Number(input?.id), + }, + }, + }); + return updatedInput?.formSystemGetInput; + }) + ) + : [] + const updatedFormBuilder = { + ...formBuilder, + form: { + ...formBuilder.form, + inputsList: updatedInputs + } + } + + + return { - formBuilder: formData.formSystemGetForm, + formBuilder: updatedFormBuilder as FormSystemFormResponse, client } } diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.tsx b/libs/portals/admin/form-system/src/screens/Form/Form.tsx index 067b72ca56b7..2e51492b6f8e 100644 --- a/libs/portals/admin/form-system/src/screens/Form/Form.tsx +++ b/libs/portals/admin/form-system/src/screens/Form/Form.tsx @@ -1,6 +1,6 @@ import { useLoaderData } from "react-router-dom" import { useEffect, useReducer, useState } from "react" -import { NavbarSelectStatus } from "../../lib/utils/interfaces" +import { IListItem, NavbarSelectStatus } from "../../lib/utils/interfaces" import { FormLoaderResponse } from "./Form.loader" import { ControlState, controlReducer } from "../../hooks/controlReducer" import { baseSettingsStep } from "../../utils/getBaseSettingsStep" @@ -12,7 +12,7 @@ import { Box, } from '@island.is/island-ui/core' import Navbar from "../../components/Navbar/Navbar" -import { FormSystemForm, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" +import { FormSystemForm, FormSystemStep } from "@island.is/api/schema" import MainContent from "../../components/MainContent/MainContent" import { useFormSystemUpdateGroupMutation } from "../../gql/Group.generated" import { useFormSystemUpdateStepMutation } from "../../gql/Step.generated" @@ -21,52 +21,55 @@ import { updateActiveItemFn } from "../../lib/utils/updateActiveItem" import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" import { ActiveItem, ItemType } from "../../lib/utils/interfaces" import { updateDnd } from "../../lib/utils/updateDnd" -import { SettingsState, settingsReducer } from "../../hooks/settingsReducer" -import { partialFormUpdate } from "../../lib/utils/updateForm" +import { entireFormUpdate, partialFormUpdate } from "../../lib/utils/updateForm" +import { removeTypename } from "../../lib/utils/removeTypename" +import NavbarSelect from "../../components/NavbarSelect/NavbarSelect" +import { useFormSystemUpdateFormSettingsMutation } from "../../gql/FormSettings.generated" +import { updateSettings as us } from "../../lib/utils/updateFormSettings" const Form = () => { - const { formBuilder, client } = useLoaderData() as FormLoaderResponse + const { formBuilder } = useLoaderData() as FormLoaderResponse const { form, applicantTypes, documentTypes, inputTypes, listTypes } = formBuilder const [focus, setFocus] = useState('') const [inSettings, setInSettings] = useState(form?.name?.is === '') + const [inListBuilder, setInListBuilder] = useState(false) const [selectStatus, setSelectStatus] = useState(NavbarSelectStatus.OFF) const [updateStep] = useFormSystemUpdateStepMutation() const [updateGroup] = useFormSystemUpdateGroupMutation() const [updateInput] = useFormSystemUpdateInputMutation() const [updateForm] = useFormSystemUpdateFormMutation() + const [updateFormSettings] = useFormSystemUpdateFormSettingsMutation() + const updateActiveItem = (updatedActiveItem?: ActiveItem) => updateActiveItemFn(control.activeItem, updateStep, updateGroup, updateInput, updatedActiveItem) const initialControl: ControlState = { activeItem: { type: 'Step', - data: inSettings ? baseSettingsStep : form?.stepsList?.find((s) => s?.type === 'Innsláttur') ?? defaultStep + data: inSettings ? baseSettingsStep : removeTypename(form?.stepsList)?.find((s: FormSystemStep) => s?.type === 'Innsláttur') ?? defaultStep }, - form: form as FormSystemForm + activeListItem: null, + form: removeTypename(form) as FormSystemForm, } - const initialSettings: SettingsState = { - applicantTypes, - documentTypes, - inputTypes, - listTypes - } - const [settings, settingsDispatch] = useReducer(settingsReducer, initialSettings) + const [control, controlDispatch] = useReducer(controlReducer, initialControl) - const updateActiveItem = (updatedActiveItem?: ActiveItem) => updateActiveItemFn(control.activeItem, updateStep, updateGroup, updateInput, updatedActiveItem) + const updateDragAndDrop = (type: ItemType) => updateDnd(type, control, updateForm) + + const updateSettings = (updatedForm?: FormSystemForm) => us(control, updatedForm, updateFormSettings) const formSettingsUpdate = (updatedForm?: FormSystemForm) => { if (updatedForm) { controlDispatch({ type: 'CHANGE_FORM_SETTINGS', payload: { newForm: updatedForm } }) } return partialFormUpdate(control, updateForm, updatedForm) } + const formUpdate = (updatedForm?: FormSystemForm) => entireFormUpdate(control, updateForm, updatedForm) const context: IControlContext = { control, controlDispatch, - apolloClient: client, applicantTypes, documentTypes, inputTypes, @@ -79,16 +82,22 @@ const Form = () => { updateDnD: updateDragAndDrop, formSettingsUpdate, selectStatus, - setSelectStatus + setSelectStatus, + formUpdate, + inListBuilder, + setInListBuilder, + updateSettings } useEffect(() => { console.log('loaderData form: ', form) - console.log('loaderData client: ', client) console.log('control: ', control) + console.log('formBuilder: ', formBuilder) }, []) + + if (!form) { return
Loading...
} @@ -96,8 +105,7 @@ const Form = () => { - {/* {selectStatus !== NavbarSelectStatus.OFF ? : } */} - + {selectStatus !== NavbarSelectStatus.OFF ? : } Date: Tue, 23 Apr 2024 15:48:33 +0000 Subject: [PATCH 28/72] took out the formsysteminputsettings and replaced it with a graphqlTypeJson --- .../form-system/src/dto/inputs.input.ts | 10 +- .../form-system/src/models/input.model.ts | 4 +- .../components/ListBuilder/ListBuilder.tsx | 6 +- .../Preview/components/FileUpload.tsx | 4 +- .../components/Preview/components/List.tsx | 2 +- .../components/Preview/components/Radio.tsx | 2 +- .../admin/form-system/src/gql/Form.graphql | 420 +----------------- .../admin/form-system/src/gql/Group.graphql | 42 +- .../admin/form-system/src/gql/Input.graphql | 84 +--- .../admin/form-system/src/gql/Step.graphql | 42 +- .../form-system/src/hooks/controlReducer.ts | 20 +- .../src/screens/Forms/CreateForm.graphql | 252 +---------- .../form-system/src/types/interfaces.tsx | 24 +- 13 files changed, 66 insertions(+), 846 deletions(-) diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index 2d17aba12824..21dc96ff8845 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -35,8 +35,8 @@ export class UpdateInput { @Field(() => String, { nullable: true }) type?: string - @Field(() => InputSettingsInput, { nullable: true }) - inputSettings?: InputSettingsInput + @Field(() => graphqlTypeJson, { nullable: true }) + inputSettings?: object @Field() isPartOfMultiSet?: boolean @@ -46,8 +46,6 @@ export class UpdateInput { } - - @InputType('FormSystemGetInputInput') export class GetInputInput { @Field(() => Int) @@ -110,8 +108,8 @@ export class InputInput { @Field(() => String, { nullable: true }) groupGuid?: string - @Field(() => InputSettingsInput, { nullable: true }) - inputSettings?: InputSettingsInput + @Field(() => graphqlTypeJson, { nullable: true }) + inputSettings?: object @Field(() => graphqlTypeJson, { nullable: true }) inputFields?: object diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index a7d41e0f70cb..0936d7e7f5d9 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -39,8 +39,8 @@ export class Input { @Field(() => String, { nullable: true }) groupGuid?: string - @Field(() => InputSettings, { nullable: true }) - inputSettings?: InputSettings + @Field(() => graphqlTypeJson, { nullable: true }) + inputSettings?: object @Field(() => graphqlTypeJson, { nullable: true }) inputFields?: object diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx index bca49a663ad8..7bed2924d4c2 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx @@ -29,8 +29,8 @@ const ListBuilder = () => { const { control, controlDispatch, setSelectStatus, setInListBuilder, updateActiveItem } = useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput const { activeListItem } = control - const listItems = currentItem?.inputSettings?.list ?? [] - const listItemIds = useMemo(() => listItems?.filter((l): l is FormSystemListItem => l !== null && l !== undefined).map((l) => l?.guid as UniqueIdentifier), [listItems]) + const listItems = currentItem?.inputSettings?.list ?? [] as FormSystemListItem[] + const listItemIds = useMemo(() => listItems?.filter((l: FormSystemListItem): l is FormSystemListItem => l !== null && l !== undefined).map((l: FormSystemListItem) => l?.guid as UniqueIdentifier), [listItems]) const [connecting, setConnecting] = useState([false]) const sensors = useSensors( @@ -118,7 +118,7 @@ const ListBuilder = () => { > {listItems && - listItems.map((l, i) => { + listItems.map((l: FormSystemListItem, i: number) => { return ( { fileList={fileList} header={currentItem?.name?.is ?? ''} description={`Eftirfarandi skjalatýpur eru leyfðar: ${currentItem?.inputSettings?.types?.map( - (f) => `${f} `, + (f: string) => `${f} `, )}`} buttonLabel="Veldu skjöl til að hlaða upp" onChange={onChange} @@ -55,7 +55,7 @@ const FileUpload = ({ currentItem }: Props) => { errorMessage={fileList.length > 0 ? error : undefined} accept={ currentItem?.inputSettings?.types?.map( - (t) => fileTypes[t as keyof typeof fileTypes], + (t: string) => fileTypes[t as keyof typeof fileTypes], ) ?? [] } showFileSize diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx index 0c09856669f5..99a5b1307fb1 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx @@ -17,7 +17,7 @@ const List = ({ currentItem }: Props) => { useEffect(() => { const currentList = currentItem.inputSettings?.list ?? [] setListItems( - currentList.map((l) => ({ + currentList.map((l: FormSystemListItem) => ({ label: l?.label?.is ?? '', value: l?.label?.is ?? '', })), diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx index 98ec59caa935..c06000c50dc9 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx @@ -7,7 +7,7 @@ interface Props { } const Radio = ({ currentItem }: Props) => { - const radioButtons = currentItem.inputSettings?.list + const radioButtons = currentItem.inputSettings?.list as FormSystemListItem[] const [radioChecked, setRadioChecked] = useState([]) useEffect(() => { diff --git a/libs/portals/admin/form-system/src/gql/Form.graphql b/libs/portals/admin/form-system/src/gql/Form.graphql index d4dc5032d9bc..5a47f0fdb018 100644 --- a/libs/portals/admin/form-system/src/gql/Form.graphql +++ b/libs/portals/admin/form-system/src/gql/Form.graphql @@ -66,47 +66,7 @@ query formSystemGetForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -164,47 +124,7 @@ query formSystemGetForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -250,47 +170,7 @@ query formSystemGetForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -385,47 +265,7 @@ query formSystemGetForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -492,47 +332,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -562,47 +362,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -660,47 +420,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -746,47 +466,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -837,47 +517,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -955,47 +595,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired diff --git a/libs/portals/admin/form-system/src/gql/Group.graphql b/libs/portals/admin/form-system/src/gql/Group.graphql index 3574a586c703..8538f403282c 100644 --- a/libs/portals/admin/form-system/src/gql/Group.graphql +++ b/libs/portals/admin/form-system/src/gql/Group.graphql @@ -16,47 +16,7 @@ mutation formSystemCreateGroup( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired diff --git a/libs/portals/admin/form-system/src/gql/Input.graphql b/libs/portals/admin/form-system/src/gql/Input.graphql index 224d71019472..be4ab3532e6a 100644 --- a/libs/portals/admin/form-system/src/gql/Input.graphql +++ b/libs/portals/admin/form-system/src/gql/Input.graphql @@ -19,47 +19,7 @@ mutation formSystemCreateInput( guid isPartOfMultiSet groupGuid - inputSettings { - isLarge - size - interval - hasLink - url - buttonText { - is - en - } - types - maxSize - isMulti - amount - header - maxLength - minLength - min - max - list { - guid - label { - is - en - } - description { - is - en - } - displayOrder - isSelected - value - } - type - name { - is - en - } - isList - hasInput - } + inputSettings inputFields } } @@ -97,47 +57,7 @@ query formSystemGetInput( guid isPartOfMultiSet groupGuid - inputSettings { - isLarge - size - interval - hasLink - url - buttonText { - is - en - } - types - maxSize - isMulti - amount - header - maxLength - minLength - min - max - list { - guid - label { - is - en - } - description { - is - en - } - displayOrder - isSelected - value - } - type - name { - is - en - } - isList - hasInput - } + inputSettings inputFields } } diff --git a/libs/portals/admin/form-system/src/gql/Step.graphql b/libs/portals/admin/form-system/src/gql/Step.graphql index 29fe5c61ea09..7346ff6b086e 100644 --- a/libs/portals/admin/form-system/src/gql/Step.graphql +++ b/libs/portals/admin/form-system/src/gql/Step.graphql @@ -19,47 +19,7 @@ mutation formSystemCreateStep( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired diff --git a/libs/portals/admin/form-system/src/hooks/controlReducer.ts b/libs/portals/admin/form-system/src/hooks/controlReducer.ts index 61dfe3d3d49b..fa5b61323f29 100644 --- a/libs/portals/admin/form-system/src/hooks/controlReducer.ts +++ b/libs/portals/admin/form-system/src/hooks/controlReducer.ts @@ -1,5 +1,5 @@ -import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemInputSettings, FormSystemListItem, FormSystemStep } from "@island.is/api/schema" -import { ActiveItem } from "../types/interfaces" +import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemListItem, FormSystemStep } from "@island.is/api/schema" +import { ActiveItem, IInputSettings } from "../types/interfaces" import { UniqueIdentifier } from "@dnd-kit/core" import { arrayMove } from "@dnd-kit/sortable" import { removeTypename } from "../lib/utils/removeTypename" @@ -16,7 +16,7 @@ type GroupActions = type InputActions = | { type: 'ADD_INPUT', payload: { input: FormSystemInput } } | { type: 'REMOVE_INPUT', payload: { inputId: number } } - | { type: 'CHANGE_INPUT_TYPE', payload: { newValue: string, inputSettings: FormSystemInputSettings, update: (updatedActiveItem?: ActiveItem) => void } } + | { type: 'CHANGE_INPUT_TYPE', payload: { newValue: string, inputSettings: IInputSettings, update: (updatedActiveItem?: ActiveItem) => void } } | { type: 'CHANGE_DESCRIPTION', payload: { lang: 'en' | 'is', newValue: string } } | { type: 'CHANGE_IS_REQUIRED', payload: { update: (updatedActiveItem?: ActiveItem) => void } } @@ -342,7 +342,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont const { property, checked, value, update } = action.payload const updateFileTypesArray = (): string[] => { - const newFileTypes = input.inputSettings?.types ?? [] + const newFileTypes = input.inputSettings?.types as string[] ?? [] if (checked) { return [...newFileTypes, value as string] } else { @@ -402,7 +402,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - list: list.map((l) => + list: list.map((l: FormSystemListItem) => l.guid === guid ? { ...l, isSelected: !l.isSelected } : { ...l, isSelected: false }, @@ -431,7 +431,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - list: list.filter((l) => l.guid !== guid) + list: list.filter((l: FormSystemListItem) => l.guid !== guid) } } update({ type: 'Input', data: newInput }) @@ -487,7 +487,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - list: list.map((l) => { + list: list.map((l: FormSystemListItem) => { if (l.guid === guid) { return { ...l, @@ -621,14 +621,14 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont if (!list) { return state } - const activeIndex = list.findIndex((item) => item.guid === activeId) - const overIndex = list.findIndex((item) => item.guid === overId) + const activeIndex = list.findIndex((item: FormSystemListItem) => item.guid === activeId) + const overIndex = list.findIndex((item: FormSystemListItem) => item.guid === overId) const newInput = { ...input, inputSettings: { ...input.inputSettings, - list: arrayMove(list, activeIndex, overIndex).map((l, i) => ({ ...l, displayOrder: i })) + list: arrayMove(list, activeIndex, overIndex).map((l: FormSystemListItem, i: number) => ({ ...l, displayOrder: i })) } } return { diff --git a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql index 74732fd9cda1..b77d578fd2a1 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql @@ -52,47 +52,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -122,47 +82,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -220,47 +140,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -306,47 +186,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -397,47 +237,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired @@ -515,47 +315,7 @@ mutation formSystemCreateForm( guid id inputFields - inputSettings { - amount - buttonText { - is - en - } - hasInput - hasLink - header - interval - isLarge - isList - isMulti - list { - description { - is - en - } - displayOrder - guid - isSelected - label { - is - en - } - value - } - max - maxLength - maxSize - min - minLength - name { - is - en - } - size - type - types - url - } + inputSettings isHidden isPartOfMultiSet isRequired diff --git a/libs/portals/admin/form-system/src/types/interfaces.tsx b/libs/portals/admin/form-system/src/types/interfaces.tsx index 54ae668c1144..9720a3276611 100644 --- a/libs/portals/admin/form-system/src/types/interfaces.tsx +++ b/libs/portals/admin/form-system/src/types/interfaces.tsx @@ -3,7 +3,7 @@ import { UniqueIdentifier } from '@dnd-kit/core' import { EFormApplicantTypes } from './enums' import { FormAction } from '../hooks/formReducer' import { FormHeaderAction } from '../hooks/headerInfoReducer' -import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemListType, FormSystemStep } from '@island.is/api/schema' +import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemLanguageType, FormSystemListItem, FormSystemListType, FormSystemStep } from '@island.is/api/schema' import { Maybe } from 'graphql/jsutils/Maybe' export type IFormBuilderContext = { @@ -247,3 +247,25 @@ export interface User { type Sizes = 'xs' | 'sm' | 'md' export type ItemType = 'Step' | 'Group' | 'Input' + +interface InputSettings { + hasInput?: boolean + isList?: boolean + isLarge?: boolean + size?: string + interval?: string + list?: FormSystemListItem[] + max?: number + min?: number + maxLength?: number + minLength?: number + amount?: number + isMulti?: boolean + maxSize?: number + types?: string[] + buttonText?: FormSystemLanguageType + hasLink?: boolean + $type?: string + name?: FormSystemLanguageType + [key: string]: unknown +} From d8a15cf5f21e2ef78a2ce09ee1b6d4879289c584 Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Wed, 24 Apr 2024 15:23:21 +0000 Subject: [PATCH 29/72] spring cleaning and creating dependencies within the form --- apps/api/src/app/app.module.ts | 2 +- .../components/AuthProvider/AuthProvider.tsx | 12 +- .../ListBuilder/components/ListItem.tsx | 10 +- apps/form-builder/context/UserContext.tsx | 5 +- apps/form-builder/hooks/useUser.ts | 6 +- apps/form-builder/pages/_app.tsx | 11 +- .../pages/api/auth/[...nextauth].ts | 9 +- apps/form-builder/screens/Form.tsx | 10 +- apps/portals/admin/src/auth.ts | 2 +- .../portals/admin/src/lib/masterNavigation.ts | 2 +- apps/portals/admin/src/lib/modules.ts | 2 +- .../caseSubscription.resolver.ts | 2 +- libs/api/domains/form-system/project.json | 19 +- .../src/dto/applicantType.input.ts | 8 +- .../dto/applicantTypeNameSuggestion.input.ts | 4 +- .../form-system/src/dto/documentType.input.ts | 6 +- .../src/dto/externalEndpoints.input.ts | 5 +- .../form-system/src/dto/forms.input.ts | 17 +- .../form-system/src/dto/groups.input.ts | 7 +- .../src/dto/inputSettings.input.ts | 7 +- .../form-system/src/dto/inputs.input.ts | 8 +- .../form-system/src/dto/language.input.ts | 2 +- .../form-system/src/dto/listItem.input.ts | 4 +- .../form-system/src/dto/listType.input.ts | 4 +- .../form-system/src/dto/organization.input.ts | 16 +- .../form-system/src/dto/services.input.ts | 2 +- .../form-system/src/dto/steps.input.ts | 6 +- .../src/dto/updateFormSettings.input.ts | 9 +- .../form-system/src/lib/form-system.module.ts | 9 +- .../src/lib/forms/forms.resolver.ts | 61 +- .../src/lib/forms/forms.service.ts | 54 +- .../src/lib/groups/groups.resolver.ts | 39 +- .../src/lib/groups/groups.service.ts | 32 +- .../src/lib/inputs/inputs.resolver.ts | 39 +- .../src/lib/inputs/inputs.service.ts | 43 +- .../organizations/organizations.resolver.ts | 27 +- .../organizations/organizations.services.ts | 24 +- .../src/lib/services/services.resolver.ts | 53 +- .../src/lib/services/services.service.ts | 19 +- .../src/lib/steps/steps.resolver.ts | 40 +- .../src/lib/steps/steps.service.ts | 29 +- .../src/lib/utils/helperFunctions.ts | 124 ---- .../src/models/applicantType.model.ts | 6 +- .../src/models/applicantTypeNameSuggestion.ts | 5 +- .../src/models/documentType.model.ts | 6 +- .../src/models/externalEndpoints.model.ts | 5 +- .../src/models/formApplicantType.model.ts | 5 +- .../src/models/formListResponse.model.ts | 4 +- .../form-system/src/models/group.model.ts | 7 +- .../form-system/src/models/input.model.ts | 2 - .../form-system/src/models/listType.model.ts | 5 +- .../src/models/organization.model.ts | 2 - .../form-system/src/models/services.model.ts | 5 +- .../form-system/src/models/step.model.ts | 7 +- libs/clients/form-system/project.json | 21 +- .../clients/form-system/src/clientConfig.json | 114 +--- .../src/lib/FormSystemApiProvider.ts | 36 +- .../src/lib/FormSystemClient.config.ts | 8 +- .../form-system/src/lib/form-system.module.ts | 23 +- libs/portals/admin/form-system/codegen.yml | 2 +- libs/portals/admin/form-system/project.json | 19 +- .../components/MainContent/MainContent.tsx | 176 ++--- .../components/BaseSettings/BaseSettings.tsx | 50 +- .../components/InputContent/InputContent.tsx | 20 +- .../InputContent/components/BaseInput.tsx | 106 +-- .../InputSettings/InputSettings.tsx | 28 +- .../components/FIleUploadSettings.tsx | 123 ++-- .../InputSettings/components/ListSettings.tsx | 38 +- .../components/MessageWithLinkSettings.tsx | 129 ++-- .../components/TextInputSettings.tsx | 30 +- .../components/ToggleConnection.tsx | 42 ++ .../components/ListBuilder/ListBuilder.tsx | 43 +- .../ListBuilder/components/ListItem.tsx | 36 +- .../components/Premises/Premises.tsx | 18 +- .../components/Preview/Preveiw.tsx | 40 +- .../Preview/components/Banknumber.tsx | 1 - .../Preview/components/Currency.tsx | 1 - .../components/Preview/components/Email.tsx | 1 - .../Preview/components/FileUpload.tsx | 1 - .../components/Preview/components/List.tsx | 10 +- .../Preview/components/MessageWithLink.tsx | 13 +- .../components/Preview/components/Radio.tsx | 4 +- .../Preview/components/TextInput.tsx | 4 +- .../PreviewStepOrGroup/PreviewStepOrGroup.tsx | 24 +- .../components/MultiSet.tsx | 8 +- .../RelevantParties/RevelantParties.tsx | 75 ++- .../components/FormApplicantType.tsx | 48 +- .../src/components/Navbar/Navbar.tsx | 115 ++-- .../components/NavComponent/NavComponent.tsx | 50 +- .../NavComponent/components/NavButtons.tsx | 76 ++- .../Navbar/components/NavbarTab/NavbarTab.tsx | 13 +- .../components/NavbarSelect/NavbarSelect.tsx | 8 +- .../components/SelectNavComponent.tsx | 43 +- .../components/selectNavComponent.css.ts | 4 + .../src/components/TableRow/TableRow.tsx | 16 +- .../form-system/src/context/ControlContext.ts | 28 +- .../src/context/FormBuilderContext.tsx | 50 -- .../form-system/src/context/LayoutContext.tsx | 14 - .../form-system/src/context/UserContext.tsx | 13 - .../admin/form-system/src/gql/Form.graphql | 89 ++- .../admin/form-system/src/gql/Group.graphql | 12 +- .../admin/form-system/src/gql/Input.graphql | 16 +- .../admin/form-system/src/gql/Step.graphql | 12 +- .../form-system/src/hooks/controlReducer.ts | 635 ++++++++++++------ .../form-system/src/hooks/formReducer.ts | 199 ------ .../src/hooks/headerInfoReducer.ts | 29 - .../form-system/src/hooks/settingsReducer.ts | 18 - .../admin/form-system/src/hooks/useUser.ts | 40 -- .../admin/form-system/src/lib/messages.ts | 9 +- .../admin/form-system/src/lib/navigation.ts | 8 +- .../form-system/src/lib/utils/fileTypes.ts | 27 +- .../form-system/src/lib/utils/interfaces.ts | 89 ++- .../src/lib/utils/updateActiveItem.ts | 44 +- .../form-system/src/lib/utils/updateDnd.ts | 96 +-- .../form-system/src/lib/utils/updateForm.ts | 96 ++- .../src/lib/utils/updateFormSettings.ts | 18 +- libs/portals/admin/form-system/src/module.tsx | 22 +- .../src/screens/Form/Form.loader.ts | 49 +- .../form-system/src/screens/Form/Form.tsx | 106 +-- .../src/screens/Forms/CreateForm.graphql | 44 +- .../src/screens/Forms/Forms.graphql | 5 +- .../src/screens/Forms/Forms.loader.ts | 26 +- .../form-system/src/screens/Forms/Forms.tsx | 39 +- .../form-system/src/services/apiService.tsx | 248 ------- .../src/services/translationStation.tsx | 41 -- .../form-system/src/services/zodValidation.ts | 193 ------ .../form-system/src/types/enums/index.tsx | 100 --- .../form-system/src/types/interfaces.tsx | 271 -------- .../form-system/src/utils/defaultStep.tsx | 3 +- .../admin/form-system/src/utils/fileTypes.ts | 69 +- libs/portals/admin/form-system/tsconfig.json | 2 +- 131 files changed, 2192 insertions(+), 3034 deletions(-) delete mode 100644 libs/api/domains/form-system/src/lib/utils/helperFunctions.ts create mode 100644 libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ToggleConnection.tsx delete mode 100644 libs/portals/admin/form-system/src/context/FormBuilderContext.tsx delete mode 100644 libs/portals/admin/form-system/src/context/LayoutContext.tsx delete mode 100644 libs/portals/admin/form-system/src/context/UserContext.tsx delete mode 100644 libs/portals/admin/form-system/src/hooks/formReducer.ts delete mode 100644 libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts delete mode 100644 libs/portals/admin/form-system/src/hooks/settingsReducer.ts delete mode 100644 libs/portals/admin/form-system/src/hooks/useUser.ts delete mode 100644 libs/portals/admin/form-system/src/services/apiService.tsx delete mode 100644 libs/portals/admin/form-system/src/services/translationStation.tsx delete mode 100644 libs/portals/admin/form-system/src/services/zodValidation.ts delete mode 100644 libs/portals/admin/form-system/src/types/enums/index.tsx delete mode 100644 libs/portals/admin/form-system/src/types/interfaces.tsx diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 21e96e6b619a..e0e668cc3f6b 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -392,4 +392,4 @@ const environment = getConfig }), ], }) -export class AppModule { } +export class AppModule {} diff --git a/apps/form-builder/components/AuthProvider/AuthProvider.tsx b/apps/form-builder/components/AuthProvider/AuthProvider.tsx index 594ceb670bec..c8b54c015ca8 100644 --- a/apps/form-builder/components/AuthProvider/AuthProvider.tsx +++ b/apps/form-builder/components/AuthProvider/AuthProvider.tsx @@ -1,17 +1,17 @@ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-nocheck -import { ReactNode } from "react" -import useUser from "../../hooks/useUser" -import UserContext from "../../context/UserContext" -import { User } from "../../types/interfaces" +import { ReactNode } from 'react' +import useUser from '../../hooks/useUser' +import UserContext from '../../context/UserContext' +import { User } from '../../types/interfaces' interface UserProps { children: ReactNode } - const AuthProvider = ({ children }: UserProps) => { - const { isAuthenticated, setIsAuthenticated, user, setUser, userLoading } = useUser() + const { isAuthenticated, setIsAuthenticated, user, setUser, userLoading } = + useUser() return ( { }} + onChange={() => {}} /> { }} + onChange={() => {}} /> @@ -75,7 +75,7 @@ export default function ListItem({ marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => { }} + onClick={() => {}} > @@ -93,7 +93,7 @@ export default function ListItem({ size="sm" value={listItem.label.is} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> @@ -104,7 +104,7 @@ export default function ListItem({ size="sm" value={listItem.label.en} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> diff --git a/apps/form-builder/context/UserContext.tsx b/apps/form-builder/context/UserContext.tsx index b59d839d23b2..c7ae918f1a3d 100644 --- a/apps/form-builder/context/UserContext.tsx +++ b/apps/form-builder/context/UserContext.tsx @@ -1,6 +1,5 @@ -import { createContext } from "react"; -import { User } from "../types/interfaces"; - +import { createContext } from 'react' +import { User } from '../types/interfaces' const UserContext = createContext({ isAuthenticated: false, diff --git a/apps/form-builder/hooks/useUser.ts b/apps/form-builder/hooks/useUser.ts index bee6280737f9..4d0458f4cd06 100644 --- a/apps/form-builder/hooks/useUser.ts +++ b/apps/form-builder/hooks/useUser.ts @@ -7,7 +7,9 @@ export default function useUser() { const [session, loading] = useSession() const timeNow = Math.floor(Date.now() / 1000) - const expiryStr = session?.expires ? new Date(session.expires.replace(/['"]+/g, '')).getTime() : undefined + const expiryStr = session?.expires + ? new Date(session.expires.replace(/['"]+/g, '')).getTime() + : undefined const expiry = Math.floor((expiryStr ?? 0) / 1000) const hasNotExpired = timeNow < expiry @@ -25,7 +27,7 @@ export default function useUser() { if (!user && session?.user) { const { name = '', email, image } = session.user || {} setUser({ name: name || '', email: email || '', image: image || '' }) - setIsAuthenticated(true); + setIsAuthenticated(true) } } }, [setUser, session, user]) diff --git a/apps/form-builder/pages/_app.tsx b/apps/form-builder/pages/_app.tsx index f86fd826885a..593db52ef5e5 100644 --- a/apps/form-builder/pages/_app.tsx +++ b/apps/form-builder/pages/_app.tsx @@ -15,10 +15,7 @@ const FormBuilderProviderApp: React.FC = ({ defaultLocale="is" onError={() => undefined} > - +
@@ -28,7 +25,6 @@ const FormBuilderProviderApp: React.FC = ({ - ) } @@ -37,10 +33,9 @@ export async function getInitialProps(appContext: AppContext) { const session = await getSession(ctx) return { pageProps: { - session: session - } + session: session, + }, } } export default FormBuilderProviderApp - diff --git a/apps/form-builder/pages/api/auth/[...nextauth].ts b/apps/form-builder/pages/api/auth/[...nextauth].ts index e0643522ceed..fb644da3b3e0 100644 --- a/apps/form-builder/pages/api/auth/[...nextauth].ts +++ b/apps/form-builder/pages/api/auth/[...nextauth].ts @@ -19,20 +19,20 @@ const providers = [ clientSecret: env.identityServerClientId, clientId: env.identityServerClientId, domain: env.identityServerDomain, - protection: 'pkce' - }) + protection: 'pkce', + }), ] const callbacks: CallbacksOptions = { signIn: signIn, jwt: jwt, - session: session + session: session, } async function signIn( user: AuthUser, account: Record, - profile: Record + profile: Record, ): Promise { return handleSignIn(user, account, profile, env.identityServerClientId) } @@ -68,4 +68,3 @@ const handleAuth = (req: NextApiRequest, res: NextApiResponse) => { } export default handleAuth - diff --git a/apps/form-builder/screens/Form.tsx b/apps/form-builder/screens/Form.tsx index 0a975f0d4415..adbe495abe4b 100644 --- a/apps/form-builder/screens/Form.tsx +++ b/apps/form-builder/screens/Form.tsx @@ -45,11 +45,11 @@ export default function Form({ form }: Props) { activeItem: inSettings ? { type: 'Step', data: baseSettingsStep } : { - type: 'Step', - data: - form?.form?.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, + type: 'Step', + data: + form?.form?.stepsList.find((s) => s.type === 'Innsláttur') || + defaultStep, + }, steps: form.form.stepsList ?? [], groups: form.form.groupsList ?? [], inputs: form.form.inputsList ?? [], diff --git a/apps/portals/admin/src/auth.ts b/apps/portals/admin/src/auth.ts index 48f53613aed3..4a081c7312ea 100644 --- a/apps/portals/admin/src/auth.ts +++ b/apps/portals/admin/src/auth.ts @@ -37,7 +37,7 @@ if (userMocked) { AdminPortalScope.signatureCollectionManage, AdminPortalScope.signatureCollectionProcess, AdminPortalScope.formSystem, - AdminPortalScope.formSystemSuperUser + AdminPortalScope.formSystemSuperUser, ], post_logout_redirect_uri: `${window.location.origin}`, userStorePrefix: 'ap.', diff --git a/apps/portals/admin/src/lib/masterNavigation.ts b/apps/portals/admin/src/lib/masterNavigation.ts index 8e99ae2a5ab7..5405d89aee5c 100644 --- a/apps/portals/admin/src/lib/masterNavigation.ts +++ b/apps/portals/admin/src/lib/masterNavigation.ts @@ -44,7 +44,7 @@ export const TOP_NAVIGATION: PortalNavigationItem = { serviceDeskNavigation, // Meðmælasöfnun signatureCollectionNavigation, - formSystemNavigation + formSystemNavigation, ], } export const BOTTOM_NAVIGATION: PortalNavigationItem = { diff --git a/apps/portals/admin/src/lib/modules.ts b/apps/portals/admin/src/lib/modules.ts index f3ec19c5a14a..73fc69898b39 100644 --- a/apps/portals/admin/src/lib/modules.ts +++ b/apps/portals/admin/src/lib/modules.ts @@ -29,5 +29,5 @@ export const modules: PortalModule[] = [ petitionModule, serviceDeskModule, signatureCollectionModule, - formSystemModule + formSystemModule, ] diff --git a/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts b/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts index cecd0a466aa4..32e9bc95fc18 100644 --- a/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts +++ b/libs/api/domains/consultation-portal/src/lib/caseSubscription/caseSubscription.resolver.ts @@ -25,7 +25,7 @@ import { Audit } from '@island.is/nest/audit' @FeatureFlag(Features.consultationPortalApplication) @Audit({ namespace: '@island.is/samradsgatt' }) export class CaseSubscriptionResolver { - constructor(private caseSubscriptionService: CaseSubscriptionService) { } + constructor(private caseSubscriptionService: CaseSubscriptionService) {} @Mutation(() => Boolean, { nullable: true, diff --git a/libs/api/domains/form-system/project.json b/libs/api/domains/form-system/project.json index 2c19fe2b679f..870258868149 100644 --- a/libs/api/domains/form-system/project.json +++ b/libs/api/domains/form-system/project.json @@ -6,20 +6,14 @@ "targets": { "lint": { "executor": "@nx/linter:eslint", - "outputs": [ - "{options.outputFile}" - ], + "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": [ - "libs/api/domains/form-system/**/*.ts" - ] + "lintFilePatterns": ["libs/api/domains/form-system/**/*.ts"] } }, "test": { "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}" - ], + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "libs/api/domains/form-system/jest.config.ts", "passWithNoTests": true @@ -32,8 +26,5 @@ } } }, - "tags": [ - "lib:api", - "scope:api" - ] -} \ No newline at end of file + "tags": ["lib:api", "scope:api"] +} diff --git a/libs/api/domains/form-system/src/dto/applicantType.input.ts b/libs/api/domains/form-system/src/dto/applicantType.input.ts index 49c0decdc602..ad4daead51ac 100644 --- a/libs/api/domains/form-system/src/dto/applicantType.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantType.input.ts @@ -1,7 +1,6 @@ -import { Field, InputType, Int } from "@nestjs/graphql"; -import { LanguageTypeInput } from "./language.input"; -import { ApplicantTypeNameSuggestionInput } from "./applicantTypeNameSuggestion.input"; - +import { Field, InputType, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' +import { ApplicantTypeNameSuggestionInput } from './applicantTypeNameSuggestion.input' @InputType('FormSystemApplicantTypeInput') export class ApplicantTypeInput { @@ -38,4 +37,3 @@ export class FormApplicantTypeInput { @Field(() => String) type?: string | null } - diff --git a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts index 9d2c163327f9..0ab05ed0084f 100644 --- a/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts +++ b/libs/api/domains/form-system/src/dto/applicantTypeNameSuggestion.input.ts @@ -1,5 +1,5 @@ -import { InputType, Field, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" +import { InputType, Field, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' @InputType('FormSystemApplicantTypeNameSuggestionInput') export class ApplicantTypeNameSuggestionInput { diff --git a/libs/api/domains/form-system/src/dto/documentType.input.ts b/libs/api/domains/form-system/src/dto/documentType.input.ts index 3be1e25d546e..57f0c0c1ab19 100644 --- a/libs/api/domains/form-system/src/dto/documentType.input.ts +++ b/libs/api/domains/form-system/src/dto/documentType.input.ts @@ -1,7 +1,5 @@ -import { Field, Int, InputType } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" - - +import { Field, Int, InputType } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' @InputType('FormSystemDocumentTypeInput') export class DocumentTypeInput { diff --git a/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts index 79a6c486d569..f3715b15019e 100644 --- a/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts +++ b/libs/api/domains/form-system/src/dto/externalEndpoints.input.ts @@ -1,5 +1,8 @@ import { Field, Int, InputType, registerEnumType } from '@nestjs/graphql' -import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' +import { + EExternalEndpointType, + EExternalEndpointEnvironment, +} from '@island.is/clients/form-system' registerEnumType(EExternalEndpointType, { name: 'FormSystemExternalEndpointType', diff --git a/libs/api/domains/form-system/src/dto/forms.input.ts b/libs/api/domains/form-system/src/dto/forms.input.ts index ad1cf2ab265c..9170db1b2e99 100644 --- a/libs/api/domains/form-system/src/dto/forms.input.ts +++ b/libs/api/domains/form-system/src/dto/forms.input.ts @@ -1,13 +1,12 @@ -import { Field, InputType, Int } from "@nestjs/graphql" +import { Field, InputType, Int } from '@nestjs/graphql' import graphqlTypeJson from 'graphql-type-json' -import { LanguageTypeInput } from "./language.input" -import { InputInput } from "./inputs.input" -import { GroupInput } from "./groups.input" -import { StepInput } from "./steps.input" -import { FormApplicantTypeInput } from "./applicantType.input" -import { DocumentTypeInput } from "./documentType.input" -import { OrganizationInput } from "./organization.input" - +import { LanguageTypeInput } from './language.input' +import { InputInput } from './inputs.input' +import { GroupInput } from './groups.input' +import { StepInput } from './steps.input' +import { FormApplicantTypeInput } from './applicantType.input' +import { DocumentTypeInput } from './documentType.input' +import { OrganizationInput } from './organization.input' @InputType('FormSystemGetFormInput') export class GetFormInput { diff --git a/libs/api/domains/form-system/src/dto/groups.input.ts b/libs/api/domains/form-system/src/dto/groups.input.ts index d9957894ec5f..415eaf0b6bd3 100644 --- a/libs/api/domains/form-system/src/dto/groups.input.ts +++ b/libs/api/domains/form-system/src/dto/groups.input.ts @@ -1,7 +1,6 @@ -import { Field, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" -import { InputInput } from "./inputs.input" - +import { Field, InputType, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' +import { InputInput } from './inputs.input' @InputType('FormSystemGroupCreation') export class CreateGroup { diff --git a/libs/api/domains/form-system/src/dto/inputSettings.input.ts b/libs/api/domains/form-system/src/dto/inputSettings.input.ts index d35bf57506a0..65fe382e11f1 100644 --- a/libs/api/domains/form-system/src/dto/inputSettings.input.ts +++ b/libs/api/domains/form-system/src/dto/inputSettings.input.ts @@ -1,7 +1,6 @@ -import { InputType, Field, Int, Float } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" -import { ListItemInput } from "./listItem.input" - +import { InputType, Field, Int, Float } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' +import { ListItemInput } from './listItem.input' @InputType('FormSystemInputSettingsInput') export class InputSettingsInput { diff --git a/libs/api/domains/form-system/src/dto/inputs.input.ts b/libs/api/domains/form-system/src/dto/inputs.input.ts index 21dc96ff8845..16f9b1a9b11e 100644 --- a/libs/api/domains/form-system/src/dto/inputs.input.ts +++ b/libs/api/domains/form-system/src/dto/inputs.input.ts @@ -1,7 +1,7 @@ -import { Field, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" +import { Field, InputType, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' import graphqlTypeJson from 'graphql-type-json' -import { InputSettingsInput } from "./inputSettings.input" +import { InputSettingsInput } from './inputSettings.input' @InputType('FormSystemInputCreation') export class CreateInput { @@ -43,7 +43,6 @@ export class UpdateInput { @Field(() => Int, { nullable: true }) groupId?: number - } @InputType('FormSystemGetInputInput') @@ -114,4 +113,3 @@ export class InputInput { @Field(() => graphqlTypeJson, { nullable: true }) inputFields?: object } - diff --git a/libs/api/domains/form-system/src/dto/language.input.ts b/libs/api/domains/form-system/src/dto/language.input.ts index bd282bf0bc68..956c62adfd8f 100644 --- a/libs/api/domains/form-system/src/dto/language.input.ts +++ b/libs/api/domains/form-system/src/dto/language.input.ts @@ -1,4 +1,4 @@ -import { Field, InputType } from "@nestjs/graphql"; +import { Field, InputType } from '@nestjs/graphql' @InputType('FormSystemLanguageTypeInput') export class LanguageTypeInput { diff --git a/libs/api/domains/form-system/src/dto/listItem.input.ts b/libs/api/domains/form-system/src/dto/listItem.input.ts index 5ea06da5abd2..ec7069bb9c8a 100644 --- a/libs/api/domains/form-system/src/dto/listItem.input.ts +++ b/libs/api/domains/form-system/src/dto/listItem.input.ts @@ -1,5 +1,5 @@ -import { InputType, Field } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" +import { InputType, Field } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' @InputType('FormSystemListItemInput') export class ListItemInput { diff --git a/libs/api/domains/form-system/src/dto/listType.input.ts b/libs/api/domains/form-system/src/dto/listType.input.ts index 9f1aff48b853..cbf1e84a90f1 100644 --- a/libs/api/domains/form-system/src/dto/listType.input.ts +++ b/libs/api/domains/form-system/src/dto/listType.input.ts @@ -1,5 +1,5 @@ -import { Field, Int, InputType } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" +import { Field, Int, InputType } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' @InputType('FormSystemListTypeInput') export class ListTypeInput { diff --git a/libs/api/domains/form-system/src/dto/organization.input.ts b/libs/api/domains/form-system/src/dto/organization.input.ts index c8ed7c23be1a..68479727381d 100644 --- a/libs/api/domains/form-system/src/dto/organization.input.ts +++ b/libs/api/domains/form-system/src/dto/organization.input.ts @@ -1,11 +1,11 @@ -import { Field, Int, InputType } from "@nestjs/graphql" -import { InputInput } from "./inputs.input" -import { DocumentTypeInput } from "./documentType.input" -import { FormInput } from "./forms.input" -import { ApplicantTypeInput } from "./applicantType.input" -import { ListTypeInput } from "./listType.input" -import { ExternalEndpointsInput } from "./externalEndpoints.input" -import { LanguageTypeInput } from "./language.input" +import { Field, Int, InputType } from '@nestjs/graphql' +import { InputInput } from './inputs.input' +import { DocumentTypeInput } from './documentType.input' +import { FormInput } from './forms.input' +import { ApplicantTypeInput } from './applicantType.input' +import { ListTypeInput } from './listType.input' +import { ExternalEndpointsInput } from './externalEndpoints.input' +import { LanguageTypeInput } from './language.input' @InputType('FormSystemOrganizationCreation') export class CreateOrganization { diff --git a/libs/api/domains/form-system/src/dto/services.input.ts b/libs/api/domains/form-system/src/dto/services.input.ts index 6b3d714dd3a3..1e37aa380c2f 100644 --- a/libs/api/domains/form-system/src/dto/services.input.ts +++ b/libs/api/domains/form-system/src/dto/services.input.ts @@ -1,4 +1,4 @@ -import { Field, InputType } from "@nestjs/graphql"; +import { Field, InputType } from '@nestjs/graphql' @InputType('FormSystemGetPropertyInput') export class GetPropertyInput { diff --git a/libs/api/domains/form-system/src/dto/steps.input.ts b/libs/api/domains/form-system/src/dto/steps.input.ts index 7b9da446ce88..ded4fe3d22f0 100644 --- a/libs/api/domains/form-system/src/dto/steps.input.ts +++ b/libs/api/domains/form-system/src/dto/steps.input.ts @@ -1,6 +1,6 @@ -import { Field, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" -import { GroupInput } from "./groups.input" +import { Field, InputType, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' +import { GroupInput } from './groups.input' @InputType('FormSystemStepCreation') export class CreateStep { diff --git a/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts b/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts index 50b5f6f50fb0..1c6982b57514 100644 --- a/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts +++ b/libs/api/domains/form-system/src/dto/updateFormSettings.input.ts @@ -1,9 +1,8 @@ -import { Field, InputType, Int } from "@nestjs/graphql" -import { LanguageTypeInput } from "./language.input" +import { Field, InputType, Int } from '@nestjs/graphql' +import { LanguageTypeInput } from './language.input' import graphqlTypeJson from 'graphql-type-json' -import { DocumentTypeUpdateInput } from "./documentType.input" -import { FormApplicantTypeInput } from "./applicantType.input" - +import { DocumentTypeUpdateInput } from './documentType.input' +import { FormApplicantTypeInput } from './applicantType.input' @InputType('FormSystemFormSettingsInput') export class FormSettingsInput { diff --git a/libs/api/domains/form-system/src/lib/form-system.module.ts b/libs/api/domains/form-system/src/lib/form-system.module.ts index 0c7660bce862..939e1e9f28a5 100644 --- a/libs/api/domains/form-system/src/lib/form-system.module.ts +++ b/libs/api/domains/form-system/src/lib/form-system.module.ts @@ -27,12 +27,9 @@ import { StepsResolver } from './steps/steps.resolver' FormSystemService, FormSystemServicesResolver, StepsService, - StepsResolver + StepsResolver, ], exports: [], - imports: [ - AuthModule, - FormSystemClientModule - ] + imports: [AuthModule, FormSystemClientModule], }) -export class FormSystemModule { } +export class FormSystemModule {} diff --git a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts index 51baab83d7e3..dbe5fc101080 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.resolver.ts @@ -1,85 +1,90 @@ -import { Args, Mutation, Query, Resolver } from "@nestjs/graphql" -import { FormsService } from "./forms.service" -import { FormResponse } from "../../models/formResponse.model" -import { CreateFormInput, GetFormInput, GetFormsInput, UpdateFormInput, DeleteFormInput } from "../../dto/forms.input" -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { FormListResponse } from "../../models/formListResponse.model" +import { Args, Mutation, Query, Resolver } from '@nestjs/graphql' +import { FormsService } from './forms.service' +import { FormResponse } from '../../models/formResponse.model' +import { + CreateFormInput, + GetFormInput, + GetFormsInput, + UpdateFormInput, + DeleteFormInput, +} from '../../dto/forms.input' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { FormListResponse } from '../../models/formListResponse.model' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common" -import { UpdateFormSettingsInput } from "../../dto/updateFormSettings.input" - - +import { UseGuards } from '@nestjs/common' +import { UpdateFormSettingsInput } from '../../dto/updateFormSettings.input' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class FormsResolver { - constructor(private readonly formsService: FormsService) { } + constructor(private readonly formsService: FormsService) {} @Query(() => FormResponse, { - name: 'formSystemGetForm' + name: 'formSystemGetForm', }) async getForm( @Args('input', { type: () => GetFormInput }) input: GetFormInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.formsService.getForm(user, input) } @Query(() => FormListResponse, { - name: 'formSystemGetForms' + name: 'formSystemGetForms', }) async getForms( @Args('input', { type: () => GetFormsInput }) input: GetFormsInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.formsService.getForms(user, input) } @Mutation(() => FormResponse, { - name: 'formSystemCreateForm' + name: 'formSystemCreateForm', }) async createForm( @Args('input', { type: () => CreateFormInput }) input: CreateFormInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.formsService.postForm(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemUpdateForm' + name: 'formSystemUpdateForm', }) async updateForm( @Args('input', { type: () => UpdateFormInput }) input: UpdateFormInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.formsService.updateForm(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemUpdateFormSettings' + name: 'formSystemUpdateFormSettings', }) async updateFormSettings( - @Args('input', { type: () => UpdateFormSettingsInput }) input: UpdateFormSettingsInput, - @CurrentUser() user: User + @Args('input', { type: () => UpdateFormSettingsInput }) + input: UpdateFormSettingsInput, + @CurrentUser() user: User, ): Promise { return this.formsService.updateFormSettings(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemDeleteForm' + name: 'formSystemDeleteForm', }) async deleteForm( @Args('input', { type: () => DeleteFormInput }) input: DeleteFormInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return await this.formsService.deleteForm(user, input) } - - } - - diff --git a/libs/api/domains/form-system/src/lib/forms/forms.service.ts b/libs/api/domains/form-system/src/lib/forms/forms.service.ts index 68a30c1e459d..be5d4c50952f 100644 --- a/libs/api/domains/form-system/src/lib/forms/forms.service.ts +++ b/libs/api/domains/form-system/src/lib/forms/forms.service.ts @@ -1,15 +1,28 @@ -import { Inject, Injectable } from "@nestjs/common" +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApiFormsFormIdDeleteRequest, ApiFormsFormIdGetRequest, ApiFormsFormIdPutRequest, ApiFormsOrganizationOrganizationIdGetRequest, FormUpdateDto, FormsApi, ApiFormsFormIdSettingsPutRequest, FormSettingsUpdateDto } from "@island.is/clients/form-system" -import { ApolloError } from "@apollo/client" +import { + ApiFormsFormIdDeleteRequest, + ApiFormsFormIdGetRequest, + ApiFormsFormIdPutRequest, + ApiFormsOrganizationOrganizationIdGetRequest, + FormUpdateDto, + FormsApi, + ApiFormsFormIdSettingsPutRequest, + FormSettingsUpdateDto, +} from '@island.is/clients/form-system' +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { CreateFormInput, DeleteFormInput, GetFormInput, GetFormsInput, UpdateFormInput } from "../../dto/forms.input" -import { FormResponse } from "../../models/formResponse.model" -import { FormListResponse } from "../../models/formListResponse.model" -import { UpdateFormSettingsInput } from "../../dto/updateFormSettings.input" -import { InputSettings } from "../../models/inputSettings.model" - - +import { + CreateFormInput, + DeleteFormInput, + GetFormInput, + GetFormsInput, + UpdateFormInput, +} from '../../dto/forms.input' +import { FormResponse } from '../../models/formResponse.model' +import { FormListResponse } from '../../models/formListResponse.model' +import { UpdateFormSettingsInput } from '../../dto/updateFormSettings.input' +import { InputSettings } from '../../models/inputSettings.model' @Injectable() export class FormsService { @@ -17,12 +30,12 @@ export class FormsService { @Inject(LOGGER_PROVIDER) private logger: Logger, private formsApi: FormsApi, - ) { } + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'forms-service' + category: 'forms-service', } this.logger.error(errorDetail || 'Error in forms service', err) @@ -40,7 +53,6 @@ export class FormsService { return this.formsApi.withMiddleware(new AuthMiddleware(auth)) } - async getForm(auth: User, input: GetFormInput): Promise { const request: ApiFormsFormIdGetRequest = { formId: input.id, @@ -75,13 +87,14 @@ export class FormsService { } const response = await this.formsApiWithAuth(auth) .apiFormsOrganizationOrganizationIdGet(request) - .catch((e) => this.handle4xx(e, 'failed to get forms from organization Id')) + .catch((e) => + this.handle4xx(e, 'failed to get forms from organization Id'), + ) if (!response || response instanceof ApolloError) { return {} } - return response as FormListResponse } @@ -120,7 +133,7 @@ export class FormsService { id: input.formId, inputsList: input.form?.inputsList?.map((input) => { return input - }) + }), } const request: ApiFormsFormIdPutRequest = { @@ -140,12 +153,15 @@ export class FormsService { return response } - async updateFormSettings(auth: User, input: UpdateFormSettingsInput): Promise { + async updateFormSettings( + auth: User, + input: UpdateFormSettingsInput, + ): Promise { const request: ApiFormsFormIdSettingsPutRequest = { formId: input.id, - formSettingsUpdateDto: input.formSettingsUpdateDto as FormSettingsUpdateDto + formSettingsUpdateDto: + input.formSettingsUpdateDto as FormSettingsUpdateDto, } - console.log('updateFormSettings request', request) const response = await this.formsApiWithAuth(auth) .apiFormsFormIdSettingsPut(request) .catch((e) => this.handle4xx(e, 'failed to update form settings')) diff --git a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts index 3d71b5e3aaff..285eb51d5496 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.resolver.ts @@ -1,55 +1,64 @@ -import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { GroupsService } from "./groups.service"; -import { GetGroupInput, CreateGroupInput, DeleteGroupInput, UpdateGroupInput } from "../../dto/groups.input"; -import { Group } from "../../models/group.model"; +import { Query, Args, Resolver, Mutation } from '@nestjs/graphql' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { GroupsService } from './groups.service' +import { + GetGroupInput, + CreateGroupInput, + DeleteGroupInput, + UpdateGroupInput, +} from '../../dto/groups.input' +import { Group } from '../../models/group.model' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common"; +import { UseGuards } from '@nestjs/common' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class GroupsResolver { - constructor(private readonly groupsService: GroupsService) { } + constructor(private readonly groupsService: GroupsService) {} @Query(() => Group, { - name: 'formSystemGetGroup' + name: 'formSystemGetGroup', }) async getGroup( @Args('input', { type: () => GetGroupInput }) input: GetGroupInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.groupsService.getGroup(user, input) } @Mutation(() => Group, { - name: 'formSystemCreateGroup' + name: 'formSystemCreateGroup', }) async postGroup( @Args('input', { type: () => CreateGroupInput }) input: CreateGroupInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.groupsService.postGroup(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemDeleteGroup' + name: 'formSystemDeleteGroup', }) async deleteGroup( @Args('input', { type: () => DeleteGroupInput }) input: DeleteGroupInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return await this.groupsService.deleteGroup(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemUpdateGroup' + name: 'formSystemUpdateGroup', }) async updateGroup( @Args('input', { type: () => UpdateGroupInput }) input: UpdateGroupInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.groupsService.updateGroup(user, input) } diff --git a/libs/api/domains/form-system/src/lib/groups/groups.service.ts b/libs/api/domains/form-system/src/lib/groups/groups.service.ts index bd791b5045c7..4a6b2a0b0a92 100644 --- a/libs/api/domains/form-system/src/lib/groups/groups.service.ts +++ b/libs/api/domains/form-system/src/lib/groups/groups.service.ts @@ -1,23 +1,36 @@ -import { Inject, Injectable } from "@nestjs/common" +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApolloError } from "@apollo/client" +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { GroupsApi, ApiGroupsGroupIdGetRequest, ApiGroupsPostRequest, ApiGroupsGroupIdDeleteRequest, ApiGroupsGroupIdPutRequest, GroupCreationDto, GroupUpdateDto } from "@island.is/clients/form-system" -import { GetGroupInput, CreateGroupInput, DeleteGroupInput, UpdateGroupInput } from "../../dto/groups.input" -import { Group } from "../../models/group.model" +import { + GroupsApi, + ApiGroupsGroupIdGetRequest, + ApiGroupsPostRequest, + ApiGroupsGroupIdDeleteRequest, + ApiGroupsGroupIdPutRequest, + GroupCreationDto, + GroupUpdateDto, +} from '@island.is/clients/form-system' +import { + GetGroupInput, + CreateGroupInput, + DeleteGroupInput, + UpdateGroupInput, +} from '../../dto/groups.input' +import { Group } from '../../models/group.model' @Injectable() export class GroupsService { constructor( @Inject(LOGGER_PROVIDER) private logger: Logger, - private formsApi: GroupsApi - ) { } + private formsApi: GroupsApi, + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'groups-service' + category: 'groups-service', } this.logger.error(errorDetail || 'Error in groups service', err) @@ -80,9 +93,8 @@ export class GroupsService { async updateGroup(auth: User, input: UpdateGroupInput): Promise { const request: ApiGroupsGroupIdPutRequest = { groupId: input.groupId, - groupUpdateDto: input.groupUpdateDto as GroupUpdateDto + groupUpdateDto: input.groupUpdateDto as GroupUpdateDto, } - console.log('groups update request: ', request) const response = await this.groupsApiWithAuth(auth) .apiGroupsGroupIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update group')) diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts index e45945ad0122..3e6645025689 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.resolver.ts @@ -1,44 +1,53 @@ -import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { GetInputInput, CreateInputInput, DeleteInputInput, UpdateInputInput } from "../../dto/inputs.input"; -import { Input } from "../../models/input.model"; -import { InputsService } from "./inputs.service"; +import { Query, Args, Resolver, Mutation } from '@nestjs/graphql' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { + GetInputInput, + CreateInputInput, + DeleteInputInput, + UpdateInputInput, +} from '../../dto/inputs.input' +import { Input } from '../../models/input.model' +import { InputsService } from './inputs.service' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common"; +import { UseGuards } from '@nestjs/common' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class InputsResolver { - constructor(private readonly inputsService: InputsService) { } + constructor(private readonly inputsService: InputsService) {} @Query(() => Input, { - name: 'formSystemGetInput' + name: 'formSystemGetInput', }) async getInput( @Args('input', { type: () => GetInputInput }) input: GetInputInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.inputsService.getInput(user, input) } @Mutation(() => Input, { - name: 'formSystemCreateInput' + name: 'formSystemCreateInput', }) async postInput( @Args('input', { type: () => CreateInputInput }) input: CreateInputInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.inputsService.postInput(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemDeleteInput' + name: 'formSystemDeleteInput', }) async deleteInput( @Args('input', { type: () => DeleteInputInput }) input: DeleteInputInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { const response = await this.inputsService.deleteInput(user, input) return response @@ -46,11 +55,11 @@ export class InputsResolver { @Mutation(() => Boolean, { nullable: true, - name: 'formSystemUpdateInput' + name: 'formSystemUpdateInput', }) async updateInput( @Args('input', { type: () => UpdateInputInput }) input: UpdateInputInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.inputsService.updateInput(user, input) } diff --git a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts index bf7d12c63704..0eac27ee5916 100644 --- a/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts +++ b/libs/api/domains/form-system/src/lib/inputs/inputs.service.ts @@ -1,10 +1,23 @@ -import { Inject, Injectable } from "@nestjs/common" +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApolloError } from "@apollo/client" +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { InputsApi, ApiInputsInputIdGetRequest, ApiInputsPostRequest, ApiInputsInputIdDeleteRequest, ApiInputsInputIdPutRequest, InputCreationDto, InputUpdateDto } from "@island.is/clients/form-system" -import { GetInputInput, CreateInputInput, DeleteInputInput, UpdateInputInput } from "../../dto/inputs.input" -import { Input } from "../../models/input.model" +import { + InputsApi, + ApiInputsInputIdGetRequest, + ApiInputsPostRequest, + ApiInputsInputIdDeleteRequest, + ApiInputsInputIdPutRequest, + InputCreationDto, + InputUpdateDto, +} from '@island.is/clients/form-system' +import { + GetInputInput, + CreateInputInput, + DeleteInputInput, + UpdateInputInput, +} from '../../dto/inputs.input' +import { Input } from '../../models/input.model' // import { graphql } from "graphql" // import { RESTInputSettings, graphqlToRestInputSettings, restToGraphqlInputSettings } from "../utils/helperFunctions" // import { InputSettings } from "../../models/inputSettings.model" @@ -14,13 +27,13 @@ export class InputsService { constructor( @Inject(LOGGER_PROVIDER) private logger: Logger, - private formsApi: InputsApi - ) { } + private formsApi: InputsApi, + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'inputs-service' + category: 'inputs-service', } this.logger.error(errorDetail || 'Error in inputs service', err) @@ -66,7 +79,6 @@ export class InputsService { if (!response || response instanceof ApolloError) { return {} } - console.log('Post input response', response) return response as Input } @@ -86,25 +98,16 @@ export class InputsService { } async updateInput(auth: User, input: UpdateInputInput): Promise { - // const request: ApiInputsInputIdPutRequest = { - // inputId: input.inputId, - // inputUpdateDto: { - // ...input.inputUpdateDto, - // inputSettings: graphqlToRestInputSettings(input.inputUpdateDto?.inputSettings as InputSettings) - // } as InputUpdateDto, - // } let request: ApiInputsInputIdPutRequest = { inputId: input.inputId, - inputUpdateDto: input.inputUpdateDto as InputUpdateDto + inputUpdateDto: input.inputUpdateDto as InputUpdateDto, } if (input.inputUpdateDto) { request = { inputId: input.inputId, - inputUpdateDto: input.inputUpdateDto + inputUpdateDto: input.inputUpdateDto, } } - - console.log('request Input update', request) const response = await this.inputsApiWithAuth(auth) .apiInputsInputIdPut(request) .catch((e) => this.handle4xx(e, 'failed to update input')) diff --git a/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts b/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts index 7f09f5d93364..ded9859a34e3 100644 --- a/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts +++ b/libs/api/domains/form-system/src/lib/organizations/organizations.resolver.ts @@ -1,25 +1,28 @@ -import { Args, Mutation, Resolver } from "@nestjs/graphql"; -import { OrganizationsService } from "./organizations.services"; -import { CreateOrganizationInput } from "../../dto/organization.input"; -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { Organization } from "../../models/organization.model"; +import { Args, Mutation, Resolver } from '@nestjs/graphql' +import { OrganizationsService } from './organizations.services' +import { CreateOrganizationInput } from '../../dto/organization.input' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { Organization } from '../../models/organization.model' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common"; - - +import { UseGuards } from '@nestjs/common' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class OrganizationsResolver { - constructor(private readonly organizationsService: OrganizationsService) { } + constructor(private readonly organizationsService: OrganizationsService) {} @Mutation(() => Organization, { - name: 'formSystemCreateOrganization' + name: 'formSystemCreateOrganization', }) async postOrganization( - @Args('input', { type: () => CreateOrganizationInput }) input: CreateOrganizationInput, - @CurrentUser() user: User + @Args('input', { type: () => CreateOrganizationInput }) + input: CreateOrganizationInput, + @CurrentUser() user: User, ): Promise { return this.organizationsService.postOrganization(user, input) } diff --git a/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts b/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts index b624ac511d98..e831d58ced94 100644 --- a/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts +++ b/libs/api/domains/form-system/src/lib/organizations/organizations.services.ts @@ -1,23 +1,26 @@ -import { Inject, Injectable } from "@nestjs/common" +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApolloError } from "@apollo/client" +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { ApiOrganizationsPostRequest, OrganizationsApi } from "@island.is/clients/form-system" -import { CreateOrganizationInput } from "../../dto/organization.input" -import { Organization } from "../../models/organization.model" +import { + ApiOrganizationsPostRequest, + OrganizationsApi, +} from '@island.is/clients/form-system' +import { CreateOrganizationInput } from '../../dto/organization.input' +import { Organization } from '../../models/organization.model' @Injectable() export class OrganizationsService { constructor( @Inject(LOGGER_PROVIDER) private logger: Logger, - private organizationsApi: OrganizationsApi - ) { } + private organizationsApi: OrganizationsApi, + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'organizations-service' + category: 'organizations-service', } this.logger.error(errorDetail || 'Error in organizations service', err) @@ -35,7 +38,10 @@ export class OrganizationsService { return this.organizationsApi.withMiddleware(new AuthMiddleware(auth)) } - async postOrganization(auth: User, input: CreateOrganizationInput): Promise { + async postOrganization( + auth: User, + input: CreateOrganizationInput, + ): Promise { const request: ApiOrganizationsPostRequest = { organizationCreationDto: { name: input.name, diff --git a/libs/api/domains/form-system/src/lib/services/services.resolver.ts b/libs/api/domains/form-system/src/lib/services/services.resolver.ts index 8eb9648ff03b..1ba7e31fdf96 100644 --- a/libs/api/domains/form-system/src/lib/services/services.resolver.ts +++ b/libs/api/domains/form-system/src/lib/services/services.resolver.ts @@ -1,69 +1,62 @@ -import { Query, Args, Resolver } from "@nestjs/graphql"; -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { FormSystemService } from "./services.service"; -import { List } from "../../models/services.model"; -import { GetPropertyInput } from "../../dto/services.input"; +import { Query, Args, Resolver } from '@nestjs/graphql' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { FormSystemService } from './services.service' +import { List } from '../../models/services.model' +import { GetPropertyInput } from '../../dto/services.input' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common"; - +import { UseGuards } from '@nestjs/common' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class FormSystemServicesResolver { - constructor(private readonly formSystemServices: FormSystemService) { } + constructor(private readonly formSystemServices: FormSystemService) {} @Query(() => List, { - name: 'formSystemGetCountries' + name: 'formSystemGetCountries', }) - async getCountries( - @CurrentUser() user: User - ): Promise { + async getCountries(@CurrentUser() user: User): Promise { return this.formSystemServices.getCountries(user) } @Query(() => List, { - name: 'formSystemGetZipCodes' + name: 'formSystemGetZipCodes', }) - async getZipCodes( - @CurrentUser() user: User - ): Promise { + async getZipCodes(@CurrentUser() user: User): Promise { return this.formSystemServices.getZipCodes(user) } @Query(() => List, { - name: 'formSystemGetMunicipalities' + name: 'formSystemGetMunicipalities', }) - async getMunicipalities( - @CurrentUser() user: User - ): Promise { + async getMunicipalities(@CurrentUser() user: User): Promise { return this.formSystemServices.getMunicipalities(user) } @Query(() => List, { - name: 'formSystemGetRegistrationCategories' + name: 'formSystemGetRegistrationCategories', }) - async getRegistrationCategories( - @CurrentUser() user: User - ): Promise { + async getRegistrationCategories(@CurrentUser() user: User): Promise { return this.formSystemServices.getRegistrationCategories(user) } @Query(() => List, { - name: 'formSystemGetTradesProfessions' + name: 'formSystemGetTradesProfessions', }) - async getTradesProfessions( - @CurrentUser() user: User - ): Promise { + async getTradesProfessions(@CurrentUser() user: User): Promise { return this.formSystemServices.getTradesProfessions(user) } @Query(() => List, { - name: 'formSystemGetProperty' + name: 'formSystemGetProperty', }) async getProperty( @Args('input', { type: () => GetPropertyInput }) input: GetPropertyInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.formSystemServices.getProperty(user, input) } diff --git a/libs/api/domains/form-system/src/lib/services/services.service.ts b/libs/api/domains/form-system/src/lib/services/services.service.ts index a6a40a625748..01cc128c4544 100644 --- a/libs/api/domains/form-system/src/lib/services/services.service.ts +++ b/libs/api/domains/form-system/src/lib/services/services.service.ts @@ -1,23 +1,26 @@ -import { Inject, Injectable } from "@nestjs/common"; +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApolloError } from "@apollo/client" +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { ApiServicesFasteignFasteignanumerGetRequest, ServicesApi } from "@island.is/clients/form-system" -import { List } from "../../models/services.model"; -import { GetPropertyInput } from "../../dto/services.input"; +import { + ApiServicesFasteignFasteignanumerGetRequest, + ServicesApi, +} from '@island.is/clients/form-system' +import { List } from '../../models/services.model' +import { GetPropertyInput } from '../../dto/services.input' @Injectable() export class FormSystemService { constructor( @Inject(LOGGER_PROVIDER) private logger: Logger, - private servicesApi: ServicesApi - ) { } + private servicesApi: ServicesApi, + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'services-service' + category: 'services-service', } this.logger.error(errorDetail || 'Error in services service', err) diff --git a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts index edfd08429eb7..88f46a9a5ec6 100644 --- a/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts +++ b/libs/api/domains/form-system/src/lib/steps/steps.resolver.ts @@ -1,56 +1,64 @@ -import { Query, Args, Resolver, Mutation } from "@nestjs/graphql"; -import { CurrentUser, IdsUserGuard, type User } from '@island.is/auth-nest-tools' -import { CreateStepInput, DeleteStepInput, GetStepInput, UpdateStepInput } from "../../dto/steps.input"; -import { Step } from "../../models/step.model"; -import { StepsService } from "./steps.service"; +import { Query, Args, Resolver, Mutation } from '@nestjs/graphql' +import { + CurrentUser, + IdsUserGuard, + type User, +} from '@island.is/auth-nest-tools' +import { + CreateStepInput, + DeleteStepInput, + GetStepInput, + UpdateStepInput, +} from '../../dto/steps.input' +import { Step } from '../../models/step.model' +import { StepsService } from './steps.service' import { Audit } from '@island.is/nest/audit' -import { UseGuards } from "@nestjs/common"; - +import { UseGuards } from '@nestjs/common' @Resolver() @UseGuards(IdsUserGuard) @Audit({ namespace: '@island.is/api/form-system' }) export class StepsResolver { - constructor(private readonly stepsService: StepsService) { } + constructor(private readonly stepsService: StepsService) {} @Query(() => Step, { - name: 'formSystemGetStep' + name: 'formSystemGetStep', }) async getStep( @Args('input', { type: () => GetStepInput }) input: GetStepInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.stepsService.getStep(user, input) } @Mutation(() => Step, { - name: 'formSystemCreateStep' + name: 'formSystemCreateStep', }) async postStep( @Args('input', { type: () => CreateStepInput }) input: CreateStepInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.stepsService.postStep(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemDeleteStep' + name: 'formSystemDeleteStep', }) async deleteStep( @Args('input', { type: () => DeleteStepInput }) input: DeleteStepInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return await this.stepsService.deleteStep(user, input) } @Mutation(() => Boolean, { nullable: true, - name: 'formSystemUpdateStep' + name: 'formSystemUpdateStep', }) async updateStep( @Args('input', { type: () => UpdateStepInput }) input: UpdateStepInput, - @CurrentUser() user: User + @CurrentUser() user: User, ): Promise { return this.stepsService.updateStep(user, input) } diff --git a/libs/api/domains/form-system/src/lib/steps/steps.service.ts b/libs/api/domains/form-system/src/lib/steps/steps.service.ts index 6b46bc31740a..dfc46c148314 100644 --- a/libs/api/domains/form-system/src/lib/steps/steps.service.ts +++ b/libs/api/domains/form-system/src/lib/steps/steps.service.ts @@ -1,23 +1,34 @@ -import { Inject, Injectable } from "@nestjs/common" +import { Inject, Injectable } from '@nestjs/common' import { LOGGER_PROVIDER, Logger } from '@island.is/logging' -import { ApiStepsPostRequest, ApiStepsStepIdDeleteRequest, ApiStepsStepIdGetRequest, ApiStepsStepIdPutRequest, StepsApi } from "@island.is/clients/form-system" -import { ApolloError } from "@apollo/client" +import { + ApiStepsPostRequest, + ApiStepsStepIdDeleteRequest, + ApiStepsStepIdGetRequest, + ApiStepsStepIdPutRequest, + StepsApi, +} from '@island.is/clients/form-system' +import { ApolloError } from '@apollo/client' import { AuthMiddleware, User } from '@island.is/auth-nest-tools' -import { CreateStepInput, DeleteStepInput, GetStepInput, UpdateStepInput } from "../../dto/steps.input" -import { Step } from "../../models/step.model" +import { + CreateStepInput, + DeleteStepInput, + GetStepInput, + UpdateStepInput, +} from '../../dto/steps.input' +import { Step } from '../../models/step.model' @Injectable() export class StepsService { constructor( @Inject(LOGGER_PROVIDER) private logger: Logger, - private formsApi: StepsApi - ) { } + private formsApi: StepsApi, + ) {} handleError(error: any, errorDetail?: string): ApolloError | null { const err = { error: JSON.stringify(error), - category: 'steps-service' + category: 'steps-service', } this.logger.error(errorDetail || 'Error in steps service', err) @@ -80,7 +91,7 @@ export class StepsService { async updateStep(auth: User, input: UpdateStepInput): Promise { const request: ApiStepsStepIdPutRequest = { stepId: input.stepId, - stepUpdateDto: input.stepUpdateDto + stepUpdateDto: input.stepUpdateDto, } const response = await this.stepsApiWithAuth(auth) diff --git a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts b/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts deleted file mode 100644 index 6bc41d718526..000000000000 --- a/libs/api/domains/form-system/src/lib/utils/helperFunctions.ts +++ /dev/null @@ -1,124 +0,0 @@ -// import { LanguageType } from "../../models/global.model" -// import { InputSettings, ListItem } from "../../models/inputSettings.model" -import { InputUpdateDto } from "@island.is/clients/form-system" -import { Input } from "../../models/input.model"; - -// export interface RESTInputSettings { -// isLarge?: boolean -// size?: string -// interval?: string -// erHlekkur?: boolean -// url?: string -// hnapptexti?: LanguageType -// tegundir?: string[] -// hamarksstaerd?: number -// erFjolval?: boolean -// fjoldi?: number -// header?: string -// hamarkslengd?: number -// lagmarkslengd?: number -// laggildi?: number -// hagildi?: number -// listi?: ListItem[] -// $type?: string -// name?: LanguageType -// erListi?: boolean -// erInnslattur?: boolean -// [key: string]: unknown -// } - -// interface GraphQLInputSettings { -// hasInput?: boolean -// isList?: boolean -// isLarge?: boolean -// size?: string -// interval?: string -// list?: ListItem[] -// max?: number -// min?: number -// maxLength?: number -// minLength?: number -// amount?: number -// isMulti?: boolean -// maxSize?: number -// types?: string[] -// buttonText?: LanguageType -// hasLink?: boolean -// $type?: string -// name?: LanguageType -// [key: string]: unknown -// } - -// export const restToGraphqlInputSettings = (input?: RESTInputSettings): GraphQLInputSettings => { -// return { -// hasInput: input?.erInnslattur, -// isList: input?.erListi, -// isLarge: input?.isLarge, -// size: input?.size, -// interval: input?.interval, -// list: input?.listi, -// max: input?.hagildi, -// min: input?.laggildi, -// maxLength: input?.hamarkslengd, -// minLength: input?.lagmarkslengd, -// amount: input?.fjoldi, -// isMulti: input?.erFjolval, -// maxSize: input?.hamarksstaerd, -// types: input?.tegundir, -// buttonText: input?.hnapptexti, -// hasLink: input?.erHlekkur, -// type: input?.type, -// name: input?.name, -// } -// } - -// export const graphqlToRestInputSettings = (input?: InputSettings): RESTInputSettings => { -// return { -// erInnslattur: input?.hasInput, -// erListi: input?.isList, -// isLarge: input?.isLarge, -// size: input?.size, -// interval: input?.interval, -// listi: input?.list, -// hagildi: input?.max, -// laggildi: input?.min, -// hamarkslengd: input?.maxLength, -// lagmarkslengd: input?.minLength, -// fjoldi: input?.amount, -// erFjolval: input?.isMulti, -// hamarksstaerd: input?.maxSize, -// tegundir: input?.types, -// hnapptexti: input?.buttonText, -// erHlekkur: input?.hasLink, -// type: input?.type, -// name: input?.name, -// } -// } - -// export const addType = (input: Input | InputUpdateDto) => { -// const types = ['TextaInnsláttur', 'Textalýsing', 'Fellilisti', 'Valhnappar', 'Skjal', 'Tölustafir', 'Fasteignanúmer', 'Klukkinnsláttur', 'Dagssetningarval'] -// const type = { -// TextaInnsláttur: 'texti', -// Textalýsing: 'textalysing', -// Fellilisti: 'fellilisti', -// Valhnappar: 'valhnappar', -// Skjal: 'skjal', -// Tölustafir: 'tolustafir', -// Fasteignanúmer: 'fasteignanumer', -// Klukkinnsláttur: 'klukkinnslattur', -// Dagssetningarval: 'dagssetningarval', -// } -// if (input.type !== null && input.type !== undefined) { -// if (types.includes(input.type)) { -// const newInputSettings = { -// ...input.inputSettings, -// $type: type[input.type as keyof typeof type] -// } -// return { -// ...input, -// inputSettings: newInputSettings, -// } -// } -// } -// return input -// } diff --git a/libs/api/domains/form-system/src/models/applicantType.model.ts b/libs/api/domains/form-system/src/models/applicantType.model.ts index 9e480c74bf84..a993d5788685 100644 --- a/libs/api/domains/form-system/src/models/applicantType.model.ts +++ b/libs/api/domains/form-system/src/models/applicantType.model.ts @@ -1,6 +1,6 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; -import { ApplicantTypeNameSuggestion } from "./applicantTypeNameSuggestion"; +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' +import { ApplicantTypeNameSuggestion } from './applicantTypeNameSuggestion' @ObjectType('FormSystemApplicantType') export class ApplicantType { diff --git a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts index 2d7c4d2d195a..70bf81bec13f 100644 --- a/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts +++ b/libs/api/domains/form-system/src/models/applicantTypeNameSuggestion.ts @@ -1,6 +1,5 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; - +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' @ObjectType('FormSystemApplicantTypeNameSuggestion') export class ApplicantTypeNameSuggestion { diff --git a/libs/api/domains/form-system/src/models/documentType.model.ts b/libs/api/domains/form-system/src/models/documentType.model.ts index 8fa4a045c200..e5772e16ab3e 100644 --- a/libs/api/domains/form-system/src/models/documentType.model.ts +++ b/libs/api/domains/form-system/src/models/documentType.model.ts @@ -1,5 +1,5 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' @ObjectType('FormSystemDocumentType') export class DocumentType { @@ -15,5 +15,3 @@ export class DocumentType { @Field(() => LanguageType, { nullable: true }) description?: LanguageType } - - diff --git a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts index abbdf6065268..bfa3d426e1cc 100644 --- a/libs/api/domains/form-system/src/models/externalEndpoints.model.ts +++ b/libs/api/domains/form-system/src/models/externalEndpoints.model.ts @@ -1,5 +1,8 @@ import { Field, Int, ObjectType, registerEnumType } from '@nestjs/graphql' -import { EExternalEndpointType, EExternalEndpointEnvironment } from '@island.is/clients/form-system' +import { + EExternalEndpointType, + EExternalEndpointEnvironment, +} from '@island.is/clients/form-system' registerEnumType(EExternalEndpointType, { name: 'FormSystemExternalEndpointType', diff --git a/libs/api/domains/form-system/src/models/formApplicantType.model.ts b/libs/api/domains/form-system/src/models/formApplicantType.model.ts index 8264b7f434d9..e00f95180eb9 100644 --- a/libs/api/domains/form-system/src/models/formApplicantType.model.ts +++ b/libs/api/domains/form-system/src/models/formApplicantType.model.ts @@ -1,6 +1,5 @@ -import { ObjectType, Field, Int } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; - +import { ObjectType, Field, Int } from '@nestjs/graphql' +import { LanguageType } from './global.model' @ObjectType('FormSystemFormApplicantType') export class FormApplicantType { diff --git a/libs/api/domains/form-system/src/models/formListResponse.model.ts b/libs/api/domains/form-system/src/models/formListResponse.model.ts index b293420430f0..e8cd56996b60 100644 --- a/libs/api/domains/form-system/src/models/formListResponse.model.ts +++ b/libs/api/domains/form-system/src/models/formListResponse.model.ts @@ -1,5 +1,5 @@ -import { Field, ObjectType } from "@nestjs/graphql"; -import { Form } from "./form.model"; +import { Field, ObjectType } from '@nestjs/graphql' +import { Form } from './form.model' @ObjectType('FormSystemFormListResponse') export class FormListResponse { diff --git a/libs/api/domains/form-system/src/models/group.model.ts b/libs/api/domains/form-system/src/models/group.model.ts index e742b2bc7e63..3f383cd90b1d 100644 --- a/libs/api/domains/form-system/src/models/group.model.ts +++ b/libs/api/domains/form-system/src/models/group.model.ts @@ -1,6 +1,6 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; -import { Input } from "./input.model"; +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' +import { Input } from './input.model' @ObjectType('FormSystemGroup') export class Group { @@ -31,4 +31,3 @@ export class Group { @Field(() => String, { nullable: true }) stepGuid?: string } - diff --git a/libs/api/domains/form-system/src/models/input.model.ts b/libs/api/domains/form-system/src/models/input.model.ts index 0936d7e7f5d9..26abc1337a6a 100644 --- a/libs/api/domains/form-system/src/models/input.model.ts +++ b/libs/api/domains/form-system/src/models/input.model.ts @@ -45,5 +45,3 @@ export class Input { @Field(() => graphqlTypeJson, { nullable: true }) inputFields?: object } - - diff --git a/libs/api/domains/form-system/src/models/listType.model.ts b/libs/api/domains/form-system/src/models/listType.model.ts index c89a60f9b02d..8950a228c8f4 100644 --- a/libs/api/domains/form-system/src/models/listType.model.ts +++ b/libs/api/domains/form-system/src/models/listType.model.ts @@ -1,6 +1,5 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; - +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' @ObjectType('FormSystemListType') export class ListType { diff --git a/libs/api/domains/form-system/src/models/organization.model.ts b/libs/api/domains/form-system/src/models/organization.model.ts index 59f890027be3..58bbce16d67f 100644 --- a/libs/api/domains/form-system/src/models/organization.model.ts +++ b/libs/api/domains/form-system/src/models/organization.model.ts @@ -36,5 +36,3 @@ export class Organization { @Field(() => [ExternalEndpoints], { nullable: 'itemsAndList' }) externalEndpoints?: ExternalEndpoints[] | null } - - diff --git a/libs/api/domains/form-system/src/models/services.model.ts b/libs/api/domains/form-system/src/models/services.model.ts index 89fe7f21329a..3470c93d85b3 100644 --- a/libs/api/domains/form-system/src/models/services.model.ts +++ b/libs/api/domains/form-system/src/models/services.model.ts @@ -1,6 +1,5 @@ -import { Field, ObjectType } from "@nestjs/graphql"; -import { ListItem } from "./inputSettings.model"; - +import { Field, ObjectType } from '@nestjs/graphql' +import { ListItem } from './inputSettings.model' @ObjectType('FormSystemList') export class List { diff --git a/libs/api/domains/form-system/src/models/step.model.ts b/libs/api/domains/form-system/src/models/step.model.ts index 078b28382eb7..771bd73c542a 100644 --- a/libs/api/domains/form-system/src/models/step.model.ts +++ b/libs/api/domains/form-system/src/models/step.model.ts @@ -1,6 +1,6 @@ -import { Field, Int, ObjectType } from "@nestjs/graphql"; -import { LanguageType } from "./global.model"; -import { Group } from "./group.model"; +import { Field, Int, ObjectType } from '@nestjs/graphql' +import { LanguageType } from './global.model' +import { Group } from './group.model' @ObjectType('FormSystemStep') export class Step { @@ -34,4 +34,3 @@ export class Step { @Field(() => [Group], { nullable: 'itemsAndList' }) groups?: Group[] | null } - diff --git a/libs/clients/form-system/project.json b/libs/clients/form-system/project.json index 6d206e0f4078..22dfef44e2de 100644 --- a/libs/clients/form-system/project.json +++ b/libs/clients/form-system/project.json @@ -6,20 +6,14 @@ "targets": { "lint": { "executor": "@nx/linter:eslint", - "outputs": [ - "{options.outputFile}" - ], + "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": [ - "libs/clients/form-system/**/*.ts" - ] + "lintFilePatterns": ["libs/clients/form-system/**/*.ts"] } }, "test": { "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}" - ], + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "libs/clients/form-system/jest.config.ts", "passWithNoTests": true @@ -36,9 +30,7 @@ "options": { "command": "yarn openapi-generator -o libs/clients/form-system/gen/fetch -i libs/clients/form-system/src/clientConfig.json" }, - "outputs": [ - "{projectRoot}/gen/fetch" - ] + "outputs": ["{projectRoot}/gen/fetch"] }, "update-openapi-document": { "executor": "nx:run-commands", @@ -48,8 +40,5 @@ } }, "schema": "libs/client/form-system/gen/fetch/api.graphql", - "tags": [ - "lib:client", - "scope:client" - ] + "tags": ["lib:client", "scope:client"] } diff --git a/libs/clients/form-system/src/clientConfig.json b/libs/clients/form-system/src/clientConfig.json index dcb5c1be4c8d..148dbaf14395 100644 --- a/libs/clients/form-system/src/clientConfig.json +++ b/libs/clients/form-system/src/clientConfig.json @@ -7,9 +7,7 @@ "paths": { "/api/Files": { "post": { - "tags": [ - "Files" - ], + "tags": ["Files"], "requestBody": { "content": { "multipart/form-data": { @@ -42,9 +40,7 @@ }, "/api/Forms/Organization/{organizationId}": { "get": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "organizationId", @@ -82,9 +78,7 @@ }, "/api/Forms/{formId}": { "get": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "formId", @@ -120,9 +114,7 @@ } }, "put": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "formId", @@ -160,9 +152,7 @@ } }, "delete": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "formId", @@ -183,9 +173,7 @@ }, "/api/Forms/{organizationId}": { "post": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "organizationId", @@ -223,9 +211,7 @@ }, "/api/Forms/{formId}/settings": { "put": { - "tags": [ - "Forms" - ], + "tags": ["Forms"], "parameters": [ { "name": "formId", @@ -265,9 +251,7 @@ }, "/api/Groups/{groupId}": { "get": { - "tags": [ - "Groups" - ], + "tags": ["Groups"], "parameters": [ { "name": "groupId", @@ -303,9 +287,7 @@ } }, "delete": { - "tags": [ - "Groups" - ], + "tags": ["Groups"], "parameters": [ { "name": "groupId", @@ -324,9 +306,7 @@ } }, "put": { - "tags": [ - "Groups" - ], + "tags": ["Groups"], "parameters": [ { "name": "groupId", @@ -366,9 +346,7 @@ }, "/api/Groups": { "post": { - "tags": [ - "Groups" - ], + "tags": ["Groups"], "requestBody": { "content": { "application/json": { @@ -414,9 +392,7 @@ }, "/api/Inputs/{inputId}": { "get": { - "tags": [ - "Inputs" - ], + "tags": ["Inputs"], "parameters": [ { "name": "inputId", @@ -452,9 +428,7 @@ } }, "put": { - "tags": [ - "Inputs" - ], + "tags": ["Inputs"], "parameters": [ { "name": "inputId", @@ -492,9 +466,7 @@ } }, "delete": { - "tags": [ - "Inputs" - ], + "tags": ["Inputs"], "parameters": [ { "name": "inputId", @@ -515,9 +487,7 @@ }, "/api/Inputs": { "post": { - "tags": [ - "Inputs" - ], + "tags": ["Inputs"], "requestBody": { "content": { "application/json": { @@ -563,9 +533,7 @@ }, "/api/Organizations": { "post": { - "tags": [ - "Organizations" - ], + "tags": ["Organizations"], "requestBody": { "content": { "application/json": { @@ -611,9 +579,7 @@ }, "/api/Services/Fasteign/{fasteignanumer}": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "parameters": [ { "name": "fasteignanumer", @@ -650,9 +616,7 @@ }, "/api/Services/IdngreinarMeistara": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "responses": { "200": { "description": "Success", @@ -679,9 +643,7 @@ }, "/api/Services/Skraningarflokkar": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "responses": { "200": { "description": "Success", @@ -708,9 +670,7 @@ }, "/api/Services/Sveitarfelog": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "responses": { "200": { "description": "Success", @@ -737,9 +697,7 @@ }, "/api/Services/Postnumer": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "responses": { "200": { "description": "Success", @@ -766,9 +724,7 @@ }, "/api/Services/Lond": { "get": { - "tags": [ - "Services" - ], + "tags": ["Services"], "responses": { "200": { "description": "Success", @@ -795,9 +751,7 @@ }, "/api/Steps/{stepId}": { "get": { - "tags": [ - "Steps" - ], + "tags": ["Steps"], "parameters": [ { "name": "stepId", @@ -833,9 +787,7 @@ } }, "delete": { - "tags": [ - "Steps" - ], + "tags": ["Steps"], "parameters": [ { "name": "stepId", @@ -854,9 +806,7 @@ } }, "put": { - "tags": [ - "Steps" - ], + "tags": ["Steps"], "parameters": [ { "name": "stepId", @@ -896,9 +846,7 @@ }, "/api/Steps": { "post": { - "tags": [ - "Steps" - ], + "tags": ["Steps"], "requestBody": { "content": { "application/json": { @@ -1049,17 +997,11 @@ "additionalProperties": false }, "EExternalEndpointEnvironment": { - "enum": [ - "development", - "production" - ], + "enum": ["development", "production"], "type": "string" }, "EExternalEndpointType": { - "enum": [ - "submit", - "validation" - ], + "enum": ["submit", "validation"], "type": "string" }, "ExternalEndpointDto": { diff --git a/libs/clients/form-system/src/lib/FormSystemApiProvider.ts b/libs/clients/form-system/src/lib/FormSystemApiProvider.ts index 3882e867fbb6..85bba8e4103c 100644 --- a/libs/clients/form-system/src/lib/FormSystemApiProvider.ts +++ b/libs/clients/form-system/src/lib/FormSystemApiProvider.ts @@ -1,35 +1,43 @@ import { Provider } from '@nestjs/common/interfaces/modules/provider.interface' import { createEnhancedFetch } from '@island.is/clients/middlewares' -import { - ConfigType, - LazyDuringDevScope, -} from '@island.is/nest/config' +import { ConfigType, LazyDuringDevScope } from '@island.is/nest/config' import { FormSystemClientConfig } from './FormSystemClient.config' -import { Configuration, FilesApi, FormsApi, GroupsApi, InputsApi, OrganizationsApi, ServicesApi, StepsApi } from '../../gen/fetch' -import * as https from 'https'; -import fetch, { RequestInfo, RequestInit } from 'node-fetch'; +import { + Configuration, + FilesApi, + FormsApi, + GroupsApi, + InputsApi, + OrganizationsApi, + ServicesApi, + StepsApi, +} from '../../gen/fetch' +import * as https from 'https' +import fetch, { RequestInfo, RequestInit } from 'node-fetch' -const httpsAgent = new https.Agent({ // remove +const httpsAgent = new https.Agent({ + // remove rejectUnauthorized: false, // This will ignore SSL certificates -}); +}) -const fetchWithHttpsAgent = (url: RequestInfo, options: RequestInit | undefined) => fetch(url, { ...options, agent: httpsAgent }); //remove +const fetchWithHttpsAgent = ( + url: RequestInfo, + options: RequestInit | undefined, +) => fetch(url, { ...options, agent: httpsAgent }) //remove const provideApi = ( Api: new (configuration: Configuration) => T, ): Provider => ({ provide: Api, scope: LazyDuringDevScope, - useFactory: ( - config: ConfigType, - ) => + useFactory: (config: ConfigType) => new Api( new Configuration({ fetchApi: createEnhancedFetch({ name: 'form-system', organizationSlug: 'stafraent-island', logErrorResponseBody: true, - fetch: fetchWithHttpsAgent // remove + fetch: fetchWithHttpsAgent, // remove }), basePath: config.basePath, headers: { diff --git a/libs/clients/form-system/src/lib/FormSystemClient.config.ts b/libs/clients/form-system/src/lib/FormSystemClient.config.ts index 6be8509b597a..85ca437a20e2 100644 --- a/libs/clients/form-system/src/lib/FormSystemClient.config.ts +++ b/libs/clients/form-system/src/lib/FormSystemClient.config.ts @@ -10,8 +10,10 @@ export const FormSystemClientConfig = defineConfig({ schema, load(env) { return { - //basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://profun.island.is/umsoknarkerfi'), - basePath: env.required('FORM_SYSTEM_API_BASE_PATH', 'https://localhost:51345') + basePath: env.required( + 'FORM_SYSTEM_API_BASE_PATH', + 'https://profun.island.is/umsoknarkerfi', + ), } - } + }, }) diff --git a/libs/clients/form-system/src/lib/form-system.module.ts b/libs/clients/form-system/src/lib/form-system.module.ts index 088984e219ed..9cbf48e8168d 100644 --- a/libs/clients/form-system/src/lib/form-system.module.ts +++ b/libs/clients/form-system/src/lib/form-system.module.ts @@ -1,7 +1,22 @@ import { Module } from '@nestjs/common' -import { FilesApiProvider, FormsApiProvider, GroupsApiProvider, InputsApiProvider, OrganizationsApiProvider, ServicesApiProvider, StepsApiProvider } from './FormSystemApiProvider' -import { FilesApi, FormsApi, GroupsApi, InputsApi, OrganizationsApi, ServicesApi, StepsApi } from '../../gen/fetch' - +import { + FilesApiProvider, + FormsApiProvider, + GroupsApiProvider, + InputsApiProvider, + OrganizationsApiProvider, + ServicesApiProvider, + StepsApiProvider, +} from './FormSystemApiProvider' +import { + FilesApi, + FormsApi, + GroupsApi, + InputsApi, + OrganizationsApi, + ServicesApi, + StepsApi, +} from '../../gen/fetch' @Module({ controllers: [], @@ -24,4 +39,4 @@ import { FilesApi, FormsApi, GroupsApi, InputsApi, OrganizationsApi, ServicesApi StepsApi, ], }) -export class FormSystemClientModule { } +export class FormSystemClientModule {} diff --git a/libs/portals/admin/form-system/codegen.yml b/libs/portals/admin/form-system/codegen.yml index cccc9acf3075..898fa11f9cfd 100644 --- a/libs/portals/admin/form-system/codegen.yml +++ b/libs/portals/admin/form-system/codegen.yml @@ -15,4 +15,4 @@ generates: DateTime: string hooks: afterAllFileWrite: - - prettier --write + - prettier --write diff --git a/libs/portals/admin/form-system/project.json b/libs/portals/admin/form-system/project.json index fea25ece2e95..ff5c911d5de2 100644 --- a/libs/portals/admin/form-system/project.json +++ b/libs/portals/admin/form-system/project.json @@ -7,20 +7,14 @@ "targets": { "lint": { "executor": "@nx/linter:eslint", - "outputs": [ - "{options.outputFile}" - ], + "outputs": ["{options.outputFile}"], "options": { - "lintFilePatterns": [ - "libs/portals/admin/form-system/**/*.ts" - ] + "lintFilePatterns": ["libs/portals/admin/form-system/**/*.ts"] } }, "test": { "executor": "@nx/jest:jest", - "outputs": [ - "{workspaceRoot}/coverage/{projectRoot}" - ], + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], "options": { "jestConfig": "libs/portals/admin/form-system/jest.config.ts", "passWithNoTests": true @@ -34,8 +28,5 @@ } } }, - "tags": [ - "scope:portals-admin", - "lib:portals-admin" - ] -} \ No newline at end of file + "tags": ["scope:portals-admin", "lib:portals-admin"] +} diff --git a/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx index dc5e9a3c99fa..259d7e97af31 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/MainContent.tsx @@ -17,95 +17,99 @@ import PreviewStepOrGroup from './components/PreviewStepOrGroup/PreviewStepOrGro import RelevantParties from './components/RelevantParties/RevelantParties' export default function MainContent() { - const { control, controlDispatch, updateActiveItem, setFocus, focus } = useContext(ControlContext) - const { activeItem, form, } = control + const { control, controlDispatch, updateActiveItem, setFocus, focus } = + useContext(ControlContext) + const { activeItem } = control const [openPreview, setOpenPreview] = useState(false) - - return ( - - {activeItem.type === 'Input' ? () - : activeItem.type === 'Step' && - (activeItem.data as FormSystemStep).type === 'BaseSetting' ? () - : activeItem.type === 'Step' && - (activeItem.data as FormSystemStep).type === 'Forsendur' ? () - : activeItem.type === 'Step' && (activeItem.data as FormSystemStep).type === 'Aðilar' ? - : openPreview ? ( - - ) : - < Stack space={2}> - - - - controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'is', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - - - - controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'en', - newValue: e.target.value, - }, - - })} - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - {activeItem.type === 'Group' && ( - - - - // listsDispatch({ - // type: 'setMultiSet', - // payload: { - // checked: e.target.checked, - // }, - // }) - // } - /> - - - )} - - - - - - - } - + {activeItem.type === 'Input' ? ( + + ) : activeItem.type === 'Step' && + (activeItem.data as FormSystemStep).type === 'BaseSetting' ? ( + + ) : activeItem.type === 'Step' && + (activeItem.data as FormSystemStep).type === 'Forsendur' ? ( + + ) : activeItem.type === 'Step' && + (activeItem.data as FormSystemStep).type === 'Aðilar' ? ( + + ) : openPreview ? ( + + ) : ( + + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + + + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + {activeItem.type === 'Group' && ( + + + + controlDispatch({ + type: 'TOGGLE_MULTI_SET', + payload: { + checked: e.target.checked, + update: updateActiveItem, + }, + }) + } + /> + + + )} + + + + + + + )} + ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx index 1bf4e1597bc6..a7a324f0c5fe 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -1,4 +1,3 @@ - import { Stack, GridRow as Row, @@ -11,13 +10,13 @@ import { useContext } from 'react' import ControlContext from '../../../../context/ControlContext' export const BaseSettings = () => { - const { control, controlDispatch, setFocus, focus, formSettingsUpdate, formUpdate } = useContext(ControlContext) + const { control, controlDispatch, setFocus, focus, formUpdate } = + useContext(ControlContext) const { form } = control - console.log('BaseSettings form', form) return ( - + { backgroundColor={'blue'} onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && formUpdate()} - onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'is', newValue: e.target.value } })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_FORM_NAME', + payload: { lang: 'is', newValue: e.target.value }, + }) + } /> - + { backgroundColor="blue" onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && formUpdate()} - onChange={(e) => controlDispatch({ type: 'CHANGE_FORM_NAME', payload: { lang: 'en', newValue: e.target.value } })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_FORM_NAME', + payload: { lang: 'en', newValue: e.target.value }, + }) + } /> @@ -57,7 +66,12 @@ export const BaseSettings = () => { type="number" onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && formUpdate()} - onChange={(e) => controlDispatch({ type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', payload: { value: parseInt(e.target.value) } })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', + payload: { value: parseInt(e.target.value) }, + }) + } /> @@ -68,12 +82,13 @@ export const BaseSettings = () => { placeholderText="Veldu dagsetningu" backgroundColor="blue" selected={ - form.invalidationDate - ? new Date(form.invalidationDate) - : null + form.invalidationDate ? new Date(form.invalidationDate) : null } handleChange={(e) => { - controlDispatch({ type: 'CHANGE_INVALIDATION_DATE', payload: { value: e } }) + controlDispatch({ + type: 'CHANGE_INVALIDATION_DATE', + payload: { value: e }, + }) }} handleCloseCalendar={() => formUpdate()} /> @@ -85,10 +100,15 @@ export const BaseSettings = () => { label="Leyfa notanda að halda áfram í umsókninni með ógild/óútfyllt gildi" checked={form.stopProgressOnValidatingStep ?? false} onChange={(e) => { - controlDispatch({ type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', payload: { value: e.target.checked } }) - formUpdate({ ...form, stopProgressOnValidatingStep: e.target.checked }) + controlDispatch({ + type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', + payload: { value: e.target.checked }, + }) + formUpdate({ + ...form, + stopProgressOnValidatingStep: e.target.checked, + }) }} - /> diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx index 5e9a2ac87e6c..ae931b30945c 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/InputContent.tsx @@ -1,16 +1,14 @@ -import { useContext } from "react" -import ControlContext from "../../../../context/ControlContext" -import { Stack } from "@island.is/island-ui/core" -import BaseInput from "./components/BaseInput" -import Preview from "../Preview/Preveiw" -import { FormSystemInput } from "@island.is/api/schema" -import InputSettings from "./components/InputSettings/InputSettings" -import ListBuilder from "./components/ListBuilder/ListBuilder" - - +import { useContext } from 'react' +import ControlContext from '../../../../context/ControlContext' +import { Stack } from '@island.is/island-ui/core' +import BaseInput from './components/BaseInput' +import Preview from '../Preview/Preveiw' +import { FormSystemInput } from '@island.is/api/schema' +import InputSettings from './components/InputSettings/InputSettings' +import ListBuilder from './components/ListBuilder/ListBuilder' const InputContent = () => { - const { control, selectStatus, setSelectStatus, inListBuilder } = useContext(ControlContext) + const { control, inListBuilder } = useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput if (inListBuilder) { diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx index 9035f0f3bcbd..95543a0c3296 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/BaseInput.tsx @@ -1,6 +1,6 @@ -import { useContext } from "react" -import ControlContext from "../../../../../context/ControlContext" -import { FormSystemInput } from "@island.is/api/schema" +import { useContext } from 'react' +import ControlContext from '../../../../../context/ControlContext' +import { FormSystemInput } from '@island.is/api/schema' import { Stack, GridRow as Row, @@ -8,20 +8,28 @@ import { Select, Option, Input, - Checkbox -} from "@island.is/island-ui/core" -import { SingleValue } from "react-select" - + Checkbox, +} from '@island.is/island-ui/core' +import { SingleValue } from 'react-select' const BaseInput = () => { - const { control, controlDispatch, setFocus, focus, inputTypes, updateActiveItem } = useContext(ControlContext) + const { + control, + controlDispatch, + setFocus, + focus, + inputTypes, + updateActiveItem, + } = useContext(ControlContext) const { activeItem } = control const currentItem = activeItem.data as FormSystemInput - const sortedInputTypes = inputTypes?.map(i => ({ - label: i?.type ?? '', - value: i?.type ?? '', - })).sort((a, b) => (a?.label ?? '').localeCompare(b?.label ?? '')) + const sortedInputTypes = inputTypes + ?.map((i) => ({ + label: i?.type ?? '', + value: i?.type ?? '', + })) + .sort((a, b) => (a?.label ?? '').localeCompare(b?.label ?? '')) const defaultOption = currentItem.type === '' @@ -45,9 +53,11 @@ const BaseInput = () => { type: 'CHANGE_INPUT_TYPE', payload: { newValue: e?.value ?? '', - inputSettings: inputTypes?.find((i) => i?.type === e?.value)?.inputSettings ?? {}, - update: updateActiveItem - } + inputSettings: + inputTypes?.find((i) => i?.type === e?.value) + ?.inputSettings ?? {}, + update: updateActiveItem, + }, }) } /> @@ -61,13 +71,15 @@ const BaseInput = () => { name="name" value={currentItem?.name?.is ?? ''} backgroundColor="blue" - onChange={(e) => controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'is', - newValue: e.target.value, - }, - })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && updateActiveItem()} /> @@ -81,13 +93,15 @@ const BaseInput = () => { name="nameEn" value={currentItem?.name?.en ?? ''} backgroundColor="blue" - onChange={(e) => controlDispatch({ - type: 'CHANGE_NAME', - payload: { - lang: 'en', - newValue: e.target.value, - }, - })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_NAME', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && updateActiveItem()} /> @@ -106,13 +120,15 @@ const BaseInput = () => { backgroundColor="blue" onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && updateActiveItem()} - onChange={(e) => controlDispatch({ - type: 'CHANGE_DESCRIPTION', - payload: { - lang: 'is', - newValue: e.target.value, - }, - })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_DESCRIPTION', + payload: { + lang: 'is', + newValue: e.target.value, + }, + }) + } /> @@ -126,13 +142,15 @@ const BaseInput = () => { backgroundColor="blue" onFocus={(e) => setFocus(e.target.value)} onBlur={(e) => e.target.value !== focus && updateActiveItem()} - onChange={(e) => controlDispatch({ - type: 'CHANGE_DESCRIPTION', - payload: { - lang: 'en', - newValue: e.target.value, - }, - })} + onChange={(e) => + controlDispatch({ + type: 'CHANGE_DESCRIPTION', + payload: { + lang: 'en', + newValue: e.target.value, + }, + }) + } /> @@ -149,7 +167,7 @@ const BaseInput = () => { type: 'CHANGE_IS_REQUIRED', payload: { update: updateActiveItem, - } + }, }) } /> diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx index f0b125c11ac1..8efc13117bfb 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/InputSettings.tsx @@ -1,26 +1,24 @@ -import { useContext } from "react" -import ControlContext from "../../../../../../context/ControlContext" -import { FormSystemInput } from "@island.is/api/schema" -import MessageWithLinkSettings from "./components/MessageWithLinkSettings" -import FileUploadSettings from "./components/FIleUploadSettings" -import TextInputSettings from "./components/TextInputSettings" -import ListSettings from "./components/ListSettings" - +import { useContext } from 'react' +import ControlContext from '../../../../../../context/ControlContext' +import { FormSystemInput } from '@island.is/api/schema' +import MessageWithLinkSettings from './components/MessageWithLinkSettings' +import FileUploadSettings from './components/FIleUploadSettings' +import TextInputSettings from './components/TextInputSettings' +import ListSettings from './components/ListSettings' +import ToggleConnection from './components/ToggleConnection' const InputSettings = () => { const { control } = useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput return ( <> - {currentItem.type === 'Textalýsing' && ( - - )} - {currentItem.type === 'Skjal' && ( - - )} - {currentItem.type === 'Textalínubox' || currentItem.type === 'TextaInnsláttur' && } + {currentItem.type === 'Textalýsing' && } + {currentItem.type === 'Skjal' && } + {currentItem.type === 'Textalínubox' || + (currentItem.type === 'TextaInnsláttur' && )} {currentItem.type === 'Fellilisti' && } {currentItem.type === 'Valhnappar' && } + {['Hakbox'].includes(currentItem.type as string) && } ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx index b1b8bdeca672..47fbd54f01da 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/FIleUploadSettings.tsx @@ -14,52 +14,53 @@ import ControlContext from '../../../../../../../context/ControlContext' import { FormSystemInput } from '@island.is/api/schema' const fileSizes = { - "fileSizes": [ + fileSizes: [ { - "label": "1 mb", - "value": 1048576 + label: '1 mb', + value: 1048576, }, { - "label": "2 mb", - "value": 2097152 + label: '2 mb', + value: 2097152, }, { - "label": "3 mb", - "value": 3145728 + label: '3 mb', + value: 3145728, }, { - "label": "4 mb", - "value": 4194304 + label: '4 mb', + value: 4194304, }, { - "label": "5 mb", - "value": 5242880 + label: '5 mb', + value: 5242880, }, { - "label": "6 mb", - "value": 6291456 + label: '6 mb', + value: 6291456, }, { - "label": "7 mb", - "value": 7340032 + label: '7 mb', + value: 7340032, }, { - "label": "8 mb", - "value": 8388608 + label: '8 mb', + value: 8388608, }, { - "label": "9 mb", - "value": 9437184 + label: '9 mb', + value: 9437184, }, { - "label": "10 mb", - "value": 10485760 - } - ] + label: '10 mb', + value: 10485760, + }, + ], } const FileUploadSettings = () => { - const { control, controlDispatch, updateActiveItem } = useContext(ControlContext) + const { control, controlDispatch, updateActiveItem } = + useContext(ControlContext) const { activeItem } = control const currentItem = activeItem.data as FormSystemInput const { inputSettings } = currentItem @@ -90,14 +91,16 @@ const FileUploadSettings = () => { name="multi" label="Er fjölval" checked={inputSettings?.isMulti ?? false} - onChange={(e) => controlDispatch({ - type: 'SET_FILE_UPLOAD_SETTINGS', - payload: { - property: 'isMulti', - checked: e.target.checked, - update: updateActiveItem - } - })} + onChange={(e) => + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'isMulti', + checked: e.target.checked, + update: updateActiveItem, + }, + }) + } /> @@ -112,14 +115,16 @@ const FileUploadSettings = () => { (f) => f.value === inputSettings?.maxSize, )} options={fileSizeOptions} - onChange={(e) => controlDispatch({ - type: 'SET_FILE_UPLOAD_SETTINGS', - payload: { - property: 'maxSize', - value: e?.value, - update: updateActiveItem - } - })} + onChange={(e) => + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'maxSize', + value: e?.value, + update: updateActiveItem, + }, + }) + } /> {inputSettings?.isMulti && ( @@ -133,14 +138,16 @@ const FileUploadSettings = () => { (f) => f.value === inputSettings.amount, )} options={fileAmountOptions} - onChange={(e) => controlDispatch({ - type: 'SET_FILE_UPLOAD_SETTINGS', - payload: { - property: 'amount', - value: e?.value, - update: updateActiveItem - } - })} + onChange={(e) => + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'amount', + value: e?.value, + update: updateActiveItem, + }, + }) + } /> )} @@ -158,15 +165,17 @@ const FileUploadSettings = () => { label={key} value={value as string} checked={inputSettings?.types?.includes(key)} - onChange={(e) => controlDispatch({ - type: 'SET_FILE_UPLOAD_SETTINGS', - payload: { - property: 'types', - checked: e.target.checked, - value: key, - update: updateActiveItem - } - })} + onChange={(e) => + controlDispatch({ + type: 'SET_FILE_UPLOAD_SETTINGS', + payload: { + property: 'types', + checked: e.target.checked, + value: key, + update: updateActiveItem, + }, + }) + } /> )} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx index c713a00ed796..be5438543397 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ListSettings.tsx @@ -1,5 +1,5 @@ -import { useContext, useState } from "react" -import ControlContext from "../../../../../../../context/ControlContext" +import { useContext, useState } from 'react' +import ControlContext from '../../../../../../../context/ControlContext' import { GridColumn as Column, GridRow as Row, @@ -8,9 +8,8 @@ import { Box, Button, RadioButton, - Option, } from '@island.is/island-ui/core' -import { FormSystemInput } from "@island.is/api/schema" +import { FormSystemInput } from '@island.is/api/schema' const predeterminedLists = [ { @@ -33,7 +32,7 @@ const predeterminedLists = [ // Need to fix the radio buttons const ListSettings = () => { - const { control, controlDispatch, setInListBuilder } = useContext(ControlContext) + const { control, setInListBuilder } = useContext(ControlContext) const { activeItem } = control const currentItem = activeItem.data as FormSystemInput const [radio, setRadio] = useState([true, false, false]) @@ -54,13 +53,25 @@ const ListSettings = () => { radioHandler(0)}> - { console.log() }} checked={radio[0]} /> + { + console.log() + }} + checked={radio[0]} + /> - { console.log() }} checked={radio[1]} /> + { + console.log() + }} + checked={radio[1]} + /> @@ -78,18 +89,7 @@ const ListSettings = () => { label="Tilbúnir fellilistar" options={predeterminedLists} backgroundColor="blue" - // onChange={async (e: SingleValue>) => { - // const newList = e && (await getList(e.value)) - // listsDispatch({ - // type: 'setInputSettings', - // payload: { - // inputSettings: { - // ...(activeItem.data as IInput).inputSettings, - // listi: newList.listi, - // }, - // }, - // }) - // }} + // TODO: add lists /> )} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx index f6c13cd6b8c8..dc6003858e16 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/MessageWithLinkSettings.tsx @@ -1,5 +1,5 @@ -import { useContext } from "react" -import ControlContext from "../../../../../../../context/ControlContext" +import { useContext } from 'react' +import ControlContext from '../../../../../../../context/ControlContext' import { GridRow as Row, GridColumn as Column, @@ -7,10 +7,11 @@ import { Checkbox, Stack, } from '@island.is/island-ui/core' -import { FormSystemInput } from "@island.is/api/schema" +import { FormSystemInput } from '@island.is/api/schema' const MessageWithLinkSettings = () => { - const { control, controlDispatch, focus, setFocus, updateActiveItem } = useContext(ControlContext) + const { control, controlDispatch, focus, setFocus, updateActiveItem } = + useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput const { inputSettings } = currentItem return ( @@ -20,80 +21,86 @@ const MessageWithLinkSettings = () => { controlDispatch({ - type: 'SET_MESSAGE_WITH_LINK_SETTINGS', - payload: { - property: 'hasLink', - checked: e.target.checked, - update: updateActiveItem - } - })} + onChange={(e) => + controlDispatch({ + type: 'SET_MESSAGE_WITH_LINK_SETTINGS', + payload: { + property: 'hasLink', + checked: e.target.checked, + update: updateActiveItem, + }, + }) + } /> - {inputSettings !== undefined && ( - inputSettings?.hasLink && ( - - - - controlDispatch({ + {inputSettings !== undefined && inputSettings?.hasLink && ( + + + + + controlDispatch({ type: 'SET_MESSAGE_WITH_LINK_SETTINGS', payload: { property: 'buttonText', lang: 'is', value: e.target.value, - } - })} - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - controlDispatch({ + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + controlDispatch({ type: 'SET_MESSAGE_WITH_LINK_SETTINGS', payload: { property: 'buttonText', lang: 'en', value: e.target.value, - } - })} - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - - - controlDispatch({ + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + + + + controlDispatch({ type: 'SET_MESSAGE_WITH_LINK_SETTINGS', payload: { property: 'url', value: e.target.value, - } - })} - onFocus={(e) => setFocus(e.target.value)} - onBlur={(e) => e.target.value !== focus && updateActiveItem()} - /> - - - - ) + }, + }) + } + onFocus={(e) => setFocus(e.target.value)} + onBlur={(e) => e.target.value !== focus && updateActiveItem()} + /> + + + )} ) diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/TextInputSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/TextInputSettings.tsx index fc26c5001cea..55948479f3c2 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/TextInputSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/TextInputSettings.tsx @@ -1,11 +1,11 @@ -import { useContext } from "react" -import ControlContext from "../../../../../../../context/ControlContext" -import { FormSystemInput } from "@island.is/api/schema" -import { Checkbox } from "@island.is/island-ui/core" - +import { useContext } from 'react' +import ControlContext from '../../../../../../../context/ControlContext' +import { FormSystemInput } from '@island.is/api/schema' +import { Checkbox } from '@island.is/island-ui/core' const TextInputSettings = () => { - const { control, controlDispatch, updateActiveItem } = useContext(ControlContext) + const { control, controlDispatch, updateActiveItem } = + useContext(ControlContext) const { activeItem } = control const currentItem = activeItem.data as FormSystemInput const { inputSettings } = currentItem @@ -14,14 +14,16 @@ const TextInputSettings = () => { controlDispatch({ - type: 'SET_INPUT_SETTINGS', - payload: { - property: 'isLarge', - value: e.target.checked, - update: updateActiveItem - }, - })} + onChange={(e) => + controlDispatch({ + type: 'SET_INPUT_SETTINGS', + payload: { + property: 'isLarge', + value: e.target.checked, + update: updateActiveItem, + }, + }) + } /> ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ToggleConnection.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ToggleConnection.tsx new file mode 100644 index 000000000000..ccf3b077d496 --- /dev/null +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/InputSettings/components/ToggleConnection.tsx @@ -0,0 +1,42 @@ +import { + GridRow as Row, + GridColumn as Column, + ToggleSwitchCheckbox, + Text, +} from '@island.is/island-ui/core' +import { useContext } from 'react' +import { FormSystemInput } from '@island.is/api/schema' +import ControlContext from '../../../../../../../context/ControlContext' +import { NavbarSelectStatus } from '../../../../../../../lib/utils/interfaces' + +const ToggleConnection = () => { + const { control, selectStatus, setSelectStatus } = useContext(ControlContext) + const currentItem = control.activeItem.data as FormSystemInput + const hasConnections = + control.form.dependencies[currentItem.guid as string] !== undefined && + control.form.dependencies[currentItem.guid as string].length > 0 + + return ( + + + + setSelectStatus( + e ? NavbarSelectStatus.NORMAL : NavbarSelectStatus.OFF, + ) + } + /> + + {hasConnections && ( + + Hefur tengingar + + )} + + ) +} + +export default ToggleConnection diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx index 7bed2924d4c2..eefd7ecbb72e 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/ListBuilder.tsx @@ -1,6 +1,6 @@ -import { useContext, useEffect, useMemo, useState } from "react" -import ControlContext from "../../../../../../context/ControlContext" -import { FormSystemInput, FormSystemListItem } from "@island.is/api/schema" +import { useContext, useEffect, useMemo, useState } from 'react' +import ControlContext from '../../../../../../context/ControlContext' +import { FormSystemInput, FormSystemListItem } from '@island.is/api/schema' import { GridRow as Row, GridColumn as Column, @@ -19,18 +19,33 @@ import { useSensor, useSensors, } from '@dnd-kit/core' -import { NavbarSelectStatus } from "../../../../../../lib/utils/interfaces" -import ListItem from "./components/ListItem" -import { SortableContext } from "@dnd-kit/sortable" -import { createPortal } from "react-dom" - +import { NavbarSelectStatus } from '../../../../../../lib/utils/interfaces' +import ListItem from './components/ListItem' +import { SortableContext } from '@dnd-kit/sortable' +import { createPortal } from 'react-dom' const ListBuilder = () => { - const { control, controlDispatch, setSelectStatus, setInListBuilder, updateActiveItem } = useContext(ControlContext) + const { + control, + controlDispatch, + setSelectStatus, + setInListBuilder, + updateActiveItem, + } = useContext(ControlContext) const currentItem = control.activeItem.data as FormSystemInput const { activeListItem } = control - const listItems = currentItem?.inputSettings?.list ?? [] as FormSystemListItem[] - const listItemIds = useMemo(() => listItems?.filter((l: FormSystemListItem): l is FormSystemListItem => l !== null && l !== undefined).map((l: FormSystemListItem) => l?.guid as UniqueIdentifier), [listItems]) + const listItems = + currentItem?.inputSettings?.list ?? ([] as FormSystemListItem[]) + const listItemIds = useMemo( + () => + listItems + ?.filter( + (l: FormSystemListItem): l is FormSystemListItem => + l !== null && l !== undefined, + ) + .map((l: FormSystemListItem) => l?.guid as UniqueIdentifier), + [listItems], + ) const [connecting, setConnecting] = useState([false]) const sensors = useSensors( @@ -41,7 +56,6 @@ const ListBuilder = () => { }), ) - const addListItem = () => { controlDispatch({ type: 'ADD_LIST_ITEM', @@ -68,7 +82,7 @@ const ListBuilder = () => { type: 'LIST_ITEM_OVER_LIST_ITEM', payload: { activeId: activeId, - overId: overId + overId: overId, }, }) } @@ -85,9 +99,6 @@ const ListBuilder = () => { } useEffect(() => { - // if (listItems.length === 0) { - // addListItem() - // } setSelectStatus(NavbarSelectStatus.ON_WITHOUT_SELECT) }, []) diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/components/ListItem.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/components/ListItem.tsx index b902ea9ea7aa..1aaecd3d91dc 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/components/ListItem.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/InputContent/components/ListBuilder/components/ListItem.tsx @@ -20,12 +20,22 @@ interface Props { } const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { - const { control, controlDispatch, setFocus, focus, setSelectStatus, updateActiveItem } = useContext(ControlContext) + const { + control, + controlDispatch, + setFocus, + focus, + setSelectStatus, + updateActiveItem, + } = useContext(ControlContext) const { activeItem } = control const currentItem = activeItem.data as FormSystemInput const isRadio = currentItem.type === 'Valhnappar' - const { setNodeRef, attributes, listeners, isDragging } = useSortable({ id: listItem.guid ?? '', data: { listItem } }) + const { setNodeRef, attributes, listeners, isDragging } = useSortable({ + id: listItem.guid ?? '', + data: { listItem }, + }) if (isDragging) { return ( @@ -53,13 +63,13 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { label="Tengja" checked={false} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> { }} + onChange={() => {}} /> @@ -67,7 +77,7 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { marginRight={2} style={{ cursor: 'pointer' }} // eslint-disable-next-line @typescript-eslint/no-empty-function - onClick={() => { }} + onClick={() => {}} > @@ -85,7 +95,7 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { size="sm" value={listItem?.label?.is ?? ''} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> @@ -96,7 +106,7 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { size="sm" value={listItem?.label?.en ?? ''} // eslint-disable-next-line @typescript-eslint/no-empty-function - onChange={() => { }} + onChange={() => {}} /> @@ -135,12 +145,15 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { setSelectStatus( e ? NavbarSelectStatus.LIST_ITEM - : NavbarSelectStatus.ON_WITHOUT_SELECT + : NavbarSelectStatus.ON_WITHOUT_SELECT, ) setConnecting((prev) => - prev.map((_, i) => (i === index ? e : false)) + prev.map((_, i) => (i === index ? e : false)), ) - controlDispatch({ type: 'SET_ACTIVE_LIST_ITEM', payload: { listItem: e ? listItem : null } }) + controlDispatch({ + type: 'SET_ACTIVE_LIST_ITEM', + payload: { listItem: e ? listItem : null }, + }) }} /> { payload: { guid: listItem.guid ?? '', update: updateActiveItem, - } + }, }) } /> @@ -281,5 +294,4 @@ const ListItem = ({ listItem, connecting, index, setConnecting }: Props) => { ) } - export default ListItem diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx index 48be875ba766..68f497f38ec9 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Premises/Premises.tsx @@ -3,10 +3,15 @@ import { useContext, useState } from 'react' import ControlContext from '../../../../context/ControlContext' import { FormSystemDocumentType } from '@island.is/api/schema' - const Premises = () => { const { control, documentTypes, updateSettings } = useContext(ControlContext) - const [formDocumentTypes, setFormDocumentTypes] = useState(control.form?.documentTypes?.filter((d): d is FormSystemDocumentType => d !== null) ?? []) + const [formDocumentTypes, setFormDocumentTypes] = useState< + FormSystemDocumentType[] + >( + control.form?.documentTypes?.filter( + (d): d is FormSystemDocumentType => d !== null, + ) ?? [], + ) const handleCheckboxChange = (documentTypeId: number) => { if (documentTypeId === -1) return @@ -15,9 +20,9 @@ const Premises = () => { ) ? formDocumentTypes.filter((f) => f?.id !== documentTypeId) : ([ - ...formDocumentTypes, - documentTypes?.find((d) => d?.id === documentTypeId), - ].filter((d) => d !== undefined) as FormSystemDocumentType[]) + ...formDocumentTypes, + documentTypes?.find((d) => d?.id === documentTypeId), + ].filter((d) => d !== undefined) as FormSystemDocumentType[]) setFormDocumentTypes(newDocumentTypes) updateSettings({ ...control.form, documentTypes: newDocumentTypes }) } @@ -49,7 +54,8 @@ const Premises = () => { ) })} - ) + + ) } export default Premises diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx index 3e350876914a..e4e2dbffac8f 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/Preveiw.tsx @@ -1,14 +1,14 @@ -import { FormSystemInput } from "@island.is/api/schema" -import { Box, DatePicker, Text } from "@island.is/island-ui/core" -import MessageWithLink from "./components/MessageWithLink" -import Banknumber from "./components/Banknumber" -import Email from "./components/Email" -import NationalId from "./components/NationalId" -import FileUpload from "./components/FileUpload" -import TextInput from "./components/TextInput" -import List from "./components/List" -import Radio from "./components/Radio" -import Currency from "./components/Currency" +import { FormSystemInput } from '@island.is/api/schema' +import { Box, DatePicker, Text } from '@island.is/island-ui/core' +import MessageWithLink from './components/MessageWithLink' +import Banknumber from './components/Banknumber' +import Email from './components/Email' +import NationalId from './components/NationalId' +import FileUpload from './components/FileUpload' +import TextInput from './components/TextInput' +import List from './components/List' +import Radio from './components/Radio' +import Currency from './components/Currency' interface Props { data: FormSystemInput @@ -17,13 +17,8 @@ interface Props { const Preview = ({ data }: Props) => { const { type } = data return ( - - {type === 'Textalýsing' && ( - - )} + + {type === 'Textalýsing' && } {type === 'Bankareikningur' && ( {data?.name?.is} @@ -34,14 +29,19 @@ const Preview = ({ data }: Props) => { {type === 'Dagssetningarval' && ( )} {type === 'Kennitala' && } {type === 'Skjal' && } - {type === 'Textalínubox' || type === 'TextaInnsláttur' && } + {type === 'Textalínubox' || + (type === 'TextaInnsláttur' && )} {type === 'Fellilisti' && } {type === 'Valhnappar' && } {type === 'Krónutölubox' && } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx index c54284c02d3a..59686cf9b2d1 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx @@ -2,7 +2,6 @@ import { GridRow as Row, GridColumn as Column, Input, - Box, } from '@island.is/island-ui/core' import { useRef, useState } from 'react' diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx index 759c8b483d66..326200dc4e7b 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Currency.tsx @@ -1,4 +1,3 @@ - import { GridRow as Row, GridColumn as Column, diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx index 8d52b21dca8c..8b593819a229 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Email.tsx @@ -2,7 +2,6 @@ import { useContext, useState } from 'react' import { Input, Stack, Text } from '@island.is/island-ui/core' import ControlContext from '../../../../../context/ControlContext' - export const Email = () => { const { control } = useContext(ControlContext) const { activeItem } = control diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx index 2e16e9df22bd..433c0268683c 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/FileUpload.tsx @@ -16,7 +16,6 @@ const FileUpload = ({ currentItem }: Props) => { const [error, setError] = useState(undefined) const [fileList, setFileList] = useState>([]) - const onChange = (files: File[]) => { const uploadFiles = files.map((file) => fileToObject(file)) const uploadFilesWithKey = uploadFiles.map((f) => ({ diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx index 99a5b1307fb1..3432e2d34697 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx @@ -1,5 +1,5 @@ -import { FormSystemInput, FormSystemListItem } from "@island.is/api/schema" -import { useEffect, useState } from "react" +import { FormSystemInput, FormSystemListItem } from '@island.is/api/schema' +import { useEffect, useState } from 'react' import { Select } from '@island.is/island-ui/core' interface Props { @@ -26,7 +26,11 @@ const List = ({ currentItem }: Props) => { return ( <> - ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx index f1662a756687..eed4d813e8bd 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/MessageWithLink.tsx @@ -1,13 +1,8 @@ -import { FormSystemInput } from "@island.is/api/schema" -import { - Box, - Button, - Text -} from "@island.is/island-ui/core" +import { FormSystemInput } from '@island.is/api/schema' +import { Box, Button, Text } from '@island.is/island-ui/core' interface Props { data: FormSystemInput - } const MessageWithLink = ({ data }: Props) => { @@ -24,8 +19,8 @@ const MessageWithLink = ({ data }: Props) => { flexDirection={'row'} display={'flex'} padding={4} - background={"white"} - alignItems={"center"} + background={'white'} + alignItems={'center'} > diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx index c06000c50dc9..49ca6bddc4c6 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Radio.tsx @@ -1,6 +1,6 @@ -import { FormSystemInput, FormSystemListItem } from "@island.is/api/schema" +import { FormSystemInput, FormSystemListItem } from '@island.is/api/schema' import { RadioButton, Text, Box } from '@island.is/island-ui/core' -import { useEffect, useState } from "react" +import { useEffect, useState } from 'react' interface Props { currentItem: FormSystemInput diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx index e0ecbf451678..7ee4c6d0f0f6 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/TextInput.tsx @@ -1,5 +1,5 @@ -import { FormSystemInput } from "@island.is/api/schema" -import { Input } from "@island.is/island-ui/core" +import { FormSystemInput } from '@island.is/api/schema' +import { Input } from '@island.is/island-ui/core' interface Props { data: FormSystemInput diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx index 48d00f321957..56f220f8a176 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx @@ -1,10 +1,10 @@ -import { Dispatch, SetStateAction, useContext, useEffect } from "react" +import { Dispatch, SetStateAction, useContext, useEffect } from 'react' import { Box, Button, Text } from '@island.is/island-ui/core' -import ControlContext from "../../../../context/ControlContext" -import { FormSystemGroup, FormSystemInput } from "@island.is/api/schema" -import { NavbarSelectStatus } from "../../../../lib/utils/interfaces" -import Preview from "../Preview/Preveiw" -import MultiSet from "./components/MultiSet" +import ControlContext from '../../../../context/ControlContext' +import { FormSystemGroup, FormSystemInput } from '@island.is/api/schema' +import { NavbarSelectStatus } from '../../../../lib/utils/interfaces' +import Preview from '../Preview/Preveiw' +import MultiSet from './components/MultiSet' interface Props { setOpenPreview: Dispatch> @@ -45,10 +45,7 @@ const PreviewStepOrGroup = ({ setOpenPreview }: Props) => { inputs ?.filter((i) => i?.groupGuid === g?.guid) .map((i) => ( - + )) )} @@ -65,12 +62,7 @@ const PreviewStepOrGroup = ({ setOpenPreview }: Props) => { ) : ( inputs ?.filter((i) => i?.groupGuid === activeItem?.data?.guid) - .map((i) => ( - - )) + .map((i) => ) )} )} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx index c92d6f466e23..5c817feb7a61 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/PreviewStepOrGroup/components/MultiSet.tsx @@ -12,7 +12,8 @@ const MultiSet = ({ group }: Props) => { const { inputsList: inputs } = control.form const originalInput = inputs?.filter((i) => i?.groupGuid === group.guid) const [multiInput, setMultiInput] = useState([ - (inputs?.filter((i) => i?.groupGuid === group.guid) || []) as FormSystemInput[], + (inputs?.filter((i) => i?.groupGuid === group.guid) || + []) as FormSystemInput[], ]) const add = () => { if (originalInput) { @@ -24,10 +25,7 @@ const MultiSet = ({ group }: Props) => { {multiInput.map((inputArray, index) => (
{inputArray.map((i) => ( - + ))}
))} diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx index 3d475571972d..f8561744541e 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/RevelantParties.tsx @@ -1,9 +1,13 @@ -import { useContext, useState } from "react" -import ControlContext from "../../../../context/ControlContext" +import { useContext, useState } from 'react' +import ControlContext from '../../../../context/ControlContext' import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' -import { FormSystemApplicantType, FormSystemFormApplicantType, FormSystemLanguageType } from "@island.is/api/schema" -import { EFormApplicantTypes } from "../../../../lib/utils/interfaces" -import FormApplicantType from "./components/FormApplicantType" +import { + FormSystemApplicantType, + FormSystemFormApplicantType, + FormSystemLanguageType, +} from '@island.is/api/schema' +import { EFormApplicantTypes } from '../../../../lib/utils/interfaces' +import FormApplicantType from './components/FormApplicantType' const applicantTypeLabel = [ 'Einstaklingur (innskráður)', @@ -23,19 +27,26 @@ const applicantTypes = [ 'Lögaðili', ] - export const RelevantParties = () => { - const { applicantTypes: applicantTypeTemplates, control, updateSettings } = useContext(ControlContext) + const { + applicantTypes: applicantTypeTemplates, + control, + updateSettings, + } = useContext(ControlContext) const { form } = control const { id: formId } = form - const [formApplicantTypes, setFormApplicantTypes] = useState( - (form.formApplicantTypes ?? []).filter(Boolean) as FormSystemFormApplicantType[] + const [formApplicantTypes, setFormApplicantTypes] = useState< + FormSystemFormApplicantType[] + >( + (form.formApplicantTypes ?? []).filter( + Boolean, + ) as FormSystemFormApplicantType[], ) const [focus, setOnFocus] = useState('') const createFormApplicantType = ( type: string, - template: FormSystemApplicantType + template: FormSystemApplicantType, ): FormSystemFormApplicantType => { return { __typename: undefined, @@ -43,7 +54,7 @@ export const RelevantParties = () => { name: template?.nameSuggestions?.[0]?.nameSuggestion ?? { __typename: undefined, is: '', - en: '' + en: '', }, applicantTypeId: template.id, formId, @@ -105,8 +116,8 @@ export const RelevantParties = () => { ) const newTypes = hasLegalEntity ? newFormApplicantTypes.filter( - (f) => f.type !== EFormApplicantTypes.logadili, - ) + (f) => f.type !== EFormApplicantTypes.logadili, + ) : newFormApplicantTypes const newList = [...formApplicantTypes, ...newTypes] updateSettings({ ...form, formApplicantTypes: newList }) @@ -114,7 +125,9 @@ export const RelevantParties = () => { } const removeFormApplicantTypes = (types: EFormApplicantTypes[]) => { - const newList = formApplicantTypes.filter((f) => !types.includes(f.type as EFormApplicantTypes)) + const newList = formApplicantTypes.filter( + (f) => !types.includes(f.type as EFormApplicantTypes), + ) updateSettings({ ...form, formApplicantTypes: newList }) setFormApplicantTypes(newList) } @@ -127,7 +140,10 @@ export const RelevantParties = () => { if (template !== undefined && template !== null) { const newFormApplicantType: FormSystemFormApplicantType = createFormApplicantType(EFormApplicantTypes.einstaklingur, template) - updateSettings({ ...form, formApplicantTypes: [...formApplicantTypes, newFormApplicantType] }) + updateSettings({ + ...form, + formApplicantTypes: [...formApplicantTypes, newFormApplicantType], + }) setFormApplicantTypes([...formApplicantTypes, newFormApplicantType]) } } else if (index === 1) { @@ -138,8 +154,10 @@ export const RelevantParties = () => { (at) => at?.id === 5, ) if ( - delegatorTemplate === undefined || delegatorTemplate === null || - delegateeTemplate === undefined || delegateeTemplate === null + delegatorTemplate === undefined || + delegatorTemplate === null || + delegateeTemplate === undefined || + delegateeTemplate === null ) { return } @@ -162,8 +180,10 @@ export const RelevantParties = () => { (at) => at?.id === 3, ) if ( - delegatorTemplate === undefined || delegatorTemplate === null || - delegateeTemplate === undefined || delegateeTemplate === null + delegatorTemplate === undefined || + delegatorTemplate === null || + delegateeTemplate === undefined || + delegateeTemplate === null ) { return } @@ -183,7 +203,12 @@ export const RelevantParties = () => { (at) => at?.id === 4, ) const legalEntity = applicantTypeTemplates?.find((at) => at?.id === 6) - if (procurationHolder === undefined || procurationHolder === null || legalEntity === undefined || legalEntity === null) { + if ( + procurationHolder === undefined || + procurationHolder === null || + legalEntity === undefined || + legalEntity === null + ) { return } @@ -267,12 +292,17 @@ export const RelevantParties = () => { {formApplicantTypes.map((f, i) => ( at?.id === f.applicantTypeId) - ?.nameSuggestions?.map((ns) => ns?.nameSuggestion) ?? []) as FormSystemLanguageType[] + ?.nameSuggestions?.map((ns) => ns?.nameSuggestion) ?? + []) as FormSystemLanguageType[] } formApplicantType={f} index={i} @@ -288,4 +318,3 @@ export const RelevantParties = () => { } export default RelevantParties - diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx index d6615e51b531..5aae9e7295f2 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx @@ -8,7 +8,10 @@ import { Stack, Text, } from '@island.is/island-ui/core' -import { FormSystemFormApplicantType, FormSystemLanguageType } from '@island.is/api/schema' +import { + FormSystemFormApplicantType, + FormSystemLanguageType, +} from '@island.is/api/schema' interface Props { title: string @@ -46,13 +49,14 @@ const FormApplicantType = ({ const other = { label: 'Annað', value: 'Annað' } const getOptions = () => { - const options = nameSuggestions?.map((suggestion) => { - return { - label: suggestion?.is ?? '', - value: suggestion?.en ?? '', - } - }) || [] - options.push(other); + const options = + nameSuggestions?.map((suggestion) => { + return { + label: suggestion?.is ?? '', + value: suggestion?.en ?? '', + } + }) || [] + options.push(other) return options } @@ -70,18 +74,20 @@ const FormApplicantType = ({ language: 'is' | 'en', ) => { setFormApplicantTypes((prev: FormSystemFormApplicantType[]) => { - const newApplicantTypes = prev.map((f: FormSystemFormApplicantType, i: number) => { - if (i === index) { - return { - ...f, - name: { - ...f.name, - [language]: e.target.value, - }, + const newApplicantTypes = prev.map( + (f: FormSystemFormApplicantType, i: number) => { + if (i === index) { + return { + ...f, + name: { + ...f.name, + [language]: e.target.value, + }, + } } - } - return f - }) + return f + }, + ) return newApplicantTypes }) } @@ -106,7 +112,9 @@ const FormApplicantType = ({ isOther ? other : { label: name.is ?? '', value: name.en ?? '' } } options={getOptions()} - onChange={(e) => handleSelectChange(e ?? { label: '', value: '' })} + onChange={(e) => + handleSelectChange(e ?? { label: '', value: '' }) + } /> diff --git a/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx index 87186ffc21b3..6e4f2a0c5682 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/Navbar.tsx @@ -7,8 +7,6 @@ import { UniqueIdentifier, DragStartEvent, DragOverEvent, - DataRef, - DragEndEvent, } from '@dnd-kit/core' import { SortableContext } from '@dnd-kit/sortable' import { useContext, useMemo } from 'react' @@ -17,14 +15,17 @@ import { Box, Button } from '@island.is/island-ui/core' import { baseSettingsStep } from '../../utils/getBaseSettingsStep' import NavbarTab from './components/NavbarTab/NavbarTab' import NavComponent from './components/NavComponent/NavComponent' -import { FormSystemFormInput, FormSystemGroup, FormSystemInput, FormSystemStep, FormSystemUpdateFormInput, Maybe } from '@island.is/api/schema' +import { + FormSystemGroup, + FormSystemInput, + FormSystemStep, + Maybe, +} from '@island.is/api/schema' import ControlContext, { IControlContext } from '../../context/ControlContext' import { useFormSystemCreateStepMutation } from '../../gql/Step.generated' -import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' import { ItemType } from '../../lib/utils/interfaces' import { removeTypename } from '../../lib/utils/removeTypename' - type DndAction = | 'STEP_OVER_STEP' | 'GROUP_OVER_STEP' @@ -33,20 +34,32 @@ type DndAction = | 'INPUT_OVER_INPUT' export default function Navbar() { - const { - control, - controlDispatch, - setInSettings, - inSettings, - updateDnD, - formUpdate - } = useContext(ControlContext) as IControlContext + const { control, controlDispatch, setInSettings, inSettings, formUpdate } = + useContext(ControlContext) as IControlContext const { activeItem, form } = control const { stepsList: steps, groupsList: groups, inputsList: inputs } = form - const stepsIds = useMemo(() => steps?.filter((s): s is FormSystemStep => s !== null && s !== undefined).map((s) => s?.guid as UniqueIdentifier), [steps]) - const groupsIds = useMemo(() => groups?.filter((g): g is FormSystemGroup => g !== null && g !== undefined).map((g) => g?.guid as UniqueIdentifier), [groups]) - const inputsIds = useMemo(() => inputs?.filter((i): i is FormSystemInput => i !== null && i !== undefined).map((i) => i?.guid as UniqueIdentifier), [inputs]) + const stepsIds = useMemo( + () => + steps + ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) + .map((s) => s?.guid as UniqueIdentifier), + [steps], + ) + const groupsIds = useMemo( + () => + groups + ?.filter((g): g is FormSystemGroup => g !== null && g !== undefined) + .map((g) => g?.guid as UniqueIdentifier), + [groups], + ) + const inputsIds = useMemo( + () => + inputs + ?.filter((i): i is FormSystemInput => i !== null && i !== undefined) + .map((i) => i?.guid as UniqueIdentifier), + [inputs], + ) const sensors = useSensors( useSensor(PointerSensor, { @@ -55,7 +68,7 @@ export default function Navbar() { }, }), ) - const [createStep, { data, loading, error }] = useFormSystemCreateStepMutation() + const [createStep] = useFormSystemCreateStepMutation() const addStep = async () => { const newStep = await createStep({ @@ -63,26 +76,36 @@ export default function Navbar() { input: { stepCreationDto: { formId: form?.id as number, - displayOrder: steps?.length - } - } - } + displayOrder: steps?.length, + }, + }, + }, }) if (newStep) { controlDispatch({ type: 'ADD_STEP', payload: { - step: removeTypename(newStep.data?.formSystemCreateStep) as FormSystemStep - } + step: removeTypename( + newStep.data?.formSystemCreateStep, + ) as FormSystemStep, + }, }) } } const focusComponent = (type: ItemType, id: UniqueIdentifier) => { - const data = type === "Step" - ? steps?.find((item: Maybe | undefined) => item?.guid === id) : type === "Group" - ? groups?.find((item: Maybe | undefined) => item?.guid === id) - : inputs?.find((item: Maybe | undefined) => item?.guid === id) + const data = + type === 'Step' + ? steps?.find( + (item: Maybe | undefined) => item?.guid === id, + ) + : type === 'Group' + ? groups?.find( + (item: Maybe | undefined) => item?.guid === id, + ) + : inputs?.find( + (item: Maybe | undefined) => item?.guid === id, + ) if (id === baseSettingsStep.guid) { controlDispatch({ type: 'SET_ACTIVE_ITEM', @@ -90,7 +113,7 @@ export default function Navbar() { activeItem: { type: 'Step', data: baseSettingsStep, - } + }, }, }) } else if (data) { @@ -100,7 +123,7 @@ export default function Navbar() { activeItem: { type: type, data: data, - } + }, }, }) } @@ -113,8 +136,8 @@ export default function Navbar() { activeItem: { type: event.active.data.current?.type, data: event.active.data.current?.data ?? null, - } - } + }, + }, }) } @@ -165,7 +188,6 @@ export default function Navbar() { } const onDragEnd = () => { - // updateDnD(activeItem.type) formUpdate() } @@ -210,7 +232,7 @@ export default function Navbar() { activeItem: { type: 'Step', data: step, - } + }, }, }) } @@ -241,7 +263,9 @@ export default function Navbar() { > {steps - ?.filter((s): s is FormSystemStep => s !== null && s !== undefined) + ?.filter( + (s): s is FormSystemStep => s !== null && s !== undefined, + ) .filter((s) => s.type === 'Innsláttur') .map((s, i) => ( @@ -254,7 +278,10 @@ export default function Navbar() { /> {groups - ?.filter((g): g is FormSystemGroup => g !== null && g !== undefined) + ?.filter( + (g): g is FormSystemGroup => + g !== null && g !== undefined, + ) .filter((g) => g.stepGuid === s.guid) .map((g) => ( @@ -267,7 +294,10 @@ export default function Navbar() { {inputs - ?.filter((i): i is FormSystemInput => i !== null && i !== undefined) + ?.filter( + (i): i is FormSystemInput => + i !== null && i !== undefined, + ) .filter((i) => i.groupGuid === g.guid) .map((i) => ( @@ -312,14 +347,8 @@ export default function Navbar() { + Bæta við skrefi - - - ) } return null - } diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx index 1cfac242be11..31eebd642753 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/NavComponent.tsx @@ -1,12 +1,16 @@ import { useState } from 'react' -import { ItemType, IGroup, IInput, IStep } from '../../../../types/interfaces' import { useSortable } from '@dnd-kit/sortable' import { Box } from '@island.is/island-ui/core' import cn from 'classnames' import * as styles from './NavComponent.css' import { UniqueIdentifier } from '@dnd-kit/core' import NavButtons from './components/NavButtons' -import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' +import { + FormSystemGroup, + FormSystemInput, + FormSystemStep, +} from '@island.is/api/schema' +import { ItemType } from '../../../../lib/utils/interfaces' type Props = { type: ItemType @@ -30,39 +34,39 @@ export default function NavComponent({ } const truncateName = (name: string) => { - let maxLength; + let maxLength if (active) { switch (type) { case 'Step': - maxLength = 23; - break; + maxLength = 23 + break case 'Group': - maxLength = 16; - break; + maxLength = 16 + break case 'Input': - maxLength = 12; - break; + maxLength = 12 + break default: - maxLength = 26; + maxLength = 26 } } else { switch (type) { case 'Step': - maxLength = 26; - break; + maxLength = 26 + break case 'Group': - maxLength = 19; - break; + maxLength = 19 + break case 'Input': - maxLength = 16; - break; + maxLength = 16 + break default: - maxLength = 26; + maxLength = 26 } } - return truncateText(name, maxLength); + return truncateText(name, maxLength) } const { setNodeRef, attributes, listeners, isDragging } = useSortable({ @@ -138,9 +142,9 @@ export default function NavComponent({ verticalAlign: 'middle', }} > - {!(type === 'Step' && (data as FormSystemStep).type !== 'Innsláttur') && ( - - )} + {!( + type === 'Step' && (data as FormSystemStep).type !== 'Innsláttur' + ) && }
) : ( @@ -168,8 +172,4 @@ export default function NavComponent({ )}
) - - - - } diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx index 0cdf8fcda401..114276c318de 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavComponent/components/NavButtons.tsx @@ -2,19 +2,24 @@ import { Box, Icon } from '@island.is/island-ui/core' import { useContext } from 'react' import ControlContext from '../../../../../context/ControlContext' import { FormSystemGroup, FormSystemInput } from '@island.is/api/schema' -import { useFormSystemCreateGroupMutation, useFormSystemDeleteGroupMutation } from '../../../../../gql/Group.generated' -import { useFormSystemCreateInputMutation, useFormSystemDeleteInputMutation } from '../../../../../gql/Input.generated' +import { + useFormSystemCreateGroupMutation, + useFormSystemDeleteGroupMutation, +} from '../../../../../gql/Group.generated' +import { + useFormSystemCreateInputMutation, + useFormSystemDeleteInputMutation, +} from '../../../../../gql/Input.generated' import { useFormSystemDeleteStepMutation } from '../../../../../gql/Step.generated' import { removeTypename } from '../../../../../lib/utils/removeTypename' - export default function NavButtons() { const { control, controlDispatch } = useContext(ControlContext) const { activeItem, form } = control const { groupsList: groups, inputsList: inputs } = form - const [addGroup, groupStatus] = useFormSystemCreateGroupMutation() - const [addInput, inputStatus] = useFormSystemCreateInputMutation() + const [addGroup] = useFormSystemCreateGroupMutation() + const [addInput] = useFormSystemCreateInputMutation() const [removeStep, removeStepStatus] = useFormSystemDeleteStepMutation() const [removeGroup, removeGroupStatus] = useFormSystemDeleteGroupMutation() const [removeInput, removeInputStatus] = useFormSystemDeleteInputMutation() @@ -26,13 +31,20 @@ export default function NavButtons() { input: { groupCreationDto: { stepId: activeItem?.data?.id, - displayOrder: groups?.length - } - } - } + displayOrder: groups?.length, + }, + }, + }, }) if (newGroup) { - controlDispatch({ type: 'ADD_GROUP', payload: { group: removeTypename(newGroup.data?.formSystemCreateGroup) as FormSystemGroup } }) + controlDispatch({ + type: 'ADD_GROUP', + payload: { + group: removeTypename( + newGroup.data?.formSystemCreateGroup, + ) as FormSystemGroup, + }, + }) } } else if (activeItem.type === 'Group') { const newInput = await addInput({ @@ -40,14 +52,20 @@ export default function NavButtons() { input: { inputCreationDto: { groupId: activeItem?.data?.id, - displayOrder: inputs?.length - } - } - } + displayOrder: inputs?.length, + }, + }, + }, }) if (newInput) { - console.log('newInput', newInput) - controlDispatch({ type: 'ADD_INPUT', payload: { input: removeTypename(newInput.data?.formSystemCreateInput) as FormSystemInput } }) + controlDispatch({ + type: 'ADD_INPUT', + payload: { + input: removeTypename( + newInput.data?.formSystemCreateInput, + ) as FormSystemInput, + }, + }) } } } @@ -58,9 +76,9 @@ export default function NavButtons() { await removeStep({ variables: { input: { - stepId: id - } - } + stepId: id, + }, + }, }) if (!removeStepStatus.loading) { controlDispatch({ type: 'REMOVE_STEP', payload: { stepId: id } }) @@ -69,9 +87,9 @@ export default function NavButtons() { await removeGroup({ variables: { input: { - groupId: id - } - } + groupId: id, + }, + }, }) if (!removeGroupStatus.loading) { controlDispatch({ type: 'REMOVE_GROUP', payload: { groupId: id } }) @@ -80,14 +98,13 @@ export default function NavButtons() { await removeInput({ variables: { input: { - inputId: id - } - } + inputId: id, + }, + }, }) if (!removeInputStatus.loading) { controlDispatch({ type: 'REMOVE_INPUT', payload: { inputId: id } }) } - } } @@ -102,14 +119,9 @@ export default function NavButtons() { )} - + ) - - } diff --git a/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx index f8084e4a89e2..9ec1cbfcd0be 100644 --- a/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx +++ b/libs/portals/admin/form-system/src/components/Navbar/components/NavbarTab/NavbarTab.tsx @@ -1,14 +1,13 @@ import { Box, Inline } from '@island.is/island-ui/core' import cn from 'classnames' import * as styles from './NavbarTab.css' -import { Dispatch, SetStateAction, useContext } from 'react' -import FormBuilderContext from '../../../../context/FormBuilderContext' +import { useContext } from 'react' import { baseSettingsStep } from '../../../../utils/getBaseSettingsStep' import ControlContext from '../../../../context/ControlContext' - export default function NavbarTab() { - const { control, controlDispatch, inSettings, setInSettings } = useContext(ControlContext) + const { control, controlDispatch, inSettings, setInSettings } = + useContext(ControlContext) const { stepsList: steps } = control.form return ( @@ -19,14 +18,14 @@ export default function NavbarTab() { [styles.selected]: !inSettings, })} onClick={() => { - const step = steps?.find(s => s?.type === 'Innsláttur') + const step = steps?.find((s) => s?.type === 'Innsláttur') controlDispatch({ type: 'SET_ACTIVE_ITEM', payload: { activeItem: { type: 'Step', data: step, - } + }, }, }) setInSettings(false) @@ -46,7 +45,7 @@ export default function NavbarTab() { activeItem: { type: 'Step', data: baseSettingsStep, - } + }, }, }) setInSettings(true) diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx index 409a2252b447..517b924682b2 100644 --- a/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/NavbarSelect.tsx @@ -1,9 +1,13 @@ import { useContext } from 'react' import { Box, Text } from '@island.is/island-ui/core' import SelectNavComponent from './components/SelectNavComponent' -import { NavbarSelectStatus } from '../../types/interfaces' import ControlContext from '../../context/ControlContext' -import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' +import { + FormSystemGroup, + FormSystemInput, + FormSystemStep, +} from '@island.is/api/schema' +import { NavbarSelectStatus } from '../../lib/utils/interfaces' export default function NavbarSelect() { const { control, selectStatus } = useContext(ControlContext) diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx index 06b75540195a..595ccf20a165 100644 --- a/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/components/SelectNavComponent.tsx @@ -3,12 +3,12 @@ import * as styles from './selectNavComponent.css' import { Box, Checkbox } from '@island.is/island-ui/core' import { useContext } from 'react' import { - ItemType, - NavbarSelectStatus, -} from '../../../types/interfaces' -import FormBuilderContext from '../../../context/FormBuilderContext' -import { FormSystemGroup, FormSystemInput, FormSystemStep } from '@island.is/api/schema' + FormSystemGroup, + FormSystemInput, + FormSystemStep, +} from '@island.is/api/schema' import ControlContext from '../../../context/ControlContext' +import { ItemType, NavbarSelectStatus } from '../../../lib/utils/interfaces' type Props = { type: ItemType @@ -23,15 +23,16 @@ export default function SelectNavComponent({ active, selectable, }: Props) { - const { control, controlDispatch, selectStatus } = useContext(ControlContext) + const { control, selectStatus, controlDispatch, updateSettings } = + useContext(ControlContext) const { activeItem, activeListItem, form } = control const activeGuid = selectStatus === NavbarSelectStatus.LIST_ITEM ? activeListItem?.guid ?? '' : activeItem?.data?.guid ?? '' - const connected = - form.dependencies[activeGuid]?.includes(data.guid as string) || - !form.dependencies + const connected: boolean = form.dependencies[activeGuid]?.includes( + data.guid as string, + ) const truncateText = (text: string, maxLength: number) => { return text.length > maxLength ? text.slice(0, maxLength) + '...' : text @@ -72,6 +73,7 @@ export default function SelectNavComponent({ return truncateText(name, maxLength) } + return ( {selectable && ( - + { - // formDispatch({ - // type: 'addRemoveConnection', - // payload: { - // active: activeGuid, - // item: data.guid, - // }, - // }) - // }} + onChange={() => + controlDispatch({ + type: 'TOGGLE_DEPENDENCY', + payload: { + activeId: activeGuid, + itemId: data.guid as string, + update: updateSettings, + }, + }) + } /> )} @@ -142,6 +145,4 @@ export default function SelectNavComponent({ )} ) - - } diff --git a/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts b/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts index 8db4cbdbcc55..e906fdb3b246 100644 --- a/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts +++ b/libs/portals/admin/form-system/src/components/NavbarSelect/components/selectNavComponent.css.ts @@ -88,3 +88,7 @@ export const navBackgroundDefault = styleVariants({ export const customBackgroundDropdown = style({ background: theme.color.blue100, }) + +export const selectableComponent = style({ + paddingTop: '10px', +}) diff --git a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx index 9f64f486cfd4..5b04a3f8cf44 100644 --- a/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx +++ b/libs/portals/admin/form-system/src/components/TableRow/TableRow.tsx @@ -13,11 +13,11 @@ import { AnimatePresence, motion } from 'framer-motion' import { useNavigate } from 'react-router-dom' import TranslationTag from '../TranslationTag/TranslationTag' import { formatDate } from '../../utils/formatDate' +import { FormSystemPaths } from '../../lib/paths' import { - ApplicationTemplateStatus, LicenseProviderEnum, -} from '../../types/enums' -import { FormSystemPaths } from '../../lib/paths' + ApplicationTemplateStatus, +} from '../../lib/utils/interfaces' interface Props { id?: number | null @@ -101,12 +101,14 @@ const TableRow = ({ { title: 'Breyta', onClick: () => { - navigate(FormSystemPaths.Form.replace(':formId', String(id)), + navigate( + FormSystemPaths.Form.replace(':formId', String(id)), { state: { - formId: id - } - }) + formId: id, + }, + }, + ) }, }, { diff --git a/libs/portals/admin/form-system/src/context/ControlContext.ts b/libs/portals/admin/form-system/src/context/ControlContext.ts index 94eba4db0f17..46b8aad1460d 100644 --- a/libs/portals/admin/form-system/src/context/ControlContext.ts +++ b/libs/portals/admin/form-system/src/context/ControlContext.ts @@ -1,8 +1,18 @@ -import { Dispatch, createContext } from "react" -import { ControlAction, ControlState } from "../hooks/controlReducer" -import { Maybe } from "graphql/jsutils/Maybe" -import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemInput, FormSystemListItem, FormSystemListType } from "@island.is/api/schema" -import { ActiveItem, ItemType, NavbarSelectStatus } from "../lib/utils/interfaces" +import { Dispatch, createContext } from 'react' +import { ControlAction, ControlState } from '../hooks/controlReducer' +import { Maybe } from 'graphql/jsutils/Maybe' +import { + FormSystemApplicantType, + FormSystemDocumentType, + FormSystemForm, + FormSystemInput, + FormSystemListType, +} from '@island.is/api/schema' +import { + ActiveItem, + ItemType, + NavbarSelectStatus, +} from '../lib/utils/interfaces' export interface IControlContext { control: ControlState @@ -17,12 +27,11 @@ export interface IControlContext { focus: string setFocus: Dispatch updateDnD: (type: ItemType) => void - formSettingsUpdate: (updatedForm?: FormSystemForm) => void selectStatus: NavbarSelectStatus setSelectStatus: Dispatch formUpdate: (updatedForm?: FormSystemForm) => void inListBuilder: boolean - setInListBuilder: Dispatch, + setInListBuilder: Dispatch updateSettings: (updatedForm?: FormSystemForm) => void } @@ -49,9 +58,6 @@ const ControlContext = createContext({ updateDnD: function (_type: ItemType): void { throw new Error('Function not implemented.') }, - formSettingsUpdate: function (_updatedForm?: FormSystemForm): void { - throw new Error('Function not implemented.') - }, selectStatus: NavbarSelectStatus.OFF, setSelectStatus: function (_value: NavbarSelectStatus): void { throw new Error('Function not implemented.') @@ -65,7 +71,7 @@ const ControlContext = createContext({ }, updateSettings: function (_updatedForm?: FormSystemForm): void { throw new Error('Function not implemented.') - } + }, }) export default ControlContext diff --git a/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx b/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx deleted file mode 100644 index 0cef53037510..000000000000 --- a/libs/portals/admin/form-system/src/context/FormBuilderContext.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { FocusEvent, SetStateAction, createContext } from 'react' -import { - ActiveItem, - IFormBuilder, - IFormBuilderContext, - IGroup, - IInput, - IListItem, - IStep, - NavbarSelectStatus, - ILists -} from '../types/interfaces' - -const FormBuilderContext = createContext({ - // formBuilder: {} as IFormBuilder, - // formDispatch: function (_value: unknown): void { - // throw new Error('Function not implemented.') - // }, - // lists: { - // activeItem: {} as ActiveItem, - // steps: [] as IStep[], - // groups: [] as IGroup[], - // inputs: [] as IInput[], - // }, - lists: {} as ILists, - formUpdate: async function (): Promise { - throw new Error('Function not implemented.') - }, - inSettings: false, - setInSettings: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - setSelectStatus: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - selectStatus: NavbarSelectStatus.OFF, - setActiveListItem: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - blur: function ( - _e: FocusEvent, - ): void { - throw new Error('Function not implemented.') - }, - onFocus: function (_e: string): void { - throw new Error('Function not implemented.') - }, -}) - -export default FormBuilderContext diff --git a/libs/portals/admin/form-system/src/context/LayoutContext.tsx b/libs/portals/admin/form-system/src/context/LayoutContext.tsx deleted file mode 100644 index 82bed301b7aa..000000000000 --- a/libs/portals/admin/form-system/src/context/LayoutContext.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext } from 'react' -import { ILayoutContext } from '../types/interfaces' - -const LayoutContext = createContext({ - info: { - organization: '', - applicationName: '', - }, - infoDispatch: function (_value: unknown): void { - throw new Error('Function not implemented.') - }, -}) - -export default LayoutContext diff --git a/libs/portals/admin/form-system/src/context/UserContext.tsx b/libs/portals/admin/form-system/src/context/UserContext.tsx deleted file mode 100644 index b59d839d23b2..000000000000 --- a/libs/portals/admin/form-system/src/context/UserContext.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { createContext } from "react"; -import { User } from "../types/interfaces"; - - -const UserContext = createContext({ - isAuthenticated: false, - setIsAuthenticated: (_: boolean) => undefined, - user: null as unknown as User, - setUser: (_: User) => undefined, - userLoading: false, -}) - -export default UserContext diff --git a/libs/portals/admin/form-system/src/gql/Form.graphql b/libs/portals/admin/form-system/src/gql/Form.graphql index 5a47f0fdb018..67304c9e1714 100644 --- a/libs/portals/admin/form-system/src/gql/Form.graphql +++ b/libs/portals/admin/form-system/src/gql/Form.graphql @@ -1,12 +1,8 @@ -mutation formSystemUpdateForm( - $input: FormSystemUpdateFormInput! -) { +mutation formSystemUpdateForm($input: FormSystemUpdateFormInput!) { formSystemUpdateForm(input: $input) } -query formSystemGetForm( - $input: FormSystemGetFormInput! -) { +query formSystemGetForm($input: FormSystemGetFormInput!) { formSystemGetForm(input: $input) { form { id @@ -255,33 +251,30 @@ query formSystemGetForm( type } inputTypes { - description { + description { + is + en + } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings + isHidden + isPartOfMultiSet + isRequired + name { is en - } - displayOrder - groupGuid - groupId - guid - id - inputFields - inputSettings - isHidden - isPartOfMultiSet - isRequired - name { - is - en - } - type } + type + } } } - -mutation formSystemCreateForm( - $input: FormSystemCreateFormInput! -) { +mutation formSystemCreateForm($input: FormSystemCreateFormInput!) { formSystemCreateForm(input: $input) { form { id @@ -353,8 +346,8 @@ mutation formSystemCreateForm( } inputsList { description { - is - en + is + en } displayOrder groupGuid @@ -585,31 +578,29 @@ mutation formSystemCreateForm( type } inputTypes { - description { + description { is en - } - displayOrder - groupGuid - groupId - guid - id - inputFields - inputSettings - isHidden - isPartOfMultiSet - isRequired - name { - is - en - } - type } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } } } -mutation formSystemDeleteForm( - $input: FormSystemDeleteFormInput! -) { +mutation formSystemDeleteForm($input: FormSystemDeleteFormInput!) { formSystemDeleteForm(input: $input) } diff --git a/libs/portals/admin/form-system/src/gql/Group.graphql b/libs/portals/admin/form-system/src/gql/Group.graphql index 8538f403282c..5f6b252c7faf 100644 --- a/libs/portals/admin/form-system/src/gql/Group.graphql +++ b/libs/portals/admin/form-system/src/gql/Group.graphql @@ -1,6 +1,4 @@ -mutation formSystemCreateGroup( - $input: FormSystemCreateGroupInput! -) { +mutation formSystemCreateGroup($input: FormSystemCreateGroupInput!) { formSystemCreateGroup(input: $input) { displayOrder guid @@ -37,14 +35,10 @@ mutation formSystemCreateGroup( } } -mutation formSystemDeleteGroup( - $input: FormSystemDeleteGroupInput! -) { +mutation formSystemDeleteGroup($input: FormSystemDeleteGroupInput!) { formSystemDeleteGroup(input: $input) } -mutation formSystemUpdateGroup( - $input: FormSystemUpdateGroupInput! -) { +mutation formSystemUpdateGroup($input: FormSystemUpdateGroupInput!) { formSystemUpdateGroup(input: $input) } diff --git a/libs/portals/admin/form-system/src/gql/Input.graphql b/libs/portals/admin/form-system/src/gql/Input.graphql index be4ab3532e6a..49ed57fb8a88 100644 --- a/libs/portals/admin/form-system/src/gql/Input.graphql +++ b/libs/portals/admin/form-system/src/gql/Input.graphql @@ -1,6 +1,4 @@ -mutation formSystemCreateInput( - $input: FormSystemCreateInputInput! - ) { +mutation formSystemCreateInput($input: FormSystemCreateInputInput!) { formSystemCreateInput(input: $input) { id name { @@ -24,21 +22,15 @@ mutation formSystemCreateInput( } } -mutation formSystemDeleteInput( - $input: FormSystemDeleteInputInput! -) { +mutation formSystemDeleteInput($input: FormSystemDeleteInputInput!) { formSystemDeleteInput(input: $input) } -mutation formSystemUpdateInput( - $input: FormSystemUpdateInputInput! -) { +mutation formSystemUpdateInput($input: FormSystemUpdateInputInput!) { formSystemUpdateInput(input: $input) } -query formSystemGetInput( - $input: FormSystemGetInputInput! -) { +query formSystemGetInput($input: FormSystemGetInputInput!) { formSystemGetInput(input: $input) { id name { diff --git a/libs/portals/admin/form-system/src/gql/Step.graphql b/libs/portals/admin/form-system/src/gql/Step.graphql index 7346ff6b086e..5e5f138330da 100644 --- a/libs/portals/admin/form-system/src/gql/Step.graphql +++ b/libs/portals/admin/form-system/src/gql/Step.graphql @@ -1,6 +1,4 @@ -mutation formSystemCreateStep( - $input: FormSystemCreateStepInput! -) { +mutation formSystemCreateStep($input: FormSystemCreateStepInput!) { formSystemCreateStep(input: $input) { callRuleset displayOrder @@ -54,14 +52,10 @@ mutation formSystemCreateStep( } } -mutation formSystemDeleteStep( - $input: FormSystemDeleteStepInput! -) { +mutation formSystemDeleteStep($input: FormSystemDeleteStepInput!) { formSystemDeleteStep(input: $input) } -mutation formSystemUpdateStep( - $input: FormSystemUpdateStepInput! -) { +mutation formSystemUpdateStep($input: FormSystemUpdateStepInput!) { formSystemUpdateStep(input: $input) } diff --git a/libs/portals/admin/form-system/src/hooks/controlReducer.ts b/libs/portals/admin/form-system/src/hooks/controlReducer.ts index fa5b61323f29..236fb3521be2 100644 --- a/libs/portals/admin/form-system/src/hooks/controlReducer.ts +++ b/libs/portals/admin/form-system/src/hooks/controlReducer.ts @@ -1,57 +1,168 @@ -import { FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemListItem, FormSystemStep } from "@island.is/api/schema" -import { ActiveItem, IInputSettings } from "../types/interfaces" -import { UniqueIdentifier } from "@dnd-kit/core" -import { arrayMove } from "@dnd-kit/sortable" -import { removeTypename } from "../lib/utils/removeTypename" -import { uuid } from "uuidv4" +import { + FormSystemForm, + FormSystemGroup, + FormSystemInput, + FormSystemListItem, + FormSystemStep, +} from '@island.is/api/schema' +import { UniqueIdentifier } from '@dnd-kit/core' +import { arrayMove } from '@dnd-kit/sortable' +import { removeTypename } from '../lib/utils/removeTypename' +import { uuid } from 'uuidv4' +import { ActiveItem, InputSettings } from '../lib/utils/interfaces' type ActiveItemActions = - | { type: 'SET_ACTIVE_ITEM', payload: { activeItem: ActiveItem } } - | { type: 'SET_ACTIVE_LIST_ITEM', payload: { listItem: FormSystemListItem | null } } + | { type: 'SET_ACTIVE_ITEM'; payload: { activeItem: ActiveItem } } + | { + type: 'SET_ACTIVE_LIST_ITEM' + payload: { listItem: FormSystemListItem | null } + } type GroupActions = - | { type: 'ADD_GROUP', payload: { group: FormSystemGroup } } - | { type: 'REMOVE_GROUP', payload: { groupId: number } } + | { type: 'ADD_GROUP'; payload: { group: FormSystemGroup } } + | { type: 'REMOVE_GROUP'; payload: { groupId: number } } type InputActions = - | { type: 'ADD_INPUT', payload: { input: FormSystemInput } } - | { type: 'REMOVE_INPUT', payload: { inputId: number } } - | { type: 'CHANGE_INPUT_TYPE', payload: { newValue: string, inputSettings: IInputSettings, update: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'CHANGE_DESCRIPTION', payload: { lang: 'en' | 'is', newValue: string } } - | { type: 'CHANGE_IS_REQUIRED', payload: { update: (updatedActiveItem?: ActiveItem) => void } } - + | { type: 'ADD_INPUT'; payload: { input: FormSystemInput } } + | { type: 'REMOVE_INPUT'; payload: { inputId: number } } + | { + type: 'CHANGE_INPUT_TYPE' + payload: { + newValue: string + inputSettings: InputSettings + update: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'CHANGE_DESCRIPTION' + payload: { lang: 'en' | 'is'; newValue: string } + } + | { + type: 'CHANGE_IS_REQUIRED' + payload: { update: (updatedActiveItem?: ActiveItem) => void } + } type StepActions = - | { type: 'ADD_STEP', payload: { step: FormSystemStep } } - | { type: 'REMOVE_STEP', payload: { stepId: number } } + | { type: 'ADD_STEP'; payload: { step: FormSystemStep } } + | { type: 'REMOVE_STEP'; payload: { stepId: number } } type DndActions = - | { type: 'STEP_OVER_STEP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } - | { type: 'GROUP_OVER_STEP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } - | { type: 'GROUP_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } - | { type: 'INPUT_OVER_GROUP', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } - | { type: 'INPUT_OVER_INPUT', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } - | { type: 'LIST_ITEM_OVER_LIST_ITEM', payload: { activeId: UniqueIdentifier, overId: UniqueIdentifier } } + | { + type: 'STEP_OVER_STEP' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'GROUP_OVER_STEP' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'GROUP_OVER_GROUP' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'INPUT_OVER_GROUP' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'INPUT_OVER_INPUT' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } + | { + type: 'LIST_ITEM_OVER_LIST_ITEM' + payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } + } type ChangeActions = - | { type: 'CHANGE_NAME', payload: { lang: 'en' | 'is', newValue: string } } - | { type: 'CHANGE_FORM_NAME', payload: { lang: 'en' | 'is', newValue: string } } - | { type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE', payload: { value: number } } - | { type: 'CHANGE_INVALIDATION_DATE', payload: { value: Date } } - | { type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP', payload: { value: boolean } } - | { type: 'CHANGE_FORM_SETTINGS', payload: { newForm: FormSystemForm } } + | { type: 'CHANGE_NAME'; payload: { lang: 'en' | 'is'; newValue: string } } + | { + type: 'CHANGE_FORM_NAME' + payload: { lang: 'en' | 'is'; newValue: string } + } + | { type: 'CHANGE_APPLICATION_DAYS_TO_REMOVE'; payload: { value: number } } + | { type: 'CHANGE_INVALIDATION_DATE'; payload: { value: Date } } + | { + type: 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP' + payload: { value: boolean } + } + | { type: 'CHANGE_FORM_SETTINGS'; payload: { newForm: FormSystemForm } } + | { + type: 'TOGGLE_DEPENDENCY' + payload: { + activeId: string + itemId: string + update: (updatedForm: FormSystemForm) => void + } + } + | { + type: 'TOGGLE_MULTI_SET' + payload: { + checked: boolean + update: (updatedActiveItem?: ActiveItem) => void + } + } type InputSettingsActions = - | { type: 'SET_MESSAGE_WITH_LINK_SETTINGS', payload: { property: 'buttonText' | 'url' | 'hasLink', value?: string, checked?: boolean, lang?: 'is' | 'en', update?: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'SET_FILE_UPLOAD_SETTINGS', payload: { property: 'isMulti' | 'maxSize' | 'amount' | 'types', checked?: boolean, value?: string | number, update: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'SET_INPUT_SETTINGS', payload: { property: 'isLarge', value: boolean, update: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'SET_LIST_ITEM_SELECTED', payload: { guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'REMOVE_LIST_ITEM', payload: { guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } - | { type: 'CHANGE_LIST_ITEM', payload: { property: 'label' | 'description', lang: 'is' | 'en', value: string, guid: UniqueIdentifier, update: (updatedActiveItem?: ActiveItem) => void } } + | { + type: 'SET_MESSAGE_WITH_LINK_SETTINGS' + payload: { + property: 'buttonText' | 'url' | 'hasLink' + value?: string + checked?: boolean + lang?: 'is' | 'en' + update?: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'SET_FILE_UPLOAD_SETTINGS' + payload: { + property: 'isMulti' | 'maxSize' | 'amount' | 'types' + checked?: boolean + value?: string | number + update: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'SET_INPUT_SETTINGS' + payload: { + property: 'isLarge' + value: boolean + update: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'SET_LIST_ITEM_SELECTED' + payload: { + guid: UniqueIdentifier + update: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'REMOVE_LIST_ITEM' + payload: { + guid: UniqueIdentifier + update: (updatedActiveItem?: ActiveItem) => void + } + } + | { + type: 'CHANGE_LIST_ITEM' + payload: { + property: 'label' | 'description' + lang: 'is' | 'en' + value: string + guid: UniqueIdentifier + update: (updatedActiveItem?: ActiveItem) => void + } + } | { type: 'ADD_LIST_ITEM' } - -export type ControlAction = ActiveItemActions | GroupActions | InputActions | StepActions | DndActions | ChangeActions | InputSettingsActions +export type ControlAction = + | ActiveItemActions + | GroupActions + | InputActions + | StepActions + | DndActions + | ChangeActions + | InputSettingsActions export interface ControlState { activeItem: ActiveItem @@ -59,20 +170,22 @@ export interface ControlState { form: FormSystemForm } -export const controlReducer = (state: ControlState, action: ControlAction): ControlState => { +export const controlReducer = ( + state: ControlState, + action: ControlAction, +): ControlState => { const { form, activeItem } = state const { stepsList: steps, groupsList: groups, inputsList: inputs } = form switch (action.type) { case 'SET_ACTIVE_ITEM': - console.log('current active item', action.payload.activeItem) return { ...state, - activeItem: action.payload.activeItem + activeItem: action.payload.activeItem, } case 'SET_ACTIVE_LIST_ITEM': { return { ...state, - activeListItem: action.payload.listItem + activeListItem: action.payload.listItem, } } // Steps @@ -81,21 +194,23 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, activeItem: { type: 'Step', - data: action.payload.step + data: action.payload.step, }, form: { ...form, - stepsList: [...(steps || []), action.payload.step] - } + stepsList: [...(steps || []), action.payload.step], + }, } case 'REMOVE_STEP': { - const newSteps = state.form.stepsList?.filter((step) => step?.id !== action.payload.stepId) + const newSteps = state.form.stepsList?.filter( + (step) => step?.id !== action.payload.stepId, + ) return { ...state, form: { ...form, - stepsList: newSteps - } + stepsList: newSteps, + }, } } @@ -105,69 +220,76 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, activeItem: { type: 'Group', - data: action.payload.group + data: action.payload.group, }, form: { ...form, - groupsList: [...(groups || []), action.payload.group] - } + groupsList: [...(groups || []), action.payload.group], + }, } case 'REMOVE_GROUP': { - const newGroups = state.form.groupsList?.filter((group) => group?.id !== action.payload.groupId) + const newGroups = state.form.groupsList?.filter( + (group) => group?.id !== action.payload.groupId, + ) const currentItem = state.activeItem.data as FormSystemGroup - const newActiveItem = state.form.stepsList?.find((step) => step?.guid === currentItem.stepGuid) + const newActiveItem = state.form.stepsList?.find( + (step) => step?.guid === currentItem.stepGuid, + ) return { ...state, activeItem: { type: 'Step', - data: newActiveItem + data: newActiveItem, }, form: { ...form, - groupsList: newGroups - } + groupsList: newGroups, + }, } } // Inputs case 'ADD_INPUT': - console.log('adding input reducer', action.payload.input) return { ...state, activeItem: { type: 'Input', - data: action.payload.input + data: action.payload.input, }, form: { ...form, - inputsList: [...(inputs || []), action.payload.input] - } + inputsList: [...(inputs || []), action.payload.input], + }, } case 'REMOVE_INPUT': { - const newInputs = state.form.inputsList?.filter((input) => input?.id !== action.payload.inputId) + const newInputs = state.form.inputsList?.filter( + (input) => input?.id !== action.payload.inputId, + ) const currentItem = state.activeItem.data as FormSystemInput - const newActiveItem = state.form.groupsList?.find((group) => group?.guid === currentItem.groupGuid) + const newActiveItem = state.form.groupsList?.find( + (group) => group?.guid === currentItem.groupGuid, + ) return { ...state, activeItem: { type: 'Group', - data: newActiveItem + data: newActiveItem, }, form: { ...form, - inputsList: newInputs - } + inputsList: newInputs, + }, } } case 'CHANGE_INPUT_TYPE': { - const { newValue, inputSettings, update } = action.payload; + const { newValue, inputSettings, update } = action.payload const newActive = { ...activeItem, data: { ...activeItem.data, type: newValue, - inputSettings: removeTypename(inputSettings) - } + inputSettings: removeTypename(inputSettings), + }, } update(newActive) return { @@ -175,8 +297,10 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont activeItem: newActive, form: { ...form, - inputsList: inputs?.map(i => i?.guid === activeItem.data?.guid ? newActive.data : i) - } + inputsList: inputs?.map((i) => + i?.guid === activeItem.data?.guid ? newActive.data : i, + ), + }, } } case 'CHANGE_DESCRIPTION': { @@ -188,28 +312,29 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...currentData, description: { ...currentData?.description, - [lang]: newValue - } - } - }; + [lang]: newValue, + }, + }, + } return { ...state, activeItem: newActive, form: { ...form, - inputsList: inputs?.map(i => i?.guid === currentData?.guid ? newActive.data : i) - } + inputsList: inputs?.map((i) => + i?.guid === currentData?.guid ? newActive.data : i, + ), + }, } } case 'CHANGE_IS_REQUIRED': { const currentData = activeItem.data as FormSystemInput - console.log(currentData) const newActive = { ...activeItem, data: { ...currentData, - isRequired: !currentData?.isRequired - } + isRequired: !currentData?.isRequired, + }, } action.payload.update(newActive) return { @@ -217,55 +342,72 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont activeItem: newActive, form: { ...form, - inputsList: inputs?.map(i => i?.guid === currentData?.guid ? newActive.data : i) - } + inputsList: inputs?.map((i) => + i?.guid === currentData?.guid ? newActive.data : i, + ), + }, } } // Change case 'CHANGE_NAME': { - const { lang, newValue } = action.payload; + const { lang, newValue } = action.payload const newActive = { ...activeItem, data: { ...activeItem.data, name: { ...activeItem.data?.name, - [lang]: newValue - } - } - }; - const { type } = activeItem; - let updatedList; + [lang]: newValue, + }, + }, + } + const { type } = activeItem + let updatedList if (type === 'Step') { - updatedList = steps?.map(s => s?.guid === activeItem.data?.guid ? newActive.data : s); + updatedList = steps?.map((s) => + s?.guid === activeItem.data?.guid ? newActive.data : s, + ) } else if (type === 'Group') { - updatedList = groups?.map(g => g?.guid === activeItem.data?.guid ? newActive.data : g); + updatedList = groups?.map((g) => + g?.guid === activeItem.data?.guid ? newActive.data : g, + ) } else if (type === 'Input') { - updatedList = inputs?.map(i => i?.guid === activeItem.data?.guid ? newActive.data : i); + updatedList = inputs?.map((i) => + i?.guid === activeItem.data?.guid ? newActive.data : i, + ) } return { ...state, activeItem: newActive, form: { ...form, - stepsList: type === 'Step' ? updatedList as FormSystemStep[] : form.stepsList, - groupsList: type === 'Group' ? updatedList as FormSystemGroup[] : form.groupsList, - inputsList: type === 'Input' ? updatedList as FormSystemInput[] : form.inputsList - } + stepsList: + type === 'Step' + ? (updatedList as FormSystemStep[]) + : form.stepsList, + groupsList: + type === 'Group' + ? (updatedList as FormSystemGroup[]) + : form.groupsList, + inputsList: + type === 'Input' + ? (updatedList as FormSystemInput[]) + : form.inputsList, + }, } } case 'CHANGE_FORM_NAME': { - const { lang, newValue } = action.payload; + const { lang, newValue } = action.payload return { ...state, form: { ...form, name: { ...form.name, - [lang]: newValue - } - } + [lang]: newValue, + }, + }, } } case 'CHANGE_APPLICATION_DAYS_TO_REMOVE': { @@ -273,8 +415,8 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - applicationsDaysToRemove: action.payload.value - } + applicationsDaysToRemove: action.payload.value, + }, } } case 'CHANGE_INVALIDATION_DATE': { @@ -282,14 +424,14 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - invalidationDate: action.payload.value - } + invalidationDate: action.payload.value, + }, } } case 'CHANGE_FORM_SETTINGS': { return { ...state, - form: action.payload.newForm + form: action.payload.newForm, } } case 'CHANGE_STOP_PROGRESS_ON_VALIDATING_STEP': { @@ -297,8 +439,57 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - stopProgressOnValidatingStep: action.payload.value + stopProgressOnValidatingStep: action.payload.value, + }, + } + } + case 'TOGGLE_DEPENDENCY': { + const { activeId, itemId, update } = action.payload + const dependencies = { ...form.dependencies } ?? {} + if (activeId in dependencies) { + if (!dependencies[activeId].includes(itemId)) { + dependencies[activeId] = [...dependencies[activeId], itemId] + } else { + dependencies[activeId] = dependencies[activeId].filter( + (t: string) => t !== itemId, + ) + if (dependencies[activeId].length === 0) { + delete dependencies[activeId] + } } + } else { + dependencies[activeId] = [itemId] + } + const updatedForm = { + ...form, + dependencies: dependencies, + } + update(updatedForm) + return { + ...state, + form: updatedForm, + } + } + + case 'TOGGLE_MULTI_SET': { + const currentData = activeItem.data as FormSystemGroup + const newActive = { + ...activeItem, + data: { + ...currentData, + multiSet: action.payload.checked ? 1 : 0, + }, + } + action.payload.update(newActive) + return { + ...state, + activeItem: newActive, + form: { + ...form, + groupsList: groups?.map((g) => + g?.guid === currentData?.guid ? newActive.data : g, + ), + }, } } // Input settings @@ -314,12 +505,12 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont [property]: property === 'hasLink' ? checked : value, ...(property === 'buttonText' ? { - buttonText: { - ...input.inputSettings?.buttonText, - [lang]: value + buttonText: { + ...input.inputSettings?.buttonText, + [lang]: value, + }, } - } - : {}) + : {}), }, } if (property === 'hasLink' && update) { @@ -329,12 +520,14 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'SET_FILE_UPLOAD_SETTINGS': { @@ -342,7 +535,7 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont const { property, checked, value, update } = action.payload const updateFileTypesArray = (): string[] => { - const newFileTypes = input.inputSettings?.types as string[] ?? [] + const newFileTypes = (input.inputSettings?.types as string[]) ?? [] if (checked) { return [...newFileTypes, value as string] } else { @@ -353,22 +546,27 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - [property]: property === 'types' ? updateFileTypesArray() : property === 'isMulti' ? checked : value - } + [property]: + property === 'types' + ? updateFileTypesArray() + : property === 'isMulti' + ? checked + : value, + }, } - console.log('property', property, 'value', value, 'checked', checked) - console.log('new input: ', newInput) update({ type: 'Input', data: newInput }) return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'SET_INPUT_SETTINGS': { @@ -378,20 +576,22 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - [property]: value - } + [property]: value, + }, } update({ type: 'Input', data: newInput }) return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'SET_LIST_ITEM_SELECTED': { @@ -406,21 +606,22 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont l.guid === guid ? { ...l, isSelected: !l.isSelected } : { ...l, isSelected: false }, - ) - } + ), + }, } update({ type: 'Input', data: newInput }) return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } - + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'REMOVE_LIST_ITEM': { @@ -431,20 +632,22 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...input, inputSettings: { ...input.inputSettings, - list: list.filter((l: FormSystemListItem) => l.guid !== guid) - } + list: list.filter((l: FormSystemListItem) => l.guid !== guid), + }, } update({ type: 'Input', data: newInput }) return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'ADD_LIST_ITEM': { @@ -461,21 +664,23 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont label: { is: '', en: '' }, description: { is: '', en: '' }, displayOrder: list.length, - isSelected: false - } - ] - } + isSelected: false, + }, + ], + }, } return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } case 'CHANGE_LIST_ITEM': { @@ -506,33 +711,40 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } // Drag and Drop case 'STEP_OVER_STEP': { - const activeIndex = steps?.findIndex((step) => step?.guid === action.payload.activeId) as number - const overIndex = steps?.findIndex((step) => step?.guid === action.payload.overId) as number + const activeIndex = steps?.findIndex( + (step) => step?.guid === action.payload.activeId, + ) as number + const overIndex = steps?.findIndex( + (step) => step?.guid === action.payload.overId, + ) as number const updatedSteps = arrayMove(steps || [], activeIndex, overIndex) return { ...state, form: { ...form, - stepsList: updatedSteps.map((s, i) => ({ ...s, displayOrder: i })) - } + stepsList: updatedSteps.map((s, i) => ({ ...s, displayOrder: i })), + }, } } case 'GROUP_OVER_STEP': { - const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number - const overIndex = steps?.findIndex((step) => step?.guid === action.payload.overId) as number - if (groups && steps) { - console.log('active: ', groups[activeIndex], 'over: ', steps[overIndex]) - } + const activeIndex = groups?.findIndex( + (group) => group?.guid === action.payload.activeId, + ) as number + const overIndex = steps?.findIndex( + (step) => step?.guid === action.payload.overId, + ) as number const updatedGroups = groups as FormSystemGroup[] if (steps && steps[overIndex]) { updatedGroups[activeIndex].stepGuid = action.payload.overId as string @@ -542,40 +754,62 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - groupsList: arrayMove(updatedGroups, activeIndex, activeIndex).map((g, i) => ({ ...g, displayOrder: i })) - } + groupsList: arrayMove(updatedGroups, activeIndex, activeIndex).map( + (g, i) => ({ ...g, displayOrder: i }), + ), + }, } } case 'GROUP_OVER_GROUP': { - const activeIndex = groups?.findIndex((group) => group?.guid === action.payload.activeId) as number - const overIndex = groups?.findIndex((group) => group?.guid === action.payload.overId) as number + const activeIndex = groups?.findIndex( + (group) => group?.guid === action.payload.activeId, + ) as number + const overIndex = groups?.findIndex( + (group) => group?.guid === action.payload.overId, + ) as number const updatedGroups = groups as FormSystemGroup[] if (updatedGroups[activeIndex] && updatedGroups[overIndex]) { - if (updatedGroups[activeIndex].stepGuid !== updatedGroups[overIndex].stepGuid) { - updatedGroups[activeIndex].stepGuid = updatedGroups[overIndex].stepGuid + if ( + updatedGroups[activeIndex].stepGuid !== + updatedGroups[overIndex].stepGuid + ) { + updatedGroups[activeIndex].stepGuid = + updatedGroups[overIndex].stepGuid updatedGroups[activeIndex].stepId = updatedGroups[overIndex].stepId return { ...state, form: { ...form, - groupsList: arrayMove(updatedGroups, activeIndex, overIndex - 1).map((g, i) => ({ ...g, displayOrder: i })) - } + groupsList: arrayMove( + updatedGroups, + activeIndex, + overIndex - 1, + ).map((g, i) => ({ ...g, displayOrder: i })), + }, } } return { ...state, form: { ...form, - groupsList: arrayMove(updatedGroups, activeIndex, overIndex).map((g, i) => ({ ...g, displayOrder: i })) - } + groupsList: arrayMove(updatedGroups, activeIndex, overIndex).map( + (g, i) => ({ ...g, displayOrder: i }), + ), + }, } } return state } case 'INPUT_OVER_GROUP': { - const activeIndex = inputs?.findIndex((input) => input?.guid === action.payload.activeId) as number - const overIndex = groups?.findIndex((group) => group?.guid === action.payload.overId) as number - const updatedInputs = inputs?.map(input => ({ ...input })) as FormSystemInput[] + const activeIndex = inputs?.findIndex( + (input) => input?.guid === action.payload.activeId, + ) as number + const overIndex = groups?.findIndex( + (group) => group?.guid === action.payload.overId, + ) as number + const updatedInputs = inputs?.map((input) => ({ + ...input, + })) as FormSystemInput[] if (groups && groups[overIndex]) { updatedInputs[activeIndex].groupGuid = action.payload.overId as string updatedInputs[activeIndex].groupId = groups[overIndex]?.id as number @@ -584,32 +818,50 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont ...state, form: { ...form, - inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map((i, index) => ({ ...i, displayOrder: index })) - } + inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map( + (i, index) => ({ ...i, displayOrder: index }), + ), + }, } } case 'INPUT_OVER_INPUT': { - const activeIndex = inputs?.findIndex((input) => input?.guid === action.payload.activeId) as number - const overIndex = inputs?.findIndex((input) => input?.guid === action.payload.overId) as number - const updatedInputs = inputs?.map(input => ({ ...input })) as FormSystemInput[] + const activeIndex = inputs?.findIndex( + (input) => input?.guid === action.payload.activeId, + ) as number + const overIndex = inputs?.findIndex( + (input) => input?.guid === action.payload.overId, + ) as number + const updatedInputs = inputs?.map((input) => ({ + ...input, + })) as FormSystemInput[] if (updatedInputs[activeIndex] && updatedInputs[overIndex]) { - if (updatedInputs[activeIndex].groupGuid !== updatedInputs[overIndex].groupGuid) { - updatedInputs[activeIndex].groupGuid = updatedInputs[overIndex].groupGuid + if ( + updatedInputs[activeIndex].groupGuid !== + updatedInputs[overIndex].groupGuid + ) { + updatedInputs[activeIndex].groupGuid = + updatedInputs[overIndex].groupGuid updatedInputs[activeIndex].groupId = updatedInputs[overIndex].groupId return { ...state, form: { ...form, - inputsList: arrayMove(updatedInputs, activeIndex, overIndex - 1).map((i, index) => ({ ...i, displayOrder: index })) - } + inputsList: arrayMove( + updatedInputs, + activeIndex, + overIndex - 1, + ).map((i, index) => ({ ...i, displayOrder: index })), + }, } } return { ...state, form: { ...form, - inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map((i, index) => ({ ...i, displayOrder: index })) - } + inputsList: arrayMove(updatedInputs, activeIndex, overIndex).map( + (i, index) => ({ ...i, displayOrder: index }), + ), + }, } } return state @@ -621,30 +873,37 @@ export const controlReducer = (state: ControlState, action: ControlAction): Cont if (!list) { return state } - const activeIndex = list.findIndex((item: FormSystemListItem) => item.guid === activeId) - const overIndex = list.findIndex((item: FormSystemListItem) => item.guid === overId) + const activeIndex = list.findIndex( + (item: FormSystemListItem) => item.guid === activeId, + ) + const overIndex = list.findIndex( + (item: FormSystemListItem) => item.guid === overId, + ) const newInput = { ...input, inputSettings: { ...input.inputSettings, - list: arrayMove(list, activeIndex, overIndex).map((l: FormSystemListItem, i: number) => ({ ...l, displayOrder: i })) - } + list: arrayMove(list, activeIndex, overIndex).map( + (l: FormSystemListItem, i: number) => ({ ...l, displayOrder: i }), + ), + }, } return { ...state, activeItem: { type: 'Input', - data: newInput + data: newInput, }, form: { ...form, - inputsList: inputs?.map(i => i?.guid === input.guid ? newInput : i) - } + inputsList: inputs?.map((i) => + i?.guid === input.guid ? newInput : i, + ), + }, } } default: return state } } - diff --git a/libs/portals/admin/form-system/src/hooks/formReducer.ts b/libs/portals/admin/form-system/src/hooks/formReducer.ts deleted file mode 100644 index 1a1fd6e1a371..000000000000 --- a/libs/portals/admin/form-system/src/hooks/formReducer.ts +++ /dev/null @@ -1,199 +0,0 @@ -/* eslint-disable func-style */ -import { UniqueIdentifier } from '@dnd-kit/core' -import { - ICertificate, - IFormBuilder, - ILanguage, - ITenging, -} from '../types/interfaces' -import { saveFormSettings } from '../services/apiService' - -type ILang = 'is' | 'en' - -type ChangeNameAction = { - type: 'changeName' - payload: { - lang: ILang - newName: string - } -} - -type ApplicationsDaysToRemoveAction = { - type: 'applicationsDaysToRemove' - payload: { - value: number - } -} - -type InvalidationDateAction = { - type: 'invalidationDate' - payload: { - value: Date - } -} - -type StopProgressOnValidatingStepAction = { - type: 'stopProgressOnValidatingStep' - payload: { - value: boolean - } -} - -type AddRemoveConnectionAction = { - type: 'addRemoveConnection' - payload: { - active: UniqueIdentifier - item: UniqueIdentifier - } -} - -type UpdateDocuments = { - type: 'updateDocuments' - payload: { - documents: ICertificate[] - } -} - -type FormSettingsPayload = - | { property: 'invalidationDate'; value: Date } - | { property: 'dependencies'; value: ITenging } - | { property: 'stopProgressOnValidatingStep'; value: boolean } - | { property: 'applicationsDaysToRemove'; value: number } - | { - property: 'formDocumentTypes' - value: { formId: number; documentTypeId: number }[] - } - | { property: 'adilar'; value: string[] } - | { property: 'completedMessage'; value: ILanguage } - | { property: 'isTranslated'; value: boolean } - -type FormSettingsAction = { - type: 'formSettings' - payload: FormSettingsPayload -} - -export type FormAction = - | ChangeNameAction - | ApplicationsDaysToRemoveAction - | InvalidationDateAction - | StopProgressOnValidatingStepAction - | AddRemoveConnectionAction - | FormSettingsAction - | UpdateDocuments - -export function formReducer(formBuilder: IFormBuilder, action: FormAction) { - switch (action.type) { - case 'changeName': { - const { lang, newName } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - name: { - ...formBuilder.form?.name, - [lang]: newName, - }, - }, - } - } - case 'applicationsDaysToRemove': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - applicationsDaysToRemove: value, - }, - } - } - case 'invalidationDate': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - invalidationDate: value, - }, - } - } - case 'stopProgressOnValidatingStep': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - stopProgressOnValidatingStep: value, - }, - } - } - case 'addRemoveConnection': { - const { active, item } = action.payload - const itemAsString = String(item) - const dependencies = { ...formBuilder.form?.dependencies } - - if (active in dependencies) { - if (!dependencies[active].includes(itemAsString)) { - dependencies[active] = [...dependencies[active], itemAsString] - } else { - dependencies[active] = dependencies[active].filter((t: UniqueIdentifier) => t !== item) - if (dependencies[active].length === 0) { - delete dependencies[active] - } - } - } else { - dependencies[active] = [itemAsString] - } - saveFormSettings(formBuilder.form?.id ?? 0, { - id: formBuilder.form?.id ?? 0, - dependencies: dependencies, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - dependencies, - }, - } - } - - case 'formSettings': { - const { property, value } = action.payload - const id = formBuilder.form?.id ?? 0 - saveFormSettings(id, { - id: id, - [property]: value, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - [property]: value, - }, - } - } - - case 'updateDocuments': { - const { documents } = action.payload - const saveDocuments = documents.map((d) => { - return { - formId: formBuilder.form?.id ?? 0, - documentTypeId: d.id, - } - }) - saveFormSettings(formBuilder.form?.id ?? 0, { - id: formBuilder.form?.id ?? 0, - formDocumentTypes: saveDocuments, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - documentTypes: documents, - }, - } - } - - default: - return formBuilder - } -} diff --git a/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts b/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts deleted file mode 100644 index a92d3484df39..000000000000 --- a/libs/portals/admin/form-system/src/hooks/headerInfoReducer.ts +++ /dev/null @@ -1,29 +0,0 @@ -export type FormHeaderAction = - | { type: 'changeOrganization'; payload: { value: string } } - | { type: 'changeApplicationName'; payload: { value: string } } - -export function headerInfoReducer( - info: { - organization: string - applicationName: string - }, - action: FormHeaderAction, -) { - switch (action.type) { - case 'changeOrganization': { - return { - ...info, - organization: action.payload?.value ? action.payload.value : '', - } - } - case 'changeApplicationName': { - return { - ...info, - applicationName: action.payload?.value ? action.payload.value : '', - } - } - default: { - return info - } - } -} diff --git a/libs/portals/admin/form-system/src/hooks/settingsReducer.ts b/libs/portals/admin/form-system/src/hooks/settingsReducer.ts deleted file mode 100644 index 2b1e82a977d9..000000000000 --- a/libs/portals/admin/form-system/src/hooks/settingsReducer.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { FormSystemApplicantType, FormSystemDocumentType, FormSystemInput, FormSystemListType } from "@island.is/api/schema" -import { Maybe } from "graphql/jsutils/Maybe" - - -export type SettingsState = { - applicantTypes: Maybe[]> | undefined - documentTypes: Maybe[]> | undefined - inputTypes: Maybe[]> | undefined - listTypes: Maybe[]> | undefined -} - -export type SettingsAction = - | { type: 'something', payload: 'something' } - -export const settingsReducer = (state: SettingsState, action: SettingsAction): SettingsState => { - - return state -} diff --git a/libs/portals/admin/form-system/src/hooks/useUser.ts b/libs/portals/admin/form-system/src/hooks/useUser.ts deleted file mode 100644 index bee6280737f9..000000000000 --- a/libs/portals/admin/form-system/src/hooks/useUser.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useSession } from 'next-auth/client' -import { useEffect, useState } from 'react' -import { User } from '../types/interfaces' - -export default function useUser() { - const [user, setUser] = useState() - const [session, loading] = useSession() - - const timeNow = Math.floor(Date.now() / 1000) - const expiryStr = session?.expires ? new Date(session.expires.replace(/['"]+/g, '')).getTime() : undefined - const expiry = Math.floor((expiryStr ?? 0) / 1000) - - const hasNotExpired = timeNow < expiry - - const [isAuthenticated, setIsAuthenticated] = useState( - Boolean(hasNotExpired), - ) - - useEffect(() => { - if (!hasNotExpired) { - setUser(undefined) - setIsAuthenticated(false) - sessionStorage.clear() - } else { - if (!user && session?.user) { - const { name = '', email, image } = session.user || {} - setUser({ name: name || '', email: email || '', image: image || '' }) - setIsAuthenticated(true); - } - } - }, [setUser, session, user]) - - return { - isAuthenticated, - setIsAuthenticated, - user, - setUser, - userLoading: loading, - } -} diff --git a/libs/portals/admin/form-system/src/lib/messages.ts b/libs/portals/admin/form-system/src/lib/messages.ts index c1124066891f..44416d48f081 100644 --- a/libs/portals/admin/form-system/src/lib/messages.ts +++ b/libs/portals/admin/form-system/src/lib/messages.ts @@ -1,15 +1,14 @@ -import { defineMessages } from "react-intl"; - +import { defineMessages } from 'react-intl' export const m = defineMessages({ formSystemIntro: { id: 'admin-portal.form-system:formSystemIntro', defaultMessage: 'Umsóknarsmiður', - description: '' + description: '', }, formSystemTitle: { id: 'admin-portal.form-system:Title', defaultMessage: 'Umsóknarsmiður', - description: '' - } + description: '', + }, }) diff --git a/libs/portals/admin/form-system/src/lib/navigation.ts b/libs/portals/admin/form-system/src/lib/navigation.ts index 9d54beeff3b8..82f03d85ffb5 100644 --- a/libs/portals/admin/form-system/src/lib/navigation.ts +++ b/libs/portals/admin/form-system/src/lib/navigation.ts @@ -5,7 +5,7 @@ import { FormSystemPaths } from './paths' export const formSystemNavigation: PortalNavigationItem = { name: m.formSystemTitle, icon: { - icon: 'settings' + icon: 'settings', }, description: m.formSystemIntro, path: FormSystemPaths.FormSystemRoot, @@ -13,7 +13,7 @@ export const formSystemNavigation: PortalNavigationItem = { { name: m.formSystemTitle, path: FormSystemPaths.Form, - activeIfExact: true - } - ] + activeIfExact: true, + }, + ], } diff --git a/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts b/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts index 95269f5716be..87eeeb048704 100644 --- a/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts +++ b/libs/portals/admin/form-system/src/lib/utils/fileTypes.ts @@ -1,15 +1,16 @@ export const fileTypes = { - ".pdf": "application/pdf", - ".doc": "application/msword", - ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - ".txt": "text/plain", - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".gif": "image/gif", - ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - ".xls": "application/vnd.ms-excel", - ".csv": "text/csv", - ".zip": "application/zip", - "*": "application/octet-stream" + '.pdf': 'application/pdf', + '.doc': 'application/msword', + '.docx': + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + '.txt': 'text/plain', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png': 'image/png', + '.gif': 'image/gif', + '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + '.xls': 'application/vnd.ms-excel', + '.csv': 'text/csv', + '.zip': 'application/zip', + '*': 'application/octet-stream', } diff --git a/libs/portals/admin/form-system/src/lib/utils/interfaces.ts b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts index 3a814ab8ec3f..20bf6ccc41a3 100644 --- a/libs/portals/admin/form-system/src/lib/utils/interfaces.ts +++ b/libs/portals/admin/form-system/src/lib/utils/interfaces.ts @@ -1,6 +1,12 @@ -import { UniqueIdentifier } from "@dnd-kit/core" -import { FormSystemStep, FormSystemGroup, FormSystemInput, FormSystemLanguageType, FormSystemLanguageTypeInput } from "@island.is/api/schema" - +import { UniqueIdentifier } from '@dnd-kit/core' +import { + FormSystemStep, + FormSystemGroup, + FormSystemInput, + FormSystemLanguageType, + FormSystemLanguageTypeInput, + FormSystemListItem, +} from '@island.is/api/schema' export enum NavbarSelectStatus { OFF = 'Off', @@ -32,3 +38,80 @@ export enum EFormApplicantTypes { einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', logadili = 'Lögaðili', } + +export interface InputSettings { + hasInput?: boolean + isList?: boolean + isLarge?: boolean + size?: string + interval?: string + list?: FormSystemListItem[] + max?: number + min?: number + maxLength?: number + minLength?: number + amount?: number + isMulti?: boolean + maxSize?: number + types?: string[] + buttonText?: FormSystemLanguageType + hasLink?: boolean + $type?: string + name?: FormSystemLanguageType + [key: string]: unknown +} + +export enum LicenseProviderEnum { + sýslumannsembættið = 1, + leyfisveitanEhf = 2, + leyfisveitanEhf2 = 9, + þjóðskráÍslands = 3, + ferðamálastofa = 4, + ferðamálastofa2 = 52, + menntamálastofnun = 5, + hallaBjörgBaldursdóttir = 6, + fiskistofa = 7, + officeOfDistrictMagistrate = 8, + registersIceland = 10, + icelandicTouristBoard = 11, + directorateOfEducation = 12, + hallaBjorgBaldursdottir = 13, + directorateOfFisheries = 14, + fjármálaOgEfnahagsráðuneytið = 15, + ministryOfFinanceAndEconomicAffairs = 16, + ríkisskattstjóri = 17, + ríkiskaup = 18, + sýslumaðurinnÁHöfuðborgarsvæðinu = 19, + sýslumaðurinnÁHöfuðborgarsvæðinu2 = 50, + theDistrictMagistrateCapitalRegion = 20, + centralPublicProcurement = 21, + directorateOfInternalRevenue = 22, + sýslumaðurinnÁVestfjörðum = 23, + theDistrictMagistrateWestfjords = 24, + útlendingastofnun = 37, + útlendingastofnun2 = 49, + icelandicDirectorateOfImmigration = 38, + utanríkisráðuneytið = 39, + ministryForForeignAffairs = 40, + ríkislögreglustjóri = 41, + ríkislögreglustjóri2 = 71, + sjúkratryggingarÍslands = 42, + sjúkratryggingarÍslands2 = 51, + þjóðskjalasafnÍslands = 43, + þjóðskjalasafnÍslands2 = 44, + sýslumenn = 53, + fjölskylduOgHúsdýragarðurinn = 59, + menntamálastofnun2 = 61, + umhverfisstofnun = 62, + héraðsdómurReykjavíkur = 63, + minjastofnunÍslands = 64, + náttúruhamfaratryggingarÍslands = 65, +} + +export enum ApplicationTemplateStatus { + Þýðing = -2, + Kerfi = -1, + Óútgefið = 0, + Útgefið = 2, + tekiðÚrNotkun = 4, +} diff --git a/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts index 144d72b52e65..03e120c2bb8a 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateActiveItem.ts @@ -1,20 +1,27 @@ -import { ActiveItem } from "./interfaces" -import { useFormSystemUpdateStepMutation } from "../../gql/Step.generated" -import { useFormSystemUpdateGroupMutation } from "../../gql/Group.generated" -import { useFormSystemUpdateInputMutation } from "../../gql/Input.generated" -import { FormSystemStep, FormSystemGroup, FormSystemInput } from "@island.is/api/schema" +import { ActiveItem } from './interfaces' +import { useFormSystemUpdateStepMutation } from '../../gql/Step.generated' +import { useFormSystemUpdateGroupMutation } from '../../gql/Group.generated' +import { useFormSystemUpdateInputMutation } from '../../gql/Input.generated' +import { + FormSystemStep, + FormSystemGroup, + FormSystemInput, +} from '@island.is/api/schema' export const updateActiveItemFn = ( activeItem: ActiveItem, updateStep = useFormSystemUpdateStepMutation()[0], updateGroup = useFormSystemUpdateGroupMutation()[0], updateInput = useFormSystemUpdateInputMutation()[0], - currentActiveItem?: ActiveItem + currentActiveItem?: ActiveItem, ) => { const { type } = activeItem try { if (type === 'Step') { - const { id, name, type, displayOrder, waitingText, callRuleset } = currentActiveItem ? currentActiveItem.data as FormSystemStep : activeItem.data as FormSystemStep + const { id, name, type, displayOrder, waitingText, callRuleset } = + currentActiveItem + ? (currentActiveItem.data as FormSystemStep) + : (activeItem.data as FormSystemStep) updateStep({ variables: { input: { @@ -25,13 +32,16 @@ export const updateActiveItemFn = ( type: type, displayOrder: displayOrder, waitingText: waitingText, - callRuleset: callRuleset - } - } - } + callRuleset: callRuleset, + }, + }, + }, }) } else if (type === 'Group') { - const { id, name, guid, displayOrder, multiSet, stepId } = currentActiveItem ? currentActiveItem.data as FormSystemGroup : activeItem.data as FormSystemGroup + const { id, name, guid, displayOrder, multiSet, stepId } = + currentActiveItem + ? (currentActiveItem.data as FormSystemGroup) + : (activeItem.data as FormSystemGroup) updateGroup({ variables: { input: { @@ -42,7 +52,7 @@ export const updateActiveItemFn = ( guid, displayOrder, multiSet, - stepId + stepId, }, }, }, @@ -58,8 +68,10 @@ export const updateActiveItemFn = ( type, inputSettings, isPartOfMultiSet, - groupId - } = currentActiveItem ? currentActiveItem.data as FormSystemInput : activeItem.data as FormSystemInput + groupId, + } = currentActiveItem + ? (currentActiveItem.data as FormSystemInput) + : (activeItem.data as FormSystemInput) updateInput({ variables: { input: { @@ -78,7 +90,7 @@ export const updateActiveItemFn = ( }, }, }, - }); + }) } } catch (e) { console.error('Error updating active item: ', e) diff --git a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts index d6c6faed6fcc..6bf8523ae690 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts @@ -1,26 +1,23 @@ -import { FormSystemFormInput, FormSystemGroup, FormSystemGroupInput, FormSystemInput, FormSystemInputInput, FormSystemOrganizationInput, FormSystemStepInput, InputMaybe } from "@island.is/api/schema" -import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" -import { ControlState } from "../../hooks/controlReducer" -import { ItemType } from "./interfaces" - +import { FormSystemGroupInput, FormSystemInput } from '@island.is/api/schema' +import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' +import { ControlState } from '../../hooks/controlReducer' +import { ItemType } from './interfaces' export const updateDnd = ( type: ItemType, control: ControlState, - updateForm = useFormSystemUpdateFormMutation()[0] + updateForm = useFormSystemUpdateFormMutation()[0], ) => { - console.log('updating: ', type) const formId = control.form.id if (type === 'Step') { const steps = control.form.stepsList - console.log('steps: ', steps) updateForm({ variables: { input: { formId: formId, form: { - stepsList: steps?.map(s => ({ + stepsList: steps?.map((s) => ({ id: s?.id, guid: s?.guid, displayOrder: s?.displayOrder, @@ -30,61 +27,64 @@ export const updateDnd = ( callRuleset: s?.callRuleset, isHidden: s?.isHidden, isCompleted: s?.isCompleted, - })) - } - } - } + })), + }, + }, + }, }) } else if (type === 'Group') { const groups = control.form.groupsList - console.log('groups: ', groups) updateForm({ variables: { input: { formId: formId, form: { - groupsList: groups?.map(g => ({ - id: g?.id, - name: g?.name, - guid: g?.guid, - displayOrder: g?.displayOrder, - isHidden: (g?.isHidden ?? false) as boolean, - stepId: g?.stepId, - multiSet: g?.multiSet, - stepGuid: g?.stepGuid, - inputs: null - } as FormSystemGroupInput), - ) - } - } - } + groupsList: groups?.map( + (g) => + ({ + id: g?.id, + name: g?.name, + guid: g?.guid, + displayOrder: g?.displayOrder, + isHidden: (g?.isHidden ?? false) as boolean, + stepId: g?.stepId, + multiSet: g?.multiSet, + stepGuid: g?.stepGuid, + inputs: null, + } as FormSystemGroupInput), + ), + }, + }, + }, }) } else if (type === 'Input') { const { inputsList } = control.form - console.log('inputs: ', inputsList) updateForm({ variables: { input: { formId: formId, form: { - inputsList: inputsList?.filter((i): i is FormSystemInput => i !== null && i !== undefined).map(i => ({ - id: i.id, - name: i.name, - description: i.description, - isRequired: i.isRequired ?? false, - displayOrder: i.displayOrder, - isHidden: i.isHidden ?? false, - type: i.type, - inputSettings: i.inputSettings, - isPartOfMultiSet: i.isPartOfMultiSet ?? false, - groupId: i.groupId, - groupGuid: i.groupGuid, - guid: i.guid - }), - ) - } - } - } + inputsList: inputsList + ?.filter( + (i): i is FormSystemInput => i !== null && i !== undefined, + ) + .map((i) => ({ + id: i.id, + name: i.name, + description: i.description, + isRequired: i.isRequired ?? false, + displayOrder: i.displayOrder, + isHidden: i.isHidden ?? false, + type: i.type, + inputSettings: i.inputSettings, + isPartOfMultiSet: i.isPartOfMultiSet ?? false, + groupId: i.groupId, + groupGuid: i.groupGuid, + guid: i.guid, + })), + }, + }, + }, }) } } diff --git a/libs/portals/admin/form-system/src/lib/utils/updateForm.ts b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts index 871c167b0d72..274aea7c258b 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateForm.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateForm.ts @@ -1,63 +1,50 @@ -import { FormSystemForm, FormSystemFormInput, FormSystemGroupInput, FormSystemInputInput, FormSystemOrganizationInput, FormSystemStepInput, InputMaybe } from "@island.is/api/schema" -import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" -import { ControlState } from "../../hooks/controlReducer" - - -export const partialFormUpdate = ( - control: ControlState, - updateForm = useFormSystemUpdateFormMutation()[0], - updatedForm?: FormSystemForm -) => { - const form = updatedForm ? updatedForm : control.form - console.log('updating form: ', form) - updateForm({ - variables: { - input: { - formId: form.id, - form: { - invalidationDate: form.invalidationDate, - name: form.name?.__typename ? { ...form.name, __typename: undefined } : form.name, - stopProgressOnValidatingStep: (form.stopProgressOnValidatingStep ?? false) as boolean, // doesnt save....whyyyy - applicationsDaysToRemove: form.applicationsDaysToRemove, - documentTypes: form.documentTypes?.map(d => ({ - __typename: undefined, - id: d?.id, - type: d?.type, - name: d?.name?.__typename ? { ...d?.name, __typename: undefined } : d?.name, - description: d?.description?.__typename ? { ...d?.description, __typename: undefined } : d?.description, - })), - } - } - } - }) -} +import { + FormSystemForm, + FormSystemFormInput, + FormSystemGroupInput, + FormSystemInputInput, + FormSystemOrganizationInput, + FormSystemStepInput, + InputMaybe, +} from '@island.is/api/schema' +import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' +import { ControlState } from '../../hooks/controlReducer' export const entireFormUpdate = ( control: ControlState, updateForm = useFormSystemUpdateFormMutation()[0], - updatedForm?: FormSystemForm + updatedForm?: FormSystemForm, ) => { const form = updatedForm ? updatedForm : control.form const organiaztionInput: FormSystemOrganizationInput = { ...(form.organization as FormSystemOrganizationInput), } - const inputs: InputMaybe[] = form.inputsList?.filter(input => input !== undefined && input !== null).map(i => ({ - ...i, - isHidden: i?.isHidden ?? false, - isPartOfMultiSet: i?.isPartOfMultiSet ?? false, - isRequired: i?.isRequired ?? false, - })) ?? [] + const inputs: InputMaybe[] = + form.inputsList + ?.filter((input) => input !== undefined && input !== null) + .map((i) => ({ + ...i, + isHidden: i?.isHidden ?? false, + isPartOfMultiSet: i?.isPartOfMultiSet ?? false, + isRequired: i?.isRequired ?? false, + })) ?? [] - const groups: InputMaybe[] = form.groupsList?.filter(group => group !== undefined && group !== null).map(g => ({ - ...g, - inputs: null - })) ?? [] + const groups: InputMaybe[] = + form.groupsList + ?.filter((group) => group !== undefined && group !== null) + .map((g) => ({ + ...g, + inputs: null, + })) ?? [] - const steps: InputMaybe[] = form.stepsList?.filter(step => step !== undefined && step !== null).map(s => ({ - ...s, - groups: null - })) ?? [] + const steps: InputMaybe[] = + form.stepsList + ?.filter((step) => step !== undefined && step !== null) + .map((s) => ({ + ...s, + groups: null, + })) ?? [] const formInput: FormSystemFormInput = { ...form, @@ -65,19 +52,14 @@ export const entireFormUpdate = ( inputsList: inputs, groupsList: groups, stepsList: steps, - steps: null + steps: null, } - console.log('updating form: ', formInput) updateForm({ variables: { input: { formId: form.id, - form: formInput - } - } + form: formInput, + }, + }, }) } - - - - diff --git a/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts b/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts index 18e6a3d33b4e..1575eac1df96 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateFormSettings.ts @@ -1,20 +1,18 @@ -import { FormSystemForm } from "@island.is/api/schema" -import { useFormSystemUpdateFormSettingsMutation } from "../../gql/FormSettings.generated" -import { ControlState } from "../../hooks/controlReducer" -import { removeTypename } from "./removeTypename" - +import { FormSystemForm } from '@island.is/api/schema' +import { useFormSystemUpdateFormSettingsMutation } from '../../gql/FormSettings.generated' +import { ControlState } from '../../hooks/controlReducer' +import { removeTypename } from './removeTypename' export const updateSettings = ( control: ControlState, updatedForm?: FormSystemForm, - updateFormSettings = useFormSystemUpdateFormSettingsMutation()[0] + updateFormSettings = useFormSystemUpdateFormSettingsMutation()[0], ) => { const form = updatedForm ? updatedForm : control.form const documentTypesInput = form?.documentTypes?.map((dt) => ({ formId: form.id, documentTypeId: dt?.id, })) - console.log('updating form settings: ', form.formApplicantTypes) updateFormSettings({ variables: { input: { @@ -31,8 +29,8 @@ export const updateSettings = ( isTranslated: form.isTranslated, stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, applicationsDaysToRemove: form.applicationsDaysToRemove, - } - } - } + }, + }, + }, }) } diff --git a/libs/portals/admin/form-system/src/module.tsx b/libs/portals/admin/form-system/src/module.tsx index e775a327c911..481951258dc2 100644 --- a/libs/portals/admin/form-system/src/module.tsx +++ b/libs/portals/admin/form-system/src/module.tsx @@ -1,20 +1,18 @@ -import { lazy } from 'react'; +import { lazy } from 'react' import { AdminPortalScope } from '@island.is/auth/scopes' -import { m } from './lib/messages'; +import { m } from './lib/messages' import { PortalModule } from '@island.is/portals/core' import { FormSystemPaths } from './lib/paths' -import { formsLoader } from './screens/Forms/Forms.loader'; -import { formLoader } from './screens/Form/Form.loader'; +import { formsLoader } from './screens/Forms/Forms.loader' +import { formLoader } from './screens/Form/Form.loader' -const Forms = lazy(() => - import('./screens/Forms/Forms') -) +const Forms = lazy(() => import('./screens/Forms/Forms')) const Form = lazy(() => import('./screens/Form/Form')) const allowedScopes: string[] = [ AdminPortalScope.formSystem, - AdminPortalScope.formSystemSuperUser + AdminPortalScope.formSystemSuperUser, ] export const formSystemModule: PortalModule = { @@ -28,14 +26,14 @@ export const formSystemModule: PortalModule = { name: m.formSystemTitle, path: FormSystemPaths.FormSystemRoot, element: , - loader: formsLoader(props) + loader: formsLoader(props), }, { name: m.formSystemIntro, path: FormSystemPaths.Form, element: , - loader: formLoader(props) - } + loader: formLoader(props), + }, ] - } + }, } diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts index e4176ee7aacf..c5659e1a4012 100644 --- a/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Form/Form.loader.ts @@ -2,15 +2,20 @@ import type { WrappedLoaderFn } from '@island.is/portals/core' import { FormSystemFormResponse } from '@island.is/api/schema' import { ApolloClient, NormalizedCacheObject } from '@apollo/client' -import { FormSystemGetFormDocument, FormSystemGetFormQuery } from '../../gql/Form.generated' -import { FormSystemGetInputDocument, FormSystemGetInputQuery } from '../../gql/Input.generated' +import { + FormSystemGetFormDocument, + FormSystemGetFormQuery, +} from '../../gql/Form.generated' +import { + FormSystemGetInputDocument, + FormSystemGetInputQuery, +} from '../../gql/Input.generated' export interface FormLoaderResponse { - formBuilder: FormSystemFormResponse, + formBuilder: FormSystemFormResponse client: ApolloClient } - export const formLoader: WrappedLoaderFn = ({ client }) => { return async ({ params }): Promise => { if (!params.formId) { @@ -24,7 +29,7 @@ export const formLoader: WrappedLoaderFn = ({ client }) => { input: { id: Number(params.formId), }, - } + }, }) if (formError) { throw formError @@ -37,34 +42,32 @@ export const formLoader: WrappedLoaderFn = ({ client }) => { const formBuilder = formData.formSystemGetForm const updatedInputs = formBuilder.form?.inputsList?.length ? await Promise.all( - formBuilder.form.inputsList.map(async (input) => { - const { data: updatedInput, error: inputError } = - await client.query({ - query: FormSystemGetInputDocument, - fetchPolicy: 'network-only', - variables: { - input: { - id: Number(input?.id), + formBuilder.form.inputsList.map(async (input) => { + const { data: updatedInput, error: inputError } = + await client.query({ + query: FormSystemGetInputDocument, + fetchPolicy: 'network-only', + variables: { + input: { + id: Number(input?.id), + }, }, - }, - }); - return updatedInput?.formSystemGetInput; - }) - ) + }) + return updatedInput?.formSystemGetInput + }), + ) : [] const updatedFormBuilder = { ...formBuilder, form: { ...formBuilder.form, - inputsList: updatedInputs - } + inputsList: updatedInputs, + }, } - - return { formBuilder: updatedFormBuilder as FormSystemFormResponse, - client + client, } } } diff --git a/libs/portals/admin/form-system/src/screens/Form/Form.tsx b/libs/portals/admin/form-system/src/screens/Form/Form.tsx index 2e51492b6f8e..2e684c9c1994 100644 --- a/libs/portals/admin/form-system/src/screens/Form/Form.tsx +++ b/libs/portals/admin/form-system/src/screens/Form/Form.tsx @@ -1,71 +1,79 @@ -import { useLoaderData } from "react-router-dom" -import { useEffect, useReducer, useState } from "react" -import { IListItem, NavbarSelectStatus } from "../../lib/utils/interfaces" -import { FormLoaderResponse } from "./Form.loader" -import { ControlState, controlReducer } from "../../hooks/controlReducer" -import { baseSettingsStep } from "../../utils/getBaseSettingsStep" -import { defaultStep } from "../../utils/defaultStep" -import ControlContext, { IControlContext } from "../../context/ControlContext" +import { useLoaderData } from 'react-router-dom' +import { useReducer, useState } from 'react' +import { NavbarSelectStatus } from '../../lib/utils/interfaces' +import { FormLoaderResponse } from './Form.loader' +import { ControlState, controlReducer } from '../../hooks/controlReducer' +import { baseSettingsStep } from '../../utils/getBaseSettingsStep' +import { defaultStep } from '../../utils/defaultStep' +import ControlContext, { IControlContext } from '../../context/ControlContext' import { GridRow as Row, GridColumn as Column, Box, } from '@island.is/island-ui/core' -import Navbar from "../../components/Navbar/Navbar" -import { FormSystemForm, FormSystemStep } from "@island.is/api/schema" -import MainContent from "../../components/MainContent/MainContent" -import { useFormSystemUpdateGroupMutation } from "../../gql/Group.generated" -import { useFormSystemUpdateStepMutation } from "../../gql/Step.generated" -import { useFormSystemUpdateInputMutation } from "../../gql/Input.generated" -import { updateActiveItemFn } from "../../lib/utils/updateActiveItem" -import { useFormSystemUpdateFormMutation } from "../../gql/Form.generated" -import { ActiveItem, ItemType } from "../../lib/utils/interfaces" -import { updateDnd } from "../../lib/utils/updateDnd" -import { entireFormUpdate, partialFormUpdate } from "../../lib/utils/updateForm" -import { removeTypename } from "../../lib/utils/removeTypename" -import NavbarSelect from "../../components/NavbarSelect/NavbarSelect" -import { useFormSystemUpdateFormSettingsMutation } from "../../gql/FormSettings.generated" -import { updateSettings as us } from "../../lib/utils/updateFormSettings" - - +import Navbar from '../../components/Navbar/Navbar' +import { FormSystemForm, FormSystemStep } from '@island.is/api/schema' +import MainContent from '../../components/MainContent/MainContent' +import { useFormSystemUpdateGroupMutation } from '../../gql/Group.generated' +import { useFormSystemUpdateStepMutation } from '../../gql/Step.generated' +import { useFormSystemUpdateInputMutation } from '../../gql/Input.generated' +import { updateActiveItemFn } from '../../lib/utils/updateActiveItem' +import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' +import { ActiveItem, ItemType } from '../../lib/utils/interfaces' +import { updateDnd } from '../../lib/utils/updateDnd' +import { entireFormUpdate } from '../../lib/utils/updateForm' +import { removeTypename } from '../../lib/utils/removeTypename' +import NavbarSelect from '../../components/NavbarSelect/NavbarSelect' +import { useFormSystemUpdateFormSettingsMutation } from '../../gql/FormSettings.generated' +import { updateSettings as us } from '../../lib/utils/updateFormSettings' const Form = () => { const { formBuilder } = useLoaderData() as FormLoaderResponse - const { form, applicantTypes, documentTypes, inputTypes, listTypes } = formBuilder + const { form, applicantTypes, documentTypes, inputTypes, listTypes } = + formBuilder const [focus, setFocus] = useState('') const [inSettings, setInSettings] = useState(form?.name?.is === '') const [inListBuilder, setInListBuilder] = useState(false) - const [selectStatus, setSelectStatus] = useState(NavbarSelectStatus.OFF) + const [selectStatus, setSelectStatus] = useState( + NavbarSelectStatus.OFF, + ) const [updateStep] = useFormSystemUpdateStepMutation() const [updateGroup] = useFormSystemUpdateGroupMutation() const [updateInput] = useFormSystemUpdateInputMutation() const [updateForm] = useFormSystemUpdateFormMutation() const [updateFormSettings] = useFormSystemUpdateFormSettingsMutation() - const updateActiveItem = (updatedActiveItem?: ActiveItem) => updateActiveItemFn(control.activeItem, updateStep, updateGroup, updateInput, updatedActiveItem) + const updateActiveItem = (updatedActiveItem?: ActiveItem) => + updateActiveItemFn( + control.activeItem, + updateStep, + updateGroup, + updateInput, + updatedActiveItem, + ) const initialControl: ControlState = { activeItem: { type: 'Step', - data: inSettings ? baseSettingsStep : removeTypename(form?.stepsList)?.find((s: FormSystemStep) => s?.type === 'Innsláttur') ?? defaultStep + data: inSettings + ? baseSettingsStep + : removeTypename(form?.stepsList)?.find( + (s: FormSystemStep) => s?.type === 'Innsláttur', + ) ?? defaultStep, }, activeListItem: null, form: removeTypename(form) as FormSystemForm, } - const [control, controlDispatch] = useReducer(controlReducer, initialControl) - const updateDragAndDrop = (type: ItemType) => updateDnd(type, control, updateForm) + const updateDragAndDrop = (type: ItemType) => + updateDnd(type, control, updateForm) - const updateSettings = (updatedForm?: FormSystemForm) => us(control, updatedForm, updateFormSettings) - const formSettingsUpdate = (updatedForm?: FormSystemForm) => { - if (updatedForm) { - controlDispatch({ type: 'CHANGE_FORM_SETTINGS', payload: { newForm: updatedForm } }) - } - return partialFormUpdate(control, updateForm, updatedForm) - } - const formUpdate = (updatedForm?: FormSystemForm) => entireFormUpdate(control, updateForm, updatedForm) + const updateSettings = (updatedForm?: FormSystemForm) => + us(control, updatedForm, updateFormSettings) + const formUpdate = (updatedForm?: FormSystemForm) => + entireFormUpdate(control, updateForm, updatedForm) const context: IControlContext = { control, @@ -80,24 +88,14 @@ const Form = () => { focus, setFocus, updateDnD: updateDragAndDrop, - formSettingsUpdate, selectStatus, setSelectStatus, formUpdate, inListBuilder, setInListBuilder, - updateSettings + updateSettings, } - - useEffect(() => { - console.log('loaderData form: ', form) - console.log('control: ', control) - console.log('formBuilder: ', formBuilder) - }, []) - - - if (!form) { return
Loading...
} @@ -105,7 +103,11 @@ const Form = () => { - {selectStatus !== NavbarSelectStatus.OFF ? : } + {selectStatus !== NavbarSelectStatus.OFF ? ( + + ) : ( + + )} { } export default Form - - diff --git a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql index b77d578fd2a1..471f5a3c157a 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/CreateForm.graphql @@ -1,7 +1,4 @@ - -mutation formSystemCreateForm( - $input: FormSystemCreateFormInput! -) { +mutation formSystemCreateForm($input: FormSystemCreateFormInput!) { formSystemCreateForm(input: $input) { form { id @@ -73,8 +70,8 @@ mutation formSystemCreateForm( } inputsList { description { - is - en + is + en } displayOrder groupGuid @@ -305,26 +302,25 @@ mutation formSystemCreateForm( type } inputTypes { - description { + description { is en - } - displayOrder - groupGuid - groupId - guid - id - inputFields - inputSettings - isHidden - isPartOfMultiSet - isRequired - name { - is - en - } - type } + displayOrder + groupGuid + groupId + guid + id + inputFields + inputSettings + isHidden + isPartOfMultiSet + isRequired + name { + is + en + } + type + } } } - diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql b/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql index 62f00817c0eb..ebee346858fb 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.graphql @@ -1,6 +1,4 @@ -query formSystemGetForms( - $input: FormSystemGetFormsInput! -) { +query formSystemGetForms($input: FormSystemGetFormsInput!) { formSystemGetForms(input: $input) { forms { id @@ -17,4 +15,3 @@ query formSystemGetForms( } } } - diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts index e91078d96c05..10c8d9a88f68 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.loader.ts @@ -1,5 +1,8 @@ import { WrappedLoaderFn } from '@island.is/portals/core' -import { FormSystemGetFormsDocument, FormSystemGetFormsQuery } from './Forms.generated' +import { + FormSystemGetFormsDocument, + FormSystemGetFormsQuery, +} from './Forms.generated' import { FormSystemForm } from '@island.is/api/schema' export interface FormsLoaderResponse { @@ -8,15 +11,14 @@ export interface FormsLoaderResponse { export const formsLoader: WrappedLoaderFn = ({ client }) => { return async (): Promise => { - const { data, error } = - await client.query({ - query: FormSystemGetFormsDocument, - variables: { - input: { - organizationId: 1 - } - } - }) + const { data, error } = await client.query({ + query: FormSystemGetFormsDocument, + variables: { + input: { + organizationId: 1, + }, + }, + }) if (error) { throw error } @@ -24,7 +26,9 @@ export const formsLoader: WrappedLoaderFn = ({ client }) => { throw new Error('No forms were found') } return { - forms: data.formSystemGetForms.forms?.filter((form) => form !== null) as FormSystemForm[] + forms: data.formSystemGetForms.forms?.filter( + (form) => form !== null, + ) as FormSystemForm[], } } } diff --git a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx index 5386ccb28aff..32f0c3c719ae 100644 --- a/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx +++ b/libs/portals/admin/form-system/src/screens/Forms/Forms.tsx @@ -1,15 +1,9 @@ -import { - Box, - Button, - Text, - Inline -} from '@island.is/island-ui/core' -import { useLoaderData, useNavigate } from 'react-router-dom' +import { Box, Button, Text, Inline } from '@island.is/island-ui/core' +import { useNavigate } from 'react-router-dom' import { FormSystemPaths } from '../../lib/paths' import TableRow from '../../components/TableRow/TableRow' import { useFormSystemGetFormsQuery } from './Forms.generated' import { useFormSystemCreateFormMutation } from './CreateForm.generated' -import { FormsLoaderResponse } from './Forms.loader' const Forms = () => { const navigate = useNavigate() @@ -17,21 +11,20 @@ const Forms = () => { const { data, loading, error } = useFormSystemGetFormsQuery({ variables: { input: { - organizationId: 1 - } - } + organizationId: 1, + }, + }, }) - const [formSystemCreateFormMutation, { data: newData, loading: newLoading, error: newError }] = useFormSystemCreateFormMutation({ + const [formSystemCreateFormMutation] = useFormSystemCreateFormMutation({ variables: { input: { - organizationId: 1 - } - } + organizationId: 1, + }, + }, }) const forms = data?.formSystemGetForms.forms - console.log(data) if (!loading && !error) { return ( @@ -45,9 +38,15 @@ const Forms = () => { variant="ghost" size="medium" onClick={async () => { - const { data } = await formSystemCreateFormMutation({ variables: { input: { organizationId: 1 } } }) - navigate(FormSystemPaths.Form.replace(':formId', String(data?.formSystemCreateForm?.form?.id))) - console.log(data) + const { data } = await formSystemCreateFormMutation({ + variables: { input: { organizationId: 1 } }, + }) + navigate( + FormSystemPaths.Form.replace( + ':formId', + String(data?.formSystemCreateForm?.form?.id), + ), + ) }} > Ný forskrift @@ -72,8 +71,6 @@ const Forms = () => { key={f?.id} id={f?.id} name={f?.name?.is ?? ''} - // created={f?.created} - // lastModified={f?.lastChanged} org={f?.organization?.id} isHeader={false} translated={f?.isTranslated ?? false} diff --git a/libs/portals/admin/form-system/src/services/apiService.tsx b/libs/portals/admin/form-system/src/services/apiService.tsx deleted file mode 100644 index fbdc0f1dd490..000000000000 --- a/libs/portals/admin/form-system/src/services/apiService.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import axios from 'axios' - -import { - IForm, - IFormApplicantType, - IFormBuilder, - IGroup, - IInput, - IInputSettings, - ILanguage, - IStep, - ItemType, -} from '../types/interfaces' -import { groupSchema, stepSchema } from './zodValidation' - -const BASEURL = 'https://profun.island.is/umsoknarkerfi/api' - -export async function getForm(id: unknown): Promise { - try { - const response = await axios.get(`${BASEURL}/Forms/${id}`) - // const validatedFormData: IFormBuilder = formFormBuilderSchema.parse(response.data) - // return validatedFormData - return response.data - } catch (error) { - console.error(error) - throw error - } -} - -export async function updateForm( - form: IForm, - steps: IStep[], - groups: IGroup[], - inputs: IInput[], -) { - const updatedForm: IForm = { - ...form, - stepsList: steps.map((s, i) => { - return { - ...s, - displayOrder: i, - } - }), - groupsList: groups.map((g, i) => { - return { - ...g, - displayOrder: i, - } - }), - inputsList: inputs.map((i, index) => { - return { - ...i, - displayOrder: index, - } - }), - } - - try { - const response = await axios.put( - `${BASEURL}/Forms/${form.id}`, - updatedForm, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - - return response - } catch (error) { - console.error('Error in updateNavbar:', error) - throw error - } -} - -export async function updateItem(type: string, data: IStep | IGroup | IInput) { - const url = `${BASEURL}/${type}s/${data.id}` - - try { - const response = await axios.put(url, data, { - headers: { - 'Content-Type': 'application/json', - }, - }) - - return response - } catch (error) { - console.error('Error in updateItem: ', error) - throw error - } -} - -export async function getNewForm(organisationId: number): Promise { - try { - const response = await axios.post(`${BASEURL}/Forms/${organisationId}`) - return response.data - } catch (error) { - console.error('Error in getNewForm: ', error) - throw error - } -} - -export async function getAllFormsFromOrganisation( - organisationId: number, -): Promise { - try { - const response = await axios.get( - `${BASEURL}/Forms/Organization/${organisationId}`, - ) - return response.data - } catch (error) { - console.error('Error in getAllFormsFromOrganisation: ', error) - throw error - } -} - -export async function addStep( - formId: number, - name: ILanguage, - displayOrder: number, - stepType: number, - waitingText: ILanguage, - callRuleset: boolean, -): Promise { - try { - const response = await axios.post(`${BASEURL}/Steps`, { - formId, - name, - displayOrder, - stepType, - waitingText, - callRuleset, - }) - - const validatedStep: IStep = stepSchema.parse(response.data) - return validatedStep - } catch (error) { - console.error('Error in addStep: ', error) - throw error - } -} - -export async function addGroup( - displayOrder: number, - parentId: number, -): Promise { - try { - const response = await axios.post(`${BASEURL}/Groups`, { - displayOrder: displayOrder, - stepId: parentId, - }) - - const validatedGroup: IGroup = groupSchema.parse(response.data) - - return validatedGroup - } catch (error) { - console.error('Error in addGroup: ', error) - throw error - } -} - -export async function addInput( - displayOrder: number, - parentId: number, -): Promise { - const requestBody = { - displayOrder: displayOrder, - groupId: parentId, - } - - try { - const response = await axios.post(`${BASEURL}/Inputs`, requestBody, { - headers: { - 'Content-Type': 'application/json', - }, - }) - - const data = response.data - - return data - } catch (error) { - console.error('Error in addInput: ', error) - throw error - } -} - -export async function deleteItem(type: ItemType, id: number) { - try { - const response = await axios.delete(`${BASEURL}/${type}s/${id}`) - return response - } catch (error) { - console.error('Error in deleteItem: ', error) - throw error - } -} - -export async function saveFormSettings(id: number, settings: IInputSettings) { - try { - const response = await axios.put( - `${BASEURL}/Forms/${id}/Settings`, - settings, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - return response - } catch (error) { - console.error('Error in saveFormSettings: ', error) - throw error - } -} - -export async function saveApplicantTypes( - id: number, - types: IFormApplicantType[], -) { - const requestData = { - id: id, - formApplicantTypes: types, - } - try { - const response = await axios.put( - `${BASEURL}/Forms/${id}/Settings`, - requestData, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - - return response - } catch (error) { - console.error('Error in saveApplicantTypes: ', error) - throw error - } -} -export async function getList(type: string) { - try { - const response = await axios.get(`${BASEURL}/Services/${type}`) - return response.data - } catch (error) { - console.error('Error in getList: ', error) - throw error - } -} diff --git a/libs/portals/admin/form-system/src/services/translationStation.tsx b/libs/portals/admin/form-system/src/services/translationStation.tsx deleted file mode 100644 index 19be4bae56f2..000000000000 --- a/libs/portals/admin/form-system/src/services/translationStation.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { ITranslationResponse } from '../types/interfaces' -import axios from 'axios' -import dotenv from 'dotenv' - -dotenv.config() - -export const translationStation = async ( - input: string, -): Promise => { - const apiUrl = process.env.MIDEIND_API - const apiKey = process.env.MIDEIND_KEY - - if (!apiUrl || !apiKey) { - throw new Error('API URL or API key is not defined.') - } - - try { - const response = await axios.post( - apiUrl, - { - contents: [input], - sourceLanguageCode: 'is', - targetLanguageCode: 'en', - model: '', - domain: '', - }, - { - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - 'X-API-Key': apiKey, - }, - }, - ) - - return response.data - } catch (error) { - console.error('Error in translationStation: ', error) - throw error - } -} diff --git a/libs/portals/admin/form-system/src/services/zodValidation.ts b/libs/portals/admin/form-system/src/services/zodValidation.ts deleted file mode 100644 index bc94f18f8e08..000000000000 --- a/libs/portals/admin/form-system/src/services/zodValidation.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { z } from 'zod' -import { EFormApplicantTypes } from '../types/enums' -import { - IApplicantType, - ICertificate, - IForm, - IFormApplicantType, - IFormBuilder, - IGroup, - IInput, - IInputSettings, - IInputType, - IListType, - IStep, - ITenging, -} from '../types/interfaces' - -const languageSchema = z.object({ - is: z.string(), - en: z.string(), -}) - -const dependencySchema = z.record(z.array(z.string())) as z.ZodSchema - -const inputSettingsSchema = z.object({ - $type: z.string().optional(), - isLarge: z.boolean().optional(), - size: z.enum(['xs', 'sm', 'md']), - interval: z.string().optional(), - erHlekkur: z.boolean().optional(), - url: z.string().optional(), - hnapptexti: languageSchema.optional(), - tegundir: z.array(z.string()).optional(), - hamarksstaerd: z.number().optional(), - erFjolval: z.boolean().optional(), - fjoldi: z.number().optional(), - header: z.string().optional(), - hamarkslengd: z.number().optional(), - lagmarkslengd: z.number().optional(), - laggildi: z.number().optional(), - hagildi: z.number().optional(), - listi: z - .array( - z.object({ - guid: z.string(), - label: languageSchema, - description: languageSchema, - displayOrder: z.number(), - isSelected: z.boolean(), - }), - ) - .optional(), - type: z.string().optional(), - name: languageSchema.optional(), - erListi: z.boolean().optional(), - erInnslattur: z.boolean().optional(), -}) as z.ZodSchema - -export const inputSchema = z.object({ - id: z.number(), - name: languageSchema, - description: languageSchema, - isRequired: z.boolean(), - displayOrder: z.number(), - groupId: z.number(), - groupGuid: z.string(), - isHidden: z.boolean(), - type: z.string(), - guid: z.string(), - inputFields: z.record(z.any()), - inputSettings: inputSettingsSchema, - isPartOfMultiSet: z.boolean(), -}) as z.ZodSchema - -export const groupSchema = z.object({ - id: z.number(), - name: languageSchema, - guid: z.string(), - displayOrder: z.number(), - isHidden: z.boolean(), - multiSet: z.number(), - stepId: z.number(), - stepGuid: z.string(), - inputs: z.array(inputSchema), -}) as z.ZodSchema - -export const stepSchema = z.object({ - id: z.number(), - guid: z.string(), - displayOrder: z.number(), - name: languageSchema, - type: z.string(), - waitingText: languageSchema, - callRuleset: z.boolean(), - isHidden: z.boolean(), - isCompleted: z.boolean(), - groups: z.array(groupSchema), -}) as z.ZodSchema - -const certificateSchema = z.object({ - id: z.number(), - type: z.string(), - name: languageSchema, - description: languageSchema, -}) as z.ZodSchema - -const applicantTypesSchema = z.enum([ - EFormApplicantTypes.einstaklingur, - EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, - EFormApplicantTypes.einstaklingurMedUmbodLogadila, - EFormApplicantTypes.einstaklingurMedProkuru, - EFormApplicantTypes.einstaklingurUmbodsveitandi, - EFormApplicantTypes.logadili, -]) - -const formApplicantSchema = z.object({ - formId: z.number(), - applicantTypeId: z.number(), - name: languageSchema, - type: applicantTypesSchema, -}) as z.ZodSchema - -export const formSchema = z.object({ - id: z.number(), - name: languageSchema, - organization: z.object({ - id: z.number(), - name: languageSchema, - kennitala: z.string(), - scope: z.string(), - xroadBaseUrl: z.string(), - }), - created: z.date(), - lastChanged: z.date(), - invalidationDate: z.date().optional(), - dependencies: dependencySchema, - stepsList: z.array(stepSchema).default([]), - groupsList: z.array(groupSchema).default([]), - inputsList: z.array(inputSchema).default([]), - stopProgressOnValidatingStep: z.boolean(), - applicationsDaysToRemove: z.number(), - isTranslated: z.boolean(), - documentTypes: z.array(certificateSchema), - formApplicantTypes: z.array(formApplicantSchema), -}) as z.ZodSchema - -const inputTypeSchema = z.object({ - type: z.string(), - name: z.string(), - description: z.string(), - organizations: z.array(z.number()).optional(), - inputFields: z.object({}).optional(), - inputMetadata: z.object({}).optional(), - ruleset: z.object({}).optional(), - inputSettings: inputSettingsSchema, -}) as z.ZodSchema - -const applicantTypeSchema = z.object({ - id: z.number(), - name: languageSchema, - type: applicantTypesSchema, - nameSuggestions: z.array( - z.object({ - applicantTypeId: z.number(), - nameSuggestion: languageSchema, - }), - ), -}) as z.ZodSchema - -const listTypeSchema = z.object({ - id: z.number(), - type: z.string(), - name: languageSchema, - description: languageSchema, -}) as z.ZodSchema - -export const formsFormBuilderSchema = z.object({ - forms: z.array(formSchema), - form: formSchema.optional(), - documentTypes: z.array(certificateSchema).optional(), - inputTypes: z.array(inputTypeSchema).optional(), - applicantTypes: z.array(applicantTypeSchema).optional(), - listTypes: z.array(listTypeSchema).optional(), -}) as z.ZodSchema - -export const formFormBuilderSchema = z.object({ - forms: z.null(), - form: formSchema, - documentTypes: z.array(certificateSchema), - inputTypes: z.array(inputTypeSchema), - applicantTypes: z.array(applicantTypeSchema), - listTypes: z.array(listTypeSchema), -}) as z.ZodSchema diff --git a/libs/portals/admin/form-system/src/types/enums/index.tsx b/libs/portals/admin/form-system/src/types/enums/index.tsx deleted file mode 100644 index fadfab2e4e4a..000000000000 --- a/libs/portals/admin/form-system/src/types/enums/index.tsx +++ /dev/null @@ -1,100 +0,0 @@ -export enum ApplicationTemplateStatus { - Þýðing = -2, - Kerfi = -1, - Óútgefið = 0, - Útgefið = 2, - tekiðÚrNotkun = 4, -} - -export enum LicenseProviderEnum { - sýslumannsembættið = 1, - leyfisveitanEhf = 2, - leyfisveitanEhf2 = 9, - þjóðskráÍslands = 3, - ferðamálastofa = 4, - ferðamálastofa2 = 52, - menntamálastofnun = 5, - hallaBjörgBaldursdóttir = 6, - fiskistofa = 7, - officeOfDistrictMagistrate = 8, - registersIceland = 10, - icelandicTouristBoard = 11, - directorateOfEducation = 12, - hallaBjorgBaldursdottir = 13, - directorateOfFisheries = 14, - fjármálaOgEfnahagsráðuneytið = 15, - ministryOfFinanceAndEconomicAffairs = 16, - ríkisskattstjóri = 17, - ríkiskaup = 18, - sýslumaðurinnÁHöfuðborgarsvæðinu = 19, - sýslumaðurinnÁHöfuðborgarsvæðinu2 = 50, - theDistrictMagistrateCapitalRegion = 20, - centralPublicProcurement = 21, - directorateOfInternalRevenue = 22, - sýslumaðurinnÁVestfjörðum = 23, - theDistrictMagistrateWestfjords = 24, - útlendingastofnun = 37, - útlendingastofnun2 = 49, - icelandicDirectorateOfImmigration = 38, - utanríkisráðuneytið = 39, - ministryForForeignAffairs = 40, - ríkislögreglustjóri = 41, - ríkislögreglustjóri2 = 71, - sjúkratryggingarÍslands = 42, - sjúkratryggingarÍslands2 = 51, - þjóðskjalasafnÍslands = 43, - þjóðskjalasafnÍslands2 = 44, - sýslumenn = 53, - fjölskylduOgHúsdýragarðurinn = 59, - menntamálastofnun2 = 61, - umhverfisstofnun = 62, - héraðsdómurReykjavíkur = 63, - minjastofnunÍslands = 64, - náttúruhamfaratryggingarÍslands = 65, -} - -export enum FileTypeEnum { - PDF, - Image, - Xls, - ALL, -} - -export enum EInputType { - Textalínubox = 1, - TextaboxStórt = 2, - Tölustafir = 3, - Textalýsing = 4, - Hakbox = 5, - Dagssetning = 6, - Fellilisti = 7, - Valhnappar = 8, - Heimagistingarnúmer = 9, - FasteignanúmerInnslegið = 10, - FasteignanúmerValiðÚrLista = 11, - Bankareikningsnúmer = 13, - Kennitala = 14, - Greiðandi = 15, - Krónutala = 16, - Krónutölusamtala = 17, - Netfang = 18, - Símanúmer = 19, - FalinnStrengur = 20, - Tími = 21, - Sveitarfélög = 22, - Landalisti = 23, - Póstnúmer = 24, - KennitalaDánarbús = 25, - KennitalaAllt = 26, - Vottorð = 28, - Aðili = 29, -} - -export enum EFormApplicantTypes { - einstaklingur = 'Einstaklingur', - einstaklingurMedUmbodAnnarsEinstaklings = 'Einstaklingur_með_umboð_annars_einstaklings', - einstaklingurMedUmbodLogadila = 'Einstaklingur_með_umboð_lögaðila', - einstaklingurMedProkuru = 'Einstaklingur_með_prókúru', - einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', - logadili = 'Lögaðili', -} diff --git a/libs/portals/admin/form-system/src/types/interfaces.tsx b/libs/portals/admin/form-system/src/types/interfaces.tsx deleted file mode 100644 index 9720a3276611..000000000000 --- a/libs/portals/admin/form-system/src/types/interfaces.tsx +++ /dev/null @@ -1,271 +0,0 @@ -import { Dispatch, SetStateAction, FocusEvent } from 'react' -import { UniqueIdentifier } from '@dnd-kit/core' -import { EFormApplicantTypes } from './enums' -import { FormAction } from '../hooks/formReducer' -import { FormHeaderAction } from '../hooks/headerInfoReducer' -import { FormSystemApplicantType, FormSystemDocumentType, FormSystemForm, FormSystemGroup, FormSystemInput, FormSystemLanguageType, FormSystemListItem, FormSystemListType, FormSystemStep } from '@island.is/api/schema' -import { Maybe } from 'graphql/jsutils/Maybe' - -export type IFormBuilderContext = { - // formBuilder: IFormBuilder - // formDispatch: Dispatch - lists: ILists - formUpdate: () => Promise - inSettings: boolean - setInSettings: Dispatch> - setSelectStatus: Dispatch> - selectStatus: NavbarSelectStatus - activeListItem?: IListItem | null - setActiveListItem: Dispatch> - blur(e: FocusEvent): void - onFocus(e: string): void -} - -export interface IInputSettings { - $type?: string - isLarge?: boolean - size?: Sizes - interval?: string - erHlekkur?: boolean - url?: string - hnapptexti?: ILanguage - tegundir?: string[] - hamarksstaerd?: number - erFjolval?: boolean - fjoldi?: number - header?: string - hamarkslengd?: number - lagmarkslengd?: number - laggildi?: number - hagildi?: number - listi?: IListItem[] - type?: string - name?: ILanguage - erListi?: boolean - erInnslattur?: boolean - [key: string]: unknown -} - -export interface IForm { - id: number - name: ILanguage - created: Date - lastChanged: Date - organization: { - id: number - name: ILanguage - kennitala: string - scope: string - xroadBaseUrl: string - } - dependencies: ITenging - stepsList: IStep[] - groupsList: IGroup[] - inputsList: IInput[] - stopProgressOnValidatingStep: boolean - applicationsDaysToRemove: number - invalidationDate?: Date - isTranslated: boolean - documentTypes: ICertificate[] - formApplicantTypes: IFormApplicantType[] -} - -export interface IStep { - id: number - guid: UniqueIdentifier - displayOrder: number - name: ILanguage - type: string - waitingText: ILanguage - callRuleset: boolean - isHidden: boolean - isCompleted: boolean - groups: IGroup[] -} - -export interface IGroup { - id: number - name: ILanguage - guid: UniqueIdentifier - displayOrder: number - isHidden: boolean - multiSet: number - stepId: number - stepGuid: UniqueIdentifier - inputs?: IInput[] -} - -export interface IInput { - id: number - name: ILanguage - description: ILanguage - isRequired: boolean - displayOrder: number - groupId: number - groupGuid: UniqueIdentifier - isHidden: boolean - type: string - guid: UniqueIdentifier - inputFields: object - inputSettings: IInputSettings - isPartOfMultiSet: boolean -} - -export type ILists = { - activeItem: ActiveItem - steps?: Maybe[] - groups?: Maybe[] - inputs?: Maybe[] - [key: string]: unknown -} - -export interface ActiveItem { - type: ItemType - data: Maybe | Maybe | Maybe -} - -export interface ISelectOption { - label: string | number - value: string | number -} - -export interface ITenging { - [key: string]: string[] -} - -export interface IFormBuilder { - form?: Maybe - forms?: Maybe[] | null - documentTypes?: Maybe[]> - inputTypes?: Maybe[]> - applicantTypes?: Maybe[]> - listTypes?: Maybe[]> -} - -export interface IListType { - id: number - type: string - name: ILanguage - description: ILanguage -} - -export interface IListItem { - guid: UniqueIdentifier - label: ILanguage - description: ILanguage - displayOrder: number - isSelected: boolean -} - -export interface ICertificate { - id: number - type: string - name: ILanguage - description: ILanguage -} - -export interface IApplicantType { - id: number - name: ILanguage - type: EFormApplicantTypes - nameSuggestions: { - applicantTypeId: number - nameSuggestion: ILanguage - }[] -} - -export type IFormApplicantType = { - formId: number - applicantTypeId: number - name: ILanguage - type: EFormApplicantTypes -} - -export interface IFormDocumentType { - formId: number - documentTypeId: number -} - -export interface IInputType { - type: string - name: string - description: string - organizations?: [] - inputFields?: object - inputMetadata?: object - ruleset?: object - inputSettings: object -} - -export interface ILayoutContext { - info: { - organization: string - applicationName: string - } - infoDispatch: React.Dispatch -} - -export interface ILicenseProvider { - licenseProviderID: number - kennitala: string - name: string - email: string - phone: string - enabled: boolean - parentId?: number - language: string -} - -export interface ITranslationResponse { - translations: ITranslation[] - sourceLanguageCode: string - targetLanguageCode: string - model: string -} - -export interface ITranslation { - translatedText: string - translatedTextStructured: [string, string][] -} - -export enum NavbarSelectStatus { - OFF = 'Off', - NORMAL = 'Normal', - LIST_ITEM = 'ListItem', - ON_WITHOUT_SELECT = 'OnWithoutSelect', -} - -export type ILanguage = { - is: string - en: string -} -export interface User { - name?: string - email?: string - image?: string -} -type Sizes = 'xs' | 'sm' | 'md' - -export type ItemType = 'Step' | 'Group' | 'Input' - -interface InputSettings { - hasInput?: boolean - isList?: boolean - isLarge?: boolean - size?: string - interval?: string - list?: FormSystemListItem[] - max?: number - min?: number - maxLength?: number - minLength?: number - amount?: number - isMulti?: boolean - maxSize?: number - types?: string[] - buttonText?: FormSystemLanguageType - hasLink?: boolean - $type?: string - name?: FormSystemLanguageType - [key: string]: unknown -} diff --git a/libs/portals/admin/form-system/src/utils/defaultStep.tsx b/libs/portals/admin/form-system/src/utils/defaultStep.tsx index 03d9bb43d8b5..1b8a23e1f2ab 100644 --- a/libs/portals/admin/form-system/src/utils/defaultStep.tsx +++ b/libs/portals/admin/form-system/src/utils/defaultStep.tsx @@ -1,5 +1,4 @@ import { uuid } from 'uuidv4' -import { IStep } from '../types/interfaces' import { FormSystemStep } from '@island.is/api/schema' export const defaultStep: FormSystemStep = { @@ -18,5 +17,5 @@ export const defaultStep: FormSystemStep = { callRuleset: false, isHidden: false, isCompleted: false, - groups: [] + groups: [], } diff --git a/libs/portals/admin/form-system/src/utils/fileTypes.ts b/libs/portals/admin/form-system/src/utils/fileTypes.ts index 1012723154a6..f0fb3c6b738a 100644 --- a/libs/portals/admin/form-system/src/utils/fileTypes.ts +++ b/libs/portals/admin/form-system/src/utils/fileTypes.ts @@ -1,58 +1,59 @@ export const fileTypes = { - ".pdf": "application/pdf", - ".doc": "application/msword", - ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - ".txt": "text/plain", - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".gif": "image/gif", - ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - ".xls": "application/vnd.ms-excel", - ".csv": "text/csv", - ".zip": "application/zip", - "*": "application/octet-stream" + '.pdf': 'application/pdf', + '.doc': 'application/msword', + '.docx': + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + '.txt': 'text/plain', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.png': 'image/png', + '.gif': 'image/gif', + '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + '.xls': 'application/vnd.ms-excel', + '.csv': 'text/csv', + '.zip': 'application/zip', + '*': 'application/octet-stream', } export const fileSizes = [ { - "label": "1 mb", - "value": 1048576 + label: '1 mb', + value: 1048576, }, { - "label": "2 mb", - "value": 2097152 + label: '2 mb', + value: 2097152, }, { - "label": "3 mb", - "value": 3145728 + label: '3 mb', + value: 3145728, }, { - "label": "4 mb", - "value": 4194304 + label: '4 mb', + value: 4194304, }, { - "label": "5 mb", - "value": 5242880 + label: '5 mb', + value: 5242880, }, { - "label": "6 mb", - "value": 6291456 + label: '6 mb', + value: 6291456, }, { - "label": "7 mb", - "value": 7340032 + label: '7 mb', + value: 7340032, }, { - "label": "8 mb", - "value": 8388608 + label: '8 mb', + value: 8388608, }, { - "label": "9 mb", - "value": 9437184 + label: '9 mb', + value: 9437184, }, { - "label": "10 mb", - "value": 10485760 - } + label: '10 mb', + value: 10485760, + }, ] diff --git a/libs/portals/admin/form-system/tsconfig.json b/libs/portals/admin/form-system/tsconfig.json index e0b49829e8f6..c3e941cbe416 100644 --- a/libs/portals/admin/form-system/tsconfig.json +++ b/libs/portals/admin/form-system/tsconfig.json @@ -4,7 +4,7 @@ //"module": "commonjs" "jsx": "react-jsx", "allowJs": true, - "resolveJsonModule": true, + "resolveJsonModule": true }, "files": [], "include": [], From 5f92d533c504583997971f0d6c54441d33760c7d Mon Sep 17 00:00:00 2001 From: Hyo-Sam Nandkisore Date: Wed, 24 Apr 2024 15:56:46 +0000 Subject: [PATCH 30/72] removed form-builder app --- apps/form-builder/.eslintrc.json | 40 - apps/form-builder/.vscode/settings.json | 1 - .../components/AuthProvider/AuthProvider.tsx | 31 - .../components/Layout/Layout.css.ts | 21 - .../form-builder/components/Layout/Layout.tsx | 74 -- .../LicenseProviderDropdown.tsx | 40 - .../MainContent/MainContent.css.tsx | 10 - .../components/MainContent/MainContent.tsx | 137 ---- .../components/BaseSettings/BaseSettings.tsx | 149 ---- .../components/InputContent/InputContent.tsx | 118 --- .../InputContent/components/BaseInput.tsx | 216 ----- .../components/FileUpload/FileUpload.tsx | 137 ---- .../components/FileUpload/fileSizes.json | 44 - .../components/MessageWithLink.tsx | 130 --- .../InputContent/components/NumberInput.tsx | 105 --- .../PropertyNumberInputSettings.tsx | 61 -- .../InputContent/components/TimeInput.tsx | 36 - .../components/ListBuilder/ListBuilder.tsx | 202 ----- .../ListBuilder/components/ListItem.tsx | 334 -------- .../components/ListContent/ListContent.tsx | 99 --- .../components/Payments/Payments.css.ts | 8 - .../components/Payments/Payments.tsx | 55 -- .../components/Premises/Premises.tsx | 63 -- .../components/Preview/Preview.tsx | 110 --- .../Preview/components/Banknumber.tsx | 108 --- .../Preview/components/Currency.tsx | 36 - .../components/Preview/components/Email.tsx | 32 - .../Preview/components/FileUpload.tsx | 66 -- .../components/Preview/components/List.tsx | 30 - .../components/MessageWithLinkButton.tsx | 59 -- .../Preview/components/NationalId.tsx | 21 - .../Preview/components/NumberInput.tsx | 45 -- .../Preview/components/PhoneInput.tsx | 20 - .../PropertyNumber/PropertyNumber.tsx | 27 - .../components/PropertyNumberCombined.tsx | 22 - .../components/PropertyNumberInput.tsx | 42 - .../components/PropertyNumberList.tsx | 54 -- .../PropertyNumber/components/index.ts | 3 - .../components/Preview/components/Radio.tsx | 57 -- .../Preview/components/TimeSelect.tsx | 215 ----- .../UtilizationSummary/UtilizationSummary.tsx | 11 - .../PreviewStepOrGroup/MultiSet/MultiSet.tsx | 59 -- .../PreviewStepOrGroup/PreviewStepOrGroup.tsx | 88 -- .../RelevantParties/RelevantParties.tsx | 285 ------- .../components/FormApplicantType.tsx | 143 ---- .../form-builder/components/Navbar/Navbar.tsx | 327 -------- .../NavComponent/NavComponent.css.ts | 90 --- .../components/NavComponent/NavComponent.tsx | 176 ---- .../NavComponent/components/NavButtons.tsx | 50 -- .../components/NavbarTab/NavbarTab.css.tsx | 17 - .../Navbar/components/NavbarTab/NavbarTab.tsx | 57 -- .../components/NavbarSelect/NavbarSelect.tsx | 62 -- .../components/SelectNavComponent.tsx | 148 ---- .../components/selectNavComponent.css.ts | 90 --- .../components/TableRow/TableRow.css.tsx | 8 - .../components/TableRow/TableRow.tsx | 181 ----- apps/form-builder/components/Tabs/index.tsx | 47 -- apps/form-builder/components/Tabs/tabs.css.ts | 14 - .../TranslationTag/TranslationTag.tsx | 12 - .../context/FormBuilderContext.tsx | 51 -- apps/form-builder/context/LayoutContext.tsx | 14 - apps/form-builder/context/UserContext.tsx | 12 - apps/form-builder/environments/environment.ts | 9 - apps/form-builder/gql/client.ts | 44 - apps/form-builder/gql/httpLink.ts | 14 - apps/form-builder/gql/queries.graphql.ts | 14 - apps/form-builder/gql/retryLink.ts | 11 - apps/form-builder/hooks/fileUploadReducer.ts | 43 - apps/form-builder/hooks/formReducer.ts | 198 ----- apps/form-builder/hooks/headerInfoReducer.ts | 29 - apps/form-builder/hooks/listsReducer.ts | 763 ------------------ apps/form-builder/hooks/useUser.ts | 42 - apps/form-builder/index.d.ts | 6 - apps/form-builder/infra/form-builder.ts | 70 -- apps/form-builder/jest.config.ts | 11 - apps/form-builder/lib/environment.ts | 31 - apps/form-builder/lib/fileTypes.json | 15 - apps/form-builder/next-env.d.ts | 5 - apps/form-builder/next.config.js | 39 - apps/form-builder/pages/Form/[id]/index.tsx | 29 - apps/form-builder/pages/Form/index.tsx | 34 - apps/form-builder/pages/Forms/index.tsx | 22 - apps/form-builder/pages/_app.tsx | 41 - .../pages/api/auth/[...nextauth].ts | 70 -- apps/form-builder/pages/index.tsx | 12 - apps/form-builder/project.json | 108 --- apps/form-builder/proxy.config.json | 6 - apps/form-builder/public/.gitkeep | 0 apps/form-builder/public/favicon.ico | Bin 15086 -> 0 bytes apps/form-builder/screens/Form.tsx | 137 ---- apps/form-builder/screens/Forms.tsx | 58 -- apps/form-builder/screens/index.tsx | 2 - apps/form-builder/server.ts | 12 - apps/form-builder/services/apiService.tsx | 248 ------ .../services/translationStation.tsx | 41 - apps/form-builder/services/zodValidation.ts | 193 ----- apps/form-builder/tsconfig.json | 36 - apps/form-builder/tsconfig.server.json | 11 - apps/form-builder/tsconfig.spec.json | 21 - apps/form-builder/types/enums/index.tsx | 100 --- apps/form-builder/types/interfaces.tsx | 253 ------ apps/form-builder/utils/defaultStep.tsx | 20 - apps/form-builder/utils/formatDate.tsx | 8 - .../utils/getBaseSettingsStep.tsx | 20 - 104 files changed, 7826 deletions(-) delete mode 100644 apps/form-builder/.eslintrc.json delete mode 100644 apps/form-builder/.vscode/settings.json delete mode 100644 apps/form-builder/components/AuthProvider/AuthProvider.tsx delete mode 100644 apps/form-builder/components/Layout/Layout.css.ts delete mode 100644 apps/form-builder/components/Layout/Layout.tsx delete mode 100644 apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx delete mode 100644 apps/form-builder/components/MainContent/MainContent.css.tsx delete mode 100644 apps/form-builder/components/MainContent/MainContent.tsx delete mode 100644 apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx delete mode 100644 apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/ListBuilder/ListBuilder.tsx delete mode 100644 apps/form-builder/components/MainContent/components/ListBuilder/components/ListItem.tsx delete mode 100644 apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Payments/Payments.css.ts delete mode 100644 apps/form-builder/components/MainContent/components/Payments/Payments.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Premises/Premises.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/Preview.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Email.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/List.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/MessageWithLinkButton.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/NationalId.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/NumberInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx delete mode 100644 apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx delete mode 100644 apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx delete mode 100644 apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx delete mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx delete mode 100644 apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx delete mode 100644 apps/form-builder/components/Navbar/Navbar.tsx delete mode 100644 apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts delete mode 100644 apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx delete mode 100644 apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx delete mode 100644 apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx delete mode 100644 apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx delete mode 100644 apps/form-builder/components/NavbarSelect/NavbarSelect.tsx delete mode 100644 apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx delete mode 100644 apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts delete mode 100644 apps/form-builder/components/TableRow/TableRow.css.tsx delete mode 100644 apps/form-builder/components/TableRow/TableRow.tsx delete mode 100644 apps/form-builder/components/Tabs/index.tsx delete mode 100644 apps/form-builder/components/Tabs/tabs.css.ts delete mode 100644 apps/form-builder/components/TranslationTag/TranslationTag.tsx delete mode 100644 apps/form-builder/context/FormBuilderContext.tsx delete mode 100644 apps/form-builder/context/LayoutContext.tsx delete mode 100644 apps/form-builder/context/UserContext.tsx delete mode 100644 apps/form-builder/environments/environment.ts delete mode 100644 apps/form-builder/gql/client.ts delete mode 100644 apps/form-builder/gql/httpLink.ts delete mode 100644 apps/form-builder/gql/queries.graphql.ts delete mode 100644 apps/form-builder/gql/retryLink.ts delete mode 100644 apps/form-builder/hooks/fileUploadReducer.ts delete mode 100644 apps/form-builder/hooks/formReducer.ts delete mode 100644 apps/form-builder/hooks/headerInfoReducer.ts delete mode 100644 apps/form-builder/hooks/listsReducer.ts delete mode 100644 apps/form-builder/hooks/useUser.ts delete mode 100644 apps/form-builder/index.d.ts delete mode 100644 apps/form-builder/infra/form-builder.ts delete mode 100644 apps/form-builder/jest.config.ts delete mode 100644 apps/form-builder/lib/environment.ts delete mode 100644 apps/form-builder/lib/fileTypes.json delete mode 100644 apps/form-builder/next-env.d.ts delete mode 100644 apps/form-builder/next.config.js delete mode 100644 apps/form-builder/pages/Form/[id]/index.tsx delete mode 100644 apps/form-builder/pages/Form/index.tsx delete mode 100644 apps/form-builder/pages/Forms/index.tsx delete mode 100644 apps/form-builder/pages/_app.tsx delete mode 100644 apps/form-builder/pages/api/auth/[...nextauth].ts delete mode 100644 apps/form-builder/pages/index.tsx delete mode 100644 apps/form-builder/project.json delete mode 100644 apps/form-builder/proxy.config.json delete mode 100644 apps/form-builder/public/.gitkeep delete mode 100644 apps/form-builder/public/favicon.ico delete mode 100644 apps/form-builder/screens/Form.tsx delete mode 100644 apps/form-builder/screens/Forms.tsx delete mode 100644 apps/form-builder/screens/index.tsx delete mode 100644 apps/form-builder/server.ts delete mode 100644 apps/form-builder/services/apiService.tsx delete mode 100644 apps/form-builder/services/translationStation.tsx delete mode 100644 apps/form-builder/services/zodValidation.ts delete mode 100644 apps/form-builder/tsconfig.json delete mode 100644 apps/form-builder/tsconfig.server.json delete mode 100644 apps/form-builder/tsconfig.spec.json delete mode 100644 apps/form-builder/types/enums/index.tsx delete mode 100644 apps/form-builder/types/interfaces.tsx delete mode 100644 apps/form-builder/utils/defaultStep.tsx delete mode 100644 apps/form-builder/utils/formatDate.tsx delete mode 100644 apps/form-builder/utils/getBaseSettingsStep.tsx diff --git a/apps/form-builder/.eslintrc.json b/apps/form-builder/.eslintrc.json deleted file mode 100644 index f653743bfa98..000000000000 --- a/apps/form-builder/.eslintrc.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "extends": [ - "plugin:@nx/react-typescript", - "next", - "next/core-web-vitals", - "../../.eslintrc.json" - ], - "ignorePatterns": ["!**/*", ".next/**/*"], - "overrides": [ - { - "files": ["*.*"], - "rules": { - "@next/next/no-html-link-for-pages": "off" - } - }, - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": { - "@next/next/no-html-link-for-pages": [ - "error", - "apps/form-builder/pages" - ] - } - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.spec.ts", "*.spec.tsx", "*.spec.js", "*.spec.jsx"], - "env": { - "jest": true - } - } - ] -} diff --git a/apps/form-builder/.vscode/settings.json b/apps/form-builder/.vscode/settings.json deleted file mode 100644 index 0967ef424bce..000000000000 --- a/apps/form-builder/.vscode/settings.json +++ /dev/null @@ -1 +0,0 @@ -{} diff --git a/apps/form-builder/components/AuthProvider/AuthProvider.tsx b/apps/form-builder/components/AuthProvider/AuthProvider.tsx deleted file mode 100644 index c8b54c015ca8..000000000000 --- a/apps/form-builder/components/AuthProvider/AuthProvider.tsx +++ /dev/null @@ -1,31 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-nocheck -import { ReactNode } from 'react' -import useUser from '../../hooks/useUser' -import UserContext from '../../context/UserContext' -import { User } from '../../types/interfaces' - -interface UserProps { - children: ReactNode -} - -const AuthProvider = ({ children }: UserProps) => { - const { isAuthenticated, setIsAuthenticated, user, setUser, userLoading } = - useUser() - - return ( - - {children} - - ) -} - -export default AuthProvider diff --git a/apps/form-builder/components/Layout/Layout.css.ts b/apps/form-builder/components/Layout/Layout.css.ts deleted file mode 100644 index eb82ed5aa329..000000000000 --- a/apps/form-builder/components/Layout/Layout.css.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { style } from '@vanilla-extract/css' - -export const processContainer = style({ - minHeight: '100vh', -}) - -export const contentContainer = style({ - maxWidth: '100vw', -}) - -export const container = style({ - display: 'flex', - justifyContent: 'center', - height: '100vh', -}) - -export const contentWrapper = style({ - //maxWidth: '1140px', - width: '100%', - padding: '1rem 1rem', -}) diff --git a/apps/form-builder/components/Layout/Layout.tsx b/apps/form-builder/components/Layout/Layout.tsx deleted file mode 100644 index 29987465d433..000000000000 --- a/apps/form-builder/components/Layout/Layout.tsx +++ /dev/null @@ -1,74 +0,0 @@ -import { - Header, - Box, - Divider, - GridContainer as Grid, - GridColumn as Column, -} from '@island.is/island-ui/core' -import Head from 'next/head' -import React, { FC, useReducer } from 'react' -import * as styles from './Layout.css' -import { useRouter } from 'next/router' -import { headerInfoReducer } from '../../hooks/headerInfoReducer' -import LayoutContext from '../../context/LayoutContext' - -type LayoutProps = { - children: React.ReactNode -} - -const Layout: FC = ({ children }: LayoutProps) => { - const route = useRouter() - const initialInfo = { - organization: '', - applicationName: '', - } - const [info, dispatch] = useReducer(headerInfoReducer, initialInfo) - const layoutContext = { - info: info, - infoDispatch: dispatch, - } - - return ( - - - - Welcome to licensing-portal! - - - - route.push('/Forms')} - > -
- - - - - - - - - {children} - - - - - - ) -} /* */ - -export default Layout diff --git a/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx b/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx deleted file mode 100644 index 3e133bb81afe..000000000000 --- a/apps/form-builder/components/LicenseProviderDropdown/LicenseProviderDropdown.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import { Box, Select } from '@island.is/island-ui/core' -import { ILicenseProvider } from '../../types/interfaces' - -interface LicenseProviderDropdownProps { - licenseProviders: ILicenseProvider[] - setSelectProvider: (value: number) => void -} - -function mappedProviders(licenseProviders: ILicenseProvider[]) { - const lp = licenseProviders - .filter((lp) => lp.name.length > 0 && lp.language === 'is') - .map((lp) => ({ - label: lp.name, - value: lp.licenseProviderID, - })) - return lp.sort((a, b) => a.label.localeCompare(b.label)) -} - -export default function LicenseProviderDropdown({ - licenseProviders, - setSelectProvider, -}: LicenseProviderDropdownProps) { - const handleChange = (e: { label: string; value: number }) => { - setSelectProvider(e.value as number) - } - return ( - - - listsDispatch({ - type: 'changeName', - payload: { - lang: 'is', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - /> - - - - - - listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - activeItem.data.name.is, - ) - listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: translation.translations[0].translatedText, - }, - }) - }, - }, - ]} - /> - - - {activeItem.type === 'Group' && ( - - - - listsDispatch({ - type: 'setMultiSet', - payload: { - checked: e.target.checked, - }, - }) - } - /> - - - )} - - - - - - - )} - - ) -} diff --git a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx b/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx deleted file mode 100644 index 151dd6e493d8..000000000000 --- a/apps/form-builder/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ /dev/null @@ -1,149 +0,0 @@ -import { useContext, useState, FocusEvent } from 'react' -import { - Stack, - GridRow as Row, - GridColumn as Column, - Input, - DatePicker, - Checkbox, -} from '@island.is/island-ui/core' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import LayoutContext from '../../../../context/LayoutContext' -import { saveFormSettings } from '../../../../services/apiService' - -export default function BaseSettings() { - const { formBuilder, formDispatch } = useContext(FormBuilderContext) - const { infoDispatch } = useContext(LayoutContext) - const [focus, setFocus] = useState('') - const { - id, - name, - applicationsDaysToRemove, - invalidationDate, - stopProgressOnValidatingStep, - } = formBuilder.form - return ( - - - - setFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => { - formDispatch({ - type: 'changeName', - payload: { - lang: 'is', - newName: e.target.value, - }, - }) - infoDispatch({ - type: 'changeApplicationName', - payload: { - value: e.target.value, - }, - }) - }} - /> - - - setFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => { - formDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newName: e.target.value, - }, - }) - }} - /> - - - - - setFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => { - formDispatch({ - type: 'applicationsDaysToRemove', - payload: { value: e.target.value as unknown as number }, - }) - }} - /> - - - - - { - formDispatch({ - type: 'invalidationDate', - payload: { value: e }, - }) - }} - /> - - - - - { - formDispatch({ - type: 'stopProgressOnValidatingStep', - payload: { value: e.target.checked }, - }) - }} - /> - - - - ) - - function blur(e: FocusEvent) { - if (focus !== e.target.value) { - setFocus('') - const toSave = { - id: id, - name: name, - applicationsDaysToRemove: applicationsDaysToRemove, - invalidationDate: invalidationDate, - stopProgressOnValidatingStep: stopProgressOnValidatingStep, - } - saveFormSettings(id, toSave) - } - } -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx b/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx deleted file mode 100644 index 338a031a45d4..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/InputContent.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import { useContext, useState } from 'react' -import { - GridRow as Row, - GridColumn as Column, - Stack, - Input, - Checkbox, - ToggleSwitchCheckbox, - Text, - Button, -} from '@island.is/island-ui/core' -import ListContent from '../ListContent/ListContent' -import Preview from '../Preview/Preview' -import ListBuilder from '../ListBuilder/ListBuilder' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import { IInput, NavbarSelectStatus } from '../../../../types/interfaces' -import BaseInput from './components/BaseInput' -import TimeInput from './components/TimeInput' -import MessageWithLink from './components/MessageWithLink' -import FileUpload from './components/FileUpload/FileUpload' -import NumberInput from './components/NumberInput' -import PropertyNumberInputSettings from './components/PropertyNumberInputSettings' - -export default function InputContent() { - const { formBuilder, lists, selectStatus, setSelectStatus } = - useContext(FormBuilderContext) - - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const { inputSettings } = currentItem - const [inListBuilder, setInListBuilder] = useState(false) - const [isLarge, setIsLarge] = useState(false) - - const hasConnections = - formBuilder.form.dependencies[activeItem.data.guid] !== undefined && - formBuilder.form.dependencies[activeItem.data.guid].length > 0 - - if ( - (inListBuilder && currentItem.type === 'Fellilisti') || - (inListBuilder && currentItem.type === 'Valhnappar') - ) { - return - } - return ( - - - - {/* Additional settings depending on chosen input type */} - {['Hakbox'].includes(currentItem.type) && ( - - - - setSelectStatus( - e ? NavbarSelectStatus.NORMAL : NavbarSelectStatus.OFF, - ) - } - /> - - {hasConnections && ( - - Hefur tengingar - - )} - - )} - {/* List */} - {currentItem.type === 'Fellilisti' && ( - <> - - - )} - {/* Radio buttons */} - {currentItem.type === 'Valhnappar' && ( - - )} - {/* Textlinubox */} - {currentItem.type === 'Textalínubox' && ( - setIsLarge(e.target.checked)} - /> - )} - {/* "Klukkuinnsláttur" */} - {currentItem.type === 'Klukkuinnsláttur' && } - {/* Heimagistingarnúmer */} - {currentItem.type === 'Heimagistingarnúmer' && ( - - - - - - )} - {/* Testing text with linked button */} - {currentItem.type === 'Textalýsing' && } - {/* File upload */} - {currentItem.type === 'Skjal' && } - {currentItem.type === 'Tölustafir' && } - {currentItem.type === 'Fasteignanúmer' && } - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx deleted file mode 100644 index 2fec7e5b5292..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/BaseInput.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Select, - Stack, - Input, - Checkbox, - Option, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { - IInput, - IInputSettings, - IInputType, -} from '../../../../../types/interfaces' -import { translationStation } from '../../../../../services/translationStation' -import { SingleValue } from 'react-select' - -export default function BaseInput() { - const { formBuilder, lists, listsDispatch, onFocus, blur } = - useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const createAndSortOptions = formBuilder.inputTypes - .map((it) => { - return { - label: it.type, - value: it.type, - } - }) - .sort((a, b) => a.label.localeCompare(b.label)) - - const defaultOption = - currentItem.type === '' - ? null - : createAndSortOptions.find((o) => o.value === currentItem.type) - - return ( - - - - - listsDispatch({ - type: 'changeName', - payload: { - lang: 'is', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - /> - - - - {/* Name en */} - - - listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: e.target.value, - }, - }) - } - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - currentItem.name.is, - ) - listsDispatch({ - type: 'changeName', - payload: { - lang: 'en', - newValue: translation.translations[0].translatedText, - }, - }) - }, - }, - ]} - /> - - - {/* Description */} - {['Textalýsing'].includes(currentItem.type) && ( - <> - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setDescription', - payload: { - lang: 'is', - newValue: e.target.value, - }, - }) - } - /> - - - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setDescription', - payload: { - lang: 'en', - newValue: e.target.value, - }, - }) - } - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - currentItem.description.is, - ) - listsDispatch({ - type: 'setDescription', - payload: { - lang: 'en', - newValue: translation.translations[0].translatedText, - }, - }) - }, - }, - ]} - /> - - - - )} - - {/* Required checkbox */} - - - listsDispatch({ - type: 'setIsRequired', - payload: { - guid: currentItem.guid, - isRequired: e.target.checked, - }, - }) - } - /> - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx deleted file mode 100644 index 147c447882fa..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/FileUpload.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Checkbox, - Stack, - Box, - Select, - Text, - Option, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../../types/interfaces' -import fileSizes from './fileSizes.json' -import * as fileTypes from '../../../../../../lib/fileTypes.json' - -export default function FileUpload() { - const { lists, listsDispatch } = useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const { inputSettings } = currentItem - - const fileSizeOptions = fileSizes.fileSizes.map((size) => ({ - label: size.label, - value: size.value, - })) - - const fileAmountOptions: Option[] = [ - { label: '1', value: 1 }, - { label: '2', value: 2 }, - { label: '3', value: 3 }, - { label: '4', value: 4 }, - { label: '5', value: 5 }, - { label: '6', value: 6 }, - { label: '7', value: 7 }, - { label: '8', value: 8 }, - { label: '9', value: 9 }, - { label: '10', value: 10 }, - ] - - return ( - - - - - listsDispatch({ - type: 'setFileUploadSettings', - payload: { - property: 'erFjolval', - checked: e.target.checked, - }, - }) - } - /> - - - - - f.value === inputSettings.fjoldi, - )} - options={fileAmountOptions} - onChange={(e) => { - listsDispatch({ - type: 'setFileUploadSettings', - payload: { - property: 'fjoldi', - value: e?.value ?? undefined, - }, - }) - }} - /> - - )} - - - - Leyfa eftirfarandi skjalatýpur - - - - {Object.entries(fileTypes).map(([key, value], i) => ( - - {key !== 'default' && ( - - listsDispatch({ - type: 'setFileUploadSettings', - payload: { - property: 'tegundir', - checked: e.target.checked, - value: key, - }, - }) - } - /> - )} - - ))} - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json b/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json deleted file mode 100644 index 8cc59c37fe35..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/FileUpload/fileSizes.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "fileSizes": [ - { - "label": "1 mb", - "value": 1048576 - }, - { - "label": "2 mb", - "value": 2097152 - }, - { - "label": "3 mb", - "value": 3145728 - }, - { - "label": "4 mb", - "value": 4194304 - }, - { - "label": "5 mb", - "value": 5242880 - }, - { - "label": "6 mb", - "value": 6291456 - }, - { - "label": "7 mb", - "value": 7340032 - }, - { - "label": "8 mb", - "value": 8388608 - }, - { - "label": "9 mb", - "value": 9437184 - }, - { - "label": "10 mb", - "value": 10485760 - } - ] -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx deleted file mode 100644 index fab2b2c45a30..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/MessageWithLink.tsx +++ /dev/null @@ -1,130 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Input, - Checkbox, - Stack, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../types/interfaces' -import { translationStation } from '../../../../../services/translationStation' - -export default function MessageWithLink() { - const { lists, listsDispatch, onFocus, blur } = useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const { inputSettings } = currentItem - return ( - - - - - listsDispatch({ - type: 'setMessageWithLinkSettings', - payload: { - property: 'erHlekkur', - checked: e.target.checked, - }, - }) - } - /> - - - {inputSettings !== undefined ? ( - inputSettings.erHlekkur && ( - - - - { - listsDispatch({ - type: 'setMessageWithLinkSettings', - payload: { - property: 'hnapptexti', - lang: 'is', - value: e.target.value, - }, - }) - }} - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - /> - - - { - listsDispatch({ - type: 'setMessageWithLinkSettings', - payload: { - property: 'hnapptexti', - lang: 'en', - value: e.target.value, - }, - }) - }} - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - inputSettings.hnapptexti?.is ?? '', - ) - listsDispatch({ - type: 'setMessageWithLinkSettings', - payload: { - property: 'hnapptexti', - lang: 'en', - value: translation.translations[0].translatedText, - }, - }) - }, - }, - ]} - /> - - - - - - listsDispatch({ - type: 'setMessageWithLinkSettings', - payload: { - property: 'url', - value: e.target.value, - }, - }) - } - onFocus={(e) => onFocus(e.target.value)} - onBlur={(e) => blur(e)} - /> - - - - ) - ) : ( - <> - )} - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx deleted file mode 100644 index 6ba8daea594a..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/NumberInput.tsx +++ /dev/null @@ -1,105 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Input, - Stack, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../types/interfaces' - -export default function NumberInput() { - const { lists, listsDispatch, onFocus, blur } = useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const { inputSettings } = currentItem - - return ( - - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setNumberInputSettings', - payload: { - property: 'lagmarkslengd', - value: e.target.value as unknown as number, - }, - }) - } - /> - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setNumberInputSettings', - payload: { - property: 'hamarkslengd', - value: e.target.value as unknown as number, - }, - }) - } - /> - - - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setNumberInputSettings', - payload: { - property: 'laggildi', - value: e.target.value as unknown as number, - }, - }) - } - /> - - - onFocus(e.target.value)} - onBlur={(e) => blur(e)} - onChange={(e) => - listsDispatch({ - type: 'setNumberInputSettings', - payload: { - property: 'hagildi', - value: e.target.value as unknown as number, - }, - }) - } - /> - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx deleted file mode 100644 index 83c23d1df331..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/PropertyNumberInputSettings.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Checkbox, - Stack, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../types/interfaces' - -export default function PropertyNumberInputSettings() { - const { lists, listsDispatch } = useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const { inputSettings: settings } = currentItem - - return ( - - - - - listsDispatch({ - type: 'setInputSettings', - payload: { - inputSettings: { - ...settings, - erListi: e.target.checked, - }, - }, - }) - } - /> - - - - - - listsDispatch({ - type: 'setInputSettings', - payload: { - inputSettings: { - ...settings, - erInnslattur: e.target.checked, - }, - }, - }) - } - /> - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx b/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx deleted file mode 100644 index b047f8c71ed6..000000000000 --- a/apps/form-builder/components/MainContent/components/InputContent/components/TimeInput.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Select, -} from '@island.is/island-ui/core' -import { useContext } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' - -export default function TimeInput() { - const { listsDispatch } = useContext(FormBuilderContext) - return ( - - - {}} - /> - - - {}} - /> - - - - ) - } - - return ( - - - - { - setConnect(e) - setSelectStatus(() => - e - ? NavbarSelectStatus.LIST_ITEM - : NavbarSelectStatus.ON_WITHOUT_SELECT, - ) - setConnecting((prev) => - prev.map((l, i) => (i === index ? e : false)), - ) - setActiveListItem(e ? listItem : null) - }} - /> - - listsDispatch({ - type: 'setListItemSelected', - payload: { - guid: listItem.guid, - checked: e, - }, - }) - } - /> - - - - listsDispatch({ - type: 'removeListItem', - payload: { - guid: listItem.guid, - }, - }) - } - > - - - - - - - - - - , - ) => onFocus(event.target.value)} - onChange={(e) => - listsDispatch({ - type: 'setListItem', - payload: { - property: 'label', - lang: 'is', - value: e.target.value, - listItemGuid: listItem.guid, - }, - }) - } - /> - - - , - ) => onFocus(event.target.value)} - onChange={(e) => - listsDispatch({ - type: 'setListItem', - payload: { - property: 'label', - lang: 'en', - value: e.target.value, - listItemGuid: listItem.guid, - }, - }) - } - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - listItem.label.is, - ) - listsDispatch({ - type: 'setListItem', - payload: { - property: 'label', - lang: 'en', - value: translation.translations[0].translatedText, - listItemGuid: listItem.guid, - }, - }) - }, - }, - ]} - /> - - - - {isRadio && ( - - - , - ) => onFocus(event.target.value)} - onChange={(e) => - listsDispatch({ - type: 'setListItem', - payload: { - property: 'description', - lang: 'is', - value: e.target.value, - listItemGuid: listItem.guid, - }, - }) - } - /> - - - , - ) => onFocus(event.target.value)} - onChange={(e) => - listsDispatch({ - type: 'setListItem', - payload: { - property: 'description', - lang: 'en', - value: e.target.value, - listItemGuid: listItem.guid, - }, - }) - } - buttons={[ - { - label: 'translate', - name: 'reader', - onClick: async () => { - const translation = await translationStation( - listItem.description.is, - ) - listsDispatch({ - type: 'setListItem', - payload: { - property: 'description', - lang: 'en', - value: translation.translations[0].translatedText, - listItemGuid: listItem.guid, - }, - }) - }, - }, - ]} - /> - - - )} - - ) -} diff --git a/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx b/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx deleted file mode 100644 index 6f2b386c1e3e..000000000000 --- a/apps/form-builder/components/MainContent/components/ListContent/ListContent.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import { - GridColumn as Column, - GridRow as Row, - Select, - Stack, - Box, - Button, - RadioButton, - Option, -} from '@island.is/island-ui/core' -import { Dispatch, SetStateAction, useContext, useState } from 'react' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import { getList } from '../../../../services/apiService' -import { IInput } from '../../../../types/interfaces' -import { SingleValue } from 'react-select' - -type Props = { - setInListBuilder: Dispatch> -} - -const predeterminedLists = [ - { - label: 'Sveitarfélög', - value: 'Sveitarfelog', - }, - { - label: 'Lönd', - value: 'Lond', - }, - { - label: 'Póstnúmer', - value: 'Postnumer', - }, - { - label: 'Iðngreinarmeistara', - value: 'Idngreinarmeistara', - }, -] - -export default function ListContent({ setInListBuilder }: Props) { - const [radio, setRadio] = useState([true, false, false]) - const { lists, listsDispatch } = useContext(FormBuilderContext) - const { activeItem } = lists - return ( - - - - radioHandler(0)}> - - - - - - - radioHandler(1)}> - - - - - {radio[0] && ( - - )} - {radio[1] && ( - - - )} - {data.type === 'Klukkuinnsláttur' && ( - - - - )} - {data.type === 'Krónutölubox' && ( - - - - - - )} - {data.type === 'Heimagistingarnúmer' && ( - - - - )} - {data.type === 'Textalýsing' && ( - - )} - {data.type === 'Netfang' && } - {data.type === 'Skjal' && } - {data.type === 'Símanúmer' && ( - - )} - {data.type === 'Tölustafir' && ( - - )} - {data.type === 'Fellilisti' && } - {data.type === 'Valhnappar' && } - {data.type === 'Fasteignanúmer' && ( - - )} - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx deleted file mode 100644 index f2e49d1954fd..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/Banknumber.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Input, -} from '@island.is/island-ui/core' -import { useRef, useState } from 'react' - -export default function Banknumber() { - const [banki, setBanki] = useState() - const [hb, setHb] = useState() - const [reikningur, setReikningur] = useState() - const inputRefs = [ - useRef(), - useRef(), - useRef(), - ] - - const handleChange = (index: number, value: string) => { - if (index === 0) { - setBanki(value) - if (value.length === 4) { - if (inputRefs[1]?.current) { - inputRefs[1]?.current.focus() - } - } - } else if (index === 1) { - setHb(value) - if (value.length === 2) { - if (inputRefs[2]?.current) { - inputRefs[2]?.current.focus() - } - } - } else if (index === 2) { - if (value.length <= 6) { - setReikningur(value) - } - if (value.length === 6) { - if (inputRefs[2]?.current) { - inputRefs[2]?.current.blur() - } - } - } - } - - const addLeadingZeros = (originalNumber: string, max: number) => { - const zerosToAdd = max - originalNumber.length - if (zerosToAdd <= 0) { - return originalNumber - } - if (originalNumber.length === 0) { - return originalNumber - } - const leadingZeros = '0'.repeat(zerosToAdd) - return leadingZeros + originalNumber - } - - return ( - - - - } - label="Banki" - type="number" - value={banki} - maxLength={4} - name="" - onChange={(e) => handleChange(0, e.target.value)} - onBlur={(e) => setBanki(addLeadingZeros(e.target.value, 4))} - /> - - - - } - label="Hb" - maxLength={2} - type="number" - value={hb} - name="" - onChange={(e) => handleChange(1, e.target.value)} - onBlur={(e) => setHb(addLeadingZeros(e.target.value, 2))} - /> - - - - } - label="Reikningsnúmer" - type="number" - value={reikningur} - name="" - onChange={(e) => handleChange(2, e.target.value)} - onBlur={(e) => setReikningur(addLeadingZeros(e.target.value, 6))} - /> - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx deleted file mode 100644 index e1b9743587f3..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/Currency.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Input, -} from '@island.is/island-ui/core' -import { ChangeEvent, useState } from 'react' - -interface Props { - label: string -} - -export default function Currency({ label }: Props) { - const [currency, setCurrency] = useState('') - const handleCurrencyChange = ( - e: ChangeEvent, - ) => { - // Remove any non-digit characters from the input value - const inputValue = e.target.value.replace(/\D/g, '') - - // Split the input value into groups of three characters - const formattedValue = inputValue.replace(/\B(?=(\d{3})+(?!\d))/g, '.') - setCurrency(formattedValue) - } - return ( - - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx deleted file mode 100644 index 406f738ab013..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/Email.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useContext, useState } from 'react' -import { Input, Stack, Text } from '@island.is/island-ui/core' -import FormBuilderContext from '../../../../../context/FormBuilderContext' - -export default function Email() { - const { lists } = useContext(FormBuilderContext) - const { activeItem } = lists - const [email, setEmail] = useState('') - const [hasError, setHasError] = useState(false) - - return ( - - {activeItem.data.name.is} - setEmail(e.target.value)} - onBlur={() => setHasError(isValidEmail())} - errorMessage="Ekki gilt netfang" - hasError={hasError} - /> - - ) - - function isValidEmail(): boolean { - const pattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/ - const res = pattern.test(email) - return !res - } -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx b/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx deleted file mode 100644 index fa972769d3b8..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/FileUpload.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { - InputFileUpload, - UploadFile, - fileToObject, -} from '@island.is/island-ui/core' -import { useState } from 'react' -import { uuid } from 'uuidv4' -import * as fileTypes from '../../../../../lib/fileTypes.json' -import { IInput } from '../../../../../types/interfaces' - -type Props = { - currentItem: IInput -} - -export default function FileUpload({ currentItem }: Props) { - const [error, setError] = useState(undefined) - const [fileList, setFileList] = useState>([]) - - const onChange = (files: File[]) => { - const uploadFiles = files.map((file) => fileToObject(file)) - const uploadFilesWithKey = uploadFiles.map((f) => ({ - ...f, - key: uuid(), - })) - - // Check whether upload will exceed limit and if so, prevent it - const currentAmount = currentItem.inputSettings.fjoldi ?? 0 - if (fileList.length + uploadFilesWithKey.length > currentAmount) { - setError(`Hámarksfjöldi skjala er ${currentItem.inputSettings.fjoldi}`) - return - } - setError('') - const newFileList = [...fileList, ...uploadFilesWithKey] - setFileList(newFileList) - } - - const onRemove = (fileToRemove: UploadFile) => { - const newFileList = fileList.filter((file) => file.key !== fileToRemove.key) - setFileList(newFileList) - } - - return ( - <> - `${f} `, - )}`} - buttonLabel="Veldu skjöl til að hlaða upp" - onChange={onChange} - onRemove={onRemove} - errorMessage={fileList.length > 0 ? error : undefined} - accept={ - currentItem.inputSettings.tegundir?.map( - (t) => fileTypes[t as keyof typeof fileTypes], - ) ?? [] - } - showFileSize - maxSize={currentItem.inputSettings.hamarksstaerd} - multiple={currentItem.inputSettings.erFjolval} - /> - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/List.tsx b/apps/form-builder/components/MainContent/components/Preview/components/List.tsx deleted file mode 100644 index a5cdf3497d6a..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/List.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { Select } from '@island.is/island-ui/core' -import { useEffect, useState } from 'react' -import { IInput } from '../../../../../types/interfaces' - -interface Props { - currentItem: IInput -} - -type ListItem = { - label: string - value: string | number -} - -export default function List({ currentItem }: Props) { - const [listItems, setListItems] = useState([]) - useEffect(() => { - const currentList = currentItem.inputSettings.listi ?? [] - setListItems( - currentList.map((l) => ({ - label: l.label.is, - value: l.label.is, - })), - ) - }, [currentItem.inputSettings.listi]) - return ( - <> - - - - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/NumberInput.tsx b/apps/form-builder/components/MainContent/components/Preview/components/NumberInput.tsx deleted file mode 100644 index a4630b86ff3b..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/NumberInput.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import { Input } from '@island.is/island-ui/core' -import { useState } from 'react' -import { IInput } from '../../../../../types/interfaces' - -type Props = { - currentItem: IInput -} - -export default function NumberInput({ currentItem }: Props) { - const { - lagmarkslengd: minLength = 0, - hamarkslengd: maxLength = 0, - laggildi: min = 0, - hagildi: max = 0, - } = currentItem.inputSettings - // need to implement saving into listsDispatch - - const [value] = useState('') - const [error, setError] = useState(undefined) - - const changeHandler = (num: number) => { - if (num.toString().length < minLength) { - setError(`Lágmarkslengd er ${minLength}`) - } else if (num.toString().length > maxLength) { - setError(`Hámarkslengd er ${maxLength}`) - } else if (num < min) { - setError(`Lággildi er ${min}`) - } else if (num > max) { - setError(`Hágildi er ${max}`) - } else { - setError(undefined) - } - } - - return ( - changeHandler(parseInt(e.target.value))} - errorMessage={error} - /> - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx deleted file mode 100644 index fbad4ea8fea8..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PhoneInput.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - PhoneInput as Phone, -} from '@island.is/island-ui/core' -import { IInput } from '../../../../../types/interfaces' - -interface Props { - currentItem: IInput -} - -export default function PhoneInput({ currentItem }: Props) { - return ( - - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx deleted file mode 100644 index 2564264febb6..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/PropertyNumber.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { IInput } from '../../../../../../types/interfaces' -import { - PropertyNumberCombined, - PropertyNumberInput, - PropertyNumberList, -} from './components' - -interface Props { - currentItem: IInput -} - -export default function PropertyNumber({ currentItem }: Props) { - const { inputSettings: settings } = currentItem - const { erListi: hasList, erInnslattur: hasInput } = settings - - return ( - <> - {hasList && !hasInput ? ( - - ) : !hasList && hasInput ? ( - - ) : hasList && hasInput ? ( - - ) : null} - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx deleted file mode 100644 index 55a549a24809..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberCombined.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Tabs } from '@island.is/island-ui/core' -import PropertyNumberList from './PropertyNumberList' -import PropertyNumberInput from './PropertyNumberInput' - -export default function PropertyNumberCombined() { - return ( - , - }, - { - label: 'Fasteignanúmerinnsláttur', - content: , - }, - ]} - contentBackground="blue100" - /> - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx deleted file mode 100644 index 9d3eb0c0c2f5..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberInput.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Stack, - Input, - Box, -} from '@island.is/island-ui/core' -import { useState } from 'react' - -export default function PropertyNumberInput() { - const [propertyNumber, setPropertyNumber] = useState('') - return ( - - - - - setPropertyNumber(e.target.value)} - /> - - - - - - - - - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx deleted file mode 100644 index 6de9e63bf2fa..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/PropertyNumberList.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Stack, - Select, - Input, - Box, -} from '@island.is/island-ui/core' - -const dummyList = [ - { - label: 'Fasteign 1', - value: '1', - }, - { - label: 'Fasteign 2', - value: '2', - }, - { - label: 'Fasteign 3', - value: '3', - }, -] - -export default function PropertyNumberList() { - return ( - - - - - - - - - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts b/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts deleted file mode 100644 index a1b1b4d6c4ac..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/PropertyNumber/components/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { default as PropertyNumberList } from './PropertyNumberList' -export { default as PropertyNumberInput } from './PropertyNumberInput' -export { default as PropertyNumberCombined } from './PropertyNumberCombined' diff --git a/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx b/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx deleted file mode 100644 index 7ca9d0360727..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/Radio.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { RadioButton, Text, Box } from '@island.is/island-ui/core' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { useContext, useEffect, useState } from 'react' -import { IInput, IListItem } from '../../../../../types/interfaces' - -export default function Radio() { - const { lists } = useContext(FormBuilderContext) - const { activeItem } = lists - const currentItem = activeItem.data as IInput - const radioButtons = currentItem.inputSettings.listi - const [radioChecked, setRadioChecked] = useState([]) - - useEffect(() => { - setRadioChecked(radioButtons?.map(() => false) ?? []) - }, [radioButtons]) - - const radioButton = (rb: IListItem, index: number) => ( - - setRadioChecked((prev) => - prev.map((rb, i) => (i === index ? true : false)), - ) - } - > - - - ) - - return ( - <> - - {currentItem.name.is} - - - {radioButtons?.map((rb, index) => radioButton(rb, index))} - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx b/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx deleted file mode 100644 index 4f88d2dbddad..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/TimeSelect.tsx +++ /dev/null @@ -1,215 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Input, - Select, - Box, -} from '@island.is/island-ui/core' -import { ChangeEvent, useContext, useState } from 'react' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IInput } from '../../../../../types/interfaces' - -type Option = { label: string; value: string } - -export default function TimeSelect() { - const { lists } = useContext(FormBuilderContext) - const { activeItem } = lists - const inputItem = activeItem.data as IInput - - const [timeInput, setTimeInput] = useState('') - - // 0: Minute - // 1: Hourly - // 2: Half hour - // 3: Quarter - const chosenMinuteList = (): Option[] => { - const min = minuteList.minuteList.map((t) => { - return { - label: t, - value: t, - } - }) - - if (inputItem?.inputSettings === undefined) { - return min - } else { - const interval = inputItem.inputSettings.interval - - if (interval === 0) { - return min - } else if (interval === 1) { - return [{ label: '00', value: '00' }] - } else if (interval === 2) { - return halfList.minuteList.map((m) => { - return { - label: m, - value: m, - } - }) - } else if (interval === 3) { - return quarterList.minuteList.map((m) => { - return { - label: m, - value: m, - } - }) - } else { - // Handle other cases if needed - return min - } - } - } - - const handleTimeInput = ( - e: ChangeEvent, - ) => { - const inputValue = e.target.value - - const isValidTime = - /^(?:[01]?[0-9]|2[0-3]):[0-5]?[0-9](?::[0-5]?[0-9])?$/.test(inputValue) - setTimeInput(inputValue) - if (isValidTime || inputValue === '') { - setTimeInput(inputValue) - } - } - - return ( - <> - - - - - - handleTimeInput(e)} - /> - - ) -} - -const hourList = { - hourList: [ - '00', - '01', - '02', - '03', - '04', - '05', - '06', - '07', - '08', - '09', - '10', - '11', - '12', - '13', - '14', - '15', - '16', - '17', - '18', - '19', - '20', - '21', - '22', - '23', - ], -} - -const minuteList = { - minuteList: [ - '00', - '01', - '02', - '03', - '04', - '05', - '06', - '07', - '08', - '09', - '10', - '11', - '12', - '13', - '14', - '15', - '16', - '17', - '18', - '19', - '20', - '21', - '22', - '23', - '24', - '25', - '26', - '27', - '28', - '29', - '30', - '31', - '32', - '33', - '34', - '35', - '36', - '37', - '38', - '39', - '40', - '41', - '42', - '43', - '44', - '45', - '46', - '47', - '48', - '49', - '50', - '51', - '52', - '53', - '54', - '55', - '56', - '57', - '58', - '59', - ], -} - -const quarterList = { - minuteList: ['00', '15', '30', '45'], -} - -const halfList = { - minuteList: ['00', '30'], -} diff --git a/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx b/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx deleted file mode 100644 index 9660d754e7b7..000000000000 --- a/apps/form-builder/components/MainContent/components/Preview/components/UtilizationSummary/UtilizationSummary.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import ReactDatePicker from 'react-datepicker' - -export default function UtilizationSummary() { - return ( - console.log(date)} - dateFormat="dd.MM.yyyy" - /> - ) -} diff --git a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx deleted file mode 100644 index 966cc1fee76e..000000000000 --- a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/MultiSet/MultiSet.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import { useContext, useState } from 'react' -import { Box, Icon } from '@island.is/island-ui/core' -import Preview from '../../Preview/Preview' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { IGroup, IInput } from '../../../../../types/interfaces' - -interface Props { - group: IGroup -} -export default function MultiSet({ group }: Props) { - const { lists } = useContext(FormBuilderContext) - const { inputs } = lists - const originalInput = inputs.filter((i) => i.groupGuid === group.guid) - const [multiInput, setMultiInput] = useState([ - inputs.filter((i) => i.groupGuid === group.guid), - ]) - - return ( - - {multiInput.map((inputArray, index) => ( -
- {inputArray.map((i) => ( - - ))} -
- ))} - - - - - -
- ) - - function add() { - setMultiInput((prev) => [...prev, originalInput]) - } -} diff --git a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx b/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx deleted file mode 100644 index 7e169c07786e..000000000000 --- a/apps/form-builder/components/MainContent/components/PreviewStepOrGroup/PreviewStepOrGroup.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { Dispatch, SetStateAction, useContext } from 'react' -import { Box, Button, Text } from '@island.is/island-ui/core' -import Preview from '../Preview/Preview' -import MultiSet from './MultiSet/MultiSet' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import { IGroup, NavbarSelectStatus } from '../../../../types/interfaces' - -interface Props { - setOpenPreview: Dispatch> -} - -export default function PreviewStepOrGroup({ setOpenPreview }: Props) { - const { lists, setSelectStatus } = useContext(FormBuilderContext) - const { activeItem, groups, inputs } = lists - const { type } = activeItem - - return ( - - {type === 'Step' && ( - <> - - {activeItem.data.name.is} - - {groups - .filter((g) => g.stepGuid === activeItem.data.guid) - .map((g) => ( - - - {g.name.is} - - {g.multiSet !== 0 ? ( - - ) : ( - inputs - .filter((i) => i.groupGuid === g.guid) - .map((i) => ( - - )) - )} - - ))} - - )} - {type === 'Group' && ( - - - {activeItem.data.name.is} - - {(activeItem.data as IGroup).multiSet !== 0 ? ( - - ) : ( - inputs - .filter((i) => i.groupGuid === activeItem.data.guid) - .map((i) => ( - - )) - )} - - )} - - - - - ) -} diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx deleted file mode 100644 index 9cd5944391fb..000000000000 --- a/apps/form-builder/components/MainContent/components/RelevantParties/RelevantParties.tsx +++ /dev/null @@ -1,285 +0,0 @@ -import React, { useContext, useState } from 'react' -import { Stack, Checkbox, Box, Text } from '@island.is/island-ui/core' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import { - IApplicantType, - IFormApplicantType, -} from '../../../../types/interfaces' -import { saveApplicantTypes } from '../../../../services/apiService' -import { EFormApplicantTypes } from '../../../../types/enums' -import { FormApplicantType } from './components/FormApplicantType' - -const applicantTypeLabel = [ - 'Einstaklingur (innskráður)', - 'Einstaklingur í umboði annars einstaklings', - 'Einstaklingur í umboði lögaðila', - 'Einstaklingur með prókúru', - 'Umboðsveitandi (einstaklingur)', - 'Lögaðili', -] - -const applicantTypes = [ - 'Einstaklingur', - 'Einstaklingur_með_umboð_annars_einstaklings', - 'Einstaklingur_með_umboð_lögaðila', - 'Einstaklingur_með_prókúru', - 'Einstaklingur_umboðsveitandi', - 'Lögaðili', -] - -export default function RelevantParties() { - const { formBuilder } = useContext(FormBuilderContext) - const applicantTypeTemplates = formBuilder.applicantTypes - const [formApplicantTypes, setFormApplicantTypes] = useState< - IFormApplicantType[] - >(formBuilder.form.formApplicantTypes) - const { id: formId } = formBuilder.form - const [focus, setOnFocus] = useState('') - - const createFormApplicantType = ( - type: EFormApplicantTypes, - template: IApplicantType, - ): IFormApplicantType => { - return { - formId: formId, - type: type, - applicantTypeId: template.id, - name: template.nameSuggestions[0].nameSuggestion, - } - } - - const handleCheckboxChange = (checked: boolean, index: number) => { - const updateFormApplicantTypes = ( - newFormApplicantTypes: IFormApplicantType[], - ) => { - const hasLegalEntity = formApplicantTypes.some( - (f) => f.type === EFormApplicantTypes.logadili, - ) - const newTypes = hasLegalEntity - ? newFormApplicantTypes.filter( - (f) => f.type !== EFormApplicantTypes.logadili, - ) - : newFormApplicantTypes - const newList = [...formApplicantTypes, ...newTypes] - saveApplicantTypes(formId, newList) - setFormApplicantTypes([...formApplicantTypes, ...newTypes]) - } - - const removeFormApplicantTypes = (types: EFormApplicantTypes[]) => { - const newList = formApplicantTypes.filter((f) => !types.includes(f.type)) - saveApplicantTypes(formId, newList) - setFormApplicantTypes(newList) - } - - if (checked) { - if (index === 0) { - const template = applicantTypeTemplates.find( - (at) => at.type === applicantTypes[index], - ) - if (template !== undefined) { - const newFormApplicantType: IFormApplicantType = - createFormApplicantType(EFormApplicantTypes.einstaklingur, template) - saveApplicantTypes(formId, [newFormApplicantType]) - setFormApplicantTypes([...formApplicantTypes, newFormApplicantType]) - } - } else if (index === 1) { - const delegatorTemplate = applicantTypeTemplates.find( - (at) => at.id === 2, - ) - const delegateeTemplate = applicantTypeTemplates.find( - (at) => at.id === 5, - ) - if ( - delegatorTemplate === undefined || - delegateeTemplate === undefined - ) { - return - } - const newFormApplicantTypes: IFormApplicantType[] = [ - createFormApplicantType( - EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, - delegatorTemplate, - ), - createFormApplicantType( - EFormApplicantTypes.einstaklingurUmbodsveitandi, - delegateeTemplate, - ), - ] - setFormApplicantTypes([...formApplicantTypes, ...newFormApplicantTypes]) - } else if (index === 2) { - const delegatorTemplate = applicantTypeTemplates.find( - (at) => at.id === 6, - ) - const delegateeTemplate = applicantTypeTemplates.find( - (at) => at.id === 3, - ) - if ( - delegatorTemplate === undefined || - delegateeTemplate === undefined - ) { - return - } - const newFormApplicantTypes: IFormApplicantType[] = [ - createFormApplicantType( - EFormApplicantTypes.einstaklingurMedUmbodLogadila, - delegateeTemplate, - ), - createFormApplicantType( - EFormApplicantTypes.logadili, - delegatorTemplate, - ), - ] - updateFormApplicantTypes(newFormApplicantTypes) - } else if (index === 3) { - const procurationHolder = applicantTypeTemplates.find( - (at) => at.id === 4, - ) - const legalEntity = applicantTypeTemplates.find((at) => at.id === 6) - if (procurationHolder === undefined || legalEntity === undefined) { - return - } - - const newFormApplicantTypes: IFormApplicantType[] = [ - createFormApplicantType( - EFormApplicantTypes.einstaklingurMedProkuru, - procurationHolder, - ), - createFormApplicantType(EFormApplicantTypes.logadili, legalEntity), - ] - updateFormApplicantTypes(newFormApplicantTypes) - } - } else { - if (index === 0) { - removeFormApplicantTypes([EFormApplicantTypes.einstaklingur]) - } else if (index === 1) { - removeFormApplicantTypes([ - EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, - EFormApplicantTypes.einstaklingurUmbodsveitandi, - ]) - } else if (index === 2) { - if ( - formApplicantTypes.some( - (f) => f.type === EFormApplicantTypes.einstaklingurMedProkuru, - ) - ) { - removeFormApplicantTypes([ - EFormApplicantTypes.einstaklingurMedUmbodLogadila, - ]) - } else { - removeFormApplicantTypes([ - EFormApplicantTypes.einstaklingurMedUmbodLogadila, - EFormApplicantTypes.logadili, - ]) - } - } else if (index === 3) { - if ( - formApplicantTypes.some( - (f) => f.type === EFormApplicantTypes.einstaklingurMedUmbodLogadila, - ) - ) { - removeFormApplicantTypes([ - EFormApplicantTypes.einstaklingurMedProkuru, - ]) - } else { - removeFormApplicantTypes([ - EFormApplicantTypes.einstaklingurMedProkuru, - EFormApplicantTypes.logadili, - ]) - } - } - } - } - - return ( - - - - Veldu þá einstaklinga sem mega opna þessa umsókn - - - - - {applicantTypeLabel.slice(0, 4).map((label, index) => ( - f.type === applicantTypes[index], - )} - onChange={(e) => handleCheckboxChange(e.target.checked, index)} - /> - ))} - - - {formApplicantTypes.length > 0 && ( - - Skilgreindu hlutaðeigandi aðila - - )} - {formApplicantTypes.map((f, i) => ( - at.id === f.applicantTypeId) - ?.nameSuggestions.map((ns) => ns.nameSuggestion) ?? [] - } - formApplicantType={f} - index={i} - handleSelect={handleSelect} - blur={blur} - setOnFocus={onFocus} - setFormApplicantTypes={setFormApplicantTypes} - isOther={isOther(f)} - /> - ))} - - ) - - function isOther(applicant: IFormApplicantType) { - const template = applicantTypeTemplates.find( - (at) => at.id === applicant.applicantTypeId, - ) - if (!template) { - return true - } - if ( - template.nameSuggestions.some( - (ns) => ns.nameSuggestion.is === applicant.name.is, - ) - ) { - return false - } - return true - } - - function handleSelect(e: { label: string; value: string }, index: number) { - const newApplicantTypes = formApplicantTypes.map((f, i) => { - if (i === index) { - return { - ...f, - name: { - is: e.label, - en: e.value, - }, - } - } - return f - }) - saveApplicantTypes(formId, newApplicantTypes) - setFormApplicantTypes(newApplicantTypes) - } - - function onFocus(value: string) { - setOnFocus(value) - } - - function blur(value: string) { - if (focus !== value) { - saveApplicantTypes(formId, formApplicantTypes) - } - setOnFocus('') - } -} diff --git a/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx b/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx deleted file mode 100644 index 8a30d746a5f1..000000000000 --- a/apps/form-builder/components/MainContent/components/RelevantParties/components/FormApplicantType.tsx +++ /dev/null @@ -1,143 +0,0 @@ -import React, { useState } from 'react' -import { - Box, - GridColumn as Column, - GridRow as Row, - Input, - Select, - Stack, - Text, -} from '@island.is/island-ui/core' -import { IFormApplicantType, ILanguage } from '../../../../../types/interfaces' - -interface Props { - title: string - nameSuggestions: ILanguage[] - name: ILanguage - formApplicantType: IFormApplicantType - handleSelect( - e: { - label: string - value: string - }, - index: number, - ): void - index: number - blur(value: string): void - setOnFocus(value: string): void - setFormApplicantTypes: React.Dispatch< - React.SetStateAction - > - isOther: boolean -} - -export function FormApplicantType({ - title, - name, - nameSuggestions, - handleSelect, - index, - blur, - setOnFocus, - setFormApplicantTypes, - isOther, -}: Props) { - const [inputEnabled, setInputEnabled] = useState(isOther) - - const other = { label: 'Annað', value: 'Annað' } - - function getOptions() { - const options = nameSuggestions.map((suggestion) => { - return { - label: suggestion.is, - value: suggestion.en, - } - }) - options.push(other) - return options - } - - function handleSelectChange(e: { label: string; value: string }) { - if (e.label === 'Annað') { - setInputEnabled(true) - } else { - setInputEnabled(false) - handleSelect(e, index) - } - } - - function handleInputChange( - e: React.ChangeEvent, - language: 'is' | 'en', - ) { - setFormApplicantTypes((prev: IFormApplicantType[]) => { - const newApplicantTypes = prev.map((f: IFormApplicantType, i: number) => { - if (i === index) { - return { - ...f, - name: { - ...f.name, - [language]: e.target.value, - }, - } - } - return f - }) - return newApplicantTypes - }) - } - - return ( - - - - - - {title} - - - - - - setOnFocus(e.target.value)} - onBlur={(e) => blur(e.target.value)} - onChange={(e) => handleInputChange(e, 'is')} - /> - - - setOnFocus(e.target.value)} - onBlur={(e) => blur(e.target.value)} - onChange={(e) => handleInputChange(e, 'en')} - /> - - - - - ) -} diff --git a/apps/form-builder/components/Navbar/Navbar.tsx b/apps/form-builder/components/Navbar/Navbar.tsx deleted file mode 100644 index 6a02863759e2..000000000000 --- a/apps/form-builder/components/Navbar/Navbar.tsx +++ /dev/null @@ -1,327 +0,0 @@ -/* eslint-disable func-style */ -import { - useSensors, - useSensor, - PointerSensor, - DndContext, - DragOverlay, - UniqueIdentifier, - DragStartEvent, - DragOverEvent, - DataRef, -} from '@dnd-kit/core' -import { SortableContext } from '@dnd-kit/sortable' -import { useContext, useMemo } from 'react' -import { createPortal } from 'react-dom' -import { Box, Button } from '@island.is/island-ui/core' -import FormBuilderContext from '../../context/FormBuilderContext' -import { baseSettingsStep } from '../../utils/getBaseSettingsStep' -import { IFormBuilderContext, ItemType } from '../../types/interfaces' -import { addStep, deleteItem } from '../../services/apiService' -import NavbarTab from './components/NavbarTab/NavbarTab' -import NavComponent from './components/NavComponent/NavComponent' - -export default function Navbar() { - const { - formBuilder, - lists, - listsDispatch, - formUpdate, - inSettings, - setInSettings, - } = useContext(FormBuilderContext) - - const { activeItem, steps, groups, inputs } = lists - const stepsIds = useMemo(() => steps?.map((s) => s.guid), [steps]) - const groupsIds = useMemo(() => groups?.map((g) => g.guid), [groups]) - const inputsIds = useMemo(() => inputs?.map((i) => i.guid), [inputs]) - - const sensors = useSensors( - useSensor(PointerSensor, { - activationConstraint: { - distance: 10, - }, - }), - ) - if (inSettings) { - return ( - - - - - - - - {steps - ?.filter((s) => s.type !== 'Innsláttur') - .map((s) => ( - - - - ))} - - - - - ) - } else if (formBuilder && activeItem) { - return ( - - - - - - - {steps - ?.filter((s) => s.type === 'Innsláttur') - .map((s, i) => ( - - - - {groups - ?.filter((g) => g.stepGuid === s.guid) - .map((g) => ( - - - - - {inputs - ?.filter((i) => i.groupGuid === g.guid) - .map((i) => ( - - ))} - - - ))} - - - ))} - - - {/* Only render client side */} - {typeof window === 'object' && - createPortal( - - {activeItem && ( - - )} - , - document.body, - )} - - - - - - ) - } - return null - - async function addNewStep() { - try { - const data = await addStep( - formBuilder.form.id, - { is: '', en: '' }, - lists.steps.length, - 2, - { is: '', en: '' }, - false, - ) - - if (data !== undefined && data !== null) { - listsDispatch({ type: 'addStep', payload: { data: data } }) - } - } catch (error) { - console.error('Error adding new step:', error) - } - } - - type ActionType = 'removeStep' | 'removeGroup' | 'removeInput' - - function removeItem(type: ItemType, guid: UniqueIdentifier, id: number) { - const actionTypes: Record = { - Step: 'removeStep', - Group: 'removeGroup', - Input: 'removeInput', - } - - listsDispatch({ - type: actionTypes[type], - payload: { - guid: guid, - }, - }) - deleteItem(type, id) - } - - function focusComponent(type: ItemType, id: UniqueIdentifier) { - const dataTypes = { - Step: lists.steps, - Group: lists.groups, - Input: lists.inputs, - } - - const data = dataTypes[type]?.find((item) => item.guid === id) - if (id === baseSettingsStep.guid) { - listsDispatch({ - type: 'setActiveItem', - payload: { - type: 'Step', - data: baseSettingsStep, - }, - }) - } else if (data) { - listsDispatch({ - type: 'setActiveItem', - payload: { - type: type, - data: data, - }, - }) - } - } - - function onDragStart(event: DragStartEvent) { - listsDispatch({ - type: 'setActiveItem', - payload: { - type: event.active.data.current?.type, - data: event.active.data.current?.data ?? null, - }, - }) - } - - function onDragEnd() { - formUpdate() - } - - type DndAction = - | 'stepOverStep' - | 'groupOverStep' - | 'groupOverGroup' - | 'inputOverGroup' - | 'inputOverInput' - - function onDragOver(event: DragOverEvent) { - const { active, over } = event - - if (!over) return - - const activeId = active.id - const overId = over.id - - if (activeId === overId) return - - const getType = ( - data: DataRef<{ [x: string]: unknown }>, - targetType: ItemType, - ) => data?.current?.type === targetType - - const activeStep = getType(active.data, 'Step') - const activeGroup = getType(active.data, 'Group') - const activeInput = getType(active.data, 'Input') - const overStep = getType(over.data, 'Step') - const overGroup = getType(over.data, 'Group') - const overInput = getType(over.data, 'Input') - - const dispatchDragAction = (type: DndAction) => - listsDispatch({ type, payload: { activeId: activeId, overId: overId } }) - - // Dragging step - if (activeStep && overStep) { - dispatchDragAction('stepOverStep') - } - // Dragging Group - else if (activeGroup) { - if (overStep) { - dispatchDragAction('groupOverStep') - } - if (overGroup) { - dispatchDragAction('groupOverGroup') - } - } - // Dragging Input - else if (activeInput) { - if (overGroup) { - dispatchDragAction('inputOverGroup') - } - if (overInput) { - dispatchDragAction('inputOverInput') - } - } - } -} diff --git a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts deleted file mode 100644 index ffee12eb1162..000000000000 --- a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.css.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { style, styleVariants } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -const base = style({ - border: `1px solid ${theme.border.color.blue200}`, - borderRadius: theme.border.radius.standard, - marginBottom: '2px', - height: '46px', - marginLeft: 'auto', - backgroundColor: theme.color.blue100, - lineHeight: '46px', - ':hover': { - fontWeight: 'bolder', - }, - cursor: 'grab', -}) - -export const step = style({ - border: `1px solid ${theme.border.color.blue200}`, - borderRadius: theme.border.radius.standard, - marginBottom: '2px', - height: '46px', - width: '100%', -}) - -export const navComponent = styleVariants({ - step: [ - base, - { - width: '100%', - }, - ], - group: [ - base, - { - width: '90%', - }, - ], - input: [ - base, - { - width: '80%', - }, - ], -}) - -const baseBackground = style({ - width: '25px', - height: '44px', - borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, - textAlign: 'center', -}) - -export const navBackgroundActive = styleVariants({ - step: [ - baseBackground, - { - backgroundColor: theme.color.blue600, - lineHeight: '45px', - color: theme.color.white, - }, - ], - group: [ - baseBackground, - { - backgroundColor: theme.color.roseTinted400, - }, - ], - input: [ - baseBackground, - { - backgroundColor: theme.color.purple400, - }, - ], -}) - -export const navBackgroundDefault = styleVariants({ - step: [ - baseBackground, - { - lineHeight: '45px', - }, - ], - group: [baseBackground, {}], - input: [baseBackground, {}], -}) - -export const customBackgroundDropdown = style({ - background: theme.color.blue100, -}) diff --git a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx b/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx deleted file mode 100644 index 4cebcf15459f..000000000000 --- a/apps/form-builder/components/Navbar/components/NavComponent/NavComponent.tsx +++ /dev/null @@ -1,176 +0,0 @@ -import { useState } from 'react' -import { ItemType, IGroup, IInput, IStep } from '../../../../types/interfaces' -import { useSortable } from '@dnd-kit/sortable' -import { Box } from '@island.is/island-ui/core' -import cn from 'classnames' -import * as styles from './NavComponent.css' -import { UniqueIdentifier } from '@dnd-kit/core' -import NavButtons from './components/NavButtons' - -type Props = { - type: ItemType - data: IStep | IGroup | IInput - active: boolean - index?: number - focusComponent(type: ItemType, id: UniqueIdentifier): void - remove( - type: 'Step' | 'Group' | 'Input', - guid: UniqueIdentifier, - id: number, - ): void -} - -export default function NavComponent({ - type, - data, - active, - index, - focusComponent, - remove, -}: Props) { - const [editMode] = useState(false) - - const { setNodeRef, attributes, listeners, isDragging } = useSortable({ - id: data.guid, - data: { - type: type, - data, - }, - disabled: editMode, - }) - - if (isDragging) { - return ( -
-
-
- ) - } - - return ( - focusComponent(type, data.guid)} - > - {active ? ( - - - {index} - - - {truncateName(data.name.is)} - - - {!(type === 'Step' && (data as IStep).type !== 'Innsláttur') && ( - - )} - - - ) : ( - - - {index} - - - {truncateName(data.name.is)} - - - )} - - ) - - function truncateText(text: string, maxLength: number) { - return text.length > maxLength ? text.slice(0, maxLength) + '...' : text - } - - function truncateName(name: string) { - let maxLength - - if (active) { - switch (type) { - case 'Step': - maxLength = 23 - break - case 'Group': - maxLength = 16 - break - case 'Input': - maxLength = 12 - break - default: - maxLength = 26 - } - } else { - switch (type) { - case 'Step': - maxLength = 26 - break - case 'Group': - maxLength = 19 - break - case 'Input': - maxLength = 16 - break - default: - maxLength = 26 - } - } - - return truncateText(name, maxLength) - } -} diff --git a/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx b/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx deleted file mode 100644 index d345afe154bc..000000000000 --- a/apps/form-builder/components/Navbar/components/NavComponent/components/NavButtons.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Box, Icon } from '@island.is/island-ui/core' -import { useContext } from 'react' -import { UniqueIdentifier } from '@dnd-kit/core' -import FormBuilderContext from '../../../../../context/FormBuilderContext' -import { addGroup, addInput } from '../../../../../services/apiService' -import { ItemType } from '../../../../../types/interfaces' - -type Props = { - remove(type: ItemType, guid: UniqueIdentifier, id: number): void -} - -export default function NavButtons({ remove }: Props) { - const { lists, listsDispatch } = useContext(FormBuilderContext) - const { activeItem } = lists - return ( - - {activeItem.type !== 'Input' && ( - - - - )} - { - remove(activeItem.type, activeItem.data.guid, activeItem.data.id) - }} - > - - - - ) - - async function addItem() { - if (activeItem.type === 'Step') { - const newGroup = await addGroup(lists.groups.length, activeItem.data.id) - if (newGroup) { - listsDispatch({ type: 'addGroup', payload: { data: newGroup } }) - } - } else if (activeItem.type === 'Group') { - const newInput = await addInput(lists.inputs.length, activeItem.data.id) - if (newInput) { - listsDispatch({ type: 'addInput', payload: { data: newInput } }) - } - } - } -} diff --git a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx deleted file mode 100644 index c6a1b1bc3068..000000000000 --- a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.css.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { style } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -export const selected = style({ - cursor: 'pointer', - fontWeight: 'bolder', - textDecoration: 'underline', - color: theme.color.blue400, -}) - -export const notSelected = style({ - cursor: 'pointer', - ':hover': { - fontWeight: 'bolder', - textDecoration: 'underline', - }, -}) diff --git a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx b/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx deleted file mode 100644 index 509ae6bc8bda..000000000000 --- a/apps/form-builder/components/Navbar/components/NavbarTab/NavbarTab.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { Box, Inline } from '@island.is/island-ui/core' -import cn from 'classnames' -import * as styles from './NavbarTab.css' -import { Dispatch, SetStateAction, useContext } from 'react' -import FormBuilderContext from '../../../../context/FormBuilderContext' -import { baseSettingsStep } from '../../../../utils/getBaseSettingsStep' - -type Props = { - inSettings: boolean - setInSettings: Dispatch> -} - -export default function NavbarTab({ inSettings, setInSettings }: Props) { - const { lists, listsDispatch } = useContext(FormBuilderContext) - return ( - - - { - listsDispatch({ - type: 'setActiveItem', - payload: { - type: 'Step', - data: lists.steps[2], - }, - }) - setInSettings(false) - }} - > - Skref - - { - listsDispatch({ - type: 'setActiveItem', - payload: { - type: 'Step', - data: baseSettingsStep, - }, - }) - setInSettings(true) - }} - > - Grunnstillingar - - - - ) -} diff --git a/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx b/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx deleted file mode 100644 index 59ea105f02ce..000000000000 --- a/apps/form-builder/components/NavbarSelect/NavbarSelect.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { useContext } from 'react' -import { Box, Text } from '@island.is/island-ui/core' -import SelectNavComponent from './components/SelectNavComponent' -import FormBuilderContext from '../../context/FormBuilderContext' -import { NavbarSelectStatus } from '../../types/interfaces' - -export default function NavbarSelect() { - const { lists, selectStatus } = useContext(FormBuilderContext) - const { activeItem, steps, groups, inputs } = lists - let selectable = false - return ( - - - Skref - - {steps - .filter((s) => s.type === 'Innsláttur') - .map((s) => ( - - - {groups - .filter((g) => g.stepGuid === s.guid) - .map((g) => ( - - - {inputs - .filter((i) => i.groupGuid === g.guid) - .map((i) => { - if (activeItem.data.guid === i.guid) { - if ( - selectStatus !== NavbarSelectStatus.ON_WITHOUT_SELECT - ) { - selectable = true - } - } - return ( - - ) - })} - - ))} - - ))} - - ) -} diff --git a/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx b/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx deleted file mode 100644 index 3ed0723a5f39..000000000000 --- a/apps/form-builder/components/NavbarSelect/components/SelectNavComponent.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import cn from 'classnames' -import * as styles from './selectNavComponent.css' -import { Box, Checkbox } from '@island.is/island-ui/core' -import { useContext } from 'react' -import { - IGroup, - IInput, - IStep, - ItemType, - NavbarSelectStatus, -} from '../../../types/interfaces' -import FormBuilderContext from '../../../context/FormBuilderContext' - -type Props = { - type: ItemType - data: IStep | IGroup | IInput - active: boolean - selectable: boolean -} - -export default function SelectNavComponent({ - type, - data, - active, - selectable, -}: Props) { - const { formBuilder, formDispatch, lists, selectStatus, activeListItem } = - useContext(FormBuilderContext) - const { activeItem } = lists - const { form } = formBuilder - const activeGuid = - selectStatus === NavbarSelectStatus.LIST_ITEM - ? activeListItem?.guid ?? '' - : activeItem.data.guid - const connected = - form.dependencies[activeGuid]?.includes(data.guid as string) || - !form.dependencies - return ( - - {active ? ( - - - {/* Index */} - - - {truncateName(data.name.is)} - - - ) : ( - - - {/* {index} */} - - - {truncateName(data.name.is)} - - {selectable && ( - - { - formDispatch({ - type: 'addRemoveConnection', - payload: { - active: activeGuid, - item: data.guid, - }, - }) - }} - /> - - )} - - )} - - ) - - function truncateText(text: string, maxLength: number) { - return text.length > maxLength ? text.slice(0, maxLength) + '...' : text - } - - function truncateName(name: string) { - let maxLength: number - - if (active) { - switch (type) { - case 'Step': - maxLength = 23 - break - case 'Group': - maxLength = 16 - break - case 'Input': - maxLength = 12 - break - default: - maxLength = 26 - } - } else { - switch (type) { - case 'Step': - maxLength = 26 - break - case 'Group': - maxLength = 19 - break - case 'Input': - maxLength = 16 - break - default: - maxLength = 26 - } - } - - return truncateText(name, maxLength) - } -} diff --git a/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts b/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts deleted file mode 100644 index 8db4cbdbcc55..000000000000 --- a/apps/form-builder/components/NavbarSelect/components/selectNavComponent.css.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { style, styleVariants } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -const base = style({ - border: `1px solid ${theme.border.color.blue200}`, - borderRadius: theme.border.radius.standard, - marginBottom: '2px', - height: '46px', - marginLeft: 'auto', - backgroundColor: theme.color.white, - lineHeight: '46px', - ':hover': { - fontWeight: 'bolder', - }, - cursor: 'grab', -}) - -export const step = style({ - border: `1px solid ${theme.border.color.blue200}`, - borderRadius: theme.border.radius.standard, - marginBottom: '2px', - height: '46px', - width: '100%', -}) - -export const navComponent = styleVariants({ - step: [ - base, - { - width: '100%', - }, - ], - group: [ - base, - { - width: '90%', - }, - ], - input: [ - base, - { - width: '80%', - }, - ], -}) - -const baseBackground = style({ - width: '25px', - height: '44px', - borderRadius: `${theme.border.radius.standard} 0 0 ${theme.border.radius.standard}`, - textAlign: 'center', -}) - -export const navBackgroundActive = styleVariants({ - step: [ - baseBackground, - { - backgroundColor: theme.color.blue600, - lineHeight: '45px', - color: theme.color.white, - }, - ], - group: [ - baseBackground, - { - backgroundColor: theme.color.roseTinted400, - }, - ], - input: [ - baseBackground, - { - backgroundColor: theme.color.purple400, - }, - ], -}) - -export const navBackgroundDefault = styleVariants({ - step: [ - baseBackground, - { - lineHeight: '45px', - }, - ], - group: [baseBackground, {}], - input: [baseBackground, {}], -}) - -export const customBackgroundDropdown = style({ - background: theme.color.blue100, -}) diff --git a/apps/form-builder/components/TableRow/TableRow.css.tsx b/apps/form-builder/components/TableRow/TableRow.css.tsx deleted file mode 100644 index 130bb8609ecc..000000000000 --- a/apps/form-builder/components/TableRow/TableRow.css.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import { style } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -export const header = style({ - padding: '10px 0 10px 0', - backgroundColor: theme.color.blue100, - borderBottom: `1px solid ${theme.border.color.blue200}`, -}) diff --git a/apps/form-builder/components/TableRow/TableRow.tsx b/apps/form-builder/components/TableRow/TableRow.tsx deleted file mode 100644 index ae90e8ab818a..000000000000 --- a/apps/form-builder/components/TableRow/TableRow.tsx +++ /dev/null @@ -1,181 +0,0 @@ -import { - GridRow as Row, - GridColumn as Column, - Text, - Divider, - Box, - DropdownMenu, - Button, -} from '@island.is/island-ui/core' -import * as styles from './TableRow.css' -import { useState } from 'react' -import { AnimatePresence, motion } from 'framer-motion' -import { useRouter } from 'next/router' -import TranslationTag from '../TranslationTag/TranslationTag' -import { formatDate } from '../../utils/formatDate' -import { - ApplicationTemplateStatus, - LicenseProviderEnum, -} from '../../types/enums' - -interface Props { - id?: number - name?: string - created?: Date - lastModified?: Date - org?: number - state?: number - options?: string - isHeader: boolean - translated?: boolean -} - -interface ColumnTextProps { - text: string | number -} - -const ColumnText = ({ text }: ColumnTextProps) => ( - - {text} - -) - -const TableRow = ({ - id, - name, - lastModified, - org, - state, - isHeader, - translated, -}: Props) => { - const [isOpen, setIsOpen] = useState(false) - const router = useRouter() - if (isHeader) return header() - return ( - setIsOpen(!isOpen)} - style={{ cursor: '' }} - > - - - - - - - - - - - - - - - - - - - - - - - - - } - items={[ - { - title: 'Breyta', - onClick: () => { - router.push(`/Form/${id}`) - }, - }, - { - title: 'Afrita', - }, - { - title: 'Þýðing enska', - }, - { - title: 'Sækja slóð', - }, - { - title: 'Export', - }, - { - title: 'Sækja json', - }, - ]} - /> - - - - - {isOpen === true ? ( - - - - - - ) : null} - - - - ) -} - -export default TableRow - -const header = () => ( - <> - - - - Númer - - - Heiti - - - Síðast breytt - - - Þýðingar - - - Stofnun - - - Staða - - - Aðgerðir - - - - -) diff --git a/apps/form-builder/components/Tabs/index.tsx b/apps/form-builder/components/Tabs/index.tsx deleted file mode 100644 index 67e6a907b717..000000000000 --- a/apps/form-builder/components/Tabs/index.tsx +++ /dev/null @@ -1,47 +0,0 @@ -import { Box, Inline, FocusableBox } from '@island.is/island-ui/core' -import { Dispatch, SetStateAction } from 'react' -import * as styles from './tabs.css' - -interface Props { - selectedTab: number - setSelectedTab: Dispatch> -} - -export default function Tabs({ selectedTab, setSelectedTab }: Props) { - return ( - - - setSelectedTab(0)} - > - Óútgefið - - setSelectedTab(1)} - > - Útgefið - - setSelectedTab(2)} - > - Útgefið - - - - ) -} diff --git a/apps/form-builder/components/Tabs/tabs.css.ts b/apps/form-builder/components/Tabs/tabs.css.ts deleted file mode 100644 index 8ea98181e27d..000000000000 --- a/apps/form-builder/components/Tabs/tabs.css.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { style } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -export const tab = style({ - padding: '10px', - width: '100%', - cursor: 'pointer', -}) - -export const selected = style({ - color: theme.color.blue400, - borderBottom: `1px solid ${theme.border.color.blue400}`, - fontWeight: 'bolder', -}) diff --git a/apps/form-builder/components/TranslationTag/TranslationTag.tsx b/apps/form-builder/components/TranslationTag/TranslationTag.tsx deleted file mode 100644 index 987ac2dc804d..000000000000 --- a/apps/form-builder/components/TranslationTag/TranslationTag.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { Tag } from '@island.is/island-ui/core' -interface Props { - translated: boolean -} - -export default function TranslationTag({ translated }: Props) { - return translated ? ( - Þýdd - ) : ( - Óþýdd - ) -} diff --git a/apps/form-builder/context/FormBuilderContext.tsx b/apps/form-builder/context/FormBuilderContext.tsx deleted file mode 100644 index b169e1d77cf2..000000000000 --- a/apps/form-builder/context/FormBuilderContext.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import { FocusEvent, SetStateAction, createContext } from 'react' -import { - ActiveItem, - IFormBuilder, - IFormBuilderContext, - IGroup, - IInput, - IListItem, - IStep, - NavbarSelectStatus, -} from '../types/interfaces' - -const FormBuilderContext = createContext({ - formBuilder: {} as IFormBuilder, - formDispatch: function (_value: unknown): void { - throw new Error('Function not implemented.') - }, - lists: { - activeItem: {} as ActiveItem, - steps: [] as IStep[], - groups: [] as IGroup[], - inputs: [] as IInput[], - }, - listsDispatch: function (_value: unknown): void { - throw new Error('Function not implemented.') - }, - formUpdate: async function (): Promise { - throw new Error('Function not implemented.') - }, - inSettings: false, - setInSettings: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - setSelectStatus: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - selectStatus: NavbarSelectStatus.OFF, - setActiveListItem: function (_value: SetStateAction): void { - throw new Error('Function not implemented.') - }, - blur: function ( - _e: FocusEvent, - ): void { - throw new Error('Function not implemented.') - }, - onFocus: function (_e: string): void { - throw new Error('Function not implemented.') - }, -}) - -export default FormBuilderContext diff --git a/apps/form-builder/context/LayoutContext.tsx b/apps/form-builder/context/LayoutContext.tsx deleted file mode 100644 index 82bed301b7aa..000000000000 --- a/apps/form-builder/context/LayoutContext.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { createContext } from 'react' -import { ILayoutContext } from '../types/interfaces' - -const LayoutContext = createContext({ - info: { - organization: '', - applicationName: '', - }, - infoDispatch: function (_value: unknown): void { - throw new Error('Function not implemented.') - }, -}) - -export default LayoutContext diff --git a/apps/form-builder/context/UserContext.tsx b/apps/form-builder/context/UserContext.tsx deleted file mode 100644 index c7ae918f1a3d..000000000000 --- a/apps/form-builder/context/UserContext.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { createContext } from 'react' -import { User } from '../types/interfaces' - -const UserContext = createContext({ - isAuthenticated: false, - setIsAuthenticated: (_: boolean) => undefined, - user: null as unknown as User, - setUser: (_: User) => undefined, - userLoading: false, -}) - -export default UserContext diff --git a/apps/form-builder/environments/environment.ts b/apps/form-builder/environments/environment.ts deleted file mode 100644 index 53f69e76d4c9..000000000000 --- a/apps/form-builder/environments/environment.ts +++ /dev/null @@ -1,9 +0,0 @@ -const devConfig = { - production: false, -} - -const prodConfig = { - production: true, -} - -export default process.env.NODE_ENV === 'production' ? prodConfig : devConfig diff --git a/apps/form-builder/gql/client.ts b/apps/form-builder/gql/client.ts deleted file mode 100644 index 5d90d250951e..000000000000 --- a/apps/form-builder/gql/client.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { - ApolloClient, - ApolloLink, - InMemoryCache, - NormalizedCacheObject, -} from '@apollo/client' -import httpLink from './httpLink' -import retryLink from './retryLink' - -const isBrowser: boolean = process.browser - -let apolloClient: ApolloClient | null = null - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function create(initialState?: any) { - const link = ApolloLink.from([retryLink, httpLink]) // Add retry, error, auth and httpLink here - - return new ApolloClient({ - name: 'form-builder', - version: '0.1', - connectToDevTools: isBrowser, - ssrMode: !isBrowser, - link, - cache: new InMemoryCache().restore(initialState || {}), - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Credentials': 'true', - }, - }) -} - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -export default function initApollo(initialState?: any) { - if (!isBrowser) { - return create(initialState) - } - - if (!apolloClient) { - apolloClient = create(initialState) - } - - return apolloClient -} diff --git a/apps/form-builder/gql/httpLink.ts b/apps/form-builder/gql/httpLink.ts deleted file mode 100644 index 91670e5233e0..000000000000 --- a/apps/form-builder/gql/httpLink.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { createHttpLink } from '@apollo/client' -import fetch from 'isomorphic-unfetch' - -// Polyfill fetch() on the server (used by apollo-client) -if (!process.browser) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(global as any).fetch = fetch -} - -export default createHttpLink({ - uri: 'https://profun.island.is/umsoknarkerfi/api/graphql', // Should be in next.config.js - credentials: 'include', - fetch, -}) diff --git a/apps/form-builder/gql/queries.graphql.ts b/apps/form-builder/gql/queries.graphql.ts deleted file mode 100644 index c1cffc22d993..000000000000 --- a/apps/form-builder/gql/queries.graphql.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { gql } from '@apollo/client' - -export const ADD_STEP = gql` - mutation AddStep($input: AddStepInput!) { - addStep(input: $input) { - id - name { - is - en - } - type - } - } -` diff --git a/apps/form-builder/gql/retryLink.ts b/apps/form-builder/gql/retryLink.ts deleted file mode 100644 index a522b345407f..000000000000 --- a/apps/form-builder/gql/retryLink.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { ServerError } from '@apollo/client' -import { RetryLink as retryLink } from '@apollo/client/link/retry' - -const RetryLink = new retryLink({ - attempts: { - max: 2, - retryIf: (error: ServerError) => error && true, - }, -}) - -export default RetryLink diff --git a/apps/form-builder/hooks/fileUploadReducer.ts b/apps/form-builder/hooks/fileUploadReducer.ts deleted file mode 100644 index 4e8c480714b1..000000000000 --- a/apps/form-builder/hooks/fileUploadReducer.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { UploadFile, UploadFileStatus } from '@island.is/island-ui/core' - -enum ActionTypes { - add = 'add', - remove = 'remove', - update = 'update', -} - -type FileUploadActions = - | { type: 'add'; payload: { newFiles: UploadFile[] } } - | { type: 'remove'; payload: { fileToRemove: UploadFile } } - | { - type: 'update' - payload: { file: UploadFile; status: UploadFileStatus; percent: number } - } - -export default function fileUploadReducer( - state: UploadFile[], - action: FileUploadActions, -) { - switch (action.type) { - case ActionTypes.add: - return state.concat(action.payload.newFiles) - - case ActionTypes.remove: - return state.filter( - (file) => file.name !== action.payload.fileToRemove.name, - ) - - case ActionTypes.update: - return [ - ...state.map((file: UploadFile) => { - if (file.name === action.payload.file.name) { - file.status = action.payload.status - file.percent = action.payload.percent - } - return file - }), - ] - default: - throw new Error() - } -} diff --git a/apps/form-builder/hooks/formReducer.ts b/apps/form-builder/hooks/formReducer.ts deleted file mode 100644 index 5dd8748acd0e..000000000000 --- a/apps/form-builder/hooks/formReducer.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { UniqueIdentifier } from '@dnd-kit/core' -import { - ICertificate, - IFormBuilder, - ILanguage, - ITenging, -} from '../types/interfaces' -import { saveFormSettings } from '../services/apiService' - -type ILang = 'is' | 'en' - -type ChangeNameAction = { - type: 'changeName' - payload: { - lang: ILang - newName: string - } -} - -type ApplicationsDaysToRemoveAction = { - type: 'applicationsDaysToRemove' - payload: { - value: number - } -} - -type InvalidationDateAction = { - type: 'invalidationDate' - payload: { - value: Date - } -} - -type StopProgressOnValidatingStepAction = { - type: 'stopProgressOnValidatingStep' - payload: { - value: boolean - } -} - -type AddRemoveConnectionAction = { - type: 'addRemoveConnection' - payload: { - active: UniqueIdentifier - item: UniqueIdentifier - } -} - -type UpdateDocuments = { - type: 'updateDocuments' - payload: { - documents: ICertificate[] - } -} - -type FormSettingsPayload = - | { property: 'invalidationDate'; value: Date } - | { property: 'dependencies'; value: ITenging } - | { property: 'stopProgressOnValidatingStep'; value: boolean } - | { property: 'applicationsDaysToRemove'; value: number } - | { - property: 'formDocumentTypes' - value: { formId: number; documentTypeId: number }[] - } - | { property: 'adilar'; value: string[] } - | { property: 'completedMessage'; value: ILanguage } - | { property: 'isTranslated'; value: boolean } - -type FormSettingsAction = { - type: 'formSettings' - payload: FormSettingsPayload -} - -export type FormAction = - | ChangeNameAction - | ApplicationsDaysToRemoveAction - | InvalidationDateAction - | StopProgressOnValidatingStepAction - | AddRemoveConnectionAction - | FormSettingsAction - | UpdateDocuments - -export function formReducer(formBuilder: IFormBuilder, action: FormAction) { - switch (action.type) { - case 'changeName': { - const { lang, newName } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - name: { - ...formBuilder.form.name, - [lang]: newName, - }, - }, - } - } - case 'applicationsDaysToRemove': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - applicationsDaysToRemove: value, - }, - } - } - case 'invalidationDate': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - invalidationDate: value, - }, - } - } - case 'stopProgressOnValidatingStep': { - const { value } = action.payload - return { - ...formBuilder, - form: { - ...formBuilder.form, - stopProgressOnValidatingStep: value, - }, - } - } - case 'addRemoveConnection': { - const { active, item } = action.payload - const itemAsString = String(item) - const dependencies = { ...formBuilder.form.dependencies } - - if (active in dependencies) { - if (!dependencies[active].includes(itemAsString)) { - dependencies[active] = [...dependencies[active], itemAsString] - } else { - dependencies[active] = dependencies[active].filter((t) => t !== item) - if (dependencies[active].length === 0) { - delete dependencies[active] - } - } - } else { - dependencies[active] = [itemAsString] - } - saveFormSettings(formBuilder.form.id, { - id: formBuilder.form.id, - dependencies: dependencies, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - dependencies, - }, - } - } - - case 'formSettings': { - const { property, value } = action.payload - const { id } = formBuilder.form - saveFormSettings(id, { - id: id, - [property]: value, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - [property]: value, - }, - } - } - - case 'updateDocuments': { - const { documents } = action.payload - const saveDocuments = documents.map((d) => { - return { - formId: formBuilder.form.id, - documentTypeId: d.id, - } - }) - saveFormSettings(formBuilder.form.id, { - id: formBuilder.form.id, - formDocumentTypes: saveDocuments, - }) - return { - ...formBuilder, - form: { - ...formBuilder.form, - documentTypes: documents, - }, - } - } - - default: - return formBuilder - } -} diff --git a/apps/form-builder/hooks/headerInfoReducer.ts b/apps/form-builder/hooks/headerInfoReducer.ts deleted file mode 100644 index a92d3484df39..000000000000 --- a/apps/form-builder/hooks/headerInfoReducer.ts +++ /dev/null @@ -1,29 +0,0 @@ -export type FormHeaderAction = - | { type: 'changeOrganization'; payload: { value: string } } - | { type: 'changeApplicationName'; payload: { value: string } } - -export function headerInfoReducer( - info: { - organization: string - applicationName: string - }, - action: FormHeaderAction, -) { - switch (action.type) { - case 'changeOrganization': { - return { - ...info, - organization: action.payload?.value ? action.payload.value : '', - } - } - case 'changeApplicationName': { - return { - ...info, - applicationName: action.payload?.value ? action.payload.value : '', - } - } - default: { - return info - } - } -} diff --git a/apps/form-builder/hooks/listsReducer.ts b/apps/form-builder/hooks/listsReducer.ts deleted file mode 100644 index 7a59f3f8671c..000000000000 --- a/apps/form-builder/hooks/listsReducer.ts +++ /dev/null @@ -1,763 +0,0 @@ -import { arrayMove } from '@dnd-kit/sortable' -import { - ItemType, - IGroup, - IInput, - IInputSettings, - IListItem, - ILists, - IStep, - ActiveItem, - ILanguage, -} from '../types/interfaces' -import { UniqueIdentifier } from '@dnd-kit/core' -import { uuid } from 'uuidv4' -import { updateItem } from '../services/apiService' - -export type ILang = 'is' | 'en' - -type DndAction = - | { - type: 'stepOverStep' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - | { - type: 'groupOverStep' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - | { - type: 'groupOverGroup' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - | { - type: 'inputOverGroup' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - | { - type: 'inputOverInput' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - | { - type: 'listItemOverListItem' - payload: { activeId: UniqueIdentifier; overId: UniqueIdentifier } - } - -type AddRemoveAction = - | { type: 'addStep'; payload: { data: IStep } } - | { type: 'addGroup'; payload: { data: IGroup } } - | { type: 'addInput'; payload: { data: IInput } } - | { type: 'removeStep'; payload: { guid: UniqueIdentifier } } - | { type: 'removeGroup'; payload: { guid: UniqueIdentifier } } - | { type: 'removeInput'; payload: { guid: UniqueIdentifier } } - | { type: 'addListItem' } - | { type: 'removeListItem'; payload: { guid: UniqueIdentifier } } - | { - type: 'addInputRelevantParty' - payload: { data: IInput; type: string; name: ILanguage } - } - -type ChangeAction = - | { - type: 'changeName' - payload: { - lang: ILang - newValue: string - } - } - | { - type: 'changeInputType' - payload: { - newValue: string | number - inputSettings: IInputSettings - } - } - | { - type: 'setIsRequired' - payload: { guid: UniqueIdentifier; isRequired: boolean } - } - | { type: 'setDescription'; payload: { lang: ILang; newValue: string } } - | { - type: 'changeInputName' - payload: { guid: UniqueIdentifier; lang: ILang; newValue: string } - } - -type ControlAction = - | { - type: 'setActiveItem' - payload: { type: ItemType; data: IStep | IGroup | IInput } - } - | { type: 'setActiveListItem'; payload: { listItem: IListItem | null } } - -type InputSettingsAction = - | { type: 'timeInterval'; payload: { data: string } } - | { type: 'setInputSettings'; payload: { inputSettings: IInputSettings } } - | { - type: 'setMessageWithLinkSettings' - payload: { - property: 'hnapptexti' | 'url' | 'erHlekkur' - value?: string - checked?: boolean - lang?: ILang - } - } - | { - type: 'setFileUploadSettings' - payload: { - property: 'erFjolval' | 'fjoldi' | 'hamarksstaerd' | 'tegundir' - checked?: boolean - value?: number | string - } - } - | { - type: 'setNumberInputSettings' - payload: { - property: 'lagmarkslengd' | 'hamarkslengd' | 'laggildi' | 'hagildi' - value: number - } - } - | { - type: 'setListItemSelected' - payload: { guid: UniqueIdentifier; checked: boolean } - } - | { - type: 'setListItem' - payload: { - property: 'label' | 'description' - lang: ILang - value: string - listItemGuid: UniqueIdentifier - } - } - | { type: 'setMultiSet'; payload: { checked: boolean } } - | { - type: 'setRelevantPartiesSettings' - payload: { property: 'type' | 'name'; lang?: ILang; type: string } - } - -export type Action = - | DndAction - | AddRemoveAction - | ChangeAction - | ControlAction - | InputSettingsAction - -export const listsReducer = (lists: ILists, action: Action): ILists => { - const types = { - Step: 'steps', - Group: 'groups', - Input: 'inputs', - } - const { activeItem, steps, groups, inputs } = lists - - const addNewInput = (newInput: IInput, toSave: boolean) => { - toSave && updateItem('Input', newInput) - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => - i.guid === activeItem.data.guid ? newInput : i, - ), - } - } - - switch (action.type) { - // DnD control - case 'stepOverStep': { - const activeIndex = steps.findIndex( - (s) => s.guid === action.payload.activeId, - ) - const overIndex = steps.findIndex((s) => s.guid === action.payload.overId) - const updatedSteps = arrayMove(steps, activeIndex, overIndex) - return { - ...lists, - steps: updatedSteps, - } - } - case 'groupOverStep': { - const activeIndex = groups.findIndex( - (g) => g.guid === action.payload.activeId, - ) - const overIndex = steps.findIndex((s) => s.guid === action.payload.overId) - - const updatedGroup = groups - updatedGroup[activeIndex].stepGuid = action.payload.overId - updatedGroup[activeIndex].stepId = steps[overIndex].id - - return { - ...lists, - groups: arrayMove(updatedGroup, activeIndex, activeIndex), - } - } - case 'groupOverGroup': { - const activeIndex = groups.findIndex( - (g) => g.guid === action.payload.activeId, - ) - const overIndex = groups.findIndex( - (g) => g.guid === action.payload.overId, - ) - - const updatedGroup = groups - if ( - updatedGroup[activeIndex].stepGuid !== updatedGroup[overIndex].stepGuid - ) { - updatedGroup[activeIndex].stepGuid = updatedGroup[overIndex].stepGuid - updatedGroup[activeIndex].stepId = updatedGroup[overIndex].stepId - return { - ...lists, - groups: arrayMove(updatedGroup, activeIndex, overIndex - 1), - } - } - return { - ...lists, - groups: arrayMove(updatedGroup, activeIndex, overIndex), - } - } - case 'inputOverGroup': { - const activeIndex = inputs.findIndex( - (i) => i.guid === action.payload.activeId, - ) - const overIndex = groups.findIndex( - (g) => g.guid === action.payload.overId, - ) - - const updatedInput = inputs - updatedInput[activeIndex].groupGuid = action.payload.overId - updatedInput[activeIndex].groupId = groups[overIndex].id - return { - ...lists, - inputs: arrayMove(updatedInput, activeIndex, activeIndex), - } - } - case 'inputOverInput': { - const activeIndex = inputs.findIndex( - (i) => i.guid === action.payload.activeId, - ) - const overIndex = inputs.findIndex( - (i) => i.guid === action.payload.overId, - ) - - const updatedInput = inputs - if ( - updatedInput[activeIndex].groupGuid !== - updatedInput[overIndex].groupGuid - ) { - updatedInput[activeIndex].groupGuid = updatedInput[overIndex].groupGuid - updatedInput[activeIndex].groupId = updatedInput[overIndex].groupId - return { - ...lists, - inputs: arrayMove(updatedInput, activeIndex, overIndex - 1), - } - } - return { - ...lists, - inputs: arrayMove(updatedInput, activeIndex, overIndex), - } - } - case 'listItemOverListItem': { - const input = activeItem.data as IInput - const { listi: list } = input.inputSettings - if (list === undefined) { - return lists - } - const activeIndex = list.findIndex( - (l) => l.guid === action.payload.activeId, - ) - const overIndex = list.findIndex((l) => l.guid === action.payload.overId) - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - listi: arrayMove(list, activeIndex, overIndex).map((l, i) => ({ - ...l, - displayOrder: i, - })), - }, - } - return addNewInput(newInput, false) - } - - // DnD control - end - // Add - case 'addStep': { - return { - ...lists, - activeItem: { - type: 'Step', - data: action.payload.data, - }, - steps: [...steps, action.payload.data], - } - } - case 'addGroup': { - return { - ...lists, - activeItem: { - type: 'Group', - data: action.payload.data, - }, - groups: [...groups, action.payload.data], - } - } - case 'addInput': { - return { - ...lists, - activeItem: { - type: 'Input', - data: action.payload.data, - }, - inputs: [...inputs, action.payload.data], - } - } - case 'addInputRelevantParty': { - const newInput = { - ...action.payload.data, - name: action.payload.name, - type: 'Aðili', - inputSettings: { - $type: 'adili', - type: action.payload.type, - }, - } - updateItem('Input', newInput) - return { - ...lists, - inputs: [...inputs, newInput], - } - } - //Add - end - // Remove - case 'removeStep': { - return { - ...lists, - steps: steps.filter((s) => s.guid !== action.payload.guid), - } - } - case 'removeGroup': { - return { - ...lists, - groups: groups.filter((g) => g.guid !== action.payload.guid), - } - } - case 'removeInput': { - return { - ...lists, - inputs: inputs.filter((i) => i.guid !== action.payload.guid), - } - } - // Remove - end - - // ChangeHandlers - case 'changeName': { - const { lang, newValue } = action.payload - const newActive = { - ...activeItem, - data: { - ...activeItem.data, - name: { - ...activeItem.data.name, - [lang]: newValue, - }, - }, - } - if (newActive.type === 'Step') { - const newSteps: IStep[] = steps.map((s) => - s.guid === newActive.data.guid ? (newActive.data as IStep) : s, - ) - return { - ...lists, - activeItem: newActive, - steps: newSteps, - } - } else if (newActive.type === 'Group') { - const newGroups: IGroup[] = groups.map((g) => - g.guid === newActive.data.guid ? (newActive.data as IGroup) : g, - ) - return { - ...lists, - activeItem: newActive, - groups: newGroups, - } - } else { - const newInputs: IInput[] = inputs.map((i) => - i.guid === newActive.data.guid ? (newActive.data as IInput) : i, - ) - return { - ...lists, - activeItem: newActive, - inputs: newInputs, - } - } - } - case 'changeInputType': { - const activeIndex = ( - lists[types[activeItem.type]] as Array<{ guid: UniqueIdentifier }> - ).findIndex( - (e: { guid: UniqueIdentifier }) => e.guid === activeItem.data.guid, - ) - const newInputs = [...inputs] - - newInputs[activeIndex] = { - ...inputs[activeIndex], - type: action.payload.newValue as string, - inputSettings: action.payload.inputSettings, - } - - const newActive: ActiveItem = { - type: 'Input', - data: newInputs[activeIndex], - } - - updateItem(newActive.type, newActive.data) - - return { - ...lists, - activeItem: newActive, - inputs: newInputs, - } - } - case 'setDescription': { - const input = activeItem.data as IInput - const newInput = { - ...input, - description: { - ...input.description, - [action.payload.lang]: action.payload.newValue, - }, - } - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => { - if (i.guid === input.guid) { - return newInput - } - return i - }), - } - } - case 'changeInputName': { - const { guid, lang, newValue } = action.payload - const currentInput = activeItem.data as IInput - const newInput = { - ...currentInput, - name: { - ...currentInput.name, - [lang]: newValue, - }, - } - return { - ...lists, - inputs: inputs.map((i) => { - if (i.guid === guid) { - return newInput - } - return i - }), - } - } - - case 'setActiveItem': { - return { - ...lists, - activeItem: { - type: action.payload.type, - data: action.payload.data, - }, - } - } - case 'setIsRequired': { - return { - ...lists, - activeItem: { - ...activeItem, - data: { - ...activeItem.data, - isRequired: action.payload.isRequired, - }, - }, - inputs: inputs.map((i) => { - if (i.guid === action.payload.guid) { - const newInput = { - ...i, - isRequired: action.payload.isRequired, - } - updateItem('Input', newInput) - return newInput - } - return i - }), - } - } - case 'timeInterval': { - if (activeItem.type === 'Input') { - const inputItem = activeItem.data as IInput - return { - ...lists, - activeItem: { - ...activeItem, - data: { - ...activeItem.data, - inputSettings: { - ...inputItem.inputSettings, - interval: action.payload.data, - }, - }, - }, - inputs: inputs.map((i) => { - if (i.guid === activeItem.data.guid) { - const newInput: IInput = { - ...i, - inputSettings: { - ...i.inputSettings, - interval: action.payload.data, - }, - } - updateItem('Input', newInput) - return newInput - } - return i - }), - } - } - break - } - case 'setMessageWithLinkSettings': { - const input: IInput = activeItem.data as IInput - - const { payload } = action - if ('property' in payload) { - const { property, lang, value, checked } = payload - - const updateMessageLink = ( - property: string, - value: string | undefined, - ) => { - if (lang === undefined || value === undefined) return - return { - ...(input.inputSettings[property] as IInputSettings), - [lang]: value, - } - } - - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - [property]: property === 'erHlekkur' ? checked : value, - ...(property === 'hnapptexti' - ? updateMessageLink(property, value) - : {}), - }, - } - if (property === 'erHlekkur') { - updateItem('Input', newInput) - } - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => - i.guid === activeItem.data.guid ? newInput : i, - ), - } - } - break - } - - case 'setFileUploadSettings': { - const input = activeItem.data as IInput - const { payload } = action - const { property, checked, value } = payload - - const updateFileTypesArray = () => { - const currentTegundir = input.inputSettings.tegundir || [] - if (checked) { - return [...currentTegundir, value as string] - } else { - return currentTegundir.filter((t) => t !== value) - } - } - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - [property]: property === 'tegundir' ? updateFileTypesArray() : value, - }, - } - updateItem('Input', newInput) - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => - i.guid === activeItem.data.guid ? newInput : i, - ), - } - } - - case 'setNumberInputSettings': { - const input = activeItem.data as IInput - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - [action.payload.property]: action.payload.value, - }, - } - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => - i.guid === activeItem.data.guid ? newInput : i, - ), - } - } - - case 'addListItem': { - const input = activeItem.data as IInput - const list = input.inputSettings.listi || [] - const newListItem = { - guid: uuid(), - label: { - is: '', - en: '', - }, - description: { - is: '', - en: '', - }, - isSelected: false, - displayOrder: list.length, - } - - const newInput: IInput = { - ...input, - inputSettings: { - ...input.inputSettings, - listi: [...list, newListItem], - }, - } - return addNewInput(newInput, true) - } - - case 'setListItemSelected': { - const input = activeItem.data as IInput - const list = input.inputSettings.listi || [] - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - listi: list.map((l) => - l.guid === action.payload.guid - ? { ...l, isSelected: !l.isSelected } - : { ...l, isSelected: false }, - ), - }, - } - return addNewInput(newInput, true) - } - - case 'removeListItem': { - const input = activeItem.data as IInput - const list = input.inputSettings.listi || [] - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - listi: list.filter((l) => l.guid !== action.payload.guid), - }, - } - return addNewInput(newInput, true) - } - - case 'setListItem': { - const input = activeItem.data as IInput - const { payload } = action - const { property, lang, value, listItemGuid } = payload - const list = input.inputSettings.listi || [] - - const newInput = { - ...input, - inputSettings: { - ...input.inputSettings, - listi: list.map((l) => { - if (l.guid === listItemGuid) { - return { - ...l, - [property]: { - ...l[property], - [lang]: value, - }, - } - } - return l - }), - }, - } - return addNewInput(newInput, false) - } - - case 'setActiveListItem': { - return { - ...lists, - activeListItem: action.payload.listItem, - } - } - - case 'setMultiSet': { - const group = activeItem.data as IGroup - const newGroup = { - ...group, - multiSet: action.payload.checked ? 10 : 0, - } - updateItem('Group', newGroup) - return { - ...lists, - activeItem: { - ...activeItem, - data: newGroup, - }, - groups: lists.groups.map((g) => - g.guid === activeItem.data.guid ? newGroup : g, - ), - } - } - - case 'setInputSettings': { - const { inputSettings } = action.payload - const input = activeItem.data as IInput - const newInput = { - ...input, - inputSettings: inputSettings, - } - updateItem('Input', newInput) - return { - ...lists, - activeItem: { - ...activeItem, - data: newInput, - }, - inputs: inputs.map((i) => - i.guid === activeItem.data.guid ? newInput : i, - ), - } - } - - default: - return lists - } - return lists -} diff --git a/apps/form-builder/hooks/useUser.ts b/apps/form-builder/hooks/useUser.ts deleted file mode 100644 index 4d0458f4cd06..000000000000 --- a/apps/form-builder/hooks/useUser.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { useSession } from 'next-auth/client' -import { useEffect, useState } from 'react' -import { User } from '../types/interfaces' - -export default function useUser() { - const [user, setUser] = useState() - const [session, loading] = useSession() - - const timeNow = Math.floor(Date.now() / 1000) - const expiryStr = session?.expires - ? new Date(session.expires.replace(/['"]+/g, '')).getTime() - : undefined - const expiry = Math.floor((expiryStr ?? 0) / 1000) - - const hasNotExpired = timeNow < expiry - - const [isAuthenticated, setIsAuthenticated] = useState( - Boolean(hasNotExpired), - ) - - useEffect(() => { - if (!hasNotExpired) { - setUser(undefined) - setIsAuthenticated(false) - sessionStorage.clear() - } else { - if (!user && session?.user) { - const { name = '', email, image } = session.user || {} - setUser({ name: name || '', email: email || '', image: image || '' }) - setIsAuthenticated(true) - } - } - }, [setUser, session, user]) - - return { - isAuthenticated, - setIsAuthenticated, - user, - setUser, - userLoading: loading, - } -} diff --git a/apps/form-builder/index.d.ts b/apps/form-builder/index.d.ts deleted file mode 100644 index a9ab53489c7f..000000000000 --- a/apps/form-builder/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -declare module '*.svg' { - const content: any - export const ReactComponent: any - export default content -} diff --git a/apps/form-builder/infra/form-builder.ts b/apps/form-builder/infra/form-builder.ts deleted file mode 100644 index 10e118a9f3f9..000000000000 --- a/apps/form-builder/infra/form-builder.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { ref, service, ServiceBuilder } from '../../../infra/src/dsl/dsl' - -export const serviceSetup = (services: { - api: ServiceBuilder<'api'> -}): ServiceBuilder<'form-builder'> => { - const formSystemsService = service('form-builder') - formSystemsService - .image('form-builder') - .namespace('form-builder') - .liveness('/liveness') - .readiness('/liveness') - .replicaCount({ - default: 2, - max: 30, - min: 2, - }) - .resources({ - limits: { cpu: '400m', memory: '512Mi' }, - requests: { cpu: '200m', memory: '256Mi' }, - }) - .env({ - BASEPATH: '/form-builder', - ENVIRONMENT: ref((h) => h.env.type), - API_URL: ref((h) => `http://${h.svc(services.api)}`), //Most likely this is incorrect - IDENTITY_SERVER_ISSUER_DOMAIN: { - dev: 'identity-server.dev01.devland.is', - staging: 'identity-server.staging01.devland.is', - prod: 'innskra.island.is', - }, - NEXTAUTH_URL: { //TODO add paths - dev: '', - staging: '', - prod: '', - }, - BACKEND_DL_URL: { //TODO add paths - dev: '', - staging: '', - prod: '', - }, - }) - .secrets({ - - }) - .ingress({ - primary: { - host: { - dev: ['beta'], - staging: ['beta'], - prod: ['', 'www.island.is'], - }, - extraAnnotations: { - dev: { - 'nginx.ingress.kubernetes.io/proxy-buffering': 'on', - 'nginx.ingress.kubernetes.io/proxy-buffer-size': '8k', - }, - staging: { - 'nginx.ingress.kubernetes.io/enable-global-auth': 'false', - 'nginx.ingress.kubernetes.io/proxy-buffering': 'on', - 'nginx.ingress.kubernetes.io/proxy-buffer-size': '8k', - }, - prod: { - 'nginx.ingress.kubernetes.io/proxy-buffering': 'on', - 'nginx.ingress.kubernetes.io/proxy-buffer-size': '8k', - }, - }, - paths: ['/form-builder'], - }, - }) - return formSystemsService -} diff --git a/apps/form-builder/jest.config.ts b/apps/form-builder/jest.config.ts deleted file mode 100644 index f205af440342..000000000000 --- a/apps/form-builder/jest.config.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'form-builder', - preset: '../../jest.preset.js', - transform: { - '^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nx/react/plugins/jest', - '^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nx/next/babel'] }], - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'], - coverageDirectory: '../../coverage/apps/form-builder', -} diff --git a/apps/form-builder/lib/environment.ts b/apps/form-builder/lib/environment.ts deleted file mode 100644 index 0a5afa989e20..000000000000 --- a/apps/form-builder/lib/environment.ts +++ /dev/null @@ -1,31 +0,0 @@ -const isProd = process.env.NODE_ENV === 'production' - -const devConfig = { - production: false, - NEXTAUTH_URL: 'http://localhost:4200/api/auth/callback', - identityServerId: 'identity-server', - identityServerClientId: '@island.is/leyfisveitingagatt', - identityServerDomain: '', - identityServerLogoutUrl: '', - identityServerSecret: '', - identityServerScope: 'openid profile', - identityServerName: 'Leyfisveitingagatt', - idsTokenCookieName: 'next-auth.csrf-token', - backendDownloadUrl: 'https://profun.island.is/umsoknarkerfi/api', -} - -const prodConfig = { - production: true, - NEXTAUTH_URL: 'http://localhost:4200/api/auth/callback', - identityServerId: 'identity-server', - identityServerClientId: '@island.is/leyfisveitingagatt', - identityServerDomain: '', - identityServerLogoutUrl: '', - identityServerSecret: '', - identityServerScope: 'openid profile', - identityServerName: 'Leyfisveitingagatt', - idsTokenCookieName: 'next-auth.csrf-token', - backendDownloadUrl: 'https://profun.island.is/umsoknarkerfi/api', -} - -export default isProd ? prodConfig : devConfig diff --git a/apps/form-builder/lib/fileTypes.json b/apps/form-builder/lib/fileTypes.json deleted file mode 100644 index a066e60198cf..000000000000 --- a/apps/form-builder/lib/fileTypes.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - ".pdf": "application/pdf", - ".doc": "application/msword", - ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", - ".txt": "text/plain", - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".gif": "image/gif", - ".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - ".xls": "application/vnd.ms-excel", - ".csv": "text/csv", - ".zip": "application/zip", - "*": "application/octet-stream" -} diff --git a/apps/form-builder/next-env.d.ts b/apps/form-builder/next-env.d.ts deleted file mode 100644 index 4f11a03dc6cc..000000000000 --- a/apps/form-builder/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/form-builder/next.config.js b/apps/form-builder/next.config.js deleted file mode 100644 index a3c0782fba37..000000000000 --- a/apps/form-builder/next.config.js +++ /dev/null @@ -1,39 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -const withNx = require('@nx/next/plugins/with-nx') -const { createVanillaExtractPlugin } = require('@vanilla-extract/next-plugin') -const withVanillaExtract = createVanillaExtractPlugin() - -/** - * @type {import('@nrwl/next/plugins/with-nx').WithNxOptions} - **/ - -const nextConfig = { - nx: { - svgr: false, - }, -} - -module.exports = withNx(withVanillaExtract(nextConfig)) - -//@ts-check - -// eslint-disable-next-line @typescript-eslint/no-var-requires -// const { composePlugins, withNx } = require('@nx/next') - -// /** -// * @type {import('@nx/next/plugins/with-nx').WithNxOptions} -// **/ -// const nextConfig = { -// nx: { -// // Set this to true if you would like to use SVGR -// // See: https://github.com/gregberge/svgr -// svgr: false, -// }, -// } - -// const plugins = [ -// // Add more Next.js plugins to this list if needed. -// withNx, -// ] - -// module.exports = composePlugins(...plugins)(nextConfig) diff --git a/apps/form-builder/pages/Form/[id]/index.tsx b/apps/form-builder/pages/Form/[id]/index.tsx deleted file mode 100644 index 6bdfb0dc1621..000000000000 --- a/apps/form-builder/pages/Form/[id]/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { GetServerSidePropsContext } from 'next' -import Form from '../../../screens/Form' -import { getForm } from '../../../services/apiService' -import { IFormBuilder } from '../../../types/interfaces' - -interface Props { - form: IFormBuilder -} - -const Index = ({ form }: Props) => { - return -} - -export default Index - -export async function getServerSideProps(context: GetServerSidePropsContext) { - const formId = context.params?.id as unknown - if (!formId) { - return { - notFound: true, - } - } - const form: IFormBuilder = await getForm(formId) - return { - props: { - form: form, - }, - } -} diff --git a/apps/form-builder/pages/Form/index.tsx b/apps/form-builder/pages/Form/index.tsx deleted file mode 100644 index 2362d796dbbf..000000000000 --- a/apps/form-builder/pages/Form/index.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useRouter } from 'next/router' -import { useEffect } from 'react' -import Form from '../../screens/Form' -import { getNewForm } from '../../services/apiService' -import { IFormBuilder } from '../../types/interfaces' - -interface Props { - form: IFormBuilder -} - -const Index = ({ form }: Props) => { - const router = useRouter() - - useEffect(() => { - router.replace(`/Form/${form.form.id}`) - }, [form.form.id, router]) - - return ( -
- -
- ) -} - -export default Index - -export async function getServerSideProps() { - const form: IFormBuilder = await getNewForm(1) - return { - props: { - form: form, - }, - } -} diff --git a/apps/form-builder/pages/Forms/index.tsx b/apps/form-builder/pages/Forms/index.tsx deleted file mode 100644 index 278098268e6a..000000000000 --- a/apps/form-builder/pages/Forms/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Forms } from '../../screens' -import { getAllFormsFromOrganisation } from '../../services/apiService' -import { IFormBuilder } from '../../types/interfaces' - -interface Props { - formBuilder: IFormBuilder -} - -const Index = ({ formBuilder }: Props) => { - return -} - -export default Index - -export async function getServerSideProps() { - const allForms: IFormBuilder = await getAllFormsFromOrganisation(1) - return { - props: { - formBuilder: allForms, - }, - } -} diff --git a/apps/form-builder/pages/_app.tsx b/apps/form-builder/pages/_app.tsx deleted file mode 100644 index 593db52ef5e5..000000000000 --- a/apps/form-builder/pages/_app.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { AppContext, AppProps } from 'next/app' -import { IntlProvider } from 'react-intl' -import Layout from '../components/Layout/Layout' -import AuthProvider from '../components/AuthProvider/AuthProvider' -import { Provider, getSession } from 'next-auth/client' - -const FormBuilderProviderApp: React.FC = ({ - Component, - pageProps, -}) => { - return ( - undefined} - > - - - -
- -
-
-
-
-
- ) -} - -export async function getInitialProps(appContext: AppContext) { - const { ctx } = appContext - const session = await getSession(ctx) - return { - pageProps: { - session: session, - }, - } -} - -export default FormBuilderProviderApp diff --git a/apps/form-builder/pages/api/auth/[...nextauth].ts b/apps/form-builder/pages/api/auth/[...nextauth].ts deleted file mode 100644 index fb644da3b3e0..000000000000 --- a/apps/form-builder/pages/api/auth/[...nextauth].ts +++ /dev/null @@ -1,70 +0,0 @@ -import NextAuth, { CallbacksOptions } from 'next-auth' -import { NextApiRequest, NextApiResponse } from 'next' -import Providers from 'next-auth/providers' -import { - AuthUser, - signIn as handleSignIn, - session as handleSession, - jwt as handleJwt, - AuthSession, -} from '@island.is/next-ids-auth' -import { JWT } from 'next-auth/jwt' -import env from '../../../lib/environment' - -const providers = [ - Providers.IdentityServer4({ - id: env.identityServerId, - name: env.identityServerName, - scope: env.identityServerScope, - clientSecret: env.identityServerClientId, - clientId: env.identityServerClientId, - domain: env.identityServerDomain, - protection: 'pkce', - }), -] - -const callbacks: CallbacksOptions = { - signIn: signIn, - jwt: jwt, - session: session, -} - -async function signIn( - user: AuthUser, - account: Record, - profile: Record, -): Promise { - return handleSignIn(user, account, profile, env.identityServerClientId) -} - -async function jwt(token: JWT, user: AuthUser) { - if (user) { - token = { - nationalId: user.nationalId, - name: user.name, - accessToken: user.accessToken, - refreshToken: user.refreshToken, - idToken: user.idToken, - isRefreshTokenExpired: false, - } - } - return await handleJwt( - token, - env.identityServerClientId, - env.identityServerSecret, - env.NEXTAUTH_URL, - env.identityServerDomain, - ) -} - -async function session(session: AuthSession, user: AuthUser) { - return handleSession(session, user) -} - -const options = { providers, callbacks } - -const handleAuth = (req: NextApiRequest, res: NextApiResponse) => { - NextAuth(req as any, res, options) -} - -export default handleAuth diff --git a/apps/form-builder/pages/index.tsx b/apps/form-builder/pages/index.tsx deleted file mode 100644 index b6b6a47ff4b8..000000000000 --- a/apps/form-builder/pages/index.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import { useEffect } from 'react' -import router from 'next/router' - -const Index = () => { - useEffect(() => { - router.push('/Forms') - }, []) - - return <> -} - -export default Index diff --git a/apps/form-builder/project.json b/apps/form-builder/project.json deleted file mode 100644 index 73c5c0878a43..000000000000 --- a/apps/form-builder/project.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "name": "form-builder", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "apps/form-builder", - "projectType": "application", - "targets": { - "build": { - "executor": "@nx/next:build", - "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", - "options": { - "outputPath": "dist/apps/form-builder" - }, - "configurations": { - "development": { - "outputPath": "apps/form-builder" - }, - "production": {} - } - }, - "build-custom-server": { - "executor": "@nx/webpack:webpack", - "defaultConfiguration": "production", - "options": { - "outputPath": "dist/apps/form-builder", - "main": "apps/form-builder/server.ts", - "tsConfig": "apps/form-builder/tsconfig.server.json", - "maxWorkers": 2, - "assets": [], - "compiler": "tsc", - "target": "node" - }, - "configurations": { - "development": {}, - "production": { - "optimization": true, - "extractLicenses": true, - "inspect": false - } - } - }, - "serve": { - "executor": "@nx/next:server", - "defaultConfiguration": "development", - "options": { - "buildTarget": "form-builder:build", - "dev": true, - "customServerTarget": "form-builder:serve-custom-server" - }, - "configurations": { - "development": { - "buildTarget": "form-builder:build:development", - "dev": true, - "customServerTarget": "form-builder:serve-custom-server:development" - }, - "production": { - "buildTarget": "form-builder:build:production", - "dev": false, - "customServerTarget": "form-builder:serve-custom-server:production" - } - } - }, - "serve-custom-server": { - "executor": "@nx/js:node", - "defaultConfiguration": "development", - "options": { - "buildTarget": "form-builder:build-custom-server" - }, - "configurations": { - "development": { - "buildTarget": "form-builder:build-custom-server:development" - }, - "production": { - "buildTarget": "form-builder:build-custom-server:production" - } - } - }, - "export": { - "executor": "@nx/next:export", - "options": { - "buildTarget": "form-builder:build:production" - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "apps/form-builder/jest.config.ts", - "passWithNoTests": true - }, - "configurations": { - "ci": { - "ci": true, - "codeCoverage": true - } - } - }, - "lint": { - "executor": "@nx/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["apps/form-builder/**/*.{ts,tsx,js,jsx}"] - } - }, - "docker-next": {} - }, - "tags": [] -} diff --git a/apps/form-builder/proxy.config.json b/apps/form-builder/proxy.config.json deleted file mode 100644 index 1ec1f59e0a1a..000000000000 --- a/apps/form-builder/proxy.config.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "/api/graphql": { - "target": "http://localhost:4444", - "secure": false - } -} diff --git a/apps/form-builder/public/.gitkeep b/apps/form-builder/public/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/form-builder/public/favicon.ico b/apps/form-builder/public/favicon.ico deleted file mode 100644 index 317ebcb2336e0833a22dddf0ab287849f26fda57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmeI332;U^%p|z7g|#(P)qFEA@4f!_@qOK2 z_lJl}!lhL!VT_U|uN7%8B2iKH??xhDa;*`g{yjTFWHvXn;2s{4R7kH|pKGdy(7z!K zgftM+Ku7~24TLlh(!g)gz|foI94G^t2^IO$uvX$3(OR0<_5L2sB)lMAMy|+`xodJ{ z_Uh_1m)~h?a;2W{dmhM;u!YGo=)OdmId_B<%^V^{ovI@y`7^g1_V9G}*f# zNzAtvou}I!W1#{M^@ROc(BZ! z+F!!_aR&Px3_reO(EW+TwlW~tv*2zr?iP7(d~a~yA|@*a89IUke+c472NXM0wiX{- zl`UrZC^1XYyf%1u)-Y)jj9;MZ!SLfd2Hl?o|80Su%Z?To_=^g_Jt0oa#CT*tjx>BI z16wec&AOWNK<#i0Qd=1O$fymLRoUR*%;h@*@v7}wApDl^w*h}!sYq%kw+DKDY)@&A z@9$ULEB3qkR#85`lb8#WZw=@})#kQig9oqy^I$dj&k4jU&^2(M3q{n1AKeGUKPFbr z1^<)aH;VsG@J|B&l>UtU#Ejv3GIqERzYgL@UOAWtW<{p#zy`WyJgpCy8$c_e%wYJL zyGHRRx38)HyjU3y{-4z6)pzb>&Q1pR)B&u01F-|&Gx4EZWK$nkUkOI|(D4UHOXg_- zw{OBf!oWQUn)Pe(=f=nt=zkmdjpO^o8ZZ9o_|4tW1ni+Un9iCW47*-ut$KQOww!;u z`0q)$s6IZO!~9$e_P9X!hqLxu`fpcL|2f^I5d4*a@Dq28;@2271v_N+5HqYZ>x;&O z05*7JT)mUe&%S0@UD)@&8SmQrMtsDfZT;fkdA!r(S=}Oz>iP)w=W508=Rc#nNn7ym z1;42c|8($ALY8#a({%1#IXbWn9-Y|0eDY$_L&j{63?{?AH{);EzcqfydD$@-B`Y3<%IIj7S7rK_N}je^=dEk%JQ4c z!tBdTPE3Tse;oYF>cnrapWq*o)m47X1`~6@(!Y29#>-#8zm&LXrXa(3=7Z)ElaQqj z-#0JJy3Fi(C#Rx(`=VXtJ63E2_bZGCz+QRa{W0e2(m3sI?LOcUBx)~^YCqZ{XEPX)C>G>U4tfqeH8L(3|pQR*zbL1 zT9e~4Tb5p9_G}$y4t`i*4t_Mr9QYvL9C&Ah*}t`q*}S+VYh0M6GxTTSXI)hMpMpIq zD1ImYqJLzbj0}~EpE-aH#VCH_udYEW#`P2zYmi&xSPs_{n6tBj=MY|-XrA;SGA_>y zGtU$?HXm$gYj*!N)_nQ59%lQdXtQZS3*#PC-{iB_sm+ytD*7j`D*k(P&IH2GHT}Eh z5697eQECVIGQAUe#eU2I!yI&%0CP#>%6MWV z@zS!p@+Y1i1b^QuuEF*13CuB zu69dve5k7&Wgb+^s|UB08Dr3u`h@yM0NTj4h7MnHo-4@xmyr7(*4$rpPwsCDZ@2be zRz9V^GnV;;?^Lk%ynzq&K(Aix`mWmW`^152Hoy$CTYVehpD-S1-W^#k#{0^L`V6CN+E z!w+xte;2vu4AmVNEFUOBmrBL>6MK@!O2*N|2=d|Y;oN&A&qv=qKn73lDD zI(+oJAdgv>Yr}8(&@ZuAZE%XUXmX(U!N+Z_sjL<1vjy1R+1IeHt`79fnYdOL{$ci7 z%3f0A*;Zt@ED&Gjm|OFTYBDe%bbo*xXAQsFz+Q`fVBH!N2)kaxN8P$c>sp~QXnv>b zwq=W3&Mtmih7xkR$YA)1Yi?avHNR6C99!u6fh=cL|KQ&PwF!n@ud^n(HNIImHD!h87!i*t?G|p0o+eelJ?B@A64_9%SBhNaJ64EvKgD&%LjLCYnNfc; znj?%*p@*?dq#NqcQFmmX($wms@CSAr9#>hUR^=I+=0B)vvGX%T&#h$kmX*s=^M2E!@N9#m?LhMvz}YB+kd zG~mbP|D(;{s_#;hsKK9lbVK&Lo734x7SIFJ9V_}2$@q?zm^7?*XH94w5Qae{7zOMUF z^?%F%)c1Y)Q?Iy?I>knw*8gYW#ok|2gdS=YYZLiD=CW|Nj;n^x!=S#iJ#`~Ld79+xXpVmUK^B(xO_vO!btA9y7w3L3-0j-y4 z?M-V{%z;JI`bk7yFDcP}OcCd*{Q9S5$iGA7*E1@tfkyjAi!;wP^O71cZ^Ep)qrQ)N z#wqw0_HS;T7x3y|`P==i3hEwK%|>fZ)c&@kgKO1~5<5xBSk?iZV?KI6&i72H6S9A* z=U(*e)EqEs?Oc04)V-~K5AUmh|62H4*`UAtItO$O(q5?6jj+K^oD!04r=6#dsxp?~}{`?&sXn#q2 zGuY~7>O2=!u@@Kfu7q=W*4egu@qPMRM>(eyYyaIE<|j%d=iWNdGsx%c!902v#ngNg z@#U-O_4xN$s_9?(`{>{>7~-6FgWpBpqXb`Ydc3OFL#&I}Irse9F_8R@4zSS*Y*o*B zXL?6*Aw!AfkNCgcr#*yj&p3ZDe2y>v$>FUdKIy_2N~}6AbHc7gA3`6$g@1o|dE>vz z4pl(j9;kyMsjaw}lO?(?Xg%4k!5%^t#@5n=WVc&JRa+XT$~#@rldvN3S1rEpU$;XgxVny7mki3 z-Hh|jUCHrUXuLr!)`w>wgO0N%KTB-1di>cj(x3Bav`7v z3G7EIbU$z>`Nad7Rk_&OT-W{;qg)-GXV-aJT#(ozdmnA~Rq3GQ_3mby(>q6Ocb-RgTUhTN)))x>m&eD;$J5Bg zo&DhY36Yg=J=$Z>t}RJ>o|@hAcwWzN#r(WJ52^g$lh^!63@hh+dR$&_dEGu&^CR*< z!oFqSqO@>xZ*nC2oiOd0eS*F^IL~W-rsrO`J`ej{=ou_q^_(<$&-3f^J z&L^MSYWIe{&pYq&9eGaArA~*kA('') - const [inSettings, setInSettings] = useState(form.form.name.is === '') - const [selectStatus, setSelectStatus] = useState( - NavbarSelectStatus.OFF, - ) - const [activeListItem, setActiveListItem] = useState(null) - const { infoDispatch } = useContext(LayoutContext) - const initialNavbar: ILists = { - activeItem: inSettings - ? { type: 'Step', data: baseSettingsStep } - : { - type: 'Step', - data: - form?.form?.stepsList.find((s) => s.type === 'Innsláttur') || - defaultStep, - }, - steps: form.form.stepsList ?? [], - groups: form.form.groupsList ?? [], - inputs: form.form.inputsList ?? [], - } - const [formBuilder, formDispatch] = useReducer(formReducer, form) - const [lists, listsDispatch] = useReducer(listsReducer, initialNavbar) - const { activeItem } = lists - - const isMounted = useRef(false) - - useEffect(() => { - isMounted.current = true - infoDispatch({ - type: 'changeOrganization', - payload: { - value: formBuilder?.form?.organization.name.is, - }, - }) - infoDispatch({ - type: 'changeApplicationName', - payload: { - value: formBuilder.form.name.is, - }, - }) - }, [formBuilder, infoDispatch]) - - const context: IFormBuilderContext = { - formBuilder: formBuilder, - formDispatch: formDispatch, - lists: lists, - listsDispatch: listsDispatch, - formUpdate: formUpdate, - inSettings: inSettings, - setInSettings: setInSettings, - setSelectStatus: setSelectStatus, - selectStatus: selectStatus, - activeListItem: activeListItem, - setActiveListItem: setActiveListItem, - blur: blur, - onFocus: onFocus, - } - - if (formBuilder.form && activeItem) { - return ( - - - - {selectStatus !== NavbarSelectStatus.OFF ? ( - - ) : ( - - )} - - - - {activeItem?.data && } - - - - - ) - } - return <>Loading - - async function formUpdate() { - updateForm(formBuilder.form, lists.steps, lists.groups, lists.inputs) - } - - function blur(e: FocusEvent) { - if (e.target.value !== focus) { - setOnFocus('') - updateItem(activeItem.type, activeItem.data) - } - } - - function onFocus(value: string) { - setOnFocus(value) - } -} diff --git a/apps/form-builder/screens/Forms.tsx b/apps/form-builder/screens/Forms.tsx deleted file mode 100644 index 358962180a9a..000000000000 --- a/apps/form-builder/screens/Forms.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { Box, Button, Inline, Text } from '@island.is/island-ui/core' -import router from 'next/router' -import TableRow from '../components/TableRow/TableRow' -import { IFormBuilder } from '../types/interfaces' - -interface Props { - formBuilder: IFormBuilder -} -export default function Forms({ formBuilder }: Props) { - if (formBuilder) { - return ( - - {/* Title and buttons */} - - Forskriftir - - - - - - - - - - - - - - - - {formBuilder.forms && - formBuilder.forms?.map((f) => { - return ( - - ) - })} - - ) - } - return <> -} diff --git a/apps/form-builder/screens/index.tsx b/apps/form-builder/screens/index.tsx deleted file mode 100644 index 3112d3ade954..000000000000 --- a/apps/form-builder/screens/index.tsx +++ /dev/null @@ -1,2 +0,0 @@ -export { default as Forms } from './Forms' -export { default as Form } from './Form' diff --git a/apps/form-builder/server.ts b/apps/form-builder/server.ts deleted file mode 100644 index 3f65dc718369..000000000000 --- a/apps/form-builder/server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { bootstrap } from '@island.is/infra-next-server' -import proxyConfig from './proxy.config.json' - -bootstrap({ - name: 'form-builder', - appDir: 'apps/form-builder', - proxyConfig, - externalEndpointDependencies: (nextConfig) => { - const { graphqlEndpoint } = nextConfig.serverRuntimeConfig - return [graphqlEndpoint] - }, -}) diff --git a/apps/form-builder/services/apiService.tsx b/apps/form-builder/services/apiService.tsx deleted file mode 100644 index 182f89bb3aa7..000000000000 --- a/apps/form-builder/services/apiService.tsx +++ /dev/null @@ -1,248 +0,0 @@ -import axios from 'axios' - -import { - IForm, - IFormApplicantType, - IFormBuilder, - IGroup, - IInput, - IInputSettings, - ILanguage, - IStep, - ItemType, -} from '../types/interfaces' -import { groupSchema, stepSchema } from './zodValidation' - -const BASEURL = 'https://profun.island.is/umsoknarkerfi/api' - -export async function getForm(id: unknown): Promise { - try { - const response = await axios.get(`${BASEURL}/Forms/${id}`) - // const validatedFormData: IFormBuilder = formFormBuilderSchema.parse(response.data) - // return validatedFormData - return response.data - } catch (error) { - console.error(error) - throw error - } -} - -export async function updateForm( - form: IForm, - steps: IStep[], - groups: IGroup[], - inputs: IInput[], -) { - const updatedForm: IForm = { - ...form, - stepsList: steps.map((s, i) => { - return { - ...s, - displayOrder: i, - } - }), - groupsList: groups.map((g, i) => { - return { - ...g, - displayOrder: i, - } - }), - inputsList: inputs.map((i, index) => { - return { - ...i, - displayOrder: index, - } - }), - } - console.log('updatedForm', updatedForm) - try { - const response = await axios.put( - `${BASEURL}/Forms/${form.id}`, - updatedForm, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - - return response - } catch (error) { - console.error('Error in updateNavbar:', error) - throw error - } -} - -export async function updateItem(type: string, data: IStep | IGroup | IInput) { - const url = `${BASEURL}/${type}s/${data.id}` - - try { - const response = await axios.put(url, data, { - headers: { - 'Content-Type': 'application/json', - }, - }) - - return response - } catch (error) { - console.error('Error in updateItem: ', error) - throw error - } -} - -export async function getNewForm(organisationId: number): Promise { - try { - const response = await axios.post(`${BASEURL}/Forms/${organisationId}`) - return response.data - } catch (error) { - console.error('Error in getNewForm: ', error) - throw error - } -} - -export async function getAllFormsFromOrganisation( - organisationId: number, -): Promise { - try { - const response = await axios.get( - `${BASEURL}/Forms/Organization/${organisationId}`, - ) - return response.data - } catch (error) { - console.error('Error in getAllFormsFromOrganisation: ', error) - throw error - } -} - -export async function addStep( - formId: number, - name: ILanguage, - displayOrder: number, - stepType: number, - waitingText: ILanguage, - callRuleset: boolean, -): Promise { - try { - const response = await axios.post(`${BASEURL}/Steps`, { - formId, - name, - displayOrder, - stepType, - waitingText, - callRuleset, - }) - - const validatedStep: IStep = stepSchema.parse(response.data) - return validatedStep - } catch (error) { - console.error('Error in addStep: ', error) - throw error - } -} - -export async function addGroup( - displayOrder: number, - parentId: number, -): Promise { - try { - const response = await axios.post(`${BASEURL}/Groups`, { - displayOrder: displayOrder, - stepId: parentId, - }) - - const validatedGroup: IGroup = groupSchema.parse(response.data) - - return validatedGroup - } catch (error) { - console.error('Error in addGroup: ', error) - throw error - } -} - -export async function addInput( - displayOrder: number, - parentId: number, -): Promise { - const requestBody = { - displayOrder: displayOrder, - groupId: parentId, - } - - try { - const response = await axios.post(`${BASEURL}/Inputs`, requestBody, { - headers: { - 'Content-Type': 'application/json', - }, - }) - - const data = response.data - - return data - } catch (error) { - console.error('Error in addInput: ', error) - throw error - } -} - -export async function deleteItem(type: ItemType, id: number) { - try { - const response = await axios.delete(`${BASEURL}/${type}s/${id}`) - return response - } catch (error) { - console.error('Error in deleteItem: ', error) - throw error - } -} - -export async function saveFormSettings(id: number, settings: IInputSettings) { - try { - const response = await axios.put( - `${BASEURL}/Forms/${id}/Settings`, - settings, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - return response - } catch (error) { - console.error('Error in saveFormSettings: ', error) - throw error - } -} - -export async function saveApplicantTypes( - id: number, - types: IFormApplicantType[], -) { - const requestData = { - id: id, - formApplicantTypes: types, - } - try { - const response = await axios.put( - `${BASEURL}/Forms/${id}/Settings`, - requestData, - { - headers: { - 'Content-Type': 'application/json', - }, - }, - ) - - return response - } catch (error) { - console.error('Error in saveApplicantTypes: ', error) - throw error - } -} -export async function getList(type: string) { - try { - const response = await axios.get(`${BASEURL}/Services/${type}`) - return response.data - } catch (error) { - console.error('Error in getList: ', error) - throw error - } -} diff --git a/apps/form-builder/services/translationStation.tsx b/apps/form-builder/services/translationStation.tsx deleted file mode 100644 index 19be4bae56f2..000000000000 --- a/apps/form-builder/services/translationStation.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { ITranslationResponse } from '../types/interfaces' -import axios from 'axios' -import dotenv from 'dotenv' - -dotenv.config() - -export const translationStation = async ( - input: string, -): Promise => { - const apiUrl = process.env.MIDEIND_API - const apiKey = process.env.MIDEIND_KEY - - if (!apiUrl || !apiKey) { - throw new Error('API URL or API key is not defined.') - } - - try { - const response = await axios.post( - apiUrl, - { - contents: [input], - sourceLanguageCode: 'is', - targetLanguageCode: 'en', - model: '', - domain: '', - }, - { - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - 'X-API-Key': apiKey, - }, - }, - ) - - return response.data - } catch (error) { - console.error('Error in translationStation: ', error) - throw error - } -} diff --git a/apps/form-builder/services/zodValidation.ts b/apps/form-builder/services/zodValidation.ts deleted file mode 100644 index bc94f18f8e08..000000000000 --- a/apps/form-builder/services/zodValidation.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { z } from 'zod' -import { EFormApplicantTypes } from '../types/enums' -import { - IApplicantType, - ICertificate, - IForm, - IFormApplicantType, - IFormBuilder, - IGroup, - IInput, - IInputSettings, - IInputType, - IListType, - IStep, - ITenging, -} from '../types/interfaces' - -const languageSchema = z.object({ - is: z.string(), - en: z.string(), -}) - -const dependencySchema = z.record(z.array(z.string())) as z.ZodSchema - -const inputSettingsSchema = z.object({ - $type: z.string().optional(), - isLarge: z.boolean().optional(), - size: z.enum(['xs', 'sm', 'md']), - interval: z.string().optional(), - erHlekkur: z.boolean().optional(), - url: z.string().optional(), - hnapptexti: languageSchema.optional(), - tegundir: z.array(z.string()).optional(), - hamarksstaerd: z.number().optional(), - erFjolval: z.boolean().optional(), - fjoldi: z.number().optional(), - header: z.string().optional(), - hamarkslengd: z.number().optional(), - lagmarkslengd: z.number().optional(), - laggildi: z.number().optional(), - hagildi: z.number().optional(), - listi: z - .array( - z.object({ - guid: z.string(), - label: languageSchema, - description: languageSchema, - displayOrder: z.number(), - isSelected: z.boolean(), - }), - ) - .optional(), - type: z.string().optional(), - name: languageSchema.optional(), - erListi: z.boolean().optional(), - erInnslattur: z.boolean().optional(), -}) as z.ZodSchema - -export const inputSchema = z.object({ - id: z.number(), - name: languageSchema, - description: languageSchema, - isRequired: z.boolean(), - displayOrder: z.number(), - groupId: z.number(), - groupGuid: z.string(), - isHidden: z.boolean(), - type: z.string(), - guid: z.string(), - inputFields: z.record(z.any()), - inputSettings: inputSettingsSchema, - isPartOfMultiSet: z.boolean(), -}) as z.ZodSchema - -export const groupSchema = z.object({ - id: z.number(), - name: languageSchema, - guid: z.string(), - displayOrder: z.number(), - isHidden: z.boolean(), - multiSet: z.number(), - stepId: z.number(), - stepGuid: z.string(), - inputs: z.array(inputSchema), -}) as z.ZodSchema - -export const stepSchema = z.object({ - id: z.number(), - guid: z.string(), - displayOrder: z.number(), - name: languageSchema, - type: z.string(), - waitingText: languageSchema, - callRuleset: z.boolean(), - isHidden: z.boolean(), - isCompleted: z.boolean(), - groups: z.array(groupSchema), -}) as z.ZodSchema - -const certificateSchema = z.object({ - id: z.number(), - type: z.string(), - name: languageSchema, - description: languageSchema, -}) as z.ZodSchema - -const applicantTypesSchema = z.enum([ - EFormApplicantTypes.einstaklingur, - EFormApplicantTypes.einstaklingurMedUmbodAnnarsEinstaklings, - EFormApplicantTypes.einstaklingurMedUmbodLogadila, - EFormApplicantTypes.einstaklingurMedProkuru, - EFormApplicantTypes.einstaklingurUmbodsveitandi, - EFormApplicantTypes.logadili, -]) - -const formApplicantSchema = z.object({ - formId: z.number(), - applicantTypeId: z.number(), - name: languageSchema, - type: applicantTypesSchema, -}) as z.ZodSchema - -export const formSchema = z.object({ - id: z.number(), - name: languageSchema, - organization: z.object({ - id: z.number(), - name: languageSchema, - kennitala: z.string(), - scope: z.string(), - xroadBaseUrl: z.string(), - }), - created: z.date(), - lastChanged: z.date(), - invalidationDate: z.date().optional(), - dependencies: dependencySchema, - stepsList: z.array(stepSchema).default([]), - groupsList: z.array(groupSchema).default([]), - inputsList: z.array(inputSchema).default([]), - stopProgressOnValidatingStep: z.boolean(), - applicationsDaysToRemove: z.number(), - isTranslated: z.boolean(), - documentTypes: z.array(certificateSchema), - formApplicantTypes: z.array(formApplicantSchema), -}) as z.ZodSchema - -const inputTypeSchema = z.object({ - type: z.string(), - name: z.string(), - description: z.string(), - organizations: z.array(z.number()).optional(), - inputFields: z.object({}).optional(), - inputMetadata: z.object({}).optional(), - ruleset: z.object({}).optional(), - inputSettings: inputSettingsSchema, -}) as z.ZodSchema - -const applicantTypeSchema = z.object({ - id: z.number(), - name: languageSchema, - type: applicantTypesSchema, - nameSuggestions: z.array( - z.object({ - applicantTypeId: z.number(), - nameSuggestion: languageSchema, - }), - ), -}) as z.ZodSchema - -const listTypeSchema = z.object({ - id: z.number(), - type: z.string(), - name: languageSchema, - description: languageSchema, -}) as z.ZodSchema - -export const formsFormBuilderSchema = z.object({ - forms: z.array(formSchema), - form: formSchema.optional(), - documentTypes: z.array(certificateSchema).optional(), - inputTypes: z.array(inputTypeSchema).optional(), - applicantTypes: z.array(applicantTypeSchema).optional(), - listTypes: z.array(listTypeSchema).optional(), -}) as z.ZodSchema - -export const formFormBuilderSchema = z.object({ - forms: z.null(), - form: formSchema, - documentTypes: z.array(certificateSchema), - inputTypes: z.array(inputTypeSchema), - applicantTypes: z.array(applicantTypeSchema), - listTypes: z.array(listTypeSchema), -}) as z.ZodSchema diff --git a/apps/form-builder/tsconfig.json b/apps/form-builder/tsconfig.json deleted file mode 100644 index 528ab5176dcf..000000000000 --- a/apps/form-builder/tsconfig.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "jsx": "preserve", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "forceConsistentCasingInFileNames": true, - "noEmit": true, - "resolveJsonModule": true, - "isolatedModules": true, - "incremental": true, - "plugins": [ - { - "name": "next" - } - ], - "types": ["jest", "node"] - }, - "include": [ - "**/*.ts", - "**/*.tsx", - "**/*.js", - "**/*.jsx", - "../../apps/form-builder/.next/types/**/*.ts", - "../../dist/apps/form-builder/.next/types/**/*.ts", - "next-env.d.ts" - ], - "exclude": [ - "node_modules", - "jest.config.ts", - "src/**/*.spec.ts", - "src/**/*.test.ts" - ] -} diff --git a/apps/form-builder/tsconfig.server.json b/apps/form-builder/tsconfig.server.json deleted file mode 100644 index 35605d15229c..000000000000 --- a/apps/form-builder/tsconfig.server.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "module": "commonjs", - "noEmit": false, - "incremental": true, - "tsBuildInfoFile": "../../tmp/buildcache/apps/form-builder/server", - "types": ["node"] - }, - "include": ["server.ts"] -} diff --git a/apps/form-builder/tsconfig.spec.json b/apps/form-builder/tsconfig.spec.json deleted file mode 100644 index 214b2cc208c1..000000000000 --- a/apps/form-builder/tsconfig.spec.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"], - "jsx": "react" - }, - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.test.tsx", - "src/**/*.spec.tsx", - "src/**/*.test.js", - "src/**/*.spec.js", - "src/**/*.test.jsx", - "src/**/*.spec.jsx", - "src/**/*.d.ts" - ] -} diff --git a/apps/form-builder/types/enums/index.tsx b/apps/form-builder/types/enums/index.tsx deleted file mode 100644 index fadfab2e4e4a..000000000000 --- a/apps/form-builder/types/enums/index.tsx +++ /dev/null @@ -1,100 +0,0 @@ -export enum ApplicationTemplateStatus { - Þýðing = -2, - Kerfi = -1, - Óútgefið = 0, - Útgefið = 2, - tekiðÚrNotkun = 4, -} - -export enum LicenseProviderEnum { - sýslumannsembættið = 1, - leyfisveitanEhf = 2, - leyfisveitanEhf2 = 9, - þjóðskráÍslands = 3, - ferðamálastofa = 4, - ferðamálastofa2 = 52, - menntamálastofnun = 5, - hallaBjörgBaldursdóttir = 6, - fiskistofa = 7, - officeOfDistrictMagistrate = 8, - registersIceland = 10, - icelandicTouristBoard = 11, - directorateOfEducation = 12, - hallaBjorgBaldursdottir = 13, - directorateOfFisheries = 14, - fjármálaOgEfnahagsráðuneytið = 15, - ministryOfFinanceAndEconomicAffairs = 16, - ríkisskattstjóri = 17, - ríkiskaup = 18, - sýslumaðurinnÁHöfuðborgarsvæðinu = 19, - sýslumaðurinnÁHöfuðborgarsvæðinu2 = 50, - theDistrictMagistrateCapitalRegion = 20, - centralPublicProcurement = 21, - directorateOfInternalRevenue = 22, - sýslumaðurinnÁVestfjörðum = 23, - theDistrictMagistrateWestfjords = 24, - útlendingastofnun = 37, - útlendingastofnun2 = 49, - icelandicDirectorateOfImmigration = 38, - utanríkisráðuneytið = 39, - ministryForForeignAffairs = 40, - ríkislögreglustjóri = 41, - ríkislögreglustjóri2 = 71, - sjúkratryggingarÍslands = 42, - sjúkratryggingarÍslands2 = 51, - þjóðskjalasafnÍslands = 43, - þjóðskjalasafnÍslands2 = 44, - sýslumenn = 53, - fjölskylduOgHúsdýragarðurinn = 59, - menntamálastofnun2 = 61, - umhverfisstofnun = 62, - héraðsdómurReykjavíkur = 63, - minjastofnunÍslands = 64, - náttúruhamfaratryggingarÍslands = 65, -} - -export enum FileTypeEnum { - PDF, - Image, - Xls, - ALL, -} - -export enum EInputType { - Textalínubox = 1, - TextaboxStórt = 2, - Tölustafir = 3, - Textalýsing = 4, - Hakbox = 5, - Dagssetning = 6, - Fellilisti = 7, - Valhnappar = 8, - Heimagistingarnúmer = 9, - FasteignanúmerInnslegið = 10, - FasteignanúmerValiðÚrLista = 11, - Bankareikningsnúmer = 13, - Kennitala = 14, - Greiðandi = 15, - Krónutala = 16, - Krónutölusamtala = 17, - Netfang = 18, - Símanúmer = 19, - FalinnStrengur = 20, - Tími = 21, - Sveitarfélög = 22, - Landalisti = 23, - Póstnúmer = 24, - KennitalaDánarbús = 25, - KennitalaAllt = 26, - Vottorð = 28, - Aðili = 29, -} - -export enum EFormApplicantTypes { - einstaklingur = 'Einstaklingur', - einstaklingurMedUmbodAnnarsEinstaklings = 'Einstaklingur_með_umboð_annars_einstaklings', - einstaklingurMedUmbodLogadila = 'Einstaklingur_með_umboð_lögaðila', - einstaklingurMedProkuru = 'Einstaklingur_með_prókúru', - einstaklingurUmbodsveitandi = 'Einstaklingur_umboðsveitandi', - logadili = 'Lögaðili', -} diff --git a/apps/form-builder/types/interfaces.tsx b/apps/form-builder/types/interfaces.tsx deleted file mode 100644 index 891c44c723ad..000000000000 --- a/apps/form-builder/types/interfaces.tsx +++ /dev/null @@ -1,253 +0,0 @@ -import { Dispatch, SetStateAction, FocusEvent } from 'react' -import { UniqueIdentifier } from '@dnd-kit/core' -import { EFormApplicantTypes } from './enums' -import { Action as ListsAction } from '../hooks/listsReducer' -import { FormAction } from '../hooks/formReducer' -import { FormHeaderAction } from '../hooks/headerInfoReducer' - -export type IFormBuilderContext = { - formBuilder: IFormBuilder - formDispatch: Dispatch - lists: { - activeItem: ActiveItem - steps: IStep[] - groups: IGroup[] - inputs: IInput[] - } - listsDispatch: Dispatch - formUpdate: () => Promise - inSettings: boolean - setInSettings: Dispatch> - setSelectStatus: Dispatch> - selectStatus: NavbarSelectStatus - activeListItem?: IListItem | null - setActiveListItem: Dispatch> - blur(e: FocusEvent): void - onFocus(e: string): void -} - -export interface IInputSettings { - $type?: string - isLarge?: boolean - size?: Sizes - interval?: string - erHlekkur?: boolean - url?: string - hnapptexti?: ILanguage - tegundir?: string[] - hamarksstaerd?: number - erFjolval?: boolean - fjoldi?: number - header?: string - hamarkslengd?: number - lagmarkslengd?: number - laggildi?: number - hagildi?: number - listi?: IListItem[] - type?: string - name?: ILanguage - erListi?: boolean - erInnslattur?: boolean - [key: string]: unknown -} - -export interface IForm { - id: number - name: ILanguage - created: Date - lastChanged: Date - organization: { - id: number - name: ILanguage - kennitala: string - scope: string - xroadBaseUrl: string - } - dependencies: ITenging - stepsList: IStep[] - groupsList: IGroup[] - inputsList: IInput[] - stopProgressOnValidatingStep: boolean - applicationsDaysToRemove: number - invalidationDate?: Date - isTranslated: boolean - documentTypes: ICertificate[] - formApplicantTypes: IFormApplicantType[] -} - -export interface IStep { - id: number - guid: UniqueIdentifier - displayOrder: number - name: ILanguage - type: string - waitingText: ILanguage - callRuleset: boolean - isHidden: boolean - isCompleted: boolean - groups: IGroup[] -} - -export interface IGroup { - id: number - name: ILanguage - guid: UniqueIdentifier - displayOrder: number - isHidden: boolean - multiSet: number - stepId: number - stepGuid: UniqueIdentifier - inputs?: IInput[] -} - -export interface IInput { - id: number - name: ILanguage - description: ILanguage - isRequired: boolean - displayOrder: number - groupId: number - groupGuid: UniqueIdentifier - isHidden: boolean - type: string - guid: UniqueIdentifier - inputFields: object - inputSettings: IInputSettings - isPartOfMultiSet: boolean -} - -export type ILists = { - activeItem: ActiveItem - steps: IStep[] - groups: IGroup[] - inputs: IInput[] - [key: string]: unknown -} - -export interface ActiveItem { - type: ItemType - data: IStep | IGroup | IInput -} - -export interface ISelectOption { - label: string | number - value: string | number -} - -export interface ITenging { - [key: string]: string[] -} - -export interface IFormBuilder { - form: IForm - forms?: IForm[] | null - documentTypes: ICertificate[] - inputTypes: IInputType[] - applicantTypes: IApplicantType[] - listTypes: IListType[] -} - -export interface IListType { - id: number - type: string - name: ILanguage - description: ILanguage -} - -export interface IListItem { - guid: UniqueIdentifier - label: ILanguage - description: ILanguage - displayOrder: number - isSelected: boolean -} - -export interface ICertificate { - id: number - type: string - name: ILanguage - description: ILanguage -} - -export interface IApplicantType { - id: number - name: ILanguage - type: EFormApplicantTypes - nameSuggestions: { - applicantTypeId: number - nameSuggestion: ILanguage - }[] -} - -export type IFormApplicantType = { - formId: number - applicantTypeId: number - name: ILanguage - type: EFormApplicantTypes -} - -export interface IFormDocumentType { - formId: number - documentTypeId: number -} - -export interface IInputType { - type: string - name: string - description: string - organizations?: [] - inputFields?: object - inputMetadata?: object - ruleset?: object - inputSettings: object -} - -export interface ILayoutContext { - info: { - organization: string - applicationName: string - } - infoDispatch: React.Dispatch -} - -export interface ILicenseProvider { - licenseProviderID: number - kennitala: string - name: string - email: string - phone: string - enabled: boolean - parentId?: number - language: string -} - -export interface ITranslationResponse { - translations: ITranslation[] - sourceLanguageCode: string - targetLanguageCode: string - model: string -} - -export interface ITranslation { - translatedText: string - translatedTextStructured: [string, string][] -} -export enum NavbarSelectStatus { - OFF = 'Off', - NORMAL = 'Normal', - LIST_ITEM = 'ListItem', - ON_WITHOUT_SELECT = 'OnWithoutSelect', -} - -export type ItemType = 'Step' | 'Group' | 'Input' - -export type ILanguage = { - is: string - en: string -} -export interface User { - name?: string - email?: string - image?: string -} -type Sizes = 'xs' | 'sm' | 'md' diff --git a/apps/form-builder/utils/defaultStep.tsx b/apps/form-builder/utils/defaultStep.tsx deleted file mode 100644 index 6130a25964f1..000000000000 --- a/apps/form-builder/utils/defaultStep.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { uuid } from 'uuidv4' -import { IStep } from '../types/interfaces' - -export const defaultStep: IStep = { - id: 0, - guid: uuid(), - displayOrder: 0, - name: { - is: '', - en: '', - }, - type: 'Innsláttur', - waitingText: { - is: '', - en: '', - }, - callRuleset: false, - isHidden: false, - isCompleted: false, -} diff --git a/apps/form-builder/utils/formatDate.tsx b/apps/form-builder/utils/formatDate.tsx deleted file mode 100644 index 7b16496029e6..000000000000 --- a/apps/form-builder/utils/formatDate.tsx +++ /dev/null @@ -1,8 +0,0 @@ -export const formatDate = (date: Date) => { - const newDate = new Date(date) - const day = newDate.getDate().toString().padStart(2, '0') - const month = (newDate.getMonth() + 1).toString().padStart(2, '0') - const year = newDate.getFullYear() - - return `${day}.${month}.${year}` //${hours}:${minutes}`; -} diff --git a/apps/form-builder/utils/getBaseSettingsStep.tsx b/apps/form-builder/utils/getBaseSettingsStep.tsx deleted file mode 100644 index 12844cbd9dbc..000000000000 --- a/apps/form-builder/utils/getBaseSettingsStep.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { uuid } from 'uuidv4' - -export const baseSettingsStep = { - id: 99999, - guid: uuid(), - displayOrder: -1, - name: { - is: 'Grunnstillingar', - en: 'Base settings', - }, - type: 'BaseSetting', - waitingText: { - is: '', - en: '', - }, - callRuleset: false, - isHidden: false, - isCompleted: false, - groups: [], -} From e2cb88e18c4e16d193b08227476588fbcdef1d2f Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 26 Apr 2024 14:02:55 +0000 Subject: [PATCH 31/72] chore: charts update dirty files --- charts/islandis/values.dev.yaml | 1 + charts/islandis/values.prod.yaml | 1 + charts/islandis/values.staging.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml index 2a0cfaa6508d..d53d4f98cc1b 100644 --- a/charts/islandis/values.dev.yaml +++ b/charts/islandis/values.dev.yaml @@ -300,6 +300,7 @@ api: FINANCIAL_STATEMENTS_INAO_TOKEN_ENDPOINT: 'https://login.microsoftonline.com/05a20268-aaea-4bb5-bb78-960b0462185e/oauth2/v2.0/token' FISHING_LICENSE_XROAD_PROVIDER_ID: 'IS-DEV/GOV/10012/Fiskistofa-Protected/veidileyfi-v1' FISKISTOFA_ZENTER_CLIENT_ID: '1114' + FORM_SYSTEM_API_BASE_PATH: 'https://profun.island.is/umsoknarkerfi' HSN_WEB_FORM_ID: '1dimJFHLFYtnhoYEA3JxRK' HUNTING_LICENSE_PASS_TEMPLATE_ID: '1da72d52-a93a-4d0f-8463-1933a2bd210b' ICELANDIC_NAMES_REGISTRY_BACKEND_URL: 'http://web-icelandic-names-registry-backend.icelandic-names-registry.svc.cluster.local' diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml index 3340e7ead6c7..00dbdcab3ce3 100644 --- a/charts/islandis/values.prod.yaml +++ b/charts/islandis/values.prod.yaml @@ -290,6 +290,7 @@ api: FINANCIAL_STATEMENTS_INAO_TOKEN_ENDPOINT: 'https://login.microsoftonline.com/05a20268-aaea-4bb5-bb78-960b0462185e/oauth2/v2.0/token' FISHING_LICENSE_XROAD_PROVIDER_ID: 'IS/GOV/6608922069/Fiskistofa-Protected/veidileyfi-v1' FISKISTOFA_ZENTER_CLIENT_ID: '1114' + FORM_SYSTEM_API_BASE_PATH: 'https://profun.island.is/umsoknarkerfi' HSN_WEB_FORM_ID: '1dimJFHLFYtnhoYEA3JxRK' HUNTING_LICENSE_PASS_TEMPLATE_ID: '5f42f942-d8d6-40bf-a186-5a9e12619d9f' ICELANDIC_NAMES_REGISTRY_BACKEND_URL: 'http://web-icelandic-names-registry-backend.icelandic-names-registry.svc.cluster.local' diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index 2ed0ed9a78ce..549a156908e5 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -300,6 +300,7 @@ api: FINANCIAL_STATEMENTS_INAO_TOKEN_ENDPOINT: 'https://login.microsoftonline.com/05a20268-aaea-4bb5-bb78-960b0462185e/oauth2/v2.0/token' FISHING_LICENSE_XROAD_PROVIDER_ID: 'IS-TEST/GOV/6608922069/Fiskistofa-Protected/veidileyfi-v1' FISKISTOFA_ZENTER_CLIENT_ID: '1114' + FORM_SYSTEM_API_BASE_PATH: 'https://profun.island.is/umsoknarkerfi' HSN_WEB_FORM_ID: '1dimJFHLFYtnhoYEA3JxRK' HUNTING_LICENSE_PASS_TEMPLATE_ID: '1da72d52-a93a-4d0f-8463-1933a2bd210b' ICELANDIC_NAMES_REGISTRY_BACKEND_URL: 'http://web-icelandic-names-registry-backend.icelandic-names-registry.svc.cluster.local' From 4aa133e7b89489a5d702b67b126ef18042e67cc9 Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 26 Apr 2024 14:20:31 +0000 Subject: [PATCH 32/72] chore: nx format:write update dirty files --- .../src/lib/FormSystemClient.config.ts | 2 +- .../components/BaseSettings/BaseSettings.tsx | 10 +++++-- .../Preview/components/Banknumber.tsx | 1 - .../Preview/components/CheckboxPreview.tsx | 9 ++++--- .../components/Preview/components/List.tsx | 1 - .../Preview/components/NationalId.tsx | 7 ++++- .../form-system/src/lib/utils/updateDnd.ts | 27 +++++++++---------- 7 files changed, 32 insertions(+), 25 deletions(-) diff --git a/libs/clients/form-system/src/lib/FormSystemClient.config.ts b/libs/clients/form-system/src/lib/FormSystemClient.config.ts index 45555c468c6e..85ca437a20e2 100644 --- a/libs/clients/form-system/src/lib/FormSystemClient.config.ts +++ b/libs/clients/form-system/src/lib/FormSystemClient.config.ts @@ -13,7 +13,7 @@ export const FormSystemClientConfig = defineConfig({ basePath: env.required( 'FORM_SYSTEM_API_BASE_PATH', 'https://profun.island.is/umsoknarkerfi', - ) + ), } }, }) diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx index 232470d98c8b..7972a593d24e 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/BaseSettings/BaseSettings.tsx @@ -10,8 +10,14 @@ import { useContext } from 'react' import ControlContext from '../../../../context/ControlContext' export const BaseSettings = () => { - const { control, controlDispatch, setFocus, focus, formUpdate, updateSettings } = - useContext(ControlContext) + const { + control, + controlDispatch, + setFocus, + focus, + formUpdate, + updateSettings, + } = useContext(ControlContext) const { form } = control return ( diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx index 406d682e271f..2c77811188bd 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/Banknumber.tsx @@ -8,7 +8,6 @@ import { FormSystemInput } from '@island.is/api/schema' interface Props { currentItem: FormSystemInput - } const Banknumber = ({ currentItem }: Props) => { diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/CheckboxPreview.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/CheckboxPreview.tsx index 66629d5f7bb0..bc944f63dea2 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/CheckboxPreview.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/CheckboxPreview.tsx @@ -1,18 +1,19 @@ -import { FormSystemInput } from "@island.is/api/schema" -import { Checkbox } from "@island.is/island-ui/core" +import { FormSystemInput } from '@island.is/api/schema' +import { Checkbox } from '@island.is/island-ui/core' interface Props { currentItem: FormSystemInput } const CheckboxPreview = ({ currentItem }: Props) => { - return ( { console.log() }} + onChange={() => { + console.log() + }} /> ) } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx index a5d0256b9034..d9483ffc0f76 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/List.tsx @@ -2,7 +2,6 @@ import { FormSystemInput, FormSystemListItem } from '@island.is/api/schema' import { useEffect, useState } from 'react' import { Select } from '@island.is/island-ui/core' - interface Props { currentItem: FormSystemInput } diff --git a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/NationalId.tsx b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/NationalId.tsx index dcc3b6306af8..a468f2037fc9 100644 --- a/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/NationalId.tsx +++ b/libs/portals/admin/form-system/src/components/MainContent/components/Preview/components/NationalId.tsx @@ -15,7 +15,12 @@ const NationalId = ({ currentItem }: Props) => { - + diff --git a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts index f0fd9e8901bd..78d00f2fc4c7 100644 --- a/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts +++ b/libs/portals/admin/form-system/src/lib/utils/updateDnd.ts @@ -1,7 +1,4 @@ -import { - FormSystemGroupInput, - FormSystemInput, -} from '@island.is/api/schema' +import { FormSystemGroupInput, FormSystemInput } from '@island.is/api/schema' import { useFormSystemUpdateFormMutation } from '../../gql/Form.generated' import { ControlState } from '../../hooks/controlReducer' import { ItemType } from './interfaces' @@ -43,17 +40,17 @@ export const updateDnd = ( form: { groupsList: groups?.map( (g) => - ({ - id: g?.id, - name: g?.name, - guid: g?.guid, - displayOrder: g?.displayOrder, - isHidden: (g?.isHidden ?? false) as boolean, - stepId: g?.stepId, - multiSet: g?.multiSet, - stepGuid: g?.stepGuid, - inputs: null, - } as FormSystemGroupInput), + ({ + id: g?.id, + name: g?.name, + guid: g?.guid, + displayOrder: g?.displayOrder, + isHidden: (g?.isHidden ?? false) as boolean, + stepId: g?.stepId, + multiSet: g?.multiSet, + stepGuid: g?.stepGuid, + inputs: null, + } as FormSystemGroupInput), ), }, }, From 1c327b4e8f07bb0c399bfd952028102f53292de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 24 May 2024 13:13:32 +0000 Subject: [PATCH 33/72] form-system backend initial commit --- apps/services/form-system/.eslintrc.json | 18 ++++++ apps/services/form-system/.sequelizerc | 6 ++ apps/services/form-system/docker-compose.yml | 17 +++++ apps/services/form-system/jest.config.ts | 11 ++++ apps/services/form-system/project.json | 64 +++++++++++++++++++ .../form-system/sequelize.config.d.ts | 17 +++++ apps/services/form-system/sequelize.config.js | 25 ++++++++ .../src/app/app.controller.spec.ts | 22 +++++++ .../form-system/src/app/app.controller.ts | 13 ++++ .../form-system/src/app/app.module.ts | 24 +++++++ .../form-system/src/app/app.service.spec.ts | 21 ++++++ .../form-system/src/app/app.service.ts | 8 +++ .../src/app/modules/form/form.controller.ts | 13 ++++ .../src/app/modules/form/form.model.ts | 19 ++++++ .../src/app/modules/form/form.module.ts | 13 ++++ .../src/app/modules/form/form.service.ts | 8 +++ .../src/app/sequelizeConfig.service.ts | 28 ++++++++ apps/services/form-system/src/assets/.gitkeep | 0 .../src/environments/environment.ts | 15 +++++ .../form-system/src/environments/index.ts | 1 + apps/services/form-system/src/main.ts | 39 +++++++++++ apps/services/form-system/tsconfig.app.json | 12 ++++ apps/services/form-system/tsconfig.json | 16 +++++ apps/services/form-system/tsconfig.spec.json | 14 ++++ apps/services/form-system/webpack.config.js | 8 +++ 25 files changed, 432 insertions(+) create mode 100644 apps/services/form-system/.eslintrc.json create mode 100644 apps/services/form-system/.sequelizerc create mode 100644 apps/services/form-system/docker-compose.yml create mode 100644 apps/services/form-system/jest.config.ts create mode 100644 apps/services/form-system/project.json create mode 100644 apps/services/form-system/sequelize.config.d.ts create mode 100644 apps/services/form-system/sequelize.config.js create mode 100644 apps/services/form-system/src/app/app.controller.spec.ts create mode 100644 apps/services/form-system/src/app/app.controller.ts create mode 100644 apps/services/form-system/src/app/app.module.ts create mode 100644 apps/services/form-system/src/app/app.service.spec.ts create mode 100644 apps/services/form-system/src/app/app.service.ts create mode 100644 apps/services/form-system/src/app/modules/form/form.controller.ts create mode 100644 apps/services/form-system/src/app/modules/form/form.model.ts create mode 100644 apps/services/form-system/src/app/modules/form/form.module.ts create mode 100644 apps/services/form-system/src/app/modules/form/form.service.ts create mode 100644 apps/services/form-system/src/app/sequelizeConfig.service.ts create mode 100644 apps/services/form-system/src/assets/.gitkeep create mode 100644 apps/services/form-system/src/environments/environment.ts create mode 100644 apps/services/form-system/src/environments/index.ts create mode 100644 apps/services/form-system/src/main.ts create mode 100644 apps/services/form-system/tsconfig.app.json create mode 100644 apps/services/form-system/tsconfig.json create mode 100644 apps/services/form-system/tsconfig.spec.json create mode 100644 apps/services/form-system/webpack.config.js diff --git a/apps/services/form-system/.eslintrc.json b/apps/services/form-system/.eslintrc.json new file mode 100644 index 000000000000..3456be9b9036 --- /dev/null +++ b/apps/services/form-system/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/apps/services/form-system/.sequelizerc b/apps/services/form-system/.sequelizerc new file mode 100644 index 000000000000..98b322c81e41 --- /dev/null +++ b/apps/services/form-system/.sequelizerc @@ -0,0 +1,6 @@ +const path = require('path') + +module.exports = { + config: path.resolve('sequelize.config.js'), + 'migrations-path': path.resolve('migrations'), +} diff --git a/apps/services/form-system/docker-compose.yml b/apps/services/form-system/docker-compose.yml new file mode 100644 index 000000000000..a7c14265f530 --- /dev/null +++ b/apps/services/form-system/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.3' + +services: + db_reference_backend: + image: public.ecr.aws/docker/library/postgres:15.3-alpine + container_name: form-system + networks: + - local + environment: + - POSTGRES_DB=form-system + - POSTGRES_USER=postgres + - POSTGRES_PASSWORD=postgres + ports: + - 5432:5432 + +networks: + local: diff --git a/apps/services/form-system/jest.config.ts b/apps/services/form-system/jest.config.ts new file mode 100644 index 000000000000..0a9ae85d4383 --- /dev/null +++ b/apps/services/form-system/jest.config.ts @@ -0,0 +1,11 @@ +/* eslint-disable */ +export default { + displayName: 'services-form-system', + preset: '../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/apps/services/form-system', +} diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json new file mode 100644 index 000000000000..cb40559c9e38 --- /dev/null +++ b/apps/services/form-system/project.json @@ -0,0 +1,64 @@ +{ + "name": "services-form-system", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "apps/services/form-system/src", + "projectType": "application", + "targets": { + "build": { + "executor": "@nx/webpack:webpack", + "outputs": ["{options.outputPath}"], + "defaultConfiguration": "production", + "options": { + "target": "node", + "compiler": "tsc", + "outputPath": "dist/apps/services/form-system", + "main": "apps/services/form-system/src/main.ts", + "tsConfig": "apps/services/form-system/tsconfig.app.json", + "assets": ["apps/services/form-system/src/assets"], + "isolatedConfig": true, + "webpackConfig": "apps/services/form-system/webpack.config.js" + }, + "configurations": { + "development": {}, + "production": {} + } + }, + "serve": { + "executor": "@nx/js:node", + "defaultConfiguration": "development", + "options": { + "buildTarget": "services-form-system:build" + }, + "configurations": { + "development": { + "buildTarget": "services-form-system:build:development" + }, + "production": { + "buildTarget": "services-form-system:build:production" + } + } + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["apps/services/form-system/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "apps/services/form-system/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/apps/services/form-system/sequelize.config.d.ts b/apps/services/form-system/sequelize.config.d.ts new file mode 100644 index 000000000000..54b35e79e1be --- /dev/null +++ b/apps/services/form-system/sequelize.config.d.ts @@ -0,0 +1,17 @@ +import { Dialect } from 'sequelize/types' + +interface SequelizeConfig { + username: string + password: string + database: string + host: string + dialect: Dialect +} + +declare namespace SequelizeConfig { + const production: SequelizeConfig + const test: SequelizeConfig + const development: SequelizeConfig +} + +export = SequelizeConfig diff --git a/apps/services/form-system/sequelize.config.js b/apps/services/form-system/sequelize.config.js new file mode 100644 index 000000000000..21a24d156cec --- /dev/null +++ b/apps/services/form-system/sequelize.config.js @@ -0,0 +1,25 @@ +/* eslint-env node */ +module.exports = { + development: { + username: 'postgres', + password: 'postgres', + database: 'form-system', + host: 'localhost', + dialect: 'postgres', + }, + test: { + username: 'test_db', + password: 'test_db', + database: 'test_db', + host: process.env.DB_HOST, + port: process.env.DB_PORT, + dialect: 'postgres', + }, + production: { + username: process.env.DB_USER, + password: process.env.DB_PASS, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: 'postgres', + }, +} diff --git a/apps/services/form-system/src/app/app.controller.spec.ts b/apps/services/form-system/src/app/app.controller.spec.ts new file mode 100644 index 000000000000..5a50edc0f469 --- /dev/null +++ b/apps/services/form-system/src/app/app.controller.spec.ts @@ -0,0 +1,22 @@ +import { Test, TestingModule } from '@nestjs/testing' + +import { AppController } from './app.controller' +import { AppService } from './app.service' + +describe('AppController', () => { + let app: TestingModule + + beforeAll(async () => { + app = await Test.createTestingModule({ + controllers: [AppController], + providers: [AppService], + }).compile() + }) + + describe('getData', () => { + it('should return "Hello API"', () => { + const appController = app.get(AppController) + expect(appController.getData()).toEqual({ message: 'Hello API' }) + }) + }) +}) diff --git a/apps/services/form-system/src/app/app.controller.ts b/apps/services/form-system/src/app/app.controller.ts new file mode 100644 index 000000000000..5ebf1da3ad58 --- /dev/null +++ b/apps/services/form-system/src/app/app.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common' + +import { AppService } from './app.service' + +@Controller() +export class AppController { + constructor(private readonly appService: AppService) {} + + @Get() + getData() { + return this.appService.getData() + } +} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts new file mode 100644 index 000000000000..39ad82191430 --- /dev/null +++ b/apps/services/form-system/src/app/app.module.ts @@ -0,0 +1,24 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { AuthModule } from '@island.is/auth-nest-tools' +import { AuditModule } from '@island.is/nest/audit' + +import { environment } from '../environments' +import { AppController } from './app.controller' +import { AppService } from './app.service' +import { FormModule } from './modules/form/form.module' +import { SequelizeConfigService } from './sequelizeConfig.service' + +@Module({ + imports: [ + AuthModule.register(environment.auth), + AuditModule.forRoot(environment.audit), + SequelizeModule.forRootAsync({ + useClass: SequelizeConfigService, + }), + FormModule, + ], + controllers: [AppController], + providers: [AppService], +}) +export class AppModule {} diff --git a/apps/services/form-system/src/app/app.service.spec.ts b/apps/services/form-system/src/app/app.service.spec.ts new file mode 100644 index 000000000000..7ba5475cf805 --- /dev/null +++ b/apps/services/form-system/src/app/app.service.spec.ts @@ -0,0 +1,21 @@ +import { Test } from '@nestjs/testing' + +import { AppService } from './app.service' + +describe('AppService', () => { + let service: AppService + + beforeAll(async () => { + const app = await Test.createTestingModule({ + providers: [AppService], + }).compile() + + service = app.get(AppService) + }) + + describe('getData', () => { + it('should return "Hello API"', () => { + expect(service.getData()).toEqual({ message: 'Hello API' }) + }) + }) +}) diff --git a/apps/services/form-system/src/app/app.service.ts b/apps/services/form-system/src/app/app.service.ts new file mode 100644 index 000000000000..9761afbf0786 --- /dev/null +++ b/apps/services/form-system/src/app/app.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common' + +@Injectable() +export class AppService { + getData(): { message: string } { + return { message: 'Hello API' } + } +} diff --git a/apps/services/form-system/src/app/modules/form/form.controller.ts b/apps/services/form-system/src/app/modules/form/form.controller.ts new file mode 100644 index 000000000000..4e91d0c72222 --- /dev/null +++ b/apps/services/form-system/src/app/modules/form/form.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get } from '@nestjs/common' + +import { FormService } from './form.service' + +@Controller('forms') +export class FormController { + constructor(private readonly formService: FormService) {} + + @Get() + getData() { + return this.formService.getData() + } +} diff --git a/apps/services/form-system/src/app/modules/form/form.model.ts b/apps/services/form-system/src/app/modules/form/form.model.ts new file mode 100644 index 000000000000..fa44c2c510c1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/form/form.model.ts @@ -0,0 +1,19 @@ +import { + Column, + DataType, + Default, + Model, + PrimaryKey, + Table, +} from 'sequelize-typescript' + +@Table({ tableName: 'applicationTemplates' }) +export class ApplicationTemplate extends Model { + @Column({ + type: DataType.UUID, + primaryKey: true, + allowNull: false, + defaultValue: DataType.UUIDV4, + }) + id!: string +} diff --git a/apps/services/form-system/src/app/modules/form/form.module.ts b/apps/services/form-system/src/app/modules/form/form.module.ts new file mode 100644 index 000000000000..aa0514c85501 --- /dev/null +++ b/apps/services/form-system/src/app/modules/form/form.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common' + +import { FormController } from './form.controller' +import { FormService } from './form.service' +import { SequelizeModule } from '@nestjs/sequelize' +import { ApplicationTemplate } from './form.model' + +@Module({ + imports: [SequelizeModule.forFeature([ApplicationTemplate])], + controllers: [FormController], + providers: [FormService], +}) +export class FormModule {} diff --git a/apps/services/form-system/src/app/modules/form/form.service.ts b/apps/services/form-system/src/app/modules/form/form.service.ts new file mode 100644 index 000000000000..de6216c0e052 --- /dev/null +++ b/apps/services/form-system/src/app/modules/form/form.service.ts @@ -0,0 +1,8 @@ +import { Injectable } from '@nestjs/common' + +@Injectable() +export class FormService { + getData(): { message: string } { + return { message: 'Hello FORM' } + } +} diff --git a/apps/services/form-system/src/app/sequelizeConfig.service.ts b/apps/services/form-system/src/app/sequelizeConfig.service.ts new file mode 100644 index 000000000000..01f2d84ab60b --- /dev/null +++ b/apps/services/form-system/src/app/sequelizeConfig.service.ts @@ -0,0 +1,28 @@ +import { Inject, Injectable } from '@nestjs/common' +import { + SequelizeModuleOptions, + SequelizeOptionsFactory, +} from '@nestjs/sequelize' + +import type { Logger } from '@island.is/logging' +import { LOGGER_PROVIDER } from '@island.is/logging' +import { getOptions } from '@island.is/nest/sequelize' + +import * as dbConfig from '../../sequelize.config.js' + +@Injectable() +export class SequelizeConfigService implements SequelizeOptionsFactory { + constructor( + @Inject(LOGGER_PROVIDER) + private logger: Logger, + ) {} + + createSequelizeOptions(): SequelizeModuleOptions { + const env = process.env.NODE_ENV || 'development' + const config = (dbConfig as { [key: string]: object })[env] + return { + ...config, + ...getOptions({ logger: this.logger }), + } + } +} diff --git a/apps/services/form-system/src/assets/.gitkeep b/apps/services/form-system/src/assets/.gitkeep new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/environments/environment.ts b/apps/services/form-system/src/environments/environment.ts new file mode 100644 index 000000000000..504d25bc57a8 --- /dev/null +++ b/apps/services/form-system/src/environments/environment.ts @@ -0,0 +1,15 @@ +export default { + production: process.env.NODE_ENV === 'production', + audit: { + defaultNamespace: '@island.is/form-system', + groupName: process.env.AUDIT_GROUP_NAME, + // Same service name as in Nx project.json + serviceName: 'services-form-system', + }, + auth: { + issuer: + process.env.IDENTITY_SERVER_ISSUER_URL ?? + 'https://identity-server.dev01.devland.is', + audience: '@island.is', + }, +} diff --git a/apps/services/form-system/src/environments/index.ts b/apps/services/form-system/src/environments/index.ts new file mode 100644 index 000000000000..f1c9690a5bd4 --- /dev/null +++ b/apps/services/form-system/src/environments/index.ts @@ -0,0 +1 @@ +export { default as environment } from './environment' diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts new file mode 100644 index 000000000000..ca19ed16cd98 --- /dev/null +++ b/apps/services/form-system/src/main.ts @@ -0,0 +1,39 @@ +/** + * This is not a production server yet! + * This is only a minimal backend to get started. + */ + +import { Logger } from '@nestjs/common' +import { NestFactory } from '@nestjs/core' +import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger' +import { AppModule } from './app/app.module' + +async function bootstrap() { + const app = await NestFactory.create(AppModule) + + const config = new DocumentBuilder() + .setTitle('FormSystem Api') + .setDescription('Api for FormSystem.') + .setVersion('1.0') + .addTag('form-system-api') + .build() + const document = SwaggerModule.createDocument(app, config) + SwaggerModule.setup('api', app, document) + + const port = process.env.PORT || 3000 + await app.listen(port) + Logger.log(`🚀 Application is running on: http://localhost:${port}`) +} + +bootstrap() + +// bootstrap({ +// appModule: AppModule, +// name: 'form-system-api', +// openApi, +// // port: environment.port, +// // enableVersioning: true, +// // healthCheck: { +// // database: true, +// // }, +// }) diff --git a/apps/services/form-system/tsconfig.app.json b/apps/services/form-system/tsconfig.app.json new file mode 100644 index 000000000000..d4cefc19c54b --- /dev/null +++ b/apps/services/form-system/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["node"], + "emitDecoratorMetadata": true, + "target": "es2021" + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/apps/services/form-system/tsconfig.json b/apps/services/form-system/tsconfig.json new file mode 100644 index 000000000000..fdfa691bda77 --- /dev/null +++ b/apps/services/form-system/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "esModuleInterop": true + } +} diff --git a/apps/services/form-system/tsconfig.spec.json b/apps/services/form-system/tsconfig.spec.json new file mode 100644 index 000000000000..69a251f328ce --- /dev/null +++ b/apps/services/form-system/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/apps/services/form-system/webpack.config.js b/apps/services/form-system/webpack.config.js new file mode 100644 index 000000000000..bb8d268d232f --- /dev/null +++ b/apps/services/form-system/webpack.config.js @@ -0,0 +1,8 @@ +const { composePlugins, withNx } = require('@nx/webpack') + +// Nx plugins for webpack. +module.exports = composePlugins(withNx(), (config) => { + // Update the webpack config as needed here. + // e.g. `config.plugins.push(new MyPlugin())` + return config +}) From 1e91ab6280b09f77b129669d9ad7ddfea738a775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Mon, 27 May 2024 14:20:47 +0000 Subject: [PATCH 34/72] initial configuration --- .../migrations/20240527093718-inital.js | 25 +++++++++ .../form-system/src/app/app.module.ts | 13 +++-- .../src/app/dataTypes/languageType.model.ts | 4 ++ .../src/app/modules/form/form.controller.ts | 7 ++- .../src/app/modules/form/form.model.ts | 17 +++++-- .../src/app/modules/form/form.module.ts | 4 +- .../app/modules/step/step.controller.spec.ts | 18 +++++++ .../src/app/modules/step/step.controller.ts | 4 ++ .../src/app/modules/step/step.model.ts | 51 +++++++++++++++++++ .../src/app/modules/step/step.module.ts | 9 ++++ .../src/app/modules/step/step.service.spec.ts | 18 +++++++ .../src/app/modules/step/step.service.ts | 4 ++ .../src/app/sequelizeConfig.service.ts | 13 +++-- 13 files changed, 168 insertions(+), 19 deletions(-) create mode 100644 apps/services/form-system/migrations/20240527093718-inital.js create mode 100644 apps/services/form-system/src/app/dataTypes/languageType.model.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.controller.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.model.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.module.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/step/step.service.ts diff --git a/apps/services/form-system/migrations/20240527093718-inital.js b/apps/services/form-system/migrations/20240527093718-inital.js new file mode 100644 index 000000000000..b81d9e980173 --- /dev/null +++ b/apps/services/form-system/migrations/20240527093718-inital.js @@ -0,0 +1,25 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'forms', + { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('forms', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 39ad82191430..600e6be51741 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -1,8 +1,8 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' -import { AuthModule } from '@island.is/auth-nest-tools' -import { AuditModule } from '@island.is/nest/audit' - +// import { AuthModule } from '@island.is/auth-nest-tools' +// import { AuditModule } from '@island.is/nest/audit' +import { ConfigModule } from '@island.is/nest/config' import { environment } from '../environments' import { AppController } from './app.controller' import { AppService } from './app.service' @@ -11,12 +11,15 @@ import { SequelizeConfigService } from './sequelizeConfig.service' @Module({ imports: [ - AuthModule.register(environment.auth), - AuditModule.forRoot(environment.audit), + // AuthModule.register(environment.auth), + // AuditModule.forRoot(environment.audit), SequelizeModule.forRootAsync({ useClass: SequelizeConfigService, }), FormModule, + ConfigModule.forRoot({ + isGlobal: true, + }), ], controllers: [AppController], providers: [AppService], diff --git a/apps/services/form-system/src/app/dataTypes/languageType.model.ts b/apps/services/form-system/src/app/dataTypes/languageType.model.ts new file mode 100644 index 000000000000..c78b5a5bfd67 --- /dev/null +++ b/apps/services/form-system/src/app/dataTypes/languageType.model.ts @@ -0,0 +1,4 @@ +export class LanguageType { + is!: string + en!: string +} diff --git a/apps/services/form-system/src/app/modules/form/form.controller.ts b/apps/services/form-system/src/app/modules/form/form.controller.ts index 4e91d0c72222..4dd4dfeabe22 100644 --- a/apps/services/form-system/src/app/modules/form/form.controller.ts +++ b/apps/services/form-system/src/app/modules/form/form.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get } from '@nestjs/common' +import { Controller, Get, Post } from '@nestjs/common' import { FormService } from './form.service' @@ -6,6 +6,11 @@ import { FormService } from './form.service' export class FormController { constructor(private readonly formService: FormService) {} + @Post() + create(): string { + return 'This action adds a new form' + } + @Get() getData() { return this.formService.getData() diff --git a/apps/services/form-system/src/app/modules/form/form.model.ts b/apps/services/form-system/src/app/modules/form/form.model.ts index fa44c2c510c1..70d50295922e 100644 --- a/apps/services/form-system/src/app/modules/form/form.model.ts +++ b/apps/services/form-system/src/app/modules/form/form.model.ts @@ -1,19 +1,28 @@ +import { CreationOptional } from 'sequelize' import { + AutoIncrement, Column, DataType, Default, Model, + NotNull, PrimaryKey, Table, } from 'sequelize-typescript' -@Table({ tableName: 'applicationTemplates' }) -export class ApplicationTemplate extends Model { +@Table({ tableName: 'forms' }) +export class Form extends Model { + @AutoIncrement @Column({ - type: DataType.UUID, + type: DataType.INTEGER, primaryKey: true, + }) + id!: CreationOptional + + @Column({ + type: DataType.UUIDV4, allowNull: false, defaultValue: DataType.UUIDV4, }) - id!: string + guid!: string } diff --git a/apps/services/form-system/src/app/modules/form/form.module.ts b/apps/services/form-system/src/app/modules/form/form.module.ts index aa0514c85501..880580143fcb 100644 --- a/apps/services/form-system/src/app/modules/form/form.module.ts +++ b/apps/services/form-system/src/app/modules/form/form.module.ts @@ -3,10 +3,10 @@ import { Module } from '@nestjs/common' import { FormController } from './form.controller' import { FormService } from './form.service' import { SequelizeModule } from '@nestjs/sequelize' -import { ApplicationTemplate } from './form.model' +import { Form } from './form.model' @Module({ - imports: [SequelizeModule.forFeature([ApplicationTemplate])], + imports: [SequelizeModule.forFeature([Form])], controllers: [FormController], providers: [FormService], }) diff --git a/apps/services/form-system/src/app/modules/step/step.controller.spec.ts b/apps/services/form-system/src/app/modules/step/step.controller.spec.ts new file mode 100644 index 000000000000..fa04203e872c --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StepController } from './step.controller'; + +describe('StepController', () => { + let controller: StepController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StepController], + }).compile(); + + controller = module.get(StepController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/step/step.controller.ts b/apps/services/form-system/src/app/modules/step/step.controller.ts new file mode 100644 index 000000000000..5dc4d60b858f --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('step') +export class StepController {} diff --git a/apps/services/form-system/src/app/modules/step/step.model.ts b/apps/services/form-system/src/app/modules/step/step.model.ts new file mode 100644 index 000000000000..97b20be2d69c --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.model.ts @@ -0,0 +1,51 @@ +import { + AutoIncrement, + Column, + DataType, + Default, + Model, + NotNull, + PrimaryKey, + Table, +} from 'sequelize-typescript' +import { LanguageType } from '../../dataTypes/languageType.model' +import { CreationOptional } from 'sequelize' + +@Table({ tableName: 'forms' }) +export class Step extends Model { + @Column({ + type: DataType.INTEGER, + }) + @PrimaryKey + @NotNull + @AutoIncrement + id!: CreationOptional + + @Column({ + type: DataType.UUIDV4, + }) + @NotNull + @Default(DataType.UUIDV4) + guid!: string + + @Column + name!: LanguageType + + @Column + type!: string + + @Column + displayOrder!: number + + @Column + waitingText?: string + + @Column + isHidden!: boolean + + @Column + callRuleset!: boolean + + @Column + isCompleted!: boolean +} diff --git a/apps/services/form-system/src/app/modules/step/step.module.ts b/apps/services/form-system/src/app/modules/step/step.module.ts new file mode 100644 index 000000000000..fcdabe93441a --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common'; +import { StepController } from './step.controller'; +import { StepService } from './step.service'; + +@Module({ + controllers: [StepController], + providers: [StepService] +}) +export class StepModule {} diff --git a/apps/services/form-system/src/app/modules/step/step.service.spec.ts b/apps/services/form-system/src/app/modules/step/step.service.spec.ts new file mode 100644 index 000000000000..7c92334f08e3 --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { StepService } from './step.service'; + +describe('StepService', () => { + let service: StepService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [StepService], + }).compile(); + + service = module.get(StepService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/step/step.service.ts b/apps/services/form-system/src/app/modules/step/step.service.ts new file mode 100644 index 000000000000..22b8e64d3490 --- /dev/null +++ b/apps/services/form-system/src/app/modules/step/step.service.ts @@ -0,0 +1,4 @@ +import { Injectable } from '@nestjs/common'; + +@Injectable() +export class StepService {} diff --git a/apps/services/form-system/src/app/sequelizeConfig.service.ts b/apps/services/form-system/src/app/sequelizeConfig.service.ts index 01f2d84ab60b..b09222a4a550 100644 --- a/apps/services/form-system/src/app/sequelizeConfig.service.ts +++ b/apps/services/form-system/src/app/sequelizeConfig.service.ts @@ -4,25 +4,24 @@ import { SequelizeOptionsFactory, } from '@nestjs/sequelize' -import type { Logger } from '@island.is/logging' -import { LOGGER_PROVIDER } from '@island.is/logging' +// import type { Logger } from '@island.is/logging' +// import { LOGGER_PROVIDER } from '@island.is/logging' import { getOptions } from '@island.is/nest/sequelize' import * as dbConfig from '../../sequelize.config.js' @Injectable() export class SequelizeConfigService implements SequelizeOptionsFactory { - constructor( - @Inject(LOGGER_PROVIDER) - private logger: Logger, - ) {} + constructor() {} + // @Inject(LOGGER_PROVIDER) + // private logger: Logger, createSequelizeOptions(): SequelizeModuleOptions { const env = process.env.NODE_ENV || 'development' const config = (dbConfig as { [key: string]: object })[env] return { ...config, - ...getOptions({ logger: this.logger }), + // ...getOptions({ logger: this.logger }), } } } From 5dd85221060a7ab9b4c925c3333c4b564f6d70ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Thu, 30 May 2024 14:41:44 +0000 Subject: [PATCH 35/72] adjust for PR --- .../migrations/20240527093718-inital.js | 25 ----- .../migrations/20240527152843-create-form.js | 73 +++++++++++++ .../migrations/20240528093950-create-step.js | 81 ++++++++++++++ apps/services/form-system/project.json | 14 +++ .../src/app/app.controller.spec.ts | 22 ---- .../form-system/src/app/app.controller.ts | 13 --- .../form-system/src/app/app.module.ts | 22 ++-- .../form-system/src/app/app.service.spec.ts | 21 ---- .../form-system/src/app/app.service.ts | 8 -- .../src/app/modules/form/form.controller.ts | 18 ---- .../src/app/modules/form/form.model.ts | 28 ----- .../src/app/modules/form/form.service.ts | 8 -- .../app/modules/forms/dto/create-form.dto.ts | 9 ++ .../src/app/modules/forms/dto/form.dto.ts | 40 +++++++ .../app/modules/forms/dto/update-form.dto.ts | 4 + .../src/app/modules/forms/form.model.ts | 101 ++++++++++++++++++ .../modules/{form => forms}/form.module.ts | 9 +- .../src/app/modules/forms/forms.controller.ts | 47 ++++++++ .../src/app/modules/forms/forms.service.ts | 27 +++++ .../app/modules/step/step.controller.spec.ts | 18 ---- .../src/app/modules/step/step.controller.ts | 4 - .../src/app/modules/step/step.model.ts | 51 --------- .../src/app/modules/step/step.module.ts | 9 -- .../src/app/modules/step/step.service.spec.ts | 18 ---- .../src/app/modules/step/step.service.ts | 4 - .../app/modules/steps/dto/create-step.dto.ts | 6 ++ .../src/app/modules/steps/step.model.ts | 94 ++++++++++++++++ .../src/app/modules/steps/step.module.ts | 12 +++ .../modules/steps/steps.controller.spec.ts | 18 ++++ .../src/app/modules/steps/steps.controller.ts | 14 +++ .../app/modules/steps/steps.service.spec.ts | 18 ++++ .../src/app/modules/steps/steps.service.ts | 18 ++++ .../src/app/sequelizeConfig.service.ts | 13 +-- 33 files changed, 596 insertions(+), 271 deletions(-) delete mode 100644 apps/services/form-system/migrations/20240527093718-inital.js create mode 100644 apps/services/form-system/migrations/20240527152843-create-form.js create mode 100644 apps/services/form-system/migrations/20240528093950-create-step.js delete mode 100644 apps/services/form-system/src/app/app.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/app.controller.ts delete mode 100644 apps/services/form-system/src/app/app.service.spec.ts delete mode 100644 apps/services/form-system/src/app/app.service.ts delete mode 100644 apps/services/form-system/src/app/modules/form/form.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/form/form.model.ts delete mode 100644 apps/services/form-system/src/app/modules/form/form.service.ts create mode 100644 apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/dto/form.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/form.model.ts rename apps/services/form-system/src/app/modules/{form => forms}/form.module.ts (57%) create mode 100644 apps/services/form-system/src/app/modules/forms/forms.controller.ts create mode 100644 apps/services/form-system/src/app/modules/forms/forms.service.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.model.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.module.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/step/step.service.ts create mode 100644 apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts create mode 100644 apps/services/form-system/src/app/modules/steps/step.model.ts create mode 100644 apps/services/form-system/src/app/modules/steps/step.module.ts create mode 100644 apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/steps/steps.controller.ts create mode 100644 apps/services/form-system/src/app/modules/steps/steps.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/steps/steps.service.ts diff --git a/apps/services/form-system/migrations/20240527093718-inital.js b/apps/services/form-system/migrations/20240527093718-inital.js deleted file mode 100644 index b81d9e980173..000000000000 --- a/apps/services/form-system/migrations/20240527093718-inital.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -module.exports = { - async up(queryInterface, Sequelize) { - return queryInterface.sequelize.transaction((t) => - queryInterface.createTable( - 'forms', - { - id: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - }, - }, - { transaction: t }, - ), - ) - }, - - async down(queryInterface, Sequelize) { - return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('forms', { transaction: t }), - ) - }, -} diff --git a/apps/services/form-system/migrations/20240527152843-create-form.js b/apps/services/form-system/migrations/20240527152843-create-form.js new file mode 100644 index 000000000000..d70dd610a3f7 --- /dev/null +++ b/apps/services/form-system/migrations/20240527152843-create-form.js @@ -0,0 +1,73 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'forms', + { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true, + allowNull: false, + }, + guid: { + type: Sequelize.UUID, + primaryKey: false, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.STRING, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + invalidation_date: { + type: Sequelize.DATE, + allowNull: true, + }, + is_translated: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + application_days_to_remove: { + type: Sequelize.INTEGER, + allowNull: false, + defaultValue: 60, + }, + derived_from: { + type: Sequelize.INTEGER, + allowNull: false, + }, + stop_progress_on_validating_step: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: true, + }, + completed_message: { + type: Sequelize.STRING, + allowNull: true, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('forms', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240528093950-create-step.js b/apps/services/form-system/migrations/20240528093950-create-step.js new file mode 100644 index 000000000000..f8a6090bdc3e --- /dev/null +++ b/apps/services/form-system/migrations/20240528093950-create-step.js @@ -0,0 +1,81 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'steps', + { + id: { + type: Sequelize.INTEGER, + primaryKey: true, + autoIncrement: true, + allowNull: false, + }, + guid: { + type: Sequelize.UUID, + primaryKey: false, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.STRING, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + type: { + type: Sequelize.STRING, + allowNull: false, + }, + display_order: { + type: Sequelize.INTEGER, + allowNull: false, + }, + waiting_text: { + type: Sequelize.STRING, + allowNull: true, + }, + is_hidden: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + call_ruleset: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + is_completed: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + form_id: { + type: Sequelize.INTEGER, + allowNull: false, + references: { + model: 'forms', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('steps', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json index cb40559c9e38..c3a48410dc82 100644 --- a/apps/services/form-system/project.json +++ b/apps/services/form-system/project.json @@ -58,6 +58,20 @@ "codeCoverage": true } } + }, + "migrate": { + "executor": "nx:run-commands", + "options": { + "command": "sequelize-cli db:migrate", + "cwd": "apps/services/form-system" + } + }, + "migrate/generate": { + "executor": "nx:run-commands", + "options": { + "command": "sequelize-cli migration:generate", + "cwd": "apps/services/form-system" + } } }, "tags": [] diff --git a/apps/services/form-system/src/app/app.controller.spec.ts b/apps/services/form-system/src/app/app.controller.spec.ts deleted file mode 100644 index 5a50edc0f469..000000000000 --- a/apps/services/form-system/src/app/app.controller.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' - -import { AppController } from './app.controller' -import { AppService } from './app.service' - -describe('AppController', () => { - let app: TestingModule - - beforeAll(async () => { - app = await Test.createTestingModule({ - controllers: [AppController], - providers: [AppService], - }).compile() - }) - - describe('getData', () => { - it('should return "Hello API"', () => { - const appController = app.get(AppController) - expect(appController.getData()).toEqual({ message: 'Hello API' }) - }) - }) -}) diff --git a/apps/services/form-system/src/app/app.controller.ts b/apps/services/form-system/src/app/app.controller.ts deleted file mode 100644 index 5ebf1da3ad58..000000000000 --- a/apps/services/form-system/src/app/app.controller.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Controller, Get } from '@nestjs/common' - -import { AppService } from './app.service' - -@Controller() -export class AppController { - constructor(private readonly appService: AppService) {} - - @Get() - getData() { - return this.appService.getData() - } -} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 600e6be51741..9fd1ed8cbed6 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -1,27 +1,23 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' -// import { AuthModule } from '@island.is/auth-nest-tools' -// import { AuditModule } from '@island.is/nest/audit' -import { ConfigModule } from '@island.is/nest/config' +import { AuthModule } from '@island.is/auth-nest-tools' +import { AuditModule } from '@island.is/nest/audit' import { environment } from '../environments' -import { AppController } from './app.controller' -import { AppService } from './app.service' -import { FormModule } from './modules/form/form.module' +import { FormModule } from './modules/forms/form.module' import { SequelizeConfigService } from './sequelizeConfig.service' +import { StepModule } from './modules/steps/step.module' +import { ProblemModule } from '@island.is/nest/problem' @Module({ imports: [ - // AuthModule.register(environment.auth), - // AuditModule.forRoot(environment.audit), + AuthModule.register(environment.auth), + AuditModule.forRoot(environment.audit), + ProblemModule, SequelizeModule.forRootAsync({ useClass: SequelizeConfigService, }), FormModule, - ConfigModule.forRoot({ - isGlobal: true, - }), + StepModule, ], - controllers: [AppController], - providers: [AppService], }) export class AppModule {} diff --git a/apps/services/form-system/src/app/app.service.spec.ts b/apps/services/form-system/src/app/app.service.spec.ts deleted file mode 100644 index 7ba5475cf805..000000000000 --- a/apps/services/form-system/src/app/app.service.spec.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Test } from '@nestjs/testing' - -import { AppService } from './app.service' - -describe('AppService', () => { - let service: AppService - - beforeAll(async () => { - const app = await Test.createTestingModule({ - providers: [AppService], - }).compile() - - service = app.get(AppService) - }) - - describe('getData', () => { - it('should return "Hello API"', () => { - expect(service.getData()).toEqual({ message: 'Hello API' }) - }) - }) -}) diff --git a/apps/services/form-system/src/app/app.service.ts b/apps/services/form-system/src/app/app.service.ts deleted file mode 100644 index 9761afbf0786..000000000000 --- a/apps/services/form-system/src/app/app.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common' - -@Injectable() -export class AppService { - getData(): { message: string } { - return { message: 'Hello API' } - } -} diff --git a/apps/services/form-system/src/app/modules/form/form.controller.ts b/apps/services/form-system/src/app/modules/form/form.controller.ts deleted file mode 100644 index 4dd4dfeabe22..000000000000 --- a/apps/services/form-system/src/app/modules/form/form.controller.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Controller, Get, Post } from '@nestjs/common' - -import { FormService } from './form.service' - -@Controller('forms') -export class FormController { - constructor(private readonly formService: FormService) {} - - @Post() - create(): string { - return 'This action adds a new form' - } - - @Get() - getData() { - return this.formService.getData() - } -} diff --git a/apps/services/form-system/src/app/modules/form/form.model.ts b/apps/services/form-system/src/app/modules/form/form.model.ts deleted file mode 100644 index 70d50295922e..000000000000 --- a/apps/services/form-system/src/app/modules/form/form.model.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CreationOptional } from 'sequelize' -import { - AutoIncrement, - Column, - DataType, - Default, - Model, - NotNull, - PrimaryKey, - Table, -} from 'sequelize-typescript' - -@Table({ tableName: 'forms' }) -export class Form extends Model { - @AutoIncrement - @Column({ - type: DataType.INTEGER, - primaryKey: true, - }) - id!: CreationOptional - - @Column({ - type: DataType.UUIDV4, - allowNull: false, - defaultValue: DataType.UUIDV4, - }) - guid!: string -} diff --git a/apps/services/form-system/src/app/modules/form/form.service.ts b/apps/services/form-system/src/app/modules/form/form.service.ts deleted file mode 100644 index de6216c0e052..000000000000 --- a/apps/services/form-system/src/app/modules/form/form.service.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Injectable } from '@nestjs/common' - -@Injectable() -export class FormService { - getData(): { message: string } { - return { message: 'Hello FORM' } - } -} diff --git a/apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts b/apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts new file mode 100644 index 000000000000..f5188ad7b43f --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class CreateFormDto { + @ApiProperty() + name!: string + + @ApiProperty() + isTranslated!: boolean +} diff --git a/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts new file mode 100644 index 000000000000..68f5bb3f5159 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts @@ -0,0 +1,40 @@ +import { Step } from '../../steps/step.model' +import { ApiProperty } from '@nestjs/swagger' + +export class FormDto { + @ApiProperty() + id!: number + + @ApiProperty() + guid!: string + + @ApiProperty() + name!: string + + @ApiProperty() + invalidationDate?: Date + + @ApiProperty() + created!: Date + + @ApiProperty() + modified!: Date + + @ApiProperty() + isTranslated!: boolean + + @ApiProperty() + applicationDaysToRemove!: number + + @ApiProperty() + derivedFrom!: number + + @ApiProperty() + stopProgressOnValidatingStep!: boolean + + @ApiProperty() + completedMessage?: string + + @ApiProperty() + steps?: Step[] +} diff --git a/apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts b/apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts new file mode 100644 index 000000000000..338e8d079bdb --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts @@ -0,0 +1,4 @@ +import { OmitType } from '@nestjs/swagger' +import { FormDto } from './form.dto' + +export class UpdateFormDto extends OmitType(FormDto, ['id', 'guid'] as const) {} diff --git a/apps/services/form-system/src/app/modules/forms/form.model.ts b/apps/services/form-system/src/app/modules/forms/form.model.ts new file mode 100644 index 000000000000..66083e5312f1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/form.model.ts @@ -0,0 +1,101 @@ +import { + CreationOptional, + InferAttributes, + InferCreationAttributes, + NonAttribute, +} from 'sequelize' +import { + AllowNull, + AutoIncrement, + Column, + CreatedAt, + DataType, + Default, + HasMany, + Model, + NotNull, + PrimaryKey, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../dataTypes/languageType.model' +import { Step } from '../steps/step.model' +import { ApiProperty } from '@nestjs/swagger' + +@Table({ tableName: 'forms' }) +export class Form extends Model { + @AutoIncrement + @Column({ + type: DataType.INTEGER, + primaryKey: true, + }) + @ApiProperty() + id!: CreationOptional + + @Column({ + type: DataType.UUID, + allowNull: false, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + guid!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + name!: string + + @Column + @ApiProperty() + invalidationDate?: Date + + @CreatedAt + @ApiProperty() + created!: CreationOptional + + @UpdatedAt + @ApiProperty() + modified!: CreationOptional + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isTranslated!: boolean + + @Column({ + type: DataType.INTEGER, + defaultValue: 60, + }) + @ApiProperty() + applicationDaysToRemove!: number + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + @ApiProperty() + derivedFrom!: number + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: true, + }) + @ApiProperty() + stopProgressOnValidatingStep!: boolean + + @Column + @ApiProperty() + completedMessage?: string + + @HasMany(() => Step) + @ApiProperty() + steps?: Step[] +} diff --git a/apps/services/form-system/src/app/modules/form/form.module.ts b/apps/services/form-system/src/app/modules/forms/form.module.ts similarity index 57% rename from apps/services/form-system/src/app/modules/form/form.module.ts rename to apps/services/form-system/src/app/modules/forms/form.module.ts index 880580143fcb..cc43b9295f0b 100644 --- a/apps/services/form-system/src/app/modules/form/form.module.ts +++ b/apps/services/form-system/src/app/modules/forms/form.module.ts @@ -1,13 +1,12 @@ import { Module } from '@nestjs/common' - -import { FormController } from './form.controller' -import { FormService } from './form.service' +import { FormsController } from './forms.controller' +import { FormsService } from './forms.service' import { SequelizeModule } from '@nestjs/sequelize' import { Form } from './form.model' @Module({ imports: [SequelizeModule.forFeature([Form])], - controllers: [FormController], - providers: [FormService], + controllers: [FormsController], + providers: [FormsService], }) export class FormModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts new file mode 100644 index 000000000000..7edb470e104c --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -0,0 +1,47 @@ +import { + Body, + Controller, + Get, + NotFoundException, + Param, + Post, +} from '@nestjs/common' +import { Documentation } from '@island.is/nest/swagger' +import { FormsService } from './forms.service' +import { Form } from './form.model' +import { ApiTags } from '@nestjs/swagger' +import { CreateFormDto } from './dto/create-form.dto' + +@ApiTags('forms') +@Controller('forms') +export class FormsController { + constructor(private readonly formsService: FormsService) {} + + @Post() + create(@Body() createFormDto: CreateFormDto): Promise { + return this.formsService.create(createFormDto as Form) + } + + @Get() + @Documentation({ + description: 'Get all Forms', + response: { status: 200, type: [Form] }, + }) + async findAll(): Promise { + return await this.formsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Form by id', + response: { status: 200, type: Form }, + }) + async findOne(@Param('id') id: number): Promise { + const form = await this.formsService.findOne(id) + if (!form) { + throw new NotFoundException(`Form not found`) + } + + return form + } +} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts new file mode 100644 index 000000000000..0567b5d435df --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -0,0 +1,27 @@ +import { Injectable } from '@nestjs/common' +import { Form } from './form.model' +import { InjectModel } from '@nestjs/sequelize' +import { Step } from '../steps/step.model' + +@Injectable() +export class FormsService { + constructor( + @InjectModel(Form) + private readonly formModel: typeof Form, + ) {} + + async findAll(): Promise { + return await this.formModel.findAll() + } + + async findOne(id: number): Promise { + const form = await this.formModel.findByPk(id, { include: [Step] }) + + return form + } + + async create(form: Form): Promise { + const newForm: Form = new this.formModel(form, { include: [Step] }) + return await newForm.save() + } +} diff --git a/apps/services/form-system/src/app/modules/step/step.controller.spec.ts b/apps/services/form-system/src/app/modules/step/step.controller.spec.ts deleted file mode 100644 index fa04203e872c..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { StepController } from './step.controller'; - -describe('StepController', () => { - let controller: StepController; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [StepController], - }).compile(); - - controller = module.get(StepController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/apps/services/form-system/src/app/modules/step/step.controller.ts b/apps/services/form-system/src/app/modules/step/step.controller.ts deleted file mode 100644 index 5dc4d60b858f..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.controller.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Controller } from '@nestjs/common'; - -@Controller('step') -export class StepController {} diff --git a/apps/services/form-system/src/app/modules/step/step.model.ts b/apps/services/form-system/src/app/modules/step/step.model.ts deleted file mode 100644 index 97b20be2d69c..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.model.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - AutoIncrement, - Column, - DataType, - Default, - Model, - NotNull, - PrimaryKey, - Table, -} from 'sequelize-typescript' -import { LanguageType } from '../../dataTypes/languageType.model' -import { CreationOptional } from 'sequelize' - -@Table({ tableName: 'forms' }) -export class Step extends Model { - @Column({ - type: DataType.INTEGER, - }) - @PrimaryKey - @NotNull - @AutoIncrement - id!: CreationOptional - - @Column({ - type: DataType.UUIDV4, - }) - @NotNull - @Default(DataType.UUIDV4) - guid!: string - - @Column - name!: LanguageType - - @Column - type!: string - - @Column - displayOrder!: number - - @Column - waitingText?: string - - @Column - isHidden!: boolean - - @Column - callRuleset!: boolean - - @Column - isCompleted!: boolean -} diff --git a/apps/services/form-system/src/app/modules/step/step.module.ts b/apps/services/form-system/src/app/modules/step/step.module.ts deleted file mode 100644 index fcdabe93441a..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; -import { StepController } from './step.controller'; -import { StepService } from './step.service'; - -@Module({ - controllers: [StepController], - providers: [StepService] -}) -export class StepModule {} diff --git a/apps/services/form-system/src/app/modules/step/step.service.spec.ts b/apps/services/form-system/src/app/modules/step/step.service.spec.ts deleted file mode 100644 index 7c92334f08e3..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { StepService } from './step.service'; - -describe('StepService', () => { - let service: StepService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [StepService], - }).compile(); - - service = module.get(StepService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/apps/services/form-system/src/app/modules/step/step.service.ts b/apps/services/form-system/src/app/modules/step/step.service.ts deleted file mode 100644 index 22b8e64d3490..000000000000 --- a/apps/services/form-system/src/app/modules/step/step.service.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Injectable } from '@nestjs/common'; - -@Injectable() -export class StepService {} diff --git a/apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts b/apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts new file mode 100644 index 000000000000..3ad79872858f --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class CreateStepDto { + @ApiProperty() + formId!: number +} diff --git a/apps/services/form-system/src/app/modules/steps/step.model.ts b/apps/services/form-system/src/app/modules/steps/step.model.ts new file mode 100644 index 000000000000..80a1e3622ec2 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/step.model.ts @@ -0,0 +1,94 @@ +import { + AutoIncrement, + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { CreationOptional } from 'sequelize' +import { Form } from '../forms/form.model' +import { ApiProperty } from '@nestjs/swagger' + +@Table({ tableName: 'steps' }) +export class Step extends Model { + @AutoIncrement + @Column({ + type: DataType.INTEGER, + primaryKey: true, + }) + @ApiProperty() + id!: CreationOptional + + @Column({ + type: DataType.UUID, + allowNull: false, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + guid!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + name!: string + + @CreatedAt + @ApiProperty() + created!: CreationOptional + + @UpdatedAt + @ApiProperty() + modified!: CreationOptional + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: 'input', + }) + type!: string + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + displayOrder!: number + + @Column({ + type: DataType.STRING, + allowNull: true, + defaultValue: '', + }) + waitingText?: string + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + isHidden!: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + callRuleset!: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + isCompleted!: boolean + + @ForeignKey(() => Form) + @Column({ type: DataType.INTEGER, allowNull: false, field: 'form_id' }) + formId!: number +} diff --git a/apps/services/form-system/src/app/modules/steps/step.module.ts b/apps/services/form-system/src/app/modules/steps/step.module.ts new file mode 100644 index 000000000000..a1f6b6baac37 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/step.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { StepsController } from './steps.controller' +import { StepsService } from './steps.service' +import { SequelizeModule } from '@nestjs/sequelize' +import { Step } from './step.model' + +@Module({ + imports: [SequelizeModule.forFeature([Step])], + controllers: [StepsController], + providers: [StepsService], +}) +export class StepModule {} diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts new file mode 100644 index 000000000000..d17b1e8a5b31 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing' +import { StepsController } from './steps.controller' + +describe('StepsController', () => { + let controller: StepsController + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [StepsController], + }).compile() + + controller = module.get(StepsController) + }) + + it('should be defined', () => { + expect(controller).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.ts new file mode 100644 index 000000000000..01738233755b --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.ts @@ -0,0 +1,14 @@ +import { Body, Controller, Post } from '@nestjs/common' +import { StepsService } from './steps.service' +import { CreateStepDto } from './dto/create-step.dto' +import { Step } from './step.model' + +@Controller('steps') +export class StepsController { + constructor(private readonly stepsService: StepsService) {} + + @Post() + create(@Body() createStepDto: CreateStepDto): Promise { + return this.stepsService.create(createStepDto) + } +} diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts new file mode 100644 index 000000000000..d8d2ce70bfc1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts @@ -0,0 +1,18 @@ +import { Test } from '@nestjs/testing' +import { StepsService } from './steps.service' + +describe('StepsService', () => { + let service: StepsService + + beforeEach(async () => { + const module = await Test.createTestingModule({ + providers: [StepsService], + }).compile() + + service = module.get(StepsService) + }) + + it('should be defined', () => { + expect(service).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.ts b/apps/services/form-system/src/app/modules/steps/steps.service.ts new file mode 100644 index 000000000000..5996b0a4ccba --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/steps.service.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { Step } from './step.model' +import { CreateStepDto } from './dto/create-step.dto' + +@Injectable() +export class StepsService { + constructor( + @InjectModel(Step) + private readonly stepModel: typeof Step, + ) {} + + async create(createStepDto: CreateStepDto): Promise { + const step = createStepDto as Step + const newStep: Step = new this.stepModel(step) + return await newStep.save() + } +} diff --git a/apps/services/form-system/src/app/sequelizeConfig.service.ts b/apps/services/form-system/src/app/sequelizeConfig.service.ts index b09222a4a550..01f2d84ab60b 100644 --- a/apps/services/form-system/src/app/sequelizeConfig.service.ts +++ b/apps/services/form-system/src/app/sequelizeConfig.service.ts @@ -4,24 +4,25 @@ import { SequelizeOptionsFactory, } from '@nestjs/sequelize' -// import type { Logger } from '@island.is/logging' -// import { LOGGER_PROVIDER } from '@island.is/logging' +import type { Logger } from '@island.is/logging' +import { LOGGER_PROVIDER } from '@island.is/logging' import { getOptions } from '@island.is/nest/sequelize' import * as dbConfig from '../../sequelize.config.js' @Injectable() export class SequelizeConfigService implements SequelizeOptionsFactory { - constructor() {} - // @Inject(LOGGER_PROVIDER) - // private logger: Logger, + constructor( + @Inject(LOGGER_PROVIDER) + private logger: Logger, + ) {} createSequelizeOptions(): SequelizeModuleOptions { const env = process.env.NODE_ENV || 'development' const config = (dbConfig as { [key: string]: object })[env] return { ...config, - // ...getOptions({ logger: this.logger }), + ...getOptions({ logger: this.logger }), } } } From c075285fbf87b1749896505721a78d157f15c46f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Tue, 4 Jun 2024 14:11:39 +0000 Subject: [PATCH 36/72] fix lint warnings --- .../form-system/src/app/modules/forms/form.model.ts | 12 +----------- apps/services/form-system/src/main.ts | 13 +------------ 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/apps/services/form-system/src/app/modules/forms/form.model.ts b/apps/services/form-system/src/app/modules/forms/form.model.ts index 66083e5312f1..192747806cef 100644 --- a/apps/services/form-system/src/app/modules/forms/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/form.model.ts @@ -1,24 +1,14 @@ +import { CreationOptional } from 'sequelize' import { - CreationOptional, - InferAttributes, - InferCreationAttributes, - NonAttribute, -} from 'sequelize' -import { - AllowNull, AutoIncrement, Column, CreatedAt, DataType, - Default, HasMany, Model, - NotNull, - PrimaryKey, Table, UpdatedAt, } from 'sequelize-typescript' -import { LanguageType } from '../../dataTypes/languageType.model' import { Step } from '../steps/step.model' import { ApiProperty } from '@nestjs/swagger' diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index ca19ed16cd98..b36967d25798 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -8,7 +8,7 @@ import { NestFactory } from '@nestjs/core' import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger' import { AppModule } from './app/app.module' -async function bootstrap() { +const bootstrap = async () => { const app = await NestFactory.create(AppModule) const config = new DocumentBuilder() @@ -26,14 +26,3 @@ async function bootstrap() { } bootstrap() - -// bootstrap({ -// appModule: AppModule, -// name: 'form-system-api', -// openApi, -// // port: environment.port, -// // enableVersioning: true, -// // healthCheck: { -// // database: true, -// // }, -// }) From 870bda39e9d9ac08573953b99edf98937bc230d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 14 Jun 2024 14:04:45 +0000 Subject: [PATCH 37/72] add models and modules --- apps/services/form-system/.sequelizerc | 1 + .../20240605120243-create-organization.js | 44 +++ ...-form.js => 20240605120322-create-form.js} | 20 +- ...-step.js => 20240605120342-create-step.js} | 24 +- .../migrations/20240605122019-create-group.js | 61 ++++ .../20240607120240-create-form-applicant.js | 60 ++++ ...1-create-applicant-type-name-suggestion.js | 62 +++++ .../20240607142452-create-input-type.js | 54 ++++ .../migrations/20240611122625-create-input.js | 74 +++++ .../20240612095843-create-input-settings.js | 125 +++++++++ ...14092719-create-organization-input-type.js | 52 ++++ .../20240614131225-create-testimony-type.js | 55 ++++ apps/services/form-system/project.json | 14 + .../seeders/20240611110210-seed-input-type.js | 239 ++++++++++++++++ .../20240611135450-seed-organization.js | 19 ++ ...0614110902-seed-organization-input-type.js | 26 ++ .../20240614132148-seed-testimony-type.js | 65 +++++ apps/services/form-system/sequelize.config.js | 1 + .../form-system/src/app/app.module.ts | 18 +- .../src/app/dataTypes/languageType.model.ts | 5 + .../src/app/enums/applicantType.enum.ts | 8 + .../src/app/enums/stepType.enum.ts | 6 + .../src/app/enums/timeInterval.enum.ts | 6 + .../applicants/models/applicant.model.ts | 95 +++++++ .../applicantTypeNameSuggestion.model.ts | 59 ++++ .../applicants/models/applicantTypes.ts | 8 + .../models/dto/formApplicant.dto.ts | 13 + .../applicants/models/formApplicant.model.ts | 60 ++++ .../src/app/modules/forms/dto/form.dto.ts | 40 --- .../src/app/modules/forms/form.module.ts | 12 - .../src/app/modules/forms/forms.controller.ts | 40 ++- .../src/app/modules/forms/forms.module.ts | 27 ++ .../src/app/modules/forms/forms.service.ts | 262 +++++++++++++++++- .../dto/createForm.dto.ts} | 5 +- .../app/modules/forms/models/dto/form.dto.ts | 56 ++++ .../forms/models/dto/form.response.dto.ts | 12 + .../dto/updateForm.dto.ts} | 2 +- .../modules/forms/{ => models}/form.model.ts | 56 ++-- .../modules/groups/groups.controller.spec.ts | 18 ++ .../app/modules/groups/groups.controller.ts | 47 ++++ .../src/app/modules/groups/groups.module.ts | 12 + .../app/modules/groups/groups.service.spec.ts | 18 ++ .../src/app/modules/groups/groups.service.ts | 29 ++ .../groups/models/dto/createGroup.dto.ts | 6 + .../modules/groups/models/dto/group.dto.ts | 28 ++ .../models/group.model.ts} | 71 ++--- .../modules/inputs/inputs.controller.spec.ts | 18 ++ .../app/modules/inputs/inputs.controller.ts | 47 ++++ .../src/app/modules/inputs/inputs.module.ts | 14 + .../app/modules/inputs/inputs.service.spec.ts | 18 ++ .../src/app/modules/inputs/inputs.service.ts | 28 ++ .../inputs/models/dto/createInput.dto.ts | 7 + .../modules/inputs/models/dto/input.dto.ts | 39 +++ .../inputs/models/dto/inputType.dto.ts | 19 ++ .../app/modules/inputs/models/input.model.ts | 98 +++++++ .../inputs/models/inputSettings.model.ts | 177 ++++++++++++ .../modules/inputs/models/inputType.model.ts | 79 ++++++ .../models/dto/createOrganization.dto.ts | 10 + .../models/dto/organization.dto.ts | 4 + .../models/organization.model.ts | 79 ++++++ .../models/organizationInputType.model.ts | 45 +++ .../organizations.controller.spec.ts | 18 ++ .../organizations/organizations.controller.ts | 49 ++++ .../organizations/organizations.module.ts | 15 + .../organizations.service.spec.ts | 18 ++ .../organizations/organizations.service.ts | 42 +++ .../dto/createStep.dto.ts} | 2 +- .../app/modules/steps/models/dto/step.dto.ts | 34 +++ .../app/modules/steps/models/step.model.ts | 108 ++++++++ .../modules/steps/steps.controller.spec.ts | 23 +- .../src/app/modules/steps/steps.controller.ts | 39 ++- .../steps/{step.module.ts => steps.module.ts} | 5 +- .../src/app/modules/steps/steps.service.ts | 24 +- .../testimonies/models/testimonyType.model.ts | 56 ++++ .../testimonies/models/testimonyTypes.ts | 9 + 75 files changed, 2951 insertions(+), 188 deletions(-) create mode 100644 apps/services/form-system/migrations/20240605120243-create-organization.js rename apps/services/form-system/migrations/{20240527152843-create-form.js => 20240605120322-create-form.js} (88%) rename apps/services/form-system/migrations/{20240528093950-create-step.js => 20240605120342-create-step.js} (84%) create mode 100644 apps/services/form-system/migrations/20240605122019-create-group.js create mode 100644 apps/services/form-system/migrations/20240607120240-create-form-applicant.js create mode 100644 apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js create mode 100644 apps/services/form-system/migrations/20240607142452-create-input-type.js create mode 100644 apps/services/form-system/migrations/20240611122625-create-input.js create mode 100644 apps/services/form-system/migrations/20240612095843-create-input-settings.js create mode 100644 apps/services/form-system/migrations/20240614092719-create-organization-input-type.js create mode 100644 apps/services/form-system/migrations/20240614131225-create-testimony-type.js create mode 100644 apps/services/form-system/seeders/20240611110210-seed-input-type.js create mode 100644 apps/services/form-system/seeders/20240611135450-seed-organization.js create mode 100644 apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js create mode 100644 apps/services/form-system/seeders/20240614132148-seed-testimony-type.js create mode 100644 apps/services/form-system/src/app/enums/applicantType.enum.ts create mode 100644 apps/services/form-system/src/app/enums/stepType.enum.ts create mode 100644 apps/services/form-system/src/app/enums/timeInterval.enum.ts create mode 100644 apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts create mode 100644 apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts create mode 100644 apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts create mode 100644 apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts create mode 100644 apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts delete mode 100644 apps/services/form-system/src/app/modules/forms/dto/form.dto.ts delete mode 100644 apps/services/form-system/src/app/modules/forms/form.module.ts create mode 100644 apps/services/form-system/src/app/modules/forms/forms.module.ts rename apps/services/form-system/src/app/modules/forms/{dto/create-form.dto.ts => models/dto/createForm.dto.ts} (61%) create mode 100644 apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts rename apps/services/form-system/src/app/modules/forms/{dto/update-form.dto.ts => models/dto/updateForm.dto.ts} (50%) rename apps/services/form-system/src/app/modules/forms/{ => models}/form.model.ts (56%) create mode 100644 apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/groups/groups.controller.ts create mode 100644 apps/services/form-system/src/app/modules/groups/groups.module.ts create mode 100644 apps/services/form-system/src/app/modules/groups/groups.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/groups/groups.service.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts rename apps/services/form-system/src/app/modules/{steps/step.model.ts => groups/models/group.model.ts} (55%) create mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.controller.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.module.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.service.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/input.model.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/models/organization.model.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/organizations.controller.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/organizations.module.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/organizations/organizations.service.ts rename apps/services/form-system/src/app/modules/steps/{dto/create-step.dto.ts => models/dto/createStep.dto.ts} (84%) create mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts create mode 100644 apps/services/form-system/src/app/modules/steps/models/step.model.ts rename apps/services/form-system/src/app/modules/steps/{step.module.ts => steps.module.ts} (76%) create mode 100644 apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts diff --git a/apps/services/form-system/.sequelizerc b/apps/services/form-system/.sequelizerc index 98b322c81e41..33a373b6a37e 100644 --- a/apps/services/form-system/.sequelizerc +++ b/apps/services/form-system/.sequelizerc @@ -2,5 +2,6 @@ const path = require('path') module.exports = { config: path.resolve('sequelize.config.js'), + 'seeders-path': path.resolve('seeders'), 'migrations-path': path.resolve('migrations'), } diff --git a/apps/services/form-system/migrations/20240605120243-create-organization.js b/apps/services/form-system/migrations/20240605120243-create-organization.js new file mode 100644 index 000000000000..d8c521ed7b80 --- /dev/null +++ b/apps/services/form-system/migrations/20240605120243-create-organization.js @@ -0,0 +1,44 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'organizations', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + national_id: { + type: Sequelize.STRING, + allowNull: false, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('organizations', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240527152843-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js similarity index 88% rename from apps/services/form-system/migrations/20240527152843-create-form.js rename to apps/services/form-system/migrations/20240605120322-create-form.js index d70dd610a3f7..6f67d592ce91 100644 --- a/apps/services/form-system/migrations/20240527152843-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -7,19 +7,13 @@ module.exports = { 'forms', { id: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - allowNull: false, - }, - guid: { type: Sequelize.UUID, - primaryKey: false, + primaryKey: true, allowNull: false, defaultValue: Sequelize.UUIDV4, }, name: { - type: Sequelize.STRING, + type: Sequelize.JSON, allowNull: false, }, created: { @@ -56,9 +50,17 @@ module.exports = { defaultValue: true, }, completed_message: { - type: Sequelize.STRING, + type: Sequelize.JSON, allowNull: true, }, + organization_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'organizations', + key: 'id', + }, + }, }, { transaction: t }, ), diff --git a/apps/services/form-system/migrations/20240528093950-create-step.js b/apps/services/form-system/migrations/20240605120342-create-step.js similarity index 84% rename from apps/services/form-system/migrations/20240528093950-create-step.js rename to apps/services/form-system/migrations/20240605120342-create-step.js index f8a6090bdc3e..909be6a52c3c 100644 --- a/apps/services/form-system/migrations/20240528093950-create-step.js +++ b/apps/services/form-system/migrations/20240605120342-create-step.js @@ -7,19 +7,13 @@ module.exports = { 'steps', { id: { - type: Sequelize.INTEGER, - primaryKey: true, - autoIncrement: true, - allowNull: false, - }, - guid: { type: Sequelize.UUID, - primaryKey: false, + primaryKey: true, allowNull: false, defaultValue: Sequelize.UUIDV4, }, name: { - type: Sequelize.STRING, + type: Sequelize.JSON, allowNull: false, }, created: { @@ -32,16 +26,22 @@ module.exports = { defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), allowNull: false, }, - type: { - type: Sequelize.STRING, + step_type: { + type: Sequelize.DataTypes.ENUM( + 'premises', + 'parties', + 'input', + 'payment', + ), allowNull: false, + defaultValue: 'input', }, display_order: { type: Sequelize.INTEGER, allowNull: false, }, waiting_text: { - type: Sequelize.STRING, + type: Sequelize.JSON, allowNull: true, }, is_hidden: { @@ -60,7 +60,7 @@ module.exports = { defaultValue: false, }, form_id: { - type: Sequelize.INTEGER, + type: Sequelize.UUID, allowNull: false, references: { model: 'forms', diff --git a/apps/services/form-system/migrations/20240605122019-create-group.js b/apps/services/form-system/migrations/20240605122019-create-group.js new file mode 100644 index 000000000000..f8c071e0a9de --- /dev/null +++ b/apps/services/form-system/migrations/20240605122019-create-group.js @@ -0,0 +1,61 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'groups', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + display_order: { + type: Sequelize.INTEGER, + allowNull: false, + }, + is_hidden: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + multiset: { + type: Sequelize.INTEGER, + allowNull: false, + }, + step_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'steps', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('groups', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240607120240-create-form-applicant.js b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js new file mode 100644 index 000000000000..1845f90795a7 --- /dev/null +++ b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js @@ -0,0 +1,60 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'form_applicants', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + applicant_type: { + type: Sequelize.ENUM( + 'individual', + 'individualWithMandateFromIndividual', + 'individualWithMandateFromLegalEntity', + 'individualWithProcuration', + 'individualGivingMandate', + 'legalEntity', + ), + allowNull: false, + defaultValue: 'individual', + }, + form_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'forms', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('form_applicants', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js new file mode 100644 index 000000000000..3717ddedcf44 --- /dev/null +++ b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js @@ -0,0 +1,62 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'applicant_type_name_suggestions', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name_suggestion: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + applicant_type: { + type: Sequelize.ENUM( + 'individual', + 'individualWithMandateFromIndividual', + 'individualWithMandateFromLegalEntity', + 'individualWithProcuration', + 'individualGivingMandate', + 'legalEntity', + ), + allowNull: false, + defaultValue: 'individual', + }, + organization_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'organizations', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('applicant_type_name_suggestions', { + transaction: t, + }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240607142452-create-input-type.js b/apps/services/form-system/migrations/20240607142452-create-input-type.js new file mode 100644 index 000000000000..912c430fd5dc --- /dev/null +++ b/apps/services/form-system/migrations/20240607142452-create-input-type.js @@ -0,0 +1,54 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'input_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + type: { + type: Sequelize.STRING, + allowNull: false, + unique: true, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + description: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + is_common: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('input_types', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240611122625-create-input.js b/apps/services/form-system/migrations/20240611122625-create-input.js new file mode 100644 index 000000000000..10b4e8d699a1 --- /dev/null +++ b/apps/services/form-system/migrations/20240611122625-create-input.js @@ -0,0 +1,74 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'inputs', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + description: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + display_order: { + type: Sequelize.INTEGER, + allowNull: false, + }, + is_hidden: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + is_part_of_multiset: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + group_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'groups', + key: 'id', + }, + }, + input_type: { + type: Sequelize.STRING, + allowNull: false, + references: { + model: 'input_types', + key: 'type', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('inputs', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240612095843-create-input-settings.js b/apps/services/form-system/migrations/20240612095843-create-input-settings.js new file mode 100644 index 000000000000..0d4fea5b08a2 --- /dev/null +++ b/apps/services/form-system/migrations/20240612095843-create-input-settings.js @@ -0,0 +1,125 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'input_settings', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + min_value: { + type: Sequelize.INTEGER, + allowNull: true, + }, + max_value: { + type: Sequelize.INTEGER, + allowNull: true, + }, + min_length: { + type: Sequelize.INTEGER, + allowNull: true, + }, + max_length: { + type: Sequelize.INTEGER, + allowNull: true, + }, + min_date: { + type: Sequelize.DATE, + allowNull: true, + }, + max_date: { + type: Sequelize.DATE, + allowNull: true, + }, + min_amount: { + type: Sequelize.STRING, + allowNull: true, + }, + max_amount: { + type: Sequelize.STRING, + allowNull: true, + }, + year: { + type: Sequelize.INTEGER, + allowNull: true, + }, + has_link: { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + url: { + type: Sequelize.STRING, + allowNull: true, + }, + button_text: { + type: Sequelize.STRING, + allowNull: true, + }, + has_property_input: { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + has_property_list: { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + list: { + type: Sequelize.JSON, + allowNull: true, + }, + file_types: { + type: Sequelize.JSON, + allowNull: true, + }, + file_max_size: { + type: Sequelize.INTEGER, + allowNull: true, + }, + max_files: { + type: Sequelize.INTEGER, + allowNull: true, + }, + time_interval: { + type: Sequelize.ENUM( + 'minutely', + 'quarterly', + 'halfHourly', + 'hourly', + ), + allowNull: true, + }, + input_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'inputs', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('input_settings', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240614092719-create-organization-input-type.js b/apps/services/form-system/migrations/20240614092719-create-organization-input-type.js new file mode 100644 index 000000000000..28a7c5bde372 --- /dev/null +++ b/apps/services/form-system/migrations/20240614092719-create-organization-input-type.js @@ -0,0 +1,52 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'organization_input_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + organization_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'organizations', + key: 'id', + }, + }, + input_type_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'input_types', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('organization_input_types', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js new file mode 100644 index 000000000000..4d3b2852dff8 --- /dev/null +++ b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js @@ -0,0 +1,55 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'testimony_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + description: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + testimony_type: { + type: Sequelize.DataTypes.ENUM( + 'estateGuardianshipCertificateStamped', + 'estateGuardianshipCertificateUnstamped', + 'residenceCertificate', + 'indebtednessCertificate', + 'criminalRecordStamped', + 'criminalRecordUnstamped', + ), + allowNull: false, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('testimony_types', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json index c3a48410dc82..2dc035e9446f 100644 --- a/apps/services/form-system/project.json +++ b/apps/services/form-system/project.json @@ -72,6 +72,20 @@ "command": "sequelize-cli migration:generate", "cwd": "apps/services/form-system" } + }, + "seed/generate": { + "executor": "nx:run-commands", + "options": { + "command": "sequelize-cli seed:generate", + "cwd": "apps/services/form-system" + } + }, + "seed": { + "executor": "nx:run-commands", + "options": { + "command": "sequelize-cli db:seed:all", + "cwd": "apps/services/form-system" + } } }, "tags": [] diff --git a/apps/services/form-system/seeders/20240611110210-seed-input-type.js b/apps/services/form-system/seeders/20240611110210-seed-input-type.js new file mode 100644 index 000000000000..f34df55cdfc1 --- /dev/null +++ b/apps/services/form-system/seeders/20240611110210-seed-input-type.js @@ -0,0 +1,239 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('input_types', [ + { + id: '09206657-9a89-4265-b58e-13b220f805a2', + type: 'default', + name: '{ "is": "", "en": "" }', + description: '{ "is": "", "en": "" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: 'db7ef634-3bec-4051-8370-e13315a7885e', + type: 'textbox', + name: '{ "is": "Textainnsláttur", "en": "Textbox" }', + description: + '{ "is": "Notandi slær inn texta", "en": "User enters text" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '2bd485da-08a3-4554-8ffc-f6632e6e5a84', + type: 'numberbox', + name: '{ "is": "Tölustafir", "en": "Numbers" }', + description: + '{ "is": "Notandi slær inn tölustafi", "en": "User enters numbers" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '59a38f6d-f369-4adc-8af6-9df91370073b', + type: 'message', + name: '{ "is": "Skilaboð", "en": "Message" }', + description: + '{ "is": "Skilaboð sem birtast í texta", "en": "Message that appears as text" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '25a339fb-2d16-4d7f-97c5-b9fe990e7b06', + type: 'checkbox', + name: '{ "is": "Hakbox", "en": "Checkbox" }', + description: '{ "is": "Já/nei val", "en": "Yes/no options" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '29b23a4b-f94b-406b-b169-d4254fac1c56', + type: 'datePicker', + name: '{ "is": "Dagssetning", "en": "Date picker" }', + description: + '{ "is": "Notandi velur dagssetningu úr dagatali", "en": "User chooses date from calendar" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '9c68695e-8205-41a9-a84f-7c741ac09c05', + type: 'dropdownList', + name: '{ "is": "Fellilisti", "en": "Dropdown list" }', + description: + '{ "is": "Notandi velur eitt gildi af nokkrum möguleikum úr lista", "en": "User chooses a single value from a dropdown list of options" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '75cbc28a-c13f-4f75-bd06-26dbb37ebdde', + type: 'radioButtons', + name: '{ "is": "Valhnappar", "en": "Radio buttons" }', + description: + '{ "is": "Notandi velur eitt gildi af nokkrum möguleikum", "en": "User chooses a single value from several options" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '81e61315-ce40-4619-b33a-b5a6a5019a77', + type: 'homestayNumber', + name: '{ "is": "Heimagistingarnúmer", "en": "Homestay number" }', + description: + '{ "is": "Notandi slær inn heimagistingarnúmer sitt", "en": "User enters their homestay number" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: 'bac7d3f2-9614-4173-8e60-1e9d07f24510', + type: 'homestayOverview', + name: '{ "is": "Heimagistingaryfirlit", "en": "Homestay overview" }', + description: + '{ "is": "Notandi fyllir út nýtingaryfirlit fyrir almanaksár", "en": "Users fills out their homestay overview for the calendar year" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '15a57466-0be3-451d-988d-5b807fea3459', + type: 'propertyNumber', + name: '{ "is": "Fasteignanúmer", "en": "Property number" }', + description: + '{ "is": "Notandi velur fasteign úr lista eða slær inn fasteignanúmer", "en": "User chooses property from a list or enters their property number" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '80bbf10c-0598-46a8-baea-1db4933a54da', + type: 'bankAccount', + name: '{ "is": "Bankareikningsnúmer", "en": "Bank account" }', + description: + '{ "is": "Notandi slær inn bankareikningsnúmer sitt", "en": "User enters their bank account" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '80cecd52-798d-424f-96b7-8b0a50bc70ba', + type: 'nationalId', + name: '{ "is": "Kennitala", "en": "National Id" }', + description: + '{ "is": "Notandi slær inn kennitölu sína", "en": "User enters their national Id" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '44b1c9b1-5a59-4c5f-b631-bc9695a91469', + type: 'payer', + name: '{ "is": "Greiðandi", "en": "Payer" }', + description: + '{ "is": "Notandi slær inn kennitölu greiðanda", "en": "User enters the national Id of the payer" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '2261d835-6be8-40b5-a5d9-ca39a2ba9150', + type: 'iskNumberbox', + name: '{ "is": "Krónutala", "en": "ISK number box" }', + description: + '{ "is": "Notandi slær inn krónutölu", "en": "User enters ISK number" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '8bcfe82c-9819-45a7-9172-f00301f5a0d9', + type: 'iskSumbox', + name: '{ "is": "Krónutölusamtala", "en": "ISK sum box" }', + description: + '{ "is": "Kerfið reiknar út samtölu krónutalna", "en": "The system calculates the sum of ISK number boxes" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '0ca1d057-99e2-46d4-b12a-e07af79e52d5', + type: 'email', + name: '{ "is": "Netfang", "en": "Email" }', + description: + '{ "is": "Notandi slær inn netfang", "en": "User enters email" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '5786bc16-b531-406e-83fe-511c4c39464e', + type: 'phoneNumber', + name: '{ "is": "Símanúmer", "en": "Phone number" }', + description: + '{ "is": "Notandi slær inn símanúmer", "en": "User enters phone number" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: 'ae7486cb-c434-48ce-8e8e-3f79e890ac46', + type: 'timeInput', + name: '{ "is": "Tími", "en": "time" }', + description: + '{ "is": "Notandi velur/slær inn tíma", "en": "User chooses/enters time" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '7cbbe78f-cd5f-4fb9-a77c-86af2bf986b1', + type: 'document', + name: '{ "is": "Skjal", "en": "Document" }', + description: + '{ "is": "Notandi hleður upp skjali/skjölum", "en": "User uploads file/s" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: 'c1e82fc0-e609-4503-87bd-37379e4f5d54', + type: 'payment', + name: '{ "is": "Greiðsla", "en": "Payment" }', + description: '{ "is": "Greiðsla", "en": "Payment" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '49599a07-4d06-4ad4-9927-b55eab2dd97d', + type: 'nationaIdEstate', + name: '{ "is": "Kennitala dánarbús", "en": "National Id estate" }', + description: + '{ "is": "Notandi slær inn kennitölu sem við flettum upp í gagnagrunni látinna", "en": "User enters national Id that we look up in database of deceaced" }', + is_common: false, + created: new Date(), + modified: new Date(), + }, + { + id: 'ad67a9c3-f5d9-47eb-bcf9-dd34becf4b76', + type: 'nationalIdAll', + name: '{ "is": "Kennitala allt", "en": "National Id all" }', + description: + '{ "is": "Notandi slær inn kennitölu sem við flettum upp í öllum gagnagrunnum", "en": "User enters national Id that we look up in all databases" }', + is_common: false, + created: new Date(), + modified: new Date(), + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('input_types', null, {}) + }, +} diff --git a/apps/services/form-system/seeders/20240611135450-seed-organization.js b/apps/services/form-system/seeders/20240611135450-seed-organization.js new file mode 100644 index 000000000000..0c729aa8f8ba --- /dev/null +++ b/apps/services/form-system/seeders/20240611135450-seed-organization.js @@ -0,0 +1,19 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('organizations', [ + { + id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', + name: '{ "is": "Sandbox Ísland ehf.", "en": "Sandbox Iceland ehf." }', + national_id: '5902697199', + created: new Date(), + modified: new Date(), + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('organizations', null, {}) + }, +} diff --git a/apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js b/apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js new file mode 100644 index 000000000000..c7b4d65881e7 --- /dev/null +++ b/apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js @@ -0,0 +1,26 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('organization_input_types', [ + { + id: 'b12e940e-1bd6-4180-a6eb-f620dce4e71c', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + input_type_id: '49599a07-4d06-4ad4-9927-b55eab2dd97d', // nationaIdEstate + }, + { + id: '298bdf4f-6340-46c0-b403-59ec4ae3c19b', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + input_type_id: 'ad67a9c3-f5d9-47eb-bcf9-dd34becf4b76', // nationalIdAll + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('organization_input_types', null, {}) + }, +} diff --git a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js new file mode 100644 index 000000000000..71d88d90c244 --- /dev/null +++ b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js @@ -0,0 +1,65 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('testimony_types', [ + { + id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', + testimony_type: 'estateGuardianshipCertificateStamped', + name: '{ "is": "Búsforræðisvottorð", "en": "Certificate of authority to manage an estate" }', + description: + '{ "is": "Búsforræðisvottorð með stimpli", "en": "A document stating that the party in question has custody of his estate, ie. has not been declared bankrupt." }', + created: new Date(), + modified: new Date(), + }, + { + id: '37b8a86e-5787-4007-be40-d3f7b0070cca', + testimony_type: 'estateGuardianshipCertificateUnstamped', + name: '{ "is": "Búsforræðisvottorð án stimpils", "en": "Certificate of authority to manage an estate" }', + description: + '{ "is": "Búsforræðisvottorð án stimpils", "en": "A document stating that the party in question has custody of his estate, ie. has not been declared bankrupt." }', + created: new Date(), + modified: new Date(), + }, + { + id: 'fa035b40-4324-4140-8747-d163ef645b28', + testimony_type: 'residenceCertificate', + name: '{ "is": "Búsetuvottorð", "en": "Residence certificate" }', + description: '{ "is": "Búsetuvottorð", "en": "Residence certificate" }', + created: new Date(), + modified: new Date(), + }, + { + id: '5ec5b516-a152-4761-b0e0-ba5aa4ffae61', + testimony_type: 'indebtednessCertificate', + name: '{ "is": "Skuldleysisvottorð", "en": "Certificate of indebtedness" }', + description: + '{ "is": "Skuldleysisvottorð", "en": "Certificate of indebtedness" }', + created: new Date(), + modified: new Date(), + }, + { + id: 'b3f37a69-2700-45f5-88e6-03fc09fcf6cc', + testimony_type: 'criminalRecordStamped', + name: '{ "is": "Sakavottorð", "en": "Criminal record" }', + description: + '{ "is": "Sakavottorð með stimpli", "en": "Document containing your criminal record with stamp" }', + created: new Date(), + modified: new Date(), + }, + { + id: '72127323-56f3-40ff-8ae4-68c20e80ff37', + testimony_type: 'criminalRecordUnstamped', + name: '{ "is": "Sakavottorð án stimpils", "en": "Criminal record without stamp" }', + description: + '{ "is": "Sakavottorð án stimpils", "en": "Document containing your criminal record without stamp" }', + created: new Date(), + modified: new Date(), + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('testimony_types', null, {}) + }, +} diff --git a/apps/services/form-system/sequelize.config.js b/apps/services/form-system/sequelize.config.js index 21a24d156cec..be5a80f2e1a6 100644 --- a/apps/services/form-system/sequelize.config.js +++ b/apps/services/form-system/sequelize.config.js @@ -6,6 +6,7 @@ module.exports = { database: 'form-system', host: 'localhost', dialect: 'postgres', + seederStorage: 'sequelize', }, test: { username: 'test_db', diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 9fd1ed8cbed6..4f4b2e760ab3 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -3,21 +3,29 @@ import { SequelizeModule } from '@nestjs/sequelize' import { AuthModule } from '@island.is/auth-nest-tools' import { AuditModule } from '@island.is/nest/audit' import { environment } from '../environments' -import { FormModule } from './modules/forms/form.module' +import { FormsModule } from './modules/forms/forms.module' import { SequelizeConfigService } from './sequelizeConfig.service' -import { StepModule } from './modules/steps/step.module' +import { StepsModule } from './modules/steps/steps.module' import { ProblemModule } from '@island.is/nest/problem' +import { OrganizationsModule } from './modules/organizations/organizations.module' +import { GroupsModule } from './modules/groups/groups.module' +import { InputsModule } from './modules/inputs/inputs.module' +import { LoggingModule } from '@island.is/logging' @Module({ imports: [ AuthModule.register(environment.auth), AuditModule.forRoot(environment.audit), - ProblemModule, + // ProblemModule, + LoggingModule, SequelizeModule.forRootAsync({ useClass: SequelizeConfigService, }), - FormModule, - StepModule, + OrganizationsModule, + FormsModule, + StepsModule, + GroupsModule, + InputsModule, ], }) export class AppModule {} diff --git a/apps/services/form-system/src/app/dataTypes/languageType.model.ts b/apps/services/form-system/src/app/dataTypes/languageType.model.ts index c78b5a5bfd67..077c09c9eebe 100644 --- a/apps/services/form-system/src/app/dataTypes/languageType.model.ts +++ b/apps/services/form-system/src/app/dataTypes/languageType.model.ts @@ -1,4 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' + export class LanguageType { + @ApiProperty() is!: string + + @ApiProperty() en!: string } diff --git a/apps/services/form-system/src/app/enums/applicantType.enum.ts b/apps/services/form-system/src/app/enums/applicantType.enum.ts new file mode 100644 index 000000000000..c93c74fdaa1b --- /dev/null +++ b/apps/services/form-system/src/app/enums/applicantType.enum.ts @@ -0,0 +1,8 @@ +export enum ApplicantType { + individual, + individualWithMandateFromIndividual, + individualWithMandateFromLegalEntity, + individualWithProcuration, + individualGivingMandate, + legalEntity, +} diff --git a/apps/services/form-system/src/app/enums/stepType.enum.ts b/apps/services/form-system/src/app/enums/stepType.enum.ts new file mode 100644 index 000000000000..7704cbb4caef --- /dev/null +++ b/apps/services/form-system/src/app/enums/stepType.enum.ts @@ -0,0 +1,6 @@ +export enum StepType { + premises, + parties, + input, + payment, +} diff --git a/apps/services/form-system/src/app/enums/timeInterval.enum.ts b/apps/services/form-system/src/app/enums/timeInterval.enum.ts new file mode 100644 index 000000000000..359cb2f8bec0 --- /dev/null +++ b/apps/services/form-system/src/app/enums/timeInterval.enum.ts @@ -0,0 +1,6 @@ +export enum TimeInterval { + minutely, + quarterly, + halfHourly, + hourly, +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts new file mode 100644 index 000000000000..f53a30452775 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts @@ -0,0 +1,95 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional } from 'sequelize' +import { + Column, + CreatedAt, + DataType, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { ApplicantType } from '../../../enums/applicantType.enum' + +@Table({ tableName: 'applicants' }) +export class Applicant extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.DATE, + allowNull: true, + }) + @ApiProperty() + lastLogin?: Date + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + name!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + nationalId!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + email!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + phoneNumber!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + address!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + municipality!: string + + @Column({ + type: DataType.ENUM, + allowNull: false, + values: [''], + defaultValue: ApplicantType.individual, + }) + @ApiProperty({ enum: ApplicantType }) + applicantType!: ApplicantType +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts new file mode 100644 index 000000000000..698ef2f1162d --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts @@ -0,0 +1,59 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { ApplicantType } from '../../../enums/applicantType.enum' +import { Organization } from '../../organizations/models/organization.model' +import { CreationOptional } from 'sequelize' + +@Table({ tableName: 'applicant_type_name_suggestions' }) +export class ApplicantTypeNameSuggestion extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType().toString(), + }) + @ApiProperty() + nameSuggestion!: LanguageType + + @Column({ + type: DataType.ENUM, + allowNull: false, + values: [''], + defaultValue: ApplicantType.individual, + }) + @ApiProperty({ enum: ApplicantType }) + applicantType!: ApplicantType + + @ForeignKey(() => Organization) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'organization_id', + }) + organizationId!: string +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts new file mode 100644 index 000000000000..e0c9b8da6864 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts @@ -0,0 +1,8 @@ +export const ApplicantTypes = { + individual: 'individual', + individualWithMandateFromIndividual: 'individualWithMandateFromIndividual', + individualWithMandateFromLegalEntity: 'individualWithMandateFromLegalEntity', + individualWithProcuration: 'individualWithProcuration', + individualGivingMandate: 'individualGivingMandate', + legalEntity: 'legalEntity', +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts b/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts new file mode 100644 index 000000000000..570b3ac8494d --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts @@ -0,0 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class FormApplicantDto { + @ApiProperty() + id!: string + + @ApiProperty() + applicantType!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts new file mode 100644 index 000000000000..9b6b72266878 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts @@ -0,0 +1,60 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { ApplicantType } from '../../../enums/applicantType.enum' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { Form } from '../../forms/models/form.model' +import { CreationOptional } from 'sequelize' +import { ApplicantTypes } from './applicantTypes' + +@Table({ tableName: 'form_applicants' }) +export class FormApplicant extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.ENUM, + allowNull: false, + values: Object.values(ApplicantTypes), + defaultValue: 'individual', + }) + @ApiProperty({ enum: ApplicantTypes }) + applicantType!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType().toString(), + }) + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ForeignKey(() => Form) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'form_id', + }) + formId!: string +} diff --git a/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts deleted file mode 100644 index 68f5bb3f5159..000000000000 --- a/apps/services/form-system/src/app/modules/forms/dto/form.dto.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { Step } from '../../steps/step.model' -import { ApiProperty } from '@nestjs/swagger' - -export class FormDto { - @ApiProperty() - id!: number - - @ApiProperty() - guid!: string - - @ApiProperty() - name!: string - - @ApiProperty() - invalidationDate?: Date - - @ApiProperty() - created!: Date - - @ApiProperty() - modified!: Date - - @ApiProperty() - isTranslated!: boolean - - @ApiProperty() - applicationDaysToRemove!: number - - @ApiProperty() - derivedFrom!: number - - @ApiProperty() - stopProgressOnValidatingStep!: boolean - - @ApiProperty() - completedMessage?: string - - @ApiProperty() - steps?: Step[] -} diff --git a/apps/services/form-system/src/app/modules/forms/form.module.ts b/apps/services/form-system/src/app/modules/forms/form.module.ts deleted file mode 100644 index cc43b9295f0b..000000000000 --- a/apps/services/form-system/src/app/modules/forms/form.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common' -import { FormsController } from './forms.controller' -import { FormsService } from './forms.service' -import { SequelizeModule } from '@nestjs/sequelize' -import { Form } from './form.model' - -@Module({ - imports: [SequelizeModule.forFeature([Form])], - controllers: [FormsController], - providers: [FormsService], -}) -export class FormModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 7edb470e104c..94a27dc600ef 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -8,9 +8,11 @@ import { } from '@nestjs/common' import { Documentation } from '@island.is/nest/swagger' import { FormsService } from './forms.service' -import { Form } from './form.model' +import { Form } from './models/form.model' import { ApiTags } from '@nestjs/swagger' -import { CreateFormDto } from './dto/create-form.dto' +import { CreateFormDto } from './models/dto/createForm.dto' +import { FormDto } from './models/dto/form.dto' +import { FormResponse } from './models/dto/form.response.dto' @ApiTags('forms') @Controller('forms') @@ -18,30 +20,40 @@ export class FormsController { constructor(private readonly formsService: FormsService) {} @Post() - create(@Body() createFormDto: CreateFormDto): Promise { - return this.formsService.create(createFormDto as Form) + @Documentation({ + description: 'Create new form', + response: { status: 200, type: FormDto }, + }) + async create(@Body() createFormDto: CreateFormDto): Promise { + const formDto = await this.formsService.create(createFormDto) + if (!formDto) { + throw new Error('bla') + } + return formDto } - @Get() + @Get('organization/:organizationId') @Documentation({ - description: 'Get all Forms', + description: 'Get all forms belonging to organization', response: { status: 200, type: [Form] }, }) - async findAll(): Promise { - return await this.formsService.findAll() + async findAll( + @Param('organizationId') organizationId: string, + ): Promise { + return await this.formsService.findAll(organizationId) } @Get(':id') @Documentation({ - description: 'Get Form by id', - response: { status: 200, type: Form }, + description: 'Get FormResponse by formId', + response: { status: 200, type: FormResponse }, }) - async findOne(@Param('id') id: number): Promise { - const form = await this.formsService.findOne(id) - if (!form) { + async findOne(@Param('id') id: string): Promise { + const formResponse = await this.formsService.findOne(id) + if (!formResponse) { throw new NotFoundException(`Form not found`) } - return form + return formResponse } } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts new file mode 100644 index 000000000000..bd1f5d10187d --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -0,0 +1,27 @@ +import { Module } from '@nestjs/common' +import { FormsController } from './forms.controller' +import { FormsService } from './forms.service' +import { SequelizeModule } from '@nestjs/sequelize' +import { Form } from './models/form.model' +import { FormApplicant } from '../applicants/models/formApplicant.model' +import { StepsService } from '../steps/steps.service' +import { Step } from '../steps/models/step.model' +import { Group } from '../groups/models/group.model' +import { Organization } from '../organizations/models/organization.model' +import { InputType } from '../inputs/models/inputType.model' + +@Module({ + imports: [ + SequelizeModule.forFeature([ + Form, + FormApplicant, + Step, + Group, + Organization, + InputType, + ]), + ], + controllers: [FormsController], + providers: [FormsService], +}) +export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 0567b5d435df..339f3cf4bbf8 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -1,27 +1,267 @@ -import { Injectable } from '@nestjs/common' -import { Form } from './form.model' +import { Injectable, NotFoundException } from '@nestjs/common' +import { Form } from './models/form.model' import { InjectModel } from '@nestjs/sequelize' -import { Step } from '../steps/step.model' +import { Step, StepTypes } from '../steps/models/step.model' +import { Group } from '../groups/models/group.model' +import { Input } from '../inputs/models/input.model' +import { CreateFormDto } from './models/dto/createForm.dto' +import { InputType } from '../inputs/models/inputType.model' +import { InputSettings } from '../inputs/models/inputSettings.model' +import { StepType } from '../../enums/stepType.enum' +import { LanguageType } from '../../dataTypes/languageType.model' +import { Organization } from '../organizations/models/organization.model' +import { FormDto } from './models/dto/form.dto' +import { StepDto } from '../steps/models/dto/step.dto' +import { GroupDto } from '../groups/models/dto/group.dto' +import { InputDto } from '../inputs/models/dto/input.dto' +import { FormResponse } from './models/dto/form.response.dto' +import { InputTypeDto } from '../inputs/models/dto/inputType.dto' +import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' @Injectable() export class FormsService { constructor( @InjectModel(Form) private readonly formModel: typeof Form, + @InjectModel(Step) + private readonly stepModel: typeof Step, + @InjectModel(Group) + private readonly groupModel: typeof Group, + @InjectModel(Organization) + private readonly organizationModel: typeof Organization, + @InjectModel(InputType) + private readonly inputTypeModel: typeof InputType, ) {} - async findAll(): Promise { - return await this.formModel.findAll() + async findAll(organizationId: string): Promise { + return await this.formModel.findAll({ + where: { organizationId: organizationId }, + }) } - async findOne(id: number): Promise { - const form = await this.formModel.findByPk(id, { include: [Step] }) + async findOne(id: string): Promise { + const form = await this.findById(id) - return form + if (!form) { + return null + } + // const formDto = this.setArrays(form) + + const formResponse = this.buildFormResponse(form) + + // const organizationSpecificInputTypes = + // await this.organizationModel.findByPk(form.organizationId, { + // include: [InputType], + // }) + + // console.log(organizationSpecificInputTypes) + + return formResponse + } + + async create(createFormDto: CreateFormDto): Promise { + const { organizationId } = createFormDto + + if (!organizationId) { + throw new Error('Missing organizationId') + } + + var organization = this.organizationModel.findByPk(organizationId) + if (!organization) { + throw new NotFoundException( + `Organization with id ${organizationId} not found`, + ) + } + + const newForm: Form = await this.formModel.create({ + organizationId: organizationId, + } as Form) + + try { + await this.createFormTemplate(newForm) + } catch (err) { + throw new Error(`Could not create formTemplate for form ${newForm.id}`) + } + + const form = await this.findById(newForm.id) + if (!form) { + return null + } + const formDto = this.setArrays(form) + + return formDto } - async create(form: Form): Promise { - const newForm: Form = new this.formModel(form, { include: [Step] }) - return await newForm.save() + private async findById(id: string): Promise { + return await this.formModel.findByPk(id, { + include: [ + { + model: Step, + as: 'steps', + include: [ + { + model: Group, + as: 'groups', + include: [ + { + model: Input, + as: 'inputs', + include: [ + { + model: InputSettings, + as: 'inputSettings', + }, + ], + }, + ], + }, + ], + }, + ], + }) + } + + private async buildFormResponse(form: Form): Promise { + const response: FormResponse = { + form: this.setArrays(form), + inputTypes: await this.getInputTypes(form.organizationId), + } + + return response + } + + private async getInputTypes(organizationId: string): Promise { + const commonInputTypes = await this.inputTypeModel.findAll({ + where: { isCommon: true }, + }) + const organizationSpecificInputTypes = + await this.organizationModel.findByPk(organizationId, { + include: [InputType], + }) + + const organizationInputTypes = commonInputTypes.concat( + organizationSpecificInputTypes?.organizationInputTypes as InputType[], + ) + + const inputTypesDto: InputTypeDto[] = [] + organizationInputTypes.map((inputType) => { + inputTypesDto.push({ + id: inputType.id, + type: inputType.type, + name: inputType.name, + description: inputType.description, + isCommon: inputType.isCommon, + } as InputTypeDto) + }) + + return inputTypesDto + } + + private setArrays(form: Form): FormDto { + const formDto: FormDto = { + id: form.id, + organizationId: form.organizationId, + name: form.name, + invalidationDate: form.invalidationDate, + created: form.created, + modified: form.modified, + isTranslated: form.isTranslated, + applicationDaysToRemove: form.applicationDaysToRemove, + derivedFrom: form.derivedFrom, + stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, + completedMessage: form.completedMessage, + formApplicants: [], + steps: [], + groups: [], + inputs: [], + } + + form.formApplicants?.map((applicant) => { + formDto.formApplicants?.push({ + id: applicant.id, + applicantType: applicant.applicantType, + name: applicant.name, + } as FormApplicantDto) + }) + + form.steps.map((step) => { + formDto.steps?.push({ + id: step.id, + name: step.name, + created: step.created, + modified: step.modified, + stepType: step.stepType, + displayOrder: step.displayOrder, + waitingText: step.waitingText, + isHidden: step.isHidden, + isCompleted: step.isCompleted, + callRuleset: step.callRuleset, + } as StepDto) + step.groups?.map((group) => { + formDto.groups?.push({ + id: group.id, + stepId: step.id, + name: group.name, + created: group.created, + modified: group.modified, + displayOrder: group.displayOrder, + isHidden: group.isHidden, + multiset: group.multiset, + } as GroupDto) + group.inputs?.map((input) => { + formDto.inputs?.push({ + id: input.id, + groupId: group.id, + name: input.name, + created: input.created, + modified: input.modified, + displayOrder: input.displayOrder, + description: input.description, + isHidden: input.isHidden, + isPartOfMultiset: input.isPartOfMultiset, + inputSettings: input.inputSettings, + inputType: input.inputType, + } as InputDto) + }) + }) + }) + + return formDto + } + + private async createFormTemplate(form: Form): Promise { + await this.stepModel.create({ + formId: form.id, + stepType: StepTypes.premises, + displayOrder: 0, + name: { is: 'Forsendur', en: 'Premises' }, + } as Step) + + await this.stepModel.create({ + formId: form.id, + stepType: StepTypes.parties, + displayOrder: 1, + name: { is: 'Hlutaðeigandi aðilar', en: 'Relevant parties' }, + } as Step) + + const inputStep = await this.stepModel.create({ + formId: form.id, + stepType: StepTypes.input, + displayOrder: 2, + name: { is: 'Innsláttarskref', en: 'InputStep' }, + } as Step) + + await this.stepModel.create({ + formId: form.id, + stepType: StepTypes.payment, + displayOrder: 3, + name: { is: 'Greiðsla', en: 'Payment' }, + } as Step) + + await this.groupModel.create({ + stepId: inputStep.id, + displayOrder: 0, + name: { is: 'Hópur 1', en: 'Group 1' }, + } as Group) } } diff --git a/apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts similarity index 61% rename from apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts rename to apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts index f5188ad7b43f..b1ea7e00560a 100644 --- a/apps/services/form-system/src/app/modules/forms/dto/create-form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts @@ -2,8 +2,5 @@ import { ApiProperty } from '@nestjs/swagger' export class CreateFormDto { @ApiProperty() - name!: string - - @ApiProperty() - isTranslated!: boolean + organizationId!: string } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts new file mode 100644 index 000000000000..039d0be75373 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -0,0 +1,56 @@ +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' +import { GroupDto } from '../../../groups/models/dto/group.dto' +import { Group } from '../../../groups/models/group.model' +import { InputDto } from '../../../inputs/models/dto/input.dto' +import { Input } from '../../../inputs/models/input.model' +import { StepDto } from '../../../steps/models/dto/step.dto' +import { Step } from '../../../steps/models/step.model' +import { ApiProperty } from '@nestjs/swagger' + +export class FormDto { + @ApiProperty() + id!: string + + @ApiProperty() + organizationId!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + invalidationDate?: Date + + @ApiProperty() + created!: Date + + @ApiProperty() + modified!: Date + + @ApiProperty() + isTranslated!: boolean + + @ApiProperty() + applicationDaysToRemove!: number + + @ApiProperty() + derivedFrom!: number + + @ApiProperty() + stopProgressOnValidatingStep!: boolean + + @ApiProperty({ type: LanguageType }) + completedMessage?: LanguageType + + @ApiProperty({ type: [FormApplicantDto] }) + formApplicants?: FormApplicantDto[] + + @ApiProperty({ type: [StepDto] }) + steps?: StepDto[] + + @ApiProperty({ type: [GroupDto] }) + groups?: GroupDto[] + + @ApiProperty({ type: [InputDto] }) + inputs?: InputDto[] +} diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts new file mode 100644 index 000000000000..580a8d3750e1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts @@ -0,0 +1,12 @@ +import { ApiProperty } from '@nestjs/swagger' +import { FormDto } from './form.dto' +import { InputType } from '../../../inputs/models/inputType.model' +import { InputTypeDto } from '../../../inputs/models/dto/inputType.dto' + +export class FormResponse { + @ApiProperty({ type: FormDto }) + form!: FormDto + + @ApiProperty({ type: [InputTypeDto] }) + inputTypes!: InputTypeDto[] +} diff --git a/apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/updateForm.dto.ts similarity index 50% rename from apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts rename to apps/services/form-system/src/app/modules/forms/models/dto/updateForm.dto.ts index 338e8d079bdb..83ad86db5e8f 100644 --- a/apps/services/form-system/src/app/modules/forms/dto/update-form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/updateForm.dto.ts @@ -1,4 +1,4 @@ import { OmitType } from '@nestjs/swagger' import { FormDto } from './form.dto' -export class UpdateFormDto extends OmitType(FormDto, ['id', 'guid'] as const) {} +export class UpdateFormDto extends OmitType(FormDto, ['id'] as const) {} diff --git a/apps/services/form-system/src/app/modules/forms/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts similarity index 56% rename from apps/services/form-system/src/app/modules/forms/form.model.ts rename to apps/services/form-system/src/app/modules/forms/models/form.model.ts index 192747806cef..441219c9c3fd 100644 --- a/apps/services/form-system/src/app/modules/forms/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -1,53 +1,49 @@ import { CreationOptional } from 'sequelize' import { - AutoIncrement, Column, CreatedAt, DataType, + ForeignKey, HasMany, Model, Table, UpdatedAt, } from 'sequelize-typescript' -import { Step } from '../steps/step.model' +import { Step } from '../../steps/models/step.model' import { ApiProperty } from '@nestjs/swagger' +import { Organization } from '../../organizations/models/organization.model' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { FormApplicant } from '../../applicants/models/formApplicant.model' @Table({ tableName: 'forms' }) export class Form extends Model { - @AutoIncrement - @Column({ - type: DataType.INTEGER, - primaryKey: true, - }) - @ApiProperty() - id!: CreationOptional - @Column({ type: DataType.UUID, allowNull: false, + primaryKey: true, defaultValue: DataType.UUIDV4, }) @ApiProperty() - guid!: string + id!: string @Column({ - type: DataType.STRING, + type: DataType.JSON, allowNull: false, - defaultValue: '', + defaultValue: new LanguageType(), }) - @ApiProperty() - name!: string + @ApiProperty({ type: LanguageType }) + name!: LanguageType @Column @ApiProperty() invalidationDate?: Date @CreatedAt - @ApiProperty() + @ApiProperty({ type: Date }) created!: CreationOptional @UpdatedAt - @ApiProperty() + @ApiProperty({ type: Date }) modified!: CreationOptional @Column({ @@ -81,11 +77,27 @@ export class Form extends Model { @ApiProperty() stopProgressOnValidatingStep!: boolean - @Column - @ApiProperty() - completedMessage?: string + @Column({ + type: DataType.JSON, + allowNull: true, + defaultValue: () => new LanguageType(), + }) + @ApiProperty({ type: LanguageType }) + completedMessage?: LanguageType @HasMany(() => Step) - @ApiProperty() - steps?: Step[] + @ApiProperty({ type: [Step] }) + steps!: Step[] + + @HasMany(() => FormApplicant) + @ApiProperty({ type: [FormApplicant] }) + formApplicants?: FormApplicant[] + + @ForeignKey(() => Organization) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'organization_id', + }) + organizationId!: string } diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts new file mode 100644 index 000000000000..71a0ead90678 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { GroupsController } from './groups.controller'; + +describe('GroupsController', () => { + let controller: GroupsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [GroupsController], + }).compile(); + + controller = module.get(GroupsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.ts new file mode 100644 index 000000000000..c6dd1dc6364c --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/groups.controller.ts @@ -0,0 +1,47 @@ +import { + Controller, + Post, + Get, + Body, + Param, + NotFoundException, +} from '@nestjs/common' +import { GroupsService } from './groups.service' +import { CreateGroupDto } from './models/dto/createGroup.dto' +import { Group } from './models/group.model' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' + +@ApiTags('groups') +@Controller('groups') +export class GroupsController { + constructor(private readonly groupsService: GroupsService) {} + + @Post() + create(@Body() createGroupDto: CreateGroupDto): Promise { + return this.groupsService.create(createGroupDto) + } + + @Get() + @Documentation({ + description: 'Get all Groups', + response: { status: 200, type: [Group] }, + }) + async findAll(): Promise { + return await this.groupsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Group by id', + response: { status: 200, type: Group }, + }) + async findOne(@Param('id') id: string): Promise { + const group = await this.groupsService.findOne(id) + if (!group) { + throw new NotFoundException(`Group not found`) + } + + return group + } +} diff --git a/apps/services/form-system/src/app/modules/groups/groups.module.ts b/apps/services/form-system/src/app/modules/groups/groups.module.ts new file mode 100644 index 000000000000..c07f954a7451 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/groups.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { GroupsController } from './groups.controller' +import { GroupsService } from './groups.service' +import { Group } from './models/group.model' +import { SequelizeModule } from '@nestjs/sequelize' + +@Module({ + imports: [SequelizeModule.forFeature([Group])], + controllers: [GroupsController], + providers: [GroupsService], +}) +export class GroupsModule {} diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts new file mode 100644 index 000000000000..77bd2c6237c1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { GroupsService } from './groups.service'; + +describe('GroupsService', () => { + let service: GroupsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [GroupsService], + }).compile(); + + service = module.get(GroupsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.ts b/apps/services/form-system/src/app/modules/groups/groups.service.ts new file mode 100644 index 000000000000..661e1da5ff12 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/groups.service.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@nestjs/common' +import { Group } from './models/group.model' +import { InjectModel } from '@nestjs/sequelize' +import { Input } from '../inputs/models/input.model' +import { CreateGroupDto } from './models/dto/createGroup.dto' + +@Injectable() +export class GroupsService { + constructor( + @InjectModel(Group) + private readonly groupModel: typeof Group, + ) {} + + async findAll(): Promise { + return await this.groupModel.findAll() + } + + async findOne(id: string): Promise { + const group = await this.groupModel.findByPk(id, { include: [Input] }) + + return group + } + + async create(createGroupDto: CreateGroupDto): Promise { + const group = createGroupDto as Group + const newGroup: Group = new this.groupModel(group) + return await newGroup.save() + } +} diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts new file mode 100644 index 000000000000..229726d96f34 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class CreateGroupDto { + @ApiProperty() + stepId!: string +} diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts new file mode 100644 index 000000000000..8f68a484ae9d --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts @@ -0,0 +1,28 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class GroupDto { + @ApiProperty() + id!: string + + @ApiProperty() + stepId!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: Date }) + created!: Date + + @ApiProperty({ type: Date }) + modified!: Date + + @ApiProperty() + displayOrder!: number + + @ApiProperty() + isHidden!: boolean + + @ApiProperty() + multiset!: number +} diff --git a/apps/services/form-system/src/app/modules/steps/step.model.ts b/apps/services/form-system/src/app/modules/groups/models/group.model.ts similarity index 55% rename from apps/services/form-system/src/app/modules/steps/step.model.ts rename to apps/services/form-system/src/app/modules/groups/models/group.model.ts index 80a1e3622ec2..202436c754f0 100644 --- a/apps/services/form-system/src/app/modules/steps/step.model.ts +++ b/apps/services/form-system/src/app/modules/groups/models/group.model.ts @@ -1,94 +1,79 @@ +import { ApiProperty } from '@nestjs/swagger' import { - AutoIncrement, Column, CreatedAt, DataType, ForeignKey, + HasMany, Model, Table, UpdatedAt, } from 'sequelize-typescript' +import { Step } from '../../steps/models/step.model' import { CreationOptional } from 'sequelize' -import { Form } from '../forms/form.model' -import { ApiProperty } from '@nestjs/swagger' - -@Table({ tableName: 'steps' }) -export class Step extends Model { - @AutoIncrement - @Column({ - type: DataType.INTEGER, - primaryKey: true, - }) - @ApiProperty() - id!: CreationOptional +import { Input } from '../../inputs/models/input.model' +import { LanguageType } from '../../../dataTypes/languageType.model' +@Table({ tableName: 'groups' }) +export class Group extends Model { @Column({ type: DataType.UUID, allowNull: false, + primaryKey: true, defaultValue: DataType.UUIDV4, }) @ApiProperty() - guid!: string + id!: string @Column({ - type: DataType.STRING, + type: DataType.JSON, allowNull: false, - defaultValue: '', + defaultValue: () => new LanguageType(), }) @ApiProperty() - name!: string + name!: LanguageType @CreatedAt - @ApiProperty() + @ApiProperty({ type: Date }) created!: CreationOptional @UpdatedAt - @ApiProperty() + @ApiProperty({ type: Date }) modified!: CreationOptional - @Column({ - type: DataType.STRING, - allowNull: false, - defaultValue: 'input', - }) - type!: string - @Column({ type: DataType.INTEGER, allowNull: false, defaultValue: 0, }) + @ApiProperty() displayOrder!: number - @Column({ - type: DataType.STRING, - allowNull: true, - defaultValue: '', - }) - waitingText?: string - @Column({ type: DataType.BOOLEAN, allowNull: false, defaultValue: false, }) + @ApiProperty() isHidden!: boolean @Column({ - type: DataType.BOOLEAN, + type: DataType.INTEGER, allowNull: false, - defaultValue: false, + defaultValue: 0, }) - callRuleset!: boolean + @ApiProperty() + multiset!: number + + @HasMany(() => Input) + @ApiProperty({ type: [Input] }) + inputs?: Input[] + @ForeignKey(() => Step) @Column({ - type: DataType.BOOLEAN, + type: DataType.STRING, allowNull: false, - defaultValue: false, + field: 'step_id', }) - isCompleted!: boolean - - @ForeignKey(() => Form) - @Column({ type: DataType.INTEGER, allowNull: false, field: 'form_id' }) - formId!: number + stepId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts new file mode 100644 index 000000000000..66d74026a461 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { InputsController } from './inputs.controller'; + +describe('InputsController', () => { + let controller: InputsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [InputsController], + }).compile(); + + controller = module.get(InputsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts new file mode 100644 index 000000000000..44b637393ea1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts @@ -0,0 +1,47 @@ +import { + Body, + Controller, + Get, + NotFoundException, + Param, + Post, +} from '@nestjs/common' +import { InputsService } from './inputs.service' +import { Input } from './models/input.model' +import { CreateInputDto } from './models/dto/createInput.dto' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' + +@ApiTags('inputs') +@Controller('inputs') +export class InputsController { + constructor(private readonly inputsService: InputsService) {} + + @Post() + create(@Body() createInputDto: CreateInputDto): Promise { + return this.inputsService.create(createInputDto) + } + + @Get() + @Documentation({ + description: 'Get all Inputs', + response: { status: 200, type: [Input] }, + }) + async findAll(): Promise { + return await this.inputsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Input by id', + response: { status: 200, type: Input }, + }) + async findOne(@Param('id') id: string): Promise { + const input = await this.inputsService.findOne(id) + if (!input) { + throw new NotFoundException(`Input not found`) + } + + return input + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts new file mode 100644 index 000000000000..45c123aabc0b --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common' +import { InputsController } from './inputs.controller' +import { InputsService } from './inputs.service' +import { Input } from './models/input.model' +import { SequelizeModule } from '@nestjs/sequelize' +import { InputType } from './models/inputType.model' +import { InputSettings } from './models/inputSettings.model' + +@Module({ + imports: [SequelizeModule.forFeature([Input, InputType, InputSettings])], + controllers: [InputsController], + providers: [InputsService], +}) +export class InputsModule {} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts new file mode 100644 index 000000000000..92179dd23402 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { InputsService } from './inputs.service'; + +describe('InputsService', () => { + let service: InputsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [InputsService], + }).compile(); + + service = module.get(InputsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts new file mode 100644 index 000000000000..a3a1abcb4d35 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@nestjs/common' +import { Input } from './models/input.model' +import { CreateInputDto } from './models/dto/createInput.dto' +import { InjectModel } from '@nestjs/sequelize' + +@Injectable() +export class InputsService { + constructor( + @InjectModel(Input) + private readonly inputModel: typeof Input, + ) {} + + async findAll(): Promise { + return await this.inputModel.findAll() + } + + async findOne(id: string): Promise { + const input = await this.inputModel.findByPk(id) + + return input + } + + async create(createInputDto: CreateInputDto): Promise { + const input = createInputDto as Input + const newInput: Input = new this.inputModel(input) + return await newInput.save() + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts new file mode 100644 index 000000000000..96b30cf6a6f4 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { InputType } from '../inputType.model' + +export class CreateInputDto { + @ApiProperty() + groupId!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts new file mode 100644 index 000000000000..490bb3f0944a --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts @@ -0,0 +1,39 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { InputSettings } from '../inputSettings.model' +import { InputType } from '../inputType.model' + +export class InputDto { + @ApiProperty() + id!: string + + @ApiProperty() + groupId!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: Date }) + created!: Date + + @ApiProperty({ type: Date }) + modified!: Date + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + isHidden!: boolean + + @ApiProperty() + isPartOfMultiset!: boolean + + @ApiProperty({ type: InputSettings }) + inputSettings?: InputSettings + + @ApiProperty() + inputType!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts new file mode 100644 index 000000000000..559a2ebd7197 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts @@ -0,0 +1,19 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class InputTypeDto { + @ApiProperty() + id!: string + + @ApiProperty() + type!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + isCommon!: boolean +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts new file mode 100644 index 000000000000..7647d73352b2 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts @@ -0,0 +1,98 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional } from 'sequelize' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + HasOne, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Group } from '../../groups/models/group.model' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { InputType } from './inputType.model' +import { InputSettings } from './inputSettings.model' + +@Table({ tableName: 'inputs' }) +export class Input extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + name!: LanguageType + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + @ApiProperty() + displayOrder!: number + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + description!: LanguageType + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isHidden!: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isPartOfMultiset!: boolean + + @ForeignKey(() => Group) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'group_id', + }) + groupId!: string + + @HasOne(() => InputSettings) + @ApiProperty({ type: InputSettings }) + inputSettings?: InputSettings + + @ForeignKey(() => InputType) + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: 'default', + field: 'input_type', + }) + @ApiProperty() + inputType!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts b/apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts new file mode 100644 index 000000000000..045f861a9677 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts @@ -0,0 +1,177 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional } from 'sequelize' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + HasMany, + HasOne, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Input } from './input.model' +import { TimeInterval } from '../../../enums/timeInterval.enum' + +@Table({ tableName: 'input_settings' }) +export class InputSettings extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + minValue?: number + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + maxValue?: number + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + minLength?: number + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + maxLength?: number + + @Column({ + type: DataType.DATE, + allowNull: true, + }) + @ApiProperty() + minDate?: Date + + @Column({ + type: DataType.DATE, + allowNull: true, + }) + @ApiProperty() + maxDate?: Date + + @Column({ + type: DataType.STRING, + allowNull: true, + }) + @ApiProperty() + minAmount?: string + + @Column({ + type: DataType.STRING, + allowNull: true, + }) + @ApiProperty() + maxAmount?: string + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + year?: number + + @Column({ + type: DataType.BOOLEAN, + allowNull: true, + }) + @ApiProperty() + hasLink?: boolean + + @Column({ + type: DataType.STRING, + allowNull: true, + }) + @ApiProperty() + url?: string + + @Column({ + type: DataType.STRING, + allowNull: true, + }) + @ApiProperty() + buttonText?: string + + @Column({ + type: DataType.BOOLEAN, + allowNull: true, + }) + @ApiProperty() + hasPropertyInput?: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: true, + }) + @ApiProperty() + hasPropertyList?: boolean + + @Column({ + type: DataType.JSON, + allowNull: true, + }) + @ApiProperty() + list?: string + + @Column({ + type: DataType.JSON, + allowNull: true, + }) + @ApiProperty() + fileTypes?: string + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + fileMaxSize?: number + + @Column({ + type: DataType.INTEGER, + allowNull: true, + }) + @ApiProperty() + maxFiles?: number + + @Column({ + type: DataType.ENUM, + allowNull: true, + values: ['minutely', 'quarterly', 'halfHourly', 'hourly'], + }) + @ApiProperty({ enum: TimeInterval }) + timeInterval?: TimeInterval + + @ForeignKey(() => Input) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'input_id', + }) + inputId!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts b/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts new file mode 100644 index 000000000000..13931e4e683f --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts @@ -0,0 +1,79 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + BelongsToMany, + Column, + CreatedAt, + DataType, + ForeignKey, + HasMany, + HasOne, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { CreationOptional, NonAttribute } from 'sequelize' +import { Input } from './input.model' +import { Organization } from '../../organizations/models/organization.model' + +@Table({ tableName: 'input_types' }) +export class InputType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.STRING, + allowNull: false, + unique: true, + }) + @ApiProperty() + type!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isCommon!: boolean + + @HasMany(() => Input) + inputs?: Input[] + + @BelongsToMany(() => Organization, { + through: 'organization_input_types', + foreignKey: 'input_type_id', + otherKey: 'organization_id', + }) + organizations?: NonAttribute +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts new file mode 100644 index 000000000000..5d51ca13beec --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts @@ -0,0 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class CreateOrganizationDto { + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + nationalId!: string +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts new file mode 100644 index 000000000000..c6e1064ca236 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts @@ -0,0 +1,4 @@ +import { OmitType } from '@nestjs/swagger' +import { Organization } from '../organization.model' + +export class OrganizationDto extends OmitType(Organization, ['id'] as const) {} diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts new file mode 100644 index 000000000000..57cea87f01e0 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -0,0 +1,79 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional, NonAttribute, UUID, UUIDV4 } from 'sequelize' +import { + BelongsToMany, + Column, + CreatedAt, + DataType, + HasMany, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Form } from '../../forms/models/form.model' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { ApplicantTypeNameSuggestion } from '../../applicants/models/applicantTypeNameSuggestion.model' +import { InputType } from '../../inputs/models/inputType.model' + +@Table({ tableName: 'organizations' }) +export class Organization extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + name!: LanguageType + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + @ApiProperty() + nationalId!: string + + @HasMany(() => Form) + @ApiProperty({ type: [Form] }) + forms?: Form[] + + @HasMany(() => ApplicantTypeNameSuggestion) + @ApiProperty({ type: [ApplicantTypeNameSuggestion] }) + applicantTypeNameSuggestions?: ApplicantTypeNameSuggestion[] + + @BelongsToMany(() => InputType, { + through: 'organization_input_types', + foreignKey: 'organization_id', + otherKey: 'input_type_id', + }) + organizationInputTypes?: NonAttribute + + // @HasMany(() => InputType) + // @ApiProperty() + // inputTypes?: InputType[] + + // @HasMany(() => DocumentType) + // @ApiProperty() + // documentTypes?: DocumentType[] + + // @HasMany(() => ListType) + // @ApiProperty() + // listTypes?: ListType[] +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts new file mode 100644 index 000000000000..c96d4676bbc4 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts @@ -0,0 +1,45 @@ +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Organization } from './organization.model' +import { InputType } from '../../inputs/models/inputType.model' +import { CreationOptional } from 'sequelize' + +@Table({ tableName: 'organization_input_types' }) +export class OrganizationInputType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + id!: string + + @CreatedAt + created!: CreationOptional + + @UpdatedAt + modified!: CreationOptional + + @ForeignKey(() => Organization) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'organization_id', + }) + organizationId!: string + + @ForeignKey(() => InputType) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'input_type_id', + }) + inputTypeId!: string +} diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts new file mode 100644 index 000000000000..dbf544f27c11 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrganizationsController } from './organizations.controller'; + +describe('OrganizationsController', () => { + let controller: OrganizationsController; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + controllers: [OrganizationsController], + }).compile(); + + controller = module.get(OrganizationsController); + }); + + it('should be defined', () => { + expect(controller).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts b/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts new file mode 100644 index 000000000000..130f79fd3cc7 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts @@ -0,0 +1,49 @@ +import { + Body, + Controller, + Post, + Get, + Param, + NotFoundException, +} from '@nestjs/common' +import { ApiTags } from '@nestjs/swagger' +import { OrganizationsService } from './organizations.service' +import { Organization } from './models/organization.model' +import { CreateOrganizationDto } from './models/dto/createOrganization.dto' +import { Documentation } from '@island.is/nest/swagger' + +@ApiTags('organizations') +@Controller('organizations') +export class OrganizationsController { + constructor(private readonly organizationsService: OrganizationsService) {} + + @Post() + create( + @Body() createOrganizationDto: CreateOrganizationDto, + ): Promise { + return this.organizationsService.create(createOrganizationDto) + } + + @Get() + @Documentation({ + description: 'Get all Organizations', + response: { status: 200, type: [Organization] }, + }) + async findAll(): Promise { + return await this.organizationsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Organization by id', + response: { status: 200, type: Organization }, + }) + async findOne(@Param('id') id: string): Promise { + const form = await this.organizationsService.findOne(id) + if (!form) { + throw new NotFoundException(`Organization not found`) + } + + return form + } +} diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.module.ts b/apps/services/form-system/src/app/modules/organizations/organizations.module.ts new file mode 100644 index 000000000000..a643ead2d87a --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/organizations.module.ts @@ -0,0 +1,15 @@ +import { Module } from '@nestjs/common' +import { OrganizationsController } from './organizations.controller' +import { OrganizationsService } from './organizations.service' +import { SequelizeModule } from '@nestjs/sequelize' +import { Organization } from './models/organization.model' +import { ApplicantTypeNameSuggestion } from '../applicants/models/applicantTypeNameSuggestion.model' + +@Module({ + imports: [ + SequelizeModule.forFeature([Organization, ApplicantTypeNameSuggestion]), + ], + controllers: [OrganizationsController], + providers: [OrganizationsService], +}) +export class OrganizationsModule {} diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts new file mode 100644 index 000000000000..c36588712703 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { OrganizationsService } from './organizations.service'; + +describe('OrganizationsService', () => { + let service: OrganizationsService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [OrganizationsService], + }).compile(); + + service = module.get(OrganizationsService); + }); + + it('should be defined', () => { + expect(service).toBeDefined(); + }); +}); diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.service.ts b/apps/services/form-system/src/app/modules/organizations/organizations.service.ts new file mode 100644 index 000000000000..2a7558d61706 --- /dev/null +++ b/apps/services/form-system/src/app/modules/organizations/organizations.service.ts @@ -0,0 +1,42 @@ +import { Injectable } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { Organization } from './models/organization.model' +import { Form } from '../forms/models/form.model' +import { CreateOrganizationDto } from './models/dto/createOrganization.dto' +import { InputType } from '../inputs/models/inputType.model' + +@Injectable() +export class OrganizationsService { + constructor( + @InjectModel(Organization) + private readonly organizationModel: typeof Organization, // @InjectModel(InputType) + ) // private readonly inputTypeModel: typeof InputType, + {} + + async findAll(): Promise { + return await this.organizationModel.findAll() + } + + async findOne(id: string): Promise { + const form = await this.organizationModel.findByPk(id, { include: [Form] }) + + return form + } + + async create( + createOrganizationDto: CreateOrganizationDto, + ): Promise { + const organization = createOrganizationDto as Organization + const newOrganzation: Organization = new this.organizationModel( + organization, + ) + return await newOrganzation.save() + } + + // async findInputTypes(organizationId: string): Promise { + // const commons = await this.inputTypeModel.findAll({ + // where: { isCommon: true }, + // }) + // return commons + // } +} diff --git a/apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts similarity index 84% rename from apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts rename to apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts index 3ad79872858f..9f54575fd828 100644 --- a/apps/services/form-system/src/app/modules/steps/dto/create-step.dto.ts +++ b/apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts @@ -2,5 +2,5 @@ import { ApiProperty } from '@nestjs/swagger' export class CreateStepDto { @ApiProperty() - formId!: number + formId!: string } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts new file mode 100644 index 000000000000..b018b4db2b8f --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts @@ -0,0 +1,34 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class StepDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: Date }) + created!: Date + + @ApiProperty({ type: Date }) + modified!: Date + + @ApiProperty() + stepType!: string + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + waitingText?: LanguageType + + @ApiProperty() + isHidden!: boolean + + @ApiProperty() + callRuleset!: boolean + + @ApiProperty() + isCompleted!: boolean +} diff --git a/apps/services/form-system/src/app/modules/steps/models/step.model.ts b/apps/services/form-system/src/app/modules/steps/models/step.model.ts new file mode 100644 index 000000000000..fdeddcfdec7f --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/step.model.ts @@ -0,0 +1,108 @@ +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, + HasMany, + Sequelize, +} from 'sequelize-typescript' +import { CreationOptional, DataTypes } from 'sequelize' +import { Form } from '../../forms/models/form.model' +import { ApiProperty } from '@nestjs/swagger' +import { Group } from '../../groups/models/group.model' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { StepType } from '../../../enums/stepType.enum' + +export const StepTypes = { + premises: 'premises', + parties: 'parties', + input: 'input', + payment: 'payment', +} + +@Table({ tableName: 'steps' }) +export class Step extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + name!: LanguageType + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataTypes.ENUM, + allowNull: false, + values: Object.values(StepTypes), + }) + @ApiProperty({ enum: StepTypes }) + stepType!: string + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + @ApiProperty() + displayOrder!: number + + @Column({ + type: DataType.JSON, + allowNull: true, + defaultValue: () => new LanguageType(), + }) + @ApiProperty({ type: LanguageType }) + waitingText?: LanguageType + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isHidden!: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + callRuleset!: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isCompleted!: boolean + + @HasMany(() => Group) + @ApiProperty({ type: [Group] }) + groups?: Group[] + + @ForeignKey(() => Form) + @Column({ type: DataType.STRING, allowNull: false, field: 'form_id' }) + formId!: string +} diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts index d17b1e8a5b31..0ee8cc4bd298 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts @@ -1,18 +1,27 @@ import { Test, TestingModule } from '@nestjs/testing' +import { TestApp, testServer, useDatabase } from '@island.is/testing/nest' import { StepsController } from './steps.controller' +import { StepsModule } from './steps.module' +import { StepsService } from './steps.service' +import { Step } from './models/step.model' +import { SequelizeModule } from '@nestjs/sequelize' +import { SequelizeConfigService } from '../../sequelizeConfig.service' describe('StepsController', () => { let controller: StepsController + let app: TestApp beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [StepsController], - }).compile() - - controller = module.get(StepsController) + app = await testServer({ + appModule: StepsModule, + hooks: [ + useDatabase({ type: 'postgres', provider: SequelizeConfigService }), + ], + }) + controller = app.get(StepsController) }) - it('should be defined', () => { - expect(controller).toBeDefined() + it('should run', () => { + expect(true).toBeTruthy }) }) diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.ts index 01738233755b..b6ce4eb783ea 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.ts @@ -1,8 +1,18 @@ -import { Body, Controller, Post } from '@nestjs/common' +import { + Body, + Controller, + Post, + Get, + Param, + NotFoundException, +} from '@nestjs/common' import { StepsService } from './steps.service' -import { CreateStepDto } from './dto/create-step.dto' -import { Step } from './step.model' +import { CreateStepDto } from './models/dto/createStep.dto' +import { Step } from './models/step.model' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' +@ApiTags('steps') @Controller('steps') export class StepsController { constructor(private readonly stepsService: StepsService) {} @@ -11,4 +21,27 @@ export class StepsController { create(@Body() createStepDto: CreateStepDto): Promise { return this.stepsService.create(createStepDto) } + + @Get() + @Documentation({ + description: 'Get all Steps', + response: { status: 200, type: [Step] }, + }) + async findAll(): Promise { + return await this.stepsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Step by id', + response: { status: 200, type: Step }, + }) + async findOne(@Param('id') id: string): Promise { + const step = await this.stepsService.findOne(id) + if (!step) { + throw new NotFoundException(`Step not found`) + } + + return step + } } diff --git a/apps/services/form-system/src/app/modules/steps/step.module.ts b/apps/services/form-system/src/app/modules/steps/steps.module.ts similarity index 76% rename from apps/services/form-system/src/app/modules/steps/step.module.ts rename to apps/services/form-system/src/app/modules/steps/steps.module.ts index a1f6b6baac37..7b0c35abc238 100644 --- a/apps/services/form-system/src/app/modules/steps/step.module.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.module.ts @@ -2,11 +2,12 @@ import { Module } from '@nestjs/common' import { StepsController } from './steps.controller' import { StepsService } from './steps.service' import { SequelizeModule } from '@nestjs/sequelize' -import { Step } from './step.model' +import { Step } from './models/step.model' @Module({ imports: [SequelizeModule.forFeature([Step])], controllers: [StepsController], providers: [StepsService], + exports: [StepsService], }) -export class StepModule {} +export class StepsModule {} diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.ts b/apps/services/form-system/src/app/modules/steps/steps.service.ts index 5996b0a4ccba..dfdb86e75052 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.service.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.service.ts @@ -1,7 +1,9 @@ import { Injectable } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' -import { Step } from './step.model' -import { CreateStepDto } from './dto/create-step.dto' +import { Step } from './models/step.model' +import { CreateStepDto } from './models/dto/createStep.dto' +import { Group } from '../groups/models/group.model' +import { Input } from '../inputs/models/input.model' @Injectable() export class StepsService { @@ -10,6 +12,24 @@ export class StepsService { private readonly stepModel: typeof Step, ) {} + async findAll(): Promise { + return await this.stepModel.findAll() + } + + async findOne(id: string): Promise { + const step = await this.stepModel.findByPk(id, { + include: [ + { + model: Group, + as: 'groups', + include: [{ model: Input, as: 'inputs' }], + }, + ], + }) + + return step + } + async create(createStepDto: CreateStepDto): Promise { const step = createStepDto as Step const newStep: Step = new this.stepModel(step) diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts new file mode 100644 index 000000000000..de57f880bd8e --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts @@ -0,0 +1,56 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + Column, + CreatedAt, + DataType, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { CreationOptional, DataTypes } from 'sequelize' +import { TestimonyTypes } from './testimonyTypes' + +@Table({ tableName: 'testimony_types' }) +export class TestimonyType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + name!: LanguageType + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + description!: LanguageType + + @Column({ + type: DataTypes.ENUM, + allowNull: false, + values: Object.values(TestimonyTypes), + }) + @ApiProperty({ enum: TestimonyTypes }) + testimonyType!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional +} diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts new file mode 100644 index 000000000000..20c50cf7ecda --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts @@ -0,0 +1,9 @@ +export const TestimonyTypes = { + estateGuardianshipCertificateStamped: 'estateGuardianshipCertificateStamped', + estateGuardianshipCertificateUnstamped: + 'estateGuardianshipCertificateUnstamped', + residenceCertificate: 'residenceCertificate', + indebtednessCertificate: 'indebtednessCertificate', + criminalRecordStamped: 'criminalRecordStamped', + criminalRecordUnstamped: 'criminalRecordUnstamped', +} From 24eca05614c354f28139b7f3ff6beabb1a8ec10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 21 Jun 2024 12:06:32 +0000 Subject: [PATCH 38/72] =?UTF-8?q?helstu=20m=C3=B3del,=20services=20og=20co?= =?UTF-8?q?ntrollerar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migrations/20240605120342-create-step.js | 1 + .../migrations/20240605122019-create-group.js | 1 + .../migrations/20240611122625-create-input.js | 1 + .../20240614131225-create-testimony-type.js | 2 +- ...2442-create-organization-testimony-type.js | 54 +++++++ ...240614152811-create-form-testimony-type.js | 54 +++++++ .../20240614162737-create-list-type.js | 59 +++++++ ...614162758-create-organization-list-type.js | 54 +++++++ .../20240614132148-seed-testimony-type.js | 12 +- ...142713-seed-organization-testimony-type.js | 54 +++++++ .../seeders/20240614162836-seed-list-type.js | 62 ++++++++ ...40614162853-seed-organization-list-type.js | 26 ++++ .../form-system/src/app/app.module.ts | 6 + .../src/app/dataTypes/listItem.model.ts | 22 +++ .../src/app/enums/applicantType.enum.ts | 8 - .../src/app/enums/applicantTypes.ts | 10 ++ .../src/app/enums/stepType.enum.ts | 6 - .../form-system/src/app/enums/stepTypes.ts | 6 + .../src/app/enums/timeInterval.enum.ts | 6 - .../src/app/enums/timeIntervals.ts | 6 + .../applicants/models/applicant.model.ts | 10 +- .../applicantTypeNameSuggestion.model.ts | 10 +- .../applicants/models/applicantTypes.ts | 8 - .../applicants/models/formApplicant.model.ts | 3 +- .../src/app/modules/forms/forms.controller.ts | 18 ++- .../src/app/modules/forms/forms.module.ts | 7 +- .../src/app/modules/forms/forms.service.ts | 146 ++++++++++++++---- .../app/modules/forms/models/dto/form.dto.ts | 6 +- .../forms/models/dto/form.response.dto.ts | 9 ++ .../app/modules/forms/models/form.model.ts | 13 +- .../app/modules/groups/groups.controller.ts | 17 ++ .../src/app/modules/groups/groups.service.ts | 35 ++++- .../modules/groups/models/dto/group.dto.ts | 9 -- .../groups/models/dto/updateGroup.dto.ts | 13 ++ .../inputSettings/inputSettings.module.ts | 12 ++ .../inputSettings.service.spec.ts | 18 +++ .../inputSettings/inputSettings.service.ts | 60 +++++++ .../models/dto/inputSettings.dto.ts | 110 +++++++++++++ .../models/dto/updateInputSettings.dto.ts | 60 +++++++ .../models/inputSettings.mapper.ts | 113 ++++++++++++++ .../models/inputSettings.model.ts | 46 +++--- .../app/modules/inputs/inputs.controller.ts | 23 ++- .../src/app/modules/inputs/inputs.module.ts | 13 +- .../src/app/modules/inputs/inputs.service.ts | 69 ++++++++- .../modules/inputs/models/dto/input.dto.ts | 19 +-- .../inputs/models/dto/inputType.dto.ts | 4 + .../inputs/models/dto/updateInput.dto.ts | 25 +++ .../app/modules/inputs/models/input.mapper.ts | 37 +++++ .../app/modules/inputs/models/input.model.ts | 2 +- .../src/app/modules/lists/lists.module.ts | 9 ++ .../modules/lists/models/dto/listType.dto.ts | 19 +++ .../modules/lists/models/listType.model.ts | 73 +++++++++ .../src/app/modules/lists/models/listTypes.ts | 7 + .../models/organizationListType.model.ts | 46 ++++++ .../models/organization.model.ts | 24 +-- .../app/modules/steps/models/dto/step.dto.ts | 12 -- .../steps/models/dto/updateStep.dto.ts | 16 ++ .../app/modules/steps/models/step.model.ts | 9 +- .../src/app/modules/steps/steps.controller.ts | 17 ++ .../src/app/modules/steps/steps.service.ts | 38 ++++- .../testimonies/dto/formTestimonyType.dto.ts | 16 ++ .../testimonies/dto/testimonyType.dto.ts | 16 ++ .../models/formTestimonyType.model.ts | 46 ++++++ .../models/organizationTestimonyType.model.ts | 46 ++++++ .../testimonies/models/testimonyType.model.ts | 21 ++- .../modules/testimonies/testimonies.module.ts | 11 ++ 66 files changed, 1609 insertions(+), 182 deletions(-) create mode 100644 apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js create mode 100644 apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js create mode 100644 apps/services/form-system/migrations/20240614162737-create-list-type.js create mode 100644 apps/services/form-system/migrations/20240614162758-create-organization-list-type.js create mode 100644 apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js create mode 100644 apps/services/form-system/seeders/20240614162836-seed-list-type.js create mode 100644 apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js create mode 100644 apps/services/form-system/src/app/dataTypes/listItem.model.ts delete mode 100644 apps/services/form-system/src/app/enums/applicantType.enum.ts create mode 100644 apps/services/form-system/src/app/enums/applicantTypes.ts delete mode 100644 apps/services/form-system/src/app/enums/stepType.enum.ts create mode 100644 apps/services/form-system/src/app/enums/stepTypes.ts delete mode 100644 apps/services/form-system/src/app/enums/timeInterval.enum.ts create mode 100644 apps/services/form-system/src/app/enums/timeIntervals.ts delete mode 100644 apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts rename apps/services/form-system/src/app/modules/{inputs => inputSettings}/models/inputSettings.model.ts (76%) create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts create mode 100644 apps/services/form-system/src/app/modules/lists/lists.module.ts create mode 100644 apps/services/form-system/src/app/modules/lists/models/dto/listType.dto.ts create mode 100644 apps/services/form-system/src/app/modules/lists/models/listType.model.ts create mode 100644 apps/services/form-system/src/app/modules/lists/models/listTypes.ts create mode 100644 apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts create mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts create mode 100644 apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts diff --git a/apps/services/form-system/migrations/20240605120342-create-step.js b/apps/services/form-system/migrations/20240605120342-create-step.js index 909be6a52c3c..cc0c3eebd758 100644 --- a/apps/services/form-system/migrations/20240605120342-create-step.js +++ b/apps/services/form-system/migrations/20240605120342-create-step.js @@ -61,6 +61,7 @@ module.exports = { }, form_id: { type: Sequelize.UUID, + onDelete: 'CASCADE', allowNull: false, references: { model: 'forms', diff --git a/apps/services/form-system/migrations/20240605122019-create-group.js b/apps/services/form-system/migrations/20240605122019-create-group.js index f8c071e0a9de..f746bfa18520 100644 --- a/apps/services/form-system/migrations/20240605122019-create-group.js +++ b/apps/services/form-system/migrations/20240605122019-create-group.js @@ -41,6 +41,7 @@ module.exports = { }, step_id: { type: Sequelize.UUID, + onDelete: 'CASCADE', allowNull: false, references: { model: 'steps', diff --git a/apps/services/form-system/migrations/20240611122625-create-input.js b/apps/services/form-system/migrations/20240611122625-create-input.js index 10b4e8d699a1..1d97cef0d907 100644 --- a/apps/services/form-system/migrations/20240611122625-create-input.js +++ b/apps/services/form-system/migrations/20240611122625-create-input.js @@ -46,6 +46,7 @@ module.exports = { }, group_id: { type: Sequelize.UUID, + onDelete: 'CASCADE', allowNull: false, references: { model: 'groups', diff --git a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js index 4d3b2852dff8..bad99ef62228 100644 --- a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js +++ b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js @@ -30,7 +30,7 @@ module.exports = { defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), allowNull: false, }, - testimony_type: { + type: { type: Sequelize.DataTypes.ENUM( 'estateGuardianshipCertificateStamped', 'estateGuardianshipCertificateUnstamped', diff --git a/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js b/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js new file mode 100644 index 000000000000..2ee302e54d88 --- /dev/null +++ b/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js @@ -0,0 +1,54 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'organization_testimony_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + organization_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'organizations', + key: 'id', + }, + }, + testimony_type_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'testimony_types', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('organization_testimony_types', { + transaction: t, + }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js b/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js new file mode 100644 index 000000000000..535de0e5e5b5 --- /dev/null +++ b/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js @@ -0,0 +1,54 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'form_testimony_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + form_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'forms', + key: 'id', + }, + }, + testimony_type_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'testimony_types', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('form_testimony_types', { + transaction: t, + }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240614162737-create-list-type.js b/apps/services/form-system/migrations/20240614162737-create-list-type.js new file mode 100644 index 000000000000..18bc8e2ea907 --- /dev/null +++ b/apps/services/form-system/migrations/20240614162737-create-list-type.js @@ -0,0 +1,59 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'list_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + name: { + type: Sequelize.JSON, + allowNull: false, + }, + description: { + type: Sequelize.JSON, + allowNull: false, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + is_common: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + type: { + type: Sequelize.DataTypes.ENUM( + 'municipalities', + 'countries', + 'postalCodes', + 'mastersTrades', + 'registrationCategoriesOfActivities', + ), + allowNull: false, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('list_types', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js b/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js new file mode 100644 index 000000000000..9fb0d79743af --- /dev/null +++ b/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js @@ -0,0 +1,54 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'organization_list_types', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + organization_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'organizations', + key: 'id', + }, + }, + list_type_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'list_types', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('organization_list_types', { + transaction: t, + }), + ) + }, +} diff --git a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js index 71d88d90c244..2b84e8ca2593 100644 --- a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js +++ b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js @@ -5,7 +5,7 @@ module.exports = { await queryInterface.bulkInsert('testimony_types', [ { id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', - testimony_type: 'estateGuardianshipCertificateStamped', + type: 'estateGuardianshipCertificateStamped', name: '{ "is": "Búsforræðisvottorð", "en": "Certificate of authority to manage an estate" }', description: '{ "is": "Búsforræðisvottorð með stimpli", "en": "A document stating that the party in question has custody of his estate, ie. has not been declared bankrupt." }', @@ -14,7 +14,7 @@ module.exports = { }, { id: '37b8a86e-5787-4007-be40-d3f7b0070cca', - testimony_type: 'estateGuardianshipCertificateUnstamped', + type: 'estateGuardianshipCertificateUnstamped', name: '{ "is": "Búsforræðisvottorð án stimpils", "en": "Certificate of authority to manage an estate" }', description: '{ "is": "Búsforræðisvottorð án stimpils", "en": "A document stating that the party in question has custody of his estate, ie. has not been declared bankrupt." }', @@ -23,7 +23,7 @@ module.exports = { }, { id: 'fa035b40-4324-4140-8747-d163ef645b28', - testimony_type: 'residenceCertificate', + type: 'residenceCertificate', name: '{ "is": "Búsetuvottorð", "en": "Residence certificate" }', description: '{ "is": "Búsetuvottorð", "en": "Residence certificate" }', created: new Date(), @@ -31,7 +31,7 @@ module.exports = { }, { id: '5ec5b516-a152-4761-b0e0-ba5aa4ffae61', - testimony_type: 'indebtednessCertificate', + type: 'indebtednessCertificate', name: '{ "is": "Skuldleysisvottorð", "en": "Certificate of indebtedness" }', description: '{ "is": "Skuldleysisvottorð", "en": "Certificate of indebtedness" }', @@ -40,7 +40,7 @@ module.exports = { }, { id: 'b3f37a69-2700-45f5-88e6-03fc09fcf6cc', - testimony_type: 'criminalRecordStamped', + type: 'criminalRecordStamped', name: '{ "is": "Sakavottorð", "en": "Criminal record" }', description: '{ "is": "Sakavottorð með stimpli", "en": "Document containing your criminal record with stamp" }', @@ -49,7 +49,7 @@ module.exports = { }, { id: '72127323-56f3-40ff-8ae4-68c20e80ff37', - testimony_type: 'criminalRecordUnstamped', + type: 'criminalRecordUnstamped', name: '{ "is": "Sakavottorð án stimpils", "en": "Criminal record without stamp" }', description: '{ "is": "Sakavottorð án stimpils", "en": "Document containing your criminal record without stamp" }', diff --git a/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js b/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js new file mode 100644 index 000000000000..7678fb348481 --- /dev/null +++ b/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js @@ -0,0 +1,54 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('organization_testimony_types', [ + { + id: 'aeac43a3-daf0-4bca-9079-7dffe6121d75', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', // estateGuardianshipCertificateStamped + }, + { + id: '2d324d06-2e2a-4da3-b6fd-f18a3e4e2dd4', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: '37b8a86e-5787-4007-be40-d3f7b0070cca', // estateGuardianshipCertificateUnstamped + }, + { + id: 'b825f585-aa5d-48e5-91d6-0e056e41b5f3', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: 'fa035b40-4324-4140-8747-d163ef645b28', // residenceCertificate + }, + { + id: '8570a43a-b694-468e-8956-c4e906c9becd', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: '5ec5b516-a152-4761-b0e0-ba5aa4ffae61', // indebtednessCertificate + }, + { + id: 'c8b66543-fe0d-45ee-98bc-3d3bc9a0ad66', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: 'b3f37a69-2700-45f5-88e6-03fc09fcf6cc', // criminalRecordStamped + }, + { + id: '65486db0-cd26-4db8-ba8c-9989ff389904', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + testimony_type_id: '72127323-56f3-40ff-8ae4-68c20e80ff37', // criminalRecordUnstamped + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('organization_testimony_types', null, {}) + }, +} diff --git a/apps/services/form-system/seeders/20240614162836-seed-list-type.js b/apps/services/form-system/seeders/20240614162836-seed-list-type.js new file mode 100644 index 000000000000..691aaaeadba0 --- /dev/null +++ b/apps/services/form-system/seeders/20240614162836-seed-list-type.js @@ -0,0 +1,62 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('list_types', [ + { + id: '436a7bb6-ce1d-42cd-a759-24774df5acff', + type: 'municipalities', + name: '{ "is": "Sveitarfélög", "en": "Municipalities" }', + description: + '{ "is": "Listi af sveitarfélögum landsins", "en": "List of Icelands municipalities" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '64f1cff8-68c1-457a-9200-5c57f7b187eb', + type: 'countries', + name: '{ "is": "Landalisti", "en": "Countries" }', + description: + '{ "is": "Listi af löndum heimsins", "en": "List of the countries of the world" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: '3fb52435-4687-4983-9948-052ff193fc20', + type: 'postalCodes', + name: '{ "is": "Póstnúmer", "en": "Postal codes" }', + description: + '{ "is": "Listi af póstnúmerum landsins", "en": "List of Icelands postal codes" }', + is_common: true, + created: new Date(), + modified: new Date(), + }, + { + id: 'd3ecbba3-68e3-4398-97b1-63bf78f24da6', + type: 'mastersTrades', + name: '{ "is": "Iðngreinar meistara", "en": "Masters trades" }', + description: + '{ "is": "Listi af iðngreinum meistara", "en": "List of masters trades" }', + is_common: false, + created: new Date(), + modified: new Date(), + }, + { + id: 'baac7e09-4f19-4455-95f6-9e7f6521267a', + type: 'registrationCategoriesOfActivities', + name: '{ "is": "Skráningarflokkar starfsemi", "en": "Registration categories of activities" }', + description: + '{ "is": "Skráningarflokkar starfsemi", "en": "Registration categories of activities" }', + is_common: false, + created: new Date(), + modified: new Date(), + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('list_types', null, {}) + }, +} diff --git a/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js b/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js new file mode 100644 index 000000000000..083c82b35d62 --- /dev/null +++ b/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js @@ -0,0 +1,26 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + await queryInterface.bulkInsert('organization_list_types', [ + { + id: 'b5d773d2-d27f-45eb-ab39-05ede05b15af', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + list_type_id: 'd3ecbba3-68e3-4398-97b1-63bf78f24da6', // mastersTrades + }, + { + id: '9e8a3d8c-b6fb-4b68-b050-0f46badfe863', + created: new Date(), + modified: new Date(), + organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. + list_type_id: 'baac7e09-4f19-4455-95f6-9e7f6521267a', // registrationCategoriesOfActivities + }, + ]) + }, + + async down(queryInterface, Sequelize) { + await queryInterface.bulkDelete('organization_list_types', null, {}) + }, +} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 4f4b2e760ab3..945f1979edcc 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -11,6 +11,9 @@ import { OrganizationsModule } from './modules/organizations/organizations.modul import { GroupsModule } from './modules/groups/groups.module' import { InputsModule } from './modules/inputs/inputs.module' import { LoggingModule } from '@island.is/logging' +import { TestimoniesModule } from './modules/testimonies/testimonies.module' +import { ListsModule } from './modules/lists/lists.module' +import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' @Module({ imports: [ @@ -26,6 +29,9 @@ import { LoggingModule } from '@island.is/logging' StepsModule, GroupsModule, InputsModule, + TestimoniesModule, + ListsModule, + InputSettingsModule, ], }) export class AppModule {} diff --git a/apps/services/form-system/src/app/dataTypes/listItem.model.ts b/apps/services/form-system/src/app/dataTypes/listItem.model.ts new file mode 100644 index 000000000000..435192b3dddc --- /dev/null +++ b/apps/services/form-system/src/app/dataTypes/listItem.model.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from './languageType.model' + +export class ListItem { + @ApiProperty() + id?: string + + @ApiProperty({ type: LanguageType }) + label!: LanguageType + + @ApiProperty({ type: LanguageType }) + description?: LanguageType + + @ApiProperty() + value?: string + + @ApiProperty() + displayOrder?: number + + @ApiProperty() + isSelected!: boolean +} diff --git a/apps/services/form-system/src/app/enums/applicantType.enum.ts b/apps/services/form-system/src/app/enums/applicantType.enum.ts deleted file mode 100644 index c93c74fdaa1b..000000000000 --- a/apps/services/form-system/src/app/enums/applicantType.enum.ts +++ /dev/null @@ -1,8 +0,0 @@ -export enum ApplicantType { - individual, - individualWithMandateFromIndividual, - individualWithMandateFromLegalEntity, - individualWithProcuration, - individualGivingMandate, - legalEntity, -} diff --git a/apps/services/form-system/src/app/enums/applicantTypes.ts b/apps/services/form-system/src/app/enums/applicantTypes.ts new file mode 100644 index 000000000000..6a465df466aa --- /dev/null +++ b/apps/services/form-system/src/app/enums/applicantTypes.ts @@ -0,0 +1,10 @@ +export const ApplicantTypes = { + INDIVIDUAL: 'individual', + iNDIVIDUAL_WITH_MANDATE_FROM_INDIVIDUAL: + 'individualWithMandateFromIndividual', + INDIVIDUAL_WITH_MANDATE_FROM_LEGAL_ENTITY: + 'individualWithMandateFromLegalEntity', + INDIVIDUAL_WITH_PROCURATION: 'individualWithProcuration', + INDIVIDUAL_GIVING_MANDATE: 'individualGivingMandate', + LEGAL_ENTITY: 'legalEntity', +} diff --git a/apps/services/form-system/src/app/enums/stepType.enum.ts b/apps/services/form-system/src/app/enums/stepType.enum.ts deleted file mode 100644 index 7704cbb4caef..000000000000 --- a/apps/services/form-system/src/app/enums/stepType.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum StepType { - premises, - parties, - input, - payment, -} diff --git a/apps/services/form-system/src/app/enums/stepTypes.ts b/apps/services/form-system/src/app/enums/stepTypes.ts new file mode 100644 index 000000000000..434bf5a60035 --- /dev/null +++ b/apps/services/form-system/src/app/enums/stepTypes.ts @@ -0,0 +1,6 @@ +export const StepTypes = { + PREMISES: 'premises', + PARTIES: 'parties', + INPUT: 'input', + PAYMENT: 'payment', +} diff --git a/apps/services/form-system/src/app/enums/timeInterval.enum.ts b/apps/services/form-system/src/app/enums/timeInterval.enum.ts deleted file mode 100644 index 359cb2f8bec0..000000000000 --- a/apps/services/form-system/src/app/enums/timeInterval.enum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export enum TimeInterval { - minutely, - quarterly, - halfHourly, - hourly, -} diff --git a/apps/services/form-system/src/app/enums/timeIntervals.ts b/apps/services/form-system/src/app/enums/timeIntervals.ts new file mode 100644 index 000000000000..8c23caaa40ef --- /dev/null +++ b/apps/services/form-system/src/app/enums/timeIntervals.ts @@ -0,0 +1,6 @@ +export const TimeIntervals = { + MINUTELY: 'minutely', + QUARTERLY: 'quarterly', + HALF_HOURLY: 'halfHourly', + HOURLY: 'hourly', +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts index f53a30452775..e1af50a064b9 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts @@ -8,7 +8,7 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { ApplicantType } from '../../../enums/applicantType.enum' +import { ApplicantTypes } from '../../../enums/applicantTypes' @Table({ tableName: 'applicants' }) export class Applicant extends Model { @@ -87,9 +87,9 @@ export class Applicant extends Model { @Column({ type: DataType.ENUM, allowNull: false, - values: [''], - defaultValue: ApplicantType.individual, + values: Object.values(ApplicantTypes), + defaultValue: ApplicantTypes.INDIVIDUAL, }) - @ApiProperty({ enum: ApplicantType }) - applicantType!: ApplicantType + @ApiProperty({ enum: ApplicantTypes }) + applicantType!: string } diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts index 698ef2f1162d..e96fd66cae8b 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts @@ -9,9 +9,9 @@ import { UpdatedAt, } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' -import { ApplicantType } from '../../../enums/applicantType.enum' import { Organization } from '../../organizations/models/organization.model' import { CreationOptional } from 'sequelize' +import { ApplicantTypes } from '../../../enums/applicantTypes' @Table({ tableName: 'applicant_type_name_suggestions' }) export class ApplicantTypeNameSuggestion extends Model { @@ -43,11 +43,11 @@ export class ApplicantTypeNameSuggestion extends Model Organization) @Column({ diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts deleted file mode 100644 index e0c9b8da6864..000000000000 --- a/apps/services/form-system/src/app/modules/applicants/models/applicantTypes.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const ApplicantTypes = { - individual: 'individual', - individualWithMandateFromIndividual: 'individualWithMandateFromIndividual', - individualWithMandateFromLegalEntity: 'individualWithMandateFromLegalEntity', - individualWithProcuration: 'individualWithProcuration', - individualGivingMandate: 'individualGivingMandate', - legalEntity: 'legalEntity', -} diff --git a/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts index 9b6b72266878..fe514cba6b24 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts @@ -8,11 +8,10 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { ApplicantType } from '../../../enums/applicantType.enum' import { LanguageType } from '../../../dataTypes/languageType.model' import { Form } from '../../forms/models/form.model' import { CreationOptional } from 'sequelize' -import { ApplicantTypes } from './applicantTypes' +import { ApplicantTypes } from '../../../enums/applicantTypes' @Table({ tableName: 'form_applicants' }) export class FormApplicant extends Model { diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 94a27dc600ef..96bb1e1e945b 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -2,6 +2,7 @@ import { Body, Controller, Get, + Delete, NotFoundException, Param, Post, @@ -22,14 +23,14 @@ export class FormsController { @Post() @Documentation({ description: 'Create new form', - response: { status: 200, type: FormDto }, + response: { status: 200, type: FormResponse }, }) - async create(@Body() createFormDto: CreateFormDto): Promise { - const formDto = await this.formsService.create(createFormDto) - if (!formDto) { - throw new Error('bla') + async create(@Body() createFormDto: CreateFormDto): Promise { + const formResponse = await this.formsService.create(createFormDto) + if (!formResponse) { + throw new Error('Error') } - return formDto + return formResponse } @Get('organization/:organizationId') @@ -56,4 +57,9 @@ export class FormsController { return formResponse } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.formsService.delete(id) + } } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index bd1f5d10187d..d4ee3afa9903 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -9,6 +9,9 @@ import { Step } from '../steps/models/step.model' import { Group } from '../groups/models/group.model' import { Organization } from '../organizations/models/organization.model' import { InputType } from '../inputs/models/inputType.model' +import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { ListType } from '../lists/models/listType.model' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' @Module({ imports: [ @@ -19,9 +22,11 @@ import { InputType } from '../inputs/models/inputType.model' Group, Organization, InputType, + TestimonyType, + ListType, ]), ], controllers: [FormsController], - providers: [FormsService], + providers: [FormsService, InputSettingsMapper], }) export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 339f3cf4bbf8..90f52aec6762 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -1,13 +1,12 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { Form } from './models/form.model' import { InjectModel } from '@nestjs/sequelize' -import { Step, StepTypes } from '../steps/models/step.model' +import { Step } from '../steps/models/step.model' import { Group } from '../groups/models/group.model' import { Input } from '../inputs/models/input.model' import { CreateFormDto } from './models/dto/createForm.dto' import { InputType } from '../inputs/models/inputType.model' -import { InputSettings } from '../inputs/models/inputSettings.model' -import { StepType } from '../../enums/stepType.enum' +import { InputSettings } from '../inputSettings/models/inputSettings.model' import { LanguageType } from '../../dataTypes/languageType.model' import { Organization } from '../organizations/models/organization.model' import { FormDto } from './models/dto/form.dto' @@ -17,6 +16,17 @@ import { InputDto } from '../inputs/models/dto/input.dto' import { FormResponse } from './models/dto/form.response.dto' import { InputTypeDto } from '../inputs/models/dto/inputType.dto' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' +import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { TestimonyTypeDto } from '../testimonies/dto/testimonyType.dto' +import { FormTestimonyTypeDto } from '../testimonies/dto/formTestimonyType.dto' +import { ListTypeDto } from '../lists/models/dto/listType.dto' +import { ListType } from '../lists/models/listType.model' +import { + InputSettingsDto, + TextboxInputSettingsDto, +} from '../inputSettings/models/dto/inputSettings.dto' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' +import { StepTypes } from '../../enums/stepTypes' @Injectable() export class FormsService { @@ -31,6 +41,11 @@ export class FormsService { private readonly organizationModel: typeof Organization, @InjectModel(InputType) private readonly inputTypeModel: typeof InputType, + @InjectModel(TestimonyType) + private readonly testimonyTypeModel: typeof TestimonyType, + @InjectModel(ListType) + private readonly listTypeModel: typeof ListType, + private readonly inputSettingsMapper: InputSettingsMapper, ) {} async findAll(organizationId: string): Promise { @@ -45,21 +60,12 @@ export class FormsService { if (!form) { return null } - // const formDto = this.setArrays(form) - - const formResponse = this.buildFormResponse(form) - - // const organizationSpecificInputTypes = - // await this.organizationModel.findByPk(form.organizationId, { - // include: [InputType], - // }) - - // console.log(organizationSpecificInputTypes) + const formResponse = await this.buildFormResponse(form) return formResponse } - async create(createFormDto: CreateFormDto): Promise { + async create(createFormDto: CreateFormDto): Promise { const { organizationId } = createFormDto if (!organizationId) { @@ -77,23 +83,22 @@ export class FormsService { organizationId: organizationId, } as Form) - try { - await this.createFormTemplate(newForm) - } catch (err) { - throw new Error(`Could not create formTemplate for form ${newForm.id}`) - } + await this.createFormTemplate(newForm) const form = await this.findById(newForm.id) - if (!form) { - return null - } - const formDto = this.setArrays(form) - return formDto + const formResponse = await this.buildFormResponse(form) + + return formResponse } - private async findById(id: string): Promise { - return await this.formModel.findByPk(id, { + async delete(id: string): Promise { + const form = await this.findById(id) + form?.destroy() + } + + private async findById(id: string): Promise { + const form = await this.formModel.findByPk(id, { include: [ { model: Step, @@ -119,17 +124,50 @@ export class FormsService { }, ], }) + + if (!form) { + throw new NotFoundException(`Form with id '${id}' not found`) + } + + return form } private async buildFormResponse(form: Form): Promise { const response: FormResponse = { form: this.setArrays(form), inputTypes: await this.getInputTypes(form.organizationId), + testimonyTypes: await this.getTestimonyTypes(form.organizationId), + listTypes: await this.getListTypes(form.organizationId), } return response } + private async getTestimonyTypes( + organizationId: string, + ): Promise { + const organizationSpecificTestimonyTypes = + await this.organizationModel.findByPk(organizationId, { + include: [TestimonyType], + }) + + const organizationTestimonyTypes = + organizationSpecificTestimonyTypes?.organizationTestimonyTypes as TestimonyType[] + + const testimonyTypesDto: TestimonyTypeDto[] = [] + + organizationTestimonyTypes?.map((testimonyType) => { + testimonyTypesDto.push({ + id: testimonyType.id, + type: testimonyType.type, + name: testimonyType.name, + description: testimonyType.description, + } as TestimonyTypeDto) + }) + + return testimonyTypesDto + } + private async getInputTypes(organizationId: string): Promise { const commonInputTypes = await this.inputTypeModel.findAll({ where: { isCommon: true }, @@ -151,12 +189,44 @@ export class FormsService { name: inputType.name, description: inputType.description, isCommon: inputType.isCommon, + inputSettings: this.inputSettingsMapper.mapInputTypeToInputSettings( + null, + inputType.type, + ), } as InputTypeDto) }) + console.log('blalala:', InputSettingsDto) return inputTypesDto } + private async getListTypes(organizationId: string): Promise { + const commonListTypes = await this.listTypeModel.findAll({ + where: { isCommon: true }, + }) + const organizationSpecificListTypes = await this.organizationModel.findByPk( + organizationId, + { include: [ListType] }, + ) + + const organizationListTypes = commonListTypes.concat( + organizationSpecificListTypes?.organizationListTypes as ListType[], + ) + + const listTypesDto: ListTypeDto[] = [] + organizationListTypes.map((listType) => { + listTypesDto.push({ + id: listType.id, + type: listType.type, + name: listType.name, + description: listType.description, + isCommon: listType.isCommon, + } as ListTypeDto) + }) + + return listTypesDto + } + private setArrays(form: Form): FormDto { const formDto: FormDto = { id: form.id, @@ -170,14 +240,24 @@ export class FormsService { derivedFrom: form.derivedFrom, stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, completedMessage: form.completedMessage, - formApplicants: [], + testimonyTypes: [], + applicants: [], steps: [], groups: [], inputs: [], } - form.formApplicants?.map((applicant) => { - formDto.formApplicants?.push({ + form.testimonyTypes?.map((testimonyType) => { + formDto.testimonyTypes?.push({ + id: testimonyType.id, + name: testimonyType.name, + description: testimonyType.description, + type: testimonyType.type, + } as FormTestimonyTypeDto) + }) + + form.applicants?.map((applicant) => { + formDto.applicants?.push({ id: applicant.id, applicantType: applicant.applicantType, name: applicant.name, @@ -232,28 +312,28 @@ export class FormsService { private async createFormTemplate(form: Form): Promise { await this.stepModel.create({ formId: form.id, - stepType: StepTypes.premises, + stepType: StepTypes.PREMISES, displayOrder: 0, name: { is: 'Forsendur', en: 'Premises' }, } as Step) await this.stepModel.create({ formId: form.id, - stepType: StepTypes.parties, + stepType: StepTypes.PARTIES, displayOrder: 1, name: { is: 'Hlutaðeigandi aðilar', en: 'Relevant parties' }, } as Step) const inputStep = await this.stepModel.create({ formId: form.id, - stepType: StepTypes.input, + stepType: StepTypes.INPUT, displayOrder: 2, name: { is: 'Innsláttarskref', en: 'InputStep' }, } as Step) await this.stepModel.create({ formId: form.id, - stepType: StepTypes.payment, + stepType: StepTypes.PAYMENT, displayOrder: 3, name: { is: 'Greiðsla', en: 'Payment' }, } as Step) diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 039d0be75373..2962567b3ecc 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -7,6 +7,7 @@ import { Input } from '../../../inputs/models/input.model' import { StepDto } from '../../../steps/models/dto/step.dto' import { Step } from '../../../steps/models/step.model' import { ApiProperty } from '@nestjs/swagger' +import { FormTestimonyTypeDto } from '../../../testimonies/dto/formTestimonyType.dto' export class FormDto { @ApiProperty() @@ -42,8 +43,11 @@ export class FormDto { @ApiProperty({ type: LanguageType }) completedMessage?: LanguageType + @ApiProperty({ type: [FormTestimonyTypeDto] }) + testimonyTypes?: FormTestimonyTypeDto[] + @ApiProperty({ type: [FormApplicantDto] }) - formApplicants?: FormApplicantDto[] + applicants?: FormApplicantDto[] @ApiProperty({ type: [StepDto] }) steps?: StepDto[] diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts index 580a8d3750e1..c37f18df7b43 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts @@ -2,6 +2,9 @@ import { ApiProperty } from '@nestjs/swagger' import { FormDto } from './form.dto' import { InputType } from '../../../inputs/models/inputType.model' import { InputTypeDto } from '../../../inputs/models/dto/inputType.dto' +import { TestimonyType } from '../../../testimonies/models/testimonyType.model' +import { TestimonyTypeDto } from '../../../testimonies/dto/testimonyType.dto' +import { ListTypeDto } from '../../../lists/models/dto/listType.dto' export class FormResponse { @ApiProperty({ type: FormDto }) @@ -9,4 +12,10 @@ export class FormResponse { @ApiProperty({ type: [InputTypeDto] }) inputTypes!: InputTypeDto[] + + @ApiProperty({ type: [TestimonyTypeDto] }) + testimonyTypes!: TestimonyTypeDto[] + + @ApiProperty({ type: [ListTypeDto] }) + listTypes!: ListTypeDto[] } diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index 441219c9c3fd..9039d27a264d 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -1,5 +1,6 @@ -import { CreationOptional } from 'sequelize' +import { CreationOptional, NonAttribute } from 'sequelize' import { + BelongsToMany, Column, CreatedAt, DataType, @@ -14,6 +15,7 @@ import { ApiProperty } from '@nestjs/swagger' import { Organization } from '../../organizations/models/organization.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { FormApplicant } from '../../applicants/models/formApplicant.model' +import { TestimonyType } from '../../testimonies/models/testimonyType.model' @Table({ tableName: 'forms' }) export class Form extends Model { @@ -91,7 +93,7 @@ export class Form extends Model { @HasMany(() => FormApplicant) @ApiProperty({ type: [FormApplicant] }) - formApplicants?: FormApplicant[] + applicants?: FormApplicant[] @ForeignKey(() => Organization) @Column({ @@ -100,4 +102,11 @@ export class Form extends Model { field: 'organization_id', }) organizationId!: string + + @BelongsToMany(() => TestimonyType, { + through: 'form_testimony_types', + foreignKey: 'form_id', + otherKey: 'testimony_type_id', + }) + testimonyTypes?: NonAttribute } diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.ts index c6dd1dc6364c..92f85802f631 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.controller.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.controller.ts @@ -2,15 +2,19 @@ import { Controller, Post, Get, + Delete, Body, Param, NotFoundException, + Put, } from '@nestjs/common' import { GroupsService } from './groups.service' import { CreateGroupDto } from './models/dto/createGroup.dto' import { Group } from './models/group.model' import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' +import { UpdateGroupDto } from './models/dto/updateGroup.dto' +import { GroupDto } from './models/dto/group.dto' @ApiTags('groups') @Controller('groups') @@ -44,4 +48,17 @@ export class GroupsController { return group } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateGroupDto: UpdateGroupDto, + ): Promise { + return await this.groupsService.update(id, updateGroupDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.groupsService.delete(id) + } } diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.ts b/apps/services/form-system/src/app/modules/groups/groups.service.ts index 661e1da5ff12..4601d6147bbf 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.service.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.service.ts @@ -1,8 +1,10 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, NotFoundException } from '@nestjs/common' import { Group } from './models/group.model' import { InjectModel } from '@nestjs/sequelize' import { Input } from '../inputs/models/input.model' import { CreateGroupDto } from './models/dto/createGroup.dto' +import { UpdateGroupDto } from './models/dto/updateGroup.dto' +import { GroupDto } from './models/dto/group.dto' @Injectable() export class GroupsService { @@ -15,9 +17,13 @@ export class GroupsService { return await this.groupModel.findAll() } - async findOne(id: string): Promise { + async findOne(id: string): Promise { const group = await this.groupModel.findByPk(id, { include: [Input] }) + if (!group) { + throw new NotFoundException(`Group with id '${id}' not found`) + } + return group } @@ -26,4 +32,29 @@ export class GroupsService { const newGroup: Group = new this.groupModel(group) return await newGroup.save() } + + async update(id: string, updateGroupDto: UpdateGroupDto): Promise { + const group = await this.findOne(id) + + group.name = updateGroupDto.name + group.multiset = updateGroupDto.multiset + group.modified = new Date() + + await group.save() + + const groupDto: GroupDto = { + id: group.id, + stepId: group.stepId, + name: group.name, + displayOrder: group.displayOrder, + multiset: group.multiset, + } + + return groupDto + } + + async delete(id: string): Promise { + const group = await this.findOne(id) + group?.destroy() + } } diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts index 8f68a484ae9d..0307e95a5628 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts +++ b/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts @@ -11,18 +11,9 @@ export class GroupDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty({ type: Date }) - created!: Date - - @ApiProperty({ type: Date }) - modified!: Date - @ApiProperty() displayOrder!: number - @ApiProperty() - isHidden!: boolean - @ApiProperty() multiset!: number } diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts new file mode 100644 index 000000000000..8fcfb5359e51 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts @@ -0,0 +1,13 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class UpdateGroupDto { + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + displayOrder!: number + + @ApiProperty() + multiset!: number +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts new file mode 100644 index 000000000000..fd21f8fa819f --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { InputSettings } from './models/inputSettings.model' +import { InputSettingsService } from './inputSettings.service' +import { InputSettingsMapper } from './models/inputSettings.mapper' + +@Module({ + imports: [SequelizeModule.forFeature([InputSettings])], + providers: [InputSettingsService, InputSettingsMapper], + exports: [InputSettingsService], +}) +export class InputSettingsModule {} diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts new file mode 100644 index 000000000000..63228222daa1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts @@ -0,0 +1,18 @@ +import { Test, TestingModule } from '@nestjs/testing' +import { InputSettingsService } from './inputSettings.service' + +describe('InputSettingsService', () => { + let service: InputSettingsService + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [InputSettingsService], + }).compile() + + service = module.get(InputSettingsService) + }) + + it('should be defined', () => { + expect(service).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts new file mode 100644 index 000000000000..2b59273fde01 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts @@ -0,0 +1,60 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { InputSettings } from './models/inputSettings.model' +import { UpdateInputSettingsDto } from './models/dto/updateInputSettings.dto' +import { InjectModel } from '@nestjs/sequelize' +import { InputSettingsMapper } from './models/inputSettings.mapper' +import { InputSettingsDto } from './models/dto/inputSettings.dto' + +@Injectable() +export class InputSettingsService { + constructor( + @InjectModel(InputSettings) + private readonly inputSettingsModel: typeof InputSettings, + private readonly inputSettingsMapper: InputSettingsMapper, + ) {} + + async create(inputId: string): Promise { + await this.inputSettingsModel.create({ + inputId: inputId, + } as InputSettings) + + return new InputSettingsDto() + } + + async findByInputId(inputId: string): Promise { + const inputSettings = await this.inputSettingsModel.findOne({ + where: { inputId: inputId }, + }) + + if (!inputSettings) { + throw new NotFoundException( + `inputSettings for input with id '${inputId}' not found`, + ) + } + + return inputSettings + } + + async findOne(inputId: string, inputType: string): Promise { + const inputSettings = await this.findByInputId(inputId) + + return this.inputSettingsMapper.mapInputTypeToInputSettings( + inputSettings, + inputType, + ) + } + + async update( + id: string, + updateInputSettings: UpdateInputSettingsDto, + ): Promise { + const inputSettings = await this.findByInputId(id) + + this.inputSettingsMapper.mapUpdateInputSettingsDtoToInputSettings( + inputSettings, + updateInputSettings, + ) + + await inputSettings.save() + } +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts b/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts new file mode 100644 index 000000000000..5fc8889159e1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts @@ -0,0 +1,110 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class InputSettingsDto { + @ApiProperty() + minValue?: number + + @ApiProperty() + maxValue?: number + + @ApiProperty() + minLength?: number + + @ApiProperty() + maxLength?: number + + @ApiProperty() + minDate?: Date + + @ApiProperty() + maxDate?: Date + + @ApiProperty() + minAmount?: string + + @ApiProperty() + maxAmount?: string + + @ApiProperty() + year?: number + + @ApiProperty() + hasLink?: boolean + + @ApiProperty() + url?: string + + @ApiProperty() + buttonText?: string + + @ApiProperty() + hasPropertyInput?: boolean + + @ApiProperty() + hasPropertyList?: boolean + + @ApiProperty() + list?: string + + @ApiProperty() + fileTypes?: string + + @ApiProperty() + fileMaxSize?: number + + @ApiProperty() + maxFiles?: number + + @ApiProperty() + timeInterval?: string +} + +export class TextboxInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'maxLength' | 'minLength' +>) {} + +export class NumberboxInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'maxLength' | 'minLength' | 'minValue' | 'maxValue' +>) {} + +export class MessageInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'hasLink' | 'url' | 'buttonText' +>) {} + +export class DatePickerInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'minDate' | 'maxDate' +>) {} + +export class DropdownListInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'list' +>) {} + +export class RadioButtonsInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'list' +>) {} + +export class IskNumberboxInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'minAmount' | 'maxAmount' +>) {} + +export class PropertyNumberInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'hasPropertyInput' | 'hasPropertyList' +>) {} + +export class DocumentInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'fileTypes' | 'fileMaxSize' | 'maxFiles' +>) {} + +export class TimeInputInputSettingsDto extends (InputSettingsDto as new () => Pick< + InputSettingsDto, + 'timeInterval' +>) {} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts b/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts new file mode 100644 index 000000000000..1cc7790e6bd8 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts @@ -0,0 +1,60 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class UpdateInputSettingsDto { + @ApiProperty() + minValue?: number + + @ApiProperty() + maxValue?: number + + @ApiProperty() + minLength?: number + + @ApiProperty() + maxLength?: number + + @ApiProperty() + minDate?: Date + + @ApiProperty() + maxDate?: Date + + @ApiProperty() + minAmount?: string + + @ApiProperty() + maxAmount?: string + + @ApiProperty() + year?: number + + @ApiProperty() + hasLink?: boolean + + @ApiProperty() + url?: string + + @ApiProperty() + buttonText?: string + + @ApiProperty() + hasPropertyInput?: boolean + + @ApiProperty() + hasPropertyList?: boolean + + @ApiProperty() + list?: string + + @ApiProperty() + fileTypes?: string + + @ApiProperty() + fileMaxSize?: number + + @ApiProperty() + maxFiles?: number + + @ApiProperty() + timeInterval?: string +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts new file mode 100644 index 000000000000..bf6cf72c4eca --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts @@ -0,0 +1,113 @@ +import { Injectable } from '@nestjs/common' +import { UpdateInputSettingsDto } from './dto/updateInputSettings.dto' +import { InputSettings } from './inputSettings.model' +import { + DatePickerInputSettingsDto, + DocumentInputSettingsDto, + DropdownListInputSettingsDto, + InputSettingsDto, + IskNumberboxInputSettingsDto, + MessageInputSettingsDto, + NumberboxInputSettingsDto, + PropertyNumberInputSettingsDto, + RadioButtonsInputSettingsDto, + TextboxInputSettingsDto, + TimeInputInputSettingsDto, +} from './dto/inputSettings.dto' + +@Injectable() +export class InputSettingsMapper { + mapUpdateInputSettingsDtoToInputSettings( + inputSettings: InputSettings, + updateInputSettingsDto: UpdateInputSettingsDto, + ): void { + console.log(updateInputSettingsDto.minLength) + ;(inputSettings.modified = new Date()), + (inputSettings.minValue = updateInputSettingsDto.minValue ?? null), + (inputSettings.maxValue = updateInputSettingsDto.maxValue ?? null), + (inputSettings.minLength = updateInputSettingsDto.minLength ?? null), + (inputSettings.maxLength = updateInputSettingsDto.maxLength ?? null), + (inputSettings.minDate = updateInputSettingsDto.minDate ?? null), + (inputSettings.maxDate = updateInputSettingsDto.maxDate ?? null), + (inputSettings.minAmount = updateInputSettingsDto.minAmount ?? null), + (inputSettings.maxAmount = updateInputSettingsDto.maxAmount ?? null), + (inputSettings.year = updateInputSettingsDto.year ?? null), + (inputSettings.hasLink = updateInputSettingsDto.hasLink ?? null), + (inputSettings.url = updateInputSettingsDto.url ?? null), + (inputSettings.buttonText = updateInputSettingsDto.buttonText ?? null), + (inputSettings.hasPropertyInput = + updateInputSettingsDto.hasPropertyInput ?? null), + (inputSettings.hasPropertyList = + updateInputSettingsDto.hasPropertyList ?? null), + (inputSettings.list = updateInputSettingsDto.list ?? null), + (inputSettings.fileTypes = updateInputSettingsDto.fileTypes ?? null), + (inputSettings.fileMaxSize = updateInputSettingsDto.fileMaxSize ?? null), + (inputSettings.maxFiles = updateInputSettingsDto.maxFiles ?? null), + (inputSettings.timeInterval = updateInputSettingsDto.timeInterval ?? null) + + console.log(inputSettings.minLength) + } + + mapInputTypeToInputSettings( + inputSettings: InputSettings | null, + inputType: string, + ): InputSettingsDto { + switch (inputType) { + case 'textbox': + return { + maxLength: inputSettings ? inputSettings.maxLength : null, + minLength: inputSettings ? inputSettings.minLength : null, + } as TextboxInputSettingsDto + case 'numberbox': + return { + maxLength: inputSettings ? inputSettings.maxLength : null, + minLength: inputSettings ? inputSettings.minLength : null, + maxValue: inputSettings ? inputSettings.maxValue : null, + minValue: inputSettings ? inputSettings.minValue : null, + } as NumberboxInputSettingsDto + case 'message': + return { + hasLink: inputSettings ? inputSettings.hasLink : null, + url: inputSettings ? inputSettings.url : null, + buttonText: inputSettings ? inputSettings.buttonText : null, + } as MessageInputSettingsDto + case 'datePicker': + return { + minDate: inputSettings ? inputSettings.minDate : null, + maxDate: inputSettings ? inputSettings.maxDate : null, + } as DatePickerInputSettingsDto + case 'dropdownList': + return { + list: inputSettings ? inputSettings.list : null, + } as DropdownListInputSettingsDto + case 'radioButtons': + return { + list: inputSettings ? inputSettings.list : null, + } as RadioButtonsInputSettingsDto + case 'iskNumberbox': + return { + minAmount: inputSettings ? inputSettings.minAmount : null, + maxAmount: inputSettings ? inputSettings.maxAmount : null, + } as IskNumberboxInputSettingsDto + case 'propertyNumber': + return { + hasPropertyInput: inputSettings + ? inputSettings.hasPropertyInput + : null, + hasPropertyList: inputSettings ? inputSettings.hasPropertyList : null, + } as PropertyNumberInputSettingsDto + case 'document': + return { + fileTypes: inputSettings ? inputSettings.fileTypes : null, + fileMaxSize: inputSettings ? inputSettings.fileMaxSize : null, + maxFiles: inputSettings ? inputSettings.maxFiles : null, + } as DocumentInputSettingsDto + case 'timeInput': + return { + timeInterval: inputSettings ? inputSettings.timeInterval : null, + } as TimeInputInputSettingsDto + default: + return {} + } + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts similarity index 76% rename from apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts rename to apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts index 045f861a9677..25ffa297c0d8 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/inputSettings.model.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts @@ -11,8 +11,8 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Input } from './input.model' -import { TimeInterval } from '../../../enums/timeInterval.enum' +import { Input } from '../../inputs/models/input.model' +import { TimeIntervals } from '../../../enums/timeIntervals' @Table({ tableName: 'input_settings' }) export class InputSettings extends Model { @@ -38,134 +38,134 @@ export class InputSettings extends Model { allowNull: true, }) @ApiProperty() - minValue?: number + minValue?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - maxValue?: number + maxValue?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - minLength?: number + minLength?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - maxLength?: number + maxLength?: number | null @Column({ type: DataType.DATE, allowNull: true, }) @ApiProperty() - minDate?: Date + minDate?: Date | null @Column({ type: DataType.DATE, allowNull: true, }) @ApiProperty() - maxDate?: Date + maxDate?: Date | null @Column({ type: DataType.STRING, allowNull: true, }) @ApiProperty() - minAmount?: string + minAmount?: string | null @Column({ type: DataType.STRING, allowNull: true, }) @ApiProperty() - maxAmount?: string + maxAmount?: string | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - year?: number + year?: number | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) @ApiProperty() - hasLink?: boolean + hasLink?: boolean | null @Column({ type: DataType.STRING, allowNull: true, }) @ApiProperty() - url?: string + url?: string | null @Column({ type: DataType.STRING, allowNull: true, }) @ApiProperty() - buttonText?: string + buttonText?: string | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) @ApiProperty() - hasPropertyInput?: boolean + hasPropertyInput?: boolean | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) @ApiProperty() - hasPropertyList?: boolean + hasPropertyList?: boolean | null @Column({ type: DataType.JSON, allowNull: true, }) @ApiProperty() - list?: string + list?: string | null @Column({ type: DataType.JSON, allowNull: true, }) @ApiProperty() - fileTypes?: string + fileTypes?: string | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - fileMaxSize?: number + fileMaxSize?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) @ApiProperty() - maxFiles?: number + maxFiles?: number | null @Column({ type: DataType.ENUM, allowNull: true, - values: ['minutely', 'quarterly', 'halfHourly', 'hourly'], + values: Object.values(TimeIntervals), }) - @ApiProperty({ enum: TimeInterval }) - timeInterval?: TimeInterval + @ApiProperty({ enum: TimeIntervals }) + timeInterval?: string | null @ForeignKey(() => Input) @Column({ diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts index 44b637393ea1..6099761972c3 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts @@ -1,16 +1,20 @@ import { Body, Controller, + Delete, Get, NotFoundException, Param, Post, + Put, } from '@nestjs/common' import { InputsService } from './inputs.service' import { Input } from './models/input.model' import { CreateInputDto } from './models/dto/createInput.dto' import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' +import { UpdateInputDto } from './models/dto/updateInput.dto' +import { InputDto } from './models/dto/input.dto' @ApiTags('inputs') @Controller('inputs') @@ -18,7 +22,7 @@ export class InputsController { constructor(private readonly inputsService: InputsService) {} @Post() - create(@Body() createInputDto: CreateInputDto): Promise { + create(@Body() createInputDto: CreateInputDto): Promise { return this.inputsService.create(createInputDto) } @@ -34,9 +38,9 @@ export class InputsController { @Get(':id') @Documentation({ description: 'Get Input by id', - response: { status: 200, type: Input }, + response: { status: 200, type: InputDto }, }) - async findOne(@Param('id') id: string): Promise { + async findOne(@Param('id') id: string): Promise { const input = await this.inputsService.findOne(id) if (!input) { throw new NotFoundException(`Input not found`) @@ -44,4 +48,17 @@ export class InputsController { return input } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateInputDto: UpdateInputDto, + ): Promise { + await this.inputsService.update(id, updateInputDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.inputsService.delete(id) + } } diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts index 45c123aabc0b..3640b002c122 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts @@ -4,11 +4,20 @@ import { InputsService } from './inputs.service' import { Input } from './models/input.model' import { SequelizeModule } from '@nestjs/sequelize' import { InputType } from './models/inputType.model' -import { InputSettings } from './models/inputSettings.model' +import { InputSettings } from '../inputSettings/models/inputSettings.model' +import { InputSettingsModule } from '../inputSettings/inputSettings.module' +import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { InputMapper } from './models/input.mapper' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' @Module({ imports: [SequelizeModule.forFeature([Input, InputType, InputSettings])], controllers: [InputsController], - providers: [InputsService], + providers: [ + InputsService, + InputSettingsService, + InputMapper, + InputSettingsMapper, + ], }) export class InputsModule {} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts index a3a1abcb4d35..85add67342f8 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -1,28 +1,85 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, NotFoundException } from '@nestjs/common' import { Input } from './models/input.model' import { CreateInputDto } from './models/dto/createInput.dto' import { InjectModel } from '@nestjs/sequelize' +import { UpdateInputDto } from './models/dto/updateInput.dto' +import { InputSettings } from '../inputSettings/models/inputSettings.model' +import { InputDto } from './models/dto/input.dto' +import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { InputMapper } from './models/input.mapper' +import { TextboxInputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' @Injectable() export class InputsService { constructor( @InjectModel(Input) private readonly inputModel: typeof Input, + private readonly inputSettingsService: InputSettingsService, + private readonly inputMapper: InputMapper, ) {} async findAll(): Promise { return await this.inputModel.findAll() } - async findOne(id: string): Promise { + async findOne(id: string): Promise { + const input = await this.findById(id) + const inputSettingsDto = await this.inputSettingsService.findOne( + id, + input.inputType, + ) + + const inputDto: InputDto = this.inputMapper.mapInputToInputDto( + input, + inputSettingsDto, + ) + + return inputDto + } + + async findById(id: string): Promise { const input = await this.inputModel.findByPk(id) + if (!input) { + throw new NotFoundException(`Input with id '${id}' not found`) + } + return input } - async create(createInputDto: CreateInputDto): Promise { - const input = createInputDto as Input - const newInput: Input = new this.inputModel(input) - return await newInput.save() + async create(createInputDto: CreateInputDto): Promise { + const { groupId } = createInputDto + + const newInput: Input = await this.inputModel.create({ + groupId: groupId, + } as Input) + + const newInputSettingsDto = await this.inputSettingsService.create( + newInput.id, + ) + + const inputDto: InputDto = this.inputMapper.mapInputToInputDto( + newInput, + newInputSettingsDto, + ) + + return inputDto + } + + async update(id: string, updateInputDto: UpdateInputDto): Promise { + const input = await this.findById(id) + + this.inputMapper.mapUpdateInputDtoToInput(input, updateInputDto) + + if (updateInputDto.inputSettings) { + await this.inputSettingsService.update(id, updateInputDto.inputSettings) + } + + await input.save() + } + + async delete(id: string): Promise { + const input = await this.findById(id) + input?.destroy() } } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts index 490bb3f0944a..7fb7ce36e2ac 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts @@ -1,7 +1,11 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettings } from '../inputSettings.model' +import { InputSettings } from '../../../inputSettings/models/inputSettings.model' import { InputType } from '../inputType.model' +import { + InputSettingsDto, + TextboxInputSettingsDto, +} from '../../../inputSettings/models/dto/inputSettings.dto' export class InputDto { @ApiProperty() @@ -13,26 +17,17 @@ export class InputDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty({ type: Date }) - created!: Date - - @ApiProperty({ type: Date }) - modified!: Date - @ApiProperty() displayOrder!: number @ApiProperty({ type: LanguageType }) description!: LanguageType - @ApiProperty() - isHidden!: boolean - @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: InputSettings }) - inputSettings?: InputSettings + @ApiProperty({ type: InputSettingsDto }) + inputSettings?: InputSettingsDto @ApiProperty() inputType!: string diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts index 559a2ebd7197..bb4e3a450369 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' export class InputTypeDto { @ApiProperty() @@ -16,4 +17,7 @@ export class InputTypeDto { @ApiProperty() isCommon!: boolean + + @ApiProperty({ type: InputSettingsDto }) + inputSettings?: InputSettingsDto } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts new file mode 100644 index 000000000000..54764da0dbad --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts @@ -0,0 +1,25 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { InputSettings } from '../../../inputSettings/models/inputSettings.model' +import { InputType } from '../inputType.model' +import { UpdateInputSettingsDto } from '../../../inputSettings/models/dto/updateInputSettings.dto' + +export class UpdateInputDto { + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + isPartOfMultiset!: boolean + + @ApiProperty({ type: UpdateInputSettingsDto }) + inputSettings?: UpdateInputSettingsDto + + @ApiProperty() + inputType!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts new file mode 100644 index 000000000000..86311131fc48 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts @@ -0,0 +1,37 @@ +import { Injectable } from '@nestjs/common' +import { InputDto } from './dto/input.dto' +import { Input } from './input.model' +import { UpdateInputDto } from './dto/updateInput.dto' +import { + InputSettingsDto, + TextboxInputSettingsDto, +} from '../../inputSettings/models/dto/inputSettings.dto' + +@Injectable() +export class InputMapper { + mapInputToInputDto( + input: Input, + inputSettingsDto: InputSettingsDto, + ): InputDto { + const inputDto: InputDto = { + id: input.id, + groupId: input.groupId, + name: input.name, + displayOrder: input.displayOrder, + description: input.description, + isPartOfMultiset: input.isPartOfMultiset, + inputType: input.inputType, + inputSettings: inputSettingsDto, + } + + return inputDto + } + + mapUpdateInputDtoToInput(input: Input, updateInputDto: UpdateInputDto): void { + input.name = updateInputDto.name + input.description = updateInputDto.description + input.isPartOfMultiset = updateInputDto.isPartOfMultiset + input.inputType = updateInputDto.inputType + input.modified = new Date() + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts index 7647d73352b2..2ea12a3877c5 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts @@ -13,7 +13,7 @@ import { import { Group } from '../../groups/models/group.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { InputType } from './inputType.model' -import { InputSettings } from './inputSettings.model' +import { InputSettings } from '../../inputSettings/models/inputSettings.model' @Table({ tableName: 'inputs' }) export class Input extends Model { diff --git a/apps/services/form-system/src/app/modules/lists/lists.module.ts b/apps/services/form-system/src/app/modules/lists/lists.module.ts new file mode 100644 index 000000000000..43536c15a90e --- /dev/null +++ b/apps/services/form-system/src/app/modules/lists/lists.module.ts @@ -0,0 +1,9 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { ListType } from './models/listType.model' +import { OrganizationListType } from './models/organizationListType.model' + +@Module({ + imports: [SequelizeModule.forFeature([ListType, OrganizationListType])], +}) +export class ListsModule {} diff --git a/apps/services/form-system/src/app/modules/lists/models/dto/listType.dto.ts b/apps/services/form-system/src/app/modules/lists/models/dto/listType.dto.ts new file mode 100644 index 000000000000..2fa6db21c3e1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/lists/models/dto/listType.dto.ts @@ -0,0 +1,19 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class ListTypeDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + type!: string + + @ApiProperty() + isCommon!: boolean +} diff --git a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts new file mode 100644 index 000000000000..7e9af76fb74f --- /dev/null +++ b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts @@ -0,0 +1,73 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + BelongsToMany, + Column, + CreatedAt, + DataType, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' +import { ListTypes } from './listTypes' +import { Organization } from '../../organizations/models/organization.model' + +@Table({ tableName: 'list_types' }) +export class ListType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + name!: LanguageType + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + description!: LanguageType + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isCommon!: boolean + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataTypes.ENUM, + allowNull: false, + values: Object.values(ListTypes), + }) + @ApiProperty({ enum: ListTypes }) + type!: string + + @BelongsToMany(() => Organization, { + through: 'organization_list_types', + foreignKey: 'list_type_id', + otherKey: 'organization_id', + }) + organizations?: NonAttribute +} diff --git a/apps/services/form-system/src/app/modules/lists/models/listTypes.ts b/apps/services/form-system/src/app/modules/lists/models/listTypes.ts new file mode 100644 index 000000000000..a8bc17b8ae5f --- /dev/null +++ b/apps/services/form-system/src/app/modules/lists/models/listTypes.ts @@ -0,0 +1,7 @@ +export const ListTypes = { + municipalities: 'municipalities', + countries: 'countries', + postalCodes: 'postalCodes', + mastersTrades: 'mastersTrades', + registrationCategoriesOfActivities: 'registrationCategoriesOfActivities', +} diff --git a/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts new file mode 100644 index 000000000000..402398a08f33 --- /dev/null +++ b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts @@ -0,0 +1,46 @@ +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Organization } from '../../organizations/models/organization.model' +import { InputType } from '../../inputs/models/inputType.model' +import { CreationOptional } from 'sequelize' +import { ListType } from './listType.model' + +@Table({ tableName: 'organization_list_types' }) +export class OrganizationListType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + id!: string + + @CreatedAt + created!: CreationOptional + + @UpdatedAt + modified!: CreationOptional + + @ForeignKey(() => Organization) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'organization_id', + }) + organizationId!: string + + @ForeignKey(() => ListType) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'list_type_id', + }) + listTypeId!: string +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index 57cea87f01e0..f53643c3f44d 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -14,6 +14,8 @@ import { Form } from '../../forms/models/form.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { ApplicantTypeNameSuggestion } from '../../applicants/models/applicantTypeNameSuggestion.model' import { InputType } from '../../inputs/models/inputType.model' +import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { ListType } from '../../lists/models/listType.model' @Table({ tableName: 'organizations' }) export class Organization extends Model { @@ -65,15 +67,17 @@ export class Organization extends Model { }) organizationInputTypes?: NonAttribute - // @HasMany(() => InputType) - // @ApiProperty() - // inputTypes?: InputType[] - - // @HasMany(() => DocumentType) - // @ApiProperty() - // documentTypes?: DocumentType[] + @BelongsToMany(() => TestimonyType, { + through: 'organization_testimony_types', + foreignKey: 'organization_id', + otherKey: 'testimony_type_id', + }) + organizationTestimonyTypes?: NonAttribute - // @HasMany(() => ListType) - // @ApiProperty() - // listTypes?: ListType[] + @BelongsToMany(() => ListType, { + through: 'organization_list_types', + foreignKey: 'organization_id', + otherKey: 'list_type_id', + }) + organizationListTypes?: NonAttribute } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts index b018b4db2b8f..8c8e1c0fd779 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts +++ b/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts @@ -8,12 +8,6 @@ export class StepDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty({ type: Date }) - created!: Date - - @ApiProperty({ type: Date }) - modified!: Date - @ApiProperty() stepType!: string @@ -23,12 +17,6 @@ export class StepDto { @ApiProperty({ type: LanguageType }) waitingText?: LanguageType - @ApiProperty() - isHidden!: boolean - @ApiProperty() callRuleset!: boolean - - @ApiProperty() - isCompleted!: boolean } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts new file mode 100644 index 000000000000..1191a5710bc8 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class UpdateStepDto { + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + waitingText?: LanguageType + + @ApiProperty() + callRuleset!: boolean +} diff --git a/apps/services/form-system/src/app/modules/steps/models/step.model.ts b/apps/services/form-system/src/app/modules/steps/models/step.model.ts index fdeddcfdec7f..85afbbea5d21 100644 --- a/apps/services/form-system/src/app/modules/steps/models/step.model.ts +++ b/apps/services/form-system/src/app/modules/steps/models/step.model.ts @@ -14,14 +14,7 @@ import { Form } from '../../forms/models/form.model' import { ApiProperty } from '@nestjs/swagger' import { Group } from '../../groups/models/group.model' import { LanguageType } from '../../../dataTypes/languageType.model' -import { StepType } from '../../../enums/stepType.enum' - -export const StepTypes = { - premises: 'premises', - parties: 'parties', - input: 'input', - payment: 'payment', -} +import { StepTypes } from '../../../enums/stepTypes' @Table({ tableName: 'steps' }) export class Step extends Model { diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.ts index b6ce4eb783ea..5a04da03cc1c 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.ts @@ -3,14 +3,18 @@ import { Controller, Post, Get, + Delete, Param, NotFoundException, + Put, } from '@nestjs/common' import { StepsService } from './steps.service' import { CreateStepDto } from './models/dto/createStep.dto' import { Step } from './models/step.model' import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' +import { UpdateStepDto } from './models/dto/updateStep.dto' +import { StepDto } from './models/dto/step.dto' @ApiTags('steps') @Controller('steps') @@ -44,4 +48,17 @@ export class StepsController { return step } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.stepsService.delete(id) + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateStepDto: UpdateStepDto, + ): Promise { + return await this.stepsService.update(id, updateStepDto) + } } diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.ts b/apps/services/form-system/src/app/modules/steps/steps.service.ts index dfdb86e75052..933f48b6864c 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.service.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.service.ts @@ -1,9 +1,11 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' import { Step } from './models/step.model' import { CreateStepDto } from './models/dto/createStep.dto' import { Group } from '../groups/models/group.model' import { Input } from '../inputs/models/input.model' +import { UpdateStepDto } from './models/dto/updateStep.dto' +import { StepDto } from './models/dto/step.dto' @Injectable() export class StepsService { @@ -16,7 +18,7 @@ export class StepsService { return await this.stepModel.findAll() } - async findOne(id: string): Promise { + async findOne(id: string): Promise { const step = await this.stepModel.findByPk(id, { include: [ { @@ -27,6 +29,10 @@ export class StepsService { ], }) + if (!step) { + throw new NotFoundException(`Step with id '${id}' not found`) + } + return step } @@ -35,4 +41,32 @@ export class StepsService { const newStep: Step = new this.stepModel(step) return await newStep.save() } + + async update(id: string, updateStepDto: UpdateStepDto): Promise { + const step = await this.findOne(id) + + step.name = updateStepDto.name + step.displayOrder = updateStepDto.displayOrder + step.waitingText = updateStepDto.waitingText + step.callRuleset = updateStepDto.callRuleset + step.modified = new Date() + + await step.save() + + const stepDto: StepDto = { + id: step.id, + name: step.name, + stepType: step.stepType, + displayOrder: step.displayOrder, + waitingText: step.waitingText, + callRuleset: step.callRuleset, + } + + return stepDto + } + + async delete(id: string): Promise { + const step = await this.findOne(id) + step?.destroy() + } } diff --git a/apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts b/apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts new file mode 100644 index 000000000000..73ac5ffcf2d9 --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../dataTypes/languageType.model' + +export class FormTestimonyTypeDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + type!: string +} diff --git a/apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts b/apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts new file mode 100644 index 000000000000..4e2532095dc3 --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../dataTypes/languageType.model' + +export class TestimonyTypeDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + type!: string +} diff --git a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts new file mode 100644 index 000000000000..d09199a1d18f --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts @@ -0,0 +1,46 @@ +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { InputType } from '../../inputs/models/inputType.model' +import { CreationOptional } from 'sequelize' +import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { Form } from '../../forms/models/form.model' + +@Table({ tableName: 'form_testimony_types' }) +export class FormTestimonyType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + id!: string + + @CreatedAt + created!: CreationOptional + + @UpdatedAt + modified!: CreationOptional + + @ForeignKey(() => Form) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'form_id', + }) + formId!: string + + @ForeignKey(() => TestimonyType) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'testimony_type_id', + }) + testimonyTypeId!: string +} diff --git a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts new file mode 100644 index 000000000000..a5005f7b47f2 --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts @@ -0,0 +1,46 @@ +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Organization } from '../../organizations/models/organization.model' +import { InputType } from '../../inputs/models/inputType.model' +import { CreationOptional } from 'sequelize' +import { TestimonyType } from './testimonyType.model' + +@Table({ tableName: 'organization_testimony_types' }) +export class OrganizationTestimonyType extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + id!: string + + @CreatedAt + created!: CreationOptional + + @UpdatedAt + modified!: CreationOptional + + @ForeignKey(() => Organization) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'organization_id', + }) + organizationId!: string + + @ForeignKey(() => TestimonyType) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'testimony_type_id', + }) + testimonyTypeId!: string +} diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts index de57f880bd8e..42b61f646ac9 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { + BelongsToMany, Column, CreatedAt, DataType, @@ -8,8 +9,10 @@ import { UpdatedAt, } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' -import { CreationOptional, DataTypes } from 'sequelize' +import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' import { TestimonyTypes } from './testimonyTypes' +import { Organization } from '../../organizations/models/organization.model' +import { Form } from '../../forms/models/form.model' @Table({ tableName: 'testimony_types' }) export class TestimonyType extends Model { @@ -44,7 +47,7 @@ export class TestimonyType extends Model { values: Object.values(TestimonyTypes), }) @ApiProperty({ enum: TestimonyTypes }) - testimonyType!: string + type!: string @CreatedAt @ApiProperty({ type: Date }) @@ -53,4 +56,18 @@ export class TestimonyType extends Model { @UpdatedAt @ApiProperty({ type: Date }) modified!: CreationOptional + + @BelongsToMany(() => Organization, { + through: 'organization_testimony_types', + foreignKey: 'testimony_type_id', + otherKey: 'organization_id', + }) + organizations?: NonAttribute + + @BelongsToMany(() => Form, { + through: 'form_testimony_types', + foreignKey: 'testimony_type_id', + otherKey: 'form_id', + }) + forms?: NonAttribute } diff --git a/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts b/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts new file mode 100644 index 000000000000..b5ff89d01bb7 --- /dev/null +++ b/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts @@ -0,0 +1,11 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { TestimonyType } from './models/testimonyType.model' +import { OrganizationTestimonyType } from './models/organizationTestimonyType.model' + +@Module({ + imports: [ + SequelizeModule.forFeature([TestimonyType, OrganizationTestimonyType]), + ], +}) +export class TestimoniesModule {} From 0f87dcd7dee0fb1d806879015963dbedf700b2c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 21 Jun 2024 12:51:28 +0000 Subject: [PATCH 39/72] make lint satisfied --- .../form-system/src/app/app.module.ts | 18 ++++---- .../src/app/enums/testimonyTypes.ts | 10 +++++ .../src/app/modules/forms/forms.controller.ts | 9 ++-- .../src/app/modules/forms/forms.module.ts | 15 ++++--- .../src/app/modules/forms/forms.service.ts | 42 ++++++++----------- .../app/modules/forms/models/dto/form.dto.ts | 7 +--- .../forms/models/dto/form.response.dto.ts | 6 +-- .../modules/groups/groups.controller.spec.ts | 18 ++++---- .../app/modules/groups/groups.service.spec.ts | 18 ++++---- .../models/inputSettings.model.ts | 4 +- .../modules/inputs/inputs.controller.spec.ts | 18 ++++---- .../src/app/modules/inputs/inputs.module.ts | 11 +++-- .../app/modules/inputs/inputs.service.spec.ts | 18 ++++---- .../src/app/modules/inputs/inputs.service.ts | 10 ++--- .../inputs/models/dto/createInput.dto.ts | 1 - .../modules/inputs/models/dto/input.dto.ts | 7 +--- .../inputs/models/dto/updateInput.dto.ts | 2 - .../app/modules/inputs/models/input.mapper.ts | 7 +--- .../modules/inputs/models/inputType.model.ts | 6 +-- .../models/organizationListType.model.ts | 3 +- .../models/organization.model.ts | 6 +-- .../organizations.controller.spec.ts | 18 ++++---- .../organizations.service.spec.ts | 18 ++++---- .../organizations/organizations.service.ts | 15 ++----- .../app/modules/steps/models/step.model.ts | 11 +++-- .../modules/steps/steps.controller.spec.ts | 6 +-- .../{ => models}/dto/formTestimonyType.dto.ts | 2 +- .../{ => models}/dto/testimonyType.dto.ts | 2 +- .../models/formTestimonyType.model.ts | 5 +-- .../models/organizationTestimonyType.model.ts | 3 +- .../testimonies/models/testimonyType.model.ts | 2 +- .../testimonies/models/testimonyTypes.ts | 9 ---- 32 files changed, 139 insertions(+), 188 deletions(-) create mode 100644 apps/services/form-system/src/app/enums/testimonyTypes.ts rename apps/services/form-system/src/app/modules/testimonies/{ => models}/dto/formTestimonyType.dto.ts (79%) rename apps/services/form-system/src/app/modules/testimonies/{ => models}/dto/testimonyType.dto.ts (79%) delete mode 100644 apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 945f1979edcc..a16a7076b35c 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -1,25 +1,23 @@ -import { Module } from '@nestjs/common' -import { SequelizeModule } from '@nestjs/sequelize' import { AuthModule } from '@island.is/auth-nest-tools' +import { LoggingModule } from '@island.is/logging' import { AuditModule } from '@island.is/nest/audit' +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' import { environment } from '../environments' import { FormsModule } from './modules/forms/forms.module' -import { SequelizeConfigService } from './sequelizeConfig.service' -import { StepsModule } from './modules/steps/steps.module' -import { ProblemModule } from '@island.is/nest/problem' -import { OrganizationsModule } from './modules/organizations/organizations.module' import { GroupsModule } from './modules/groups/groups.module' +import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' import { InputsModule } from './modules/inputs/inputs.module' -import { LoggingModule } from '@island.is/logging' -import { TestimoniesModule } from './modules/testimonies/testimonies.module' import { ListsModule } from './modules/lists/lists.module' -import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' +import { OrganizationsModule } from './modules/organizations/organizations.module' +import { StepsModule } from './modules/steps/steps.module' +import { TestimoniesModule } from './modules/testimonies/testimonies.module' +import { SequelizeConfigService } from './sequelizeConfig.service' @Module({ imports: [ AuthModule.register(environment.auth), AuditModule.forRoot(environment.audit), - // ProblemModule, LoggingModule, SequelizeModule.forRootAsync({ useClass: SequelizeConfigService, diff --git a/apps/services/form-system/src/app/enums/testimonyTypes.ts b/apps/services/form-system/src/app/enums/testimonyTypes.ts new file mode 100644 index 000000000000..8920e9964540 --- /dev/null +++ b/apps/services/form-system/src/app/enums/testimonyTypes.ts @@ -0,0 +1,10 @@ +export const TestimonyTypes = { + ESTATE_GUARDIANSHIP_CERTIFICATE_STAMPED: + 'estateGuardianshipCertificateStamped', + ESTATE_GUARDIANSHIP_CERTIFICATE_UNSTAMPED: + 'estateGuardianshipCertificateUnstamped', + RESIDENCE_CERTIFICATE: 'residenceCertificate', + INDEBTEDNESS_CERTIFICATE: 'indebtednessCertificate', + CRIMINAL_RECORD_STAMPED: 'criminalRecordStamped', + CRIMINAL_RECORD_UNSTAMPED: 'criminalRecordUnstamped', +} diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 96bb1e1e945b..1ca70db8ab0a 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -1,19 +1,18 @@ +import { Documentation } from '@island.is/nest/swagger' import { Body, Controller, - Get, Delete, + Get, NotFoundException, Param, Post, } from '@nestjs/common' -import { Documentation } from '@island.is/nest/swagger' -import { FormsService } from './forms.service' -import { Form } from './models/form.model' import { ApiTags } from '@nestjs/swagger' +import { FormsService } from './forms.service' import { CreateFormDto } from './models/dto/createForm.dto' -import { FormDto } from './models/dto/form.dto' import { FormResponse } from './models/dto/form.response.dto' +import { Form } from './models/form.model' @ApiTags('forms') @Controller('forms') diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index d4ee3afa9903..88f53978fc0a 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -1,17 +1,16 @@ import { Module } from '@nestjs/common' -import { FormsController } from './forms.controller' -import { FormsService } from './forms.service' import { SequelizeModule } from '@nestjs/sequelize' -import { Form } from './models/form.model' import { FormApplicant } from '../applicants/models/formApplicant.model' -import { StepsService } from '../steps/steps.service' -import { Step } from '../steps/models/step.model' import { Group } from '../groups/models/group.model' -import { Organization } from '../organizations/models/organization.model' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputType } from '../inputs/models/inputType.model' -import { TestimonyType } from '../testimonies/models/testimonyType.model' import { ListType } from '../lists/models/listType.model' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' +import { Organization } from '../organizations/models/organization.model' +import { Step } from '../steps/models/step.model' +import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { FormsController } from './forms.controller' +import { FormsService } from './forms.service' +import { Form } from './models/form.model' @Module({ imports: [ diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 90f52aec6762..9db73da7a8a4 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -1,32 +1,28 @@ import { Injectable, NotFoundException } from '@nestjs/common' -import { Form } from './models/form.model' import { InjectModel } from '@nestjs/sequelize' -import { Step } from '../steps/models/step.model' +import { StepTypes } from '../../enums/stepTypes' +import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' +import { GroupDto } from '../groups/models/dto/group.dto' import { Group } from '../groups/models/group.model' -import { Input } from '../inputs/models/input.model' -import { CreateFormDto } from './models/dto/createForm.dto' -import { InputType } from '../inputs/models/inputType.model' +import { InputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { LanguageType } from '../../dataTypes/languageType.model' -import { Organization } from '../organizations/models/organization.model' -import { FormDto } from './models/dto/form.dto' -import { StepDto } from '../steps/models/dto/step.dto' -import { GroupDto } from '../groups/models/dto/group.dto' import { InputDto } from '../inputs/models/dto/input.dto' -import { FormResponse } from './models/dto/form.response.dto' import { InputTypeDto } from '../inputs/models/dto/inputType.dto' -import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' -import { TestimonyType } from '../testimonies/models/testimonyType.model' -import { TestimonyTypeDto } from '../testimonies/dto/testimonyType.dto' -import { FormTestimonyTypeDto } from '../testimonies/dto/formTestimonyType.dto' +import { Input } from '../inputs/models/input.model' +import { InputType } from '../inputs/models/inputType.model' import { ListTypeDto } from '../lists/models/dto/listType.dto' import { ListType } from '../lists/models/listType.model' -import { - InputSettingsDto, - TextboxInputSettingsDto, -} from '../inputSettings/models/dto/inputSettings.dto' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' -import { StepTypes } from '../../enums/stepTypes' +import { Organization } from '../organizations/models/organization.model' +import { StepDto } from '../steps/models/dto/step.dto' +import { Step } from '../steps/models/step.model' +import { FormTestimonyTypeDto } from '../testimonies/models/dto/formTestimonyType.dto' +import { TestimonyTypeDto } from '../testimonies/models/dto/testimonyType.dto' +import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { CreateFormDto } from './models/dto/createForm.dto' +import { FormDto } from './models/dto/form.dto' +import { FormResponse } from './models/dto/form.response.dto' +import { Form } from './models/form.model' @Injectable() export class FormsService { @@ -41,8 +37,6 @@ export class FormsService { private readonly organizationModel: typeof Organization, @InjectModel(InputType) private readonly inputTypeModel: typeof InputType, - @InjectModel(TestimonyType) - private readonly testimonyTypeModel: typeof TestimonyType, @InjectModel(ListType) private readonly listTypeModel: typeof ListType, private readonly inputSettingsMapper: InputSettingsMapper, @@ -72,7 +66,7 @@ export class FormsService { throw new Error('Missing organizationId') } - var organization = this.organizationModel.findByPk(organizationId) + const organization = this.organizationModel.findByPk(organizationId) if (!organization) { throw new NotFoundException( `Organization with id ${organizationId} not found`, diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 2962567b3ecc..98d10d8520b9 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -1,13 +1,10 @@ +import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' import { GroupDto } from '../../../groups/models/dto/group.dto' -import { Group } from '../../../groups/models/group.model' import { InputDto } from '../../../inputs/models/dto/input.dto' -import { Input } from '../../../inputs/models/input.model' import { StepDto } from '../../../steps/models/dto/step.dto' -import { Step } from '../../../steps/models/step.model' -import { ApiProperty } from '@nestjs/swagger' -import { FormTestimonyTypeDto } from '../../../testimonies/dto/formTestimonyType.dto' +import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' export class FormDto { @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts index c37f18df7b43..93ca4725d5a7 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts @@ -1,10 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' -import { FormDto } from './form.dto' -import { InputType } from '../../../inputs/models/inputType.model' import { InputTypeDto } from '../../../inputs/models/dto/inputType.dto' -import { TestimonyType } from '../../../testimonies/models/testimonyType.model' -import { TestimonyTypeDto } from '../../../testimonies/dto/testimonyType.dto' import { ListTypeDto } from '../../../lists/models/dto/listType.dto' +import { TestimonyTypeDto } from '../../../testimonies/models/dto/testimonyType.dto' +import { FormDto } from './form.dto' export class FormResponse { @ApiProperty({ type: FormDto }) diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts index 71a0ead90678..2d07b6b54c99 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GroupsController } from './groups.controller'; +import { Test, TestingModule } from '@nestjs/testing' +import { GroupsController } from './groups.controller' describe('GroupsController', () => { - let controller: GroupsController; + let controller: GroupsController beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [GroupsController], - }).compile(); + }).compile() - controller = module.get(GroupsController); - }); + controller = module.get(GroupsController) + }) it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); + expect(controller).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts index 77bd2c6237c1..59671cb000cc 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { GroupsService } from './groups.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { GroupsService } from './groups.service' describe('GroupsService', () => { - let service: GroupsService; + let service: GroupsService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [GroupsService], - }).compile(); + }).compile() - service = module.get(GroupsService); - }); + service = module.get(GroupsService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts index 25ffa297c0d8..10b164b3d82f 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts @@ -5,14 +5,12 @@ import { CreatedAt, DataType, ForeignKey, - HasMany, - HasOne, Model, Table, UpdatedAt, } from 'sequelize-typescript' -import { Input } from '../../inputs/models/input.model' import { TimeIntervals } from '../../../enums/timeIntervals' +import { Input } from '../../inputs/models/input.model' @Table({ tableName: 'input_settings' }) export class InputSettings extends Model { diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts index 66d74026a461..06d5a5362686 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { InputsController } from './inputs.controller'; +import { Test, TestingModule } from '@nestjs/testing' +import { InputsController } from './inputs.controller' describe('InputsController', () => { - let controller: InputsController; + let controller: InputsController beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [InputsController], - }).compile(); + }).compile() - controller = module.get(InputsController); - }); + controller = module.get(InputsController) + }) it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); + expect(controller).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts index 3640b002c122..e748fef94709 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts @@ -1,14 +1,13 @@ import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' +import { InputSettings } from '../inputSettings/models/inputSettings.model' import { InputsController } from './inputs.controller' import { InputsService } from './inputs.service' +import { InputMapper } from './models/input.mapper' import { Input } from './models/input.model' -import { SequelizeModule } from '@nestjs/sequelize' import { InputType } from './models/inputType.model' -import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { InputSettingsModule } from '../inputSettings/inputSettings.module' -import { InputSettingsService } from '../inputSettings/inputSettings.service' -import { InputMapper } from './models/input.mapper' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' @Module({ imports: [SequelizeModule.forFeature([Input, InputType, InputSettings])], diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts index 92179dd23402..3a5adb4ff960 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { InputsService } from './inputs.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { InputsService } from './inputs.service' describe('InputsService', () => { - let service: InputsService; + let service: InputsService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [InputsService], - }).compile(); + }).compile() - service = module.get(InputsService); - }); + service = module.get(InputsService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts index 85add67342f8..e3fb9e3a4a45 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -1,13 +1,11 @@ import { Injectable, NotFoundException } from '@nestjs/common' -import { Input } from './models/input.model' -import { CreateInputDto } from './models/dto/createInput.dto' import { InjectModel } from '@nestjs/sequelize' -import { UpdateInputDto } from './models/dto/updateInput.dto' -import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { InputDto } from './models/dto/input.dto' import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { CreateInputDto } from './models/dto/createInput.dto' +import { InputDto } from './models/dto/input.dto' +import { UpdateInputDto } from './models/dto/updateInput.dto' import { InputMapper } from './models/input.mapper' -import { TextboxInputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' +import { Input } from './models/input.model' @Injectable() export class InputsService { diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts index 96b30cf6a6f4..7bf7205e1698 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts @@ -1,5 +1,4 @@ import { ApiProperty } from '@nestjs/swagger' -import { InputType } from '../inputType.model' export class CreateInputDto { @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts index 7fb7ce36e2ac..dd6ec454b505 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts @@ -1,11 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettings } from '../../../inputSettings/models/inputSettings.model' -import { InputType } from '../inputType.model' -import { - InputSettingsDto, - TextboxInputSettingsDto, -} from '../../../inputSettings/models/dto/inputSettings.dto' +import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' export class InputDto { @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts index 54764da0dbad..5e788cd621c1 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts @@ -1,7 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettings } from '../../../inputSettings/models/inputSettings.model' -import { InputType } from '../inputType.model' import { UpdateInputSettingsDto } from '../../../inputSettings/models/dto/updateInputSettings.dto' export class UpdateInputDto { diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts index 86311131fc48..e4838aaec76c 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts @@ -1,11 +1,8 @@ import { Injectable } from '@nestjs/common' +import { InputSettingsDto } from '../../inputSettings/models/dto/inputSettings.dto' import { InputDto } from './dto/input.dto' -import { Input } from './input.model' import { UpdateInputDto } from './dto/updateInput.dto' -import { - InputSettingsDto, - TextboxInputSettingsDto, -} from '../../inputSettings/models/dto/inputSettings.dto' +import { Input } from './input.model' @Injectable() export class InputMapper { diff --git a/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts b/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts index 13931e4e683f..dd809b44d626 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts @@ -1,20 +1,18 @@ import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional, NonAttribute } from 'sequelize' import { BelongsToMany, Column, CreatedAt, DataType, - ForeignKey, HasMany, - HasOne, Model, Table, UpdatedAt, } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' -import { CreationOptional, NonAttribute } from 'sequelize' -import { Input } from './input.model' import { Organization } from '../../organizations/models/organization.model' +import { Input } from './input.model' @Table({ tableName: 'input_types' }) export class InputType extends Model { diff --git a/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts index 402398a08f33..abc6b65cb7ed 100644 --- a/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts +++ b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts @@ -1,3 +1,4 @@ +import { CreationOptional } from 'sequelize' import { Column, CreatedAt, @@ -8,8 +9,6 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Organization } from '../../organizations/models/organization.model' -import { InputType } from '../../inputs/models/inputType.model' -import { CreationOptional } from 'sequelize' import { ListType } from './listType.model' @Table({ tableName: 'organization_list_types' }) diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index f53643c3f44d..c9e03af8f56b 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' -import { CreationOptional, NonAttribute, UUID, UUIDV4 } from 'sequelize' +import { CreationOptional, NonAttribute } from 'sequelize' import { BelongsToMany, Column, @@ -10,12 +10,12 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Form } from '../../forms/models/form.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { ApplicantTypeNameSuggestion } from '../../applicants/models/applicantTypeNameSuggestion.model' +import { Form } from '../../forms/models/form.model' import { InputType } from '../../inputs/models/inputType.model' -import { TestimonyType } from '../../testimonies/models/testimonyType.model' import { ListType } from '../../lists/models/listType.model' +import { TestimonyType } from '../../testimonies/models/testimonyType.model' @Table({ tableName: 'organizations' }) export class Organization extends Model { diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts index dbf544f27c11..125cba9400a0 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { OrganizationsController } from './organizations.controller'; +import { Test, TestingModule } from '@nestjs/testing' +import { OrganizationsController } from './organizations.controller' describe('OrganizationsController', () => { - let controller: OrganizationsController; + let controller: OrganizationsController beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ controllers: [OrganizationsController], - }).compile(); + }).compile() - controller = module.get(OrganizationsController); - }); + controller = module.get(OrganizationsController) + }) it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); + expect(controller).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts index c36588712703..a3ab5837b929 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts @@ -1,18 +1,18 @@ -import { Test, TestingModule } from '@nestjs/testing'; -import { OrganizationsService } from './organizations.service'; +import { Test, TestingModule } from '@nestjs/testing' +import { OrganizationsService } from './organizations.service' describe('OrganizationsService', () => { - let service: OrganizationsService; + let service: OrganizationsService beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ providers: [OrganizationsService], - }).compile(); + }).compile() - service = module.get(OrganizationsService); - }); + service = module.get(OrganizationsService) + }) it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); + expect(service).toBeDefined() + }) +}) diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.service.ts b/apps/services/form-system/src/app/modules/organizations/organizations.service.ts index 2a7558d61706..dbbc1621e227 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.service.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.service.ts @@ -1,17 +1,15 @@ import { Injectable } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' -import { Organization } from './models/organization.model' import { Form } from '../forms/models/form.model' import { CreateOrganizationDto } from './models/dto/createOrganization.dto' -import { InputType } from '../inputs/models/inputType.model' +import { Organization } from './models/organization.model' @Injectable() export class OrganizationsService { constructor( @InjectModel(Organization) - private readonly organizationModel: typeof Organization, // @InjectModel(InputType) - ) // private readonly inputTypeModel: typeof InputType, - {} + private readonly organizationModel: typeof Organization, + ) {} async findAll(): Promise { return await this.organizationModel.findAll() @@ -32,11 +30,4 @@ export class OrganizationsService { ) return await newOrganzation.save() } - - // async findInputTypes(organizationId: string): Promise { - // const commons = await this.inputTypeModel.findAll({ - // where: { isCommon: true }, - // }) - // return commons - // } } diff --git a/apps/services/form-system/src/app/modules/steps/models/step.model.ts b/apps/services/form-system/src/app/modules/steps/models/step.model.ts index 85afbbea5d21..76060d779284 100644 --- a/apps/services/form-system/src/app/modules/steps/models/step.model.ts +++ b/apps/services/form-system/src/app/modules/steps/models/step.model.ts @@ -1,20 +1,19 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional, DataTypes } from 'sequelize' import { Column, CreatedAt, DataType, ForeignKey, + HasMany, Model, Table, UpdatedAt, - HasMany, - Sequelize, } from 'sequelize-typescript' -import { CreationOptional, DataTypes } from 'sequelize' -import { Form } from '../../forms/models/form.model' -import { ApiProperty } from '@nestjs/swagger' -import { Group } from '../../groups/models/group.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { StepTypes } from '../../../enums/stepTypes' +import { Form } from '../../forms/models/form.model' +import { Group } from '../../groups/models/group.model' @Table({ tableName: 'steps' }) export class Step extends Model { diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts index 0ee8cc4bd298..9e5114c7afd2 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts @@ -1,11 +1,7 @@ -import { Test, TestingModule } from '@nestjs/testing' import { TestApp, testServer, useDatabase } from '@island.is/testing/nest' +import { SequelizeConfigService } from '../../sequelizeConfig.service' import { StepsController } from './steps.controller' import { StepsModule } from './steps.module' -import { StepsService } from './steps.service' -import { Step } from './models/step.model' -import { SequelizeModule } from '@nestjs/sequelize' -import { SequelizeConfigService } from '../../sequelizeConfig.service' describe('StepsController', () => { let controller: StepsController diff --git a/apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts b/apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts similarity index 79% rename from apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts rename to apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts index 73ac5ffcf2d9..8da00a0a7a6d 100644 --- a/apps/services/form-system/src/app/modules/testimonies/dto/formTestimonyType.dto.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' -import { LanguageType } from '../../../dataTypes/languageType.model' +import { LanguageType } from '../../../../dataTypes/languageType.model' export class FormTestimonyTypeDto { @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts b/apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts similarity index 79% rename from apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts rename to apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts index 4e2532095dc3..cb6366867db2 100644 --- a/apps/services/form-system/src/app/modules/testimonies/dto/testimonyType.dto.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' -import { LanguageType } from '../../../dataTypes/languageType.model' +import { LanguageType } from '../../../../dataTypes/languageType.model' export class TestimonyTypeDto { @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts index d09199a1d18f..b5bce82bbf49 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts @@ -1,3 +1,4 @@ +import { CreationOptional } from 'sequelize' import { Column, CreatedAt, @@ -7,10 +8,8 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { InputType } from '../../inputs/models/inputType.model' -import { CreationOptional } from 'sequelize' -import { TestimonyType } from '../../testimonies/models/testimonyType.model' import { Form } from '../../forms/models/form.model' +import { TestimonyType } from '../../testimonies/models/testimonyType.model' @Table({ tableName: 'form_testimony_types' }) export class FormTestimonyType extends Model { diff --git a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts index a5005f7b47f2..f3b5a943f265 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts @@ -1,3 +1,4 @@ +import { CreationOptional } from 'sequelize' import { Column, CreatedAt, @@ -8,8 +9,6 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Organization } from '../../organizations/models/organization.model' -import { InputType } from '../../inputs/models/inputType.model' -import { CreationOptional } from 'sequelize' import { TestimonyType } from './testimonyType.model' @Table({ tableName: 'organization_testimony_types' }) diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts index 42b61f646ac9..bb88da7f0784 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts @@ -10,7 +10,7 @@ import { } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' -import { TestimonyTypes } from './testimonyTypes' +import { TestimonyTypes } from '../../../enums/testimonyTypes' import { Organization } from '../../organizations/models/organization.model' import { Form } from '../../forms/models/form.model' diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts deleted file mode 100644 index 20c50cf7ecda..000000000000 --- a/apps/services/form-system/src/app/modules/testimonies/models/testimonyTypes.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const TestimonyTypes = { - estateGuardianshipCertificateStamped: 'estateGuardianshipCertificateStamped', - estateGuardianshipCertificateUnstamped: - 'estateGuardianshipCertificateUnstamped', - residenceCertificate: 'residenceCertificate', - indebtednessCertificate: 'indebtednessCertificate', - criminalRecordStamped: 'criminalRecordStamped', - criminalRecordUnstamped: 'criminalRecordUnstamped', -} From 08f76df98d58f270f087533f30cadd9f7484d725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Wed, 26 Jun 2024 09:13:45 +0000 Subject: [PATCH 40/72] Add functionality to create and edit custom lists --- .../20240612095843-create-input-settings.js | 12 ++- .../20240621165216-create-list-item.js | 68 +++++++++++++++ .../form-system/src/app/app.module.ts | 2 + .../src/app/dataTypes/listItem.model.ts | 22 ----- .../form-system/src/app/enums/listTypes.ts | 8 ++ .../src/app/modules/forms/forms.module.ts | 5 +- .../src/app/modules/forms/forms.service.ts | 15 +++- .../app/modules/groups/groups.controller.ts | 12 +++ .../src/app/modules/groups/groups.service.ts | 19 +++++ .../models/dto/groupDisplayOrder.dto.ts | 9 ++ .../groups/models/dto/updateGroup.dto.ts | 3 - .../dto/updateGroupsDisplayOrder.dto.ts | 7 ++ .../inputSettings/inputSettings.module.ts | 6 +- .../inputSettings/inputSettings.service.ts | 13 ++- .../models/dto/inputSettings.dto.ts | 8 +- .../models/dto/updateInputSettings.dto.ts | 2 +- .../models/inputSettings.mapper.ts | 20 +++-- .../models/inputSettings.model.ts | 14 +++- .../app/modules/inputs/inputs.controller.ts | 12 +++ .../src/app/modules/inputs/inputs.module.ts | 2 + .../src/app/modules/inputs/inputs.service.ts | 22 +++++ .../models/dto/inputDisplayOrder.dto.ts | 9 ++ .../inputs/models/dto/updateInput.dto.ts | 3 - .../dto/updateInputsDisplayOrder.dto.ts | 7 ++ .../models/organizationInputType.model.ts | 4 +- .../modules/listItems/listItems.controller.ts | 45 ++++++++++ .../app/modules/listItems/listItems.module.ts | 22 +++++ .../modules/listItems/listItems.service.ts | 84 +++++++++++++++++++ .../models/dto/createListItem.dto.ts | 9 ++ .../listItems/models/dto/listItem.dto.ts | 22 +++++ .../models/dto/listItemDisplayOrder.dto.ts | 6 ++ .../models/dto/updateListItem.dto.ts | 16 ++++ .../dto/updateListItemsDisplayOrder.dto.ts | 7 ++ .../listItems/models/listItem.mapper.ts | 44 ++++++++++ .../listItems/models/listItem.model.ts | 80 ++++++++++++++++++ .../modules/lists/models/listType.model.ts | 2 +- .../src/app/modules/lists/models/listTypes.ts | 7 -- .../steps/models/dto/stepDisplayOrder.dto.ts | 6 ++ .../steps/models/dto/updateStep.dto.ts | 3 - .../models/dto/updateStepsDisplayOrder.dto.ts | 7 ++ .../modules/steps/steps.controller.spec.ts | 40 ++++----- .../src/app/modules/steps/steps.controller.ts | 12 +++ .../src/app/modules/steps/steps.service.ts | 22 ++++- apps/services/form-system/src/main.ts | 4 +- 44 files changed, 652 insertions(+), 90 deletions(-) create mode 100644 apps/services/form-system/migrations/20240621165216-create-list-item.js delete mode 100644 apps/services/form-system/src/app/dataTypes/listItem.model.ts create mode 100644 apps/services/form-system/src/app/enums/listTypes.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts rename apps/services/form-system/src/app/modules/{organizations => inputs}/models/organizationInputType.model.ts (87%) create mode 100644 apps/services/form-system/src/app/modules/listItems/listItems.controller.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/listItems.module.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/listItems.service.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/listItem.mapper.ts create mode 100644 apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts delete mode 100644 apps/services/form-system/src/app/modules/lists/models/listTypes.ts create mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts diff --git a/apps/services/form-system/migrations/20240612095843-create-input-settings.js b/apps/services/form-system/migrations/20240612095843-create-input-settings.js index 0d4fea5b08a2..474105e0f185 100644 --- a/apps/services/form-system/migrations/20240612095843-create-input-settings.js +++ b/apps/services/form-system/migrations/20240612095843-create-input-settings.js @@ -78,8 +78,15 @@ module.exports = { type: Sequelize.BOOLEAN, allowNull: true, }, - list: { - type: Sequelize.JSON, + list_type: { + type: Sequelize.ENUM( + 'custom', + 'municipalities', + 'countries', + 'postalCodes', + 'mastersTrades', + 'registrationCategoriesOfActivities', + ), allowNull: true, }, file_types: { @@ -105,6 +112,7 @@ module.exports = { }, input_id: { type: Sequelize.UUID, + onDelete: 'CASCADE', allowNull: false, references: { model: 'inputs', diff --git a/apps/services/form-system/migrations/20240621165216-create-list-item.js b/apps/services/form-system/migrations/20240621165216-create-list-item.js new file mode 100644 index 000000000000..2e216c5142c4 --- /dev/null +++ b/apps/services/form-system/migrations/20240621165216-create-list-item.js @@ -0,0 +1,68 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'list_items', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + label: { + type: Sequelize.JSON, + allowNull: false, + }, + description: { + type: Sequelize.JSON, + allowNull: true, + }, + value: { + type: Sequelize.STRING, + allowNull: false, + defaultValue: '', + }, + is_selected: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, + display_order: { + type: Sequelize.INTEGER, + allowNull: false, + defaultValue: 0, + }, + input_settings_id: { + type: Sequelize.UUID, + onDelete: 'CASCADE', + allowNull: false, + references: { + model: 'input_settings', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('list_items', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index a16a7076b35c..64c122ed4cf4 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -13,6 +13,7 @@ import { OrganizationsModule } from './modules/organizations/organizations.modul import { StepsModule } from './modules/steps/steps.module' import { TestimoniesModule } from './modules/testimonies/testimonies.module' import { SequelizeConfigService } from './sequelizeConfig.service' +import { ListItemsModule } from './modules/listItems/listItems.module' @Module({ imports: [ @@ -30,6 +31,7 @@ import { SequelizeConfigService } from './sequelizeConfig.service' TestimoniesModule, ListsModule, InputSettingsModule, + ListItemsModule, ], }) export class AppModule {} diff --git a/apps/services/form-system/src/app/dataTypes/listItem.model.ts b/apps/services/form-system/src/app/dataTypes/listItem.model.ts deleted file mode 100644 index 435192b3dddc..000000000000 --- a/apps/services/form-system/src/app/dataTypes/listItem.model.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { LanguageType } from './languageType.model' - -export class ListItem { - @ApiProperty() - id?: string - - @ApiProperty({ type: LanguageType }) - label!: LanguageType - - @ApiProperty({ type: LanguageType }) - description?: LanguageType - - @ApiProperty() - value?: string - - @ApiProperty() - displayOrder?: number - - @ApiProperty() - isSelected!: boolean -} diff --git a/apps/services/form-system/src/app/enums/listTypes.ts b/apps/services/form-system/src/app/enums/listTypes.ts new file mode 100644 index 000000000000..c7306283eabf --- /dev/null +++ b/apps/services/form-system/src/app/enums/listTypes.ts @@ -0,0 +1,8 @@ +export const ListTypes = { + CUSTOM: 'custom', + MUNICIPALITIES: 'municipalities', + COUNTRIES: 'countries', + POSTAL_CODES: 'postalCodes', + MASTERS_TRADES: 'mastersTrades', + REGISTRATION_CATEGORIES_OF_ACTIVITIES: 'registrationCategoriesOfActivities', +} diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index 88f53978fc0a..d2abdc7984e6 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -11,6 +11,8 @@ import { TestimonyType } from '../testimonies/models/testimonyType.model' import { FormsController } from './forms.controller' import { FormsService } from './forms.service' import { Form } from './models/form.model' +import { ListItemMapper } from '../listItems/models/listItem.mapper' +import { ListItem } from '../listItems/models/listItem.model' @Module({ imports: [ @@ -23,9 +25,10 @@ import { Form } from './models/form.model' InputType, TestimonyType, ListType, + ListItem, ]), ], controllers: [FormsController], - providers: [FormsService, InputSettingsMapper], + providers: [FormsService, InputSettingsMapper, ListItemMapper], }) export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 9db73da7a8a4..02c4d3799ad2 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -23,6 +23,7 @@ import { CreateFormDto } from './models/dto/createForm.dto' import { FormDto } from './models/dto/form.dto' import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' +import { ListItem } from '../listItems/models/listItem.model' @Injectable() export class FormsService { @@ -109,6 +110,12 @@ export class FormsService { { model: InputSettings, as: 'inputSettings', + include: [ + { + model: ListItem, + as: 'list', + }, + ], }, ], }, @@ -183,7 +190,7 @@ export class FormsService { name: inputType.name, description: inputType.description, isCommon: inputType.isCommon, - inputSettings: this.inputSettingsMapper.mapInputTypeToInputSettings( + inputSettings: this.inputSettingsMapper.mapInputTypeToInputSettingsDto( null, inputType.type, ), @@ -293,7 +300,11 @@ export class FormsService { description: input.description, isHidden: input.isHidden, isPartOfMultiset: input.isPartOfMultiset, - inputSettings: input.inputSettings, + inputSettings: + this.inputSettingsMapper.mapInputTypeToInputSettingsDto( + input.inputSettings, + input.inputType, + ), inputType: input.inputType, } as InputDto) }) diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.ts index 92f85802f631..537b091a4963 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.controller.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.controller.ts @@ -15,6 +15,7 @@ import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' import { UpdateGroupDto } from './models/dto/updateGroup.dto' import { GroupDto } from './models/dto/group.dto' +import { UpdateGroupsDisplayOrderDto } from './models/dto/updateGroupsDisplayOrder.dto' @ApiTags('groups') @Controller('groups') @@ -57,6 +58,17 @@ export class GroupsController { return await this.groupsService.update(id, updateGroupDto) } + @Put() + @Documentation({ + description: 'Update display order of groups', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateGroupsDisplayOrderDto: UpdateGroupsDisplayOrderDto, + ): Promise { + return this.groupsService.updateDisplayOrder(updateGroupsDisplayOrderDto) + } + @Delete(':id') async delete(@Param('id') id: string): Promise { return this.groupsService.delete(id) diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.ts b/apps/services/form-system/src/app/modules/groups/groups.service.ts index 4601d6147bbf..cbcdd1640c19 100644 --- a/apps/services/form-system/src/app/modules/groups/groups.service.ts +++ b/apps/services/form-system/src/app/modules/groups/groups.service.ts @@ -5,6 +5,7 @@ import { Input } from '../inputs/models/input.model' import { CreateGroupDto } from './models/dto/createGroup.dto' import { UpdateGroupDto } from './models/dto/updateGroup.dto' import { GroupDto } from './models/dto/group.dto' +import { UpdateGroupsDisplayOrderDto } from './models/dto/updateGroupsDisplayOrder.dto' @Injectable() export class GroupsService { @@ -53,6 +54,24 @@ export class GroupsService { return groupDto } + async updateDisplayOrder( + updateGroupsDisplayOrderDto: UpdateGroupsDisplayOrderDto, + ): Promise { + const { groupsDisplayOrderDto } = updateGroupsDisplayOrderDto + + for (let i = 0; i < groupsDisplayOrderDto.length; i++) { + const group = await this.groupModel.findByPk(groupsDisplayOrderDto[i].id) + + if (!group) { + throw new NotFoundException( + `Group with id '${groupsDisplayOrderDto[i].id}' not found`, + ) + } + + group.update({ displayOrder: i, stepId: groupsDisplayOrderDto[i].stepId }) + } + } + async delete(id: string): Promise { const group = await this.findOne(id) group?.destroy() diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts new file mode 100644 index 000000000000..38333a682469 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class GroupDisplayOrderDto { + @ApiProperty() + id!: string + + @ApiProperty() + stepId!: string +} diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts index 8fcfb5359e51..a01611de5dcc 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts +++ b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts @@ -5,9 +5,6 @@ export class UpdateGroupDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty() - displayOrder!: number - @ApiProperty() multiset!: number } diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts new file mode 100644 index 000000000000..84608f082349 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { GroupDisplayOrderDto } from './groupDisplayOrder.dto' + +export class UpdateGroupsDisplayOrderDto { + @ApiProperty({ type: [GroupDisplayOrderDto] }) + groupsDisplayOrderDto!: GroupDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts index fd21f8fa819f..55ef0e7f9e0c 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts @@ -3,10 +3,12 @@ import { SequelizeModule } from '@nestjs/sequelize' import { InputSettings } from './models/inputSettings.model' import { InputSettingsService } from './inputSettings.service' import { InputSettingsMapper } from './models/inputSettings.mapper' +import { ListItemMapper } from '../listItems/models/listItem.mapper' +import { ListItem } from '../listItems/models/listItem.model' @Module({ - imports: [SequelizeModule.forFeature([InputSettings])], - providers: [InputSettingsService, InputSettingsMapper], + imports: [SequelizeModule.forFeature([InputSettings, ListItem])], + providers: [InputSettingsService, InputSettingsMapper, ListItemMapper], exports: [InputSettingsService], }) export class InputSettingsModule {} diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts index 2b59273fde01..8ae1ecbbee63 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts @@ -4,6 +4,7 @@ import { UpdateInputSettingsDto } from './models/dto/updateInputSettings.dto' import { InjectModel } from '@nestjs/sequelize' import { InputSettingsMapper } from './models/inputSettings.mapper' import { InputSettingsDto } from './models/dto/inputSettings.dto' +import { ListItem } from '../listItems/models/listItem.model' @Injectable() export class InputSettingsService { @@ -24,6 +25,7 @@ export class InputSettingsService { async findByInputId(inputId: string): Promise { const inputSettings = await this.inputSettingsModel.findOne({ where: { inputId: inputId }, + include: [{ model: ListItem, as: 'list' }], }) if (!inputSettings) { @@ -38,10 +40,13 @@ export class InputSettingsService { async findOne(inputId: string, inputType: string): Promise { const inputSettings = await this.findByInputId(inputId) - return this.inputSettingsMapper.mapInputTypeToInputSettings( - inputSettings, - inputType, - ) + const inputSettingsDto = + this.inputSettingsMapper.mapInputTypeToInputSettingsDto( + inputSettings, + inputType, + ) + + return inputSettingsDto } async update( diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts b/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts index 5fc8889159e1..4e673961b890 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' +import { ListItemDto } from '../../../listItems/models/dto/listItem.dto' export class InputSettingsDto { @ApiProperty() @@ -43,8 +44,11 @@ export class InputSettingsDto { @ApiProperty() hasPropertyList?: boolean + @ApiProperty({ type: [ListItemDto] }) + list?: ListItemDto[] + @ApiProperty() - list?: string + listType?: string @ApiProperty() fileTypes?: string @@ -81,7 +85,7 @@ export class DatePickerInputSettingsDto extends (InputSettingsDto as new () => P export class DropdownListInputSettingsDto extends (InputSettingsDto as new () => Pick< InputSettingsDto, - 'list' + 'list' | 'listType' >) {} export class RadioButtonsInputSettingsDto extends (InputSettingsDto as new () => Pick< diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts b/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts index 1cc7790e6bd8..8e9e6322e5bd 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts @@ -44,7 +44,7 @@ export class UpdateInputSettingsDto { hasPropertyList?: boolean @ApiProperty() - list?: string + listType?: string @ApiProperty() fileTypes?: string diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts index bf6cf72c4eca..e298dfa35f57 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts @@ -14,14 +14,15 @@ import { TextboxInputSettingsDto, TimeInputInputSettingsDto, } from './dto/inputSettings.dto' +import { ListItemMapper } from '../../listItems/models/listItem.mapper' @Injectable() export class InputSettingsMapper { + constructor(private readonly listItemMapper: ListItemMapper) {} mapUpdateInputSettingsDtoToInputSettings( inputSettings: InputSettings, updateInputSettingsDto: UpdateInputSettingsDto, ): void { - console.log(updateInputSettingsDto.minLength) ;(inputSettings.modified = new Date()), (inputSettings.minValue = updateInputSettingsDto.minValue ?? null), (inputSettings.maxValue = updateInputSettingsDto.maxValue ?? null), @@ -39,17 +40,15 @@ export class InputSettingsMapper { updateInputSettingsDto.hasPropertyInput ?? null), (inputSettings.hasPropertyList = updateInputSettingsDto.hasPropertyList ?? null), - (inputSettings.list = updateInputSettingsDto.list ?? null), + (inputSettings.listType = updateInputSettingsDto.listType ?? null), (inputSettings.fileTypes = updateInputSettingsDto.fileTypes ?? null), (inputSettings.fileMaxSize = updateInputSettingsDto.fileMaxSize ?? null), (inputSettings.maxFiles = updateInputSettingsDto.maxFiles ?? null), (inputSettings.timeInterval = updateInputSettingsDto.timeInterval ?? null) - - console.log(inputSettings.minLength) } - mapInputTypeToInputSettings( - inputSettings: InputSettings | null, + mapInputTypeToInputSettingsDto( + inputSettings: InputSettings | null | undefined, inputType: string, ): InputSettingsDto { switch (inputType) { @@ -78,11 +77,16 @@ export class InputSettingsMapper { } as DatePickerInputSettingsDto case 'dropdownList': return { - list: inputSettings ? inputSettings.list : null, + list: inputSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(inputSettings.list) + : '', + listType: inputSettings?.listType ? inputSettings.listType : '', } as DropdownListInputSettingsDto case 'radioButtons': return { - list: inputSettings ? inputSettings.list : null, + list: inputSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(inputSettings.list) + : null, } as RadioButtonsInputSettingsDto case 'iskNumberbox': return { diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts index 10b164b3d82f..8b3457eebcdd 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts +++ b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts @@ -5,12 +5,15 @@ import { CreatedAt, DataType, ForeignKey, + HasMany, Model, Table, UpdatedAt, } from 'sequelize-typescript' import { TimeIntervals } from '../../../enums/timeIntervals' import { Input } from '../../inputs/models/input.model' +import { ListTypes } from '../../../enums/listTypes' +import { ListItem } from '../../listItems/models/listItem.model' @Table({ tableName: 'input_settings' }) export class InputSettings extends Model { @@ -129,12 +132,17 @@ export class InputSettings extends Model { @ApiProperty() hasPropertyList?: boolean | null + @HasMany(() => ListItem) + @ApiProperty({ type: [ListItem] }) + list?: ListItem[] | null + @Column({ - type: DataType.JSON, + type: DataType.ENUM, allowNull: true, + values: Object.values(ListTypes), }) - @ApiProperty() - list?: string | null + @ApiProperty({ enum: ListTypes }) + listType?: string | null @Column({ type: DataType.JSON, diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts index 6099761972c3..bbe08321a5dd 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts @@ -15,6 +15,7 @@ import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' import { UpdateInputDto } from './models/dto/updateInput.dto' import { InputDto } from './models/dto/input.dto' +import { UpdateInputsDisplayOrderDto } from './models/dto/updateInputsDisplayOrder.dto' @ApiTags('inputs') @Controller('inputs') @@ -57,6 +58,17 @@ export class InputsController { await this.inputsService.update(id, updateInputDto) } + @Put() + @Documentation({ + description: 'Update display order of inputs', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateInputsDisplayOrderDto: UpdateInputsDisplayOrderDto, + ): Promise { + return this.inputsService.updateDisplayOrder(updateInputsDisplayOrderDto) + } + @Delete(':id') async delete(@Param('id') id: string): Promise { return this.inputsService.delete(id) diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts index e748fef94709..40778a1243a0 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts @@ -8,6 +8,7 @@ import { InputsService } from './inputs.service' import { InputMapper } from './models/input.mapper' import { Input } from './models/input.model' import { InputType } from './models/inputType.model' +import { ListItemMapper } from '../listItems/models/listItem.mapper' @Module({ imports: [SequelizeModule.forFeature([Input, InputType, InputSettings])], @@ -17,6 +18,7 @@ import { InputType } from './models/inputType.model' InputSettingsService, InputMapper, InputSettingsMapper, + ListItemMapper, ], }) export class InputsModule {} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts index e3fb9e3a4a45..ac7cc68a8b40 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -6,6 +6,7 @@ import { InputDto } from './models/dto/input.dto' import { UpdateInputDto } from './models/dto/updateInput.dto' import { InputMapper } from './models/input.mapper' import { Input } from './models/input.model' +import { UpdateInputsDisplayOrderDto } from './models/dto/updateInputsDisplayOrder.dto' @Injectable() export class InputsService { @@ -76,6 +77,27 @@ export class InputsService { await input.save() } + async updateDisplayOrder( + updateInputsDisplayOrderDto: UpdateInputsDisplayOrderDto, + ): Promise { + const { inputsDisplayOrderDto } = updateInputsDisplayOrderDto + + for (let i = 0; i < inputsDisplayOrderDto.length; i++) { + const input = await this.inputModel.findByPk(inputsDisplayOrderDto[i].id) + + if (!input) { + throw new NotFoundException( + `Input with id '${inputsDisplayOrderDto[i].id}' not found`, + ) + } + + await input.update({ + displayOrder: i, + groupId: inputsDisplayOrderDto[i].groupId, + }) + } + } + async delete(id: string): Promise { const input = await this.findById(id) input?.destroy() diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts new file mode 100644 index 000000000000..89cc4030e955 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class InputDisplayOrderDto { + @ApiProperty() + id!: string + + @ApiProperty() + groupId!: string +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts index 5e788cd621c1..349087c920ba 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts @@ -6,9 +6,6 @@ export class UpdateInputDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty() - displayOrder!: number - @ApiProperty({ type: LanguageType }) description!: LanguageType diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts new file mode 100644 index 000000000000..5f641c5d9c79 --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { InputDisplayOrderDto } from './inputDisplayOrder.dto' + +export class UpdateInputsDisplayOrderDto { + @ApiProperty({ type: [InputDisplayOrderDto] }) + inputsDisplayOrderDto!: InputDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts b/apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts similarity index 87% rename from apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts rename to apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts index c96d4676bbc4..4c9d693a0635 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organizationInputType.model.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts @@ -7,8 +7,8 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Organization } from './organization.model' -import { InputType } from '../../inputs/models/inputType.model' +import { Organization } from '../../organizations/models/organization.model' +import { InputType } from './inputType.model' import { CreationOptional } from 'sequelize' @Table({ tableName: 'organization_input_types' }) diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts b/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts new file mode 100644 index 000000000000..90ae7abd511f --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts @@ -0,0 +1,45 @@ +import { Body, Controller, Param, Post, Put, Delete } from '@nestjs/common' +import { ApiTags } from '@nestjs/swagger' +import { ListItemsService } from './listItems.service' +import { CreateListItemDto } from './models/dto/createListItem.dto' +import { ListItemDto } from './models/dto/listItem.dto' +import { UpdateListItemDto } from './models/dto/updateListItem.dto' +import { UpdateListItemsDisplayOrderDto } from './models/dto/updateListItemsDisplayOrder.dto' +import { Documentation } from '@island.is/nest/swagger' + +@ApiTags('list items') +@Controller('listItems') +export class ListItemsController { + constructor(private readonly listItemsService: ListItemsService) {} + + @Post() + create(@Body() createListItem: CreateListItemDto): Promise { + return this.listItemsService.create(createListItem) + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateListItemDto: UpdateListItemDto, + ): Promise { + return this.listItemsService.update(id, updateListItemDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.listItemsService.delete(id) + } + + @Put() + @Documentation({ + description: 'Update display order of list items', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateListItemsDisplayOrderDto: UpdateListItemsDisplayOrderDto, + ): Promise { + return this.listItemsService.updateDisplayOrder( + updateListItemsDisplayOrderDto, + ) + } +} diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.module.ts b/apps/services/form-system/src/app/modules/listItems/listItems.module.ts new file mode 100644 index 000000000000..758382087457 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/listItems.module.ts @@ -0,0 +1,22 @@ +import { SequelizeModule } from '@nestjs/sequelize' +import { ListItem } from './models/listItem.model' +import { ListItemsService } from './listItems.service' +import { Module } from '@nestjs/common' +import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { InputSettings } from '../inputSettings/models/inputSettings.model' +import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' +import { ListItemsController } from './listItems.controller' +import { ListItemMapper } from './models/listItem.mapper' + +@Module({ + imports: [SequelizeModule.forFeature([ListItem, InputSettings])], + controllers: [ListItemsController], + providers: [ + ListItemsService, + InputSettingsService, + InputSettingsMapper, + ListItemMapper, + ], + exports: [ListItemsService, ListItemMapper], +}) +export class ListItemsModule {} diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.service.ts b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts new file mode 100644 index 000000000000..271c748e38ee --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts @@ -0,0 +1,84 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { ListItem } from './models/listItem.model' +import { ListItemDto } from './models/dto/listItem.dto' +import { CreateListItemDto } from './models/dto/createListItem.dto' +import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { ListItemMapper } from './models/listItem.mapper' +import { UpdateListItemDto } from './models/dto/updateListItem.dto' +import { UpdateListItemsDisplayOrderDto } from './models/dto/updateListItemsDisplayOrder.dto' + +@Injectable() +export class ListItemsService { + constructor( + @InjectModel(ListItem) + private readonly listItemModel: typeof ListItem, + private readonly inputSettingsService: InputSettingsService, + private listItemMapper: ListItemMapper, + ) {} + + async findById(id: string): Promise { + const listItem = await this.listItemModel.findByPk(id) + + if (!listItem) { + throw new NotFoundException(`List item with id '${id}' not found`) + } + + return listItem + } + + async create(createListItem: CreateListItemDto): Promise { + const inputSettings = await this.inputSettingsService.findByInputId( + createListItem.inputId, + ) + + const listItem = await this.listItemModel.create({ + inputSettingsId: inputSettings.id, + displayOrder: createListItem.displayOrder, + } as ListItem) + + return this.listItemMapper.mapListItemToListItemDto(listItem) + } + + async update( + id: string, + updateListItemDto: UpdateListItemDto, + ): Promise { + const listItem = await this.findById(id) + + this.listItemMapper.mapUpdateListItemDtoToListItem( + listItem, + updateListItemDto, + ) + listItem.modified = new Date() + + await listItem.save() + } + + async updateDisplayOrder( + updateListItemsDisplayOrderDto: UpdateListItemsDisplayOrderDto, + ): Promise { + const { listItemsDisplayOrderDto } = updateListItemsDisplayOrderDto + + for (let i = 0; i < listItemsDisplayOrderDto.length; i++) { + const listItem = await this.listItemModel.findByPk( + listItemsDisplayOrderDto[i].id, + ) + + if (!listItem) { + throw new NotFoundException( + `List item with id '${listItemsDisplayOrderDto[i].id}' not found`, + ) + } + + await listItem.update({ + displayOrder: i, + }) + } + } + + async delete(id: string): Promise { + const listItem = await this.findById(id) + listItem?.destroy() + } +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts new file mode 100644 index 000000000000..be42d0438b4e --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class CreateListItemDto { + @ApiProperty() + inputId!: string + + @ApiProperty() + displayOrder!: number +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts new file mode 100644 index 000000000000..dbc670b10680 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts @@ -0,0 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class ListItemDto { + @ApiProperty() + id!: string + + @ApiProperty() + label!: LanguageType + + @ApiProperty() + description?: LanguageType + + @ApiProperty() + value!: string + + @ApiProperty() + displayOrder!: number + + @ApiProperty() + isSelected!: boolean +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts new file mode 100644 index 000000000000..a5242a87c7e4 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class ListItemDisplayOrderDto { + @ApiProperty() + id!: string +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts new file mode 100644 index 000000000000..d1e861cf4b0d --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts @@ -0,0 +1,16 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class UpdateListItemDto { + @ApiProperty() + label!: LanguageType + + @ApiProperty() + description?: LanguageType + + @ApiProperty() + value!: string + + @ApiProperty() + isSelected!: boolean +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts new file mode 100644 index 000000000000..0a007cb166b6 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { ListItemDisplayOrderDto } from './listItemDisplayOrder.dto' + +export class UpdateListItemsDisplayOrderDto { + @ApiProperty({ type: [ListItemDisplayOrderDto] }) + listItemsDisplayOrderDto!: ListItemDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/listItem.mapper.ts b/apps/services/form-system/src/app/modules/listItems/models/listItem.mapper.ts new file mode 100644 index 000000000000..846876ae4415 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/listItem.mapper.ts @@ -0,0 +1,44 @@ +import { Injectable } from '@nestjs/common' +import { ListItem } from './listItem.model' +import { ListItemDto } from './dto/listItem.dto' +import { UpdateListItemDto } from './dto/updateListItem.dto' + +@Injectable() +export class ListItemMapper { + mapListItemsToListItemsDto(listItems: ListItem[]): ListItemDto[] { + const listItemsDto: ListItemDto[] = listItems.map((listItem) => { + return { + id: listItem.id, + label: listItem.label, + description: listItem.description, + value: listItem.value, + displayOrder: listItem.displayOrder, + isSelected: listItem.isSelected, + } as ListItemDto + }) + return listItemsDto + } + + mapListItemToListItemDto(listItem: ListItem): ListItemDto { + const listItemDto: ListItemDto = { + id: listItem.id, + label: listItem.label, + description: listItem.description, + value: listItem.value, + displayOrder: listItem.displayOrder, + isSelected: listItem.isSelected, + } + + return listItemDto + } + + mapUpdateListItemDtoToListItem( + listItem: ListItem, + updateListItemDto: UpdateListItemDto, + ): void { + listItem.label = updateListItemDto.label + listItem.description = updateListItemDto.description + listItem.value = updateListItemDto.value + listItem.isSelected = updateListItemDto.isSelected + } +} diff --git a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts new file mode 100644 index 000000000000..8c147fcc7225 --- /dev/null +++ b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts @@ -0,0 +1,80 @@ +import { ApiProperty } from '@nestjs/swagger' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { LanguageType } from '../../../dataTypes/languageType.model' +import { CreationOptional } from 'sequelize' +import { InputSettings } from '../../inputSettings/models/inputSettings.model' + +@Table({ tableName: 'list_items' }) +export class ListItem extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @Column({ + type: DataType.JSON, + allowNull: false, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + label!: LanguageType + + @Column({ + type: DataType.JSON, + allowNull: true, + defaultValue: () => new LanguageType(), + }) + @ApiProperty() + description?: LanguageType + + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + value!: string + + @Column({ + type: DataType.INTEGER, + allowNull: false, + defaultValue: 0, + }) + @ApiProperty() + displayOrder!: number + + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + isSelected!: boolean + + @ForeignKey(() => InputSettings) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'input_settings_id', + }) + inputSettingsId!: string +} diff --git a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts index 7e9af76fb74f..c134d4c2b48a 100644 --- a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts +++ b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts @@ -10,7 +10,7 @@ import { } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' -import { ListTypes } from './listTypes' +import { ListTypes } from '../../../enums/listTypes' import { Organization } from '../../organizations/models/organization.model' @Table({ tableName: 'list_types' }) diff --git a/apps/services/form-system/src/app/modules/lists/models/listTypes.ts b/apps/services/form-system/src/app/modules/lists/models/listTypes.ts deleted file mode 100644 index a8bc17b8ae5f..000000000000 --- a/apps/services/form-system/src/app/modules/lists/models/listTypes.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const ListTypes = { - municipalities: 'municipalities', - countries: 'countries', - postalCodes: 'postalCodes', - mastersTrades: 'mastersTrades', - registrationCategoriesOfActivities: 'registrationCategoriesOfActivities', -} diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts new file mode 100644 index 000000000000..5e3e42f9c87d --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger' + +export class StepDisplayOrderDto { + @ApiProperty() + id!: string +} diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts index 1191a5710bc8..80304f71c59e 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts +++ b/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts @@ -5,9 +5,6 @@ export class UpdateStepDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty() - displayOrder!: number - @ApiProperty({ type: LanguageType }) waitingText?: LanguageType diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts new file mode 100644 index 000000000000..7b83d9f72491 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { StepDisplayOrderDto } from './stepDisplayOrder.dto' + +export class UpdateStepsDisplayOrderDto { + @ApiProperty({ type: [StepDisplayOrderDto] }) + stepsDisplayOrderDto!: StepDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts index 9e5114c7afd2..96c9f42c0d5b 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts @@ -1,23 +1,23 @@ -import { TestApp, testServer, useDatabase } from '@island.is/testing/nest' -import { SequelizeConfigService } from '../../sequelizeConfig.service' -import { StepsController } from './steps.controller' -import { StepsModule } from './steps.module' +// import { TestApp, testServer, useDatabase } from '@island.is/testing/nest' +// import { SequelizeConfigService } from '../../sequelizeConfig.service' +// import { StepsController } from './steps.controller' +// import { StepsModule } from './steps.module' -describe('StepsController', () => { - let controller: StepsController - let app: TestApp +// describe('StepsController', () => { +// let controller: StepsController +// let app: TestApp - beforeEach(async () => { - app = await testServer({ - appModule: StepsModule, - hooks: [ - useDatabase({ type: 'postgres', provider: SequelizeConfigService }), - ], - }) - controller = app.get(StepsController) - }) +// beforeEach(async () => { +// app = await testServer({ +// appModule: StepsModule, +// hooks: [ +// useDatabase({ type: 'postgres', provider: SequelizeConfigService }), +// ], +// }) +// controller = app.get(StepsController) +// }) - it('should run', () => { - expect(true).toBeTruthy - }) -}) +// it('should run', () => { +// expect(true).toBeTruthy +// }) +// }) diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.ts index 5a04da03cc1c..e2111671e7c7 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.controller.ts @@ -15,6 +15,7 @@ import { Documentation } from '@island.is/nest/swagger' import { ApiTags } from '@nestjs/swagger' import { UpdateStepDto } from './models/dto/updateStep.dto' import { StepDto } from './models/dto/step.dto' +import { UpdateStepsDisplayOrderDto } from './models/dto/updateStepsDisplayOrder.dto' @ApiTags('steps') @Controller('steps') @@ -61,4 +62,15 @@ export class StepsController { ): Promise { return await this.stepsService.update(id, updateStepDto) } + + @Put() + @Documentation({ + description: 'Update display order of steps', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateStepsDisplayOrderDto: UpdateStepsDisplayOrderDto, + ): Promise { + return this.stepsService.updateDisplayOrder(updateStepsDisplayOrderDto) + } } diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.ts b/apps/services/form-system/src/app/modules/steps/steps.service.ts index 933f48b6864c..c309afe363fb 100644 --- a/apps/services/form-system/src/app/modules/steps/steps.service.ts +++ b/apps/services/form-system/src/app/modules/steps/steps.service.ts @@ -6,6 +6,7 @@ import { Group } from '../groups/models/group.model' import { Input } from '../inputs/models/input.model' import { UpdateStepDto } from './models/dto/updateStep.dto' import { StepDto } from './models/dto/step.dto' +import { UpdateStepsDisplayOrderDto } from './models/dto/updateStepsDisplayOrder.dto' @Injectable() export class StepsService { @@ -46,7 +47,6 @@ export class StepsService { const step = await this.findOne(id) step.name = updateStepDto.name - step.displayOrder = updateStepDto.displayOrder step.waitingText = updateStepDto.waitingText step.callRuleset = updateStepDto.callRuleset step.modified = new Date() @@ -65,6 +65,26 @@ export class StepsService { return stepDto } + async updateDisplayOrder( + updateStepsDisplayOrderDto: UpdateStepsDisplayOrderDto, + ): Promise { + const { stepsDisplayOrderDto } = updateStepsDisplayOrderDto + + for (let i = 0; i < stepsDisplayOrderDto.length; i++) { + const step = await this.stepModel.findByPk(stepsDisplayOrderDto[i].id) + + if (!step) { + throw new NotFoundException( + `Step with id '${stepsDisplayOrderDto[i].id}' not found`, + ) + } + + await step.update({ + displayOrder: i, + }) + } + } + async delete(id: string): Promise { const step = await this.findOne(id) step?.destroy() diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index b36967d25798..890020281fcf 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -12,10 +12,8 @@ const bootstrap = async () => { const app = await NestFactory.create(AppModule) const config = new DocumentBuilder() - .setTitle('FormSystem Api') - .setDescription('Api for FormSystem.') + .setTitle('Form System Api') .setVersion('1.0') - .addTag('form-system-api') .build() const document = SwaggerModule.createDocument(app, config) SwaggerModule.setup('api', app, document) From a55ed630fc4df2a35adb9e390a16af5c5ff4b676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Wed, 26 Jun 2024 13:25:35 +0000 Subject: [PATCH 41/72] application part start --- .../migrations/20240605120322-create-form.js | 5 ++ .../20240626093536-create-application.js | 44 ++++++++++ .../20240626093807-create-applicant.js | 88 +++++++++++++++++++ .../form-system/src/app/app.module.ts | 2 + .../applicants/models/applicant.model.ts | 22 +++-- .../applications/applications.controller.ts | 20 +++++ .../applications/applications.module.ts | 12 +++ .../applications/applications.service.ts | 20 +++++ .../applications/models/application.model.ts | 40 +++++++++ .../models/dto/application.dto.ts | 25 ++++++ .../src/app/modules/forms/forms.controller.ts | 7 +- .../src/app/modules/forms/forms.module.ts | 3 +- .../src/app/modules/forms/forms.service.ts | 14 ++- .../app/modules/forms/models/dto/form.dto.ts | 4 + .../modules/forms/models/dto/formsList.dto.ts | 7 ++ .../forms/models/dto/formsListForm.dto.ts | 34 +++++++ .../app/modules/forms/models/form.mapper.ts | 29 ++++++ .../app/modules/forms/models/form.model.ts | 7 ++ .../groups/models/dto/applicationGroup.dto.ts | 23 +++++ .../inputs/models/dto/applicationInput.dto.ts | 29 ++++++ .../steps/models/dto/applicationStep.dto.ts | 26 ++++++ 21 files changed, 448 insertions(+), 13 deletions(-) create mode 100644 apps/services/form-system/migrations/20240626093536-create-application.js create mode 100644 apps/services/form-system/migrations/20240626093807-create-applicant.js create mode 100644 apps/services/form-system/src/app/modules/applications/applications.controller.ts create mode 100644 apps/services/form-system/src/app/modules/applications/applications.module.ts create mode 100644 apps/services/form-system/src/app/modules/applications/applications.service.ts create mode 100644 apps/services/form-system/src/app/modules/applications/models/application.model.ts create mode 100644 apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/models/dto/formsList.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts create mode 100644 apps/services/form-system/src/app/modules/forms/models/form.mapper.ts create mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts create mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts create mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 6f67d592ce91..083db8b9571d 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -16,6 +16,11 @@ module.exports = { type: Sequelize.JSON, allowNull: false, }, + url_name: { + type: Sequelize.STRING, + allowNull: false, + defaultValue: '', + }, created: { type: 'TIMESTAMP WITH TIME ZONE', defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), diff --git a/apps/services/form-system/migrations/20240626093536-create-application.js b/apps/services/form-system/migrations/20240626093536-create-application.js new file mode 100644 index 000000000000..813b40c5a2a9 --- /dev/null +++ b/apps/services/form-system/migrations/20240626093536-create-application.js @@ -0,0 +1,44 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'applications', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + form_id: { + type: Sequelize.UUID, + allowNull: false, + references: { + model: 'forms', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('applications', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/migrations/20240626093807-create-applicant.js b/apps/services/form-system/migrations/20240626093807-create-applicant.js new file mode 100644 index 000000000000..cfc1192d579e --- /dev/null +++ b/apps/services/form-system/migrations/20240626093807-create-applicant.js @@ -0,0 +1,88 @@ +'use strict' + +module.exports = { + async up(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.createTable( + 'applicants', + { + id: { + type: Sequelize.UUID, + primaryKey: true, + allowNull: false, + defaultValue: Sequelize.UUIDV4, + }, + created: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + modified: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + last_login: { + type: 'TIMESTAMP WITH TIME ZONE', + defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), + allowNull: false, + }, + name: { + type: Sequelize.STRING, + allowNull: false, + defaultValue: '', + }, + national_id: { + type: Sequelize.STRING, + allowNull: false, + defaultValue: '', + }, + email: { + type: Sequelize.STRING, + allowNull: true, + }, + phone_number: { + type: Sequelize.STRING, + allowNull: true, + }, + address: { + type: Sequelize.STRING, + allowNull: true, + }, + municipality: { + type: Sequelize.STRING, + allowNull: true, + }, + applicant_type: { + type: Sequelize.ENUM( + 'individual', + 'individualWithMandateFromIndividual', + 'individualWithMandateFromLegalEntity', + 'individualWithProcuration', + 'individualGivingMandate', + 'legalEntity', + ), + allowNull: false, + defaultValue: 'individual', + }, + application_id: { + type: Sequelize.UUID, + onDelete: 'CASCADE', + allowNull: false, + references: { + model: 'applications', + key: 'id', + }, + }, + }, + { transaction: t }, + ), + ) + }, + + async down(queryInterface, Sequelize) { + return queryInterface.sequelize.transaction((t) => + queryInterface.dropTable('applicants', { transaction: t }), + ) + }, +} diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 64c122ed4cf4..9e204a087510 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -14,6 +14,7 @@ import { StepsModule } from './modules/steps/steps.module' import { TestimoniesModule } from './modules/testimonies/testimonies.module' import { SequelizeConfigService } from './sequelizeConfig.service' import { ListItemsModule } from './modules/listItems/listItems.module' +import { ApplicationsModule } from './modules/applications/applications.module' @Module({ imports: [ @@ -32,6 +33,7 @@ import { ListItemsModule } from './modules/listItems/listItems.module' ListsModule, InputSettingsModule, ListItemsModule, + ApplicationsModule, ], }) export class AppModule {} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts index e1af50a064b9..c0613846f63c 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts @@ -4,11 +4,13 @@ import { Column, CreatedAt, DataType, + ForeignKey, Model, Table, UpdatedAt, } from 'sequelize-typescript' import { ApplicantTypes } from '../../../enums/applicantTypes' +import { Application } from '../../applications/models/application.model' @Table({ tableName: 'applicants' }) export class Applicant extends Model { @@ -54,32 +56,28 @@ export class Applicant extends Model { @Column({ type: DataType.STRING, - allowNull: false, - defaultValue: '', + allowNull: true, }) @ApiProperty() email!: string @Column({ type: DataType.STRING, - allowNull: false, - defaultValue: '', + allowNull: true, }) @ApiProperty() phoneNumber!: string @Column({ type: DataType.STRING, - allowNull: false, - defaultValue: '', + allowNull: true, }) @ApiProperty() address!: string @Column({ type: DataType.STRING, - allowNull: false, - defaultValue: '', + allowNull: true, }) @ApiProperty() municipality!: string @@ -92,4 +90,12 @@ export class Applicant extends Model { }) @ApiProperty({ enum: ApplicantTypes }) applicantType!: string + + @ForeignKey(() => Application) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'application_id', + }) + applicationId!: string } diff --git a/apps/services/form-system/src/app/modules/applications/applications.controller.ts b/apps/services/form-system/src/app/modules/applications/applications.controller.ts new file mode 100644 index 000000000000..ab673ee7d150 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/applications.controller.ts @@ -0,0 +1,20 @@ +import { Controller, Get, Param } from '@nestjs/common' +import { ApiTags } from '@nestjs/swagger' +import { ApplicationsService } from './applications.service' +import { ApplicationDto } from './models/dto/application.dto' +import { Documentation } from '@island.is/nest/swagger' + +@ApiTags('applications') +@Controller('applications') +export class ApplicationsController { + constructor(private readonly applicationsService: ApplicationsService) {} + + @Get() + @Documentation({ + description: 'Get application preview', + response: { status: 200, type: [ApplicationDto] }, + }) + getPreview(@Param('formId') formId: string): ApplicationDto { + return this.applicationsService.getPreview(formId) + } +} diff --git a/apps/services/form-system/src/app/modules/applications/applications.module.ts b/apps/services/form-system/src/app/modules/applications/applications.module.ts new file mode 100644 index 000000000000..936b3ea0b4be --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/applications.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { Application } from './models/application.model' +import { SequelizeModule } from '@nestjs/sequelize' +import { ApplicationsService } from './applications.service' +import { ApplicationsController } from './applications.controller' + +@Module({ + imports: [SequelizeModule.forFeature([Application])], + controllers: [ApplicationsController], + providers: [ApplicationsService], +}) +export class ApplicationsModule {} diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts new file mode 100644 index 000000000000..959b89567f8a --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -0,0 +1,20 @@ +import { Injectable } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { Application } from './models/application.model' +import { ApplicationDto } from './models/dto/application.dto' + +@Injectable() +export class ApplicationsService { + constructor( + @InjectModel(Application) + private readonly applicationModel: typeof Application, + ) {} + + create(formId: string): ApplicationDto { + return new ApplicationDto() + } + + getPreview(formId: string): ApplicationDto { + return new ApplicationDto() + } +} diff --git a/apps/services/form-system/src/app/modules/applications/models/application.model.ts b/apps/services/form-system/src/app/modules/applications/models/application.model.ts new file mode 100644 index 000000000000..bc2f131a52fd --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/models/application.model.ts @@ -0,0 +1,40 @@ +import { ApiProperty } from '@nestjs/swagger' +import { CreationOptional } from 'sequelize' +import { + Column, + CreatedAt, + DataType, + ForeignKey, + Model, + Table, + UpdatedAt, +} from 'sequelize-typescript' +import { Form } from '../../forms/models/form.model' + +@Table({ tableName: 'applications' }) +export class Application extends Model { + @Column({ + type: DataType.UUID, + allowNull: false, + primaryKey: true, + defaultValue: DataType.UUIDV4, + }) + @ApiProperty() + id!: string + + @CreatedAt + @ApiProperty({ type: Date }) + created!: CreationOptional + + @UpdatedAt + @ApiProperty({ type: Date }) + modified!: CreationOptional + + @ForeignKey(() => Form) + @Column({ + type: DataType.STRING, + allowNull: false, + field: 'form_id', + }) + formId!: string +} diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts new file mode 100644 index 000000000000..26cddf8264c1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -0,0 +1,25 @@ +import { ApiProperty } from '@nestjs/swagger' +import { ApplicationStep } from '../../../steps/models/dto/applicationStep.dto' + +export class ApplicationDto { + @ApiProperty() + applicationId?: string + + @ApiProperty() + organizationId?: string + + @ApiProperty() + formId?: string + + @ApiProperty() + formUrlName?: string + + @ApiProperty() + created?: Date + + @ApiProperty() + modified?: Date + + @ApiProperty({ type: [ApplicationStep] }) + steps?: ApplicationStep[] +} diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 1ca70db8ab0a..8eb2aa60b138 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -13,6 +13,9 @@ import { FormsService } from './forms.service' import { CreateFormDto } from './models/dto/createForm.dto' import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' +import { FormDto } from './models/dto/form.dto' +import { FormsListFormDto } from './models/dto/formsListForm.dto' +import { FormsListDto } from './models/dto/formsList.dto' @ApiTags('forms') @Controller('forms') @@ -35,11 +38,11 @@ export class FormsController { @Get('organization/:organizationId') @Documentation({ description: 'Get all forms belonging to organization', - response: { status: 200, type: [Form] }, + response: { status: 200, type: FormsListDto }, }) async findAll( @Param('organizationId') organizationId: string, - ): Promise { + ): Promise { return await this.formsService.findAll(organizationId) } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index d2abdc7984e6..1b37e2df0175 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -13,6 +13,7 @@ import { FormsService } from './forms.service' import { Form } from './models/form.model' import { ListItemMapper } from '../listItems/models/listItem.mapper' import { ListItem } from '../listItems/models/listItem.model' +import { FormMapper } from './models/form.mapper' @Module({ imports: [ @@ -29,6 +30,6 @@ import { ListItem } from '../listItems/models/listItem.model' ]), ], controllers: [FormsController], - providers: [FormsService, InputSettingsMapper, ListItemMapper], + providers: [FormsService, InputSettingsMapper, ListItemMapper, FormMapper], }) export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 02c4d3799ad2..93549e57dce3 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -24,6 +24,9 @@ import { FormDto } from './models/dto/form.dto' import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' import { ListItem } from '../listItems/models/listItem.model' +import { FormsListFormDto } from './models/dto/formsListForm.dto' +import { FormsListDto } from './models/dto/formsList.dto' +import { FormMapper } from './models/form.mapper' @Injectable() export class FormsService { @@ -41,12 +44,18 @@ export class FormsService { @InjectModel(ListType) private readonly listTypeModel: typeof ListType, private readonly inputSettingsMapper: InputSettingsMapper, + private readonly formMapper: FormMapper, ) {} - async findAll(organizationId: string): Promise { - return await this.formModel.findAll({ + async findAll(organizationId: string): Promise { + const forms = await this.formModel.findAll({ where: { organizationId: organizationId }, }) + + const formsListDto: FormsListDto = + this.formMapper.mapFormsToFormsListDto(forms) + + return formsListDto } async findOne(id: string): Promise { @@ -233,6 +242,7 @@ export class FormsService { id: form.id, organizationId: form.organizationId, name: form.name, + urlName: form.urlName, invalidationDate: form.invalidationDate, created: form.created, modified: form.modified, diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 98d10d8520b9..da2939428b1b 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -5,6 +5,7 @@ import { GroupDto } from '../../../groups/models/dto/group.dto' import { InputDto } from '../../../inputs/models/dto/input.dto' import { StepDto } from '../../../steps/models/dto/step.dto' import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' +import { String } from 'aws-sdk/clients/apigateway' export class FormDto { @ApiProperty() @@ -16,6 +17,9 @@ export class FormDto { @ApiProperty({ type: LanguageType }) name!: LanguageType + @ApiProperty() + urlName!: String + @ApiProperty() invalidationDate?: Date diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsList.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsList.dto.ts new file mode 100644 index 000000000000..4d128b1500c8 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsList.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { FormsListFormDto } from './formsListForm.dto' + +export class FormsListDto { + @ApiProperty({ type: [FormsListFormDto] }) + forms!: FormsListFormDto[] +} diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts new file mode 100644 index 000000000000..c00a67899d0e --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -0,0 +1,34 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' + +export class FormsListFormDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + urlName!: String + + @ApiProperty() + invalidationDate?: Date + + @ApiProperty() + created!: Date + + @ApiProperty() + modified!: Date + + @ApiProperty() + isTranslated!: boolean + + @ApiProperty() + applicationDaysToRemove!: number + + @ApiProperty() + derivedFrom!: number + + @ApiProperty() + stopProgressOnValidatingStep!: boolean +} diff --git a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts new file mode 100644 index 000000000000..daf52e719d20 --- /dev/null +++ b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts @@ -0,0 +1,29 @@ +import { Injectable } from '@nestjs/common' +import { Form } from './form.model' +import { FormsListDto } from './dto/formsList.dto' +import { FormsListFormDto } from './dto/formsListForm.dto' + +@Injectable() +export class FormMapper { + mapFormsToFormsListDto(forms: Form[]): FormsListDto { + const formsListForms = forms.map((form) => { + return { + id: form.id, + name: form.name, + urlName: form.urlName, + invalidationDate: form.invalidationDate, + created: form.created, + modified: form.modified, + isTranslated: form.isTranslated, + applicationDaysToRemove: form.applicationDaysToRemove, + derivedFrom: form.derivedFrom, + stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, + } as FormsListFormDto + }) + const formsListDto: FormsListDto = { + forms: formsListForms, + } + + return formsListDto + } +} diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index 9039d27a264d..a078d55ebf66 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -36,6 +36,13 @@ export class Form extends Model { @ApiProperty({ type: LanguageType }) name!: LanguageType + @Column({ + type: DataType.STRING, + allowNull: false, + defaultValue: '', + }) + urlName!: string + @Column @ApiProperty() invalidationDate?: Date diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts new file mode 100644 index 000000000000..c5a316d487d1 --- /dev/null +++ b/apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts @@ -0,0 +1,23 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { ApplicationInput } from '../../../inputs/models/dto/applicationInput.dto' + +export class ApplicationGroup { + @ApiProperty() + id!: string + + @ApiProperty() + stepId!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + displayOrder!: number + + @ApiProperty() + multiset!: number + + @ApiProperty({ type: [ApplicationInput] }) + inputs!: ApplicationInput[] +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts new file mode 100644 index 000000000000..8d965f0d1a7a --- /dev/null +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts @@ -0,0 +1,29 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' + +export class ApplicationInput { + @ApiProperty() + id!: string + + @ApiProperty() + groupId!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + description!: LanguageType + + @ApiProperty() + isPartOfMultiset!: boolean + + @ApiProperty({ type: InputSettingsDto }) + inputSettings?: InputSettingsDto + + @ApiProperty() + inputType!: string +} diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts new file mode 100644 index 000000000000..3812a147f476 --- /dev/null +++ b/apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts @@ -0,0 +1,26 @@ +import { ApiProperty } from '@nestjs/swagger' +import { LanguageType } from '../../../../dataTypes/languageType.model' +import { ApplicationGroup } from '../../../groups/models/dto/applicationGroup.dto' + +export class ApplicationStep { + @ApiProperty() + id!: string + + @ApiProperty({ type: LanguageType }) + name!: LanguageType + + @ApiProperty() + stepType!: string + + @ApiProperty() + displayOrder!: number + + @ApiProperty({ type: LanguageType }) + waitingText?: LanguageType + + @ApiProperty() + callRuleset!: boolean + + @ApiProperty({ type: [ApplicationGroup] }) + groups!: ApplicationGroup[] +} From 7d0c9f0474756a8f2c843f91e4203f553f624e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Thu, 27 Jun 2024 13:54:55 +0000 Subject: [PATCH 42/72] change step to section and group to page --- .../migrations/20240605120322-create-form.js | 2 +- ...ep.js => 20240605120342-create-section.js} | 6 +- ...group.js => 20240605122019-create-page.js} | 8 +- .../migrations/20240611122625-create-input.js | 4 +- .../form-system/src/app/app.module.ts | 8 +- .../enums/{stepTypes.ts => sectionTypes.ts} | 2 +- .../models/dto/applicationApplicant.dto.ts | 37 ++++++ .../models/dto/application.dto.ts | 6 +- .../src/app/modules/forms/forms.module.ts | 8 +- .../src/app/modules/forms/forms.service.ts | 118 +++++++++--------- .../app/modules/forms/models/dto/form.dto.ts | 14 +-- .../forms/models/dto/formsListForm.dto.ts | 2 +- .../app/modules/forms/models/form.mapper.ts | 2 +- .../app/modules/forms/models/form.model.ts | 10 +- .../modules/groups/groups.controller.spec.ts | 18 --- .../app/modules/groups/groups.controller.ts | 76 ----------- .../src/app/modules/groups/groups.module.ts | 12 -- .../app/modules/groups/groups.service.spec.ts | 18 --- .../src/app/modules/groups/groups.service.ts | 79 ------------ .../dto/updateGroupsDisplayOrder.dto.ts | 7 -- .../src/app/modules/inputs/inputs.service.ts | 6 +- .../inputs/models/dto/applicationInput.dto.ts | 2 +- .../inputs/models/dto/createInput.dto.ts | 2 +- .../modules/inputs/models/dto/input.dto.ts | 2 +- .../models/dto/inputDisplayOrder.dto.ts | 2 +- .../app/modules/inputs/models/input.mapper.ts | 2 +- .../app/modules/inputs/models/input.model.ts | 8 +- .../models/dto/applicationPage.dto.ts} | 4 +- .../models/dto/createPage.dto.ts} | 4 +- .../models/dto/page.dto.ts} | 4 +- .../models/dto/pageDisplayOrder.dto.ts} | 4 +- .../models/dto/updatePage.dto.ts} | 2 +- .../models/dto/updatePagesDisplayOrder.dto.ts | 7 ++ .../models/page.model.ts} | 12 +- .../modules/pages/pages.controller.spec.ts | 0 .../src/app/modules/pages/pages.controller.ts | 76 +++++++++++ .../src/app/modules/pages/pages.module.ts | 12 ++ .../app/modules/pages/pages.service.spec.ts | 0 .../src/app/modules/pages/pages.service.ts | 83 ++++++++++++ .../models/dto/applicationSection.dto.ts} | 10 +- .../models/dto/createSection.dto.ts} | 2 +- .../models/dto/section.dto.ts} | 4 +- .../models/dto/sectionDisplayOrder.dto.ts} | 2 +- .../models/dto/updateSection.dto.ts} | 2 +- .../dto/updateSectionsDisplayOrder.dto.ts | 7 ++ .../models/section.model.ts} | 20 +-- .../sections/sections.controller.spec.ts | 0 .../modules/sections/sections.controller.ts | 78 ++++++++++++ .../app/modules/sections/sections.module.ts | 13 ++ .../modules/sections/sections.service.spec.ts | 0 .../app/modules/sections/sections.service.ts | 98 +++++++++++++++ .../models/dto/updateStepsDisplayOrder.dto.ts | 7 -- .../modules/steps/steps.controller.spec.ts | 23 ---- .../src/app/modules/steps/steps.controller.ts | 76 ----------- .../src/app/modules/steps/steps.module.ts | 13 -- .../app/modules/steps/steps.service.spec.ts | 18 --- .../src/app/modules/steps/steps.service.ts | 92 -------------- 57 files changed, 553 insertions(+), 581 deletions(-) rename apps/services/form-system/migrations/{20240605120342-create-step.js => 20240605120342-create-section.js} (94%) rename apps/services/form-system/migrations/{20240605122019-create-group.js => 20240605122019-create-page.js} (91%) rename apps/services/form-system/src/app/enums/{stepTypes.ts => sectionTypes.ts} (74%) create mode 100644 apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/groups.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/groups.module.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/groups.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/groups.service.ts delete mode 100644 apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts rename apps/services/form-system/src/app/modules/{groups/models/dto/applicationGroup.dto.ts => pages/models/dto/applicationPage.dto.ts} (90%) rename apps/services/form-system/src/app/modules/{groups/models/dto/createGroup.dto.ts => pages/models/dto/createPage.dto.ts} (56%) rename apps/services/form-system/src/app/modules/{groups/models/dto/group.dto.ts => pages/models/dto/page.dto.ts} (87%) rename apps/services/form-system/src/app/modules/{groups/models/dto/groupDisplayOrder.dto.ts => pages/models/dto/pageDisplayOrder.dto.ts} (63%) rename apps/services/form-system/src/app/modules/{groups/models/dto/updateGroup.dto.ts => pages/models/dto/updatePage.dto.ts} (88%) create mode 100644 apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts rename apps/services/form-system/src/app/modules/{groups/models/group.model.ts => pages/models/page.model.ts} (86%) create mode 100644 apps/services/form-system/src/app/modules/pages/pages.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/pages/pages.controller.ts create mode 100644 apps/services/form-system/src/app/modules/pages/pages.module.ts create mode 100644 apps/services/form-system/src/app/modules/pages/pages.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/pages/pages.service.ts rename apps/services/form-system/src/app/modules/{steps/models/dto/applicationStep.dto.ts => sections/models/dto/applicationSection.dto.ts} (64%) rename apps/services/form-system/src/app/modules/{steps/models/dto/createStep.dto.ts => sections/models/dto/createSection.dto.ts} (72%) rename apps/services/form-system/src/app/modules/{steps/models/dto/step.dto.ts => sections/models/dto/section.dto.ts} (88%) rename apps/services/form-system/src/app/modules/{steps/models/dto/stepDisplayOrder.dto.ts => sections/models/dto/sectionDisplayOrder.dto.ts} (67%) rename apps/services/form-system/src/app/modules/{steps/models/dto/updateStep.dto.ts => sections/models/dto/updateSection.dto.ts} (90%) create mode 100644 apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts rename apps/services/form-system/src/app/modules/{steps/models/step.model.ts => sections/models/section.model.ts} (82%) create mode 100644 apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/sections/sections.controller.ts create mode 100644 apps/services/form-system/src/app/modules/sections/sections.module.ts create mode 100644 apps/services/form-system/src/app/modules/sections/sections.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/sections/sections.service.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/steps.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/steps.module.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/steps.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/steps/steps.service.ts diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 083db8b9571d..06c5820b9b1b 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -49,7 +49,7 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, }, - stop_progress_on_validating_step: { + stop_progress_on_validating_page: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, diff --git a/apps/services/form-system/migrations/20240605120342-create-step.js b/apps/services/form-system/migrations/20240605120342-create-section.js similarity index 94% rename from apps/services/form-system/migrations/20240605120342-create-step.js rename to apps/services/form-system/migrations/20240605120342-create-section.js index cc0c3eebd758..10ace092726c 100644 --- a/apps/services/form-system/migrations/20240605120342-create-step.js +++ b/apps/services/form-system/migrations/20240605120342-create-section.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'steps', + 'sections', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'), allowNull: false, }, - step_type: { + section_type: { type: Sequelize.DataTypes.ENUM( 'premises', 'parties', @@ -76,7 +76,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('steps', { transaction: t }), + queryInterface.dropTable('sections', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240605122019-create-group.js b/apps/services/form-system/migrations/20240605122019-create-page.js similarity index 91% rename from apps/services/form-system/migrations/20240605122019-create-group.js rename to apps/services/form-system/migrations/20240605122019-create-page.js index f746bfa18520..bfcc12b3c983 100644 --- a/apps/services/form-system/migrations/20240605122019-create-group.js +++ b/apps/services/form-system/migrations/20240605122019-create-page.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'groups', + 'pages', { id: { type: Sequelize.UUID, @@ -39,12 +39,12 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, }, - step_id: { + section_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'steps', + model: 'sections', key: 'id', }, }, @@ -56,7 +56,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('groups', { transaction: t }), + queryInterface.dropTable('pages', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240611122625-create-input.js b/apps/services/form-system/migrations/20240611122625-create-input.js index 1d97cef0d907..4dc47bc40164 100644 --- a/apps/services/form-system/migrations/20240611122625-create-input.js +++ b/apps/services/form-system/migrations/20240611122625-create-input.js @@ -44,12 +44,12 @@ module.exports = { allowNull: false, defaultValue: false, }, - group_id: { + page_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'groups', + model: 'pages', key: 'id', }, }, diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 9e204a087510..ecb8ad50f1a6 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -5,12 +5,12 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' import { environment } from '../environments' import { FormsModule } from './modules/forms/forms.module' -import { GroupsModule } from './modules/groups/groups.module' +import { PagesModule } from './modules/pages/pages.module' import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' import { InputsModule } from './modules/inputs/inputs.module' import { ListsModule } from './modules/lists/lists.module' import { OrganizationsModule } from './modules/organizations/organizations.module' -import { StepsModule } from './modules/steps/steps.module' +import { SectionsModule } from './modules/sections/sections.module' import { TestimoniesModule } from './modules/testimonies/testimonies.module' import { SequelizeConfigService } from './sequelizeConfig.service' import { ListItemsModule } from './modules/listItems/listItems.module' @@ -26,8 +26,8 @@ import { ApplicationsModule } from './modules/applications/applications.module' }), OrganizationsModule, FormsModule, - StepsModule, - GroupsModule, + SectionsModule, + PagesModule, InputsModule, TestimoniesModule, ListsModule, diff --git a/apps/services/form-system/src/app/enums/stepTypes.ts b/apps/services/form-system/src/app/enums/sectionTypes.ts similarity index 74% rename from apps/services/form-system/src/app/enums/stepTypes.ts rename to apps/services/form-system/src/app/enums/sectionTypes.ts index 434bf5a60035..e1cd8de72f64 100644 --- a/apps/services/form-system/src/app/enums/stepTypes.ts +++ b/apps/services/form-system/src/app/enums/sectionTypes.ts @@ -1,4 +1,4 @@ -export const StepTypes = { +export const SectionTypes = { PREMISES: 'premises', PARTIES: 'parties', INPUT: 'input', diff --git a/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts b/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts new file mode 100644 index 000000000000..74d385876077 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts @@ -0,0 +1,37 @@ +import { ApiProperty } from '@nestjs/swagger' +import { ApplicantTypes } from '../../../../enums/applicantTypes' + +export class ApplicationApplicantDto { + @ApiProperty() + id!: string + + @ApiProperty({ type: Date }) + created!: Date + + @ApiProperty({ type: Date }) + modified!: Date + + @ApiProperty() + lastLogin?: Date + + @ApiProperty() + name!: string + + @ApiProperty() + nationalId!: string + + @ApiProperty() + email!: string + + @ApiProperty() + phoneNumber!: string + + @ApiProperty() + address!: string + + @ApiProperty() + municipality!: string + + @ApiProperty({ enum: ApplicantTypes }) + applicantType!: string +} diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts index 26cddf8264c1..94cd2fb8ed97 100644 --- a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' -import { ApplicationStep } from '../../../steps/models/dto/applicationStep.dto' +import { ApplicationSection } from '../../../sections/models/dto/applicationSection.dto' export class ApplicationDto { @ApiProperty() @@ -20,6 +20,6 @@ export class ApplicationDto { @ApiProperty() modified?: Date - @ApiProperty({ type: [ApplicationStep] }) - steps?: ApplicationStep[] + @ApiProperty({ type: [ApplicationSection] }) + sections?: ApplicationSection[] } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index 1b37e2df0175..3d7bd70fc8d8 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -1,12 +1,12 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' import { FormApplicant } from '../applicants/models/formApplicant.model' -import { Group } from '../groups/models/group.model' +import { Page } from '../pages/models/page.model' import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputType } from '../inputs/models/inputType.model' import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' -import { Step } from '../steps/models/step.model' +import { Section } from '../sections/models/section.model' import { TestimonyType } from '../testimonies/models/testimonyType.model' import { FormsController } from './forms.controller' import { FormsService } from './forms.service' @@ -20,8 +20,8 @@ import { FormMapper } from './models/form.mapper' SequelizeModule.forFeature([ Form, FormApplicant, - Step, - Group, + Section, + Page, Organization, InputType, TestimonyType, diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 93549e57dce3..229343bd1075 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -1,9 +1,9 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' -import { StepTypes } from '../../enums/stepTypes' +import { SectionTypes } from '../../enums/sectionTypes' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' -import { GroupDto } from '../groups/models/dto/group.dto' -import { Group } from '../groups/models/group.model' +import { PageDto } from '../pages/models/dto/page.dto' +import { Page } from '../pages/models/page.model' import { InputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputSettings } from '../inputSettings/models/inputSettings.model' @@ -14,8 +14,8 @@ import { InputType } from '../inputs/models/inputType.model' import { ListTypeDto } from '../lists/models/dto/listType.dto' import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' -import { StepDto } from '../steps/models/dto/step.dto' -import { Step } from '../steps/models/step.model' +import { SectionDto } from '../sections/models/dto/section.dto' +import { Section } from '../sections/models/section.model' import { FormTestimonyTypeDto } from '../testimonies/models/dto/formTestimonyType.dto' import { TestimonyTypeDto } from '../testimonies/models/dto/testimonyType.dto' import { TestimonyType } from '../testimonies/models/testimonyType.model' @@ -33,10 +33,10 @@ export class FormsService { constructor( @InjectModel(Form) private readonly formModel: typeof Form, - @InjectModel(Step) - private readonly stepModel: typeof Step, - @InjectModel(Group) - private readonly groupModel: typeof Group, + @InjectModel(Section) + private readonly sectionModel: typeof Section, + @InjectModel(Page) + private readonly pageModel: typeof Page, @InjectModel(Organization) private readonly organizationModel: typeof Organization, @InjectModel(InputType) @@ -105,12 +105,12 @@ export class FormsService { const form = await this.formModel.findByPk(id, { include: [ { - model: Step, - as: 'steps', + model: Section, + as: 'sections', include: [ { - model: Group, - as: 'groups', + model: Page, + as: 'pages', include: [ { model: Input, @@ -249,12 +249,12 @@ export class FormsService { isTranslated: form.isTranslated, applicationDaysToRemove: form.applicationDaysToRemove, derivedFrom: form.derivedFrom, - stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, + stopProgressOnValidatingPage: form.stopProgressOnValidatingPage, completedMessage: form.completedMessage, testimonyTypes: [], applicants: [], - steps: [], - groups: [], + sections: [], + pages: [], inputs: [], } @@ -275,34 +275,34 @@ export class FormsService { } as FormApplicantDto) }) - form.steps.map((step) => { - formDto.steps?.push({ - id: step.id, - name: step.name, - created: step.created, - modified: step.modified, - stepType: step.stepType, - displayOrder: step.displayOrder, - waitingText: step.waitingText, - isHidden: step.isHidden, - isCompleted: step.isCompleted, - callRuleset: step.callRuleset, - } as StepDto) - step.groups?.map((group) => { - formDto.groups?.push({ - id: group.id, - stepId: step.id, - name: group.name, - created: group.created, - modified: group.modified, - displayOrder: group.displayOrder, - isHidden: group.isHidden, - multiset: group.multiset, - } as GroupDto) - group.inputs?.map((input) => { + form.sections.map((section) => { + formDto.sections?.push({ + id: section.id, + name: section.name, + created: section.created, + modified: section.modified, + sectionType: section.sectionType, + displayOrder: section.displayOrder, + waitingText: section.waitingText, + isHidden: section.isHidden, + isCompleted: section.isCompleted, + callRuleset: section.callRuleset, + } as SectionDto) + section.pages?.map((page) => { + formDto.pages?.push({ + id: page.id, + sectionId: section.id, + name: page.name, + created: page.created, + modified: page.modified, + displayOrder: page.displayOrder, + isHidden: page.isHidden, + multiset: page.multiset, + } as PageDto) + page.inputs?.map((input) => { formDto.inputs?.push({ id: input.id, - groupId: group.id, + pageId: page.id, name: input.name, created: input.created, modified: input.modified, @@ -325,38 +325,38 @@ export class FormsService { } private async createFormTemplate(form: Form): Promise { - await this.stepModel.create({ + await this.sectionModel.create({ formId: form.id, - stepType: StepTypes.PREMISES, + sectionType: SectionTypes.PREMISES, displayOrder: 0, name: { is: 'Forsendur', en: 'Premises' }, - } as Step) + } as Section) - await this.stepModel.create({ + await this.sectionModel.create({ formId: form.id, - stepType: StepTypes.PARTIES, + sectionType: SectionTypes.PARTIES, displayOrder: 1, name: { is: 'Hlutaðeigandi aðilar', en: 'Relevant parties' }, - } as Step) + } as Section) - const inputStep = await this.stepModel.create({ + const inputSection = await this.sectionModel.create({ formId: form.id, - stepType: StepTypes.INPUT, + sectionType: SectionTypes.INPUT, displayOrder: 2, - name: { is: 'Innsláttarskref', en: 'InputStep' }, - } as Step) + name: { is: 'Innsláttarsíða', en: 'InputPage' }, + } as Section) - await this.stepModel.create({ + await this.sectionModel.create({ formId: form.id, - stepType: StepTypes.PAYMENT, + sectionType: SectionTypes.PAYMENT, displayOrder: 3, name: { is: 'Greiðsla', en: 'Payment' }, - } as Step) + } as Section) - await this.groupModel.create({ - stepId: inputStep.id, + await this.pageModel.create({ + sectionId: inputSection.id, displayOrder: 0, - name: { is: 'Hópur 1', en: 'Group 1' }, - } as Group) + name: { is: 'Síða 1', en: 'Page 1' }, + } as Page) } } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index da2939428b1b..dcc2f89f3eed 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' -import { GroupDto } from '../../../groups/models/dto/group.dto' +import { PageDto } from '../../../pages/models/dto/page.dto' import { InputDto } from '../../../inputs/models/dto/input.dto' -import { StepDto } from '../../../steps/models/dto/step.dto' +import { SectionDto } from '../../../sections/models/dto/section.dto' import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' import { String } from 'aws-sdk/clients/apigateway' @@ -39,7 +39,7 @@ export class FormDto { derivedFrom!: number @ApiProperty() - stopProgressOnValidatingStep!: boolean + stopProgressOnValidatingPage!: boolean @ApiProperty({ type: LanguageType }) completedMessage?: LanguageType @@ -50,11 +50,11 @@ export class FormDto { @ApiProperty({ type: [FormApplicantDto] }) applicants?: FormApplicantDto[] - @ApiProperty({ type: [StepDto] }) - steps?: StepDto[] + @ApiProperty({ type: [SectionDto] }) + sections?: SectionDto[] - @ApiProperty({ type: [GroupDto] }) - groups?: GroupDto[] + @ApiProperty({ type: [PageDto] }) + pages?: PageDto[] @ApiProperty({ type: [InputDto] }) inputs?: InputDto[] diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts index c00a67899d0e..eec39ffa153b 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -30,5 +30,5 @@ export class FormsListFormDto { derivedFrom!: number @ApiProperty() - stopProgressOnValidatingStep!: boolean + stopProgressOnValidatingPage!: boolean } diff --git a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts index daf52e719d20..fffe08187d07 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts @@ -17,7 +17,7 @@ export class FormMapper { isTranslated: form.isTranslated, applicationDaysToRemove: form.applicationDaysToRemove, derivedFrom: form.derivedFrom, - stopProgressOnValidatingStep: form.stopProgressOnValidatingStep, + stopProgressOnValidatingPage: form.stopProgressOnValidatingPage, } as FormsListFormDto }) const formsListDto: FormsListDto = { diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index a078d55ebf66..8561429b79fe 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -10,7 +10,7 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Step } from '../../steps/models/step.model' +import { Section } from '../../sections/models/section.model' import { ApiProperty } from '@nestjs/swagger' import { Organization } from '../../organizations/models/organization.model' import { LanguageType } from '../../../dataTypes/languageType.model' @@ -84,7 +84,7 @@ export class Form extends Model { defaultValue: true, }) @ApiProperty() - stopProgressOnValidatingStep!: boolean + stopProgressOnValidatingPage!: boolean @Column({ type: DataType.JSON, @@ -94,9 +94,9 @@ export class Form extends Model { @ApiProperty({ type: LanguageType }) completedMessage?: LanguageType - @HasMany(() => Step) - @ApiProperty({ type: [Step] }) - steps!: Step[] + @HasMany(() => Section) + @ApiProperty({ type: [Section] }) + sections!: Section[] @HasMany(() => FormApplicant) @ApiProperty({ type: [FormApplicant] }) diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts deleted file mode 100644 index 2d07b6b54c99..000000000000 --- a/apps/services/form-system/src/app/modules/groups/groups.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' -import { GroupsController } from './groups.controller' - -describe('GroupsController', () => { - let controller: GroupsController - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [GroupsController], - }).compile() - - controller = module.get(GroupsController) - }) - - it('should be defined', () => { - expect(controller).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/groups/groups.controller.ts b/apps/services/form-system/src/app/modules/groups/groups.controller.ts deleted file mode 100644 index 537b091a4963..000000000000 --- a/apps/services/form-system/src/app/modules/groups/groups.controller.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - Controller, - Post, - Get, - Delete, - Body, - Param, - NotFoundException, - Put, -} from '@nestjs/common' -import { GroupsService } from './groups.service' -import { CreateGroupDto } from './models/dto/createGroup.dto' -import { Group } from './models/group.model' -import { Documentation } from '@island.is/nest/swagger' -import { ApiTags } from '@nestjs/swagger' -import { UpdateGroupDto } from './models/dto/updateGroup.dto' -import { GroupDto } from './models/dto/group.dto' -import { UpdateGroupsDisplayOrderDto } from './models/dto/updateGroupsDisplayOrder.dto' - -@ApiTags('groups') -@Controller('groups') -export class GroupsController { - constructor(private readonly groupsService: GroupsService) {} - - @Post() - create(@Body() createGroupDto: CreateGroupDto): Promise { - return this.groupsService.create(createGroupDto) - } - - @Get() - @Documentation({ - description: 'Get all Groups', - response: { status: 200, type: [Group] }, - }) - async findAll(): Promise { - return await this.groupsService.findAll() - } - - @Get(':id') - @Documentation({ - description: 'Get Group by id', - response: { status: 200, type: Group }, - }) - async findOne(@Param('id') id: string): Promise { - const group = await this.groupsService.findOne(id) - if (!group) { - throw new NotFoundException(`Group not found`) - } - - return group - } - - @Put(':id') - async update( - @Param('id') id: string, - @Body() updateGroupDto: UpdateGroupDto, - ): Promise { - return await this.groupsService.update(id, updateGroupDto) - } - - @Put() - @Documentation({ - description: 'Update display order of groups', - response: { status: 204 }, - }) - async updateDisplayOrder( - @Body() updateGroupsDisplayOrderDto: UpdateGroupsDisplayOrderDto, - ): Promise { - return this.groupsService.updateDisplayOrder(updateGroupsDisplayOrderDto) - } - - @Delete(':id') - async delete(@Param('id') id: string): Promise { - return this.groupsService.delete(id) - } -} diff --git a/apps/services/form-system/src/app/modules/groups/groups.module.ts b/apps/services/form-system/src/app/modules/groups/groups.module.ts deleted file mode 100644 index c07f954a7451..000000000000 --- a/apps/services/form-system/src/app/modules/groups/groups.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common' -import { GroupsController } from './groups.controller' -import { GroupsService } from './groups.service' -import { Group } from './models/group.model' -import { SequelizeModule } from '@nestjs/sequelize' - -@Module({ - imports: [SequelizeModule.forFeature([Group])], - controllers: [GroupsController], - providers: [GroupsService], -}) -export class GroupsModule {} diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts b/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts deleted file mode 100644 index 59671cb000cc..000000000000 --- a/apps/services/form-system/src/app/modules/groups/groups.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' -import { GroupsService } from './groups.service' - -describe('GroupsService', () => { - let service: GroupsService - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [GroupsService], - }).compile() - - service = module.get(GroupsService) - }) - - it('should be defined', () => { - expect(service).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/groups/groups.service.ts b/apps/services/form-system/src/app/modules/groups/groups.service.ts deleted file mode 100644 index cbcdd1640c19..000000000000 --- a/apps/services/form-system/src/app/modules/groups/groups.service.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { Injectable, NotFoundException } from '@nestjs/common' -import { Group } from './models/group.model' -import { InjectModel } from '@nestjs/sequelize' -import { Input } from '../inputs/models/input.model' -import { CreateGroupDto } from './models/dto/createGroup.dto' -import { UpdateGroupDto } from './models/dto/updateGroup.dto' -import { GroupDto } from './models/dto/group.dto' -import { UpdateGroupsDisplayOrderDto } from './models/dto/updateGroupsDisplayOrder.dto' - -@Injectable() -export class GroupsService { - constructor( - @InjectModel(Group) - private readonly groupModel: typeof Group, - ) {} - - async findAll(): Promise { - return await this.groupModel.findAll() - } - - async findOne(id: string): Promise { - const group = await this.groupModel.findByPk(id, { include: [Input] }) - - if (!group) { - throw new NotFoundException(`Group with id '${id}' not found`) - } - - return group - } - - async create(createGroupDto: CreateGroupDto): Promise { - const group = createGroupDto as Group - const newGroup: Group = new this.groupModel(group) - return await newGroup.save() - } - - async update(id: string, updateGroupDto: UpdateGroupDto): Promise { - const group = await this.findOne(id) - - group.name = updateGroupDto.name - group.multiset = updateGroupDto.multiset - group.modified = new Date() - - await group.save() - - const groupDto: GroupDto = { - id: group.id, - stepId: group.stepId, - name: group.name, - displayOrder: group.displayOrder, - multiset: group.multiset, - } - - return groupDto - } - - async updateDisplayOrder( - updateGroupsDisplayOrderDto: UpdateGroupsDisplayOrderDto, - ): Promise { - const { groupsDisplayOrderDto } = updateGroupsDisplayOrderDto - - for (let i = 0; i < groupsDisplayOrderDto.length; i++) { - const group = await this.groupModel.findByPk(groupsDisplayOrderDto[i].id) - - if (!group) { - throw new NotFoundException( - `Group with id '${groupsDisplayOrderDto[i].id}' not found`, - ) - } - - group.update({ displayOrder: i, stepId: groupsDisplayOrderDto[i].stepId }) - } - } - - async delete(id: string): Promise { - const group = await this.findOne(id) - group?.destroy() - } -} diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts deleted file mode 100644 index 84608f082349..000000000000 --- a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroupsDisplayOrder.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { GroupDisplayOrderDto } from './groupDisplayOrder.dto' - -export class UpdateGroupsDisplayOrderDto { - @ApiProperty({ type: [GroupDisplayOrderDto] }) - groupsDisplayOrderDto!: GroupDisplayOrderDto[] -} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts index ac7cc68a8b40..ab66da4beaac 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -47,10 +47,10 @@ export class InputsService { } async create(createInputDto: CreateInputDto): Promise { - const { groupId } = createInputDto + const { pageId: pageId } = createInputDto const newInput: Input = await this.inputModel.create({ - groupId: groupId, + pageId: pageId, } as Input) const newInputSettingsDto = await this.inputSettingsService.create( @@ -93,7 +93,7 @@ export class InputsService { await input.update({ displayOrder: i, - groupId: inputsDisplayOrderDto[i].groupId, + pageId: inputsDisplayOrderDto[i].pageId, }) } } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts index 8d965f0d1a7a..a90141bcbce3 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts @@ -7,7 +7,7 @@ export class ApplicationInput { id!: string @ApiProperty() - groupId!: string + pageId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts index 7bf7205e1698..da71a7dba095 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts @@ -2,5 +2,5 @@ import { ApiProperty } from '@nestjs/swagger' export class CreateInputDto { @ApiProperty() - groupId!: string + pageId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts index dd6ec454b505..9b886ca943b2 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts @@ -7,7 +7,7 @@ export class InputDto { id!: string @ApiProperty() - groupId!: string + pageId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts index 89cc4030e955..401aa548d1dd 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts @@ -5,5 +5,5 @@ export class InputDisplayOrderDto { id!: string @ApiProperty() - groupId!: string + pageId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts index e4838aaec76c..4ad3a3f9ccb9 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts @@ -12,7 +12,7 @@ export class InputMapper { ): InputDto { const inputDto: InputDto = { id: input.id, - groupId: input.groupId, + pageId: input.pageId, name: input.name, displayOrder: input.displayOrder, description: input.description, diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts index 2ea12a3877c5..071d4661845e 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts @@ -10,7 +10,7 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Group } from '../../groups/models/group.model' +import { Page } from '../../pages/models/page.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { InputType } from './inputType.model' import { InputSettings } from '../../inputSettings/models/inputSettings.model' @@ -74,13 +74,13 @@ export class Input extends Model { @ApiProperty() isPartOfMultiset!: boolean - @ForeignKey(() => Group) + @ForeignKey(() => Page) @Column({ type: DataType.STRING, allowNull: false, - field: 'group_id', + field: 'page_id', }) - groupId!: string + pageId!: string @HasOne(() => InputSettings) @ApiProperty({ type: InputSettings }) diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts similarity index 90% rename from apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts rename to apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts index c5a316d487d1..c97c291e8674 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/applicationGroup.dto.ts +++ b/apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts @@ -2,12 +2,12 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { ApplicationInput } from '../../../inputs/models/dto/applicationInput.dto' -export class ApplicationGroup { +export class ApplicationPage { @ApiProperty() id!: string @ApiProperty() - stepId!: string + sectionId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts similarity index 56% rename from apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts rename to apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts index 229726d96f34..81e966446074 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/createGroup.dto.ts +++ b/apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class CreateGroupDto { +export class CreatePageDto { @ApiProperty() - stepId!: string + sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts similarity index 87% rename from apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts rename to apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts index 0307e95a5628..4f8368e887f0 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/group.dto.ts +++ b/apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts @@ -1,12 +1,12 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class GroupDto { +export class PageDto { @ApiProperty() id!: string @ApiProperty() - stepId!: string + sectionId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts similarity index 63% rename from apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts rename to apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts index 38333a682469..aa8deab9c1d3 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/groupDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' -export class GroupDisplayOrderDto { +export class PageDisplayOrderDto { @ApiProperty() id!: string @ApiProperty() - stepId!: string + sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts similarity index 88% rename from apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts rename to apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts index a01611de5dcc..a591d04fb003 100644 --- a/apps/services/form-system/src/app/modules/groups/models/dto/updateGroup.dto.ts +++ b/apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class UpdateGroupDto { +export class UpdatePageDto { @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts new file mode 100644 index 000000000000..bd2dc3503c39 --- /dev/null +++ b/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { PageDisplayOrderDto } from './pageDisplayOrder.dto' + +export class UpdatePagesDisplayOrderDto { + @ApiProperty({ type: [PageDisplayOrderDto] }) + pagesDisplayOrderDto!: PageDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/groups/models/group.model.ts b/apps/services/form-system/src/app/modules/pages/models/page.model.ts similarity index 86% rename from apps/services/form-system/src/app/modules/groups/models/group.model.ts rename to apps/services/form-system/src/app/modules/pages/models/page.model.ts index 202436c754f0..1826382e4636 100644 --- a/apps/services/form-system/src/app/modules/groups/models/group.model.ts +++ b/apps/services/form-system/src/app/modules/pages/models/page.model.ts @@ -9,13 +9,13 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Step } from '../../steps/models/step.model' +import { Section } from '../../sections/models/section.model' import { CreationOptional } from 'sequelize' import { Input } from '../../inputs/models/input.model' import { LanguageType } from '../../../dataTypes/languageType.model' -@Table({ tableName: 'groups' }) -export class Group extends Model { +@Table({ tableName: 'pages' }) +export class Page extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -69,11 +69,11 @@ export class Group extends Model { @ApiProperty({ type: [Input] }) inputs?: Input[] - @ForeignKey(() => Step) + @ForeignKey(() => Section) @Column({ type: DataType.STRING, allowNull: false, - field: 'step_id', + field: 'section_id', }) - stepId!: string + sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/pages/pages.controller.spec.ts b/apps/services/form-system/src/app/modules/pages/pages.controller.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/pages/pages.controller.ts b/apps/services/form-system/src/app/modules/pages/pages.controller.ts new file mode 100644 index 000000000000..f8dca995b23c --- /dev/null +++ b/apps/services/form-system/src/app/modules/pages/pages.controller.ts @@ -0,0 +1,76 @@ +import { + Controller, + Post, + Get, + Delete, + Body, + Param, + NotFoundException, + Put, +} from '@nestjs/common' +import { PagesService } from './pages.service' +import { CreatePageDto } from './models/dto/createPage.dto' +import { Page } from './models/page.model' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' +import { UpdatePageDto } from './models/dto/updatePage.dto' +import { PageDto } from './models/dto/page.dto' +import { UpdatePagesDisplayOrderDto } from './models/dto/updatePagesDisplayOrder.dto' + +@ApiTags('pages') +@Controller('pages') +export class PagesController { + constructor(private readonly pagesService: PagesService) {} + + @Post() + create(@Body() createPageDto: CreatePageDto): Promise { + return this.pagesService.create(createPageDto) + } + + @Get() + @Documentation({ + description: 'Get all Pages', + response: { status: 200, type: [Page] }, + }) + async findAll(): Promise { + return await this.pagesService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Page by id', + response: { status: 200, type: Page }, + }) + async findOne(@Param('id') id: string): Promise { + const page = await this.pagesService.findOne(id) + if (!page) { + throw new NotFoundException(`Page not found`) + } + + return page + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updatePageDto: UpdatePageDto, + ): Promise { + return await this.pagesService.update(id, updatePageDto) + } + + @Put() + @Documentation({ + description: 'Update display order of pages', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updatePagesDisplayOrderDto: UpdatePagesDisplayOrderDto, + ): Promise { + return this.pagesService.updateDisplayOrder(updatePagesDisplayOrderDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.pagesService.delete(id) + } +} diff --git a/apps/services/form-system/src/app/modules/pages/pages.module.ts b/apps/services/form-system/src/app/modules/pages/pages.module.ts new file mode 100644 index 000000000000..8ca5be631b8e --- /dev/null +++ b/apps/services/form-system/src/app/modules/pages/pages.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { PagesController } from './pages.controller' +import { PagesService } from './pages.service' +import { Page } from './models/page.model' +import { SequelizeModule } from '@nestjs/sequelize' + +@Module({ + imports: [SequelizeModule.forFeature([Page])], + controllers: [PagesController], + providers: [PagesService], +}) +export class PagesModule {} diff --git a/apps/services/form-system/src/app/modules/pages/pages.service.spec.ts b/apps/services/form-system/src/app/modules/pages/pages.service.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/pages/pages.service.ts b/apps/services/form-system/src/app/modules/pages/pages.service.ts new file mode 100644 index 000000000000..623219e0172b --- /dev/null +++ b/apps/services/form-system/src/app/modules/pages/pages.service.ts @@ -0,0 +1,83 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { Page } from './models/page.model' +import { InjectModel } from '@nestjs/sequelize' +import { Input } from '../inputs/models/input.model' +import { CreatePageDto } from './models/dto/createPage.dto' +import { UpdatePageDto } from './models/dto/updatePage.dto' +import { PageDto } from './models/dto/page.dto' +import { UpdatePagesDisplayOrderDto } from './models/dto/updatePagesDisplayOrder.dto' + +@Injectable() +export class PagesService { + constructor( + @InjectModel(Page) + private readonly pageModel: typeof Page, + ) {} + + async findAll(): Promise { + return await this.pageModel.findAll() + } + + async findOne(id: string): Promise { + const page = await this.pageModel.findByPk(id, { include: [Input] }) + + if (!page) { + throw new NotFoundException(`Page with id '${id}' not found`) + } + + return page + } + + async create(createPageDto: CreatePageDto): Promise { + const page = createPageDto as Page + const newPage: Page = new this.pageModel(page) + return await newPage.save() + } + + async update(id: string, updatePageDto: UpdatePageDto): Promise { + const page = await this.findOne(id) + + page.name = updatePageDto.name + page.multiset = updatePageDto.multiset + page.modified = new Date() + + await page.save() + + const pageDto: PageDto = { + id: page.id, + sectionId: page.sectionId, + name: page.name, + displayOrder: page.displayOrder, + multiset: page.multiset, + } + + return pageDto + } + + async updateDisplayOrder( + updatePagesDisplayOrderDto: UpdatePagesDisplayOrderDto, + ): Promise { + const { pagesDisplayOrderDto: pagesDisplayOrderDto } = + updatePagesDisplayOrderDto + + for (let i = 0; i < pagesDisplayOrderDto.length; i++) { + const page = await this.pageModel.findByPk(pagesDisplayOrderDto[i].id) + + if (!page) { + throw new NotFoundException( + `Page with id '${pagesDisplayOrderDto[i].id}' not found`, + ) + } + + page.update({ + displayOrder: i, + sectionId: pagesDisplayOrderDto[i].sectionId, + }) + } + } + + async delete(id: string): Promise { + const page = await this.findOne(id) + page?.destroy() + } +} diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts similarity index 64% rename from apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts rename to apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts index 3812a147f476..40410a17b0ee 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/applicationStep.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { ApplicationGroup } from '../../../groups/models/dto/applicationGroup.dto' +import { ApplicationPage } from '../../../pages/models/dto/applicationPage.dto' -export class ApplicationStep { +export class ApplicationSection { @ApiProperty() id!: string @@ -10,7 +10,7 @@ export class ApplicationStep { name!: LanguageType @ApiProperty() - stepType!: string + sectionType!: string @ApiProperty() displayOrder!: number @@ -21,6 +21,6 @@ export class ApplicationStep { @ApiProperty() callRuleset!: boolean - @ApiProperty({ type: [ApplicationGroup] }) - groups!: ApplicationGroup[] + @ApiProperty({ type: [ApplicationPage] }) + pages!: ApplicationPage[] } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts similarity index 72% rename from apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts rename to apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts index 9f54575fd828..d1702024e4b2 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/createStep.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class CreateStepDto { +export class CreateSectionDto { @ApiProperty() formId!: string } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts similarity index 88% rename from apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts rename to apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts index 8c8e1c0fd779..69f2d3804db2 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/step.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class StepDto { +export class SectionDto { @ApiProperty() id!: string @@ -9,7 +9,7 @@ export class StepDto { name!: LanguageType @ApiProperty() - stepType!: string + sectionType!: string @ApiProperty() displayOrder!: number diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts similarity index 67% rename from apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts rename to apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts index 5e3e42f9c87d..a7bfe50acd43 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/stepDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class StepDisplayOrderDto { +export class SectionDisplayOrderDto { @ApiProperty() id!: string } diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts similarity index 90% rename from apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts rename to apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts index 80304f71c59e..00133fa926dd 100644 --- a/apps/services/form-system/src/app/modules/steps/models/dto/updateStep.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class UpdateStepDto { +export class UpdateSectionDto { @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts new file mode 100644 index 000000000000..b2c60ca15ff9 --- /dev/null +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { SectionDisplayOrderDto } from './sectionDisplayOrder.dto' + +export class UpdateSectionsDisplayOrderDto { + @ApiProperty({ type: [SectionDisplayOrderDto] }) + sectionsDisplayOrderDto!: SectionDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/steps/models/step.model.ts b/apps/services/form-system/src/app/modules/sections/models/section.model.ts similarity index 82% rename from apps/services/form-system/src/app/modules/steps/models/step.model.ts rename to apps/services/form-system/src/app/modules/sections/models/section.model.ts index 76060d779284..96e4a59afcdc 100644 --- a/apps/services/form-system/src/app/modules/steps/models/step.model.ts +++ b/apps/services/form-system/src/app/modules/sections/models/section.model.ts @@ -11,12 +11,12 @@ import { UpdatedAt, } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' -import { StepTypes } from '../../../enums/stepTypes' +import { SectionTypes } from '../../../enums/sectionTypes' import { Form } from '../../forms/models/form.model' -import { Group } from '../../groups/models/group.model' +import { Page } from '../../pages/models/page.model' -@Table({ tableName: 'steps' }) -export class Step extends Model { +@Table({ tableName: 'sections' }) +export class Section extends Model
{ @Column({ type: DataType.UUID, allowNull: false, @@ -45,10 +45,10 @@ export class Step extends Model { @Column({ type: DataTypes.ENUM, allowNull: false, - values: Object.values(StepTypes), + values: Object.values(SectionTypes), }) - @ApiProperty({ enum: StepTypes }) - stepType!: string + @ApiProperty({ enum: SectionTypes }) + sectionType!: string @Column({ type: DataType.INTEGER, @@ -90,9 +90,9 @@ export class Step extends Model { @ApiProperty() isCompleted!: boolean - @HasMany(() => Group) - @ApiProperty({ type: [Group] }) - groups?: Group[] + @HasMany(() => Page) + @ApiProperty({ type: [Page] }) + pages?: Page[] @ForeignKey(() => Form) @Column({ type: DataType.STRING, allowNull: false, field: 'form_id' }) diff --git a/apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts b/apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/sections/sections.controller.ts b/apps/services/form-system/src/app/modules/sections/sections.controller.ts new file mode 100644 index 000000000000..40edd5ce9535 --- /dev/null +++ b/apps/services/form-system/src/app/modules/sections/sections.controller.ts @@ -0,0 +1,78 @@ +import { + Body, + Controller, + Post, + Get, + Delete, + Param, + NotFoundException, + Put, +} from '@nestjs/common' +import { SectionsService } from './sections.service' +import { CreateSectionDto } from './models/dto/createSection.dto' +import { Section } from './models/section.model' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' +import { UpdateSectionDto } from './models/dto/updateSection.dto' +import { SectionDto } from './models/dto/section.dto' +import { UpdateSectionsDisplayOrderDto } from './models/dto/updateSectionsDisplayOrder.dto' + +@ApiTags('sections') +@Controller('sections') +export class SectionsController { + constructor(private readonly sectionsService: SectionsService) {} + + @Post() + create(@Body() createSectionDto: CreateSectionDto): Promise
{ + return this.sectionsService.create(createSectionDto) + } + + @Get() + @Documentation({ + description: 'Get all Sections', + response: { status: 200, type: [Section] }, + }) + async findAll(): Promise { + return await this.sectionsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Section by id', + response: { status: 200, type: Section }, + }) + async findOne(@Param('id') id: string): Promise
{ + const section = await this.sectionsService.findOne(id) + if (!section) { + throw new NotFoundException(`Section not found`) + } + + return section + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.sectionsService.delete(id) + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateSectionDto: UpdateSectionDto, + ): Promise { + return await this.sectionsService.update(id, updateSectionDto) + } + + @Put() + @Documentation({ + description: 'Update display order of sections', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateSectionsDisplayOrderDto: UpdateSectionsDisplayOrderDto, + ): Promise { + return this.sectionsService.updateDisplayOrder( + updateSectionsDisplayOrderDto, + ) + } +} diff --git a/apps/services/form-system/src/app/modules/sections/sections.module.ts b/apps/services/form-system/src/app/modules/sections/sections.module.ts new file mode 100644 index 000000000000..3aac7bc369ce --- /dev/null +++ b/apps/services/form-system/src/app/modules/sections/sections.module.ts @@ -0,0 +1,13 @@ +import { Module } from '@nestjs/common' +import { SectionsController } from './sections.controller' +import { SectionsService } from './sections.service' +import { SequelizeModule } from '@nestjs/sequelize' +import { Section } from './models/section.model' + +@Module({ + imports: [SequelizeModule.forFeature([Section])], + controllers: [SectionsController], + providers: [SectionsService], + exports: [SectionsService], +}) +export class SectionsModule {} diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.spec.ts b/apps/services/form-system/src/app/modules/sections/sections.service.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.ts b/apps/services/form-system/src/app/modules/sections/sections.service.ts new file mode 100644 index 000000000000..78d1939dab8b --- /dev/null +++ b/apps/services/form-system/src/app/modules/sections/sections.service.ts @@ -0,0 +1,98 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { Section } from './models/section.model' +import { CreateSectionDto } from './models/dto/createSection.dto' +import { Page } from '../pages/models/page.model' +import { Input } from '../inputs/models/input.model' +import { UpdateSectionDto } from './models/dto/updateSection.dto' +import { SectionDto } from './models/dto/section.dto' +import { UpdateSectionsDisplayOrderDto } from './models/dto/updateSectionsDisplayOrder.dto' + +@Injectable() +export class SectionsService { + constructor( + @InjectModel(Section) + private readonly sectionModel: typeof Section, + ) {} + + async findAll(): Promise { + return await this.sectionModel.findAll() + } + + async findOne(id: string): Promise
{ + const section = await this.sectionModel.findByPk(id, { + include: [ + { + model: Page, + as: 'pages', + include: [{ model: Input, as: 'inputs' }], + }, + ], + }) + + if (!section) { + throw new NotFoundException(`Section with id '${id}' not found`) + } + + return section + } + + async create(createSectionDto: CreateSectionDto): Promise
{ + const section = createSectionDto as Section + const newSection: Section = new this.sectionModel(section) + return await newSection.save() + } + + async update( + id: string, + updateSectionDto: UpdateSectionDto, + ): Promise { + const section = await this.findOne(id) + + section.name = updateSectionDto.name + section.waitingText = updateSectionDto.waitingText + section.callRuleset = updateSectionDto.callRuleset + section.modified = new Date() + + await section.save() + + const sectionDto: SectionDto = { + id: section.id, + name: section.name, + sectionType: section.sectionType, + displayOrder: section.displayOrder, + waitingText: section.waitingText, + callRuleset: section.callRuleset, + } + + return sectionDto + } + + async updateDisplayOrder( + updateSectionDisplayOrderDto: UpdateSectionsDisplayOrderDto, + ): Promise { + const { sectionsDisplayOrderDto: sectionsDisplayOrderDto } = + updateSectionDisplayOrderDto + + for (let i = 0; i < sectionsDisplayOrderDto.length; i++) { + const section = await this.sectionModel.findByPk( + sectionsDisplayOrderDto[i].id, + ) + + if (!section) { + throw new NotFoundException( + `Section with id '${sectionsDisplayOrderDto[i].id}' not found`, + ) + } + + await section.update({ + displayOrder: i, + }) + } + } + + async delete(id: string): Promise { + const section = await this.findOne(id) + section?.destroy() + } +} diff --git a/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts deleted file mode 100644 index 7b83d9f72491..000000000000 --- a/apps/services/form-system/src/app/modules/steps/models/dto/updateStepsDisplayOrder.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { StepDisplayOrderDto } from './stepDisplayOrder.dto' - -export class UpdateStepsDisplayOrderDto { - @ApiProperty({ type: [StepDisplayOrderDto] }) - stepsDisplayOrderDto!: StepDisplayOrderDto[] -} diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts deleted file mode 100644 index 96c9f42c0d5b..000000000000 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -// import { TestApp, testServer, useDatabase } from '@island.is/testing/nest' -// import { SequelizeConfigService } from '../../sequelizeConfig.service' -// import { StepsController } from './steps.controller' -// import { StepsModule } from './steps.module' - -// describe('StepsController', () => { -// let controller: StepsController -// let app: TestApp - -// beforeEach(async () => { -// app = await testServer({ -// appModule: StepsModule, -// hooks: [ -// useDatabase({ type: 'postgres', provider: SequelizeConfigService }), -// ], -// }) -// controller = app.get(StepsController) -// }) - -// it('should run', () => { -// expect(true).toBeTruthy -// }) -// }) diff --git a/apps/services/form-system/src/app/modules/steps/steps.controller.ts b/apps/services/form-system/src/app/modules/steps/steps.controller.ts deleted file mode 100644 index e2111671e7c7..000000000000 --- a/apps/services/form-system/src/app/modules/steps/steps.controller.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - Body, - Controller, - Post, - Get, - Delete, - Param, - NotFoundException, - Put, -} from '@nestjs/common' -import { StepsService } from './steps.service' -import { CreateStepDto } from './models/dto/createStep.dto' -import { Step } from './models/step.model' -import { Documentation } from '@island.is/nest/swagger' -import { ApiTags } from '@nestjs/swagger' -import { UpdateStepDto } from './models/dto/updateStep.dto' -import { StepDto } from './models/dto/step.dto' -import { UpdateStepsDisplayOrderDto } from './models/dto/updateStepsDisplayOrder.dto' - -@ApiTags('steps') -@Controller('steps') -export class StepsController { - constructor(private readonly stepsService: StepsService) {} - - @Post() - create(@Body() createStepDto: CreateStepDto): Promise { - return this.stepsService.create(createStepDto) - } - - @Get() - @Documentation({ - description: 'Get all Steps', - response: { status: 200, type: [Step] }, - }) - async findAll(): Promise { - return await this.stepsService.findAll() - } - - @Get(':id') - @Documentation({ - description: 'Get Step by id', - response: { status: 200, type: Step }, - }) - async findOne(@Param('id') id: string): Promise { - const step = await this.stepsService.findOne(id) - if (!step) { - throw new NotFoundException(`Step not found`) - } - - return step - } - - @Delete(':id') - async delete(@Param('id') id: string): Promise { - return this.stepsService.delete(id) - } - - @Put(':id') - async update( - @Param('id') id: string, - @Body() updateStepDto: UpdateStepDto, - ): Promise { - return await this.stepsService.update(id, updateStepDto) - } - - @Put() - @Documentation({ - description: 'Update display order of steps', - response: { status: 204 }, - }) - async updateDisplayOrder( - @Body() updateStepsDisplayOrderDto: UpdateStepsDisplayOrderDto, - ): Promise { - return this.stepsService.updateDisplayOrder(updateStepsDisplayOrderDto) - } -} diff --git a/apps/services/form-system/src/app/modules/steps/steps.module.ts b/apps/services/form-system/src/app/modules/steps/steps.module.ts deleted file mode 100644 index 7b0c35abc238..000000000000 --- a/apps/services/form-system/src/app/modules/steps/steps.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Module } from '@nestjs/common' -import { StepsController } from './steps.controller' -import { StepsService } from './steps.service' -import { SequelizeModule } from '@nestjs/sequelize' -import { Step } from './models/step.model' - -@Module({ - imports: [SequelizeModule.forFeature([Step])], - controllers: [StepsController], - providers: [StepsService], - exports: [StepsService], -}) -export class StepsModule {} diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts b/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts deleted file mode 100644 index d8d2ce70bfc1..000000000000 --- a/apps/services/form-system/src/app/modules/steps/steps.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test } from '@nestjs/testing' -import { StepsService } from './steps.service' - -describe('StepsService', () => { - let service: StepsService - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [StepsService], - }).compile() - - service = module.get(StepsService) - }) - - it('should be defined', () => { - expect(service).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/steps/steps.service.ts b/apps/services/form-system/src/app/modules/steps/steps.service.ts deleted file mode 100644 index c309afe363fb..000000000000 --- a/apps/services/form-system/src/app/modules/steps/steps.service.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Injectable, NotFoundException } from '@nestjs/common' -import { InjectModel } from '@nestjs/sequelize' -import { Step } from './models/step.model' -import { CreateStepDto } from './models/dto/createStep.dto' -import { Group } from '../groups/models/group.model' -import { Input } from '../inputs/models/input.model' -import { UpdateStepDto } from './models/dto/updateStep.dto' -import { StepDto } from './models/dto/step.dto' -import { UpdateStepsDisplayOrderDto } from './models/dto/updateStepsDisplayOrder.dto' - -@Injectable() -export class StepsService { - constructor( - @InjectModel(Step) - private readonly stepModel: typeof Step, - ) {} - - async findAll(): Promise { - return await this.stepModel.findAll() - } - - async findOne(id: string): Promise { - const step = await this.stepModel.findByPk(id, { - include: [ - { - model: Group, - as: 'groups', - include: [{ model: Input, as: 'inputs' }], - }, - ], - }) - - if (!step) { - throw new NotFoundException(`Step with id '${id}' not found`) - } - - return step - } - - async create(createStepDto: CreateStepDto): Promise { - const step = createStepDto as Step - const newStep: Step = new this.stepModel(step) - return await newStep.save() - } - - async update(id: string, updateStepDto: UpdateStepDto): Promise { - const step = await this.findOne(id) - - step.name = updateStepDto.name - step.waitingText = updateStepDto.waitingText - step.callRuleset = updateStepDto.callRuleset - step.modified = new Date() - - await step.save() - - const stepDto: StepDto = { - id: step.id, - name: step.name, - stepType: step.stepType, - displayOrder: step.displayOrder, - waitingText: step.waitingText, - callRuleset: step.callRuleset, - } - - return stepDto - } - - async updateDisplayOrder( - updateStepsDisplayOrderDto: UpdateStepsDisplayOrderDto, - ): Promise { - const { stepsDisplayOrderDto } = updateStepsDisplayOrderDto - - for (let i = 0; i < stepsDisplayOrderDto.length; i++) { - const step = await this.stepModel.findByPk(stepsDisplayOrderDto[i].id) - - if (!step) { - throw new NotFoundException( - `Step with id '${stepsDisplayOrderDto[i].id}' not found`, - ) - } - - await step.update({ - displayOrder: i, - }) - } - } - - async delete(id: string): Promise { - const step = await this.findOne(id) - step?.destroy() - } -} From 8944cddf3b73af43c6e5ea90eb13213d8b52ddc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Thu, 27 Jun 2024 13:56:54 +0000 Subject: [PATCH 43/72] tiny lint things --- .../services/form-system/src/app/modules/forms/forms.service.ts | 1 - .../form-system/src/app/modules/forms/models/dto/form.dto.ts | 2 +- .../src/app/modules/forms/models/dto/formsListForm.dto.ts | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 229343bd1075..b86a50171803 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -24,7 +24,6 @@ import { FormDto } from './models/dto/form.dto' import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' import { ListItem } from '../listItems/models/listItem.model' -import { FormsListFormDto } from './models/dto/formsListForm.dto' import { FormsListDto } from './models/dto/formsList.dto' import { FormMapper } from './models/form.mapper' diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index dcc2f89f3eed..d974ea985fd2 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -18,7 +18,7 @@ export class FormDto { name!: LanguageType @ApiProperty() - urlName!: String + urlName!: string @ApiProperty() invalidationDate?: Date diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts index eec39ffa153b..632afd0fd42f 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -9,7 +9,7 @@ export class FormsListFormDto { name!: LanguageType @ApiProperty() - urlName!: String + urlName!: string @ApiProperty() invalidationDate?: Date From 87a06365d1cab4d73a7c0af8d4320b4a22a974d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Thu, 27 Jun 2024 17:04:56 +0000 Subject: [PATCH 44/72] change naming of page to screen --- .../migrations/20240605120322-create-form.js | 2 +- ...age.js => 20240605122019-create-screen.js} | 4 +- .../migrations/20240611122625-create-input.js | 4 +- .../form-system/src/app/app.module.ts | 4 +- .../src/app/modules/forms/forms.module.ts | 4 +- .../src/app/modules/forms/forms.service.ts | 48 +++++----- .../app/modules/forms/models/dto/form.dto.ts | 8 +- .../forms/models/dto/formsListForm.dto.ts | 2 +- .../app/modules/forms/models/form.mapper.ts | 2 +- .../app/modules/forms/models/form.model.ts | 2 +- .../src/app/modules/inputs/inputs.service.ts | 6 +- .../inputs/models/dto/applicationInput.dto.ts | 2 +- .../inputs/models/dto/createInput.dto.ts | 2 +- .../modules/inputs/models/dto/input.dto.ts | 2 +- .../models/dto/inputDisplayOrder.dto.ts | 2 +- .../app/modules/inputs/models/input.mapper.ts | 2 +- .../app/modules/inputs/models/input.model.ts | 8 +- .../models/dto/updatePagesDisplayOrder.dto.ts | 7 -- .../src/app/modules/pages/pages.controller.ts | 76 ---------------- .../src/app/modules/pages/pages.module.ts | 12 --- .../src/app/modules/pages/pages.service.ts | 83 ----------------- .../models/dto/applicationScreen.dto.ts} | 2 +- .../models/dto/createScreen.dto.ts} | 2 +- .../models/dto/screen.dto.ts} | 2 +- .../models/dto/screenDisplayOrder.dto.ts} | 2 +- .../models/dto/updateScreen.dto.ts} | 2 +- .../dto/updateScreensDisplayOrder.dto.ts | 7 ++ .../models/screen.model.ts} | 4 +- .../screens.controller.spec.ts} | 0 .../app/modules/screens/screens.controller.ts | 76 ++++++++++++++++ .../src/app/modules/screens/screens.module.ts | 12 +++ .../screens.service.spec.ts} | 0 .../app/modules/screens/screens.service.ts | 88 +++++++++++++++++++ .../models/dto/applicationSection.dto.ts | 6 +- .../modules/sections/models/section.model.ts | 8 +- .../app/modules/sections/sections.service.ts | 6 +- 36 files changed, 252 insertions(+), 247 deletions(-) rename apps/services/form-system/migrations/{20240605122019-create-page.js => 20240605122019-create-screen.js} (94%) delete mode 100644 apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts delete mode 100644 apps/services/form-system/src/app/modules/pages/pages.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/pages/pages.module.ts delete mode 100644 apps/services/form-system/src/app/modules/pages/pages.service.ts rename apps/services/form-system/src/app/modules/{pages/models/dto/applicationPage.dto.ts => screens/models/dto/applicationScreen.dto.ts} (93%) rename apps/services/form-system/src/app/modules/{pages/models/dto/createPage.dto.ts => screens/models/dto/createScreen.dto.ts} (73%) rename apps/services/form-system/src/app/modules/{pages/models/dto/page.dto.ts => screens/models/dto/screen.dto.ts} (93%) rename apps/services/form-system/src/app/modules/{pages/models/dto/pageDisplayOrder.dto.ts => screens/models/dto/screenDisplayOrder.dto.ts} (76%) rename apps/services/form-system/src/app/modules/{pages/models/dto/updatePage.dto.ts => screens/models/dto/updateScreen.dto.ts} (87%) create mode 100644 apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts rename apps/services/form-system/src/app/modules/{pages/models/page.model.ts => screens/models/screen.model.ts} (95%) rename apps/services/form-system/src/app/modules/{pages/pages.controller.spec.ts => screens/screens.controller.spec.ts} (100%) create mode 100644 apps/services/form-system/src/app/modules/screens/screens.controller.ts create mode 100644 apps/services/form-system/src/app/modules/screens/screens.module.ts rename apps/services/form-system/src/app/modules/{pages/pages.service.spec.ts => screens/screens.service.spec.ts} (100%) create mode 100644 apps/services/form-system/src/app/modules/screens/screens.service.ts diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 06c5820b9b1b..44761a82754a 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -49,7 +49,7 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, }, - stop_progress_on_validating_page: { + stop_progress_on_validating_screen: { type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true, diff --git a/apps/services/form-system/migrations/20240605122019-create-page.js b/apps/services/form-system/migrations/20240605122019-create-screen.js similarity index 94% rename from apps/services/form-system/migrations/20240605122019-create-page.js rename to apps/services/form-system/migrations/20240605122019-create-screen.js index bfcc12b3c983..12e8d2065f8d 100644 --- a/apps/services/form-system/migrations/20240605122019-create-page.js +++ b/apps/services/form-system/migrations/20240605122019-create-screen.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'pages', + 'screens', { id: { type: Sequelize.UUID, @@ -56,7 +56,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('pages', { transaction: t }), + queryInterface.dropTable('screens', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240611122625-create-input.js b/apps/services/form-system/migrations/20240611122625-create-input.js index 4dc47bc40164..d7646974d024 100644 --- a/apps/services/form-system/migrations/20240611122625-create-input.js +++ b/apps/services/form-system/migrations/20240611122625-create-input.js @@ -44,12 +44,12 @@ module.exports = { allowNull: false, defaultValue: false, }, - page_id: { + screen_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'pages', + model: 'screens', key: 'id', }, }, diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index ecb8ad50f1a6..13eaa911ba82 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -5,7 +5,7 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' import { environment } from '../environments' import { FormsModule } from './modules/forms/forms.module' -import { PagesModule } from './modules/pages/pages.module' +import { ScreensModule } from './modules/screens/screens.module' import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' import { InputsModule } from './modules/inputs/inputs.module' import { ListsModule } from './modules/lists/lists.module' @@ -27,7 +27,7 @@ import { ApplicationsModule } from './modules/applications/applications.module' OrganizationsModule, FormsModule, SectionsModule, - PagesModule, + ScreensModule, InputsModule, TestimoniesModule, ListsModule, diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index 3d7bd70fc8d8..45802aea6fa1 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -1,7 +1,7 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' import { FormApplicant } from '../applicants/models/formApplicant.model' -import { Page } from '../pages/models/page.model' +import { Screen } from '../screens/models/screen.model' import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputType } from '../inputs/models/inputType.model' import { ListType } from '../lists/models/listType.model' @@ -21,7 +21,7 @@ import { FormMapper } from './models/form.mapper' Form, FormApplicant, Section, - Page, + Screen, Organization, InputType, TestimonyType, diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index b86a50171803..7634d5737e93 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -2,8 +2,8 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' import { SectionTypes } from '../../enums/sectionTypes' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' -import { PageDto } from '../pages/models/dto/page.dto' -import { Page } from '../pages/models/page.model' +import { ScreenDto } from '../screens/models/dto/screen.dto' +import { Screen } from '../screens/models/screen.model' import { InputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' import { InputSettings } from '../inputSettings/models/inputSettings.model' @@ -34,8 +34,8 @@ export class FormsService { private readonly formModel: typeof Form, @InjectModel(Section) private readonly sectionModel: typeof Section, - @InjectModel(Page) - private readonly pageModel: typeof Page, + @InjectModel(Screen) + private readonly screenModel: typeof Screen, @InjectModel(Organization) private readonly organizationModel: typeof Organization, @InjectModel(InputType) @@ -108,8 +108,8 @@ export class FormsService { as: 'sections', include: [ { - model: Page, - as: 'pages', + model: Screen, + as: 'screens', include: [ { model: Input, @@ -248,12 +248,12 @@ export class FormsService { isTranslated: form.isTranslated, applicationDaysToRemove: form.applicationDaysToRemove, derivedFrom: form.derivedFrom, - stopProgressOnValidatingPage: form.stopProgressOnValidatingPage, + stopProgressOnValidatingScreen: form.stopProgressOnValidatingScreen, completedMessage: form.completedMessage, testimonyTypes: [], applicants: [], sections: [], - pages: [], + screens: [], inputs: [], } @@ -287,21 +287,21 @@ export class FormsService { isCompleted: section.isCompleted, callRuleset: section.callRuleset, } as SectionDto) - section.pages?.map((page) => { - formDto.pages?.push({ - id: page.id, + section.screens?.map((screen) => { + formDto.screens?.push({ + id: screen.id, sectionId: section.id, - name: page.name, - created: page.created, - modified: page.modified, - displayOrder: page.displayOrder, - isHidden: page.isHidden, - multiset: page.multiset, - } as PageDto) - page.inputs?.map((input) => { + name: screen.name, + created: screen.created, + modified: screen.modified, + displayOrder: screen.displayOrder, + isHidden: screen.isHidden, + multiset: screen.multiset, + } as ScreenDto) + screen.inputs?.map((input) => { formDto.inputs?.push({ id: input.id, - pageId: page.id, + screenId: screen.id, name: input.name, created: input.created, modified: input.modified, @@ -342,7 +342,7 @@ export class FormsService { formId: form.id, sectionType: SectionTypes.INPUT, displayOrder: 2, - name: { is: 'Innsláttarsíða', en: 'InputPage' }, + name: { is: 'Innsláttarskjár', en: 'InputScreen' }, } as Section) await this.sectionModel.create({ @@ -352,10 +352,10 @@ export class FormsService { name: { is: 'Greiðsla', en: 'Payment' }, } as Section) - await this.pageModel.create({ + await this.screenModel.create({ sectionId: inputSection.id, displayOrder: 0, - name: { is: 'Síða 1', en: 'Page 1' }, - } as Page) + name: { is: 'Skjár 1', en: 'Screen 1' }, + } as Screen) } } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index d974ea985fd2..6ac943c9c883 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' -import { PageDto } from '../../../pages/models/dto/page.dto' +import { ScreenDto } from '../../../screens/models/dto/screen.dto' import { InputDto } from '../../../inputs/models/dto/input.dto' import { SectionDto } from '../../../sections/models/dto/section.dto' import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' @@ -39,7 +39,7 @@ export class FormDto { derivedFrom!: number @ApiProperty() - stopProgressOnValidatingPage!: boolean + stopProgressOnValidatingScreen!: boolean @ApiProperty({ type: LanguageType }) completedMessage?: LanguageType @@ -53,8 +53,8 @@ export class FormDto { @ApiProperty({ type: [SectionDto] }) sections?: SectionDto[] - @ApiProperty({ type: [PageDto] }) - pages?: PageDto[] + @ApiProperty({ type: [ScreenDto] }) + screens?: ScreenDto[] @ApiProperty({ type: [InputDto] }) inputs?: InputDto[] diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts index 632afd0fd42f..2f0e8fa5949b 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -30,5 +30,5 @@ export class FormsListFormDto { derivedFrom!: number @ApiProperty() - stopProgressOnValidatingPage!: boolean + stopProgressOnValidatingScreen!: boolean } diff --git a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts index fffe08187d07..9db6d94e8448 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts @@ -17,7 +17,7 @@ export class FormMapper { isTranslated: form.isTranslated, applicationDaysToRemove: form.applicationDaysToRemove, derivedFrom: form.derivedFrom, - stopProgressOnValidatingPage: form.stopProgressOnValidatingPage, + stopProgressOnValidatingScreen: form.stopProgressOnValidatingScreen, } as FormsListFormDto }) const formsListDto: FormsListDto = { diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index 8561429b79fe..d58a9846f0fd 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -84,7 +84,7 @@ export class Form extends Model { defaultValue: true, }) @ApiProperty() - stopProgressOnValidatingPage!: boolean + stopProgressOnValidatingScreen!: boolean @Column({ type: DataType.JSON, diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts index ab66da4beaac..e344692f71b3 100644 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts @@ -47,10 +47,10 @@ export class InputsService { } async create(createInputDto: CreateInputDto): Promise { - const { pageId: pageId } = createInputDto + const { screenId } = createInputDto const newInput: Input = await this.inputModel.create({ - pageId: pageId, + screenId: screenId, } as Input) const newInputSettingsDto = await this.inputSettingsService.create( @@ -93,7 +93,7 @@ export class InputsService { await input.update({ displayOrder: i, - pageId: inputsDisplayOrderDto[i].pageId, + screenId: inputsDisplayOrderDto[i].screenId, }) } } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts index a90141bcbce3..4fc4cd346f0e 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts @@ -7,7 +7,7 @@ export class ApplicationInput { id!: string @ApiProperty() - pageId!: string + screenId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts index da71a7dba095..2fda88eeae32 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts @@ -2,5 +2,5 @@ import { ApiProperty } from '@nestjs/swagger' export class CreateInputDto { @ApiProperty() - pageId!: string + screenId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts index 9b886ca943b2..6a8d5475ddcc 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts @@ -7,7 +7,7 @@ export class InputDto { id!: string @ApiProperty() - pageId!: string + screenId!: string @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts index 401aa548d1dd..caccd0a0c024 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts @@ -5,5 +5,5 @@ export class InputDisplayOrderDto { id!: string @ApiProperty() - pageId!: string + screenId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts index 4ad3a3f9ccb9..228782bf5407 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts @@ -12,7 +12,7 @@ export class InputMapper { ): InputDto { const inputDto: InputDto = { id: input.id, - pageId: input.pageId, + screenId: input.screenId, name: input.name, displayOrder: input.displayOrder, description: input.description, diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts index 071d4661845e..8b886d90f2b6 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts +++ b/apps/services/form-system/src/app/modules/inputs/models/input.model.ts @@ -10,7 +10,7 @@ import { Table, UpdatedAt, } from 'sequelize-typescript' -import { Page } from '../../pages/models/page.model' +import { Screen } from '../../screens/models/screen.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { InputType } from './inputType.model' import { InputSettings } from '../../inputSettings/models/inputSettings.model' @@ -74,13 +74,13 @@ export class Input extends Model { @ApiProperty() isPartOfMultiset!: boolean - @ForeignKey(() => Page) + @ForeignKey(() => Screen) @Column({ type: DataType.STRING, allowNull: false, - field: 'page_id', + field: 'screen_id', }) - pageId!: string + screenId!: string @HasOne(() => InputSettings) @ApiProperty({ type: InputSettings }) diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts deleted file mode 100644 index bd2dc3503c39..000000000000 --- a/apps/services/form-system/src/app/modules/pages/models/dto/updatePagesDisplayOrder.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { PageDisplayOrderDto } from './pageDisplayOrder.dto' - -export class UpdatePagesDisplayOrderDto { - @ApiProperty({ type: [PageDisplayOrderDto] }) - pagesDisplayOrderDto!: PageDisplayOrderDto[] -} diff --git a/apps/services/form-system/src/app/modules/pages/pages.controller.ts b/apps/services/form-system/src/app/modules/pages/pages.controller.ts deleted file mode 100644 index f8dca995b23c..000000000000 --- a/apps/services/form-system/src/app/modules/pages/pages.controller.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - Controller, - Post, - Get, - Delete, - Body, - Param, - NotFoundException, - Put, -} from '@nestjs/common' -import { PagesService } from './pages.service' -import { CreatePageDto } from './models/dto/createPage.dto' -import { Page } from './models/page.model' -import { Documentation } from '@island.is/nest/swagger' -import { ApiTags } from '@nestjs/swagger' -import { UpdatePageDto } from './models/dto/updatePage.dto' -import { PageDto } from './models/dto/page.dto' -import { UpdatePagesDisplayOrderDto } from './models/dto/updatePagesDisplayOrder.dto' - -@ApiTags('pages') -@Controller('pages') -export class PagesController { - constructor(private readonly pagesService: PagesService) {} - - @Post() - create(@Body() createPageDto: CreatePageDto): Promise { - return this.pagesService.create(createPageDto) - } - - @Get() - @Documentation({ - description: 'Get all Pages', - response: { status: 200, type: [Page] }, - }) - async findAll(): Promise { - return await this.pagesService.findAll() - } - - @Get(':id') - @Documentation({ - description: 'Get Page by id', - response: { status: 200, type: Page }, - }) - async findOne(@Param('id') id: string): Promise { - const page = await this.pagesService.findOne(id) - if (!page) { - throw new NotFoundException(`Page not found`) - } - - return page - } - - @Put(':id') - async update( - @Param('id') id: string, - @Body() updatePageDto: UpdatePageDto, - ): Promise { - return await this.pagesService.update(id, updatePageDto) - } - - @Put() - @Documentation({ - description: 'Update display order of pages', - response: { status: 204 }, - }) - async updateDisplayOrder( - @Body() updatePagesDisplayOrderDto: UpdatePagesDisplayOrderDto, - ): Promise { - return this.pagesService.updateDisplayOrder(updatePagesDisplayOrderDto) - } - - @Delete(':id') - async delete(@Param('id') id: string): Promise { - return this.pagesService.delete(id) - } -} diff --git a/apps/services/form-system/src/app/modules/pages/pages.module.ts b/apps/services/form-system/src/app/modules/pages/pages.module.ts deleted file mode 100644 index 8ca5be631b8e..000000000000 --- a/apps/services/form-system/src/app/modules/pages/pages.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Module } from '@nestjs/common' -import { PagesController } from './pages.controller' -import { PagesService } from './pages.service' -import { Page } from './models/page.model' -import { SequelizeModule } from '@nestjs/sequelize' - -@Module({ - imports: [SequelizeModule.forFeature([Page])], - controllers: [PagesController], - providers: [PagesService], -}) -export class PagesModule {} diff --git a/apps/services/form-system/src/app/modules/pages/pages.service.ts b/apps/services/form-system/src/app/modules/pages/pages.service.ts deleted file mode 100644 index 623219e0172b..000000000000 --- a/apps/services/form-system/src/app/modules/pages/pages.service.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { Injectable, NotFoundException } from '@nestjs/common' -import { Page } from './models/page.model' -import { InjectModel } from '@nestjs/sequelize' -import { Input } from '../inputs/models/input.model' -import { CreatePageDto } from './models/dto/createPage.dto' -import { UpdatePageDto } from './models/dto/updatePage.dto' -import { PageDto } from './models/dto/page.dto' -import { UpdatePagesDisplayOrderDto } from './models/dto/updatePagesDisplayOrder.dto' - -@Injectable() -export class PagesService { - constructor( - @InjectModel(Page) - private readonly pageModel: typeof Page, - ) {} - - async findAll(): Promise { - return await this.pageModel.findAll() - } - - async findOne(id: string): Promise { - const page = await this.pageModel.findByPk(id, { include: [Input] }) - - if (!page) { - throw new NotFoundException(`Page with id '${id}' not found`) - } - - return page - } - - async create(createPageDto: CreatePageDto): Promise { - const page = createPageDto as Page - const newPage: Page = new this.pageModel(page) - return await newPage.save() - } - - async update(id: string, updatePageDto: UpdatePageDto): Promise { - const page = await this.findOne(id) - - page.name = updatePageDto.name - page.multiset = updatePageDto.multiset - page.modified = new Date() - - await page.save() - - const pageDto: PageDto = { - id: page.id, - sectionId: page.sectionId, - name: page.name, - displayOrder: page.displayOrder, - multiset: page.multiset, - } - - return pageDto - } - - async updateDisplayOrder( - updatePagesDisplayOrderDto: UpdatePagesDisplayOrderDto, - ): Promise { - const { pagesDisplayOrderDto: pagesDisplayOrderDto } = - updatePagesDisplayOrderDto - - for (let i = 0; i < pagesDisplayOrderDto.length; i++) { - const page = await this.pageModel.findByPk(pagesDisplayOrderDto[i].id) - - if (!page) { - throw new NotFoundException( - `Page with id '${pagesDisplayOrderDto[i].id}' not found`, - ) - } - - page.update({ - displayOrder: i, - sectionId: pagesDisplayOrderDto[i].sectionId, - }) - } - } - - async delete(id: string): Promise { - const page = await this.findOne(id) - page?.destroy() - } -} diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts similarity index 93% rename from apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts rename to apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts index c97c291e8674..c47c667c9802 100644 --- a/apps/services/form-system/src/app/modules/pages/models/dto/applicationPage.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { ApplicationInput } from '../../../inputs/models/dto/applicationInput.dto' -export class ApplicationPage { +export class ApplicationScreen { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts similarity index 73% rename from apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts rename to apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts index 81e966446074..18d68cb51b36 100644 --- a/apps/services/form-system/src/app/modules/pages/models/dto/createPage.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class CreatePageDto { +export class CreateScreenDto { @ApiProperty() sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts similarity index 93% rename from apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts rename to apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts index 4f8368e887f0..65ea08e69ce4 100644 --- a/apps/services/form-system/src/app/modules/pages/models/dto/page.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class PageDto { +export class ScreenDto { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts similarity index 76% rename from apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts rename to apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts index aa8deab9c1d3..b315cd1bdec1 100644 --- a/apps/services/form-system/src/app/modules/pages/models/dto/pageDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class PageDisplayOrderDto { +export class ScreenDisplayOrderDto { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts similarity index 87% rename from apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts rename to apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts index a591d04fb003..943dc33f7e75 100644 --- a/apps/services/form-system/src/app/modules/pages/models/dto/updatePage.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class UpdatePageDto { +export class UpdateScreenDto { @ApiProperty({ type: LanguageType }) name!: LanguageType diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts new file mode 100644 index 000000000000..5f4ed4a02952 --- /dev/null +++ b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { ScreenDisplayOrderDto } from './screenDisplayOrder.dto' + +export class UpdateScreensDisplayOrderDto { + @ApiProperty({ type: [ScreenDisplayOrderDto] }) + screensDisplayOrderDto!: ScreenDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/pages/models/page.model.ts b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts similarity index 95% rename from apps/services/form-system/src/app/modules/pages/models/page.model.ts rename to apps/services/form-system/src/app/modules/screens/models/screen.model.ts index 1826382e4636..c4850603d0da 100644 --- a/apps/services/form-system/src/app/modules/pages/models/page.model.ts +++ b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts @@ -14,8 +14,8 @@ import { CreationOptional } from 'sequelize' import { Input } from '../../inputs/models/input.model' import { LanguageType } from '../../../dataTypes/languageType.model' -@Table({ tableName: 'pages' }) -export class Page extends Model { +@Table({ tableName: 'screens' }) +export class Screen extends Model { @Column({ type: DataType.UUID, allowNull: false, diff --git a/apps/services/form-system/src/app/modules/pages/pages.controller.spec.ts b/apps/services/form-system/src/app/modules/screens/screens.controller.spec.ts similarity index 100% rename from apps/services/form-system/src/app/modules/pages/pages.controller.spec.ts rename to apps/services/form-system/src/app/modules/screens/screens.controller.spec.ts diff --git a/apps/services/form-system/src/app/modules/screens/screens.controller.ts b/apps/services/form-system/src/app/modules/screens/screens.controller.ts new file mode 100644 index 000000000000..98246cc8e367 --- /dev/null +++ b/apps/services/form-system/src/app/modules/screens/screens.controller.ts @@ -0,0 +1,76 @@ +import { + Controller, + Post, + Get, + Delete, + Body, + Param, + NotFoundException, + Put, +} from '@nestjs/common' +import { ScreensService } from './screens.service' +import { CreateScreenDto } from './models/dto/createScreen.dto' +import { Screen } from './models/screen.model' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' +import { UpdateScreenDto } from './models/dto/updateScreen.dto' +import { ScreenDto } from './models/dto/screen.dto' +import { UpdateScreensDisplayOrderDto } from './models/dto/updateScreensDisplayOrder.dto' + +@ApiTags('screens') +@Controller('screens') +export class ScreensController { + constructor(private readonly screensService: ScreensService) {} + + @Post() + create(@Body() createScreenDto: CreateScreenDto): Promise { + return this.screensService.create(createScreenDto) + } + + @Get() + @Documentation({ + description: 'Get all Screens', + response: { status: 200, type: [Screen] }, + }) + async findAll(): Promise { + return await this.screensService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Screen by id', + response: { status: 200, type: Screen }, + }) + async findOne(@Param('id') id: string): Promise { + const screen = await this.screensService.findOne(id) + if (!screen) { + throw new NotFoundException(`Screen not found`) + } + + return screen + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateScreenDto: UpdateScreenDto, + ): Promise { + return await this.screensService.update(id, updateScreenDto) + } + + @Put() + @Documentation({ + description: 'Update display order of screens', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateScreensDisplayOrderDto: UpdateScreensDisplayOrderDto, + ): Promise { + return this.screensService.updateDisplayOrder(updateScreensDisplayOrderDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.screensService.delete(id) + } +} diff --git a/apps/services/form-system/src/app/modules/screens/screens.module.ts b/apps/services/form-system/src/app/modules/screens/screens.module.ts new file mode 100644 index 000000000000..b24990443416 --- /dev/null +++ b/apps/services/form-system/src/app/modules/screens/screens.module.ts @@ -0,0 +1,12 @@ +import { Module } from '@nestjs/common' +import { ScreensController } from './screens.controller' +import { ScreensService } from './screens.service' +import { Screen } from './models/screen.model' +import { SequelizeModule } from '@nestjs/sequelize' + +@Module({ + imports: [SequelizeModule.forFeature([Screen])], + controllers: [ScreensController], + providers: [ScreensService], +}) +export class ScreensModule {} diff --git a/apps/services/form-system/src/app/modules/pages/pages.service.spec.ts b/apps/services/form-system/src/app/modules/screens/screens.service.spec.ts similarity index 100% rename from apps/services/form-system/src/app/modules/pages/pages.service.spec.ts rename to apps/services/form-system/src/app/modules/screens/screens.service.spec.ts diff --git a/apps/services/form-system/src/app/modules/screens/screens.service.ts b/apps/services/form-system/src/app/modules/screens/screens.service.ts new file mode 100644 index 000000000000..531aa55b6eda --- /dev/null +++ b/apps/services/form-system/src/app/modules/screens/screens.service.ts @@ -0,0 +1,88 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { Screen } from './models/screen.model' +import { InjectModel } from '@nestjs/sequelize' +import { Input } from '../inputs/models/input.model' +import { CreateScreenDto } from './models/dto/createScreen.dto' +import { UpdateScreenDto } from './models/dto/updateScreen.dto' +import { ScreenDto } from './models/dto/screen.dto' +import { UpdateScreensDisplayOrderDto } from './models/dto/updateScreensDisplayOrder.dto' + +@Injectable() +export class ScreensService { + constructor( + @InjectModel(Screen) + private readonly screenModel: typeof Screen, + ) {} + + async findAll(): Promise { + return await this.screenModel.findAll() + } + + async findOne(id: string): Promise { + const screen = await this.screenModel.findByPk(id, { include: [Input] }) + + if (!screen) { + throw new NotFoundException(`Screen with id '${id}' not found`) + } + + return screen + } + + async create(createScreenDto: CreateScreenDto): Promise { + const screen = createScreenDto as Screen + const newScreen: Screen = new this.screenModel(screen) + return await newScreen.save() + } + + async update( + id: string, + updateScreenDto: UpdateScreenDto, + ): Promise { + const screen = await this.findOne(id) + + screen.name = updateScreenDto.name + screen.multiset = updateScreenDto.multiset + screen.modified = new Date() + + await screen.save() + + const screenDto: ScreenDto = { + id: screen.id, + sectionId: screen.sectionId, + name: screen.name, + displayOrder: screen.displayOrder, + multiset: screen.multiset, + } + + return screenDto + } + + async updateDisplayOrder( + updateScreensDisplayOrderDto: UpdateScreensDisplayOrderDto, + ): Promise { + const { screensDisplayOrderDto: screensDisplayOrderDto } = + updateScreensDisplayOrderDto + + for (let i = 0; i < screensDisplayOrderDto.length; i++) { + const screen = await this.screenModel.findByPk( + screensDisplayOrderDto[i].id, + ) + + if (!screen) { + throw new NotFoundException( + `Screen with id '${screensDisplayOrderDto[i].id}' not found`, + ) + } + + screen.update({ + displayOrder: i, + sectionId: screensDisplayOrderDto[i].sectionId, + }) + } + } + + async delete(id: string): Promise { + const screen = await this.findOne(id) + screen?.destroy() + } +} diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts index 40410a17b0ee..cf5b78ab5bbc 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { ApplicationPage } from '../../../pages/models/dto/applicationPage.dto' +import { ApplicationScreen } from '../../../screens/models/dto/applicationScreen.dto' export class ApplicationSection { @ApiProperty() @@ -21,6 +21,6 @@ export class ApplicationSection { @ApiProperty() callRuleset!: boolean - @ApiProperty({ type: [ApplicationPage] }) - pages!: ApplicationPage[] + @ApiProperty({ type: [ApplicationScreen] }) + screens!: ApplicationScreen[] } diff --git a/apps/services/form-system/src/app/modules/sections/models/section.model.ts b/apps/services/form-system/src/app/modules/sections/models/section.model.ts index 96e4a59afcdc..93047683311c 100644 --- a/apps/services/form-system/src/app/modules/sections/models/section.model.ts +++ b/apps/services/form-system/src/app/modules/sections/models/section.model.ts @@ -13,7 +13,7 @@ import { import { LanguageType } from '../../../dataTypes/languageType.model' import { SectionTypes } from '../../../enums/sectionTypes' import { Form } from '../../forms/models/form.model' -import { Page } from '../../pages/models/page.model' +import { Screen } from '../../screens/models/screen.model' @Table({ tableName: 'sections' }) export class Section extends Model
{ @@ -90,9 +90,9 @@ export class Section extends Model
{ @ApiProperty() isCompleted!: boolean - @HasMany(() => Page) - @ApiProperty({ type: [Page] }) - pages?: Page[] + @HasMany(() => Screen) + @ApiProperty({ type: [Screen] }) + screens?: Screen[] @ForeignKey(() => Form) @Column({ type: DataType.STRING, allowNull: false, field: 'form_id' }) diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.ts b/apps/services/form-system/src/app/modules/sections/sections.service.ts index 78d1939dab8b..ee9e82df1e6d 100644 --- a/apps/services/form-system/src/app/modules/sections/sections.service.ts +++ b/apps/services/form-system/src/app/modules/sections/sections.service.ts @@ -2,7 +2,7 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' import { Section } from './models/section.model' import { CreateSectionDto } from './models/dto/createSection.dto' -import { Page } from '../pages/models/page.model' +import { Screen } from '../screens/models/screen.model' import { Input } from '../inputs/models/input.model' import { UpdateSectionDto } from './models/dto/updateSection.dto' import { SectionDto } from './models/dto/section.dto' @@ -23,8 +23,8 @@ export class SectionsService { const section = await this.sectionModel.findByPk(id, { include: [ { - model: Page, - as: 'pages', + model: Screen, + as: 'screens', include: [{ model: Input, as: 'inputs' }], }, ], From 65acc75ba7e0ce70aca765b8b8268c895ffc2e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 28 Jun 2024 11:11:52 +0000 Subject: [PATCH 45/72] changed naming of input to field --- ...js => 20240607142452-create-field-type.js} | 4 +- ...nput.js => 20240611122625-create-field.js} | 8 +- ...> 20240612095843-create-field-settings.js} | 8 +- ...4092719-create-organization-field-type.js} | 8 +- .../20240621165216-create-list-item.js | 4 +- ...e.js => 20240611110210-seed-field-type.js} | 4 +- ...614110902-seed-organization-field-type.js} | 8 +- .../form-system/src/app/app.module.ts | 8 +- .../fieldSettings/fieldSettings.module.ts | 14 +++ .../fieldSettings.service.spec.ts | 0 .../fieldSettings/fieldSettings.service.ts | 65 ++++++++++ .../models/dto/fieldSettings.dto.ts} | 42 +++---- .../models/dto/updateFieldSettings.dto.ts} | 2 +- .../models/fieldSettings.mapper.ts | 117 ++++++++++++++++++ .../models/fieldSettings.model.ts} | 12 +- .../modules/fields/fields.controller.spec.ts | 0 .../app/modules/fields/fields.controller.ts | 76 ++++++++++++ .../src/app/modules/fields/fields.module.ts | 24 ++++ .../app/modules/fields/fields.service.spec.ts | 0 .../src/app/modules/fields/fields.service.ts | 105 ++++++++++++++++ .../models/dto/applicationField.dto.ts} | 10 +- .../models/dto/createField.dto.ts} | 2 +- .../models/dto/field.dto.ts} | 10 +- .../models/dto/fieldDisplayOrder.dto.ts} | 2 +- .../models/dto/fieldType.dto.ts} | 8 +- .../models/dto/updateField.dto.ts} | 10 +- .../dto/updateFieldsDisplayOrder.dto.ts | 7 ++ .../app/modules/fields/models/field.mapper.ts | 34 +++++ .../models/field.model.ts} | 20 +-- .../models/fieldType.model.ts} | 14 +-- .../models/organizationFieldType.model.ts} | 12 +- .../src/app/modules/forms/forms.module.ts | 8 +- .../src/app/modules/forms/forms.service.ts | 105 ++++++++-------- .../app/modules/forms/models/dto/form.dto.ts | 6 +- .../forms/models/dto/form.response.dto.ts | 6 +- .../inputSettings/inputSettings.module.ts | 14 --- .../inputSettings.service.spec.ts | 18 --- .../inputSettings/inputSettings.service.ts | 65 ---------- .../models/inputSettings.mapper.ts | 117 ------------------ .../modules/inputs/inputs.controller.spec.ts | 18 --- .../app/modules/inputs/inputs.controller.ts | 76 ------------ .../src/app/modules/inputs/inputs.module.ts | 24 ---- .../app/modules/inputs/inputs.service.spec.ts | 18 --- .../src/app/modules/inputs/inputs.service.ts | 105 ---------------- .../dto/updateInputsDisplayOrder.dto.ts | 7 -- .../app/modules/inputs/models/input.mapper.ts | 34 ----- .../app/modules/listItems/listItems.module.ts | 12 +- .../modules/listItems/listItems.service.ts | 10 +- .../models/dto/createListItem.dto.ts | 2 +- .../listItems/models/listItem.model.ts | 8 +- .../models/organization.model.ts | 10 +- .../models/dto/applicationScreen.dto.ts | 6 +- .../modules/screens/models/screen.model.ts | 8 +- .../app/modules/screens/screens.service.ts | 4 +- .../app/modules/sections/sections.service.ts | 4 +- 55 files changed, 634 insertions(+), 689 deletions(-) rename apps/services/form-system/migrations/{20240607142452-create-input-type.js => 20240607142452-create-field-type.js} (93%) rename apps/services/form-system/migrations/{20240611122625-create-input.js => 20240611122625-create-field.js} (92%) rename apps/services/form-system/migrations/{20240612095843-create-input-settings.js => 20240612095843-create-field-settings.js} (95%) rename apps/services/form-system/migrations/{20240614092719-create-organization-input-type.js => 20240614092719-create-organization-field-type.js} (88%) rename apps/services/form-system/seeders/{20240611110210-seed-input-type.js => 20240611110210-seed-field-type.js} (98%) rename apps/services/form-system/seeders/{20240614110902-seed-organization-input-type.js => 20240614110902-seed-organization-field-type.js} (70%) create mode 100644 apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.module.ts create mode 100644 apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts rename apps/services/form-system/src/app/modules/{inputSettings/models/dto/inputSettings.dto.ts => fieldSettings/models/dto/fieldSettings.dto.ts} (63%) rename apps/services/form-system/src/app/modules/{inputSettings/models/dto/updateInputSettings.dto.ts => fieldSettings/models/dto/updateFieldSettings.dto.ts} (95%) create mode 100644 apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts rename apps/services/form-system/src/app/modules/{inputSettings/models/inputSettings.model.ts => fieldSettings/models/fieldSettings.model.ts} (93%) create mode 100644 apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts create mode 100644 apps/services/form-system/src/app/modules/fields/fields.controller.ts create mode 100644 apps/services/form-system/src/app/modules/fields/fields.module.ts create mode 100644 apps/services/form-system/src/app/modules/fields/fields.service.spec.ts create mode 100644 apps/services/form-system/src/app/modules/fields/fields.service.ts rename apps/services/form-system/src/app/modules/{inputs/models/dto/applicationInput.dto.ts => fields/models/dto/applicationField.dto.ts} (66%) rename apps/services/form-system/src/app/modules/{inputs/models/dto/createInput.dto.ts => fields/models/dto/createField.dto.ts} (74%) rename apps/services/form-system/src/app/modules/{inputs/models/dto/input.dto.ts => fields/models/dto/field.dto.ts} (67%) rename apps/services/form-system/src/app/modules/{inputs/models/dto/inputDisplayOrder.dto.ts => fields/models/dto/fieldDisplayOrder.dto.ts} (76%) rename apps/services/form-system/src/app/modules/{inputs/models/dto/inputType.dto.ts => fields/models/dto/fieldType.dto.ts} (64%) rename apps/services/form-system/src/app/modules/{inputs/models/dto/updateInput.dto.ts => fields/models/dto/updateField.dto.ts} (56%) create mode 100644 apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts create mode 100644 apps/services/form-system/src/app/modules/fields/models/field.mapper.ts rename apps/services/form-system/src/app/modules/{inputs/models/input.model.ts => fields/models/field.model.ts} (81%) rename apps/services/form-system/src/app/modules/{inputs/models/inputType.model.ts => fields/models/fieldType.model.ts} (85%) rename apps/services/form-system/src/app/modules/{inputs/models/organizationInputType.model.ts => fields/models/organizationFieldType.model.ts} (73%) delete mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts delete mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts delete mode 100644 apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.controller.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.module.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/inputs.service.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts delete mode 100644 apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts diff --git a/apps/services/form-system/migrations/20240607142452-create-input-type.js b/apps/services/form-system/migrations/20240607142452-create-field-type.js similarity index 93% rename from apps/services/form-system/migrations/20240607142452-create-input-type.js rename to apps/services/form-system/migrations/20240607142452-create-field-type.js index 912c430fd5dc..4f66a6810259 100644 --- a/apps/services/form-system/migrations/20240607142452-create-input-type.js +++ b/apps/services/form-system/migrations/20240607142452-create-field-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'input_types', + 'field_types', { id: { type: Sequelize.UUID, @@ -48,7 +48,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('input_types', { transaction: t }), + queryInterface.dropTable('field_types', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240611122625-create-input.js b/apps/services/form-system/migrations/20240611122625-create-field.js similarity index 92% rename from apps/services/form-system/migrations/20240611122625-create-input.js rename to apps/services/form-system/migrations/20240611122625-create-field.js index d7646974d024..2a5293e4cf15 100644 --- a/apps/services/form-system/migrations/20240611122625-create-input.js +++ b/apps/services/form-system/migrations/20240611122625-create-field.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'inputs', + 'fields', { id: { type: Sequelize.UUID, @@ -53,11 +53,11 @@ module.exports = { key: 'id', }, }, - input_type: { + field_type: { type: Sequelize.STRING, allowNull: false, references: { - model: 'input_types', + model: 'field_types', key: 'type', }, }, @@ -69,7 +69,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('inputs', { transaction: t }), + queryInterface.dropTable('fields', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240612095843-create-input-settings.js b/apps/services/form-system/migrations/20240612095843-create-field-settings.js similarity index 95% rename from apps/services/form-system/migrations/20240612095843-create-input-settings.js rename to apps/services/form-system/migrations/20240612095843-create-field-settings.js index 474105e0f185..51d2d0c9574a 100644 --- a/apps/services/form-system/migrations/20240612095843-create-input-settings.js +++ b/apps/services/form-system/migrations/20240612095843-create-field-settings.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'input_settings', + 'field_settings', { id: { type: Sequelize.UUID, @@ -110,12 +110,12 @@ module.exports = { ), allowNull: true, }, - input_id: { + field_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'inputs', + model: 'fields', key: 'id', }, }, @@ -127,7 +127,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('input_settings', { transaction: t }), + queryInterface.dropTable('field_settings', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240614092719-create-organization-input-type.js b/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js similarity index 88% rename from apps/services/form-system/migrations/20240614092719-create-organization-input-type.js rename to apps/services/form-system/migrations/20240614092719-create-organization-field-type.js index 28a7c5bde372..4e6692b790e7 100644 --- a/apps/services/form-system/migrations/20240614092719-create-organization-input-type.js +++ b/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organization_input_types', + 'organization_field_types', { id: { type: Sequelize.UUID, @@ -30,11 +30,11 @@ module.exports = { key: 'id', }, }, - input_type_id: { + field_type_id: { type: Sequelize.UUID, allowNull: false, references: { - model: 'input_types', + model: 'field_types', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organization_input_types', { transaction: t }), + queryInterface.dropTable('organization_field_types', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240621165216-create-list-item.js b/apps/services/form-system/migrations/20240621165216-create-list-item.js index 2e216c5142c4..af438922c068 100644 --- a/apps/services/form-system/migrations/20240621165216-create-list-item.js +++ b/apps/services/form-system/migrations/20240621165216-create-list-item.js @@ -45,12 +45,12 @@ module.exports = { allowNull: false, defaultValue: 0, }, - input_settings_id: { + field_settings_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'input_settings', + model: 'field_settings', key: 'id', }, }, diff --git a/apps/services/form-system/seeders/20240611110210-seed-input-type.js b/apps/services/form-system/seeders/20240611110210-seed-field-type.js similarity index 98% rename from apps/services/form-system/seeders/20240611110210-seed-input-type.js rename to apps/services/form-system/seeders/20240611110210-seed-field-type.js index f34df55cdfc1..611013768f1e 100644 --- a/apps/services/form-system/seeders/20240611110210-seed-input-type.js +++ b/apps/services/form-system/seeders/20240611110210-seed-field-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('input_types', [ + await queryInterface.bulkInsert('field_types', [ { id: '09206657-9a89-4265-b58e-13b220f805a2', type: 'default', @@ -234,6 +234,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('input_types', null, {}) + await queryInterface.bulkDelete('field_types', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js b/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js similarity index 70% rename from apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js rename to apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js index c7b4d65881e7..3cc720346ea8 100644 --- a/apps/services/form-system/seeders/20240614110902-seed-organization-input-type.js +++ b/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js @@ -2,25 +2,25 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organization_input_types', [ + await queryInterface.bulkInsert('organization_field_types', [ { id: 'b12e940e-1bd6-4180-a6eb-f620dce4e71c', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - input_type_id: '49599a07-4d06-4ad4-9927-b55eab2dd97d', // nationaIdEstate + field_type_id: '49599a07-4d06-4ad4-9927-b55eab2dd97d', // nationaIdEstate }, { id: '298bdf4f-6340-46c0-b403-59ec4ae3c19b', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - input_type_id: 'ad67a9c3-f5d9-47eb-bcf9-dd34becf4b76', // nationalIdAll + field_type_id: 'ad67a9c3-f5d9-47eb-bcf9-dd34becf4b76', // nationalIdAll }, ]) }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organization_input_types', null, {}) + await queryInterface.bulkDelete('organization_field_types', null, {}) }, } diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index 13eaa911ba82..a91a035fcc27 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -6,8 +6,8 @@ import { SequelizeModule } from '@nestjs/sequelize' import { environment } from '../environments' import { FormsModule } from './modules/forms/forms.module' import { ScreensModule } from './modules/screens/screens.module' -import { InputSettingsModule } from './modules/inputSettings/inputSettings.module' -import { InputsModule } from './modules/inputs/inputs.module' +import { FieldSettingsModule } from './modules/fieldSettings/fieldSettings.module' +import { FieldsModule } from './modules/fields/fields.module' import { ListsModule } from './modules/lists/lists.module' import { OrganizationsModule } from './modules/organizations/organizations.module' import { SectionsModule } from './modules/sections/sections.module' @@ -28,10 +28,10 @@ import { ApplicationsModule } from './modules/applications/applications.module' FormsModule, SectionsModule, ScreensModule, - InputsModule, + FieldsModule, TestimoniesModule, ListsModule, - InputSettingsModule, + FieldSettingsModule, ListItemsModule, ApplicationsModule, ], diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.module.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.module.ts new file mode 100644 index 000000000000..c718689d0bae --- /dev/null +++ b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { FieldSettings } from './models/fieldSettings.model' +import { FieldSettingsService } from './fieldSettings.service' +import { FieldSettingsMapper } from './models/fieldSettings.mapper' +import { ListItemMapper } from '../listItems/models/listItem.mapper' +import { ListItem } from '../listItems/models/listItem.model' + +@Module({ + imports: [SequelizeModule.forFeature([FieldSettings, ListItem])], + providers: [FieldSettingsService, FieldSettingsMapper, ListItemMapper], + exports: [FieldSettingsService], +}) +export class FieldSettingsModule {} diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts new file mode 100644 index 000000000000..554e8fddc0d7 --- /dev/null +++ b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts @@ -0,0 +1,65 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { FieldSettings } from './models/fieldSettings.model' +import { UpdateFieldSettingsDto } from './models/dto/updateFieldSettings.dto' +import { InjectModel } from '@nestjs/sequelize' +import { FieldSettingsMapper } from './models/fieldSettings.mapper' +import { FieldSettingsDto } from './models/dto/fieldSettings.dto' +import { ListItem } from '../listItems/models/listItem.model' + +@Injectable() +export class FieldSettingsService { + constructor( + @InjectModel(FieldSettings) + private readonly fieldSettingsModel: typeof FieldSettings, + private readonly fieldSettingsMapper: FieldSettingsMapper, + ) {} + + async create(fieldId: string): Promise { + await this.fieldSettingsModel.create({ + fieldId: fieldId, + } as FieldSettings) + + return new FieldSettingsDto() + } + + async findByFieldId(fieldId: string): Promise { + const fieldSettings = await this.fieldSettingsModel.findOne({ + where: { fieldId: fieldId }, + include: [{ model: ListItem, as: 'list' }], + }) + + if (!fieldSettings) { + throw new NotFoundException( + `fieldSettings for field with id '${fieldId}' not found`, + ) + } + + return fieldSettings + } + + async findOne(fieldId: string, fieldType: string): Promise { + const fieldSettings = await this.findByFieldId(fieldId) + + const fieldSettingsDto = + this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( + fieldSettings, + fieldType, + ) + + return fieldSettingsDto + } + + async update( + id: string, + updateFieldSettings: UpdateFieldSettingsDto, + ): Promise { + const fieldSettings = await this.findByFieldId(id) + + this.fieldSettingsMapper.mapUpdateFieldSettingsDtoToFieldSettings( + fieldSettings, + updateFieldSettings, + ) + + await fieldSettings.save() + } +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts similarity index 63% rename from apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts rename to apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts index 4e673961b890..1b4dde1234c4 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/dto/inputSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { ListItemDto } from '../../../listItems/models/dto/listItem.dto' -export class InputSettingsDto { +export class FieldSettingsDto { @ApiProperty() minValue?: number @@ -63,52 +63,52 @@ export class InputSettingsDto { timeInterval?: string } -export class TextboxInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class TextboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'maxLength' | 'minLength' >) {} -export class NumberboxInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class NumberboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'maxLength' | 'minLength' | 'minValue' | 'maxValue' >) {} -export class MessageInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class MessageFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'hasLink' | 'url' | 'buttonText' >) {} -export class DatePickerInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class DatePickerFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'minDate' | 'maxDate' >) {} -export class DropdownListInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class DropdownListFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'list' | 'listType' >) {} -export class RadioButtonsInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class RadioButtonsFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'list' >) {} -export class IskNumberboxInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class IskNumberboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'minAmount' | 'maxAmount' >) {} -export class PropertyNumberInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class PropertyNumberFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'hasPropertyInput' | 'hasPropertyList' >) {} -export class DocumentInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class DocumentFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'fileTypes' | 'fileMaxSize' | 'maxFiles' >) {} -export class TimeInputInputSettingsDto extends (InputSettingsDto as new () => Pick< - InputSettingsDto, +export class TimeInputFieldSettingsDto extends (FieldSettingsDto as new () => Pick< + FieldSettingsDto, 'timeInterval' >) {} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts similarity index 95% rename from apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts rename to apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts index 8e9e6322e5bd..e04b1d1e9649 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/dto/updateInputSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class UpdateInputSettingsDto { +export class UpdateFieldSettingsDto { @ApiProperty() minValue?: number diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts new file mode 100644 index 000000000000..512478641879 --- /dev/null +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -0,0 +1,117 @@ +import { Injectable } from '@nestjs/common' +import { UpdateFieldSettingsDto } from './dto/updateFieldSettings.dto' +import { FieldSettings } from './fieldSettings.model' +import { + DatePickerFieldSettingsDto, + DocumentFieldSettingsDto, + DropdownListFieldSettingsDto, + FieldSettingsDto, + IskNumberboxFieldSettingsDto, + MessageFieldSettingsDto, + NumberboxFieldSettingsDto, + PropertyNumberFieldSettingsDto, + RadioButtonsFieldSettingsDto, + TextboxFieldSettingsDto, + TimeInputFieldSettingsDto, +} from './dto/fieldSettings.dto' +import { ListItemMapper } from '../../listItems/models/listItem.mapper' + +@Injectable() +export class FieldSettingsMapper { + constructor(private readonly listItemMapper: ListItemMapper) {} + mapUpdateFieldSettingsDtoToFieldSettings( + fieldSettings: FieldSettings, + updateFieldSettingsDto: UpdateFieldSettingsDto, + ): void { + ;(fieldSettings.modified = new Date()), + (fieldSettings.minValue = updateFieldSettingsDto.minValue ?? null), + (fieldSettings.maxValue = updateFieldSettingsDto.maxValue ?? null), + (fieldSettings.minLength = updateFieldSettingsDto.minLength ?? null), + (fieldSettings.maxLength = updateFieldSettingsDto.maxLength ?? null), + (fieldSettings.minDate = updateFieldSettingsDto.minDate ?? null), + (fieldSettings.maxDate = updateFieldSettingsDto.maxDate ?? null), + (fieldSettings.minAmount = updateFieldSettingsDto.minAmount ?? null), + (fieldSettings.maxAmount = updateFieldSettingsDto.maxAmount ?? null), + (fieldSettings.year = updateFieldSettingsDto.year ?? null), + (fieldSettings.hasLink = updateFieldSettingsDto.hasLink ?? null), + (fieldSettings.url = updateFieldSettingsDto.url ?? null), + (fieldSettings.buttonText = updateFieldSettingsDto.buttonText ?? null), + (fieldSettings.hasPropertyInput = + updateFieldSettingsDto.hasPropertyInput ?? null), + (fieldSettings.hasPropertyList = + updateFieldSettingsDto.hasPropertyList ?? null), + (fieldSettings.listType = updateFieldSettingsDto.listType ?? null), + (fieldSettings.fileTypes = updateFieldSettingsDto.fileTypes ?? null), + (fieldSettings.fileMaxSize = updateFieldSettingsDto.fileMaxSize ?? null), + (fieldSettings.maxFiles = updateFieldSettingsDto.maxFiles ?? null), + (fieldSettings.timeInterval = updateFieldSettingsDto.timeInterval ?? null) + } + + mapFieldTypeToFieldSettingsDto( + fieldSettings: FieldSettings | null | undefined, + fieldType: string, + ): FieldSettingsDto { + switch (fieldType) { + case 'textbox': + return { + maxLength: fieldSettings ? fieldSettings.maxLength : null, + minLength: fieldSettings ? fieldSettings.minLength : null, + } as TextboxFieldSettingsDto + case 'numberbox': + return { + maxLength: fieldSettings ? fieldSettings.maxLength : null, + minLength: fieldSettings ? fieldSettings.minLength : null, + maxValue: fieldSettings ? fieldSettings.maxValue : null, + minValue: fieldSettings ? fieldSettings.minValue : null, + } as NumberboxFieldSettingsDto + case 'message': + return { + hasLink: fieldSettings ? fieldSettings.hasLink : null, + url: fieldSettings ? fieldSettings.url : null, + buttonText: fieldSettings ? fieldSettings.buttonText : null, + } as MessageFieldSettingsDto + case 'datePicker': + return { + minDate: fieldSettings ? fieldSettings.minDate : null, + maxDate: fieldSettings ? fieldSettings.maxDate : null, + } as DatePickerFieldSettingsDto + case 'dropdownList': + return { + list: fieldSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) + : '', + listType: fieldSettings?.listType ? fieldSettings.listType : '', + } as DropdownListFieldSettingsDto + case 'radioButtons': + return { + list: fieldSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) + : null, + } as RadioButtonsFieldSettingsDto + case 'iskNumberbox': + return { + minAmount: fieldSettings ? fieldSettings.minAmount : null, + maxAmount: fieldSettings ? fieldSettings.maxAmount : null, + } as IskNumberboxFieldSettingsDto + case 'propertyNumber': + return { + hasPropertyInput: fieldSettings + ? fieldSettings.hasPropertyInput + : null, + hasPropertyList: fieldSettings ? fieldSettings.hasPropertyList : null, + } as PropertyNumberFieldSettingsDto + case 'document': + return { + fileTypes: fieldSettings ? fieldSettings.fileTypes : null, + fileMaxSize: fieldSettings ? fieldSettings.fileMaxSize : null, + maxFiles: fieldSettings ? fieldSettings.maxFiles : null, + } as DocumentFieldSettingsDto + case 'timeInput': + return { + timeInterval: fieldSettings ? fieldSettings.timeInterval : null, + } as TimeInputFieldSettingsDto + default: + return {} + } + } +} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts similarity index 93% rename from apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts rename to apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts index 8b3457eebcdd..20a362043b96 100644 --- a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.model.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts @@ -11,12 +11,12 @@ import { UpdatedAt, } from 'sequelize-typescript' import { TimeIntervals } from '../../../enums/timeIntervals' -import { Input } from '../../inputs/models/input.model' +import { Field } from '../../fields/models/field.model' import { ListTypes } from '../../../enums/listTypes' import { ListItem } from '../../listItems/models/listItem.model' -@Table({ tableName: 'input_settings' }) -export class InputSettings extends Model { +@Table({ tableName: 'field_settings' }) +export class FieldSettings extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -173,11 +173,11 @@ export class InputSettings extends Model { @ApiProperty({ enum: TimeIntervals }) timeInterval?: string | null - @ForeignKey(() => Input) + @ForeignKey(() => Field) @Column({ type: DataType.STRING, allowNull: false, - field: 'input_id', + field: 'field_id', }) - inputId!: string + fieldId!: string } diff --git a/apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts b/apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/fields/fields.controller.ts b/apps/services/form-system/src/app/modules/fields/fields.controller.ts new file mode 100644 index 000000000000..52d9a3011bd8 --- /dev/null +++ b/apps/services/form-system/src/app/modules/fields/fields.controller.ts @@ -0,0 +1,76 @@ +import { + Body, + Controller, + Delete, + Get, + NotFoundException, + Param, + Post, + Put, +} from '@nestjs/common' +import { FieldsService } from './fields.service' +import { Field } from './models/field.model' +import { CreateFieldDto } from './models/dto/createField.dto' +import { Documentation } from '@island.is/nest/swagger' +import { ApiTags } from '@nestjs/swagger' +import { UpdateFieldDto } from './models/dto/updateField.dto' +import { FieldDto } from './models/dto/field.dto' +import { UpdateFieldsDisplayOrderDto } from './models/dto/updateFieldsDisplayOrder.dto' + +@ApiTags('fields') +@Controller('fields') +export class FieldsController { + constructor(private readonly fieldsService: FieldsService) {} + + @Post() + create(@Body() createFieldDto: CreateFieldDto): Promise { + return this.fieldsService.create(createFieldDto) + } + + @Get() + @Documentation({ + description: 'Get all Fields', + response: { status: 200, type: [Field] }, + }) + async findAll(): Promise { + return await this.fieldsService.findAll() + } + + @Get(':id') + @Documentation({ + description: 'Get Field by id', + response: { status: 200, type: FieldDto }, + }) + async findOne(@Param('id') id: string): Promise { + const field = await this.fieldsService.findOne(id) + if (!field) { + throw new NotFoundException(`Field not found`) + } + + return field + } + + @Put(':id') + async update( + @Param('id') id: string, + @Body() updateFieldDto: UpdateFieldDto, + ): Promise { + await this.fieldsService.update(id, updateFieldDto) + } + + @Put() + @Documentation({ + description: 'Update display order of fields', + response: { status: 204 }, + }) + async updateDisplayOrder( + @Body() updateFieldsDisplayOrderDto: UpdateFieldsDisplayOrderDto, + ): Promise { + return this.fieldsService.updateDisplayOrder(updateFieldsDisplayOrderDto) + } + + @Delete(':id') + async delete(@Param('id') id: string): Promise { + return this.fieldsService.delete(id) + } +} diff --git a/apps/services/form-system/src/app/modules/fields/fields.module.ts b/apps/services/form-system/src/app/modules/fields/fields.module.ts new file mode 100644 index 000000000000..7e4e49c5fb9e --- /dev/null +++ b/apps/services/form-system/src/app/modules/fields/fields.module.ts @@ -0,0 +1,24 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { FieldSettingsService } from '../fieldSettings/fieldSettings.service' +import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' +import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' +import { FieldsController } from './fields.controller' +import { FieldsService } from './fields.service' +import { FieldMapper } from './models/field.mapper' +import { Field } from './models/field.model' +import { FieldType } from './models/fieldType.model' +import { ListItemMapper } from '../listItems/models/listItem.mapper' + +@Module({ + imports: [SequelizeModule.forFeature([Field, FieldType, FieldSettings])], + controllers: [FieldsController], + providers: [ + FieldsService, + FieldSettingsService, + FieldMapper, + FieldSettingsMapper, + ListItemMapper, + ], +}) +export class FieldsModule {} diff --git a/apps/services/form-system/src/app/modules/fields/fields.service.spec.ts b/apps/services/form-system/src/app/modules/fields/fields.service.spec.ts new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/apps/services/form-system/src/app/modules/fields/fields.service.ts b/apps/services/form-system/src/app/modules/fields/fields.service.ts new file mode 100644 index 000000000000..974e5ed2b813 --- /dev/null +++ b/apps/services/form-system/src/app/modules/fields/fields.service.ts @@ -0,0 +1,105 @@ +import { Injectable, NotFoundException } from '@nestjs/common' +import { InjectModel } from '@nestjs/sequelize' +import { FieldSettingsService } from '../fieldSettings/fieldSettings.service' +import { CreateFieldDto } from './models/dto/createField.dto' +import { FieldDto } from './models/dto/field.dto' +import { UpdateFieldDto } from './models/dto/updateField.dto' +import { FieldMapper } from './models/field.mapper' +import { Field } from './models/field.model' +import { UpdateFieldsDisplayOrderDto } from './models/dto/updateFieldsDisplayOrder.dto' + +@Injectable() +export class FieldsService { + constructor( + @InjectModel(Field) + private readonly fieldModel: typeof Field, + private readonly fieldSettingsService: FieldSettingsService, + private readonly fieldMapper: FieldMapper, + ) {} + + async findAll(): Promise { + return await this.fieldModel.findAll() + } + + async findOne(id: string): Promise { + const field = await this.findById(id) + const fieldSettingsDto = await this.fieldSettingsService.findOne( + id, + field.fieldType, + ) + + const fieldDto: FieldDto = this.fieldMapper.mapFieldToFieldDto( + field, + fieldSettingsDto, + ) + + return fieldDto + } + + async findById(id: string): Promise { + const field = await this.fieldModel.findByPk(id) + + if (!field) { + throw new NotFoundException(`Field with id '${id}' not found`) + } + + return field + } + + async create(createFieldDto: CreateFieldDto): Promise { + const { screenId } = createFieldDto + + const newField: Field = await this.fieldModel.create({ + screenId: screenId, + } as Field) + + const newFieldSettingsDto = await this.fieldSettingsService.create( + newField.id, + ) + + const fieldDto: FieldDto = this.fieldMapper.mapFieldToFieldDto( + newField, + newFieldSettingsDto, + ) + + return fieldDto + } + + async update(id: string, updateFieldDto: UpdateFieldDto): Promise { + const field = await this.findById(id) + + this.fieldMapper.mapUpdateFieldDtoToField(field, updateFieldDto) + + if (updateFieldDto.fieldSettings) { + await this.fieldSettingsService.update(id, updateFieldDto.fieldSettings) + } + + await field.save() + } + + async updateDisplayOrder( + updateFieldsDisplayOrderDto: UpdateFieldsDisplayOrderDto, + ): Promise { + const { fieldsDisplayOrderDto } = updateFieldsDisplayOrderDto + + for (let i = 0; i < fieldsDisplayOrderDto.length; i++) { + const field = await this.fieldModel.findByPk(fieldsDisplayOrderDto[i].id) + + if (!field) { + throw new NotFoundException( + `Field with id '${fieldsDisplayOrderDto[i].id}' not found`, + ) + } + + await field.update({ + displayOrder: i, + screenId: fieldsDisplayOrderDto[i].screenId, + }) + } + } + + async delete(id: string): Promise { + const field = await this.findById(id) + field?.destroy() + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts similarity index 66% rename from apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts index 4fc4cd346f0e..d90e973614cd 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/applicationInput.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' +import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' -export class ApplicationInput { +export class ApplicationFieldDto { @ApiProperty() id!: string @@ -21,9 +21,9 @@ export class ApplicationInput { @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: InputSettingsDto }) - inputSettings?: InputSettingsDto + @ApiProperty({ type: FieldSettingsDto }) + fieldSettings?: FieldSettingsDto @ApiProperty() - inputType!: string + fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts similarity index 74% rename from apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts index 2fda88eeae32..ebd0e045ee14 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/createInput.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class CreateInputDto { +export class CreateFieldDto { @ApiProperty() screenId!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts similarity index 67% rename from apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts index 6a8d5475ddcc..421c752cb53b 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/input.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' +import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' -export class InputDto { +export class FieldDto { @ApiProperty() id!: string @@ -21,9 +21,9 @@ export class InputDto { @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: InputSettingsDto }) - inputSettings?: InputSettingsDto + @ApiProperty({ type: FieldSettingsDto }) + fieldSettings?: FieldSettingsDto @ApiProperty() - inputType!: string + fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts similarity index 76% rename from apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts index caccd0a0c024..0fa79ca953d0 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/inputDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' -export class InputDisplayOrderDto { +export class FieldDisplayOrderDto { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts similarity index 64% rename from apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts index bb4e3a450369..fbf1132168b3 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/inputType.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { InputSettingsDto } from '../../../inputSettings/models/dto/inputSettings.dto' +import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' -export class InputTypeDto { +export class FieldTypeDto { @ApiProperty() id!: string @@ -18,6 +18,6 @@ export class InputTypeDto { @ApiProperty() isCommon!: boolean - @ApiProperty({ type: InputSettingsDto }) - inputSettings?: InputSettingsDto + @ApiProperty({ type: FieldSettingsDto }) + fieldSettings?: FieldSettingsDto } diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts similarity index 56% rename from apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts rename to apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts index 349087c920ba..92a4b8a82e28 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInput.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { UpdateInputSettingsDto } from '../../../inputSettings/models/dto/updateInputSettings.dto' +import { UpdateFieldSettingsDto } from '../../../fieldSettings/models/dto/updateFieldSettings.dto' -export class UpdateInputDto { +export class UpdateFieldDto { @ApiProperty({ type: LanguageType }) name!: LanguageType @@ -12,9 +12,9 @@ export class UpdateInputDto { @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: UpdateInputSettingsDto }) - inputSettings?: UpdateInputSettingsDto + @ApiProperty({ type: UpdateFieldSettingsDto }) + fieldSettings?: UpdateFieldSettingsDto @ApiProperty() - inputType!: string + fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts new file mode 100644 index 000000000000..46589d192a0a --- /dev/null +++ b/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts @@ -0,0 +1,7 @@ +import { ApiProperty } from '@nestjs/swagger' +import { FieldDisplayOrderDto } from './fieldDisplayOrder.dto' + +export class UpdateFieldsDisplayOrderDto { + @ApiProperty({ type: [FieldDisplayOrderDto] }) + fieldsDisplayOrderDto!: FieldDisplayOrderDto[] +} diff --git a/apps/services/form-system/src/app/modules/fields/models/field.mapper.ts b/apps/services/form-system/src/app/modules/fields/models/field.mapper.ts new file mode 100644 index 000000000000..38c26539a59f --- /dev/null +++ b/apps/services/form-system/src/app/modules/fields/models/field.mapper.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@nestjs/common' +import { FieldSettingsDto } from '../../fieldSettings/models/dto/fieldSettings.dto' +import { FieldDto } from './dto/field.dto' +import { UpdateFieldDto } from './dto/updateField.dto' +import { Field } from './field.model' + +@Injectable() +export class FieldMapper { + mapFieldToFieldDto( + field: Field, + fieldSettingsDto: FieldSettingsDto, + ): FieldDto { + const fieldDto: FieldDto = { + id: field.id, + screenId: field.screenId, + name: field.name, + displayOrder: field.displayOrder, + description: field.description, + isPartOfMultiset: field.isPartOfMultiset, + fieldType: field.fieldType, + fieldSettings: fieldSettingsDto, + } + + return fieldDto + } + + mapUpdateFieldDtoToField(field: Field, updateFieldDto: UpdateFieldDto): void { + field.name = updateFieldDto.name + field.description = updateFieldDto.description + field.isPartOfMultiset = updateFieldDto.isPartOfMultiset + field.fieldType = updateFieldDto.fieldType + field.modified = new Date() + } +} diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts b/apps/services/form-system/src/app/modules/fields/models/field.model.ts similarity index 81% rename from apps/services/form-system/src/app/modules/inputs/models/input.model.ts rename to apps/services/form-system/src/app/modules/fields/models/field.model.ts index 8b886d90f2b6..9a52edc9fcf5 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/input.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/field.model.ts @@ -12,11 +12,11 @@ import { } from 'sequelize-typescript' import { Screen } from '../../screens/models/screen.model' import { LanguageType } from '../../../dataTypes/languageType.model' -import { InputType } from './inputType.model' -import { InputSettings } from '../../inputSettings/models/inputSettings.model' +import { FieldType } from './fieldType.model' +import { FieldSettings } from '../../fieldSettings/models/fieldSettings.model' -@Table({ tableName: 'inputs' }) -export class Input extends Model { +@Table({ tableName: 'fields' }) +export class Field extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -82,17 +82,17 @@ export class Input extends Model { }) screenId!: string - @HasOne(() => InputSettings) - @ApiProperty({ type: InputSettings }) - inputSettings?: InputSettings + @HasOne(() => FieldSettings) + @ApiProperty({ type: FieldSettings }) + fieldSettings?: FieldSettings - @ForeignKey(() => InputType) + @ForeignKey(() => FieldType) @Column({ type: DataType.STRING, allowNull: false, defaultValue: 'default', - field: 'input_type', + field: 'field_type', }) @ApiProperty() - inputType!: string + fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts b/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts similarity index 85% rename from apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts rename to apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts index dd809b44d626..bb7fd6c4575d 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/inputType.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts @@ -12,10 +12,10 @@ import { } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' import { Organization } from '../../organizations/models/organization.model' -import { Input } from './input.model' +import { Field } from './field.model' -@Table({ tableName: 'input_types' }) -export class InputType extends Model { +@Table({ tableName: 'field_types' }) +export class FieldType extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -65,12 +65,12 @@ export class InputType extends Model { @ApiProperty() isCommon!: boolean - @HasMany(() => Input) - inputs?: Input[] + @HasMany(() => Field) + fields?: Field[] @BelongsToMany(() => Organization, { - through: 'organization_input_types', - foreignKey: 'input_type_id', + through: 'organization_field_types', + foreignKey: 'field_type_id', otherKey: 'organization_id', }) organizations?: NonAttribute diff --git a/apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts b/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts similarity index 73% rename from apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts rename to apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts index 4c9d693a0635..bfd940e90dde 100644 --- a/apps/services/form-system/src/app/modules/inputs/models/organizationInputType.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts @@ -8,11 +8,11 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Organization } from '../../organizations/models/organization.model' -import { InputType } from './inputType.model' +import { FieldType } from './fieldType.model' import { CreationOptional } from 'sequelize' -@Table({ tableName: 'organization_input_types' }) -export class OrganizationInputType extends Model { +@Table({ tableName: 'organization_field_types' }) +export class OrganizationFieldType extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -35,11 +35,11 @@ export class OrganizationInputType extends Model { }) organizationId!: string - @ForeignKey(() => InputType) + @ForeignKey(() => FieldType) @Column({ type: DataType.STRING, allowNull: false, - field: 'input_type_id', + field: 'field_type_id', }) - inputTypeId!: string + fieldTypeId!: string } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index 45802aea6fa1..9ff9827a9cac 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -2,8 +2,8 @@ import { Module } from '@nestjs/common' import { SequelizeModule } from '@nestjs/sequelize' import { FormApplicant } from '../applicants/models/formApplicant.model' import { Screen } from '../screens/models/screen.model' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' -import { InputType } from '../inputs/models/inputType.model' +import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' +import { FieldType } from '../fields/models/fieldType.model' import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' import { Section } from '../sections/models/section.model' @@ -23,13 +23,13 @@ import { FormMapper } from './models/form.mapper' Section, Screen, Organization, - InputType, + FieldType, TestimonyType, ListType, ListItem, ]), ], controllers: [FormsController], - providers: [FormsService, InputSettingsMapper, ListItemMapper, FormMapper], + providers: [FormsService, FieldSettingsMapper, ListItemMapper, FormMapper], }) export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 7634d5737e93..1a9a725e8190 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -4,13 +4,13 @@ import { SectionTypes } from '../../enums/sectionTypes' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' import { ScreenDto } from '../screens/models/dto/screen.dto' import { Screen } from '../screens/models/screen.model' -import { InputSettingsDto } from '../inputSettings/models/dto/inputSettings.dto' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' -import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { InputDto } from '../inputs/models/dto/input.dto' -import { InputTypeDto } from '../inputs/models/dto/inputType.dto' -import { Input } from '../inputs/models/input.model' -import { InputType } from '../inputs/models/inputType.model' +import { FieldSettingsDto } from '../fieldSettings/models/dto/fieldSettings.dto' +import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' +import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' +import { FieldDto } from '../fields/models/dto/field.dto' +import { FieldTypeDto } from '../fields/models/dto/fieldType.dto' +import { Field } from '../fields/models/field.model' +import { FieldType } from '../fields/models/fieldType.model' import { ListTypeDto } from '../lists/models/dto/listType.dto' import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' @@ -38,11 +38,11 @@ export class FormsService { private readonly screenModel: typeof Screen, @InjectModel(Organization) private readonly organizationModel: typeof Organization, - @InjectModel(InputType) - private readonly inputTypeModel: typeof InputType, + @InjectModel(FieldType) + private readonly fieldTypeModel: typeof FieldType, @InjectModel(ListType) private readonly listTypeModel: typeof ListType, - private readonly inputSettingsMapper: InputSettingsMapper, + private readonly fieldSettingsMapper: FieldSettingsMapper, private readonly formMapper: FormMapper, ) {} @@ -112,12 +112,12 @@ export class FormsService { as: 'screens', include: [ { - model: Input, - as: 'inputs', + model: Field, + as: 'fields', include: [ { - model: InputSettings, - as: 'inputSettings', + model: FieldSettings, + as: 'fieldSettings', include: [ { model: ListItem, @@ -144,7 +144,7 @@ export class FormsService { private async buildFormResponse(form: Form): Promise { const response: FormResponse = { form: this.setArrays(form), - inputTypes: await this.getInputTypes(form.organizationId), + fieldTypes: await this.getFieldTypes(form.organizationId), testimonyTypes: await this.getTestimonyTypes(form.organizationId), listTypes: await this.getListTypes(form.organizationId), } @@ -177,36 +177,35 @@ export class FormsService { return testimonyTypesDto } - private async getInputTypes(organizationId: string): Promise { - const commonInputTypes = await this.inputTypeModel.findAll({ + private async getFieldTypes(organizationId: string): Promise { + const commonFieldTypes = await this.fieldTypeModel.findAll({ where: { isCommon: true }, }) - const organizationSpecificInputTypes = + const organizationSpecificFieldTypes = await this.organizationModel.findByPk(organizationId, { - include: [InputType], + include: [FieldType], }) - const organizationInputTypes = commonInputTypes.concat( - organizationSpecificInputTypes?.organizationInputTypes as InputType[], + const organizationFieldTypes = commonFieldTypes.concat( + organizationSpecificFieldTypes?.organizationFieldTypes as FieldType[], ) - const inputTypesDto: InputTypeDto[] = [] - organizationInputTypes.map((inputType) => { - inputTypesDto.push({ - id: inputType.id, - type: inputType.type, - name: inputType.name, - description: inputType.description, - isCommon: inputType.isCommon, - inputSettings: this.inputSettingsMapper.mapInputTypeToInputSettingsDto( + const fieldTypesDto: FieldTypeDto[] = [] + organizationFieldTypes.map((fieldType) => { + fieldTypesDto.push({ + id: fieldType.id, + type: fieldType.type, + name: fieldType.name, + description: fieldType.description, + isCommon: fieldType.isCommon, + fieldSettings: this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( null, - inputType.type, + fieldType.type, ), - } as InputTypeDto) + } as FieldTypeDto) }) - console.log('blalala:', InputSettingsDto) - return inputTypesDto + return fieldTypesDto } private async getListTypes(organizationId: string): Promise { @@ -254,7 +253,7 @@ export class FormsService { applicants: [], sections: [], screens: [], - inputs: [], + fields: [], } form.testimonyTypes?.map((testimonyType) => { @@ -298,24 +297,24 @@ export class FormsService { isHidden: screen.isHidden, multiset: screen.multiset, } as ScreenDto) - screen.inputs?.map((input) => { - formDto.inputs?.push({ - id: input.id, + screen.fields?.map((field) => { + formDto.fields?.push({ + id: field.id, screenId: screen.id, - name: input.name, - created: input.created, - modified: input.modified, - displayOrder: input.displayOrder, - description: input.description, - isHidden: input.isHidden, - isPartOfMultiset: input.isPartOfMultiset, - inputSettings: - this.inputSettingsMapper.mapInputTypeToInputSettingsDto( - input.inputSettings, - input.inputType, + name: field.name, + created: field.created, + modified: field.modified, + displayOrder: field.displayOrder, + description: field.description, + isHidden: field.isHidden, + isPartOfMultiset: field.isPartOfMultiset, + fieldSettings: + this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( + field.fieldSettings, + field.fieldType, ), - inputType: input.inputType, - } as InputDto) + fieldType: field.fieldType, + } as FieldDto) }) }) }) @@ -342,7 +341,7 @@ export class FormsService { formId: form.id, sectionType: SectionTypes.INPUT, displayOrder: 2, - name: { is: 'Innsláttarskjár', en: 'InputScreen' }, + name: { is: 'Kafli', en: 'Section' }, } as Section) await this.sectionModel.create({ @@ -355,7 +354,7 @@ export class FormsService { await this.screenModel.create({ sectionId: inputSection.id, displayOrder: 0, - name: { is: 'Skjár 1', en: 'Screen 1' }, + name: { is: 'innsláttarsíða 1', en: 'Input screen 1' }, } as Screen) } } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 6ac943c9c883..5b4a53184e7e 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' import { ScreenDto } from '../../../screens/models/dto/screen.dto' -import { InputDto } from '../../../inputs/models/dto/input.dto' +import { FieldDto } from '../../../fields/models/dto/field.dto' import { SectionDto } from '../../../sections/models/dto/section.dto' import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' import { String } from 'aws-sdk/clients/apigateway' @@ -56,6 +56,6 @@ export class FormDto { @ApiProperty({ type: [ScreenDto] }) screens?: ScreenDto[] - @ApiProperty({ type: [InputDto] }) - inputs?: InputDto[] + @ApiProperty({ type: [FieldDto] }) + fields?: FieldDto[] } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts index 93ca4725d5a7..bf47cd9d911c 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger' -import { InputTypeDto } from '../../../inputs/models/dto/inputType.dto' +import { FieldTypeDto } from '../../../fields/models/dto/fieldType.dto' import { ListTypeDto } from '../../../lists/models/dto/listType.dto' import { TestimonyTypeDto } from '../../../testimonies/models/dto/testimonyType.dto' import { FormDto } from './form.dto' @@ -8,8 +8,8 @@ export class FormResponse { @ApiProperty({ type: FormDto }) form!: FormDto - @ApiProperty({ type: [InputTypeDto] }) - inputTypes!: InputTypeDto[] + @ApiProperty({ type: [FieldTypeDto] }) + fieldTypes!: FieldTypeDto[] @ApiProperty({ type: [TestimonyTypeDto] }) testimonyTypes!: TestimonyTypeDto[] diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts deleted file mode 100644 index 55ef0e7f9e0c..000000000000 --- a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from '@nestjs/common' -import { SequelizeModule } from '@nestjs/sequelize' -import { InputSettings } from './models/inputSettings.model' -import { InputSettingsService } from './inputSettings.service' -import { InputSettingsMapper } from './models/inputSettings.mapper' -import { ListItemMapper } from '../listItems/models/listItem.mapper' -import { ListItem } from '../listItems/models/listItem.model' - -@Module({ - imports: [SequelizeModule.forFeature([InputSettings, ListItem])], - providers: [InputSettingsService, InputSettingsMapper, ListItemMapper], - exports: [InputSettingsService], -}) -export class InputSettingsModule {} diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts deleted file mode 100644 index 63228222daa1..000000000000 --- a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' -import { InputSettingsService } from './inputSettings.service' - -describe('InputSettingsService', () => { - let service: InputSettingsService - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [InputSettingsService], - }).compile() - - service = module.get(InputSettingsService) - }) - - it('should be defined', () => { - expect(service).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts b/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts deleted file mode 100644 index 8ae1ecbbee63..000000000000 --- a/apps/services/form-system/src/app/modules/inputSettings/inputSettings.service.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Injectable, NotFoundException } from '@nestjs/common' -import { InputSettings } from './models/inputSettings.model' -import { UpdateInputSettingsDto } from './models/dto/updateInputSettings.dto' -import { InjectModel } from '@nestjs/sequelize' -import { InputSettingsMapper } from './models/inputSettings.mapper' -import { InputSettingsDto } from './models/dto/inputSettings.dto' -import { ListItem } from '../listItems/models/listItem.model' - -@Injectable() -export class InputSettingsService { - constructor( - @InjectModel(InputSettings) - private readonly inputSettingsModel: typeof InputSettings, - private readonly inputSettingsMapper: InputSettingsMapper, - ) {} - - async create(inputId: string): Promise { - await this.inputSettingsModel.create({ - inputId: inputId, - } as InputSettings) - - return new InputSettingsDto() - } - - async findByInputId(inputId: string): Promise { - const inputSettings = await this.inputSettingsModel.findOne({ - where: { inputId: inputId }, - include: [{ model: ListItem, as: 'list' }], - }) - - if (!inputSettings) { - throw new NotFoundException( - `inputSettings for input with id '${inputId}' not found`, - ) - } - - return inputSettings - } - - async findOne(inputId: string, inputType: string): Promise { - const inputSettings = await this.findByInputId(inputId) - - const inputSettingsDto = - this.inputSettingsMapper.mapInputTypeToInputSettingsDto( - inputSettings, - inputType, - ) - - return inputSettingsDto - } - - async update( - id: string, - updateInputSettings: UpdateInputSettingsDto, - ): Promise { - const inputSettings = await this.findByInputId(id) - - this.inputSettingsMapper.mapUpdateInputSettingsDtoToInputSettings( - inputSettings, - updateInputSettings, - ) - - await inputSettings.save() - } -} diff --git a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts b/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts deleted file mode 100644 index e298dfa35f57..000000000000 --- a/apps/services/form-system/src/app/modules/inputSettings/models/inputSettings.mapper.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { Injectable } from '@nestjs/common' -import { UpdateInputSettingsDto } from './dto/updateInputSettings.dto' -import { InputSettings } from './inputSettings.model' -import { - DatePickerInputSettingsDto, - DocumentInputSettingsDto, - DropdownListInputSettingsDto, - InputSettingsDto, - IskNumberboxInputSettingsDto, - MessageInputSettingsDto, - NumberboxInputSettingsDto, - PropertyNumberInputSettingsDto, - RadioButtonsInputSettingsDto, - TextboxInputSettingsDto, - TimeInputInputSettingsDto, -} from './dto/inputSettings.dto' -import { ListItemMapper } from '../../listItems/models/listItem.mapper' - -@Injectable() -export class InputSettingsMapper { - constructor(private readonly listItemMapper: ListItemMapper) {} - mapUpdateInputSettingsDtoToInputSettings( - inputSettings: InputSettings, - updateInputSettingsDto: UpdateInputSettingsDto, - ): void { - ;(inputSettings.modified = new Date()), - (inputSettings.minValue = updateInputSettingsDto.minValue ?? null), - (inputSettings.maxValue = updateInputSettingsDto.maxValue ?? null), - (inputSettings.minLength = updateInputSettingsDto.minLength ?? null), - (inputSettings.maxLength = updateInputSettingsDto.maxLength ?? null), - (inputSettings.minDate = updateInputSettingsDto.minDate ?? null), - (inputSettings.maxDate = updateInputSettingsDto.maxDate ?? null), - (inputSettings.minAmount = updateInputSettingsDto.minAmount ?? null), - (inputSettings.maxAmount = updateInputSettingsDto.maxAmount ?? null), - (inputSettings.year = updateInputSettingsDto.year ?? null), - (inputSettings.hasLink = updateInputSettingsDto.hasLink ?? null), - (inputSettings.url = updateInputSettingsDto.url ?? null), - (inputSettings.buttonText = updateInputSettingsDto.buttonText ?? null), - (inputSettings.hasPropertyInput = - updateInputSettingsDto.hasPropertyInput ?? null), - (inputSettings.hasPropertyList = - updateInputSettingsDto.hasPropertyList ?? null), - (inputSettings.listType = updateInputSettingsDto.listType ?? null), - (inputSettings.fileTypes = updateInputSettingsDto.fileTypes ?? null), - (inputSettings.fileMaxSize = updateInputSettingsDto.fileMaxSize ?? null), - (inputSettings.maxFiles = updateInputSettingsDto.maxFiles ?? null), - (inputSettings.timeInterval = updateInputSettingsDto.timeInterval ?? null) - } - - mapInputTypeToInputSettingsDto( - inputSettings: InputSettings | null | undefined, - inputType: string, - ): InputSettingsDto { - switch (inputType) { - case 'textbox': - return { - maxLength: inputSettings ? inputSettings.maxLength : null, - minLength: inputSettings ? inputSettings.minLength : null, - } as TextboxInputSettingsDto - case 'numberbox': - return { - maxLength: inputSettings ? inputSettings.maxLength : null, - minLength: inputSettings ? inputSettings.minLength : null, - maxValue: inputSettings ? inputSettings.maxValue : null, - minValue: inputSettings ? inputSettings.minValue : null, - } as NumberboxInputSettingsDto - case 'message': - return { - hasLink: inputSettings ? inputSettings.hasLink : null, - url: inputSettings ? inputSettings.url : null, - buttonText: inputSettings ? inputSettings.buttonText : null, - } as MessageInputSettingsDto - case 'datePicker': - return { - minDate: inputSettings ? inputSettings.minDate : null, - maxDate: inputSettings ? inputSettings.maxDate : null, - } as DatePickerInputSettingsDto - case 'dropdownList': - return { - list: inputSettings?.list - ? this.listItemMapper.mapListItemsToListItemsDto(inputSettings.list) - : '', - listType: inputSettings?.listType ? inputSettings.listType : '', - } as DropdownListInputSettingsDto - case 'radioButtons': - return { - list: inputSettings?.list - ? this.listItemMapper.mapListItemsToListItemsDto(inputSettings.list) - : null, - } as RadioButtonsInputSettingsDto - case 'iskNumberbox': - return { - minAmount: inputSettings ? inputSettings.minAmount : null, - maxAmount: inputSettings ? inputSettings.maxAmount : null, - } as IskNumberboxInputSettingsDto - case 'propertyNumber': - return { - hasPropertyInput: inputSettings - ? inputSettings.hasPropertyInput - : null, - hasPropertyList: inputSettings ? inputSettings.hasPropertyList : null, - } as PropertyNumberInputSettingsDto - case 'document': - return { - fileTypes: inputSettings ? inputSettings.fileTypes : null, - fileMaxSize: inputSettings ? inputSettings.fileMaxSize : null, - maxFiles: inputSettings ? inputSettings.maxFiles : null, - } as DocumentInputSettingsDto - case 'timeInput': - return { - timeInterval: inputSettings ? inputSettings.timeInterval : null, - } as TimeInputInputSettingsDto - default: - return {} - } - } -} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts deleted file mode 100644 index 06d5a5362686..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/inputs.controller.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' -import { InputsController } from './inputs.controller' - -describe('InputsController', () => { - let controller: InputsController - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [InputsController], - }).compile() - - controller = module.get(InputsController) - }) - - it('should be defined', () => { - expect(controller).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts b/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts deleted file mode 100644 index bbe08321a5dd..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/inputs.controller.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { - Body, - Controller, - Delete, - Get, - NotFoundException, - Param, - Post, - Put, -} from '@nestjs/common' -import { InputsService } from './inputs.service' -import { Input } from './models/input.model' -import { CreateInputDto } from './models/dto/createInput.dto' -import { Documentation } from '@island.is/nest/swagger' -import { ApiTags } from '@nestjs/swagger' -import { UpdateInputDto } from './models/dto/updateInput.dto' -import { InputDto } from './models/dto/input.dto' -import { UpdateInputsDisplayOrderDto } from './models/dto/updateInputsDisplayOrder.dto' - -@ApiTags('inputs') -@Controller('inputs') -export class InputsController { - constructor(private readonly inputsService: InputsService) {} - - @Post() - create(@Body() createInputDto: CreateInputDto): Promise { - return this.inputsService.create(createInputDto) - } - - @Get() - @Documentation({ - description: 'Get all Inputs', - response: { status: 200, type: [Input] }, - }) - async findAll(): Promise { - return await this.inputsService.findAll() - } - - @Get(':id') - @Documentation({ - description: 'Get Input by id', - response: { status: 200, type: InputDto }, - }) - async findOne(@Param('id') id: string): Promise { - const input = await this.inputsService.findOne(id) - if (!input) { - throw new NotFoundException(`Input not found`) - } - - return input - } - - @Put(':id') - async update( - @Param('id') id: string, - @Body() updateInputDto: UpdateInputDto, - ): Promise { - await this.inputsService.update(id, updateInputDto) - } - - @Put() - @Documentation({ - description: 'Update display order of inputs', - response: { status: 204 }, - }) - async updateDisplayOrder( - @Body() updateInputsDisplayOrderDto: UpdateInputsDisplayOrderDto, - ): Promise { - return this.inputsService.updateDisplayOrder(updateInputsDisplayOrderDto) - } - - @Delete(':id') - async delete(@Param('id') id: string): Promise { - return this.inputsService.delete(id) - } -} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts b/apps/services/form-system/src/app/modules/inputs/inputs.module.ts deleted file mode 100644 index 40778a1243a0..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/inputs.module.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Module } from '@nestjs/common' -import { SequelizeModule } from '@nestjs/sequelize' -import { InputSettingsService } from '../inputSettings/inputSettings.service' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' -import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { InputsController } from './inputs.controller' -import { InputsService } from './inputs.service' -import { InputMapper } from './models/input.mapper' -import { Input } from './models/input.model' -import { InputType } from './models/inputType.model' -import { ListItemMapper } from '../listItems/models/listItem.mapper' - -@Module({ - imports: [SequelizeModule.forFeature([Input, InputType, InputSettings])], - controllers: [InputsController], - providers: [ - InputsService, - InputSettingsService, - InputMapper, - InputSettingsMapper, - ListItemMapper, - ], -}) -export class InputsModule {} diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts deleted file mode 100644 index 3a5adb4ff960..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Test, TestingModule } from '@nestjs/testing' -import { InputsService } from './inputs.service' - -describe('InputsService', () => { - let service: InputsService - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [InputsService], - }).compile() - - service = module.get(InputsService) - }) - - it('should be defined', () => { - expect(service).toBeDefined() - }) -}) diff --git a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts b/apps/services/form-system/src/app/modules/inputs/inputs.service.ts deleted file mode 100644 index e344692f71b3..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/inputs.service.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { Injectable, NotFoundException } from '@nestjs/common' -import { InjectModel } from '@nestjs/sequelize' -import { InputSettingsService } from '../inputSettings/inputSettings.service' -import { CreateInputDto } from './models/dto/createInput.dto' -import { InputDto } from './models/dto/input.dto' -import { UpdateInputDto } from './models/dto/updateInput.dto' -import { InputMapper } from './models/input.mapper' -import { Input } from './models/input.model' -import { UpdateInputsDisplayOrderDto } from './models/dto/updateInputsDisplayOrder.dto' - -@Injectable() -export class InputsService { - constructor( - @InjectModel(Input) - private readonly inputModel: typeof Input, - private readonly inputSettingsService: InputSettingsService, - private readonly inputMapper: InputMapper, - ) {} - - async findAll(): Promise { - return await this.inputModel.findAll() - } - - async findOne(id: string): Promise { - const input = await this.findById(id) - const inputSettingsDto = await this.inputSettingsService.findOne( - id, - input.inputType, - ) - - const inputDto: InputDto = this.inputMapper.mapInputToInputDto( - input, - inputSettingsDto, - ) - - return inputDto - } - - async findById(id: string): Promise { - const input = await this.inputModel.findByPk(id) - - if (!input) { - throw new NotFoundException(`Input with id '${id}' not found`) - } - - return input - } - - async create(createInputDto: CreateInputDto): Promise { - const { screenId } = createInputDto - - const newInput: Input = await this.inputModel.create({ - screenId: screenId, - } as Input) - - const newInputSettingsDto = await this.inputSettingsService.create( - newInput.id, - ) - - const inputDto: InputDto = this.inputMapper.mapInputToInputDto( - newInput, - newInputSettingsDto, - ) - - return inputDto - } - - async update(id: string, updateInputDto: UpdateInputDto): Promise { - const input = await this.findById(id) - - this.inputMapper.mapUpdateInputDtoToInput(input, updateInputDto) - - if (updateInputDto.inputSettings) { - await this.inputSettingsService.update(id, updateInputDto.inputSettings) - } - - await input.save() - } - - async updateDisplayOrder( - updateInputsDisplayOrderDto: UpdateInputsDisplayOrderDto, - ): Promise { - const { inputsDisplayOrderDto } = updateInputsDisplayOrderDto - - for (let i = 0; i < inputsDisplayOrderDto.length; i++) { - const input = await this.inputModel.findByPk(inputsDisplayOrderDto[i].id) - - if (!input) { - throw new NotFoundException( - `Input with id '${inputsDisplayOrderDto[i].id}' not found`, - ) - } - - await input.update({ - displayOrder: i, - screenId: inputsDisplayOrderDto[i].screenId, - }) - } - } - - async delete(id: string): Promise { - const input = await this.findById(id) - input?.destroy() - } -} diff --git a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts deleted file mode 100644 index 5f641c5d9c79..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/models/dto/updateInputsDisplayOrder.dto.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { ApiProperty } from '@nestjs/swagger' -import { InputDisplayOrderDto } from './inputDisplayOrder.dto' - -export class UpdateInputsDisplayOrderDto { - @ApiProperty({ type: [InputDisplayOrderDto] }) - inputsDisplayOrderDto!: InputDisplayOrderDto[] -} diff --git a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts b/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts deleted file mode 100644 index 228782bf5407..000000000000 --- a/apps/services/form-system/src/app/modules/inputs/models/input.mapper.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Injectable } from '@nestjs/common' -import { InputSettingsDto } from '../../inputSettings/models/dto/inputSettings.dto' -import { InputDto } from './dto/input.dto' -import { UpdateInputDto } from './dto/updateInput.dto' -import { Input } from './input.model' - -@Injectable() -export class InputMapper { - mapInputToInputDto( - input: Input, - inputSettingsDto: InputSettingsDto, - ): InputDto { - const inputDto: InputDto = { - id: input.id, - screenId: input.screenId, - name: input.name, - displayOrder: input.displayOrder, - description: input.description, - isPartOfMultiset: input.isPartOfMultiset, - inputType: input.inputType, - inputSettings: inputSettingsDto, - } - - return inputDto - } - - mapUpdateInputDtoToInput(input: Input, updateInputDto: UpdateInputDto): void { - input.name = updateInputDto.name - input.description = updateInputDto.description - input.isPartOfMultiset = updateInputDto.isPartOfMultiset - input.inputType = updateInputDto.inputType - input.modified = new Date() - } -} diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.module.ts b/apps/services/form-system/src/app/modules/listItems/listItems.module.ts index 758382087457..fc7a8c7c3971 100644 --- a/apps/services/form-system/src/app/modules/listItems/listItems.module.ts +++ b/apps/services/form-system/src/app/modules/listItems/listItems.module.ts @@ -2,19 +2,19 @@ import { SequelizeModule } from '@nestjs/sequelize' import { ListItem } from './models/listItem.model' import { ListItemsService } from './listItems.service' import { Module } from '@nestjs/common' -import { InputSettingsService } from '../inputSettings/inputSettings.service' -import { InputSettings } from '../inputSettings/models/inputSettings.model' -import { InputSettingsMapper } from '../inputSettings/models/inputSettings.mapper' +import { FieldSettingsService } from '../fieldSettings/fieldSettings.service' +import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' +import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' import { ListItemsController } from './listItems.controller' import { ListItemMapper } from './models/listItem.mapper' @Module({ - imports: [SequelizeModule.forFeature([ListItem, InputSettings])], + imports: [SequelizeModule.forFeature([ListItem, FieldSettings])], controllers: [ListItemsController], providers: [ ListItemsService, - InputSettingsService, - InputSettingsMapper, + FieldSettingsService, + FieldSettingsMapper, ListItemMapper, ], exports: [ListItemsService, ListItemMapper], diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.service.ts b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts index 271c748e38ee..c3e0a60a7aa9 100644 --- a/apps/services/form-system/src/app/modules/listItems/listItems.service.ts +++ b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts @@ -3,7 +3,7 @@ import { InjectModel } from '@nestjs/sequelize' import { ListItem } from './models/listItem.model' import { ListItemDto } from './models/dto/listItem.dto' import { CreateListItemDto } from './models/dto/createListItem.dto' -import { InputSettingsService } from '../inputSettings/inputSettings.service' +import { FieldSettingsService } from '../fieldSettings/fieldSettings.service' import { ListItemMapper } from './models/listItem.mapper' import { UpdateListItemDto } from './models/dto/updateListItem.dto' import { UpdateListItemsDisplayOrderDto } from './models/dto/updateListItemsDisplayOrder.dto' @@ -13,7 +13,7 @@ export class ListItemsService { constructor( @InjectModel(ListItem) private readonly listItemModel: typeof ListItem, - private readonly inputSettingsService: InputSettingsService, + private readonly inputSettingsService: FieldSettingsService, private listItemMapper: ListItemMapper, ) {} @@ -28,12 +28,12 @@ export class ListItemsService { } async create(createListItem: CreateListItemDto): Promise { - const inputSettings = await this.inputSettingsService.findByInputId( - createListItem.inputId, + const inputSettings = await this.inputSettingsService.findByFieldId( + createListItem.fieldId, ) const listItem = await this.listItemModel.create({ - inputSettingsId: inputSettings.id, + fieldSettingsId: inputSettings.id, displayOrder: createListItem.displayOrder, } as ListItem) diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts index be42d0438b4e..3e1377897651 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger' export class CreateListItemDto { @ApiProperty() - inputId!: string + fieldId!: string @ApiProperty() displayOrder!: number diff --git a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts index 8c147fcc7225..13fea01c45c1 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts @@ -10,7 +10,7 @@ import { } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' import { CreationOptional } from 'sequelize' -import { InputSettings } from '../../inputSettings/models/inputSettings.model' +import { FieldSettings } from '../../fieldSettings/models/fieldSettings.model' @Table({ tableName: 'list_items' }) export class ListItem extends Model { @@ -70,11 +70,11 @@ export class ListItem extends Model { @ApiProperty() isSelected!: boolean - @ForeignKey(() => InputSettings) + @ForeignKey(() => FieldSettings) @Column({ type: DataType.STRING, allowNull: false, - field: 'input_settings_id', + field: 'field_settings_id', }) - inputSettingsId!: string + fieldSettingsId!: string } diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index c9e03af8f56b..99f8b08eca16 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -13,7 +13,7 @@ import { import { LanguageType } from '../../../dataTypes/languageType.model' import { ApplicantTypeNameSuggestion } from '../../applicants/models/applicantTypeNameSuggestion.model' import { Form } from '../../forms/models/form.model' -import { InputType } from '../../inputs/models/inputType.model' +import { FieldType } from '../../fields/models/fieldType.model' import { ListType } from '../../lists/models/listType.model' import { TestimonyType } from '../../testimonies/models/testimonyType.model' @@ -60,12 +60,12 @@ export class Organization extends Model { @ApiProperty({ type: [ApplicantTypeNameSuggestion] }) applicantTypeNameSuggestions?: ApplicantTypeNameSuggestion[] - @BelongsToMany(() => InputType, { - through: 'organization_input_types', + @BelongsToMany(() => FieldType, { + through: 'organization_field_types', foreignKey: 'organization_id', - otherKey: 'input_type_id', + otherKey: 'field_type_id', }) - organizationInputTypes?: NonAttribute + organizationFieldTypes?: NonAttribute @BelongsToMany(() => TestimonyType, { through: 'organization_testimony_types', diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts index c47c667c9802..b69a0a26bb3b 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { ApplicationInput } from '../../../inputs/models/dto/applicationInput.dto' +import { ApplicationFieldDto } from '../../../fields/models/dto/applicationField.dto' export class ApplicationScreen { @ApiProperty() @@ -18,6 +18,6 @@ export class ApplicationScreen { @ApiProperty() multiset!: number - @ApiProperty({ type: [ApplicationInput] }) - inputs!: ApplicationInput[] + @ApiProperty({ type: [ApplicationFieldDto] }) + fields!: ApplicationFieldDto[] } diff --git a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts index c4850603d0da..6b226897b3d2 100644 --- a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts +++ b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts @@ -11,7 +11,7 @@ import { } from 'sequelize-typescript' import { Section } from '../../sections/models/section.model' import { CreationOptional } from 'sequelize' -import { Input } from '../../inputs/models/input.model' +import { Field } from '../../fields/models/field.model' import { LanguageType } from '../../../dataTypes/languageType.model' @Table({ tableName: 'screens' }) @@ -65,9 +65,9 @@ export class Screen extends Model { @ApiProperty() multiset!: number - @HasMany(() => Input) - @ApiProperty({ type: [Input] }) - inputs?: Input[] + @HasMany(() => Field) + @ApiProperty({ type: [Field] }) + fields?: Field[] @ForeignKey(() => Section) @Column({ diff --git a/apps/services/form-system/src/app/modules/screens/screens.service.ts b/apps/services/form-system/src/app/modules/screens/screens.service.ts index 531aa55b6eda..13dc0de2ba46 100644 --- a/apps/services/form-system/src/app/modules/screens/screens.service.ts +++ b/apps/services/form-system/src/app/modules/screens/screens.service.ts @@ -1,7 +1,7 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { Screen } from './models/screen.model' import { InjectModel } from '@nestjs/sequelize' -import { Input } from '../inputs/models/input.model' +import { Field } from '../fields/models/field.model' import { CreateScreenDto } from './models/dto/createScreen.dto' import { UpdateScreenDto } from './models/dto/updateScreen.dto' import { ScreenDto } from './models/dto/screen.dto' @@ -19,7 +19,7 @@ export class ScreensService { } async findOne(id: string): Promise { - const screen = await this.screenModel.findByPk(id, { include: [Input] }) + const screen = await this.screenModel.findByPk(id, { include: [Field] }) if (!screen) { throw new NotFoundException(`Screen with id '${id}' not found`) diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.ts b/apps/services/form-system/src/app/modules/sections/sections.service.ts index ee9e82df1e6d..4fd199fbbe67 100644 --- a/apps/services/form-system/src/app/modules/sections/sections.service.ts +++ b/apps/services/form-system/src/app/modules/sections/sections.service.ts @@ -3,7 +3,7 @@ import { InjectModel } from '@nestjs/sequelize' import { Section } from './models/section.model' import { CreateSectionDto } from './models/dto/createSection.dto' import { Screen } from '../screens/models/screen.model' -import { Input } from '../inputs/models/input.model' +import { Field } from '../fields/models/field.model' import { UpdateSectionDto } from './models/dto/updateSection.dto' import { SectionDto } from './models/dto/section.dto' import { UpdateSectionsDisplayOrderDto } from './models/dto/updateSectionsDisplayOrder.dto' @@ -25,7 +25,7 @@ export class SectionsService { { model: Screen, as: 'screens', - include: [{ model: Input, as: 'inputs' }], + include: [{ model: Field, as: 'fields' }], }, ], }) From 86581eea7fe2db4c6693f5b8cbc88d510a785a44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 28 Jun 2024 11:27:14 +0000 Subject: [PATCH 46/72] fix lint warnings --- .../form-system/src/app/modules/forms/forms.controller.ts | 3 --- .../form-system/src/app/modules/forms/forms.service.ts | 1 - .../form-system/src/app/modules/forms/models/dto/form.dto.ts | 1 - 3 files changed, 5 deletions(-) diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 8eb2aa60b138..8419b38e8218 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -12,9 +12,6 @@ import { ApiTags } from '@nestjs/swagger' import { FormsService } from './forms.service' import { CreateFormDto } from './models/dto/createForm.dto' import { FormResponse } from './models/dto/form.response.dto' -import { Form } from './models/form.model' -import { FormDto } from './models/dto/form.dto' -import { FormsListFormDto } from './models/dto/formsListForm.dto' import { FormsListDto } from './models/dto/formsList.dto' @ApiTags('forms') diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 1a9a725e8190..bca65396ee0b 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -4,7 +4,6 @@ import { SectionTypes } from '../../enums/sectionTypes' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' import { ScreenDto } from '../screens/models/dto/screen.dto' import { Screen } from '../screens/models/screen.model' -import { FieldSettingsDto } from '../fieldSettings/models/dto/fieldSettings.dto' import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' import { FieldDto } from '../fields/models/dto/field.dto' diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 5b4a53184e7e..2977e6419c57 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -5,7 +5,6 @@ import { ScreenDto } from '../../../screens/models/dto/screen.dto' import { FieldDto } from '../../../fields/models/dto/field.dto' import { SectionDto } from '../../../sections/models/dto/section.dto' import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' -import { String } from 'aws-sdk/clients/apigateway' export class FormDto { @ApiProperty() From 1b56c1e988d21c4dde2564f97689d6e3e17073de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 28 Jun 2024 11:28:38 +0000 Subject: [PATCH 47/72] change naming of input to field --- .../src/app/modules/listItems/listItems.service.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.service.ts b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts index c3e0a60a7aa9..da37baa18632 100644 --- a/apps/services/form-system/src/app/modules/listItems/listItems.service.ts +++ b/apps/services/form-system/src/app/modules/listItems/listItems.service.ts @@ -13,7 +13,7 @@ export class ListItemsService { constructor( @InjectModel(ListItem) private readonly listItemModel: typeof ListItem, - private readonly inputSettingsService: FieldSettingsService, + private readonly fieldSettingsService: FieldSettingsService, private listItemMapper: ListItemMapper, ) {} @@ -28,12 +28,12 @@ export class ListItemsService { } async create(createListItem: CreateListItemDto): Promise { - const inputSettings = await this.inputSettingsService.findByFieldId( + const fieldSettings = await this.fieldSettingsService.findByFieldId( createListItem.fieldId, ) const listItem = await this.listItemModel.create({ - fieldSettingsId: inputSettings.id, + fieldSettingsId: fieldSettings.id, displayOrder: createListItem.displayOrder, } as ListItem) From e0dcd221f9bdac2fc171b08e854bf2cd680d739e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 28 Jun 2024 13:25:28 +0000 Subject: [PATCH 48/72] work on application part --- .../migrations/20240605120322-create-form.js | 2 +- .../applications/applications.controller.ts | 15 ++++- .../applications/applications.module.ts | 7 +- .../applications/applications.service.ts | 64 ++++++++++++++++++- .../applications/models/application.mapper.ts | 10 +++ .../app/modules/forms/models/form.model.ts | 4 +- 6 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 apps/services/form-system/src/app/modules/applications/models/application.mapper.ts diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 44761a82754a..52ca45f1173a 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -19,7 +19,7 @@ module.exports = { url_name: { type: Sequelize.STRING, allowNull: false, - defaultValue: '', + unique: true, }, created: { type: 'TIMESTAMP WITH TIME ZONE', diff --git a/apps/services/form-system/src/app/modules/applications/applications.controller.ts b/apps/services/form-system/src/app/modules/applications/applications.controller.ts index ab673ee7d150..e07f48ceacfc 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.controller.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Param } from '@nestjs/common' +import { Controller, Get, Param, Post } from '@nestjs/common' import { ApiTags } from '@nestjs/swagger' import { ApplicationsService } from './applications.service' import { ApplicationDto } from './models/dto/application.dto' @@ -12,9 +12,20 @@ export class ApplicationsController { @Get() @Documentation({ description: 'Get application preview', - response: { status: 200, type: [ApplicationDto] }, + response: { status: 200, type: ApplicationDto }, }) getPreview(@Param('formId') formId: string): ApplicationDto { return this.applicationsService.getPreview(formId) } + + @Documentation({ + description: 'Create new application', + response: { status: 200, type: ApplicationDto }, + }) + @Post(':formUrlName') + async create( + @Param('formUrlName') formUrlName: string, + ): Promise { + return this.applicationsService.create(formUrlName) + } } diff --git a/apps/services/form-system/src/app/modules/applications/applications.module.ts b/apps/services/form-system/src/app/modules/applications/applications.module.ts index 936b3ea0b4be..416bd9450863 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.module.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.module.ts @@ -3,10 +3,13 @@ import { Application } from './models/application.model' import { SequelizeModule } from '@nestjs/sequelize' import { ApplicationsService } from './applications.service' import { ApplicationsController } from './applications.controller' +import { FormsService } from '../forms/forms.service' +import { Form } from '../forms/models/form.model' +import { ApplicationMapper } from './models/application.mapper' @Module({ - imports: [SequelizeModule.forFeature([Application])], + imports: [SequelizeModule.forFeature([Application, Form])], controllers: [ApplicationsController], - providers: [ApplicationsService], + providers: [ApplicationsService, ApplicationMapper], }) export class ApplicationsModule {} diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts index 959b89567f8a..fe8f2d6c1943 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.service.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -1,20 +1,78 @@ -import { Injectable } from '@nestjs/common' +import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' import { Application } from './models/application.model' import { ApplicationDto } from './models/dto/application.dto' +import { Form } from '../forms/models/form.model' +import { FormsService } from '../forms/forms.service' +import { FormDto } from '../forms/models/dto/form.dto' +import { Section } from '../sections/models/section.model' +import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' +import { ListItem } from '../listItems/models/listItem.model' +import { Field } from '../fields/models/field.model' +import { Screen } from '../screens/models/screen.model' +import { ApplicationMapper } from './models/application.mapper' @Injectable() export class ApplicationsService { constructor( @InjectModel(Application) private readonly applicationModel: typeof Application, + @InjectModel(Form) + private readonly formModel: typeof Form, + private readonly applicationMapper: ApplicationMapper, ) {} - create(formId: string): ApplicationDto { - return new ApplicationDto() + async create(formUrlName: string): Promise { + const form: Form = await this.getForm(formUrlName) + + const applicationDto = this.applicationMapper.mapFormToApplicationDto(form) + return applicationDto } getPreview(formId: string): ApplicationDto { return new ApplicationDto() } + + private async getForm(urlName: string): Promise { + console.log('urlName', urlName) + const form = await this.formModel.findOne({ + where: { urlName: urlName }, + include: [ + { + model: Section, + as: 'sections', + include: [ + { + model: Screen, + as: 'screens', + include: [ + { + model: Field, + as: 'fields', + include: [ + { + model: FieldSettings, + as: 'fieldSettings', + include: [ + { + model: ListItem, + as: 'list', + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }) + + if (!form) { + throw new NotFoundException(`Form with urlName '${urlName}' not found`) + } + + return form + } } diff --git a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts new file mode 100644 index 000000000000..6316a6eae6f0 --- /dev/null +++ b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts @@ -0,0 +1,10 @@ +import { Injectable } from '@nestjs/common' +import { Form } from '../../forms/models/form.model' +import { ApplicationDto } from './dto/application.dto' + +@Injectable() +export class ApplicationMapper { + mapFormToApplicationDto(form: Form): ApplicationDto { + return new ApplicationDto() + } +} diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index d58a9846f0fd..a35da4018ff5 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -16,6 +16,7 @@ import { Organization } from '../../organizations/models/organization.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { FormApplicant } from '../../applicants/models/formApplicant.model' import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { randomUUID } from 'crypto' @Table({ tableName: 'forms' }) export class Form extends Model { @@ -39,7 +40,8 @@ export class Form extends Model { @Column({ type: DataType.STRING, allowNull: false, - defaultValue: '', + unique: true, + defaultValue: randomUUID(), }) urlName!: string From e0ec76ffc4cd70af07835186d983ca7a4a755e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 28 Jun 2024 14:41:58 +0000 Subject: [PATCH 49/72] change tablenames to singular --- .../20240605120243-create-organization.js | 4 +- .../migrations/20240605120322-create-form.js | 6 +-- .../20240605120342-create-section.js | 11 ++-- .../20240605122019-create-screen.js | 11 ++-- .../20240607120240-create-form-applicant.js | 6 +-- ...1-create-applicant-type-name-suggestion.js | 6 +-- .../20240607142452-create-field-type.js | 4 +- .../migrations/20240611122625-create-field.js | 8 +-- .../20240612095843-create-field-settings.js | 2 +- ...14092719-create-organization-field-type.js | 8 +-- .../20240614131225-create-testimony-type.js | 4 +- ...2442-create-organization-testimony-type.js | 8 +-- ...240614152811-create-form-testimony-type.js | 8 +-- .../20240614162737-create-list-type.js | 4 +- ...614162758-create-organization-list-type.js | 8 +-- .../20240621165216-create-list-item.js | 4 +- .../20240626093536-create-application.js | 6 +-- .../20240626093807-create-applicant.js | 6 +-- .../seeders/20240611110210-seed-field-type.js | 4 +- .../20240611135450-seed-organization.js | 4 +- ...0614110902-seed-organization-field-type.js | 4 +- .../20240614132148-seed-testimony-type.js | 4 +- ...142713-seed-organization-testimony-type.js | 4 +- .../seeders/20240614162836-seed-list-type.js | 4 +- ...40614162853-seed-organization-list-type.js | 4 +- .../applicants/models/applicant.model.ts | 2 +- .../applicantTypeNameSuggestion.model.ts | 2 +- .../applicants/models/formApplicant.model.ts | 2 +- .../applications/applications.service.ts | 9 +++- .../applications/models/application.mapper.ts | 52 ++++++++++++++++++- .../applications/models/application.model.ts | 2 +- .../models/dto/application.dto.ts | 9 ++-- .../app/modules/fields/models/field.model.ts | 2 +- .../modules/fields/models/fieldType.model.ts | 4 +- .../models/organizationFieldType.model.ts | 2 +- .../src/app/modules/forms/forms.service.ts | 2 +- .../app/modules/forms/models/form.model.ts | 4 +- .../listItems/models/listItem.model.ts | 2 +- .../modules/lists/models/listType.model.ts | 4 +- .../models/organizationListType.model.ts | 2 +- .../models/dto/organization.dto.ts | 11 +++- .../models/organization.model.ts | 8 +-- .../models/dto/applicationScreen.dto.ts | 5 +- .../modules/screens/models/dto/screen.dto.ts | 3 ++ .../screens/models/dto/updateScreen.dto.ts | 3 ++ .../modules/screens/models/screen.model.ts | 10 +++- .../app/modules/screens/screens.service.ts | 2 + .../models/dto/applicationSection.dto.ts | 11 ++-- .../sections/models/dto/section.dto.ts | 3 -- .../sections/models/dto/updateSection.dto.ts | 3 -- .../modules/sections/models/section.model.ts | 10 +--- .../app/modules/sections/sections.service.ts | 2 - .../models/formTestimonyType.model.ts | 2 +- .../models/organizationTestimonyType.model.ts | 2 +- .../testimonies/models/testimonyType.model.ts | 6 +-- 55 files changed, 193 insertions(+), 130 deletions(-) diff --git a/apps/services/form-system/migrations/20240605120243-create-organization.js b/apps/services/form-system/migrations/20240605120243-create-organization.js index d8c521ed7b80..cc9834e4b448 100644 --- a/apps/services/form-system/migrations/20240605120243-create-organization.js +++ b/apps/services/form-system/migrations/20240605120243-create-organization.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organizations', + 'organization', { id: { type: Sequelize.UUID, @@ -38,7 +38,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organizations', { transaction: t }), + queryInterface.dropTable('organization', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 52ca45f1173a..0404c0ded228 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'forms', + 'form', { id: { type: Sequelize.UUID, @@ -62,7 +62,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'organizations', + model: 'organization', key: 'id', }, }, @@ -74,7 +74,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('forms', { transaction: t }), + queryInterface.dropTable('form', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240605120342-create-section.js b/apps/services/form-system/migrations/20240605120342-create-section.js index 10ace092726c..2bed02d30f85 100644 --- a/apps/services/form-system/migrations/20240605120342-create-section.js +++ b/apps/services/form-system/migrations/20240605120342-create-section.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'sections', + 'section', { id: { type: Sequelize.UUID, @@ -49,11 +49,6 @@ module.exports = { allowNull: false, defaultValue: false, }, - call_ruleset: { - type: Sequelize.BOOLEAN, - allowNull: false, - defaultValue: false, - }, is_completed: { type: Sequelize.BOOLEAN, allowNull: false, @@ -64,7 +59,7 @@ module.exports = { onDelete: 'CASCADE', allowNull: false, references: { - model: 'forms', + model: 'form', key: 'id', }, }, @@ -76,7 +71,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('sections', { transaction: t }), + queryInterface.dropTable('section', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240605122019-create-screen.js b/apps/services/form-system/migrations/20240605122019-create-screen.js index 12e8d2065f8d..820a39343150 100644 --- a/apps/services/form-system/migrations/20240605122019-create-screen.js +++ b/apps/services/form-system/migrations/20240605122019-create-screen.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'screens', + 'screen', { id: { type: Sequelize.UUID, @@ -39,12 +39,17 @@ module.exports = { type: Sequelize.INTEGER, allowNull: false, }, + call_ruleset: { + type: Sequelize.BOOLEAN, + allowNull: false, + defaultValue: false, + }, section_id: { type: Sequelize.UUID, onDelete: 'CASCADE', allowNull: false, references: { - model: 'sections', + model: 'section', key: 'id', }, }, @@ -56,7 +61,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('screens', { transaction: t }), + queryInterface.dropTable('screen', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240607120240-create-form-applicant.js b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js index 1845f90795a7..18df4b4e2d73 100644 --- a/apps/services/form-system/migrations/20240607120240-create-form-applicant.js +++ b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'form_applicants', + 'form_applicant', { id: { type: Sequelize.UUID, @@ -42,7 +42,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'forms', + model: 'form', key: 'id', }, }, @@ -54,7 +54,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('form_applicants', { transaction: t }), + queryInterface.dropTable('form_applicant', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js index 3717ddedcf44..6b1209610a87 100644 --- a/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js +++ b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'applicant_type_name_suggestions', + 'applicant_type_name_suggestion', { id: { type: Sequelize.UUID, @@ -42,7 +42,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'organizations', + model: 'organization', key: 'id', }, }, @@ -54,7 +54,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('applicant_type_name_suggestions', { + queryInterface.dropTable('applicant_type_name_suggestion', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240607142452-create-field-type.js b/apps/services/form-system/migrations/20240607142452-create-field-type.js index 4f66a6810259..32c3fbd9c4e0 100644 --- a/apps/services/form-system/migrations/20240607142452-create-field-type.js +++ b/apps/services/form-system/migrations/20240607142452-create-field-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'field_types', + 'field_type', { id: { type: Sequelize.UUID, @@ -48,7 +48,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('field_types', { transaction: t }), + queryInterface.dropTable('field_type', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240611122625-create-field.js b/apps/services/form-system/migrations/20240611122625-create-field.js index 2a5293e4cf15..68fd272320e0 100644 --- a/apps/services/form-system/migrations/20240611122625-create-field.js +++ b/apps/services/form-system/migrations/20240611122625-create-field.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'fields', + 'field', { id: { type: Sequelize.UUID, @@ -49,7 +49,7 @@ module.exports = { onDelete: 'CASCADE', allowNull: false, references: { - model: 'screens', + model: 'screen', key: 'id', }, }, @@ -57,7 +57,7 @@ module.exports = { type: Sequelize.STRING, allowNull: false, references: { - model: 'field_types', + model: 'field_type', key: 'type', }, }, @@ -69,7 +69,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('fields', { transaction: t }), + queryInterface.dropTable('field', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240612095843-create-field-settings.js b/apps/services/form-system/migrations/20240612095843-create-field-settings.js index 51d2d0c9574a..3486afd9449c 100644 --- a/apps/services/form-system/migrations/20240612095843-create-field-settings.js +++ b/apps/services/form-system/migrations/20240612095843-create-field-settings.js @@ -115,7 +115,7 @@ module.exports = { onDelete: 'CASCADE', allowNull: false, references: { - model: 'fields', + model: 'field', key: 'id', }, }, diff --git a/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js b/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js index 4e6692b790e7..0dc6c6e2f2dc 100644 --- a/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js +++ b/apps/services/form-system/migrations/20240614092719-create-organization-field-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organization_field_types', + 'organization_field_type', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'organizations', + model: 'organization', key: 'id', }, }, @@ -34,7 +34,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'field_types', + model: 'field_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organization_field_types', { transaction: t }), + queryInterface.dropTable('organization_field_type', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js index bad99ef62228..1a75d03459c2 100644 --- a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js +++ b/apps/services/form-system/migrations/20240614131225-create-testimony-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'testimony_types', + 'testimony_type', { id: { type: Sequelize.UUID, @@ -49,7 +49,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('testimony_types', { transaction: t }), + queryInterface.dropTable('testimony_type', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js b/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js index 2ee302e54d88..6bfcc9d76461 100644 --- a/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js +++ b/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organization_testimony_types', + 'organization_testimony_type', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'organizations', + model: 'organization', key: 'id', }, }, @@ -34,7 +34,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'testimony_types', + model: 'testimony_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organization_testimony_types', { + queryInterface.dropTable('organization_testimony_type', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js b/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js index 535de0e5e5b5..ddb949ded28e 100644 --- a/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js +++ b/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'form_testimony_types', + 'form_testimony_type', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'forms', + model: 'form', key: 'id', }, }, @@ -34,7 +34,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'testimony_types', + model: 'testimony_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('form_testimony_types', { + queryInterface.dropTable('form_testimony_type', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240614162737-create-list-type.js b/apps/services/form-system/migrations/20240614162737-create-list-type.js index 18bc8e2ea907..d056bc1676fb 100644 --- a/apps/services/form-system/migrations/20240614162737-create-list-type.js +++ b/apps/services/form-system/migrations/20240614162737-create-list-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'list_types', + 'list_type', { id: { type: Sequelize.UUID, @@ -53,7 +53,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('list_types', { transaction: t }), + queryInterface.dropTable('list_type', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js b/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js index 9fb0d79743af..c46f66890193 100644 --- a/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js +++ b/apps/services/form-system/migrations/20240614162758-create-organization-list-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organization_list_types', + 'organization_list_type', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'organizations', + model: 'organization', key: 'id', }, }, @@ -34,7 +34,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'list_types', + model: 'list_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organization_list_types', { + queryInterface.dropTable('organization_list_type', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240621165216-create-list-item.js b/apps/services/form-system/migrations/20240621165216-create-list-item.js index af438922c068..3c1afe93b133 100644 --- a/apps/services/form-system/migrations/20240621165216-create-list-item.js +++ b/apps/services/form-system/migrations/20240621165216-create-list-item.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'list_items', + 'list_item', { id: { type: Sequelize.UUID, @@ -62,7 +62,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('list_items', { transaction: t }), + queryInterface.dropTable('list_item', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240626093536-create-application.js b/apps/services/form-system/migrations/20240626093536-create-application.js index 813b40c5a2a9..c400545c2a22 100644 --- a/apps/services/form-system/migrations/20240626093536-create-application.js +++ b/apps/services/form-system/migrations/20240626093536-create-application.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'applications', + 'application', { id: { type: Sequelize.UUID, @@ -26,7 +26,7 @@ module.exports = { type: Sequelize.UUID, allowNull: false, references: { - model: 'forms', + model: 'form', key: 'id', }, }, @@ -38,7 +38,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('applications', { transaction: t }), + queryInterface.dropTable('application', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240626093807-create-applicant.js b/apps/services/form-system/migrations/20240626093807-create-applicant.js index cfc1192d579e..aa7923bf6b04 100644 --- a/apps/services/form-system/migrations/20240626093807-create-applicant.js +++ b/apps/services/form-system/migrations/20240626093807-create-applicant.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'applicants', + 'applicant', { id: { type: Sequelize.UUID, @@ -70,7 +70,7 @@ module.exports = { onDelete: 'CASCADE', allowNull: false, references: { - model: 'applications', + model: 'application', key: 'id', }, }, @@ -82,7 +82,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('applicants', { transaction: t }), + queryInterface.dropTable('applicant', { transaction: t }), ) }, } diff --git a/apps/services/form-system/seeders/20240611110210-seed-field-type.js b/apps/services/form-system/seeders/20240611110210-seed-field-type.js index 611013768f1e..183d0b906a3d 100644 --- a/apps/services/form-system/seeders/20240611110210-seed-field-type.js +++ b/apps/services/form-system/seeders/20240611110210-seed-field-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('field_types', [ + await queryInterface.bulkInsert('field_type', [ { id: '09206657-9a89-4265-b58e-13b220f805a2', type: 'default', @@ -234,6 +234,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('field_types', null, {}) + await queryInterface.bulkDelete('field_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240611135450-seed-organization.js b/apps/services/form-system/seeders/20240611135450-seed-organization.js index 0c729aa8f8ba..32fa338272a4 100644 --- a/apps/services/form-system/seeders/20240611135450-seed-organization.js +++ b/apps/services/form-system/seeders/20240611135450-seed-organization.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organizations', [ + await queryInterface.bulkInsert('organization', [ { id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', name: '{ "is": "Sandbox Ísland ehf.", "en": "Sandbox Iceland ehf." }', @@ -14,6 +14,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organizations', null, {}) + await queryInterface.bulkDelete('organization', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js b/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js index 3cc720346ea8..cd469b188c93 100644 --- a/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js +++ b/apps/services/form-system/seeders/20240614110902-seed-organization-field-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organization_field_types', [ + await queryInterface.bulkInsert('organization_field_type', [ { id: 'b12e940e-1bd6-4180-a6eb-f620dce4e71c', created: new Date(), @@ -21,6 +21,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organization_field_types', null, {}) + await queryInterface.bulkDelete('organization_field_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js index 2b84e8ca2593..23973c67edf0 100644 --- a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js +++ b/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('testimony_types', [ + await queryInterface.bulkInsert('testimony_type', [ { id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', type: 'estateGuardianshipCertificateStamped', @@ -60,6 +60,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('testimony_types', null, {}) + await queryInterface.bulkDelete('testimony_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js b/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js index 7678fb348481..12df1b02456a 100644 --- a/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js +++ b/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organization_testimony_types', [ + await queryInterface.bulkInsert('organization_testimony_type', [ { id: 'aeac43a3-daf0-4bca-9079-7dffe6121d75', created: new Date(), @@ -49,6 +49,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organization_testimony_types', null, {}) + await queryInterface.bulkDelete('organization_testimony_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614162836-seed-list-type.js b/apps/services/form-system/seeders/20240614162836-seed-list-type.js index 691aaaeadba0..3c816b579ff4 100644 --- a/apps/services/form-system/seeders/20240614162836-seed-list-type.js +++ b/apps/services/form-system/seeders/20240614162836-seed-list-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('list_types', [ + await queryInterface.bulkInsert('list_type', [ { id: '436a7bb6-ce1d-42cd-a759-24774df5acff', type: 'municipalities', @@ -57,6 +57,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('list_types', null, {}) + await queryInterface.bulkDelete('list_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js b/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js index 083c82b35d62..3d71374d3a74 100644 --- a/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js +++ b/apps/services/form-system/seeders/20240614162853-seed-organization-list-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organization_list_types', [ + await queryInterface.bulkInsert('organization_list_type', [ { id: 'b5d773d2-d27f-45eb-ab39-05ede05b15af', created: new Date(), @@ -21,6 +21,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organization_list_types', null, {}) + await queryInterface.bulkDelete('organization_list_type', null, {}) }, } diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts index c0613846f63c..65136f823583 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts @@ -12,7 +12,7 @@ import { import { ApplicantTypes } from '../../../enums/applicantTypes' import { Application } from '../../applications/models/application.model' -@Table({ tableName: 'applicants' }) +@Table({ tableName: 'applicant' }) export class Applicant extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts index e96fd66cae8b..820098a54078 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts @@ -13,7 +13,7 @@ import { Organization } from '../../organizations/models/organization.model' import { CreationOptional } from 'sequelize' import { ApplicantTypes } from '../../../enums/applicantTypes' -@Table({ tableName: 'applicant_type_name_suggestions' }) +@Table({ tableName: 'applicant_type_name_suggestion' }) export class ApplicantTypeNameSuggestion extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts index fe514cba6b24..c327dee0aa17 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/formApplicant.model.ts @@ -13,7 +13,7 @@ import { Form } from '../../forms/models/form.model' import { CreationOptional } from 'sequelize' import { ApplicantTypes } from '../../../enums/applicantTypes' -@Table({ tableName: 'form_applicants' }) +@Table({ tableName: 'form_applicant' }) export class FormApplicant extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts index fe8f2d6c1943..db3aff975109 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.service.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -25,7 +25,14 @@ export class ApplicationsService { async create(formUrlName: string): Promise { const form: Form = await this.getForm(formUrlName) - const applicationDto = this.applicationMapper.mapFormToApplicationDto(form) + const newApplication: Application = await this.applicationModel.create({ + formId: form.id, + } as Application) + + const applicationDto = this.applicationMapper.mapFormToApplicationDto( + form, + newApplication, + ) return applicationDto } diff --git a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts index 6316a6eae6f0..967a62e9e549 100644 --- a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts +++ b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts @@ -1,10 +1,58 @@ import { Injectable } from '@nestjs/common' import { Form } from '../../forms/models/form.model' import { ApplicationDto } from './dto/application.dto' +import { Application } from './application.model' +import { OrganizationDto } from '../../organizations/models/dto/organization.dto' +import { ApplicationSectionDto } from '../../sections/models/dto/applicationSection.dto' +import { ApplicationScreenDto } from '../../screens/models/dto/applicationScreen.dto' +import { ApplicationFieldDto } from '../../fields/models/dto/applicationField.dto' @Injectable() export class ApplicationMapper { - mapFormToApplicationDto(form: Form): ApplicationDto { - return new ApplicationDto() + mapFormToApplicationDto( + form: Form, + application: Application, + ): ApplicationDto { + const applicationDto: ApplicationDto = { + applicationId: application.id, + formId: form.id, + formUrlName: form.urlName, + organization: new OrganizationDto(), + sections: [], + } + + form.sections?.map((section) => { + applicationDto.sections?.push({ + id: section.id, + name: section.name, + sectionType: section.sectionType, + displayOrder: section.displayOrder, + waitingText: section.waitingText, + screens: section.screens?.map((screen) => { + return { + id: screen.id, + sectionId: screen.sectionId, + name: screen.name, + displayOrder: screen.displayOrder, + multiset: screen.multiset, + callRuleset: screen.callRuleset, + fields: screen.fields?.map((field) => { + return { + id: field.id, + screenId: field.screenId, + name: field.name, + displayOrder: field.displayOrder, + description: field.description, + isPartOfMultiset: field.isPartOfMultiset, + fieldType: field.fieldType, + fieldSettings: field.fieldSettings, + } as ApplicationFieldDto + }), + } as ApplicationScreenDto + }), + } as ApplicationSectionDto) + }) + + return applicationDto } } diff --git a/apps/services/form-system/src/app/modules/applications/models/application.model.ts b/apps/services/form-system/src/app/modules/applications/models/application.model.ts index bc2f131a52fd..fad0ba804142 100644 --- a/apps/services/form-system/src/app/modules/applications/models/application.model.ts +++ b/apps/services/form-system/src/app/modules/applications/models/application.model.ts @@ -11,7 +11,7 @@ import { } from 'sequelize-typescript' import { Form } from '../../forms/models/form.model' -@Table({ tableName: 'applications' }) +@Table({ tableName: 'application' }) export class Application extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts index 94cd2fb8ed97..1aa4ba5bed4e 100644 --- a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -1,12 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' -import { ApplicationSection } from '../../../sections/models/dto/applicationSection.dto' +import { ApplicationSectionDto } from '../../../sections/models/dto/applicationSection.dto' +import { OrganizationDto } from '../../../organizations/models/dto/organization.dto' export class ApplicationDto { @ApiProperty() applicationId?: string @ApiProperty() - organizationId?: string + organization?: OrganizationDto @ApiProperty() formId?: string @@ -20,6 +21,6 @@ export class ApplicationDto { @ApiProperty() modified?: Date - @ApiProperty({ type: [ApplicationSection] }) - sections?: ApplicationSection[] + @ApiProperty({ type: [ApplicationSectionDto] }) + sections?: ApplicationSectionDto[] } diff --git a/apps/services/form-system/src/app/modules/fields/models/field.model.ts b/apps/services/form-system/src/app/modules/fields/models/field.model.ts index 9a52edc9fcf5..c402d34e2187 100644 --- a/apps/services/form-system/src/app/modules/fields/models/field.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/field.model.ts @@ -15,7 +15,7 @@ import { LanguageType } from '../../../dataTypes/languageType.model' import { FieldType } from './fieldType.model' import { FieldSettings } from '../../fieldSettings/models/fieldSettings.model' -@Table({ tableName: 'fields' }) +@Table({ tableName: 'field' }) export class Field extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts b/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts index bb7fd6c4575d..7e7e08489d08 100644 --- a/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/fieldType.model.ts @@ -14,7 +14,7 @@ import { LanguageType } from '../../../dataTypes/languageType.model' import { Organization } from '../../organizations/models/organization.model' import { Field } from './field.model' -@Table({ tableName: 'field_types' }) +@Table({ tableName: 'field_type' }) export class FieldType extends Model { @Column({ type: DataType.UUID, @@ -69,7 +69,7 @@ export class FieldType extends Model { fields?: Field[] @BelongsToMany(() => Organization, { - through: 'organization_field_types', + through: 'organization_field_type', foreignKey: 'field_type_id', otherKey: 'organization_id', }) diff --git a/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts b/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts index bfd940e90dde..3f46728593a1 100644 --- a/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/organizationFieldType.model.ts @@ -11,7 +11,7 @@ import { Organization } from '../../organizations/models/organization.model' import { FieldType } from './fieldType.model' import { CreationOptional } from 'sequelize' -@Table({ tableName: 'organization_field_types' }) +@Table({ tableName: 'organization_field_type' }) export class OrganizationFieldType extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index bca65396ee0b..48b344ca5c6d 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -283,7 +283,6 @@ export class FormsService { waitingText: section.waitingText, isHidden: section.isHidden, isCompleted: section.isCompleted, - callRuleset: section.callRuleset, } as SectionDto) section.screens?.map((screen) => { formDto.screens?.push({ @@ -295,6 +294,7 @@ export class FormsService { displayOrder: screen.displayOrder, isHidden: screen.isHidden, multiset: screen.multiset, + callRuleset: screen.callRuleset, } as ScreenDto) screen.fields?.map((field) => { formDto.fields?.push({ diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index a35da4018ff5..3682a005c3aa 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -18,7 +18,7 @@ import { FormApplicant } from '../../applicants/models/formApplicant.model' import { TestimonyType } from '../../testimonies/models/testimonyType.model' import { randomUUID } from 'crypto' -@Table({ tableName: 'forms' }) +@Table({ tableName: 'form' }) export class Form extends Model { @Column({ type: DataType.UUID, @@ -113,7 +113,7 @@ export class Form extends Model { organizationId!: string @BelongsToMany(() => TestimonyType, { - through: 'form_testimony_types', + through: 'form_testimony_type', foreignKey: 'form_id', otherKey: 'testimony_type_id', }) diff --git a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts index 13fea01c45c1..9aface4bc9aa 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts @@ -12,7 +12,7 @@ import { LanguageType } from '../../../dataTypes/languageType.model' import { CreationOptional } from 'sequelize' import { FieldSettings } from '../../fieldSettings/models/fieldSettings.model' -@Table({ tableName: 'list_items' }) +@Table({ tableName: 'list_item' }) export class ListItem extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts index c134d4c2b48a..a91a3d8d12ce 100644 --- a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts +++ b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts @@ -13,7 +13,7 @@ import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' import { ListTypes } from '../../../enums/listTypes' import { Organization } from '../../organizations/models/organization.model' -@Table({ tableName: 'list_types' }) +@Table({ tableName: 'list_type' }) export class ListType extends Model { @Column({ type: DataType.UUID, @@ -65,7 +65,7 @@ export class ListType extends Model { type!: string @BelongsToMany(() => Organization, { - through: 'organization_list_types', + through: 'organization_list_type', foreignKey: 'list_type_id', otherKey: 'organization_id', }) diff --git a/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts index abc6b65cb7ed..c4e3a1cc386e 100644 --- a/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts +++ b/apps/services/form-system/src/app/modules/lists/models/organizationListType.model.ts @@ -11,7 +11,7 @@ import { import { Organization } from '../../organizations/models/organization.model' import { ListType } from './listType.model' -@Table({ tableName: 'organization_list_types' }) +@Table({ tableName: 'organization_list_type' }) export class OrganizationListType extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts index c6e1064ca236..06a9fbfabd32 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts @@ -1,4 +1,11 @@ -import { OmitType } from '@nestjs/swagger' +import { ApiProperty, OmitType } from '@nestjs/swagger' import { Organization } from '../organization.model' +import { LanguageType } from '../../../../dataTypes/languageType.model' -export class OrganizationDto extends OmitType(Organization, ['id'] as const) {} +export class OrganizationDto { + @ApiProperty() + name!: LanguageType + + @ApiProperty() + nationalId!: string +} diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index 99f8b08eca16..25f062a3f2c2 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -17,7 +17,7 @@ import { FieldType } from '../../fields/models/fieldType.model' import { ListType } from '../../lists/models/listType.model' import { TestimonyType } from '../../testimonies/models/testimonyType.model' -@Table({ tableName: 'organizations' }) +@Table({ tableName: 'organization' }) export class Organization extends Model { @Column({ type: DataType.UUID, @@ -61,21 +61,21 @@ export class Organization extends Model { applicantTypeNameSuggestions?: ApplicantTypeNameSuggestion[] @BelongsToMany(() => FieldType, { - through: 'organization_field_types', + through: 'organization_field_type', foreignKey: 'organization_id', otherKey: 'field_type_id', }) organizationFieldTypes?: NonAttribute @BelongsToMany(() => TestimonyType, { - through: 'organization_testimony_types', + through: 'organization_testimony_type', foreignKey: 'organization_id', otherKey: 'testimony_type_id', }) organizationTestimonyTypes?: NonAttribute @BelongsToMany(() => ListType, { - through: 'organization_list_types', + through: 'organization_list_type', foreignKey: 'organization_id', otherKey: 'list_type_id', }) diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts index b69a0a26bb3b..1876a240302e 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/applicationScreen.dto.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { ApplicationFieldDto } from '../../../fields/models/dto/applicationField.dto' -export class ApplicationScreen { +export class ApplicationScreenDto { @ApiProperty() id!: string @@ -18,6 +18,9 @@ export class ApplicationScreen { @ApiProperty() multiset!: number + @ApiProperty() + callRuleset!: boolean + @ApiProperty({ type: [ApplicationFieldDto] }) fields!: ApplicationFieldDto[] } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts index 65ea08e69ce4..a090a77e71e9 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/screen.dto.ts @@ -16,4 +16,7 @@ export class ScreenDto { @ApiProperty() multiset!: number + + @ApiProperty() + callRuleset!: boolean } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts index 943dc33f7e75..b16dd949005b 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts @@ -7,4 +7,7 @@ export class UpdateScreenDto { @ApiProperty() multiset!: number + + @ApiProperty() + callRuleset!: boolean } diff --git a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts index 6b226897b3d2..d105bb74a4d7 100644 --- a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts +++ b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts @@ -14,7 +14,7 @@ import { CreationOptional } from 'sequelize' import { Field } from '../../fields/models/field.model' import { LanguageType } from '../../../dataTypes/languageType.model' -@Table({ tableName: 'screens' }) +@Table({ tableName: 'screen' }) export class Screen extends Model { @Column({ type: DataType.UUID, @@ -65,6 +65,14 @@ export class Screen extends Model { @ApiProperty() multiset!: number + @Column({ + type: DataType.BOOLEAN, + allowNull: false, + defaultValue: false, + }) + @ApiProperty() + callRuleset!: boolean + @HasMany(() => Field) @ApiProperty({ type: [Field] }) fields?: Field[] diff --git a/apps/services/form-system/src/app/modules/screens/screens.service.ts b/apps/services/form-system/src/app/modules/screens/screens.service.ts index 13dc0de2ba46..68790516447b 100644 --- a/apps/services/form-system/src/app/modules/screens/screens.service.ts +++ b/apps/services/form-system/src/app/modules/screens/screens.service.ts @@ -42,6 +42,7 @@ export class ScreensService { screen.name = updateScreenDto.name screen.multiset = updateScreenDto.multiset + screen.callRuleset = updateScreenDto.callRuleset screen.modified = new Date() await screen.save() @@ -52,6 +53,7 @@ export class ScreensService { name: screen.name, displayOrder: screen.displayOrder, multiset: screen.multiset, + callRuleset: screen.callRuleset, } return screenDto diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts index cf5b78ab5bbc..10117c5a09c3 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -import { ApplicationScreen } from '../../../screens/models/dto/applicationScreen.dto' +import { ApplicationScreenDto } from '../../../screens/models/dto/applicationScreen.dto' -export class ApplicationSection { +export class ApplicationSectionDto { @ApiProperty() id!: string @@ -18,9 +18,6 @@ export class ApplicationSection { @ApiProperty({ type: LanguageType }) waitingText?: LanguageType - @ApiProperty() - callRuleset!: boolean - - @ApiProperty({ type: [ApplicationScreen] }) - screens!: ApplicationScreen[] + @ApiProperty({ type: [ApplicationScreenDto] }) + screens!: ApplicationScreenDto[] } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts index 69f2d3804db2..802ee0ac078c 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts @@ -16,7 +16,4 @@ export class SectionDto { @ApiProperty({ type: LanguageType }) waitingText?: LanguageType - - @ApiProperty() - callRuleset!: boolean } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts index 00133fa926dd..0f8d1ac63518 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts @@ -7,7 +7,4 @@ export class UpdateSectionDto { @ApiProperty({ type: LanguageType }) waitingText?: LanguageType - - @ApiProperty() - callRuleset!: boolean } diff --git a/apps/services/form-system/src/app/modules/sections/models/section.model.ts b/apps/services/form-system/src/app/modules/sections/models/section.model.ts index 93047683311c..47f275399d3e 100644 --- a/apps/services/form-system/src/app/modules/sections/models/section.model.ts +++ b/apps/services/form-system/src/app/modules/sections/models/section.model.ts @@ -15,7 +15,7 @@ import { SectionTypes } from '../../../enums/sectionTypes' import { Form } from '../../forms/models/form.model' import { Screen } from '../../screens/models/screen.model' -@Table({ tableName: 'sections' }) +@Table({ tableName: 'section' }) export class Section extends Model
{ @Column({ type: DataType.UUID, @@ -74,14 +74,6 @@ export class Section extends Model
{ @ApiProperty() isHidden!: boolean - @Column({ - type: DataType.BOOLEAN, - allowNull: false, - defaultValue: false, - }) - @ApiProperty() - callRuleset!: boolean - @Column({ type: DataType.BOOLEAN, allowNull: false, diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.ts b/apps/services/form-system/src/app/modules/sections/sections.service.ts index 4fd199fbbe67..f0ef20c95e26 100644 --- a/apps/services/form-system/src/app/modules/sections/sections.service.ts +++ b/apps/services/form-system/src/app/modules/sections/sections.service.ts @@ -51,7 +51,6 @@ export class SectionsService { section.name = updateSectionDto.name section.waitingText = updateSectionDto.waitingText - section.callRuleset = updateSectionDto.callRuleset section.modified = new Date() await section.save() @@ -62,7 +61,6 @@ export class SectionsService { sectionType: section.sectionType, displayOrder: section.displayOrder, waitingText: section.waitingText, - callRuleset: section.callRuleset, } return sectionDto diff --git a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts index b5bce82bbf49..7ab34a62d8a7 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts @@ -11,7 +11,7 @@ import { import { Form } from '../../forms/models/form.model' import { TestimonyType } from '../../testimonies/models/testimonyType.model' -@Table({ tableName: 'form_testimony_types' }) +@Table({ tableName: 'form_testimony_type' }) export class FormTestimonyType extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts index f3b5a943f265..03528d43a153 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts @@ -11,7 +11,7 @@ import { import { Organization } from '../../organizations/models/organization.model' import { TestimonyType } from './testimonyType.model' -@Table({ tableName: 'organization_testimony_types' }) +@Table({ tableName: 'organization_testimony_type' }) export class OrganizationTestimonyType extends Model { @Column({ type: DataType.UUID, diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts index bb88da7f0784..753c7b2ffd80 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts @@ -14,7 +14,7 @@ import { TestimonyTypes } from '../../../enums/testimonyTypes' import { Organization } from '../../organizations/models/organization.model' import { Form } from '../../forms/models/form.model' -@Table({ tableName: 'testimony_types' }) +@Table({ tableName: 'testimony_type' }) export class TestimonyType extends Model { @Column({ type: DataType.UUID, @@ -58,14 +58,14 @@ export class TestimonyType extends Model { modified!: CreationOptional @BelongsToMany(() => Organization, { - through: 'organization_testimony_types', + through: 'organization_testimony_type', foreignKey: 'testimony_type_id', otherKey: 'organization_id', }) organizations?: NonAttribute @BelongsToMany(() => Form, { - through: 'form_testimony_types', + through: 'form_testimony_type', foreignKey: 'testimony_type_id', otherKey: 'form_id', }) From 6a3c7d9387bc63d371ae21680bf2047562c1a477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Mon, 1 Jul 2024 15:26:45 +0000 Subject: [PATCH 50/72] changed naming of testimony to certification --- apps/services/form-system/docker-compose.yml | 4 +- apps/services/form-system/jest.config.ts | 2 +- .../20240607120240-create-form-applicant.js | 6 +-- ...1-create-applicant-type-name-suggestion.js | 6 +-- ...240614131225-create-certification-type.js} | 4 +- ...create-organization-certification-type.js} | 8 +-- ...4152811-create-form-certification-type.js} | 8 +-- .../20240626093807-create-applicant.js | 6 +-- ...20240614132148-seed-certification-type.js} | 4 +- ...3-seed-organization-certification-type.js} | 16 +++--- apps/services/form-system/sequelize.config.js | 4 +- .../form-system/src/app/app.module.ts | 4 +- .../src/app/enums/applicantTypes.ts | 10 ++-- ...estimonyTypes.ts => certificationTypes.ts} | 2 +- .../applications/applications.module.ts | 10 +++- .../applications/applications.service.ts | 16 ++++++ .../applications/models/application.mapper.ts | 8 ++- .../certifications/certifications.module.ts | 14 +++++ .../models/certificationType.model.ts} | 14 ++--- .../models/dto/certificationType.dto.ts} | 2 +- .../models/dto/formCertificationType.dto.ts} | 2 +- .../models/formCertificationType.model.ts} | 12 ++--- .../organizationCertificationType.model.ts} | 12 ++--- .../src/app/modules/forms/forms.module.ts | 4 +- .../src/app/modules/forms/forms.service.ts | 54 +++++++++---------- .../app/modules/forms/models/dto/form.dto.ts | 6 +-- .../forms/models/dto/form.response.dto.ts | 6 +-- .../app/modules/forms/models/form.model.ts | 10 ++-- .../models/organization.model.ts | 10 ++-- .../modules/testimonies/testimonies.module.ts | 11 ---- 30 files changed, 153 insertions(+), 122 deletions(-) rename apps/services/form-system/migrations/{20240614131225-create-testimony-type.js => 20240614131225-create-certification-type.js} (93%) rename apps/services/form-system/migrations/{20240614142442-create-organization-testimony-type.js => 20240614142442-create-organization-certification-type.js} (86%) rename apps/services/form-system/migrations/{20240614152811-create-form-testimony-type.js => 20240614152811-create-form-certification-type.js} (87%) rename apps/services/form-system/seeders/{20240614132148-seed-testimony-type.js => 20240614132148-seed-certification-type.js} (95%) rename apps/services/form-system/seeders/{20240614142713-seed-organization-testimony-type.js => 20240614142713-seed-organization-certification-type.js} (65%) rename apps/services/form-system/src/app/enums/{testimonyTypes.ts => certificationTypes.ts} (91%) create mode 100644 apps/services/form-system/src/app/modules/certifications/certifications.module.ts rename apps/services/form-system/src/app/modules/{testimonies/models/testimonyType.model.ts => certifications/models/certificationType.model.ts} (80%) rename apps/services/form-system/src/app/modules/{testimonies/models/dto/formTestimonyType.dto.ts => certifications/models/dto/certificationType.dto.ts} (89%) rename apps/services/form-system/src/app/modules/{testimonies/models/dto/testimonyType.dto.ts => certifications/models/dto/formCertificationType.dto.ts} (88%) rename apps/services/form-system/src/app/modules/{testimonies/models/formTestimonyType.model.ts => certifications/models/formCertificationType.model.ts} (69%) rename apps/services/form-system/src/app/modules/{testimonies/models/organizationTestimonyType.model.ts => certifications/models/organizationCertificationType.model.ts} (69%) delete mode 100644 apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts diff --git a/apps/services/form-system/docker-compose.yml b/apps/services/form-system/docker-compose.yml index a7c14265f530..afa184ba451f 100644 --- a/apps/services/form-system/docker-compose.yml +++ b/apps/services/form-system/docker-compose.yml @@ -7,9 +7,9 @@ services: networks: - local environment: - - POSTGRES_DB=form-system + - POSTGRES_DB=dev_db - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=postgres + - POSTGRES_PASSWORD=dev_db ports: - 5432:5432 diff --git a/apps/services/form-system/jest.config.ts b/apps/services/form-system/jest.config.ts index 0a9ae85d4383..0a5719515c39 100644 --- a/apps/services/form-system/jest.config.ts +++ b/apps/services/form-system/jest.config.ts @@ -7,5 +7,5 @@ export default { '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], }, moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../../coverage/apps/services/form-system', + coverageDirectory: '/coverage/', } diff --git a/apps/services/form-system/migrations/20240607120240-create-form-applicant.js b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js index 18df4b4e2d73..a9194efe6216 100644 --- a/apps/services/form-system/migrations/20240607120240-create-form-applicant.js +++ b/apps/services/form-system/migrations/20240607120240-create-form-applicant.js @@ -29,10 +29,10 @@ module.exports = { applicant_type: { type: Sequelize.ENUM( 'individual', - 'individualWithMandateFromIndividual', - 'individualWithMandateFromLegalEntity', + 'individualWithDelegationFromIndividual', + 'individualWithDelegationFromLegalEntity', 'individualWithProcuration', - 'individualGivingMandate', + 'individualGivingDelegation', 'legalEntity', ), allowNull: false, diff --git a/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js index 6b1209610a87..7223c4843f71 100644 --- a/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js +++ b/apps/services/form-system/migrations/20240607130311-create-applicant-type-name-suggestion.js @@ -29,10 +29,10 @@ module.exports = { applicant_type: { type: Sequelize.ENUM( 'individual', - 'individualWithMandateFromIndividual', - 'individualWithMandateFromLegalEntity', + 'individualWithDelegationFromIndividual', + 'individualWithDelegationFromLegalEntity', 'individualWithProcuration', - 'individualGivingMandate', + 'individualGivingDelegation', 'legalEntity', ), allowNull: false, diff --git a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js b/apps/services/form-system/migrations/20240614131225-create-certification-type.js similarity index 93% rename from apps/services/form-system/migrations/20240614131225-create-testimony-type.js rename to apps/services/form-system/migrations/20240614131225-create-certification-type.js index 1a75d03459c2..fe5b9685ad35 100644 --- a/apps/services/form-system/migrations/20240614131225-create-testimony-type.js +++ b/apps/services/form-system/migrations/20240614131225-create-certification-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'testimony_type', + 'certification_type', { id: { type: Sequelize.UUID, @@ -49,7 +49,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('testimony_type', { transaction: t }), + queryInterface.dropTable('certification_type', { transaction: t }), ) }, } diff --git a/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js b/apps/services/form-system/migrations/20240614142442-create-organization-certification-type.js similarity index 86% rename from apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js rename to apps/services/form-system/migrations/20240614142442-create-organization-certification-type.js index 6bfcc9d76461..10fbb2b2850f 100644 --- a/apps/services/form-system/migrations/20240614142442-create-organization-testimony-type.js +++ b/apps/services/form-system/migrations/20240614142442-create-organization-certification-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'organization_testimony_type', + 'organization_certification_type', { id: { type: Sequelize.UUID, @@ -30,11 +30,11 @@ module.exports = { key: 'id', }, }, - testimony_type_id: { + certification_type_id: { type: Sequelize.UUID, allowNull: false, references: { - model: 'testimony_type', + model: 'certification_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('organization_testimony_type', { + queryInterface.dropTable('organization_certification_type', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js b/apps/services/form-system/migrations/20240614152811-create-form-certification-type.js similarity index 87% rename from apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js rename to apps/services/form-system/migrations/20240614152811-create-form-certification-type.js index ddb949ded28e..348acf7503f1 100644 --- a/apps/services/form-system/migrations/20240614152811-create-form-testimony-type.js +++ b/apps/services/form-system/migrations/20240614152811-create-form-certification-type.js @@ -4,7 +4,7 @@ module.exports = { async up(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => queryInterface.createTable( - 'form_testimony_type', + 'form_certification_type', { id: { type: Sequelize.UUID, @@ -30,11 +30,11 @@ module.exports = { key: 'id', }, }, - testimony_type_id: { + certification_type_id: { type: Sequelize.UUID, allowNull: false, references: { - model: 'testimony_type', + model: 'certification_type', key: 'id', }, }, @@ -46,7 +46,7 @@ module.exports = { async down(queryInterface, Sequelize) { return queryInterface.sequelize.transaction((t) => - queryInterface.dropTable('form_testimony_type', { + queryInterface.dropTable('form_certification_type', { transaction: t, }), ) diff --git a/apps/services/form-system/migrations/20240626093807-create-applicant.js b/apps/services/form-system/migrations/20240626093807-create-applicant.js index aa7923bf6b04..c2c51a3a5fc5 100644 --- a/apps/services/form-system/migrations/20240626093807-create-applicant.js +++ b/apps/services/form-system/migrations/20240626093807-create-applicant.js @@ -56,10 +56,10 @@ module.exports = { applicant_type: { type: Sequelize.ENUM( 'individual', - 'individualWithMandateFromIndividual', - 'individualWithMandateFromLegalEntity', + 'individualWithDelegationFromIndividual', + 'individualWithDelegationFromLegalEntity', 'individualWithProcuration', - 'individualGivingMandate', + 'individualGivingDelegation', 'legalEntity', ), allowNull: false, diff --git a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js b/apps/services/form-system/seeders/20240614132148-seed-certification-type.js similarity index 95% rename from apps/services/form-system/seeders/20240614132148-seed-testimony-type.js rename to apps/services/form-system/seeders/20240614132148-seed-certification-type.js index 23973c67edf0..c1310ab7c97d 100644 --- a/apps/services/form-system/seeders/20240614132148-seed-testimony-type.js +++ b/apps/services/form-system/seeders/20240614132148-seed-certification-type.js @@ -2,7 +2,7 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('testimony_type', [ + await queryInterface.bulkInsert('certification_type', [ { id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', type: 'estateGuardianshipCertificateStamped', @@ -60,6 +60,6 @@ module.exports = { }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('testimony_type', null, {}) + await queryInterface.bulkDelete('certification_type', null, {}) }, } diff --git a/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js b/apps/services/form-system/seeders/20240614142713-seed-organization-certification-type.js similarity index 65% rename from apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js rename to apps/services/form-system/seeders/20240614142713-seed-organization-certification-type.js index 12df1b02456a..dc63e7b77852 100644 --- a/apps/services/form-system/seeders/20240614142713-seed-organization-testimony-type.js +++ b/apps/services/form-system/seeders/20240614142713-seed-organization-certification-type.js @@ -2,53 +2,53 @@ module.exports = { async up(queryInterface, Sequelize) { - await queryInterface.bulkInsert('organization_testimony_type', [ + await queryInterface.bulkInsert('organization_certification_type', [ { id: 'aeac43a3-daf0-4bca-9079-7dffe6121d75', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', // estateGuardianshipCertificateStamped + certification_type_id: '329e9b75-62a6-41af-a1cb-2052d26ac31b', // estateGuardianshipCertificateStamped }, { id: '2d324d06-2e2a-4da3-b6fd-f18a3e4e2dd4', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: '37b8a86e-5787-4007-be40-d3f7b0070cca', // estateGuardianshipCertificateUnstamped + certification_type_id: '37b8a86e-5787-4007-be40-d3f7b0070cca', // estateGuardianshipCertificateUnstamped }, { id: 'b825f585-aa5d-48e5-91d6-0e056e41b5f3', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: 'fa035b40-4324-4140-8747-d163ef645b28', // residenceCertificate + certification_type_id: 'fa035b40-4324-4140-8747-d163ef645b28', // residenceCertificate }, { id: '8570a43a-b694-468e-8956-c4e906c9becd', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: '5ec5b516-a152-4761-b0e0-ba5aa4ffae61', // indebtednessCertificate + certification_type_id: '5ec5b516-a152-4761-b0e0-ba5aa4ffae61', // indebtednessCertificate }, { id: 'c8b66543-fe0d-45ee-98bc-3d3bc9a0ad66', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: 'b3f37a69-2700-45f5-88e6-03fc09fcf6cc', // criminalRecordStamped + certification_type_id: 'b3f37a69-2700-45f5-88e6-03fc09fcf6cc', // criminalRecordStamped }, { id: '65486db0-cd26-4db8-ba8c-9989ff389904', created: new Date(), modified: new Date(), organization_id: 'a4b0db68-e169-416a-8ad9-e46b73ce2d39', // Sandbox Ísland ehf. - testimony_type_id: '72127323-56f3-40ff-8ae4-68c20e80ff37', // criminalRecordUnstamped + certification_type_id: '72127323-56f3-40ff-8ae4-68c20e80ff37', // criminalRecordUnstamped }, ]) }, async down(queryInterface, Sequelize) { - await queryInterface.bulkDelete('organization_testimony_type', null, {}) + await queryInterface.bulkDelete('organization_certification_type', null, {}) }, } diff --git a/apps/services/form-system/sequelize.config.js b/apps/services/form-system/sequelize.config.js index be5a80f2e1a6..0af30bf8fd95 100644 --- a/apps/services/form-system/sequelize.config.js +++ b/apps/services/form-system/sequelize.config.js @@ -2,8 +2,8 @@ module.exports = { development: { username: 'postgres', - password: 'postgres', - database: 'form-system', + password: 'dev_db', + database: 'dev_db', host: 'localhost', dialect: 'postgres', seederStorage: 'sequelize', diff --git a/apps/services/form-system/src/app/app.module.ts b/apps/services/form-system/src/app/app.module.ts index a91a035fcc27..ee8ef6f5d035 100644 --- a/apps/services/form-system/src/app/app.module.ts +++ b/apps/services/form-system/src/app/app.module.ts @@ -11,7 +11,7 @@ import { FieldsModule } from './modules/fields/fields.module' import { ListsModule } from './modules/lists/lists.module' import { OrganizationsModule } from './modules/organizations/organizations.module' import { SectionsModule } from './modules/sections/sections.module' -import { TestimoniesModule } from './modules/testimonies/testimonies.module' +import { CertificationsModule } from './modules/certifications/certifications.module' import { SequelizeConfigService } from './sequelizeConfig.service' import { ListItemsModule } from './modules/listItems/listItems.module' import { ApplicationsModule } from './modules/applications/applications.module' @@ -29,7 +29,7 @@ import { ApplicationsModule } from './modules/applications/applications.module' SectionsModule, ScreensModule, FieldsModule, - TestimoniesModule, + CertificationsModule, ListsModule, FieldSettingsModule, ListItemsModule, diff --git a/apps/services/form-system/src/app/enums/applicantTypes.ts b/apps/services/form-system/src/app/enums/applicantTypes.ts index 6a465df466aa..8044550c07e7 100644 --- a/apps/services/form-system/src/app/enums/applicantTypes.ts +++ b/apps/services/form-system/src/app/enums/applicantTypes.ts @@ -1,10 +1,10 @@ export const ApplicantTypes = { INDIVIDUAL: 'individual', - iNDIVIDUAL_WITH_MANDATE_FROM_INDIVIDUAL: - 'individualWithMandateFromIndividual', - INDIVIDUAL_WITH_MANDATE_FROM_LEGAL_ENTITY: - 'individualWithMandateFromLegalEntity', + iNDIVIDUAL_WITH_DELEGATION_FROM_INDIVIDUAL: + 'individualWithDelegationFromIndividual', + INDIVIDUAL_WITH_DELEGATION_FROM_LEGAL_ENTITY: + 'individualWithDelegationFromLegalEntity', INDIVIDUAL_WITH_PROCURATION: 'individualWithProcuration', - INDIVIDUAL_GIVING_MANDATE: 'individualGivingMandate', + INDIVIDUAL_GIVING_DELEGATION: 'individualGivingDelegation', LEGAL_ENTITY: 'legalEntity', } diff --git a/apps/services/form-system/src/app/enums/testimonyTypes.ts b/apps/services/form-system/src/app/enums/certificationTypes.ts similarity index 91% rename from apps/services/form-system/src/app/enums/testimonyTypes.ts rename to apps/services/form-system/src/app/enums/certificationTypes.ts index 8920e9964540..5840181752ec 100644 --- a/apps/services/form-system/src/app/enums/testimonyTypes.ts +++ b/apps/services/form-system/src/app/enums/certificationTypes.ts @@ -1,4 +1,4 @@ -export const TestimonyTypes = { +export const CertificationTypes = { ESTATE_GUARDIANSHIP_CERTIFICATE_STAMPED: 'estateGuardianshipCertificateStamped', ESTATE_GUARDIANSHIP_CERTIFICATE_UNSTAMPED: diff --git a/apps/services/form-system/src/app/modules/applications/applications.module.ts b/apps/services/form-system/src/app/modules/applications/applications.module.ts index 416bd9450863..3d996c2b8f99 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.module.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.module.ts @@ -3,13 +3,19 @@ import { Application } from './models/application.model' import { SequelizeModule } from '@nestjs/sequelize' import { ApplicationsService } from './applications.service' import { ApplicationsController } from './applications.controller' -import { FormsService } from '../forms/forms.service' import { Form } from '../forms/models/form.model' import { ApplicationMapper } from './models/application.mapper' +import { FieldSettingsMapper } from '../fieldSettings/models/fieldSettings.mapper' +import { ListItemMapper } from '../listItems/models/listItem.mapper' @Module({ imports: [SequelizeModule.forFeature([Application, Form])], controllers: [ApplicationsController], - providers: [ApplicationsService, ApplicationMapper], + providers: [ + ApplicationsService, + ApplicationMapper, + FieldSettingsMapper, + ListItemMapper, + ], }) export class ApplicationsModule {} diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts index db3aff975109..cc9b8460b93f 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.service.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -74,6 +74,22 @@ export class ApplicationsService { ], }, ], + order: [ + [{ model: Section, as: 'sections' }, 'displayOrder', 'ASC'], + [ + { model: Section, as: 'sections' }, + { model: Screen, as: 'screens' }, + 'displayOrder', + 'ASC', + ], + [ + { model: Section, as: 'sections' }, + { model: Screen, as: 'screens' }, + { model: Field, as: 'fields' }, + 'displayOrder', + 'ASC', + ], + ], }) if (!form) { diff --git a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts index 967a62e9e549..68cc5507212b 100644 --- a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts +++ b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts @@ -6,9 +6,11 @@ import { OrganizationDto } from '../../organizations/models/dto/organization.dto import { ApplicationSectionDto } from '../../sections/models/dto/applicationSection.dto' import { ApplicationScreenDto } from '../../screens/models/dto/applicationScreen.dto' import { ApplicationFieldDto } from '../../fields/models/dto/applicationField.dto' +import { FieldSettingsMapper } from '../../fieldSettings/models/fieldSettings.mapper' @Injectable() export class ApplicationMapper { + constructor(private readonly fieldSettingsMapper: FieldSettingsMapper) {} mapFormToApplicationDto( form: Form, application: Application, @@ -45,7 +47,11 @@ export class ApplicationMapper { description: field.description, isPartOfMultiset: field.isPartOfMultiset, fieldType: field.fieldType, - fieldSettings: field.fieldSettings, + fieldSettings: + this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( + field.fieldSettings, + field.fieldType, + ), } as ApplicationFieldDto }), } as ApplicationScreenDto diff --git a/apps/services/form-system/src/app/modules/certifications/certifications.module.ts b/apps/services/form-system/src/app/modules/certifications/certifications.module.ts new file mode 100644 index 000000000000..409dd812cef6 --- /dev/null +++ b/apps/services/form-system/src/app/modules/certifications/certifications.module.ts @@ -0,0 +1,14 @@ +import { Module } from '@nestjs/common' +import { SequelizeModule } from '@nestjs/sequelize' +import { CertificationType } from './models/certificationType.model' +import { OrganizationCertificationType } from './models/organizationCertificationType.model' + +@Module({ + imports: [ + SequelizeModule.forFeature([ + CertificationType, + OrganizationCertificationType, + ]), + ], +}) +export class CertificationsModule {} diff --git a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts b/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts similarity index 80% rename from apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts rename to apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts index 753c7b2ffd80..5d36f3348ff0 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/testimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts @@ -10,12 +10,12 @@ import { } from 'sequelize-typescript' import { LanguageType } from '../../../dataTypes/languageType.model' import { CreationOptional, DataTypes, NonAttribute } from 'sequelize' -import { TestimonyTypes } from '../../../enums/testimonyTypes' +import { CertificationTypes } from '../../../enums/certificationTypes' import { Organization } from '../../organizations/models/organization.model' import { Form } from '../../forms/models/form.model' -@Table({ tableName: 'testimony_type' }) -export class TestimonyType extends Model { +@Table({ tableName: 'certification_type' }) +export class CertificationType extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -44,9 +44,9 @@ export class TestimonyType extends Model { @Column({ type: DataTypes.ENUM, allowNull: false, - values: Object.values(TestimonyTypes), + values: Object.values(CertificationTypes), }) - @ApiProperty({ enum: TestimonyTypes }) + @ApiProperty({ enum: CertificationTypes }) type!: string @CreatedAt @@ -59,14 +59,14 @@ export class TestimonyType extends Model { @BelongsToMany(() => Organization, { through: 'organization_testimony_type', - foreignKey: 'testimony_type_id', + foreignKey: 'certification_type_id', otherKey: 'organization_id', }) organizations?: NonAttribute @BelongsToMany(() => Form, { through: 'form_testimony_type', - foreignKey: 'testimony_type_id', + foreignKey: 'certification_type_id', otherKey: 'form_id', }) forms?: NonAttribute diff --git a/apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts b/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts similarity index 89% rename from apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts rename to apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts index 8da00a0a7a6d..ad992013f2dd 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/dto/formTestimonyType.dto.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class FormTestimonyTypeDto { +export class CertificationTypeDto { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts b/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts similarity index 88% rename from apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts rename to apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts index cb6366867db2..0b1d6db6fab1 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/dto/testimonyType.dto.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' -export class TestimonyTypeDto { +export class FormCertificationTypeDto { @ApiProperty() id!: string diff --git a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts b/apps/services/form-system/src/app/modules/certifications/models/formCertificationType.model.ts similarity index 69% rename from apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts rename to apps/services/form-system/src/app/modules/certifications/models/formCertificationType.model.ts index 7ab34a62d8a7..c1dd7b5f8778 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/formTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/formCertificationType.model.ts @@ -9,10 +9,10 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Form } from '../../forms/models/form.model' -import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { CertificationType } from './certificationType.model' -@Table({ tableName: 'form_testimony_type' }) -export class FormTestimonyType extends Model { +@Table({ tableName: 'form_certification_type' }) +export class FormCertificationType extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -35,11 +35,11 @@ export class FormTestimonyType extends Model { }) formId!: string - @ForeignKey(() => TestimonyType) + @ForeignKey(() => CertificationType) @Column({ type: DataType.STRING, allowNull: false, - field: 'testimony_type_id', + field: 'certification_type_id', }) - testimonyTypeId!: string + certificationTypeId!: string } diff --git a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts b/apps/services/form-system/src/app/modules/certifications/models/organizationCertificationType.model.ts similarity index 69% rename from apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts rename to apps/services/form-system/src/app/modules/certifications/models/organizationCertificationType.model.ts index 03528d43a153..d7e74c6f73ec 100644 --- a/apps/services/form-system/src/app/modules/testimonies/models/organizationTestimonyType.model.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/organizationCertificationType.model.ts @@ -9,10 +9,10 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Organization } from '../../organizations/models/organization.model' -import { TestimonyType } from './testimonyType.model' +import { CertificationType } from './certificationType.model' -@Table({ tableName: 'organization_testimony_type' }) -export class OrganizationTestimonyType extends Model { +@Table({ tableName: 'organization_certification_type' }) +export class OrganizationCertificationType extends Model { @Column({ type: DataType.UUID, allowNull: false, @@ -35,11 +35,11 @@ export class OrganizationTestimonyType extends Model }) organizationId!: string - @ForeignKey(() => TestimonyType) + @ForeignKey(() => CertificationType) @Column({ type: DataType.STRING, allowNull: false, - field: 'testimony_type_id', + field: 'certification_type_id', }) - testimonyTypeId!: string + certificationTypeId!: string } diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index 9ff9827a9cac..c6d4de84da6e 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -7,7 +7,7 @@ import { FieldType } from '../fields/models/fieldType.model' import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' import { Section } from '../sections/models/section.model' -import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { CertificationType } from '../certifications/models/certificationType.model' import { FormsController } from './forms.controller' import { FormsService } from './forms.service' import { Form } from './models/form.model' @@ -24,7 +24,7 @@ import { FormMapper } from './models/form.mapper' Screen, Organization, FieldType, - TestimonyType, + CertificationType, ListType, ListItem, ]), diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 48b344ca5c6d..f69f3e0126bc 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -15,9 +15,9 @@ import { ListType } from '../lists/models/listType.model' import { Organization } from '../organizations/models/organization.model' import { SectionDto } from '../sections/models/dto/section.dto' import { Section } from '../sections/models/section.model' -import { FormTestimonyTypeDto } from '../testimonies/models/dto/formTestimonyType.dto' -import { TestimonyTypeDto } from '../testimonies/models/dto/testimonyType.dto' -import { TestimonyType } from '../testimonies/models/testimonyType.model' +import { FormCertificationTypeDto } from '../certifications/models/dto/formCertificationType.dto' +import { CertificationTypeDto } from '../certifications/models/dto/certificationType.dto' +import { CertificationType } from '../certifications/models/certificationType.model' import { CreateFormDto } from './models/dto/createForm.dto' import { FormDto } from './models/dto/form.dto' import { FormResponse } from './models/dto/form.response.dto' @@ -144,36 +144,36 @@ export class FormsService { const response: FormResponse = { form: this.setArrays(form), fieldTypes: await this.getFieldTypes(form.organizationId), - testimonyTypes: await this.getTestimonyTypes(form.organizationId), + certificationTypes: await this.getCertificationTypes(form.organizationId), listTypes: await this.getListTypes(form.organizationId), } return response } - private async getTestimonyTypes( + private async getCertificationTypes( organizationId: string, - ): Promise { - const organizationSpecificTestimonyTypes = + ): Promise { + const organizationSpecificCertificationTypes = await this.organizationModel.findByPk(organizationId, { - include: [TestimonyType], + include: [CertificationType], }) - const organizationTestimonyTypes = - organizationSpecificTestimonyTypes?.organizationTestimonyTypes as TestimonyType[] + const organizationCertificationTypes = + organizationSpecificCertificationTypes?.organizationCertificationTypes as CertificationType[] - const testimonyTypesDto: TestimonyTypeDto[] = [] + const certificationTypesDto: CertificationTypeDto[] = [] - organizationTestimonyTypes?.map((testimonyType) => { - testimonyTypesDto.push({ - id: testimonyType.id, - type: testimonyType.type, - name: testimonyType.name, - description: testimonyType.description, - } as TestimonyTypeDto) + organizationCertificationTypes?.map((certificationType) => { + certificationTypesDto.push({ + id: certificationType.id, + type: certificationType.type, + name: certificationType.name, + description: certificationType.description, + } as CertificationTypeDto) }) - return testimonyTypesDto + return certificationTypesDto } private async getFieldTypes(organizationId: string): Promise { @@ -248,20 +248,20 @@ export class FormsService { derivedFrom: form.derivedFrom, stopProgressOnValidatingScreen: form.stopProgressOnValidatingScreen, completedMessage: form.completedMessage, - testimonyTypes: [], + certificationTypes: [], applicants: [], sections: [], screens: [], fields: [], } - form.testimonyTypes?.map((testimonyType) => { - formDto.testimonyTypes?.push({ - id: testimonyType.id, - name: testimonyType.name, - description: testimonyType.description, - type: testimonyType.type, - } as FormTestimonyTypeDto) + form.certificationTypes?.map((certificationType) => { + formDto.certificationTypes?.push({ + id: certificationType.id, + name: certificationType.name, + description: certificationType.description, + type: certificationType.type, + } as FormCertificationTypeDto) }) form.applicants?.map((applicant) => { diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 2977e6419c57..70a41d9e7e29 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -4,7 +4,7 @@ import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.d import { ScreenDto } from '../../../screens/models/dto/screen.dto' import { FieldDto } from '../../../fields/models/dto/field.dto' import { SectionDto } from '../../../sections/models/dto/section.dto' -import { FormTestimonyTypeDto } from '../../../testimonies/models/dto/formTestimonyType.dto' +import { FormCertificationTypeDto } from '../../../certifications/models/dto/formCertificationType.dto' export class FormDto { @ApiProperty() @@ -43,8 +43,8 @@ export class FormDto { @ApiProperty({ type: LanguageType }) completedMessage?: LanguageType - @ApiProperty({ type: [FormTestimonyTypeDto] }) - testimonyTypes?: FormTestimonyTypeDto[] + @ApiProperty({ type: [FormCertificationTypeDto] }) + certificationTypes?: FormCertificationTypeDto[] @ApiProperty({ type: [FormApplicantDto] }) applicants?: FormApplicantDto[] diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts index bf47cd9d911c..ca267983c79a 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.response.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { FieldTypeDto } from '../../../fields/models/dto/fieldType.dto' import { ListTypeDto } from '../../../lists/models/dto/listType.dto' -import { TestimonyTypeDto } from '../../../testimonies/models/dto/testimonyType.dto' +import { CertificationTypeDto } from '../../../certifications/models/dto/certificationType.dto' import { FormDto } from './form.dto' export class FormResponse { @@ -11,8 +11,8 @@ export class FormResponse { @ApiProperty({ type: [FieldTypeDto] }) fieldTypes!: FieldTypeDto[] - @ApiProperty({ type: [TestimonyTypeDto] }) - testimonyTypes!: TestimonyTypeDto[] + @ApiProperty({ type: [CertificationTypeDto] }) + certificationTypes!: CertificationTypeDto[] @ApiProperty({ type: [ListTypeDto] }) listTypes!: ListTypeDto[] diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index 3682a005c3aa..b125fd58dd2b 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -15,7 +15,7 @@ import { ApiProperty } from '@nestjs/swagger' import { Organization } from '../../organizations/models/organization.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { FormApplicant } from '../../applicants/models/formApplicant.model' -import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { CertificationType } from '../../certifications/models/certificationType.model' import { randomUUID } from 'crypto' @Table({ tableName: 'form' }) @@ -112,10 +112,10 @@ export class Form extends Model { }) organizationId!: string - @BelongsToMany(() => TestimonyType, { - through: 'form_testimony_type', + @BelongsToMany(() => CertificationType, { + through: 'form_certification_type', foreignKey: 'form_id', - otherKey: 'testimony_type_id', + otherKey: 'certification_type_id', }) - testimonyTypes?: NonAttribute + certificationTypes?: NonAttribute } diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index 25f062a3f2c2..526660036a81 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -15,7 +15,7 @@ import { ApplicantTypeNameSuggestion } from '../../applicants/models/applicantTy import { Form } from '../../forms/models/form.model' import { FieldType } from '../../fields/models/fieldType.model' import { ListType } from '../../lists/models/listType.model' -import { TestimonyType } from '../../testimonies/models/testimonyType.model' +import { CertificationType } from '../../certifications/models/certificationType.model' @Table({ tableName: 'organization' }) export class Organization extends Model { @@ -67,12 +67,12 @@ export class Organization extends Model { }) organizationFieldTypes?: NonAttribute - @BelongsToMany(() => TestimonyType, { - through: 'organization_testimony_type', + @BelongsToMany(() => CertificationType, { + through: 'organization_certification_type', foreignKey: 'organization_id', - otherKey: 'testimony_type_id', + otherKey: 'certification_type_id', }) - organizationTestimonyTypes?: NonAttribute + organizationCertificationTypes?: NonAttribute @BelongsToMany(() => ListType, { through: 'organization_list_type', diff --git a/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts b/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts deleted file mode 100644 index b5ff89d01bb7..000000000000 --- a/apps/services/form-system/src/app/modules/testimonies/testimonies.module.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Module } from '@nestjs/common' -import { SequelizeModule } from '@nestjs/sequelize' -import { TestimonyType } from './models/testimonyType.model' -import { OrganizationTestimonyType } from './models/organizationTestimonyType.model' - -@Module({ - imports: [ - SequelizeModule.forFeature([TestimonyType, OrganizationTestimonyType]), - ], -}) -export class TestimoniesModule {} From faf16327055d67259e5e0be7623b4e4cd1c2dba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Tue, 2 Jul 2024 14:09:25 +0000 Subject: [PATCH 51/72] fixing apiproperty configurations --- apps/services/form-system/docker-compose.yml | 2 +- apps/services/form-system/sequelize.config.js | 2 +- .../form-system/src/app/enums/fieldTypes.ts | 25 +++++++++++ .../applicants/models/applicant.model.ts | 4 +- .../applicantTypeNameSuggestion.model.ts | 2 +- .../models/dto/applicationApplicant.dto.ts | 4 +- .../models/dto/formApplicant.dto.ts | 3 +- .../models/dto/application.dto.ts | 16 +++---- .../models/certificationType.model.ts | 4 +- .../models/dto/certificationType.dto.ts | 3 +- .../models/dto/formCertificationType.dto.ts | 3 +- .../models/dto/fieldSettings.dto.ts | 42 +++++++++---------- .../models/dto/updateFieldSettings.dto.ts | 40 +++++++++--------- .../models/fieldSettings.model.ts | 42 +++++++++---------- .../fields/models/dto/applicationField.dto.ts | 7 ++-- .../modules/fields/models/dto/field.dto.ts | 7 ++-- .../fields/models/dto/fieldType.dto.ts | 7 ++-- .../fields/models/dto/updateField.dto.ts | 3 +- .../app/modules/fields/models/field.model.ts | 8 ++-- .../app/modules/forms/models/dto/form.dto.ts | 20 ++++----- .../forms/models/dto/formsListForm.dto.ts | 8 ++-- .../app/modules/forms/models/form.model.ts | 8 ++-- .../listItems/models/dto/listItem.dto.ts | 6 +-- .../models/dto/updateListItem.dto.ts | 6 +-- .../listItems/models/listItem.model.ts | 6 +-- .../modules/lists/models/listType.model.ts | 4 +- .../models/dto/organization.dto.ts | 2 +- .../models/organization.model.ts | 2 +- .../modules/screens/models/screen.model.ts | 2 +- .../models/dto/applicationSection.dto.ts | 7 ++-- .../sections/models/dto/section.dto.ts | 7 ++-- .../sections/models/dto/updateSection.dto.ts | 4 +- .../modules/sections/models/section.model.ts | 8 ++-- apps/services/form-system/src/main.ts | 28 ++++--------- apps/services/form-system/src/openApi.ts | 8 ++++ .../domains/form-system/.vscode/settings.json | 3 -- package.json | 3 +- 37 files changed, 192 insertions(+), 164 deletions(-) create mode 100644 apps/services/form-system/src/app/enums/fieldTypes.ts create mode 100644 apps/services/form-system/src/openApi.ts delete mode 100644 libs/api/domains/form-system/.vscode/settings.json diff --git a/apps/services/form-system/docker-compose.yml b/apps/services/form-system/docker-compose.yml index afa184ba451f..4e5920686fc2 100644 --- a/apps/services/form-system/docker-compose.yml +++ b/apps/services/form-system/docker-compose.yml @@ -8,7 +8,7 @@ services: - local environment: - POSTGRES_DB=dev_db - - POSTGRES_USER=postgres + - POSTGRES_USER=dev_db - POSTGRES_PASSWORD=dev_db ports: - 5432:5432 diff --git a/apps/services/form-system/sequelize.config.js b/apps/services/form-system/sequelize.config.js index 0af30bf8fd95..ccb1353c48f3 100644 --- a/apps/services/form-system/sequelize.config.js +++ b/apps/services/form-system/sequelize.config.js @@ -1,7 +1,7 @@ /* eslint-env node */ module.exports = { development: { - username: 'postgres', + username: 'dev_db', password: 'dev_db', database: 'dev_db', host: 'localhost', diff --git a/apps/services/form-system/src/app/enums/fieldTypes.ts b/apps/services/form-system/src/app/enums/fieldTypes.ts new file mode 100644 index 000000000000..7686453d8d44 --- /dev/null +++ b/apps/services/form-system/src/app/enums/fieldTypes.ts @@ -0,0 +1,25 @@ +export const FieldTypes = { + DEFAULT: 'default', + EMAIL: 'email', + PROPERTY_NUMBER: 'propertyNumber', + ISK_NUMBERBOX: 'iskNumberbox', + CHECKBOX: 'checkbox', + DATE_PICKER: 'datePicker', + NUMBERBOX: 'numberbox', + PAYER: 'payer', + NATIONAL_ID_ESTATE: 'nationaIdEstate', + PHONE_NUMBER: 'phoneNumber', + MESSAGE: 'message', + RADIO_BUTTONS: 'radioButtons', + DOCUMENT: 'document', + BANK_ACCOUNT: 'bankAccount', + NATIONAL_ID: 'nationalId', + HOMESTAY_NUMBER: 'homestayNumber', + ISK_SUMBOX: 'iskSumbox', + DROPDOWN_LIST: 'dropdownList', + NATIONAL_ID_ALL: 'nationalIdAll', + TIME_INPUT: 'timeInput', + HOMESTAY_OVERVIEW: 'homestayOverview', + PAYMENT: 'payment', + TEXTBOX: 'textbox', +} diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts index 65136f823583..466b86e92fc5 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicant.model.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { CreationOptional } from 'sequelize' import { Column, @@ -35,7 +35,7 @@ export class Applicant extends Model { type: DataType.DATE, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() lastLogin?: Date @Column({ diff --git a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts index 820098a54078..99f381bc980b 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/applicantTypeNameSuggestion.model.ts @@ -37,7 +37,7 @@ export class ApplicantTypeNameSuggestion extends Model new LanguageType().toString(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) nameSuggestion!: LanguageType @Column({ diff --git a/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts b/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts index 74d385876077..814c9708a48f 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/dto/applicationApplicant.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { ApplicantTypes } from '../../../../enums/applicantTypes' export class ApplicationApplicantDto { @@ -11,7 +11,7 @@ export class ApplicationApplicantDto { @ApiProperty({ type: Date }) modified!: Date - @ApiProperty() + @ApiPropertyOptional() lastLogin?: Date @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts b/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts index 570b3ac8494d..e78a1c50ed5e 100644 --- a/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts +++ b/apps/services/form-system/src/app/modules/applicants/models/dto/formApplicant.dto.ts @@ -1,11 +1,12 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { ApplicantTypes } from '../../../../enums/applicantTypes' export class FormApplicantDto { @ApiProperty() id!: string - @ApiProperty() + @ApiProperty({ enum: ApplicantTypes }) applicantType!: string @ApiProperty({ type: LanguageType }) diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts index 1aa4ba5bed4e..5a68fcf4a38b 100644 --- a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -1,26 +1,26 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { ApplicationSectionDto } from '../../../sections/models/dto/applicationSection.dto' import { OrganizationDto } from '../../../organizations/models/dto/organization.dto' export class ApplicationDto { - @ApiProperty() + @ApiPropertyOptional() applicationId?: string - @ApiProperty() + @ApiPropertyOptional({ type: OrganizationDto }) organization?: OrganizationDto - @ApiProperty() + @ApiPropertyOptional() formId?: string - @ApiProperty() + @ApiPropertyOptional() formUrlName?: string - @ApiProperty() + @ApiPropertyOptional({ type: Date }) created?: Date - @ApiProperty() + @ApiPropertyOptional({ type: Date }) modified?: Date - @ApiProperty({ type: [ApplicationSectionDto] }) + @ApiPropertyOptional({ type: [ApplicationSectionDto] }) sections?: ApplicationSectionDto[] } diff --git a/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts b/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts index 5d36f3348ff0..905e7058eac3 100644 --- a/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/certificationType.model.ts @@ -30,7 +30,7 @@ export class CertificationType extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @Column({ @@ -38,7 +38,7 @@ export class CertificationType extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) description!: LanguageType @Column({ diff --git a/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts b/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts index ad992013f2dd..100ffc4bf5b6 100644 --- a/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/dto/certificationType.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { CertificationTypes } from '../../../../enums/certificationTypes' export class CertificationTypeDto { @ApiProperty() @@ -11,6 +12,6 @@ export class CertificationTypeDto { @ApiProperty({ type: LanguageType }) description!: LanguageType - @ApiProperty() + @ApiProperty({ enum: CertificationTypes }) type!: string } diff --git a/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts b/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts index 0b1d6db6fab1..62d0a0a57be8 100644 --- a/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts +++ b/apps/services/form-system/src/app/modules/certifications/models/dto/formCertificationType.dto.ts @@ -1,5 +1,6 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { CertificationTypes } from '../../../../enums/certificationTypes' export class FormCertificationTypeDto { @ApiProperty() @@ -11,6 +12,6 @@ export class FormCertificationTypeDto { @ApiProperty({ type: LanguageType }) description!: LanguageType - @ApiProperty() + @ApiProperty({ enum: CertificationTypes }) type!: string } diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts index 1b4dde1234c4..c00095df43a9 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts @@ -1,65 +1,65 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { ListItemDto } from '../../../listItems/models/dto/listItem.dto' export class FieldSettingsDto { - @ApiProperty() + @ApiPropertyOptional() minValue?: number - @ApiProperty() + @ApiPropertyOptional() maxValue?: number - @ApiProperty() + @ApiPropertyOptional() minLength?: number - @ApiProperty() + @ApiPropertyOptional() maxLength?: number - @ApiProperty() + @ApiPropertyOptional() minDate?: Date - @ApiProperty() + @ApiPropertyOptional() maxDate?: Date - @ApiProperty() + @ApiPropertyOptional() minAmount?: string - @ApiProperty() + @ApiPropertyOptional() maxAmount?: string - @ApiProperty() + @ApiPropertyOptional() year?: number - @ApiProperty() + @ApiPropertyOptional() hasLink?: boolean - @ApiProperty() + @ApiPropertyOptional() url?: string - @ApiProperty() + @ApiPropertyOptional() buttonText?: string - @ApiProperty() + @ApiPropertyOptional() hasPropertyInput?: boolean - @ApiProperty() + @ApiPropertyOptional() hasPropertyList?: boolean - @ApiProperty({ type: [ListItemDto] }) + @ApiPropertyOptional({ type: [ListItemDto] }) list?: ListItemDto[] - @ApiProperty() + @ApiPropertyOptional() listType?: string - @ApiProperty() + @ApiPropertyOptional() fileTypes?: string - @ApiProperty() + @ApiPropertyOptional() fileMaxSize?: number - @ApiProperty() + @ApiPropertyOptional() maxFiles?: number - @ApiProperty() + @ApiPropertyOptional() timeInterval?: string } diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts index e04b1d1e9649..8008d3dcfb55 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts @@ -1,60 +1,60 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' export class UpdateFieldSettingsDto { - @ApiProperty() + @ApiPropertyOptional() minValue?: number - @ApiProperty() + @ApiPropertyOptional() maxValue?: number - @ApiProperty() + @ApiPropertyOptional() minLength?: number - @ApiProperty() + @ApiPropertyOptional() maxLength?: number - @ApiProperty() + @ApiPropertyOptional() minDate?: Date - @ApiProperty() + @ApiPropertyOptional() maxDate?: Date - @ApiProperty() + @ApiPropertyOptional() minAmount?: string - @ApiProperty() + @ApiPropertyOptional() maxAmount?: string - @ApiProperty() + @ApiPropertyOptional() year?: number - @ApiProperty() + @ApiPropertyOptional() hasLink?: boolean - @ApiProperty() + @ApiPropertyOptional() url?: string - @ApiProperty() + @ApiPropertyOptional() buttonText?: string - @ApiProperty() + @ApiPropertyOptional() hasPropertyInput?: boolean - @ApiProperty() + @ApiPropertyOptional() hasPropertyList?: boolean - @ApiProperty() + @ApiPropertyOptional() listType?: string - @ApiProperty() + @ApiPropertyOptional() fileTypes?: string - @ApiProperty() + @ApiPropertyOptional() fileMaxSize?: number - @ApiProperty() + @ApiPropertyOptional() maxFiles?: number - @ApiProperty() + @ApiPropertyOptional() timeInterval?: string } diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts index 20a362043b96..03f773b73786 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.model.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { CreationOptional } from 'sequelize' import { Column, @@ -38,102 +38,102 @@ export class FieldSettings extends Model { type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() minValue?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() maxValue?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() minLength?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() maxLength?: number | null @Column({ type: DataType.DATE, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() minDate?: Date | null @Column({ type: DataType.DATE, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() maxDate?: Date | null @Column({ type: DataType.STRING, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() minAmount?: string | null @Column({ type: DataType.STRING, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() maxAmount?: string | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() year?: number | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() hasLink?: boolean | null @Column({ type: DataType.STRING, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() url?: string | null @Column({ type: DataType.STRING, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() buttonText?: string | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() hasPropertyInput?: boolean | null @Column({ type: DataType.BOOLEAN, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() hasPropertyList?: boolean | null @HasMany(() => ListItem) - @ApiProperty({ type: [ListItem] }) + @ApiPropertyOptional({ type: [ListItem] }) list?: ListItem[] | null @Column({ @@ -141,28 +141,28 @@ export class FieldSettings extends Model { allowNull: true, values: Object.values(ListTypes), }) - @ApiProperty({ enum: ListTypes }) + @ApiPropertyOptional({ enum: ListTypes }) listType?: string | null @Column({ type: DataType.JSON, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() fileTypes?: string | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() fileMaxSize?: number | null @Column({ type: DataType.INTEGER, allowNull: true, }) - @ApiProperty() + @ApiPropertyOptional() maxFiles?: number | null @Column({ @@ -170,7 +170,7 @@ export class FieldSettings extends Model { allowNull: true, values: Object.values(TimeIntervals), }) - @ApiProperty({ enum: TimeIntervals }) + @ApiPropertyOptional({ enum: TimeIntervals }) timeInterval?: string | null @ForeignKey(() => Field) diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts index d90e973614cd..b17e108d1fd9 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/applicationField.dto.ts @@ -1,6 +1,7 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' +import { FieldTypes } from '../../../../enums/fieldTypes' export class ApplicationFieldDto { @ApiProperty() @@ -21,9 +22,9 @@ export class ApplicationFieldDto { @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: FieldSettingsDto }) + @ApiPropertyOptional({ type: FieldSettingsDto }) fieldSettings?: FieldSettingsDto - @ApiProperty() + @ApiProperty({ enum: FieldTypes }) fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts index 421c752cb53b..676a235e2e72 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/field.dto.ts @@ -1,6 +1,7 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' +import { FieldTypes } from '../../../../enums/fieldTypes' export class FieldDto { @ApiProperty() @@ -21,9 +22,9 @@ export class FieldDto { @ApiProperty() isPartOfMultiset!: boolean - @ApiProperty({ type: FieldSettingsDto }) + @ApiPropertyOptional({ type: FieldSettingsDto }) fieldSettings?: FieldSettingsDto - @ApiProperty() + @ApiProperty({ enum: FieldTypes }) fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts index fbf1132168b3..e89dbfab84d5 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/fieldType.dto.ts @@ -1,12 +1,13 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FieldSettingsDto } from '../../../fieldSettings/models/dto/fieldSettings.dto' +import { FieldTypes } from '../../../../enums/fieldTypes' export class FieldTypeDto { @ApiProperty() id!: string - @ApiProperty() + @ApiProperty({ enum: FieldTypes }) type!: string @ApiProperty({ type: LanguageType }) @@ -18,6 +19,6 @@ export class FieldTypeDto { @ApiProperty() isCommon!: boolean - @ApiProperty({ type: FieldSettingsDto }) + @ApiPropertyOptional({ type: FieldSettingsDto }) fieldSettings?: FieldSettingsDto } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts index 92a4b8a82e28..f1fcd619c923 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts @@ -1,6 +1,7 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { UpdateFieldSettingsDto } from '../../../fieldSettings/models/dto/updateFieldSettings.dto' +import { FieldTypes } from '../../../../enums/fieldTypes' export class UpdateFieldDto { @ApiProperty({ type: LanguageType }) @@ -15,6 +16,6 @@ export class UpdateFieldDto { @ApiProperty({ type: UpdateFieldSettingsDto }) fieldSettings?: UpdateFieldSettingsDto - @ApiProperty() + @ApiProperty({ enum: FieldTypes }) fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/field.model.ts b/apps/services/form-system/src/app/modules/fields/models/field.model.ts index c402d34e2187..eb9f1ed62ecb 100644 --- a/apps/services/form-system/src/app/modules/fields/models/field.model.ts +++ b/apps/services/form-system/src/app/modules/fields/models/field.model.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { CreationOptional } from 'sequelize' import { Column, @@ -31,7 +31,7 @@ export class Field extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @CreatedAt @@ -55,7 +55,7 @@ export class Field extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) description!: LanguageType @Column({ @@ -83,7 +83,7 @@ export class Field extends Model { screenId!: string @HasOne(() => FieldSettings) - @ApiProperty({ type: FieldSettings }) + @ApiPropertyOptional({ type: FieldSettings }) fieldSettings?: FieldSettings @ForeignKey(() => FieldType) diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 70a41d9e7e29..15f4a181569e 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { FormApplicantDto } from '../../../applicants/models/dto/formApplicant.dto' import { ScreenDto } from '../../../screens/models/dto/screen.dto' @@ -19,13 +19,13 @@ export class FormDto { @ApiProperty() urlName!: string - @ApiProperty() + @ApiPropertyOptional({ type: Date }) invalidationDate?: Date - @ApiProperty() + @ApiProperty({ type: Date }) created!: Date - @ApiProperty() + @ApiProperty({ type: Date }) modified!: Date @ApiProperty() @@ -40,21 +40,21 @@ export class FormDto { @ApiProperty() stopProgressOnValidatingScreen!: boolean - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) completedMessage?: LanguageType - @ApiProperty({ type: [FormCertificationTypeDto] }) + @ApiPropertyOptional({ type: [FormCertificationTypeDto] }) certificationTypes?: FormCertificationTypeDto[] - @ApiProperty({ type: [FormApplicantDto] }) + @ApiPropertyOptional({ type: [FormApplicantDto] }) applicants?: FormApplicantDto[] - @ApiProperty({ type: [SectionDto] }) + @ApiPropertyOptional({ type: [SectionDto] }) sections?: SectionDto[] - @ApiProperty({ type: [ScreenDto] }) + @ApiPropertyOptional({ type: [ScreenDto] }) screens?: ScreenDto[] - @ApiProperty({ type: [FieldDto] }) + @ApiPropertyOptional({ type: [FieldDto] }) fields?: FieldDto[] } diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts index 2f0e8fa5949b..e3b037ffcb91 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' export class FormsListFormDto { @@ -11,13 +11,13 @@ export class FormsListFormDto { @ApiProperty() urlName!: string - @ApiProperty() + @ApiPropertyOptional({ type: Date }) invalidationDate?: Date - @ApiProperty() + @ApiProperty({ type: Date }) created!: Date - @ApiProperty() + @ApiProperty({ type: Date }) modified!: Date @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index b125fd58dd2b..a10a9b39a8af 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -11,7 +11,7 @@ import { UpdatedAt, } from 'sequelize-typescript' import { Section } from '../../sections/models/section.model' -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { Organization } from '../../organizations/models/organization.model' import { LanguageType } from '../../../dataTypes/languageType.model' import { FormApplicant } from '../../applicants/models/formApplicant.model' @@ -46,7 +46,7 @@ export class Form extends Model { urlName!: string @Column - @ApiProperty() + @ApiPropertyOptional({ type: Date }) invalidationDate?: Date @CreatedAt @@ -93,7 +93,7 @@ export class Form extends Model { allowNull: true, defaultValue: () => new LanguageType(), }) - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) completedMessage?: LanguageType @HasMany(() => Section) @@ -101,7 +101,7 @@ export class Form extends Model { sections!: Section[] @HasMany(() => FormApplicant) - @ApiProperty({ type: [FormApplicant] }) + @ApiPropertyOptional({ type: [FormApplicant] }) applicants?: FormApplicant[] @ForeignKey(() => Organization) diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts index dbc670b10680..78d4f70585a2 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/listItem.dto.ts @@ -1,14 +1,14 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' export class ListItemDto { @ApiProperty() id!: string - @ApiProperty() + @ApiProperty({ type: LanguageType }) label!: LanguageType - @ApiProperty() + @ApiPropertyOptional({ type: LanguageType }) description?: LanguageType @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts index d1e861cf4b0d..8a56b8bc0116 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts @@ -1,11 +1,11 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' export class UpdateListItemDto { - @ApiProperty() + @ApiProperty({ type: LanguageType }) label!: LanguageType - @ApiProperty() + @ApiPropertyOptional({ type: LanguageType }) description?: LanguageType @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts index 9aface4bc9aa..e13332aacb40 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/listItem.model.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { Column, CreatedAt, @@ -36,7 +36,7 @@ export class ListItem extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) label!: LanguageType @Column({ @@ -44,7 +44,7 @@ export class ListItem extends Model { allowNull: true, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiPropertyOptional({ type: LanguageType }) description?: LanguageType @Column({ diff --git a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts index a91a3d8d12ce..39270c2cebbe 100644 --- a/apps/services/form-system/src/app/modules/lists/models/listType.model.ts +++ b/apps/services/form-system/src/app/modules/lists/models/listType.model.ts @@ -29,7 +29,7 @@ export class ListType extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @Column({ @@ -37,7 +37,7 @@ export class ListType extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) description!: LanguageType @Column({ diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts index 06a9fbfabd32..9926924fe944 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts @@ -3,7 +3,7 @@ import { Organization } from '../organization.model' import { LanguageType } from '../../../../dataTypes/languageType.model' export class OrganizationDto { - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @ApiProperty() diff --git a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts index 526660036a81..28fc5ed8eba8 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/organization.model.ts @@ -33,7 +33,7 @@ export class Organization extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @CreatedAt diff --git a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts index d105bb74a4d7..57ab5448b69e 100644 --- a/apps/services/form-system/src/app/modules/screens/models/screen.model.ts +++ b/apps/services/form-system/src/app/modules/screens/models/screen.model.ts @@ -30,7 +30,7 @@ export class Screen extends Model { allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @CreatedAt diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts index 10117c5a09c3..0e22ed5385ae 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/applicationSection.dto.ts @@ -1,6 +1,7 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { ApplicationScreenDto } from '../../../screens/models/dto/applicationScreen.dto' +import { SectionTypes } from '../../../../enums/sectionTypes' export class ApplicationSectionDto { @ApiProperty() @@ -9,13 +10,13 @@ export class ApplicationSectionDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty() + @ApiProperty({ enum: SectionTypes }) sectionType!: string @ApiProperty() displayOrder!: number - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) waitingText?: LanguageType @ApiProperty({ type: [ApplicationScreenDto] }) diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts index 802ee0ac078c..7dbcc5753ae4 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/section.dto.ts @@ -1,5 +1,6 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { SectionTypes } from '../../../../enums/sectionTypes' export class SectionDto { @ApiProperty() @@ -8,12 +9,12 @@ export class SectionDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty() + @ApiProperty({ enum: SectionTypes }) sectionType!: string @ApiProperty() displayOrder!: number - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) waitingText?: LanguageType } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts index 0f8d1ac63518..940e5ab6efac 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts @@ -1,10 +1,10 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' export class UpdateSectionDto { @ApiProperty({ type: LanguageType }) name!: LanguageType - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) waitingText?: LanguageType } diff --git a/apps/services/form-system/src/app/modules/sections/models/section.model.ts b/apps/services/form-system/src/app/modules/sections/models/section.model.ts index 47f275399d3e..5695b67247c4 100644 --- a/apps/services/form-system/src/app/modules/sections/models/section.model.ts +++ b/apps/services/form-system/src/app/modules/sections/models/section.model.ts @@ -1,4 +1,4 @@ -import { ApiProperty } from '@nestjs/swagger' +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { CreationOptional, DataTypes } from 'sequelize' import { Column, @@ -31,7 +31,7 @@ export class Section extends Model
{ allowNull: false, defaultValue: () => new LanguageType(), }) - @ApiProperty() + @ApiProperty({ type: LanguageType }) name!: LanguageType @CreatedAt @@ -63,7 +63,7 @@ export class Section extends Model
{ allowNull: true, defaultValue: () => new LanguageType(), }) - @ApiProperty({ type: LanguageType }) + @ApiPropertyOptional({ type: LanguageType }) waitingText?: LanguageType @Column({ @@ -83,7 +83,7 @@ export class Section extends Model
{ isCompleted!: boolean @HasMany(() => Screen) - @ApiProperty({ type: [Screen] }) + @ApiPropertyOptional({ type: [Screen] }) screens?: Screen[] @ForeignKey(() => Form) diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index 890020281fcf..7707dbb06781 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -3,24 +3,14 @@ * This is only a minimal backend to get started. */ -import { Logger } from '@nestjs/common' -import { NestFactory } from '@nestjs/core' -import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger' import { AppModule } from './app/app.module' +import { openApi } from './openApi' +import { bootstrap } from '@island.is/infra-nest-server' -const bootstrap = async () => { - const app = await NestFactory.create(AppModule) - - const config = new DocumentBuilder() - .setTitle('Form System Api') - .setVersion('1.0') - .build() - const document = SwaggerModule.createDocument(app, config) - SwaggerModule.setup('api', app, document) - - const port = process.env.PORT || 3000 - await app.listen(port) - Logger.log(`🚀 Application is running on: http://localhost:${port}`) -} - -bootstrap() +bootstrap({ + appModule: AppModule, + name: 'services-form-system', + openApi, + swaggerPath: 'api/swagger', + port: 3434, +}) diff --git a/apps/services/form-system/src/openApi.ts b/apps/services/form-system/src/openApi.ts new file mode 100644 index 000000000000..fbeb5dc59da3 --- /dev/null +++ b/apps/services/form-system/src/openApi.ts @@ -0,0 +1,8 @@ +import { DocumentBuilder } from '@nestjs/swagger' + +export const openApi = new DocumentBuilder() + .setTitle('Form System API') + .setDescription('Formbuilder and form-rendering (application) system') + .addServer(process.env.PUBLIC_URL ?? 'http://localhost:3434') + .setVersion('1.0') + .build() diff --git a/libs/api/domains/form-system/.vscode/settings.json b/libs/api/domains/form-system/.vscode/settings.json deleted file mode 100644 index e82e18462638..000000000000 --- a/libs/api/domains/form-system/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "workbench.colorTheme": "Default Dark+" -} diff --git a/package.json b/package.json index 1cf784754375..265683cff8bd 100644 --- a/package.json +++ b/package.json @@ -427,7 +427,7 @@ "dotenv": "16.3.1", "esbuild": "0.15.7", "eslint": "8.46.0", - "eslint-config-next": "13.4.1", + "eslint-config-next": "13.1.1", "eslint-config-prettier": "8.1.0", "eslint-plugin-cypress": "2.14.0", "eslint-plugin-import": "2.27.5", @@ -449,7 +449,6 @@ "next-secure-headers": "2.1.0", "nx": "16.9.0", "prettier": "2.6.2", - "sass": "1.62.1", "sequelize-cli": "6.4.1", "sort-paths": "1.1.1", "sqlite3": "5.1.6", From c6e22313ebf46cba2d11f83db29f22b4b92e5a87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Tue, 2 Jul 2024 14:15:31 +0000 Subject: [PATCH 52/72] changed naming of urlName to slug --- .../migrations/20240605120322-create-form.js | 2 +- .../modules/applications/applications.controller.ts | 8 +++----- .../app/modules/applications/applications.service.ts | 11 +++++------ .../modules/applications/models/application.mapper.ts | 2 +- .../applications/models/dto/application.dto.ts | 2 +- .../src/app/modules/forms/forms.service.ts | 2 +- .../src/app/modules/forms/models/dto/form.dto.ts | 2 +- .../app/modules/forms/models/dto/formsListForm.dto.ts | 2 +- .../src/app/modules/forms/models/form.mapper.ts | 2 +- .../src/app/modules/forms/models/form.model.ts | 2 +- 10 files changed, 16 insertions(+), 19 deletions(-) diff --git a/apps/services/form-system/migrations/20240605120322-create-form.js b/apps/services/form-system/migrations/20240605120322-create-form.js index 0404c0ded228..11fabda5ec94 100644 --- a/apps/services/form-system/migrations/20240605120322-create-form.js +++ b/apps/services/form-system/migrations/20240605120322-create-form.js @@ -16,7 +16,7 @@ module.exports = { type: Sequelize.JSON, allowNull: false, }, - url_name: { + slug: { type: Sequelize.STRING, allowNull: false, unique: true, diff --git a/apps/services/form-system/src/app/modules/applications/applications.controller.ts b/apps/services/form-system/src/app/modules/applications/applications.controller.ts index e07f48ceacfc..be35b989d696 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.controller.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.controller.ts @@ -22,10 +22,8 @@ export class ApplicationsController { description: 'Create new application', response: { status: 200, type: ApplicationDto }, }) - @Post(':formUrlName') - async create( - @Param('formUrlName') formUrlName: string, - ): Promise { - return this.applicationsService.create(formUrlName) + @Post(':slug') + async create(@Param('slug') slug: string): Promise { + return this.applicationsService.create(slug) } } diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts index cc9b8460b93f..92e56d4c8cce 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.service.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -22,8 +22,8 @@ export class ApplicationsService { private readonly applicationMapper: ApplicationMapper, ) {} - async create(formUrlName: string): Promise { - const form: Form = await this.getForm(formUrlName) + async create(slug: string): Promise { + const form: Form = await this.getForm(slug) const newApplication: Application = await this.applicationModel.create({ formId: form.id, @@ -40,10 +40,9 @@ export class ApplicationsService { return new ApplicationDto() } - private async getForm(urlName: string): Promise { - console.log('urlName', urlName) + private async getForm(slug: string): Promise { const form = await this.formModel.findOne({ - where: { urlName: urlName }, + where: { slug: slug }, include: [ { model: Section, @@ -93,7 +92,7 @@ export class ApplicationsService { }) if (!form) { - throw new NotFoundException(`Form with urlName '${urlName}' not found`) + throw new NotFoundException(`Form with slug '${slug}' not found`) } return form diff --git a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts index 68cc5507212b..570bfd459db3 100644 --- a/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts +++ b/apps/services/form-system/src/app/modules/applications/models/application.mapper.ts @@ -18,7 +18,7 @@ export class ApplicationMapper { const applicationDto: ApplicationDto = { applicationId: application.id, formId: form.id, - formUrlName: form.urlName, + slug: form.slug, organization: new OrganizationDto(), sections: [], } diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts index 5a68fcf4a38b..b75cfb6818fd 100644 --- a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -13,7 +13,7 @@ export class ApplicationDto { formId?: string @ApiPropertyOptional() - formUrlName?: string + slug?: string @ApiPropertyOptional({ type: Date }) created?: Date diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index f69f3e0126bc..4d7b9b84d168 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -239,7 +239,7 @@ export class FormsService { id: form.id, organizationId: form.organizationId, name: form.name, - urlName: form.urlName, + slug: form.slug, invalidationDate: form.invalidationDate, created: form.created, modified: form.modified, diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts index 15f4a181569e..fc0ff2eac177 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/form.dto.ts @@ -17,7 +17,7 @@ export class FormDto { name!: LanguageType @ApiProperty() - urlName!: string + slug!: string @ApiPropertyOptional({ type: Date }) invalidationDate?: Date diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts index e3b037ffcb91..f5734e5b7e73 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/formsListForm.dto.ts @@ -9,7 +9,7 @@ export class FormsListFormDto { name!: LanguageType @ApiProperty() - urlName!: string + slug!: string @ApiPropertyOptional({ type: Date }) invalidationDate?: Date diff --git a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts index 9db6d94e8448..5706427027bc 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts @@ -10,7 +10,7 @@ export class FormMapper { return { id: form.id, name: form.name, - urlName: form.urlName, + slug: form.slug, invalidationDate: form.invalidationDate, created: form.created, modified: form.modified, diff --git a/apps/services/form-system/src/app/modules/forms/models/form.model.ts b/apps/services/form-system/src/app/modules/forms/models/form.model.ts index a10a9b39a8af..fcc9d33c7784 100644 --- a/apps/services/form-system/src/app/modules/forms/models/form.model.ts +++ b/apps/services/form-system/src/app/modules/forms/models/form.model.ts @@ -43,7 +43,7 @@ export class Form extends Model { unique: true, defaultValue: randomUUID(), }) - urlName!: string + slug!: string @Column @ApiPropertyOptional({ type: Date }) From 6000f59f0b26c53f3036f7bb1e8d23cb2aad2b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Thu, 4 Jul 2024 12:29:58 +0000 Subject: [PATCH 53/72] introduce lodash pick --- .../fieldSettings/fieldSettings.service.ts | 2 + .../models/dto/fieldSettings.dto.ts | 52 +-------- .../models/dto/updateFieldSettings.dto.ts | 64 +---------- .../models/fieldSettings.mapper.ts | 106 ++++++++---------- .../fieldSettings/models/fieldSettingsKeys.ts | 21 ++++ .../src/app/modules/forms/forms.controller.ts | 7 +- .../src/app/modules/forms/forms.service.ts | 1 + apps/services/form-system/src/main.ts | 38 +++++-- apps/services/form-system/src/openApi.ts | 2 +- 9 files changed, 109 insertions(+), 184 deletions(-) create mode 100644 apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettingsKeys.ts diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts index 554e8fddc0d7..eb8d267f187a 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts @@ -5,6 +5,8 @@ import { InjectModel } from '@nestjs/sequelize' import { FieldSettingsMapper } from './models/fieldSettings.mapper' import { FieldSettingsDto } from './models/dto/fieldSettings.dto' import { ListItem } from '../listItems/models/listItem.model' +import { defaults, keys, keysIn, pick, zipObject } from 'lodash' +import { FieldSettingsKeys } from './models/fieldSettingsKeys' @Injectable() export class FieldSettingsService { diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts index c00095df43a9..945b6d3d7b2b 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/fieldSettings.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { ApiPropertyOptional } from '@nestjs/swagger' import { ListItemDto } from '../../../listItems/models/dto/listItem.dto' export class FieldSettingsDto { @@ -62,53 +62,3 @@ export class FieldSettingsDto { @ApiPropertyOptional() timeInterval?: string } - -export class TextboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'maxLength' | 'minLength' ->) {} - -export class NumberboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'maxLength' | 'minLength' | 'minValue' | 'maxValue' ->) {} - -export class MessageFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'hasLink' | 'url' | 'buttonText' ->) {} - -export class DatePickerFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'minDate' | 'maxDate' ->) {} - -export class DropdownListFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'list' | 'listType' ->) {} - -export class RadioButtonsFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'list' ->) {} - -export class IskNumberboxFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'minAmount' | 'maxAmount' ->) {} - -export class PropertyNumberFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'hasPropertyInput' | 'hasPropertyList' ->) {} - -export class DocumentFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'fileTypes' | 'fileMaxSize' | 'maxFiles' ->) {} - -export class TimeInputFieldSettingsDto extends (FieldSettingsDto as new () => Pick< - FieldSettingsDto, - 'timeInterval' ->) {} diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts index 8008d3dcfb55..ca6c2ad14046 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts @@ -1,60 +1,6 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { OmitType } from '@nestjs/swagger' +import { FieldSettingsDto } from './fieldSettings.dto' -export class UpdateFieldSettingsDto { - @ApiPropertyOptional() - minValue?: number - - @ApiPropertyOptional() - maxValue?: number - - @ApiPropertyOptional() - minLength?: number - - @ApiPropertyOptional() - maxLength?: number - - @ApiPropertyOptional() - minDate?: Date - - @ApiPropertyOptional() - maxDate?: Date - - @ApiPropertyOptional() - minAmount?: string - - @ApiPropertyOptional() - maxAmount?: string - - @ApiPropertyOptional() - year?: number - - @ApiPropertyOptional() - hasLink?: boolean - - @ApiPropertyOptional() - url?: string - - @ApiPropertyOptional() - buttonText?: string - - @ApiPropertyOptional() - hasPropertyInput?: boolean - - @ApiPropertyOptional() - hasPropertyList?: boolean - - @ApiPropertyOptional() - listType?: string - - @ApiPropertyOptional() - fileTypes?: string - - @ApiPropertyOptional() - fileMaxSize?: number - - @ApiPropertyOptional() - maxFiles?: number - - @ApiPropertyOptional() - timeInterval?: string -} +export class UpdateFieldSettingsDto extends OmitType(FieldSettingsDto, [ + 'list', +] as const) {} diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts index 512478641879..42aef3d88076 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -1,20 +1,10 @@ import { Injectable } from '@nestjs/common' import { UpdateFieldSettingsDto } from './dto/updateFieldSettings.dto' import { FieldSettings } from './fieldSettings.model' -import { - DatePickerFieldSettingsDto, - DocumentFieldSettingsDto, - DropdownListFieldSettingsDto, - FieldSettingsDto, - IskNumberboxFieldSettingsDto, - MessageFieldSettingsDto, - NumberboxFieldSettingsDto, - PropertyNumberFieldSettingsDto, - RadioButtonsFieldSettingsDto, - TextboxFieldSettingsDto, - TimeInputFieldSettingsDto, -} from './dto/fieldSettings.dto' +import { FieldSettingsDto } from './dto/fieldSettings.dto' import { ListItemMapper } from '../../listItems/models/listItem.mapper' +import { defaults, pick, zipObject } from 'lodash' +import { ListItemDto } from '../../listItems/models/dto/listItem.dto' @Injectable() export class FieldSettingsMapper { @@ -48,70 +38,62 @@ export class FieldSettingsMapper { } mapFieldTypeToFieldSettingsDto( - fieldSettings: FieldSettings | null | undefined, + fieldSettings: FieldSettings | undefined | null, fieldType: string, ): FieldSettingsDto { + let keys: string[] switch (fieldType) { case 'textbox': - return { - maxLength: fieldSettings ? fieldSettings.maxLength : null, - minLength: fieldSettings ? fieldSettings.minLength : null, - } as TextboxFieldSettingsDto + keys = ['minLength', 'maxLength'] + return this.pickSettings(fieldSettings, keys) case 'numberbox': - return { - maxLength: fieldSettings ? fieldSettings.maxLength : null, - minLength: fieldSettings ? fieldSettings.minLength : null, - maxValue: fieldSettings ? fieldSettings.maxValue : null, - minValue: fieldSettings ? fieldSettings.minValue : null, - } as NumberboxFieldSettingsDto + keys = ['minLength', 'maxLength', 'minValue', 'maxValue'] + return this.pickSettings(fieldSettings, keys) case 'message': - return { - hasLink: fieldSettings ? fieldSettings.hasLink : null, - url: fieldSettings ? fieldSettings.url : null, - buttonText: fieldSettings ? fieldSettings.buttonText : null, - } as MessageFieldSettingsDto + keys = ['hasLink', 'url', 'buttonText'] + return this.pickSettings(fieldSettings, keys) case 'datePicker': - return { - minDate: fieldSettings ? fieldSettings.minDate : null, - maxDate: fieldSettings ? fieldSettings.maxDate : null, - } as DatePickerFieldSettingsDto + keys = ['minDate', 'maxDate'] + return this.pickSettings(fieldSettings, keys) case 'dropdownList': - return { - list: fieldSettings?.list - ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) - : '', - listType: fieldSettings?.listType ? fieldSettings.listType : '', - } as DropdownListFieldSettingsDto + keys = ['list', 'listType'] + const dropdownListFieldSettings = this.pickSettings(fieldSettings, keys) + dropdownListFieldSettings.list = fieldSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) + : [] + return dropdownListFieldSettings case 'radioButtons': - return { - list: fieldSettings?.list - ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) - : null, - } as RadioButtonsFieldSettingsDto + keys = ['list'] + const radioButtonsFieldSettings = this.pickSettings(fieldSettings, keys) + radioButtonsFieldSettings.list = fieldSettings?.list + ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) + : [] + return radioButtonsFieldSettings case 'iskNumberbox': - return { - minAmount: fieldSettings ? fieldSettings.minAmount : null, - maxAmount: fieldSettings ? fieldSettings.maxAmount : null, - } as IskNumberboxFieldSettingsDto + keys = ['minAmount', 'maxAmount'] + return this.pickSettings(fieldSettings, keys) case 'propertyNumber': - return { - hasPropertyInput: fieldSettings - ? fieldSettings.hasPropertyInput - : null, - hasPropertyList: fieldSettings ? fieldSettings.hasPropertyList : null, - } as PropertyNumberFieldSettingsDto + keys = ['hasPropertyInput', 'hasPropertyList'] + return this.pickSettings(fieldSettings, keys) case 'document': - return { - fileTypes: fieldSettings ? fieldSettings.fileTypes : null, - fileMaxSize: fieldSettings ? fieldSettings.fileMaxSize : null, - maxFiles: fieldSettings ? fieldSettings.maxFiles : null, - } as DocumentFieldSettingsDto + keys = ['fileTypes', 'fileMaxSize', 'maxFiles'] + return this.pickSettings(fieldSettings, keys) case 'timeInput': - return { - timeInterval: fieldSettings ? fieldSettings.timeInterval : null, - } as TimeInputFieldSettingsDto + keys = ['timeInterval'] + return this.pickSettings(fieldSettings, keys) default: return {} } } + + private pickSettings = ( + obj: FieldSettings | undefined | null, + keys: string[], + defaultValue = null, + ): FieldSettingsDto => { + return defaults( + pick(obj, keys), + zipObject(keys, Array(keys.length).fill(defaultValue)), + ) as FieldSettingsDto + } } diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettingsKeys.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettingsKeys.ts new file mode 100644 index 000000000000..5712218fae9c --- /dev/null +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettingsKeys.ts @@ -0,0 +1,21 @@ +export const FieldSettingsKeys = [ + 'minValue', + 'maxValue', + 'minLength', + 'maxLength', + 'minDate', + 'maxDate', + 'minAmount', + 'maxAmount', + 'year', + 'hasLink', + 'url', + 'buttonText', + 'hasPropertyInput', + 'hasPropertyList', + 'listType', + 'fileTypes', + 'fileMaxSize', + 'maxFiles', + 'timeInterval', +] diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 8419b38e8218..523cd0de0cc4 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -8,7 +8,7 @@ import { Param, Post, } from '@nestjs/common' -import { ApiTags } from '@nestjs/swagger' +import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger' import { FormsService } from './forms.service' import { CreateFormDto } from './models/dto/createForm.dto' import { FormResponse } from './models/dto/form.response.dto' @@ -20,11 +20,12 @@ export class FormsController { constructor(private readonly formsService: FormsService) {} @Post() - @Documentation({ + @ApiCreatedResponse({ + type: FormResponse, description: 'Create new form', - response: { status: 200, type: FormResponse }, }) async create(@Body() createFormDto: CreateFormDto): Promise { + console.log('blee') const formResponse = await this.formsService.create(createFormDto) if (!formResponse) { throw new Error('Error') diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 4d7b9b84d168..14752d967e59 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -68,6 +68,7 @@ export class FormsService { } async create(createFormDto: CreateFormDto): Promise { + console.log('halló') const { organizationId } = createFormDto if (!organizationId) { diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index 7707dbb06781..48e02e2088db 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -3,14 +3,36 @@ * This is only a minimal backend to get started. */ +import { NestFactory } from '@nestjs/core' import { AppModule } from './app/app.module' import { openApi } from './openApi' -import { bootstrap } from '@island.is/infra-nest-server' +import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' +import { Logger } from '@nestjs/common' +// import { bootstrap } from '@island.is/infra-nest-server' -bootstrap({ - appModule: AppModule, - name: 'services-form-system', - openApi, - swaggerPath: 'api/swagger', - port: 3434, -}) +const bootstrap = async () => { + const app = await NestFactory.create(AppModule) + + const config = new DocumentBuilder() + .setTitle('FormSystem Api') + .setDescription('Api for FormSystem.') + .setVersion('1.0') + .addTag('form-system-api') + .build() + const document = SwaggerModule.createDocument(app, config) + SwaggerModule.setup('api', app, document) + + const port = process.env.PORT || 3000 + await app.listen(port) + Logger.log(`🚀 Application is running on: http://localhost:${port}`) +} + +bootstrap() + +// bootstrap({ +// appModule: AppModule, +// name: 'services-form-system', +// openApi, +// swaggerPath: 'api', +// port: 3000, +// }) diff --git a/apps/services/form-system/src/openApi.ts b/apps/services/form-system/src/openApi.ts index fbeb5dc59da3..02373b4706db 100644 --- a/apps/services/form-system/src/openApi.ts +++ b/apps/services/form-system/src/openApi.ts @@ -3,6 +3,6 @@ import { DocumentBuilder } from '@nestjs/swagger' export const openApi = new DocumentBuilder() .setTitle('Form System API') .setDescription('Formbuilder and form-rendering (application) system') - .addServer(process.env.PUBLIC_URL ?? 'http://localhost:3434') + .addServer(process.env.PUBLIC_URL ?? 'http://localhost:3000') .setVersion('1.0') .build() From 976f897e90eed87ee5b0360d1f5f42492c9b0233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 5 Jul 2024 15:08:15 +0000 Subject: [PATCH 54/72] refactor vegna PR --- .../applications/applications.controller.ts | 4 +- .../applications/applications.service.ts | 2 - .../models/dto/application.dto.ts | 2 +- .../fieldSettings/fieldSettings.service.ts | 2 - .../models/fieldSettings.mapper.ts | 1 - .../app/modules/fields/fields.controller.ts | 3 +- .../src/app/modules/forms/forms.controller.ts | 3 +- .../src/app/modules/forms/forms.module.ts | 3 +- .../src/app/modules/forms/forms.service.ts | 300 +++++++++++------- .../app/modules/forms/models/form.mapper.ts | 29 -- .../modules/listItems/listItems.controller.ts | 12 +- .../models/dto/organization.dto.ts | 3 +- .../organizations/organizations.controller.ts | 3 +- .../app/modules/screens/screens.controller.ts | 3 +- .../modules/sections/sections.controller.ts | 3 +- .../app/modules/translations/form/create.ts | 8 + .../app/modules/translations/form/index.ts | 1 + .../modules/translations/section/create.ts | 5 + .../app/modules/translations/section/index.ts | 1 + apps/services/form-system/src/main.ts | 46 +-- apps/services/form-system/src/openApi.ts | 6 +- 21 files changed, 247 insertions(+), 193 deletions(-) delete mode 100644 apps/services/form-system/src/app/modules/forms/models/form.mapper.ts create mode 100644 apps/services/form-system/src/app/modules/translations/form/create.ts create mode 100644 apps/services/form-system/src/app/modules/translations/form/index.ts create mode 100644 apps/services/form-system/src/app/modules/translations/section/create.ts create mode 100644 apps/services/form-system/src/app/modules/translations/section/index.ts diff --git a/apps/services/form-system/src/app/modules/applications/applications.controller.ts b/apps/services/form-system/src/app/modules/applications/applications.controller.ts index be35b989d696..68cf4867c84e 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.controller.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.controller.ts @@ -1,11 +1,11 @@ -import { Controller, Get, Param, Post } from '@nestjs/common' +import { Controller, Get, Param, Post, VERSION_NEUTRAL } from '@nestjs/common' import { ApiTags } from '@nestjs/swagger' import { ApplicationsService } from './applications.service' import { ApplicationDto } from './models/dto/application.dto' import { Documentation } from '@island.is/nest/swagger' @ApiTags('applications') -@Controller('applications') +@Controller({ path: 'applications', version: ['1', VERSION_NEUTRAL] }) export class ApplicationsController { constructor(private readonly applicationsService: ApplicationsService) {} diff --git a/apps/services/form-system/src/app/modules/applications/applications.service.ts b/apps/services/form-system/src/app/modules/applications/applications.service.ts index 92e56d4c8cce..ae331a713170 100644 --- a/apps/services/form-system/src/app/modules/applications/applications.service.ts +++ b/apps/services/form-system/src/app/modules/applications/applications.service.ts @@ -3,8 +3,6 @@ import { InjectModel } from '@nestjs/sequelize' import { Application } from './models/application.model' import { ApplicationDto } from './models/dto/application.dto' import { Form } from '../forms/models/form.model' -import { FormsService } from '../forms/forms.service' -import { FormDto } from '../forms/models/dto/form.dto' import { Section } from '../sections/models/section.model' import { FieldSettings } from '../fieldSettings/models/fieldSettings.model' import { ListItem } from '../listItems/models/listItem.model' diff --git a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts index b75cfb6818fd..0f17620ee08c 100644 --- a/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts +++ b/apps/services/form-system/src/app/modules/applications/models/dto/application.dto.ts @@ -1,4 +1,4 @@ -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' +import { ApiPropertyOptional } from '@nestjs/swagger' import { ApplicationSectionDto } from '../../../sections/models/dto/applicationSection.dto' import { OrganizationDto } from '../../../organizations/models/dto/organization.dto' diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts index eb8d267f187a..554e8fddc0d7 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.ts @@ -5,8 +5,6 @@ import { InjectModel } from '@nestjs/sequelize' import { FieldSettingsMapper } from './models/fieldSettings.mapper' import { FieldSettingsDto } from './models/dto/fieldSettings.dto' import { ListItem } from '../listItems/models/listItem.model' -import { defaults, keys, keysIn, pick, zipObject } from 'lodash' -import { FieldSettingsKeys } from './models/fieldSettingsKeys' @Injectable() export class FieldSettingsService { diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts index 42aef3d88076..659ab3d429ef 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -4,7 +4,6 @@ import { FieldSettings } from './fieldSettings.model' import { FieldSettingsDto } from './dto/fieldSettings.dto' import { ListItemMapper } from '../../listItems/models/listItem.mapper' import { defaults, pick, zipObject } from 'lodash' -import { ListItemDto } from '../../listItems/models/dto/listItem.dto' @Injectable() export class FieldSettingsMapper { diff --git a/apps/services/form-system/src/app/modules/fields/fields.controller.ts b/apps/services/form-system/src/app/modules/fields/fields.controller.ts index 52d9a3011bd8..15396cb78d60 100644 --- a/apps/services/form-system/src/app/modules/fields/fields.controller.ts +++ b/apps/services/form-system/src/app/modules/fields/fields.controller.ts @@ -7,6 +7,7 @@ import { Param, Post, Put, + VERSION_NEUTRAL, } from '@nestjs/common' import { FieldsService } from './fields.service' import { Field } from './models/field.model' @@ -18,7 +19,7 @@ import { FieldDto } from './models/dto/field.dto' import { UpdateFieldsDisplayOrderDto } from './models/dto/updateFieldsDisplayOrder.dto' @ApiTags('fields') -@Controller('fields') +@Controller({ path: 'fields', version: ['1', VERSION_NEUTRAL] }) export class FieldsController { constructor(private readonly fieldsService: FieldsService) {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.controller.ts b/apps/services/form-system/src/app/modules/forms/forms.controller.ts index 523cd0de0cc4..51b296e3cc2d 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.controller.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.controller.ts @@ -7,6 +7,7 @@ import { NotFoundException, Param, Post, + VERSION_NEUTRAL, } from '@nestjs/common' import { ApiCreatedResponse, ApiTags } from '@nestjs/swagger' import { FormsService } from './forms.service' @@ -15,7 +16,7 @@ import { FormResponse } from './models/dto/form.response.dto' import { FormsListDto } from './models/dto/formsList.dto' @ApiTags('forms') -@Controller('forms') +@Controller({ path: 'forms', version: ['1', VERSION_NEUTRAL] }) export class FormsController { constructor(private readonly formsService: FormsService) {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.module.ts b/apps/services/form-system/src/app/modules/forms/forms.module.ts index c6d4de84da6e..5e5da2423b84 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.module.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.module.ts @@ -13,7 +13,6 @@ import { FormsService } from './forms.service' import { Form } from './models/form.model' import { ListItemMapper } from '../listItems/models/listItem.mapper' import { ListItem } from '../listItems/models/listItem.model' -import { FormMapper } from './models/form.mapper' @Module({ imports: [ @@ -30,6 +29,6 @@ import { FormMapper } from './models/form.mapper' ]), ], controllers: [FormsController], - providers: [FormsService, FieldSettingsMapper, ListItemMapper, FormMapper], + providers: [FormsService, FieldSettingsMapper, ListItemMapper], }) export class FormsModule {} diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index 14752d967e59..dcfee0a9d071 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -24,7 +24,10 @@ import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' import { ListItem } from '../listItems/models/listItem.model' import { FormsListDto } from './models/dto/formsList.dto' -import { FormMapper } from './models/form.mapper' +import { defaults, pick, zipObject } from 'lodash' +import { FormsListFormDto } from './models/dto/formsListForm.dto' +import { createFormTranslations } from '../translations/form' +import { createSectionTranslations } from '../translations/section' @Injectable() export class FormsService { @@ -42,7 +45,6 @@ export class FormsService { @InjectModel(ListType) private readonly listTypeModel: typeof ListType, private readonly fieldSettingsMapper: FieldSettingsMapper, - private readonly formMapper: FormMapper, ) {} async findAll(organizationId: string): Promise { @@ -50,8 +52,26 @@ export class FormsService { where: { organizationId: organizationId }, }) - const formsListDto: FormsListDto = - this.formMapper.mapFormsToFormsListDto(forms) + const keys = [ + 'id', + 'name', + 'slug', + 'invalidationDate', + 'created', + 'modified', + 'isTranslated', + 'applicationDaysToRemove', + 'stopProgressOnValidatingScreen', + ] + + const formsListDto: FormsListDto = { + forms: forms.map((form) => { + return defaults( + pick(form, keys), + zipObject(keys, Array(keys.length).fill(null)), + ) as FormsListFormDto + }), + } return formsListDto } @@ -68,7 +88,6 @@ export class FormsService { } async create(createFormDto: CreateFormDto): Promise { - console.log('halló') const { organizationId } = createFormDto if (!organizationId) { @@ -165,13 +184,14 @@ export class FormsService { const certificationTypesDto: CertificationTypeDto[] = [] + const keys = ['id', 'type', 'name', 'description'] organizationCertificationTypes?.map((certificationType) => { - certificationTypesDto.push({ - id: certificationType.id, - type: certificationType.type, - name: certificationType.name, - description: certificationType.description, - } as CertificationTypeDto) + certificationTypesDto.push( + defaults( + pick(certificationType, keys), + zipObject(keys, Array(keys.length).fill(null)), + ) as CertificationTypeDto, + ) }) return certificationTypesDto @@ -191,18 +211,23 @@ export class FormsService { ) const fieldTypesDto: FieldTypeDto[] = [] + const keys = ['id', 'type', 'name', 'description', 'isCommon'] organizationFieldTypes.map((fieldType) => { - fieldTypesDto.push({ - id: fieldType.id, - type: fieldType.type, - name: fieldType.name, - description: fieldType.description, - isCommon: fieldType.isCommon, - fieldSettings: this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( - null, - fieldType.type, - ), - } as FieldTypeDto) + fieldTypesDto.push( + Object.assign( + defaults( + pick(fieldType, keys), + zipObject(keys, Array(keys.length).fill(null)), + ), + { + fieldSettings: + this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( + null, + fieldType.type, + ), + }, + ) as FieldTypeDto, + ) }) return fieldTypesDto @@ -222,99 +247,134 @@ export class FormsService { ) const listTypesDto: ListTypeDto[] = [] + const keys = ['id', 'type', 'name', 'description', 'isCommon'] organizationListTypes.map((listType) => { - listTypesDto.push({ - id: listType.id, - type: listType.type, - name: listType.name, - description: listType.description, - isCommon: listType.isCommon, - } as ListTypeDto) + listTypesDto.push( + defaults( + pick(listType, keys), + zipObject(keys, Array(keys.length).fill(null)), + ) as ListTypeDto, + ) }) return listTypesDto } private setArrays(form: Form): FormDto { - const formDto: FormDto = { - id: form.id, - organizationId: form.organizationId, - name: form.name, - slug: form.slug, - invalidationDate: form.invalidationDate, - created: form.created, - modified: form.modified, - isTranslated: form.isTranslated, - applicationDaysToRemove: form.applicationDaysToRemove, - derivedFrom: form.derivedFrom, - stopProgressOnValidatingScreen: form.stopProgressOnValidatingScreen, - completedMessage: form.completedMessage, - certificationTypes: [], - applicants: [], - sections: [], - screens: [], - fields: [], - } - + const formKeys = [ + 'id', + 'organizationId', + 'name', + 'slug', + 'invalidationDate', + 'created', + 'modified', + 'isTranslated', + 'applicationDaysToRemove', + 'stopProgressOnValidatingScreen', + 'completedMessage', + ] + const formDto: FormDto = Object.assign( + defaults( + pick(form, formKeys), + zipObject(formKeys, Array(formKeys.length).fill(null)), + ), + { + certificationTypes: [], + applicants: [], + sections: [], + screens: [], + fields: [], + }, + ) as FormDto + + const formCertificationTypeKeys = ['id', 'name', 'description', 'type'] form.certificationTypes?.map((certificationType) => { - formDto.certificationTypes?.push({ - id: certificationType.id, - name: certificationType.name, - description: certificationType.description, - type: certificationType.type, - } as FormCertificationTypeDto) + formDto.certificationTypes?.push( + defaults( + pick(certificationType, formCertificationTypeKeys), + zipObject( + formCertificationTypeKeys, + Array(formCertificationTypeKeys.length).fill(null), + ), + ) as FormCertificationTypeDto, + ) }) + const applicantKeys = ['id', 'applicantType', 'name'] form.applicants?.map((applicant) => { - formDto.applicants?.push({ - id: applicant.id, - applicantType: applicant.applicantType, - name: applicant.name, - } as FormApplicantDto) + formDto.applicants?.push( + defaults( + pick(applicant, applicantKeys), + zipObject(applicantKeys, Array(applicantKeys.length).fill(null)), + ) as FormApplicantDto, + ) }) + const sectionKeys = [ + 'id', + 'name', + 'created', + 'modified', + 'sectionType', + 'displayOrder', + 'waitingText', + 'isHidden', + 'isCompleted', + ] + const screenKeys = [ + 'id', + 'sectionId', + 'name', + 'created', + 'modified', + 'displayOrder', + 'isHidden', + 'multiset', + 'callRuleset', + ] + const fieldKeys = [ + 'id', + 'screenId', + 'name', + 'created', + 'modified', + 'displayOrder', + 'description', + 'isHidden', + 'isPartOfMultiset', + 'fieldType', + ] form.sections.map((section) => { - formDto.sections?.push({ - id: section.id, - name: section.name, - created: section.created, - modified: section.modified, - sectionType: section.sectionType, - displayOrder: section.displayOrder, - waitingText: section.waitingText, - isHidden: section.isHidden, - isCompleted: section.isCompleted, - } as SectionDto) + formDto.sections?.push( + defaults( + pick(section, sectionKeys), + zipObject(sectionKeys, Array(sectionKeys.length).fill(null)), + ) as SectionDto, + ) section.screens?.map((screen) => { - formDto.screens?.push({ - id: screen.id, - sectionId: section.id, - name: screen.name, - created: screen.created, - modified: screen.modified, - displayOrder: screen.displayOrder, - isHidden: screen.isHidden, - multiset: screen.multiset, - callRuleset: screen.callRuleset, - } as ScreenDto) + formDto.screens?.push( + defaults( + pick(screen, screenKeys), + zipObject(screenKeys, Array(screenKeys.length).fill(null)), + ) as ScreenDto, + ) screen.fields?.map((field) => { - formDto.fields?.push({ - id: field.id, - screenId: screen.id, - name: field.name, - created: field.created, - modified: field.modified, - displayOrder: field.displayOrder, - description: field.description, - isHidden: field.isHidden, - isPartOfMultiset: field.isPartOfMultiset, - fieldSettings: - this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( - field.fieldSettings, - field.fieldType, + formDto.fields?.push( + Object.assign( + defaults( + pick(field, fieldKeys), + zipObject(fieldKeys, Array(fieldKeys.length).fill(null)), ), - fieldType: field.fieldType, - } as FieldDto) + { + fieldSettings: + this.fieldSettingsMapper.mapFieldTypeToFieldSettingsDto( + field.fieldSettings, + field.fieldType, + ), + }, + ) as FieldDto, + ) }) }) }) @@ -323,38 +383,38 @@ export class FormsService { } private async createFormTemplate(form: Form): Promise { - await this.sectionModel.create({ - formId: form.id, - sectionType: SectionTypes.PREMISES, - displayOrder: 0, - name: { is: 'Forsendur', en: 'Premises' }, - } as Section) - - await this.sectionModel.create({ - formId: form.id, - sectionType: SectionTypes.PARTIES, - displayOrder: 1, - name: { is: 'Hlutaðeigandi aðilar', en: 'Relevant parties' }, - } as Section) + await this.sectionModel.bulkCreate([ + { + formId: form.id, + sectionType: SectionTypes.PREMISES, + displayOrder: 0, + name: createFormTranslations.premise, + } as Section, + { + formId: form.id, + sectionType: SectionTypes.PARTIES, + displayOrder: 1, + name: createFormTranslations.parties, + } as Section, + { + formId: form.id, + sectionType: SectionTypes.PAYMENT, + displayOrder: 3, + name: createFormTranslations.payment, + } as Section, + ]) const inputSection = await this.sectionModel.create({ formId: form.id, sectionType: SectionTypes.INPUT, displayOrder: 2, - name: { is: 'Kafli', en: 'Section' }, - } as Section) - - await this.sectionModel.create({ - formId: form.id, - sectionType: SectionTypes.PAYMENT, - displayOrder: 3, - name: { is: 'Greiðsla', en: 'Payment' }, + name: createSectionTranslations.input, } as Section) await this.screenModel.create({ sectionId: inputSection.id, displayOrder: 0, - name: { is: 'innsláttarsíða 1', en: 'Input screen 1' }, + name: createFormTranslations.input, } as Screen) } } diff --git a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts b/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts deleted file mode 100644 index 5706427027bc..000000000000 --- a/apps/services/form-system/src/app/modules/forms/models/form.mapper.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Injectable } from '@nestjs/common' -import { Form } from './form.model' -import { FormsListDto } from './dto/formsList.dto' -import { FormsListFormDto } from './dto/formsListForm.dto' - -@Injectable() -export class FormMapper { - mapFormsToFormsListDto(forms: Form[]): FormsListDto { - const formsListForms = forms.map((form) => { - return { - id: form.id, - name: form.name, - slug: form.slug, - invalidationDate: form.invalidationDate, - created: form.created, - modified: form.modified, - isTranslated: form.isTranslated, - applicationDaysToRemove: form.applicationDaysToRemove, - derivedFrom: form.derivedFrom, - stopProgressOnValidatingScreen: form.stopProgressOnValidatingScreen, - } as FormsListFormDto - }) - const formsListDto: FormsListDto = { - forms: formsListForms, - } - - return formsListDto - } -} diff --git a/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts b/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts index 90ae7abd511f..c1fd29ec2daf 100644 --- a/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts +++ b/apps/services/form-system/src/app/modules/listItems/listItems.controller.ts @@ -1,4 +1,12 @@ -import { Body, Controller, Param, Post, Put, Delete } from '@nestjs/common' +import { + Body, + Controller, + Param, + Post, + Put, + Delete, + VERSION_NEUTRAL, +} from '@nestjs/common' import { ApiTags } from '@nestjs/swagger' import { ListItemsService } from './listItems.service' import { CreateListItemDto } from './models/dto/createListItem.dto' @@ -8,7 +16,7 @@ import { UpdateListItemsDisplayOrderDto } from './models/dto/updateListItemsDisp import { Documentation } from '@island.is/nest/swagger' @ApiTags('list items') -@Controller('listItems') +@Controller({ path: 'listItems', version: ['1', VERSION_NEUTRAL] }) export class ListItemsController { constructor(private readonly listItemsService: ListItemsService) {} diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts index 9926924fe944..fa34161fbc5d 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/organization.dto.ts @@ -1,5 +1,4 @@ -import { ApiProperty, OmitType } from '@nestjs/swagger' -import { Organization } from '../organization.model' +import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' export class OrganizationDto { diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts b/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts index 130f79fd3cc7..bf6feb3a7ded 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.controller.ts @@ -5,6 +5,7 @@ import { Get, Param, NotFoundException, + VERSION_NEUTRAL, } from '@nestjs/common' import { ApiTags } from '@nestjs/swagger' import { OrganizationsService } from './organizations.service' @@ -13,7 +14,7 @@ import { CreateOrganizationDto } from './models/dto/createOrganization.dto' import { Documentation } from '@island.is/nest/swagger' @ApiTags('organizations') -@Controller('organizations') +@Controller({ path: 'organizations', version: ['1', VERSION_NEUTRAL] }) export class OrganizationsController { constructor(private readonly organizationsService: OrganizationsService) {} diff --git a/apps/services/form-system/src/app/modules/screens/screens.controller.ts b/apps/services/form-system/src/app/modules/screens/screens.controller.ts index 98246cc8e367..ce6c10df0007 100644 --- a/apps/services/form-system/src/app/modules/screens/screens.controller.ts +++ b/apps/services/form-system/src/app/modules/screens/screens.controller.ts @@ -7,6 +7,7 @@ import { Param, NotFoundException, Put, + VERSION_NEUTRAL, } from '@nestjs/common' import { ScreensService } from './screens.service' import { CreateScreenDto } from './models/dto/createScreen.dto' @@ -18,7 +19,7 @@ import { ScreenDto } from './models/dto/screen.dto' import { UpdateScreensDisplayOrderDto } from './models/dto/updateScreensDisplayOrder.dto' @ApiTags('screens') -@Controller('screens') +@Controller({ path: 'screens', version: ['1', VERSION_NEUTRAL] }) export class ScreensController { constructor(private readonly screensService: ScreensService) {} diff --git a/apps/services/form-system/src/app/modules/sections/sections.controller.ts b/apps/services/form-system/src/app/modules/sections/sections.controller.ts index 40edd5ce9535..718f58c095d3 100644 --- a/apps/services/form-system/src/app/modules/sections/sections.controller.ts +++ b/apps/services/form-system/src/app/modules/sections/sections.controller.ts @@ -7,6 +7,7 @@ import { Param, NotFoundException, Put, + VERSION_NEUTRAL, } from '@nestjs/common' import { SectionsService } from './sections.service' import { CreateSectionDto } from './models/dto/createSection.dto' @@ -18,7 +19,7 @@ import { SectionDto } from './models/dto/section.dto' import { UpdateSectionsDisplayOrderDto } from './models/dto/updateSectionsDisplayOrder.dto' @ApiTags('sections') -@Controller('sections') +@Controller({ path: 'sections', version: ['1', VERSION_NEUTRAL] }) export class SectionsController { constructor(private readonly sectionsService: SectionsService) {} diff --git a/apps/services/form-system/src/app/modules/translations/form/create.ts b/apps/services/form-system/src/app/modules/translations/form/create.ts new file mode 100644 index 000000000000..76fa4289029d --- /dev/null +++ b/apps/services/form-system/src/app/modules/translations/form/create.ts @@ -0,0 +1,8 @@ +import { LanguageType } from '../../../dataTypes/languageType.model' + +export const createFormTranslations: Record = { + premise: { is: 'Forsendur', en: 'Premises' }, + parties: { is: 'Hlutaðeigandi aðilar', en: 'Relevant parties' }, + payment: { is: 'Greiðsla', en: 'Payment' }, + input: { is: 'innsláttarsíða 1', en: 'Input screen 1' }, +} diff --git a/apps/services/form-system/src/app/modules/translations/form/index.ts b/apps/services/form-system/src/app/modules/translations/form/index.ts new file mode 100644 index 000000000000..f756a8bb30f9 --- /dev/null +++ b/apps/services/form-system/src/app/modules/translations/form/index.ts @@ -0,0 +1 @@ +export * from './create' diff --git a/apps/services/form-system/src/app/modules/translations/section/create.ts b/apps/services/form-system/src/app/modules/translations/section/create.ts new file mode 100644 index 000000000000..d18768e37813 --- /dev/null +++ b/apps/services/form-system/src/app/modules/translations/section/create.ts @@ -0,0 +1,5 @@ +import { LanguageType } from '../../../dataTypes/languageType.model' + +export const createSectionTranslations: Record = { + input: { is: 'Kafli', en: 'Section' }, +} diff --git a/apps/services/form-system/src/app/modules/translations/section/index.ts b/apps/services/form-system/src/app/modules/translations/section/index.ts new file mode 100644 index 000000000000..f756a8bb30f9 --- /dev/null +++ b/apps/services/form-system/src/app/modules/translations/section/index.ts @@ -0,0 +1 @@ +export * from './create' diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index 48e02e2088db..ec4b2dfb8d16 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -8,31 +8,31 @@ import { AppModule } from './app/app.module' import { openApi } from './openApi' import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' import { Logger } from '@nestjs/common' -// import { bootstrap } from '@island.is/infra-nest-server' +import { bootstrap } from '@island.is/infra-nest-server' -const bootstrap = async () => { - const app = await NestFactory.create(AppModule) +bootstrap({ + appModule: AppModule, + name: 'services-form-system', + openApi, + swaggerPath: 'api/swagger', + port: 3434, +}) - const config = new DocumentBuilder() - .setTitle('FormSystem Api') - .setDescription('Api for FormSystem.') - .setVersion('1.0') - .addTag('form-system-api') - .build() - const document = SwaggerModule.createDocument(app, config) - SwaggerModule.setup('api', app, document) +// const bootstrap = async () => { +// const app = await NestFactory.create(AppModule) - const port = process.env.PORT || 3000 - await app.listen(port) - Logger.log(`🚀 Application is running on: http://localhost:${port}`) -} +// const config = new DocumentBuilder() +// .setTitle('FormSystem Api') +// .setDescription('Api for FormSystem.') +// .setVersion('1.0') +// .addTag('form-system-api') +// .build() +// const document = SwaggerModule.createDocument(app, config) +// SwaggerModule.setup('api', app, document) -bootstrap() +// const port = process.env.PORT || 3000 +// await app.listen(port) +// Logger.log(`🚀 Application is running on: http://localhost:${port}`) +// } -// bootstrap({ -// appModule: AppModule, -// name: 'services-form-system', -// openApi, -// swaggerPath: 'api', -// port: 3000, -// }) +// bootstrap() diff --git a/apps/services/form-system/src/openApi.ts b/apps/services/form-system/src/openApi.ts index 02373b4706db..e4049fed211d 100644 --- a/apps/services/form-system/src/openApi.ts +++ b/apps/services/form-system/src/openApi.ts @@ -2,7 +2,9 @@ import { DocumentBuilder } from '@nestjs/swagger' export const openApi = new DocumentBuilder() .setTitle('Form System API') - .setDescription('Formbuilder and form-rendering (application) system') - .addServer(process.env.PUBLIC_URL ?? 'http://localhost:3000') + .setDescription( + 'This is an API for formbuilder and form-rendering (application) system', + ) + .addServer(process.env.PUBLIC_URL ?? 'http://localhost:3434') .setVersion('1.0') .build() From 449fbf9d68997ad5f5e7c592e55ff91ff3df9d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20Georg=20Gylfason?= Date: Fri, 5 Jul 2024 15:47:27 +0000 Subject: [PATCH 55/72] add openapi.yaml build --- apps/services/form-system/project.json | 7 +++++++ apps/services/form-system/src/buildOpenApi.ts | 9 +++++++++ 2 files changed, 16 insertions(+) create mode 100644 apps/services/form-system/src/buildOpenApi.ts diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json index 2dc035e9446f..6d13767a82de 100644 --- a/apps/services/form-system/project.json +++ b/apps/services/form-system/project.json @@ -59,6 +59,13 @@ } } }, + "codegen/backend-schema": { + "executor": "nx:run-commands", + "options": { + "command": "cross-env INIT_SCHEMA=true yarn ts-node -P apps/services/form-system/tsconfig.app.json apps/services/form-system/src/buildOpenApi.ts" + }, + "outputs": ["{projectRoot}/src/openapi.yaml"] + }, "migrate": { "executor": "nx:run-commands", "options": { diff --git a/apps/services/form-system/src/buildOpenApi.ts b/apps/services/form-system/src/buildOpenApi.ts new file mode 100644 index 000000000000..e0b5118489b0 --- /dev/null +++ b/apps/services/form-system/src/buildOpenApi.ts @@ -0,0 +1,9 @@ +import { buildOpenApi } from '@island.is/infra-nest-server' +import { AppModule } from './app/app.module' +import { openApi } from './openApi' + +buildOpenApi({ + path: 'apps/services/form-system/src/openapi.yaml', + appModule: AppModule, + openApi, +}) From e6f67ee429a305eff17df4ec259e422fd6d3f169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Fri, 5 Jul 2024 16:21:17 +0000 Subject: [PATCH 56/72] Refactor project setup --- apps/services/form-system/project.json | 16 +++++++--------- apps/services/form-system/tsconfig.app.json | 2 +- apps/services/form-system/webpack.config.js | 8 -------- 3 files changed, 8 insertions(+), 18 deletions(-) delete mode 100644 apps/services/form-system/webpack.config.js diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json index 6d13767a82de..86cc59994585 100644 --- a/apps/services/form-system/project.json +++ b/apps/services/form-system/project.json @@ -5,22 +5,20 @@ "projectType": "application", "targets": { "build": { - "executor": "@nx/webpack:webpack", + "executor": "./tools/executors/node:build", "outputs": ["{options.outputPath}"], - "defaultConfiguration": "production", "options": { - "target": "node", - "compiler": "tsc", "outputPath": "dist/apps/services/form-system", "main": "apps/services/form-system/src/main.ts", "tsConfig": "apps/services/form-system/tsconfig.app.json", - "assets": ["apps/services/form-system/src/assets"], - "isolatedConfig": true, - "webpackConfig": "apps/services/form-system/webpack.config.js" + "assets": ["apps/services/form-system/src/assets"] }, "configurations": { - "development": {}, - "production": {} + "production": { + "optimization": true, + "extractLicenses": true, + "inspect": false + } } }, "serve": { diff --git a/apps/services/form-system/tsconfig.app.json b/apps/services/form-system/tsconfig.app.json index d4cefc19c54b..2b5b31ae5d69 100644 --- a/apps/services/form-system/tsconfig.app.json +++ b/apps/services/form-system/tsconfig.app.json @@ -8,5 +8,5 @@ "target": "es2021" }, "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], - "include": ["src/**/*.ts"] + "include": ["**/*.ts"] } diff --git a/apps/services/form-system/webpack.config.js b/apps/services/form-system/webpack.config.js deleted file mode 100644 index bb8d268d232f..000000000000 --- a/apps/services/form-system/webpack.config.js +++ /dev/null @@ -1,8 +0,0 @@ -const { composePlugins, withNx } = require('@nx/webpack') - -// Nx plugins for webpack. -module.exports = composePlugins(withNx(), (config) => { - // Update the webpack config as needed here. - // e.g. `config.plugins.push(new MyPlugin())` - return config -}) From ff69ada59ed676b4d932942449bb933dff6985a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Fri, 5 Jul 2024 16:21:27 +0000 Subject: [PATCH 57/72] Add class validation for CreateFormDto --- .../src/app/modules/forms/models/dto/createForm.dto.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts b/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts index b1ea7e00560a..32f857b362c7 100644 --- a/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts +++ b/apps/services/form-system/src/app/modules/forms/models/dto/createForm.dto.ts @@ -1,6 +1,9 @@ +import { IsNotEmpty, IsString } from 'class-validator' import { ApiProperty } from '@nestjs/swagger' export class CreateFormDto { + @IsNotEmpty() + @IsString() @ApiProperty() organizationId!: string } From 290114f2e223ca83db002d7e07f9388f711f16a7 Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Wed, 10 Jul 2024 10:02:52 +0000 Subject: [PATCH 58/72] add class-validation --- .../src/app/dataTypes/languageType.model.ts | 5 + .../models/dto/updateFieldSettings.dto.ts | 109 +++++++++++++++++- .../fields/models/dto/createField.dto.ts | 3 + .../models/dto/fieldDisplayOrder.dto.ts | 5 + .../fields/models/dto/updateField.dto.ts | 14 +++ .../dto/updateFieldsDisplayOrder.dto.ts | 6 + .../models/dto/createListItem.dto.ts | 5 + .../models/dto/listItemDisplayOrder.dto.ts | 3 + .../models/dto/updateListItem.dto.ts | 17 +++ .../dto/updateListItemsDisplayOrder.dto.ts | 6 + .../models/dto/createOrganization.dto.ts | 7 ++ .../screens/models/dto/createScreen.dto.ts | 3 + .../models/dto/screenDisplayOrder.dto.ts | 5 + .../screens/models/dto/updateScreen.dto.ts | 14 +++ .../dto/updateScreensDisplayOrder.dto.ts | 6 + .../sections/models/dto/createSection.dto.ts | 3 + .../models/dto/sectionDisplayOrder.dto.ts | 3 + .../sections/models/dto/updateSection.dto.ts | 8 ++ .../dto/updateSectionsDisplayOrder.dto.ts | 6 + .../modules/sections/models/section.model.ts | 1 + 20 files changed, 224 insertions(+), 5 deletions(-) diff --git a/apps/services/form-system/src/app/dataTypes/languageType.model.ts b/apps/services/form-system/src/app/dataTypes/languageType.model.ts index 077c09c9eebe..eb9fdd222f60 100644 --- a/apps/services/form-system/src/app/dataTypes/languageType.model.ts +++ b/apps/services/form-system/src/app/dataTypes/languageType.model.ts @@ -1,9 +1,14 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class LanguageType { + @IsNotEmpty() + @IsString() @ApiProperty() is!: string + @IsNotEmpty() + @IsString() @ApiProperty() en!: string } diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts index ca6c2ad14046..7c724fbd92ff 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/dto/updateFieldSettings.dto.ts @@ -1,6 +1,105 @@ -import { OmitType } from '@nestjs/swagger' -import { FieldSettingsDto } from './fieldSettings.dto' +import { ApiPropertyOptional } from '@nestjs/swagger' +import { + IsBoolean, + IsDate, + IsNumber, + IsOptional, + IsString, +} from 'class-validator' -export class UpdateFieldSettingsDto extends OmitType(FieldSettingsDto, [ - 'list', -] as const) {} +export class UpdateFieldSettingsDto { + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + minValue?: number + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + maxValue?: number + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + minLength?: number + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + maxLength?: number + + @IsOptional() + @IsDate() + @ApiPropertyOptional() + minDate?: Date + + @IsOptional() + @IsDate() + @ApiPropertyOptional() + maxDate?: Date + + @IsOptional() + @IsString() + @ApiPropertyOptional() + minAmount?: string + + @IsOptional() + @IsString() + @ApiPropertyOptional() + maxAmount?: string + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + year?: number + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional() + hasLink?: boolean + + @IsOptional() + @IsString() + @ApiPropertyOptional() + url?: string + + @IsOptional() + @IsString() + @ApiPropertyOptional() + buttonText?: string + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional() + hasPropertyInput?: boolean + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional() + hasPropertyList?: boolean + + @IsOptional() + @IsString() + @ApiPropertyOptional() + listType?: string + + @IsOptional() + @IsString() + @ApiPropertyOptional() + fileTypes?: string + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + fileMaxSize?: number + + @IsOptional() + @IsNumber() + @ApiPropertyOptional() + maxFiles?: number + + @IsOptional() + @IsString() + @ApiPropertyOptional() + timeInterval?: string +} diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts index ebd0e045ee14..8e7065b1cb2a 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/createField.dto.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class CreateFieldDto { + @IsNotEmpty() + @IsString() @ApiProperty() screenId!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts index 0fa79ca953d0..609cd86cbcf0 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/fieldDisplayOrder.dto.ts @@ -1,9 +1,14 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class FieldDisplayOrderDto { + @IsNotEmpty() + @IsString() @ApiProperty() id!: string + @IsNotEmpty() + @IsString() @ApiProperty() screenId!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts index f1fcd619c923..8e3388cfe8fb 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/updateField.dto.ts @@ -2,20 +2,34 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' import { UpdateFieldSettingsDto } from '../../../fieldSettings/models/dto/updateFieldSettings.dto' import { FieldTypes } from '../../../../enums/fieldTypes' +import { IsEnum, IsNotEmpty, IsOptional, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateFieldDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) name!: LanguageType + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) description!: LanguageType + @IsNotEmpty() @ApiProperty() isPartOfMultiset!: boolean + @IsOptional() + @ValidateNested() + @Type(() => UpdateFieldSettingsDto) @ApiProperty({ type: UpdateFieldSettingsDto }) fieldSettings?: UpdateFieldSettingsDto + @IsNotEmpty() + @IsEnum(FieldTypes) @ApiProperty({ enum: FieldTypes }) fieldType!: string } diff --git a/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts index 46589d192a0a..5f76fc72ae13 100644 --- a/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/fields/models/dto/updateFieldsDisplayOrder.dto.ts @@ -1,7 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' import { FieldDisplayOrderDto } from './fieldDisplayOrder.dto' +import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateFieldsDisplayOrderDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => FieldDisplayOrderDto) + @IsArray() @ApiProperty({ type: [FieldDisplayOrderDto] }) fieldsDisplayOrderDto!: FieldDisplayOrderDto[] } diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts index 3e1377897651..c562c784effe 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/createListItem.dto.ts @@ -1,9 +1,14 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsNumber, IsString } from 'class-validator' export class CreateListItemDto { + @IsNotEmpty() + @IsString() @ApiProperty() fieldId!: string @ApiProperty() + @IsNotEmpty() + @IsNumber() displayOrder!: number } diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts index a5242a87c7e4..750d7e8afd01 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/listItemDisplayOrder.dto.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class ListItemDisplayOrderDto { + @IsNotEmpty() + @IsString() @ApiProperty() id!: string } diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts index 8a56b8bc0116..ecb211ec43a6 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItem.dto.ts @@ -1,16 +1,33 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { + IsBoolean, + IsNotEmpty, + IsString, + ValidateNested, +} from 'class-validator' +import { Type } from 'class-transformer' export class UpdateListItemDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) label!: LanguageType + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiPropertyOptional({ type: LanguageType }) description?: LanguageType + @IsNotEmpty() + @IsString() @ApiProperty() value!: string + @IsNotEmpty() + @IsBoolean() @ApiProperty() isSelected!: boolean } diff --git a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts index 0a007cb166b6..27fe48800f55 100644 --- a/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/listItems/models/dto/updateListItemsDisplayOrder.dto.ts @@ -1,7 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' import { ListItemDisplayOrderDto } from './listItemDisplayOrder.dto' +import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateListItemsDisplayOrderDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => ListItemDisplayOrderDto) + @IsArray() @ApiProperty({ type: [ListItemDisplayOrderDto] }) listItemsDisplayOrderDto!: ListItemDisplayOrderDto[] } diff --git a/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts b/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts index 5d51ca13beec..3d7bf01fce72 100644 --- a/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts +++ b/apps/services/form-system/src/app/modules/organizations/models/dto/createOrganization.dto.ts @@ -1,10 +1,17 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { IsNotEmpty, IsString, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class CreateOrganizationDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) name!: LanguageType + @IsNotEmpty() + @IsString() @ApiProperty() nationalId!: string } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts index 18d68cb51b36..46034a10c88b 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/createScreen.dto.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class CreateScreenDto { + @IsNotEmpty() + @IsString() @ApiProperty() sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts index b315cd1bdec1..c560d7da5b6f 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/screenDisplayOrder.dto.ts @@ -1,9 +1,14 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class ScreenDisplayOrderDto { + @IsNotEmpty() + @IsString() @ApiProperty() id!: string + @IsNotEmpty() + @IsString() @ApiProperty() sectionId!: string } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts index b16dd949005b..35ef774d9409 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreen.dto.ts @@ -1,13 +1,27 @@ import { ApiProperty } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { + IsBoolean, + IsNotEmpty, + IsNumber, + ValidateNested, +} from 'class-validator' +import { Type } from 'class-transformer' export class UpdateScreenDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) name!: LanguageType + @IsNotEmpty() + @IsNumber() @ApiProperty() multiset!: number + @IsNotEmpty() + @IsBoolean() @ApiProperty() callRuleset!: boolean } diff --git a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts index 5f4ed4a02952..b7916a5c7974 100644 --- a/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/screens/models/dto/updateScreensDisplayOrder.dto.ts @@ -1,7 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' import { ScreenDisplayOrderDto } from './screenDisplayOrder.dto' +import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateScreensDisplayOrderDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => ScreenDisplayOrderDto) + @IsArray() @ApiProperty({ type: [ScreenDisplayOrderDto] }) screensDisplayOrderDto!: ScreenDisplayOrderDto[] } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts index d1702024e4b2..3d4edc38b10c 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/createSection.dto.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class CreateSectionDto { + @IsNotEmpty() + @IsString() @ApiProperty() formId!: string } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts index a7bfe50acd43..7dd26e7a2ffb 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/sectionDisplayOrder.dto.ts @@ -1,6 +1,9 @@ import { ApiProperty } from '@nestjs/swagger' +import { IsNotEmpty, IsString } from 'class-validator' export class SectionDisplayOrderDto { + @IsNotEmpty() + @IsString() @ApiProperty() id!: string } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts index 940e5ab6efac..45f6e58c8969 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSection.dto.ts @@ -1,10 +1,18 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger' import { LanguageType } from '../../../../dataTypes/languageType.model' +import { IsNotEmpty, IsOptional, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateSectionDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => LanguageType) @ApiProperty({ type: LanguageType }) name!: LanguageType + @IsOptional() + @ValidateNested() + @Type(() => LanguageType) @ApiPropertyOptional({ type: LanguageType }) waitingText?: LanguageType } diff --git a/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts b/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts index b2c60ca15ff9..76daf3de7335 100644 --- a/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts +++ b/apps/services/form-system/src/app/modules/sections/models/dto/updateSectionsDisplayOrder.dto.ts @@ -1,7 +1,13 @@ import { ApiProperty } from '@nestjs/swagger' import { SectionDisplayOrderDto } from './sectionDisplayOrder.dto' +import { IsArray, IsNotEmpty, ValidateNested } from 'class-validator' +import { Type } from 'class-transformer' export class UpdateSectionsDisplayOrderDto { + @IsNotEmpty() + @ValidateNested() + @Type(() => SectionDisplayOrderDto) + @IsArray() @ApiProperty({ type: [SectionDisplayOrderDto] }) sectionsDisplayOrderDto!: SectionDisplayOrderDto[] } diff --git a/apps/services/form-system/src/app/modules/sections/models/section.model.ts b/apps/services/form-system/src/app/modules/sections/models/section.model.ts index 5695b67247c4..e89e4eeceb6a 100644 --- a/apps/services/form-system/src/app/modules/sections/models/section.model.ts +++ b/apps/services/form-system/src/app/modules/sections/models/section.model.ts @@ -46,6 +46,7 @@ export class Section extends Model
{ type: DataTypes.ENUM, allowNull: false, values: Object.values(SectionTypes), + defaultValue: 'input', }) @ApiProperty({ enum: SectionTypes }) sectionType!: string From 410c3d38925d204420732dc2b570ceac6fff37da Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Wed, 10 Jul 2024 14:31:02 +0000 Subject: [PATCH 59/72] use predefined types for cases in switch --- .../models/fieldSettings.mapper.ts | 21 +++++++++--------- apps/services/form-system/src/main.ts | 22 ------------------- yarn.lock | 13 ----------- 3 files changed, 11 insertions(+), 45 deletions(-) diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts index 659ab3d429ef..01f2d0886df9 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -4,6 +4,7 @@ import { FieldSettings } from './fieldSettings.model' import { FieldSettingsDto } from './dto/fieldSettings.dto' import { ListItemMapper } from '../../listItems/models/listItem.mapper' import { defaults, pick, zipObject } from 'lodash' +import { FieldTypes } from '../../../enums/fieldTypes' @Injectable() export class FieldSettingsMapper { @@ -42,42 +43,42 @@ export class FieldSettingsMapper { ): FieldSettingsDto { let keys: string[] switch (fieldType) { - case 'textbox': + case FieldTypes.TEXTBOX: keys = ['minLength', 'maxLength'] return this.pickSettings(fieldSettings, keys) - case 'numberbox': + case FieldTypes.NUMBERBOX: keys = ['minLength', 'maxLength', 'minValue', 'maxValue'] return this.pickSettings(fieldSettings, keys) - case 'message': + case FieldTypes.MESSAGE: keys = ['hasLink', 'url', 'buttonText'] return this.pickSettings(fieldSettings, keys) - case 'datePicker': + case FieldTypes.DATE_PICKER: keys = ['minDate', 'maxDate'] return this.pickSettings(fieldSettings, keys) - case 'dropdownList': + case FieldTypes.DROPDOWN_LIST: keys = ['list', 'listType'] const dropdownListFieldSettings = this.pickSettings(fieldSettings, keys) dropdownListFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return dropdownListFieldSettings - case 'radioButtons': + case FieldTypes.RADIO_BUTTONS: keys = ['list'] const radioButtonsFieldSettings = this.pickSettings(fieldSettings, keys) radioButtonsFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return radioButtonsFieldSettings - case 'iskNumberbox': + case FieldTypes.ISK_NUMBERBOX: keys = ['minAmount', 'maxAmount'] return this.pickSettings(fieldSettings, keys) - case 'propertyNumber': + case FieldTypes.PROPERTY_NUMBER: keys = ['hasPropertyInput', 'hasPropertyList'] return this.pickSettings(fieldSettings, keys) - case 'document': + case FieldTypes.DOCUMENT: keys = ['fileTypes', 'fileMaxSize', 'maxFiles'] return this.pickSettings(fieldSettings, keys) - case 'timeInput': + case FieldTypes.TIME_INPUT: keys = ['timeInterval'] return this.pickSettings(fieldSettings, keys) default: diff --git a/apps/services/form-system/src/main.ts b/apps/services/form-system/src/main.ts index ec4b2dfb8d16..7707dbb06781 100644 --- a/apps/services/form-system/src/main.ts +++ b/apps/services/form-system/src/main.ts @@ -3,11 +3,8 @@ * This is only a minimal backend to get started. */ -import { NestFactory } from '@nestjs/core' import { AppModule } from './app/app.module' import { openApi } from './openApi' -import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger' -import { Logger } from '@nestjs/common' import { bootstrap } from '@island.is/infra-nest-server' bootstrap({ @@ -17,22 +14,3 @@ bootstrap({ swaggerPath: 'api/swagger', port: 3434, }) - -// const bootstrap = async () => { -// const app = await NestFactory.create(AppModule) - -// const config = new DocumentBuilder() -// .setTitle('FormSystem Api') -// .setDescription('Api for FormSystem.') -// .setVersion('1.0') -// .addTag('form-system-api') -// .build() -// const document = SwaggerModule.createDocument(app, config) -// SwaggerModule.setup('api', app, document) - -// const port = process.env.PORT || 3000 -// await app.listen(port) -// Logger.log(`🚀 Application is running on: http://localhost:${port}`) -// } - -// bootstrap() diff --git a/yarn.lock b/yarn.lock index b050bf20b316..57a87eeaf986 100644 --- a/yarn.lock +++ b/yarn.lock @@ -48758,19 +48758,6 @@ __metadata: languageName: node linkType: hard -"sass@npm:1.62.1": - version: 1.62.1 - resolution: "sass@npm:1.62.1" - dependencies: - chokidar: ">=3.0.0 <4.0.0" - immutable: ^4.0.0 - source-map-js: ">=0.6.2 <2.0.0" - bin: - sass: sass.js - checksum: 1b1b3584b38a63dd94156b65f13b90e3f84b170a38c3d5e3fa578b7a32a37aeb349b4926b0eaf9448d48e955e86b1ee01b13993f19611dad8068af07a607c13b - languageName: node - linkType: hard - "sass@npm:^1.42.1": version: 1.63.2 resolution: "sass@npm:1.63.2" From 6908cb1fd688ca5ea3d8705537707b56d4e12cf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 08:54:32 +0000 Subject: [PATCH 60/72] Fix build --- apps/services/form-system/esbuild.json | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 apps/services/form-system/esbuild.json diff --git a/apps/services/form-system/esbuild.json b/apps/services/form-system/esbuild.json new file mode 100644 index 000000000000..b6cfcbf1d3b6 --- /dev/null +++ b/apps/services/form-system/esbuild.json @@ -0,0 +1,62 @@ +{ + "platform": "node", + "external": [ + "fsevents", + "color-convert", + "color-string", + "@nestjs/microservices", + "class-transformer", + "cache-manager", + "@nestjs/websockets/socket-module", + "class-validator", + "class-transformer", + "@nestjs/microservices/microservices-module", + "apollo-server-fastify", + "@elastic/elasticsearch", + "fastify-swagger", + "@nestjs/mongoose", + "@nestjs/typeorm", + "dd-trace", + "express", + "http-errors", + "graphql", + "pg", + "winston", + "util-deprecate", + "source-map-resolve", + "atob", + "logform", + "pg-native", + "form-data", + "swagger-ui-dist", + "configcat-node", + "mock-aws-s3", + "nock", + "@protobufjs/aspromise", + "@protobufjs/base64", + "@protobufjs/codegen", + "@protobufjs/eventemitter", + "@protobufjs/fetch", + "@protobufjs/float", + "@protobufjs/inquire", + "@protobufjs/path", + "@protobufjs/pool", + "@protobufjs/utf8", + "pseudomap", + "p-cancelable", + "@sindresorhus/is", + "@szmarczak/http-timer", + "cacheable-request", + "decompress-response", + "duplexer3", + "get-stream", + "lowercase-keys", + "mimic-response", + "to-readable-stream", + "url-parse-lax", + "safer-buffer", + "ioredis", + "@mikro-orm/core" + ], + "keepNames": true +} From 9fc825a50c3a0de43e46988c1467242a244020f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 08:56:43 +0000 Subject: [PATCH 61/72] Fix lint --- .../fieldSettings/models/fieldSettings.mapper.ts | 11 ++++++++--- .../src/app/modules/forms/forms.service.ts | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts index 01f2d0886df9..07d38a805977 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -1,9 +1,12 @@ import { Injectable } from '@nestjs/common' +import defaults from 'lodash/defaults' +import pick from 'lodash/pick' +import zipObject from 'lodash/zipObject' + import { UpdateFieldSettingsDto } from './dto/updateFieldSettings.dto' import { FieldSettings } from './fieldSettings.model' import { FieldSettingsDto } from './dto/fieldSettings.dto' import { ListItemMapper } from '../../listItems/models/listItem.mapper' -import { defaults, pick, zipObject } from 'lodash' import { FieldTypes } from '../../../enums/fieldTypes' @Injectable() @@ -55,20 +58,22 @@ export class FieldSettingsMapper { case FieldTypes.DATE_PICKER: keys = ['minDate', 'maxDate'] return this.pickSettings(fieldSettings, keys) - case FieldTypes.DROPDOWN_LIST: + case FieldTypes.DROPDOWN_LIST: { keys = ['list', 'listType'] const dropdownListFieldSettings = this.pickSettings(fieldSettings, keys) dropdownListFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return dropdownListFieldSettings - case FieldTypes.RADIO_BUTTONS: + } + case FieldTypes.RADIO_BUTTONS: { keys = ['list'] const radioButtonsFieldSettings = this.pickSettings(fieldSettings, keys) radioButtonsFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return radioButtonsFieldSettings + } case FieldTypes.ISK_NUMBERBOX: keys = ['minAmount', 'maxAmount'] return this.pickSettings(fieldSettings, keys) diff --git a/apps/services/form-system/src/app/modules/forms/forms.service.ts b/apps/services/form-system/src/app/modules/forms/forms.service.ts index dcfee0a9d071..a819ffe94a47 100644 --- a/apps/services/form-system/src/app/modules/forms/forms.service.ts +++ b/apps/services/form-system/src/app/modules/forms/forms.service.ts @@ -1,5 +1,9 @@ import { Injectable, NotFoundException } from '@nestjs/common' import { InjectModel } from '@nestjs/sequelize' +import defaults from 'lodash/defaults' +import pick from 'lodash/pick' +import zipObject from 'lodash/zipObject' + import { SectionTypes } from '../../enums/sectionTypes' import { FormApplicantDto } from '../applicants/models/dto/formApplicant.dto' import { ScreenDto } from '../screens/models/dto/screen.dto' @@ -24,7 +28,6 @@ import { FormResponse } from './models/dto/form.response.dto' import { Form } from './models/form.model' import { ListItem } from '../listItems/models/listItem.model' import { FormsListDto } from './models/dto/formsList.dto' -import { defaults, pick, zipObject } from 'lodash' import { FormsListFormDto } from './models/dto/formsListForm.dto' import { createFormTranslations } from '../translations/form' import { createSectionTranslations } from '../translations/section' From a70e211a4c8f983c62073ed6ba2e8ea86bfb4a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 10:25:05 +0000 Subject: [PATCH 62/72] Update tags --- apps/services/form-system/project.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/services/form-system/project.json b/apps/services/form-system/project.json index 86cc59994585..e4d160ed6ded 100644 --- a/apps/services/form-system/project.json +++ b/apps/services/form-system/project.json @@ -3,6 +3,7 @@ "$schema": "../../../node_modules/nx/schemas/project-schema.json", "sourceRoot": "apps/services/form-system/src", "projectType": "application", + "tags": ["scope:nest"], "targets": { "build": { "executor": "./tools/executors/node:build", @@ -92,6 +93,5 @@ "cwd": "apps/services/form-system" } } - }, - "tags": [] + } } From 73743be487c5e87babae38eb5eca2b5248897141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 11:27:19 +0000 Subject: [PATCH 63/72] Remove empty test files --- .../src/app/modules/fieldSettings/fieldSettings.service.spec.ts | 0 .../form-system/src/app/modules/fields/fields.controller.spec.ts | 0 .../form-system/src/app/modules/fields/fields.service.spec.ts | 0 .../src/app/modules/screens/screens.controller.spec.ts | 0 .../form-system/src/app/modules/screens/screens.service.spec.ts | 0 .../src/app/modules/sections/sections.controller.spec.ts | 0 .../form-system/src/app/modules/sections/sections.service.spec.ts | 0 7 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/fields/fields.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/screens/screens.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/screens/screens.service.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts delete mode 100644 apps/services/form-system/src/app/modules/sections/sections.service.spec.ts diff --git a/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts b/apps/services/form-system/src/app/modules/fieldSettings/fieldSettings.service.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts b/apps/services/form-system/src/app/modules/fields/fields.controller.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/fields/fields.service.spec.ts b/apps/services/form-system/src/app/modules/fields/fields.service.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/screens/screens.controller.spec.ts b/apps/services/form-system/src/app/modules/screens/screens.controller.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/screens/screens.service.spec.ts b/apps/services/form-system/src/app/modules/screens/screens.service.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts b/apps/services/form-system/src/app/modules/sections/sections.controller.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/apps/services/form-system/src/app/modules/sections/sections.service.spec.ts b/apps/services/form-system/src/app/modules/sections/sections.service.spec.ts deleted file mode 100644 index e69de29bb2d1..000000000000 From d171d4f73a87e85729565f372f3dc19bf53ec38a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 11:27:53 +0000 Subject: [PATCH 64/72] Skip tests until implemented --- .../app/modules/organizations/organizations.controller.spec.ts | 2 +- .../src/app/modules/organizations/organizations.service.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts index 125cba9400a0..6e61c1db2a20 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.controller.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing' import { OrganizationsController } from './organizations.controller' -describe('OrganizationsController', () => { +describe.skip('OrganizationsController', () => { let controller: OrganizationsController beforeEach(async () => { diff --git a/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts index a3ab5837b929..99f79d770aa0 100644 --- a/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts +++ b/apps/services/form-system/src/app/modules/organizations/organizations.service.spec.ts @@ -1,7 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing' import { OrganizationsService } from './organizations.service' -describe('OrganizationsService', () => { +describe.skip('OrganizationsService', () => { let service: OrganizationsService beforeEach(async () => { From 1ccf17020fa96d118952c4a0213e6d4bf7790705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A6ring=20Gunnar=20Stein=C3=BE=C3=B3rsson?= Date: Thu, 18 Jul 2024 11:41:52 +0000 Subject: [PATCH 65/72] Add advania as codeowner for new service --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cb6923c1c5d8..1ba24789db2a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -265,6 +265,7 @@ codemagic.yaml /libs/island-ui/ @island-is/island-ui /apps/consultation-portal/ @island-is/advania +/apps/services/form-system/ @island-is/advania /libs/clients/consultation-portal/ @island-is/advania /libs/api/domains/consultation-portal/ @island-is/advania From 2cdf46c3c964b86e82a9b5ed2dd018ac88e91ed9 Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Thu, 8 Aug 2024 15:04:00 +0000 Subject: [PATCH 66/72] add infra definition --- apps/services/form-system/infra/form-system.ts | 18 ++++++++++++++++++ .../src/app/enums/applicantTypes.ts | 2 +- .../models/fieldSettings.mapper.ts | 6 ++++-- 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 apps/services/form-system/infra/form-system.ts diff --git a/apps/services/form-system/infra/form-system.ts b/apps/services/form-system/infra/form-system.ts new file mode 100644 index 000000000000..2c9968823335 --- /dev/null +++ b/apps/services/form-system/infra/form-system.ts @@ -0,0 +1,18 @@ +import { service, ServiceBuilder } from '../../../../infra/src/dsl/dsl' + +export const serviceSetup = (): ServiceBuilder<'services-form-system'> => + service('services-form-system') + .image('services-form-system') + .namespace('services-form-system') + .env({ + IDENTITY_SERVER_ISSUER_URL: { + dev: 'https://identity-server.dev01.devland.is', + staging: 'https://identity-server.staging01.devland.is', + prod: 'https://innskra.island.is', + }, + }) + .liveness('/liveness') + .readiness('/readiness') + .db() + .migrations() + .grantNamespaces('islandis', 'form-system-service') diff --git a/apps/services/form-system/src/app/enums/applicantTypes.ts b/apps/services/form-system/src/app/enums/applicantTypes.ts index 8044550c07e7..a12e7e691bde 100644 --- a/apps/services/form-system/src/app/enums/applicantTypes.ts +++ b/apps/services/form-system/src/app/enums/applicantTypes.ts @@ -1,6 +1,6 @@ export const ApplicantTypes = { INDIVIDUAL: 'individual', - iNDIVIDUAL_WITH_DELEGATION_FROM_INDIVIDUAL: + INDIVIDUAL_WITH_DELEGATION_FROM_INDIVIDUAL: 'individualWithDelegationFromIndividual', INDIVIDUAL_WITH_DELEGATION_FROM_LEGAL_ENTITY: 'individualWithDelegationFromLegalEntity', diff --git a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts index 01f2d0886df9..33b0ccce5340 100644 --- a/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts +++ b/apps/services/form-system/src/app/modules/fieldSettings/models/fieldSettings.mapper.ts @@ -55,20 +55,22 @@ export class FieldSettingsMapper { case FieldTypes.DATE_PICKER: keys = ['minDate', 'maxDate'] return this.pickSettings(fieldSettings, keys) - case FieldTypes.DROPDOWN_LIST: + case FieldTypes.DROPDOWN_LIST: { keys = ['list', 'listType'] const dropdownListFieldSettings = this.pickSettings(fieldSettings, keys) dropdownListFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return dropdownListFieldSettings - case FieldTypes.RADIO_BUTTONS: + } + case FieldTypes.RADIO_BUTTONS: { keys = ['list'] const radioButtonsFieldSettings = this.pickSettings(fieldSettings, keys) radioButtonsFieldSettings.list = fieldSettings?.list ? this.listItemMapper.mapListItemsToListItemsDto(fieldSettings.list) : [] return radioButtonsFieldSettings + } case FieldTypes.ISK_NUMBERBOX: keys = ['minAmount', 'maxAmount'] return this.pickSettings(fieldSettings, keys) From f2689acc050c56a92f8c3b0f6b08a97de2063ee9 Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Fri, 9 Aug 2024 11:24:01 +0000 Subject: [PATCH 67/72] add the service to uber-charts --- infra/src/uber-charts/islandis.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/infra/src/uber-charts/islandis.ts b/infra/src/uber-charts/islandis.ts index 5239d4333d88..9fa56fc236e6 100644 --- a/infra/src/uber-charts/islandis.ts +++ b/infra/src/uber-charts/islandis.ts @@ -31,6 +31,8 @@ import { serviceSetup as downloadServiceSetup } from '../../../apps/download-ser import { serviceSetup as endorsementServiceSetup } from '../../../apps/services/endorsements/api/infra/endorsement-system-api' import { serviceSetup as githubActionsCacheSetup } from '../../../apps/github-actions-cache/infra/github-actions-cache' +import { serviceSetup as formSystemApiSetup } from '../../../apps/services/form-system/infra/form-system' + import { userNotificationServiceSetup, userNotificationCleanUpWorkerSetup, @@ -138,6 +140,8 @@ const userNotificationCleanupWorkerService = const endorsementSystemCleanUpWorkerService = endorsementSystemCleanUpWorkerSetup() +const formSystemApi = formSystemApiSetup() + const githubActionsCache = githubActionsCacheSetup() const externalContractsTests = externalContractsTestsSetup() @@ -171,6 +175,7 @@ export const Services: EnvironmentServices = { userNotificationCleanupWorkerService, endorsementSystemCleanUpWorkerService, licenseApi, + formSystemApi, sessionsService, sessionsWorker, sessionsCleanupWorker, @@ -207,6 +212,7 @@ export const Services: EnvironmentServices = { userNotificationCleanupWorkerService, endorsementSystemCleanUpWorkerService, licenseApi, + formSystemApi, sessionsService, sessionsWorker, sessionsCleanupWorker, @@ -244,6 +250,7 @@ export const Services: EnvironmentServices = { appSystemApiWorker, contentfulEntryTagger, licenseApi, + formSystemApi, sessionsService, sessionsWorker, sessionsCleanupWorker, From f0078dd3d40e912a1328d93c89a3761fcf288512 Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 9 Aug 2024 11:25:09 +0000 Subject: [PATCH 68/72] chore: charts update dirty files --- charts/islandis/values.dev.yaml | 79 +++++++++++++++++++++++++++++ charts/islandis/values.prod.yaml | 79 +++++++++++++++++++++++++++++ charts/islandis/values.staging.yaml | 79 +++++++++++++++++++++++++++++ 3 files changed, 237 insertions(+) diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml index 346fbc950112..55ac540d07fc 100644 --- a/charts/islandis/values.dev.yaml +++ b/charts/islandis/values.dev.yaml @@ -1888,6 +1888,7 @@ namespaces: - 'external-contracts-tests' - 'contentful-entry-tagger' - 'license-api' + - 'services-form-system' - 'services-sessions' - 'contentful-apps' - 'services-university-gateway' @@ -2455,6 +2456,84 @@ services-documents: securityContext: allowPrivilegeEscalation: false privileged: false +services-form-system: + enabled: true + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications-reader.internal' + DB_USER: 'services_form_system' + IDENTITY_SERVER_ISSUER_URL: 'https://identity-server.dev01.devland.is' + LOG_LEVEL: 'info' + NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init' + SERVERSIDE_FEATURES_ON: '' + grantNamespaces: + - 'islandis' + - 'form-system-service' + grantNamespacesEnabled: true + healthCheck: + liveness: + initialDelaySeconds: 3 + path: '/liveness' + timeoutSeconds: 3 + readiness: + initialDelaySeconds: 3 + path: '/readiness' + timeoutSeconds: 3 + hpa: + scaling: + metric: + cpuAverageUtilization: 90 + nginxRequestsIrate: 5 + replicas: + max: 3 + min: 1 + image: + repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' + initContainer: + containers: + - args: + - 'sequelize-cli' + - 'db:migrate' + command: + - 'npx' + name: 'migrations' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications-reader.internal' + DB_USER: 'services_form_system' + SERVERSIDE_FEATURES_ON: '' + secrets: + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + namespace: 'services-form-system' + podDisruptionBudget: + maxUnavailable: 1 + pvcs: [] + replicaCount: + default: 1 + max: 3 + min: 1 + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '100m' + memory: '128Mi' + secrets: + CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY' + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + securityContext: + allowPrivilegeEscalation: false + privileged: false services-sessions: enabled: true env: diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml index 2c1c89f3468a..537cfeb5aa7b 100644 --- a/charts/islandis/values.prod.yaml +++ b/charts/islandis/values.prod.yaml @@ -1752,6 +1752,7 @@ namespaces: - 'regulations-admin' - 'user-notification' - 'license-api' + - 'services-form-system' - 'services-sessions' - 'services-university-gateway' - 'contentful-apps' @@ -2326,6 +2327,84 @@ services-documents: securityContext: allowPrivilegeEscalation: false privileged: false +services-form-system: + enabled: true + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications.internal' + DB_USER: 'services_form_system' + IDENTITY_SERVER_ISSUER_URL: 'https://innskra.island.is' + LOG_LEVEL: 'info' + NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init' + SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms' + grantNamespaces: + - 'islandis' + - 'form-system-service' + grantNamespacesEnabled: true + healthCheck: + liveness: + initialDelaySeconds: 3 + path: '/liveness' + timeoutSeconds: 3 + readiness: + initialDelaySeconds: 3 + path: '/readiness' + timeoutSeconds: 3 + hpa: + scaling: + metric: + cpuAverageUtilization: 90 + nginxRequestsIrate: 5 + replicas: + max: 10 + min: 3 + image: + repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' + initContainer: + containers: + - args: + - 'sequelize-cli' + - 'db:migrate' + command: + - 'npx' + name: 'migrations' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications.internal' + DB_USER: 'services_form_system' + SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms' + secrets: + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + namespace: 'services-form-system' + podDisruptionBudget: + maxUnavailable: 1 + pvcs: [] + replicaCount: + default: 3 + max: 10 + min: 3 + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '100m' + memory: '128Mi' + secrets: + CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY' + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + securityContext: + allowPrivilegeEscalation: false + privileged: false services-sessions: enabled: true env: diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index 008ec45f8a29..7642ba676c90 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -1630,6 +1630,7 @@ namespaces: - 'regulations-admin' - 'user-notification' - 'license-api' + - 'services-form-system' - 'services-sessions' - 'services-university-gateway' portals-admin: @@ -2198,6 +2199,84 @@ services-documents: securityContext: allowPrivilegeEscalation: false privileged: false +services-form-system: + enabled: true + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications.internal' + DB_USER: 'services_form_system' + IDENTITY_SERVER_ISSUER_URL: 'https://identity-server.staging01.devland.is' + LOG_LEVEL: 'info' + NODE_OPTIONS: '--max-old-space-size=230 -r dd-trace/init' + SERVERSIDE_FEATURES_ON: '' + grantNamespaces: + - 'islandis' + - 'form-system-service' + grantNamespacesEnabled: true + healthCheck: + liveness: + initialDelaySeconds: 3 + path: '/liveness' + timeoutSeconds: 3 + readiness: + initialDelaySeconds: 3 + path: '/readiness' + timeoutSeconds: 3 + hpa: + scaling: + metric: + cpuAverageUtilization: 90 + nginxRequestsIrate: 5 + replicas: + max: 3 + min: 1 + image: + repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' + initContainer: + containers: + - args: + - 'sequelize-cli' + - 'db:migrate' + command: + - 'npx' + name: 'migrations' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' + env: + DB_HOST: 'postgres-applications.internal' + DB_NAME: 'services_form_system' + DB_REPLICAS_HOST: 'postgres-applications.internal' + DB_USER: 'services_form_system' + SERVERSIDE_FEATURES_ON: '' + secrets: + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + namespace: 'services-form-system' + podDisruptionBudget: + maxUnavailable: 1 + pvcs: [] + replicaCount: + default: 1 + max: 3 + min: 1 + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '100m' + memory: '128Mi' + secrets: + CONFIGCAT_SDK_KEY: '/k8s/configcat/CONFIGCAT_SDK_KEY' + DB_PASS: '/k8s/services-form-system/DB_PASSWORD' + securityContext: + allowPrivilegeEscalation: false + privileged: false services-sessions: enabled: true env: From 99dc205d0f027e008afc3858eb31b3039506d97d Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Fri, 9 Aug 2024 11:37:49 +0000 Subject: [PATCH 69/72] update grantNamespaces --- apps/services/form-system/infra/form-system.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/services/form-system/infra/form-system.ts b/apps/services/form-system/infra/form-system.ts index 2c9968823335..d597634ea9c8 100644 --- a/apps/services/form-system/infra/form-system.ts +++ b/apps/services/form-system/infra/form-system.ts @@ -15,4 +15,4 @@ export const serviceSetup = (): ServiceBuilder<'services-form-system'> => .readiness('/readiness') .db() .migrations() - .grantNamespaces('islandis', 'form-system-service') + .grantNamespaces('islandis') From a49ae841646b31da181396c2978620c8fc2dfc83 Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 9 Aug 2024 11:38:31 +0000 Subject: [PATCH 70/72] chore: charts update dirty files --- charts/islandis/values.dev.yaml | 1 - charts/islandis/values.prod.yaml | 1 - charts/islandis/values.staging.yaml | 1 - 3 files changed, 3 deletions(-) diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml index 55ac540d07fc..4a498e335a79 100644 --- a/charts/islandis/values.dev.yaml +++ b/charts/islandis/values.dev.yaml @@ -2469,7 +2469,6 @@ services-form-system: SERVERSIDE_FEATURES_ON: '' grantNamespaces: - 'islandis' - - 'form-system-service' grantNamespacesEnabled: true healthCheck: liveness: diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml index 537cfeb5aa7b..8911d6ea34ef 100644 --- a/charts/islandis/values.prod.yaml +++ b/charts/islandis/values.prod.yaml @@ -2340,7 +2340,6 @@ services-form-system: SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms' grantNamespaces: - 'islandis' - - 'form-system-service' grantNamespacesEnabled: true healthCheck: liveness: diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index 7642ba676c90..e5f9a3824b6b 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -2212,7 +2212,6 @@ services-form-system: SERVERSIDE_FEATURES_ON: '' grantNamespaces: - 'islandis' - - 'form-system-service' grantNamespacesEnabled: true healthCheck: liveness: From 74341f43fca68b6044c048b0a6e728d9e1c9623a Mon Sep 17 00:00:00 2001 From: OlafurGeorg Date: Fri, 9 Aug 2024 11:47:25 +0000 Subject: [PATCH 71/72] added seed instruction to DLS --- apps/services/form-system/infra/form-system.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/services/form-system/infra/form-system.ts b/apps/services/form-system/infra/form-system.ts index d597634ea9c8..1005b6aeceb8 100644 --- a/apps/services/form-system/infra/form-system.ts +++ b/apps/services/form-system/infra/form-system.ts @@ -14,5 +14,6 @@ export const serviceSetup = (): ServiceBuilder<'services-form-system'> => .liveness('/liveness') .readiness('/readiness') .db() + .seed() .migrations() .grantNamespaces('islandis') From 01ef9e2eb9ca5dcf84de8e8817f5315b464da614 Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 9 Aug 2024 11:48:33 +0000 Subject: [PATCH 72/72] chore: charts update dirty files --- charts/islandis/values.dev.yaml | 13 +++++++++++++ charts/islandis/values.prod.yaml | 13 +++++++++++++ charts/islandis/values.staging.yaml | 13 +++++++++++++ 3 files changed, 39 insertions(+) diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml index 4a498e335a79..e6be2ed53328 100644 --- a/charts/islandis/values.dev.yaml +++ b/charts/islandis/values.dev.yaml @@ -2491,6 +2491,19 @@ services-form-system: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' initContainer: containers: + - args: + - 'sequelize-cli' + - 'db:seed:all' + command: + - 'npx' + name: 'seed' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' - args: - 'sequelize-cli' - 'db:migrate' diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml index 8911d6ea34ef..38e815b7954f 100644 --- a/charts/islandis/values.prod.yaml +++ b/charts/islandis/values.prod.yaml @@ -2362,6 +2362,19 @@ services-form-system: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' initContainer: containers: + - args: + - 'sequelize-cli' + - 'db:seed:all' + command: + - 'npx' + name: 'seed' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' - args: - 'sequelize-cli' - 'db:migrate' diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index e5f9a3824b6b..ed0f7df2db01 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -2234,6 +2234,19 @@ services-form-system: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-form-system' initContainer: containers: + - args: + - 'sequelize-cli' + - 'db:seed:all' + command: + - 'npx' + name: 'seed' + resources: + limits: + cpu: '200m' + memory: '256Mi' + requests: + cpu: '50m' + memory: '128Mi' - args: - 'sequelize-cli' - 'db:migrate'