From e0e74cae60915482c81d380898f20fba06b6abbb Mon Sep 17 00:00:00 2001 From: unakb Date: Thu, 12 Dec 2024 12:06:44 +0000 Subject: [PATCH 01/32] chore(j-s): Add more info to new indictment robot emails (#17184) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/app/modules/case/internalCase.service.ts | 1 + .../deliverIndictmentInfoToCourt.spec.ts | 6 +++++- .../backend/src/app/modules/court/court.service.ts | 12 +++++++++--- .../app/modules/court/test/createCourtCase.spec.ts | 8 ++++---- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts index a969cf40351b..729645bb5f82 100644 --- a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts @@ -606,6 +606,7 @@ export class InternalCaseService { ? { name: theCase.prosecutor.name, nationalId: theCase.prosecutor.nationalId, + email: theCase.prosecutor.email, } : undefined, ) diff --git a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentInfoToCourt.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentInfoToCourt.spec.ts index 3236f05eb4de..c7b01baee552 100644 --- a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentInfoToCourt.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverIndictmentInfoToCourt.spec.ts @@ -54,7 +54,11 @@ describe('InternalCaseController - Deliver indictment info to court', () => { { eventType: EventType.INDICTMENT_CONFIRMED, created: indictmentDate }, ], defendants: [{ name: 'Test Ákærði', nationalId: '1234567890' }], - prosecutor: { name: 'Test Sækjandi', nationalId: '0101010101' }, + prosecutor: { + name: 'Test Sækjandi', + nationalId: '0101010101', + email: 'prosecutor@omnitrix.is', + }, } as Case let mockCourtService: CourtService diff --git a/apps/judicial-system/backend/src/app/modules/court/court.service.ts b/apps/judicial-system/backend/src/app/modules/court/court.service.ts index 7113dd6769b0..df13b35a90be 100644 --- a/apps/judicial-system/backend/src/app/modules/court/court.service.ts +++ b/apps/judicial-system/backend/src/app/modules/court/court.service.ts @@ -336,6 +336,9 @@ export class CourtService { ) const isIndictment = isIndictmentCase(type) + const policeCaseNumber = policeCaseNumbers[0] + ? policeCaseNumbers[0].replace(/-/g, '') + : '' return await this.courtClientService.createCase(courtId, { caseType: isIndictment ? 'S - Ákærumál' : 'R - Rannsóknarmál', @@ -344,7 +347,7 @@ export class CourtService { receivalDate: formatISO(receivalDate, { representation: 'date' }), basedOn: isIndictment ? 'Sakamál' : 'Rannsóknarhagsmunir', // TODO: pass in all policeCaseNumbers when CourtService supports it - sourceNumber: policeCaseNumbers[0] ? policeCaseNumbers[0] : '', + sourceNumber: policeCaseNumber, }) } catch (reason) { if (reason instanceof ServiceUnavailableException) { @@ -569,14 +572,17 @@ export class CourtService { policeCaseNumber?: string, subtypes?: string[], defendants?: { name?: string; nationalId?: string }[], - prosecutor?: { name?: string; nationalId?: string }, + prosecutor?: { name?: string; nationalId?: string; email?: string }, ): Promise { try { const subject = `${courtName} - ${courtCaseNumber} - upplýsingar` + + const sanitizedPoliceCaseNumber = policeCaseNumber?.replace(/-/g, '') + const content = JSON.stringify({ receivedByCourtDate, indictmentDate, - policeCaseNumber, + sanitizedPoliceCaseNumber, subtypes, defendants, prosecutor, diff --git a/apps/judicial-system/backend/src/app/modules/court/test/createCourtCase.spec.ts b/apps/judicial-system/backend/src/app/modules/court/test/createCourtCase.spec.ts index a32798d80b4e..5b98cb354570 100644 --- a/apps/judicial-system/backend/src/app/modules/court/test/createCourtCase.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/court/test/createCourtCase.spec.ts @@ -105,7 +105,7 @@ describe('CourtService - Create court case', () => { status: 'Skráð', receivalDate: formatISO(receivalDate, { representation: 'date' }), basedOn: 'Rannsóknarhagsmunir', - sourceNumber: policeCaseNumbers[0], + sourceNumber: policeCaseNumbers[0].replace(/-/g, ''), }, ) }) @@ -146,7 +146,7 @@ describe('CourtService - Create court case', () => { status: 'Skráð', receivalDate: formatISO(receivalDate, { representation: 'date' }), basedOn: 'Sakamál', - sourceNumber: policeCaseNumbers[0], + sourceNumber: policeCaseNumbers[0].replace(/-/g, ''), }, ) }) @@ -183,7 +183,7 @@ describe('CourtService - Create court case', () => { status: 'Skráð', receivalDate: formatISO(receivalDate, { representation: 'date' }), basedOn: 'Rannsóknarhagsmunir', - sourceNumber: policeCaseNumbers[0], + sourceNumber: policeCaseNumbers[0].replace(/-/g, ''), }) }) }) @@ -218,7 +218,7 @@ describe('CourtService - Create court case', () => { status: 'Skráð', receivalDate: formatISO(receivalDate, { representation: 'date' }), basedOn: 'Rannsóknarhagsmunir', - sourceNumber: policeCaseNumbers[0], + sourceNumber: policeCaseNumbers[0].replace(/-/g, ''), }) }) }) From 32a256e32eedb1de0324c61f8c5bb803d48313e7 Mon Sep 17 00:00:00 2001 From: unakb Date: Thu, 12 Dec 2024 12:32:33 +0000 Subject: [PATCH 02/32] feat(j-s): Tooltip with info about service not being required (#17200) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../Court/Indictments/Completed/Completed.strings.ts | 7 +++++++ .../src/routes/Court/Indictments/Completed/Completed.tsx | 3 +++ 2 files changed, 10 insertions(+) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.strings.ts index 884252537f62..d231db70e78f 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.strings.ts @@ -36,6 +36,13 @@ const strings = defineMessages({ description: 'Notaður sem texti í valmöguleika fyrir það þegar ekki skal birta dómdfellda dóminn.', }, + serviceRequirementNotRequiredTooltip: { + id: 'judicial.system.core:court.indictments.completed.service_requirement_not_required_tooltip', + defaultMessage: + 'Ekki þarf að birta dóm þar sem sektarfjárhæð er lægri en sem nemur áfrýjunarfjárhæð í einkamáli kr. 1.355.762. Gildir frá 01.01.2024', + description: + 'Notað sem tooltip í valmöguleika fyrir það þegar ekki skal birta dómdfellda dóminn.', + }, serviceRequirementNotApplicable: { id: 'judicial.system.core:court.indictments.completed.service_requirement_not_applicable', defaultMessage: 'Dómfelldi var viðstaddur dómsuppkvaðningu', diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.tsx index d988fde76856..88ac21c155da 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Completed/Completed.tsx @@ -291,6 +291,9 @@ const Completed: FC = () => { large backgroundColor="white" label={formatMessage(strings.serviceRequirementNotRequired)} + tooltip={formatMessage( + strings.serviceRequirementNotRequiredTooltip, + )} /> From 37fe92be86722e95ff07f0ea2d18145c8b81793e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9E=C3=B3rey=20J=C3=B3na?= Date: Thu, 12 Dec 2024 14:09:20 +0000 Subject: [PATCH 03/32] fix(native-app): Android build fixes (#17211) * fix: import for gradle-plugin * fix: update import for react-native-clipboard as well * fix: update build.gradle imports * fix: update reanimated * fix: add folder references to build.gradle * fix: remove react native clipboard from settings.gradle * fix(app): Use dev firebase in for dev android app * fix: remove added newline --------- Co-authored-by: Eirikur Nilsson Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/native/app/android/app/build.gradle | 6 +- apps/native/app/android/build.gradle | 4 +- apps/native/app/android/settings.gradle | 5 +- apps/native/app/package.json | 2 +- codemagic.yaml | 2 +- yarn.lock | 184 ++++++++++++++++++++++- 6 files changed, 186 insertions(+), 17 deletions(-) diff --git a/apps/native/app/android/app/build.gradle b/apps/native/app/android/app/build.gradle index a32464e07a8f..997472187673 100644 --- a/apps/native/app/android/app/build.gradle +++ b/apps/native/app/android/app/build.gradle @@ -16,11 +16,11 @@ react { // The root of your project, i.e. where "package.json" lives. Default is '..' // root = file("../") // The folder where the react-native NPM package is. Default is ../node_modules/react-native - // reactNativeDir = file("../node_modules/react-native") + reactNativeDir = file("../../../../../node_modules/react-native") // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen - // codegenDir = file("../node_modules/@react-native/codegen") + codegenDir = file("../../../../../node_modules/@react-native/codegen") // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js - // cliFile = file("../node_modules/react-native/cli.js") + cliFile = file("../../../../../node_modules/react-native/cli.js") /* Variants */ // The list of variants to that are debuggable. For those we're going to diff --git a/apps/native/app/android/build.gradle b/apps/native/app/android/build.gradle index 46f7b30a85d0..06110e23ae99 100644 --- a/apps/native/app/android/build.gradle +++ b/apps/native/app/android/build.gradle @@ -33,11 +33,11 @@ allprojects { repositories { maven { // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm - url("$rootDir/../node_modules/react-native/android") + url("$rootDir/../../../../../node_modules/react-native/android") } maven { // Android JSC is installed from npm - url("$rootDir/../node_modules/jsc-android/dist") + url("$rootDir/../../../../../node_modules/jsc-android/dist") } mavenCentral { // We don't want to fetch react-native from Maven Central as there are diff --git a/apps/native/app/android/settings.gradle b/apps/native/app/android/settings.gradle index 12979ce6cda2..d9655025ec45 100644 --- a/apps/native/app/android/settings.gradle +++ b/apps/native/app/android/settings.gradle @@ -6,11 +6,8 @@ applyNativeModulesSettingsGradle(settings) include ':app', ':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../../../../node_modules/react-native-code-push/android/app') -include ':react-native-clipboard' -project(':react-native-clipboard').projectDir = new File(rootProject.projectDir, '../../node_modules/@react-native-clipboard/clipboard/android') - include ':app' -includeBuild('../node_modules/@react-native/gradle-plugin') +includeBuild('../../../../node_modules/@react-native/gradle-plugin') apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle") useExpoModules() diff --git a/apps/native/app/package.json b/apps/native/app/package.json index 3ebb950c5cba..f742ee2bb587 100644 --- a/apps/native/app/package.json +++ b/apps/native/app/package.json @@ -90,7 +90,7 @@ "react-native-pdf": "6.7.5", "react-native-quick-actions": "0.3.13", "react-native-quick-base64": "2.1.2", - "react-native-reanimated": "3.12.1", + "react-native-reanimated": "3.16.5", "react-native-share": "10.2.1", "react-native-spotlight-search": "2.0.0", "react-native-svg": "15.2.0", diff --git a/codemagic.yaml b/codemagic.yaml index a0840a6144b2..e6d07bc39ad9 100644 --- a/codemagic.yaml +++ b/codemagic.yaml @@ -219,7 +219,7 @@ workflows: - island-upload-keystore groups: - google_credentials - - firebase_credentials + - firebase_credentials_dev vars: <<: *shared_envs PACKAGE_NAME: 'is.island.app.dev' diff --git a/yarn.lock b/yarn.lock index e0441eb6d923..26095abdf270 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2754,6 +2754,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-annotate-as-pure@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-annotate-as-pure@npm:7.25.9" + dependencies: + "@babel/types": ^7.25.9 + checksum: 41edda10df1ae106a9b4fe617bf7c6df77db992992afd46192534f5cff29f9e49a303231733782dd65c5f9409714a529f215325569f14282046e9d3b7a1ffb6c + languageName: node + linkType: hard + "@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.18.6": version: 7.18.9 resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.18.9" @@ -2954,6 +2963,23 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-class-features-plugin@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-create-class-features-plugin@npm:7.25.9" + dependencies: + "@babel/helper-annotate-as-pure": ^7.25.9 + "@babel/helper-member-expression-to-functions": ^7.25.9 + "@babel/helper-optimise-call-expression": ^7.25.9 + "@babel/helper-replace-supers": ^7.25.9 + "@babel/helper-skip-transparent-expression-wrappers": ^7.25.9 + "@babel/traverse": ^7.25.9 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 91dd5f203ed04568c70b052e2f26dfaac7c146447196c00b8ecbb6d3d2f3b517abadb985d3321a19d143adaed6fe17f7f79f8f50e0c20e9d8ad83e1027b42424 + languageName: node + linkType: hard + "@babel/helper-create-regexp-features-plugin@npm:^7.16.7, @babel/helper-create-regexp-features-plugin@npm:^7.17.12": version: 7.17.12 resolution: "@babel/helper-create-regexp-features-plugin@npm:7.17.12" @@ -3017,6 +3043,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-create-regexp-features-plugin@npm:^7.25.9": + version: 7.26.3 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.26.3" + dependencies: + "@babel/helper-annotate-as-pure": ^7.25.9 + regexpu-core: ^6.2.0 + semver: ^6.3.1 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 50a27d8ce6da5c2fa0c62c132c4d27cfeb36e3233ff1e5220d643de3dafe49423b507382f0b72a696fce7486014b134c1e742f55438590f9405d26765b009af0 + languageName: node + linkType: hard + "@babel/helper-define-polyfill-provider@npm:^0.3.3": version: 0.3.3 resolution: "@babel/helper-define-polyfill-provider@npm:0.3.3" @@ -3258,6 +3297,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-member-expression-to-functions@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-member-expression-to-functions@npm:7.25.9" + dependencies: + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: 8e2f1979b6d596ac2a8cbf17f2cf709180fefc274ac3331408b48203fe19134ed87800774ef18838d0275c3965130bae22980d90caed756b7493631d4b2cf961 + languageName: node + linkType: hard + "@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.16.0, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-module-imports@npm:7.18.6" @@ -3452,6 +3501,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-optimise-call-expression@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-optimise-call-expression@npm:7.25.9" + dependencies: + "@babel/types": ^7.25.9 + checksum: f09d0ad60c0715b9a60c31841b3246b47d67650c512ce85bbe24a3124f1a4d66377df793af393273bc6e1015b0a9c799626c48e53747581c1582b99167cc65dc + languageName: node + linkType: hard + "@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.13.0, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.16.7, @babel/helper-plugin-utils@npm:^7.17.12, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.19.0, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": version: 7.19.0 resolution: "@babel/helper-plugin-utils@npm:7.19.0" @@ -3494,6 +3552,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-plugin-utils@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-plugin-utils@npm:7.25.9" + checksum: e19ec8acf0b696756e6d84531f532c5fe508dce57aa68c75572a77798bd04587a844a9a6c8ea7d62d673e21fdc174d091c9097fb29aea1c1b49f9c6eaa80f022 + languageName: node + linkType: hard + "@babel/helper-remap-async-to-generator@npm:^7.18.9": version: 7.18.9 resolution: "@babel/helper-remap-async-to-generator@npm:7.18.9" @@ -3627,6 +3692,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-replace-supers@npm:7.25.9" + dependencies: + "@babel/helper-member-expression-to-functions": ^7.25.9 + "@babel/helper-optimise-call-expression": ^7.25.9 + "@babel/traverse": ^7.25.9 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 84f40e12520b7023e52d289bf9d569a06284879fe23bbbacad86bec5d978b2669769f11b073fcfeb1567d8c547168323005fda88607a4681ecaeb4a5cdd48bb9 + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.18.2, @babel/helper-simple-access@npm:^7.18.6": version: 7.19.4 resolution: "@babel/helper-simple-access@npm:7.19.4" @@ -3710,6 +3788,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.25.9" + dependencies: + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: fdbb5248932198bc26daa6abf0d2ac42cab9c2dbb75b7e9f40d425c8f28f09620b886d40e7f9e4e08ffc7aaa2cefe6fc2c44be7c20e81f7526634702fb615bdc + languageName: node + linkType: hard + "@babel/helper-split-export-declaration@npm:^7.16.7, @babel/helper-split-export-declaration@npm:^7.18.6": version: 7.18.6 resolution: "@babel/helper-split-export-declaration@npm:7.18.6" @@ -5153,6 +5241,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-class-properties@npm:^7.0.0-0": + version: 7.25.9 + resolution: "@babel/plugin-transform-class-properties@npm:7.25.9" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.25.9 + "@babel/helper-plugin-utils": ^7.25.9 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: a8d69e2c285486b63f49193cbcf7a15e1d3a5f632c1c07d7a97f65306df7f554b30270b7378dde143f8b557d1f8f6336c643377943dec8ec405e4cd11e90b9ea + languageName: node + linkType: hard + "@babel/plugin-transform-class-properties@npm:^7.22.3": version: 7.22.3 resolution: "@babel/plugin-transform-class-properties@npm:7.22.3" @@ -5234,6 +5334,22 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-classes@npm:^7.0.0-0": + version: 7.25.9 + resolution: "@babel/plugin-transform-classes@npm:7.25.9" + dependencies: + "@babel/helper-annotate-as-pure": ^7.25.9 + "@babel/helper-compilation-targets": ^7.25.9 + "@babel/helper-plugin-utils": ^7.25.9 + "@babel/helper-replace-supers": ^7.25.9 + "@babel/traverse": ^7.25.9 + globals: ^11.1.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: d12584f72125314cc0fa8c77586ece2888d677788ac75f7393f5da574dfe4e45a556f7e3488fab29c8777ab3e5856d7a2d79f6df02834083aaa9d766440e3c68 + languageName: node + linkType: hard + "@babel/plugin-transform-classes@npm:^7.21.0": version: 7.21.0 resolution: "@babel/plugin-transform-classes@npm:7.21.0" @@ -7372,6 +7488,18 @@ __metadata: languageName: node linkType: hard +"@babel/plugin-transform-unicode-regex@npm:^7.0.0-0": + version: 7.25.9 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.25.9" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.25.9 + "@babel/helper-plugin-utils": ^7.25.9 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: e8baae867526e179467c6ef5280d70390fa7388f8763a19a27c21302dd59b121032568be080749514b097097ceb9af716bf4b90638f1b3cf689aa837ba20150f + languageName: node + linkType: hard + "@babel/plugin-transform-unicode-regex@npm:^7.22.5": version: 7.22.5 resolution: "@babel/plugin-transform-unicode-regex@npm:7.22.5" @@ -13522,7 +13650,7 @@ __metadata: react-native-pdf: 6.7.5 react-native-quick-actions: 0.3.13 react-native-quick-base64: 2.1.2 - react-native-reanimated: 3.12.1 + react-native-reanimated: 3.16.5 react-native-share: 10.2.1 react-native-spotlight-search: 2.0.0 react-native-svg: 15.2.0 @@ -40842,7 +40970,7 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^3.0.2": +"jsesc@npm:^3.0.2, jsesc@npm:~3.0.2": version: 3.0.2 resolution: "jsesc@npm:3.0.2" bin: @@ -49993,15 +50121,18 @@ __metadata: languageName: node linkType: hard -"react-native-reanimated@npm:3.12.1": - version: 3.12.1 - resolution: "react-native-reanimated@npm:3.12.1" +"react-native-reanimated@npm:3.16.5": + version: 3.16.5 + resolution: "react-native-reanimated@npm:3.16.5" dependencies: "@babel/plugin-transform-arrow-functions": ^7.0.0-0 + "@babel/plugin-transform-class-properties": ^7.0.0-0 + "@babel/plugin-transform-classes": ^7.0.0-0 "@babel/plugin-transform-nullish-coalescing-operator": ^7.0.0-0 "@babel/plugin-transform-optional-chaining": ^7.0.0-0 "@babel/plugin-transform-shorthand-properties": ^7.0.0-0 "@babel/plugin-transform-template-literals": ^7.0.0-0 + "@babel/plugin-transform-unicode-regex": ^7.0.0-0 "@babel/preset-typescript": ^7.16.7 convert-source-map: ^2.0.0 invariant: ^2.2.4 @@ -50009,7 +50140,7 @@ __metadata: "@babel/core": ^7.0.0-0 react: "*" react-native: "*" - checksum: 91575b3a20a5878f42d0302cf304ed46ff35c12ce717018c0bfb6af047bf675f224ab95de778daae483b139e66c5290a661635c06304065879b02a5926243e1c + checksum: 29d28dcf99acb2e3928963106a2860d15c9929712832d8d8437fb563691d0199884a63e925548fe5e4b6fc7a9008eadec3e0294b521d9466c875caf16de9c303 languageName: node linkType: hard @@ -51053,6 +51184,15 @@ __metadata: languageName: node linkType: hard +"regenerate-unicode-properties@npm:^10.2.0": + version: 10.2.0 + resolution: "regenerate-unicode-properties@npm:10.2.0" + dependencies: + regenerate: ^1.4.2 + checksum: d5c5fc13f8b8d7e16e791637a4bfef741f8d70e267d51845ee7d5404a32fa14c75b181c4efba33e4bff8b0000a2f13e9773593713dfe5b66597df4259275ce63 + languageName: node + linkType: hard + "regenerate@npm:^1.4.2": version: 1.4.2 resolution: "regenerate@npm:1.4.2" @@ -51175,6 +51315,20 @@ __metadata: languageName: node linkType: hard +"regexpu-core@npm:^6.2.0": + version: 6.2.0 + resolution: "regexpu-core@npm:6.2.0" + dependencies: + regenerate: ^1.4.2 + regenerate-unicode-properties: ^10.2.0 + regjsgen: ^0.8.0 + regjsparser: ^0.12.0 + unicode-match-property-ecmascript: ^2.0.0 + unicode-match-property-value-ecmascript: ^2.1.0 + checksum: 67d3c4a3f6c99bc80b5d690074a27e6f675be1c1739f8a9acf028fbc36f1a468472574ea65e331e217995198ba4404d7878f3cb3739a73552dd3c70d3fb7f8e6 + languageName: node + linkType: hard + "regjsgen@npm:^0.6.0": version: 0.6.0 resolution: "regjsgen@npm:0.6.0" @@ -51182,6 +51336,24 @@ __metadata: languageName: node linkType: hard +"regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "regjsgen@npm:0.8.0" + checksum: a1d925ff14a4b2be774e45775ee6b33b256f89c42d480e6d85152d2133f18bd3d6af662161b226fa57466f7efec367eaf7ccd2a58c0ec2a1306667ba2ad07b0d + languageName: node + linkType: hard + +"regjsparser@npm:^0.12.0": + version: 0.12.0 + resolution: "regjsparser@npm:0.12.0" + dependencies: + jsesc: ~3.0.2 + bin: + regjsparser: bin/parser + checksum: 094b55b0ab3e1fd58f8ce5132a1d44dab08d91f7b0eea4132b0157b303ebb8ded20a9cbd893d25402d2aeddb23fac1f428ab4947b295d6fa51dd1c334a9e76f0 + languageName: node + linkType: hard + "regjsparser@npm:^0.8.2": version: 0.8.4 resolution: "regjsparser@npm:0.8.4" From 057fb9e7eb9df544c8a82c924a26e5551cb85a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3nas=20G=2E=20Sigur=C3=B0sson?= Date: Thu, 12 Dec 2024 16:11:28 +0000 Subject: [PATCH 04/32] feat(accident-notification): procure for accident notifications (#16337) * feat: start of procure for accident notifications * feat: adjust aplicantInformationMultiField for procure * fix: typo in message * chore: simplify conditions and small clean up * chore: remove unused functions * chore: remove console.log * chore: make mapUserToRole slightly cleaner * chore: more concise if statement * chore: trigger deploy-feature * chore: move constants to utils * fix: typo * feat: remove two custom components with text * chore: remove unused messages * chore: remove unused import * chore: remove comment --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/dataProviders/index.ts | 4 + .../src/fields/AgreementDescription/index.tsx | 25 ----- .../src/fields/DateOfAccident/index.tsx | 2 +- .../descriptionWithLink.css.ts | 11 --- .../src/fields/DescriptionWithLink/index.tsx | 43 -------- .../src/fields/FormOverview/index.tsx | 2 +- .../accident-notification/src/fields/index.ts | 2 - .../attachmentsSubSection.ts | 7 +- .../locationSubSection.ts | 2 +- .../workMachineSubSection.ts | 2 +- .../applicantInformationSection.ts | 2 - .../betaTestSection.ts | 24 ----- .../agreementDescriptionMultiField.ts | 30 ------ .../externalDataSection/index.ts | 10 -- .../forms/AccidentNotificationForm/index.ts | 6 -- .../juridicialPersonCompanySubSection.ts | 2 +- .../powerOfAttorneyUploadSubSection.ts | 2 +- .../whoIsTheNotificationForMultiField.ts | 39 ++++---- .../InReviewForm/addAttachmentsSection.ts | 2 +- .../PrerequisitesForm/dataHandlingSection.ts | 30 ++++++ .../externalDataSection.ts} | 25 ++++- .../src/forms/PrerequisitesForm/index.ts | 15 +++ .../externalDataSection.ts | 43 ++++++++ .../forms/PrerequisitesProcureForm/index.ts | 15 +++ .../src/lib/AccidentNotificationTemplate.ts | 98 ++++++++++++++++--- .../src/lib/dataSchema.ts | 2 +- .../src/lib/messages/applicantInformation.ts | 12 +++ .../src/lib/messages/externalData.ts | 58 +++++------ .../lib/messages/whoIsTheNotificationFor.ts | 10 ++ .../accident-notification/src/types/index.ts | 7 +- .../src/{ => utils}/constants/index.ts | 1 + .../getWhoIstheNotificationForOptions.ts | 32 ++++++ .../src/utils/getWorkplaceData.spec.ts | 2 +- .../src/utils/hasMissingDocuments.spec.ts | 2 +- .../src/utils/hasMissingDocuments.ts | 2 +- .../src/utils/index.spec.ts | 2 +- .../accident-notification/src/utils/index.ts | 2 +- .../src/utils/isFatalAccident.spec.ts | 2 +- .../src/utils/isFatalAccident.ts | 2 +- .../utils/isMachineRelatedAccident.spec.ts | 2 +- .../src/utils/isMachineRelatedAccident.ts | 2 +- ...RepresentativeOfCompanyOrInstitute.spec.ts | 2 +- .../isRepresentativeOfCompanyOrInstitute.ts | 2 +- .../announcement-of-death/src/types/index.ts | 4 - .../src/types/index.ts | 6 -- .../src/dataProviders/index.ts | 2 +- .../src/lib/dataSchema.ts | 2 +- .../src/types/index.ts | 6 -- .../src/fields/Overview/Overview.tsx | 14 +-- .../applicantInformationMultiField.ts | 12 +-- .../applicantInformationMultiField/types.ts | 2 +- 51 files changed, 349 insertions(+), 286 deletions(-) create mode 100644 libs/application/templates/accident-notification/src/dataProviders/index.ts delete mode 100644 libs/application/templates/accident-notification/src/fields/AgreementDescription/index.tsx delete mode 100644 libs/application/templates/accident-notification/src/fields/DescriptionWithLink/descriptionWithLink.css.ts delete mode 100644 libs/application/templates/accident-notification/src/fields/DescriptionWithLink/index.tsx delete mode 100644 libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/betaTestSection.ts delete mode 100644 libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/agreementDescriptionMultiField.ts delete mode 100644 libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/index.ts create mode 100644 libs/application/templates/accident-notification/src/forms/PrerequisitesForm/dataHandlingSection.ts rename libs/application/templates/accident-notification/src/forms/{AccidentNotificationForm/externalDataSection/accidentNotificationSubSection.ts => PrerequisitesForm/externalDataSection.ts} (74%) create mode 100644 libs/application/templates/accident-notification/src/forms/PrerequisitesForm/index.ts create mode 100644 libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/externalDataSection.ts create mode 100644 libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/index.ts rename libs/application/templates/accident-notification/src/{ => utils}/constants/index.ts (90%) create mode 100644 libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts diff --git a/libs/application/templates/accident-notification/src/dataProviders/index.ts b/libs/application/templates/accident-notification/src/dataProviders/index.ts new file mode 100644 index 000000000000..fb1bb027a65c --- /dev/null +++ b/libs/application/templates/accident-notification/src/dataProviders/index.ts @@ -0,0 +1,4 @@ +export { + IdentityApi, + NationalRegistryUserApi, +} from '@island.is/application/types' diff --git a/libs/application/templates/accident-notification/src/fields/AgreementDescription/index.tsx b/libs/application/templates/accident-notification/src/fields/AgreementDescription/index.tsx deleted file mode 100644 index 0470ab316795..000000000000 --- a/libs/application/templates/accident-notification/src/fields/AgreementDescription/index.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { FieldBaseProps } from '@island.is/application/types' -import { Bullet, Stack } from '@island.is/island-ui/core' -import { useLocale } from '@island.is/localization' -import React, { FC } from 'react' -import { externalData } from '../../lib/messages' - -export const AgreementDescription: FC< - React.PropsWithChildren -> = () => { - const { formatMessage } = useLocale() - - return ( - - - {formatMessage(externalData.agreementDescription.bulletOne)} - - - {formatMessage(externalData.agreementDescription.bulletTwo)} - - - {formatMessage(externalData.agreementDescription.bulletThree)} - - - ) -} diff --git a/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx b/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx index b212e92ae31b..27627c0f8f2b 100644 --- a/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx @@ -5,7 +5,7 @@ import { useLocale } from '@island.is/localization' import { DatePickerController } from '@island.is/shared/form-fields' import React, { FC, useCallback, useEffect, useState } from 'react' import { Controller, useFormContext } from 'react-hook-form' -import { NO, YES } from '../../constants' +import { NO, YES } from '../../utils/constants' import { useLazyIsHealthInsured } from '../../hooks/useLazyIsHealthInsured' import { AccidentNotification } from '../../lib/dataSchema' import { accidentDetails } from '../../lib/messages' diff --git a/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/descriptionWithLink.css.ts b/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/descriptionWithLink.css.ts deleted file mode 100644 index 8ed6d0294c97..000000000000 --- a/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/descriptionWithLink.css.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { style } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -export const link = style({ - color: theme.color.blue600, - selectors: { - '&:hover': { - backgroundColor: theme.color.purple100, - }, - }, -}) diff --git a/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/index.tsx b/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/index.tsx deleted file mode 100644 index b83eaff05827..000000000000 --- a/libs/application/templates/accident-notification/src/fields/DescriptionWithLink/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Link, Text } from '@island.is/island-ui/core' -import React, { FC } from 'react' -import { useLocale } from '@island.is/localization' -import { formatText } from '@island.is/application/core' -import { FieldBaseProps } from '@island.is/application/types' -import { Box } from '@island.is/island-ui/core' -import * as styles from './descriptionWithLink.css' - -type DescriptionLinkProps = { - field: { - props: { - descriptionFirstPart: string - descriptionSecondPart: string - linkName: string - url: string - } - } -} - -export const DescriptionWithLink: FC< - React.PropsWithChildren -> = ({ application, field }) => { - const { props } = field - const { formatMessage } = useLocale() - const { descriptionFirstPart, descriptionSecondPart, linkName, url } = props - return ( - - - - {`${formatText(descriptionFirstPart, application, formatMessage)} `} - - {` ${formatText( - linkName, - application, - formatMessage, - )}`} - - {formatText(descriptionSecondPart, application, formatMessage)} - - - - ) -} diff --git a/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx b/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx index e3401b90871a..3eb21101ca94 100644 --- a/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx @@ -18,7 +18,7 @@ import is from 'date-fns/locale/is' import parseISO from 'date-fns/parseISO' import kennitala from 'kennitala' import React, { FC } from 'react' -import { States, YES } from '../../constants' +import { States, YES } from '../../utils/constants' import { AccidentNotification } from '../../lib/dataSchema' import { accidentDetails, diff --git a/libs/application/templates/accident-notification/src/fields/index.ts b/libs/application/templates/accident-notification/src/fields/index.ts index d2880db80314..82bbce3df36a 100644 --- a/libs/application/templates/accident-notification/src/fields/index.ts +++ b/libs/application/templates/accident-notification/src/fields/index.ts @@ -1,8 +1,6 @@ -export { AgreementDescription } from './AgreementDescription' export { DateOfAccident } from './DateOfAccident' export { FormOverview } from './FormOverview' export { HiddenInformation } from './HiddenInformation' export { ApplicationStatus } from './ApplicationStatus' export { FormOverviewInReview } from './FormOverviewInReview' export { ProxyDocument } from './ProxyDocument' -export { DescriptionWithLink } from './DescriptionWithLink' diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts index 8d666ce9d97c..e8c71b90e331 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts @@ -21,7 +21,12 @@ import { isRepresentativeOfCompanyOrInstitute, } from '../../../utils' import { AttachmentsEnum } from '../../../types' -import { FILE_SIZE_LIMIT, NO, UPLOAD_ACCEPT, YES } from '../../../constants' +import { + FILE_SIZE_LIMIT, + NO, + UPLOAD_ACCEPT, + YES, +} from '../../../utils/constants' // Injury certificate and fatal accident section export const attachmentsSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts index 7e97ccbd88ae..be855a49a6f0 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts @@ -22,7 +22,7 @@ import { isRescueWorkAccident, isStudiesAccident, } from '../../../utils' -import { NO, YES } from '../../../constants' +import { NO, YES } from '../../../utils/constants' import { isSportAccidentAndEmployee } from '../../../utils/isSportAccidentAndEmployee' import { AgricultureAccidentLocationEnum, diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts index 67b73e98e2d6..bdfa59c43e79 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts @@ -10,7 +10,7 @@ import { isGeneralWorkplaceAccident, } from '../../../utils' import { isSportAccidentAndEmployee } from '../../../utils/isSportAccidentAndEmployee' -import { NO, YES } from '../../../constants' +import { NO, YES } from '../../../utils/constants' // Workmachine information only applicable to generic workplace accidents export const workMachineSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts index dc0cde867058..f91bcfaaee43 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts @@ -1,8 +1,6 @@ import { buildSection } from '@island.is/application/core' - import { applicantInformation } from '../../lib/messages' import { applicantInformationMultiField } from '@island.is/application/ui-forms' - export const applicantInformationSection = buildSection({ id: 'informationAboutApplicantSection', title: applicantInformation.general.title, diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/betaTestSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/betaTestSection.ts deleted file mode 100644 index c37d5bbc3359..000000000000 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/betaTestSection.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { buildCustomField, buildSection } from '@island.is/application/core' -import { betaTest } from '../../lib/messages' - -// Should only be here with the soft release, remove on official release. -export const betaTestSection = buildSection({ - id: 'betaTest.section', - title: betaTest.title, - children: [ - buildCustomField( - { - id: 'betaTest.section.textField', - title: betaTest.title, - component: 'DescriptionWithLink', - doesNotRequireAnswer: true, - }, - { - descriptionFirstPart: betaTest.descriptionFirstPart, - descriptionSecondPart: betaTest.descriptionSecondPart, - linkName: betaTest.emailText, - url: betaTest.email, - }, - ), - ], -}) diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/agreementDescriptionMultiField.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/agreementDescriptionMultiField.ts deleted file mode 100644 index ff2088966a1e..000000000000 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/agreementDescriptionMultiField.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { buildCustomField, buildMultiField } from '@island.is/application/core' -import { externalData } from '../../../lib/messages' - -export const agreementDescriptionMultiField = buildMultiField({ - title: externalData.agreementDescription.sectionTitle, - id: 'agreementDescriptionMultiField', - space: 2, - children: [ - buildCustomField({ - id: 'agreementDescriptionCustomField', - title: '', - component: 'AgreementDescription', - doesNotRequireAnswer: true, - }), - buildCustomField( - { - id: 'extrainformationWithDataprovider', - title: '', - component: 'DescriptionWithLink', - doesNotRequireAnswer: true, - }, - { - descriptionFirstPart: externalData.extraInformation.description, - descriptionSecondPart: '', - linkName: externalData.extraInformation.linkText, - url: externalData.extraInformation.link, - }, - ), - ], -}) diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/index.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/index.ts deleted file mode 100644 index d46bf5c0c1b0..000000000000 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { buildSection } from '@island.is/application/core' -import { agreementDescriptionMultiField } from './agreementDescriptionMultiField' -import { accidentNotificationSubSection } from './accidentNotificationSubSection' -import { externalData } from '../../../lib/messages' - -export const externalDataSection = buildSection({ - id: 'ExternalDataSection', - title: externalData.agreementDescription.listTitle, - children: [agreementDescriptionMultiField, accidentNotificationSubSection], -}) diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/index.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/index.ts index 82a2dfd20d95..e3b6e2d8ed99 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/index.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/index.ts @@ -2,14 +2,10 @@ import { buildForm } from '@island.is/application/core' import { Form, FormModes } from '@island.is/application/types' import Logo from '../../assets/Logo' import { application } from '../../lib/messages' - import { conclusionSection } from './conclusionSection' - import { overviewSection } from './overviewSection' -import { betaTestSection } from './betaTestSection' import { applicantInformationSection } from './applicantInformationSection' import { whoIsTheNotificationForSection } from './whoIsTheNotificationForSection' -import { externalDataSection } from './externalDataSection' import { aboutTheAccidentSection } from './aboutTheAccidentSection' export const AccidentNotificationForm: Form = buildForm({ @@ -18,8 +14,6 @@ export const AccidentNotificationForm: Form = buildForm({ logo: Logo, mode: FormModes.DRAFT, children: [ - betaTestSection, - externalDataSection, applicantInformationSection, whoIsTheNotificationForSection, aboutTheAccidentSection, diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts index 45ec29a5a2a7..5d747453c1d0 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts @@ -6,7 +6,7 @@ import { } from '@island.is/application/core' import { juridicalPerson } from '../../../lib/messages' import { isReportingOnBehalfOfEmployee } from '../../../utils' -import { YES } from '../../../constants' +import { YES } from '../../../utils/constants' export const juridicalPersonCompanySubSection = buildSubSection({ id: 'juridicalPerson.company', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts index d3defa608ae5..00ec8aff756d 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts @@ -5,7 +5,7 @@ import { buildSubSection, } from '@island.is/application/core' import { error, powerOfAttorney } from '../../../lib/messages' -import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../../constants' +import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../../utils/constants' import { isUploadNow } from '../../../utils/isUploadNow' export const powerOfAttorneyUploadSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts index 766ea3128bc2..d59f1f345a83 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts @@ -1,34 +1,33 @@ import { buildMultiField, buildRadioField } from '@island.is/application/core' import { whoIsTheNotificationFor } from '../../../lib/messages' -import { WhoIsTheNotificationForEnum } from '../../../types' +import { + whoIsTheNotificationForOptions, + whoIsTheNotificationForProcureOptions, +} from '../../../utils/getWhoIstheNotificationForOptions' export const whoIsTheNotificationForMultiField = buildMultiField({ id: 'whoIsTheNotificationFor', title: whoIsTheNotificationFor.general.heading, - description: whoIsTheNotificationFor.general.description, + description: (application) => { + if (application.externalData.identity) { + return whoIsTheNotificationFor.general.procureDescription + } + return whoIsTheNotificationFor.general.description + }, children: [ buildRadioField({ id: 'whoIsTheNotificationFor.answer', title: '', width: 'half', - options: [ - { - value: WhoIsTheNotificationForEnum.ME, - label: whoIsTheNotificationFor.labels.me, - }, - { - value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - label: whoIsTheNotificationFor.labels.powerOfAttorney, - }, - { - value: WhoIsTheNotificationForEnum.JURIDICALPERSON, - label: whoIsTheNotificationFor.labels.juridicalPerson, - }, - { - value: WhoIsTheNotificationForEnum.CHILDINCUSTODY, - label: whoIsTheNotificationFor.labels.childInCustody, - }, - ], + condition: (_answers, externalData) => !externalData.identity, + options: whoIsTheNotificationForOptions, + }), + buildRadioField({ + id: 'whoIsTheNotificationFor.answer', + title: '', + width: 'half', + condition: (_answers, externalData) => !!externalData.identity, + options: whoIsTheNotificationForProcureOptions, }), ], }) diff --git a/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts b/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts index 13d264c39118..f0c88a39c67a 100644 --- a/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts +++ b/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts @@ -7,7 +7,7 @@ import { buildSubmitField, } from '@island.is/application/core' import { DefaultEvents, FormValue } from '@island.is/application/types' -import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../constants' +import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../utils/constants' import { addDocuments, error } from '../../lib/messages' import { hasReceivedInjuryCertificate, diff --git a/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/dataHandlingSection.ts b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/dataHandlingSection.ts new file mode 100644 index 000000000000..240af507eadb --- /dev/null +++ b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/dataHandlingSection.ts @@ -0,0 +1,30 @@ +import { + buildDescriptionField, + buildMultiField, + buildSection, +} from '@island.is/application/core' +import { externalData } from '../../lib/messages' + +export const dataHandlingSection = buildSection({ + id: 'ExternalDataSection', + title: externalData.agreementDescription.listTitle, + children: [ + buildMultiField({ + title: externalData.agreementDescription.sectionTitle, + id: 'agreementDescriptionMultiField', + space: 2, + children: [ + buildDescriptionField({ + id: 'agreementDescriptionDescriptionField', + title: '', + description: externalData.agreementDescription.bullets, + }), + buildDescriptionField({ + id: 'moreInformation', + title: '', + description: externalData.agreementDescription.moreInformation, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/accidentNotificationSubSection.ts b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/externalDataSection.ts similarity index 74% rename from libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/accidentNotificationSubSection.ts rename to libs/application/templates/accident-notification/src/forms/PrerequisitesForm/externalDataSection.ts index 9551bdb5bad5..9edaba894625 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/externalDataSection/accidentNotificationSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/externalDataSection.ts @@ -1,13 +1,15 @@ import { buildDataProviderItem, buildExternalDataProvider, - buildSubSection, + buildSection, + buildSubmitField, + coreMessages, } from '@island.is/application/core' -import { externalData } from '../../../lib/messages' -import { NationalRegistryUserApi } from '@island.is/application/types' +import { externalData } from '../../lib/messages' +import { NationalRegistryUserApi } from '../../dataProviders' -export const accidentNotificationSubSection = buildSubSection({ - id: 'AccidentNotificationForm', +export const externalDataSection = buildSection({ + id: 'ExternalDataRegularSection', title: externalData.dataProvider.sectionTitle, children: [ buildExternalDataProvider({ @@ -16,6 +18,19 @@ export const accidentNotificationSubSection = buildSubSection({ subTitle: externalData.dataProvider.subTitle, description: '', checkboxLabel: externalData.dataProvider.checkboxLabel, + submitField: buildSubmitField({ + id: 'submit', + placement: 'footer', + title: '', + refetchApplicationAfterSubmit: true, + actions: [ + { + event: 'SUBMIT', + name: coreMessages.buttonNext, + type: 'primary', + }, + ], + }), dataProviders: [ buildDataProviderItem({ id: 'directoryOfLabor', diff --git a/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/index.ts b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/index.ts new file mode 100644 index 000000000000..89c7e17800ad --- /dev/null +++ b/libs/application/templates/accident-notification/src/forms/PrerequisitesForm/index.ts @@ -0,0 +1,15 @@ +import { buildForm } from '@island.is/application/core' +import { Form } from '@island.is/application/types' +import { application } from '../../lib/messages' +import Logo from '../../assets/Logo' +import { dataHandlingSection } from './dataHandlingSection' +import { externalDataSection } from './externalDataSection' + +export const PrerequisitesForm: Form = buildForm({ + id: 'PrerequisitesForm', + title: application.general.name, + logo: Logo, + renderLastScreenButton: true, + renderLastScreenBackButton: true, + children: [dataHandlingSection, externalDataSection], +}) diff --git a/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/externalDataSection.ts b/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/externalDataSection.ts new file mode 100644 index 000000000000..8cf32a765fd2 --- /dev/null +++ b/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/externalDataSection.ts @@ -0,0 +1,43 @@ +import { + buildDataProviderItem, + buildExternalDataProvider, + buildSection, + buildSubmitField, + coreMessages, +} from '@island.is/application/core' +import { externalData } from '../../lib/messages' +import { IdentityApi } from '../../dataProviders' + +export const externalDataSection = buildSection({ + id: 'ExternalDataProcureSection', + title: externalData.agreementDescription.listTitle, + children: [ + buildExternalDataProvider({ + title: externalData.dataProvider.pageTitle, + id: 'approveExternalData', + subTitle: externalData.dataProvider.subTitle, + description: '', + checkboxLabel: externalData.dataProvider.checkboxLabel, + submitField: buildSubmitField({ + id: 'submit', + placement: 'footer', + title: '', + refetchApplicationAfterSubmit: true, + actions: [ + { + event: 'SUBMIT', + name: coreMessages.buttonNext, + type: 'primary', + }, + ], + }), + dataProviders: [ + buildDataProviderItem({ + provider: IdentityApi, + title: externalData.nationalRegistry.title, + subTitle: externalData.nationalRegistry.subTitle, + }), + ], + }), + ], +}) diff --git a/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/index.ts b/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/index.ts new file mode 100644 index 000000000000..f792bfe3737a --- /dev/null +++ b/libs/application/templates/accident-notification/src/forms/PrerequisitesProcureForm/index.ts @@ -0,0 +1,15 @@ +import { buildForm } from '@island.is/application/core' +import { Form } from '@island.is/application/types' +import { application } from '../../lib/messages' +import Logo from '../../assets/Logo' +import { dataHandlingSection } from '../PrerequisitesForm/dataHandlingSection' +import { externalDataSection } from './externalDataSection' + +export const PrerequisitesProcureForm: Form = buildForm({ + id: 'PrerequisitesProcureForm', + title: application.general.name, + logo: Logo, + renderLastScreenButton: true, + renderLastScreenBackButton: true, + children: [dataHandlingSection, externalDataSection], +}) diff --git a/libs/application/templates/accident-notification/src/lib/AccidentNotificationTemplate.ts b/libs/application/templates/accident-notification/src/lib/AccidentNotificationTemplate.ts index 064f8b9d2530..e28f58669588 100644 --- a/libs/application/templates/accident-notification/src/lib/AccidentNotificationTemplate.ts +++ b/libs/application/templates/accident-notification/src/lib/AccidentNotificationTemplate.ts @@ -14,30 +14,33 @@ import { ApplicationTypes, DefaultEvents, defineTemplateApi, - NationalRegistryUserApi, PendingAction, + FormModes, } from '@island.is/application/types' import set from 'lodash/set' import { assign } from 'xstate' import { AccidentTypeEnum, ReviewApprovalEnum } from '..' -import { States } from '../constants' +import { States } from '../utils/constants' import { ApiActions } from '../shared' import { WhoIsTheNotificationForEnum } from '../types' import { AccidentNotificationSchema } from './dataSchema' import { anPendingActionMessages, application } from './messages' +import { AuthDelegationType } from '@island.is/shared/types' +import { IdentityApi, NationalRegistryUserApi } from '../dataProviders' // The applicant is the applicant of the application, can be someone in power of attorney or the representative for the company // The assignee is the person who is assigned to review the application can be the injured person or the representative for the company // The assignee should see all data related to the application being submitted to sjukra but not data only relevant to applicant enum Roles { + PROCURER = 'procurer', APPLICANT = 'applicant', ASSIGNEE = 'assignee', } type AccidentNotificationEvent = | { type: DefaultEvents.APPROVE } - | { type: DefaultEvents.SUBMIT } | { type: DefaultEvents.REJECT } + | { type: DefaultEvents.SUBMIT } | { type: DefaultEvents.ASSIGN } const assignStatePendingAction = ( @@ -61,7 +64,7 @@ const assignStatePendingAction = ( } const reviewStatePendingAction = ( - application: Application, + _application: Application, role: string, ): PendingAction => { if (role === Roles.ASSIGNEE) { @@ -91,15 +94,72 @@ const AccidentNotificationTemplate: ApplicationTemplate< ApplicationConfigurations.AccidentNotification.translation, ], dataSchema: AccidentNotificationSchema, + allowedDelegations: [ + { + type: AuthDelegationType.ProcurationHolder, + }, + { + type: AuthDelegationType.Custom, + }, + ], stateMachineConfig: { - initial: States.DRAFT, + initial: States.PREREQUISITES, states: { + [States.PREREQUISITES]: { + meta: { + name: application.general.name.defaultMessage, + progress: 0, + lifecycle: DefaultStateLifeCycle, + status: FormModes.DRAFT, + actionCard: { + historyLogs: [ + { + onEvent: DefaultEvents.SUBMIT, + logMessage: coreHistoryMessages.applicationStarted, + }, + ], + }, + roles: [ + { + id: Roles.APPLICANT, + formLoader: () => + import('../forms/PrerequisitesForm').then((val) => + Promise.resolve(val.PrerequisitesForm), + ), + actions: [ + { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' }, + ], + write: 'all', + api: [NationalRegistryUserApi, IdentityApi], + delete: true, + }, + { + id: Roles.PROCURER, + formLoader: () => + import('../forms/PrerequisitesProcureForm').then((val) => + Promise.resolve(val.PrerequisitesProcureForm), + ), + actions: [ + { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' }, + ], + write: 'all', + api: [NationalRegistryUserApi, IdentityApi], + delete: true, + }, + ], + }, + on: { + [DefaultEvents.SUBMIT]: { + target: States.DRAFT, + }, + }, + }, [States.DRAFT]: { meta: { name: application.general.name.defaultMessage, progress: 0.4, lifecycle: DefaultStateLifeCycle, - status: 'draft', + status: FormModes.DRAFT, actionCard: { historyLogs: [ { @@ -122,6 +182,19 @@ const AccidentNotificationTemplate: ApplicationTemplate< api: [NationalRegistryUserApi], delete: true, }, + { + id: Roles.PROCURER, + formLoader: () => + import('../forms/AccidentNotificationForm/index').then((val) => + Promise.resolve(val.AccidentNotificationForm), + ), + actions: [ + { event: 'SUBMIT', name: 'Staðfesta', type: 'primary' }, + ], + write: 'all', + api: [NationalRegistryUserApi], + delete: true, + }, ], }, on: { @@ -346,17 +419,16 @@ const AccidentNotificationTemplate: ApplicationTemplate< id: string, application: Application, ): ApplicationRole | undefined { - if (id === application.applicant && application.assignees.includes(id)) { - return Roles.ASSIGNEE - } + const { applicant, applicantActors, assignees } = application - if (id === application.applicant) { + if (id === applicant) { + if (applicantActors.length) return Roles.PROCURER + if (assignees.includes(id)) return Roles.ASSIGNEE return Roles.APPLICANT } - if (application.assignees.includes(id)) { - return Roles.ASSIGNEE - } + if (assignees.includes(id)) return Roles.ASSIGNEE + return undefined }, } diff --git a/libs/application/templates/accident-notification/src/lib/dataSchema.ts b/libs/application/templates/accident-notification/src/lib/dataSchema.ts index a9ee0e7b182b..afb53946fe3b 100644 --- a/libs/application/templates/accident-notification/src/lib/dataSchema.ts +++ b/libs/application/templates/accident-notification/src/lib/dataSchema.ts @@ -1,7 +1,7 @@ import { applicantInformationSchema } from '@island.is/application/ui-forms' import * as kennitala from 'kennitala' import { z } from 'zod' -import { YES } from '../constants' +import { YES } from '../utils/constants' import { AccidentTypeEnum, AgricultureAccidentLocationEnum, diff --git a/libs/application/templates/accident-notification/src/lib/messages/applicantInformation.ts b/libs/application/templates/accident-notification/src/lib/messages/applicantInformation.ts index 9c9a7954b983..e02b7d08abc8 100644 --- a/libs/application/templates/accident-notification/src/lib/messages/applicantInformation.ts +++ b/libs/application/templates/accident-notification/src/lib/messages/applicantInformation.ts @@ -55,6 +55,18 @@ export const applicantInformation = { description: 'Telephone number', }, }), + procure: defineMessages({ + titill: { + id: 'an.application:applicantInfo.procure.title', + defaultMessage: 'Upplýsingar um ', + description: 'Name of the procure identity', + }, + name: { + id: 'an.application:applicantInfo.procure.name', + defaultMessage: 'Nafn', + description: 'Name of the procure identity', + }, + }), forThirdParty: defineMessages({ title: { id: 'an.application:applicantInfo.forThirdParty.title', diff --git a/libs/application/templates/accident-notification/src/lib/messages/externalData.ts b/libs/application/templates/accident-notification/src/lib/messages/externalData.ts index 017a2fefda6f..869618dbdc54 100644 --- a/libs/application/templates/accident-notification/src/lib/messages/externalData.ts +++ b/libs/application/templates/accident-notification/src/lib/messages/externalData.ts @@ -12,30 +12,24 @@ export const externalData = { defaultMessage: 'Meðferð á gögnum', description: 'Data handling list item title', }, - bulletOne: { - id: 'an.application:section.agreementDescription.BulletOne', - defaultMessage: - 'Þegar tilkynning um slys er send Sjúkratryggingum Íslands mun stofnunin miðla upplýsingum um afstöðu til bótaskyldu með þeim atvinnurekanda eða íþróttafélagi sem á í hlut. Ástæðan þess er að umræddir aðilar kunna að eiga rétt á endurgreiðslu útlagðs kostnaðar og/eða dagpeningum ef greidd hafa verið laun í veikindaforföllum vegna slyssins. Þessir aðilar fá aldrei afhentar heilsufars- eða sjúkraskrárupplýsingar.', - description: 'List item 1 on data gathering information', - }, - bulletTwo: { - id: 'an.application:section.agreementDescription.BulletTwo', - defaultMessage: - 'Vinnueftirlit ríkisins kann einnig að fá afrit af tilkynningunni undir ákveðnum kringumstæðum á grundvelli 4. mgr. 79. gr. laga nr. 46/1980 sem og Rannsóknarnefnd samgönguslysa á grundvelli 12. og 16. gr. laga nr. 18/2013.', - description: 'List item 2 on data gathering information', - }, - bulletThree: { - id: 'an.application:section.agreementDescription.BulletThree', - defaultMessage: - 'Eitthvað óvænt verður að hafa gerst sem veldur tjóni á líkama hins tryggða og áhorfandi getur áttað sig á að hafi gerst.', - description: 'List item 3 on data gathering information', - }, bulletFour: { id: 'an.application:section.agreementDescription.BulletFour', defaultMessage: 'Ef tilkynningaskylda er vanrækt skal það ekki vera því til fyrirstöðu að sá slasaði eða vandamenn geti gert kröfu til bóta. Heimilt er að veita undanþágu þótt meira en ár sé liðið ef atvik slyss eru alveg ljós og drátturinn torveldar ekki gagnaöflun um atriði sem skipta máli. Þá er það skilyrði að unnt sé að meta orsakasamband slyssins og heilsutjóns slasaða.', description: 'List item 4 on data gathering information', }, + bullets: { + id: 'an.application:section.agreementDescription.bullets#markdown', + defaultMessage: + '* Þegar tilkynning um slys er send Sjúkratryggingum Íslands mun stofnunin miðla upplýsingum um afstöðu til bótaskyldu með þeim atvinnurekanda eða íþróttafélagi sem á í hlut. Ástæða þess er að umræddir aðilar kunna að eiga rétt á endurgreiðslu útlagðs kostnaðar og/eða dagpeningum ef greidd hafa verið laun í veikindaforföllum vegna slyssins. Þessir aðilar fá aldrei afhentar heilsufars- eða sjúkraskrárupplýsingar. \n\n* Vinnueftirlit ríkisins kann einnig að fá afrit af tilkynningunni undir ákveðnum kringumstæðum á grundvelli 4. mgr. 79. gr. laga nr. 46/1980 sem og Rannsóknarnefnd samgönguslysa á grundvelli 12. og 16. gr. laga nr. 18/2013. \n\n* Eitthvað óvænt verður að hafa gerst sem veldur tjóni á líkama hins tryggða og áhorfandi getur áttað sig á að hafi gerst.', + description: 'Information on data handling before prerequisites', + }, + moreInformation: { + id: 'an.application:section.agreementDescription.moreInformation#markdown', + defaultMessage: + 'Nánari upplýsingar um vinnslu persónuupplýsinga hjá Sjúkratryggingum Íslands á [Persónuverndarsíðu Sjúkratrygginga](https://www.sjukra.is/personuvernd)', + description: 'More information about data handling', + }, }), dataProvider: defineMessages({ sectionTitle: { @@ -72,6 +66,16 @@ export const externalData = { 'Upplýsingar um nafn, kennitölu og heimilisfang. Upplýsingar um börn og maka.', description: 'Description: National Registry', }, + procureDescription: { + id: 'an.application:section.externalData.nationalRegistry.procureDescription', + defaultMessage: 'Upplýsingar um nafn, kennitölu og heimilisfang.', + description: 'Description: National Registry for procure holder', + }, + subTitle: { + id: 'an.application:section.externalData.nationalRegistry.subTitle', + defaultMessage: 'Hér sækjum við nafn, kennitölu og heimilisfang', + description: 'We will fetch name, national id and address', + }, }), accidentProvider: defineMessages({ title: { @@ -152,22 +156,4 @@ export const externalData = { 'Approval of gathering information from Approval of Municipal Collection Agency', }, }), - extraInformation: defineMessages({ - description: { - id: 'an.application:section.externalData.extraInformation.descriptionFirstPart', - defaultMessage: - 'Nánari upplýsingar um vinnslu persónuupplýsinga hjá Sjúkratryggingum Íslands ', - description: 'Description for link in extrainformation', - }, - linkText: { - id: 'an.application:section.externalData.extraInformation.linkText', - defaultMessage: 'Persónuverndarsíðu SÍ.', - description: 'Link text for link', - }, - link: { - id: 'an.application:section.externalData.extraInformation.link', - defaultMessage: 'https://www.sjukra.is/personuvernd.', - description: 'The url the link text links to', - }, - }), } diff --git a/libs/application/templates/accident-notification/src/lib/messages/whoIsTheNotificationFor.ts b/libs/application/templates/accident-notification/src/lib/messages/whoIsTheNotificationFor.ts index 0c5a1b8195b3..035a2a62108f 100644 --- a/libs/application/templates/accident-notification/src/lib/messages/whoIsTheNotificationFor.ts +++ b/libs/application/templates/accident-notification/src/lib/messages/whoIsTheNotificationFor.ts @@ -17,6 +17,11 @@ export const whoIsTheNotificationFor = { defaultMessage: `Hægt er að tilkynna slys í eigin nafni , fyrir aðra einstaklinga sem þú ert með skriflegt umboð frá eða fyrir starfsmann lögaðila. Foreldrar og forráðamenn geta líka sent inn tilkynningu fyrir hönd barna sem þeir fara með forsjá yfir. Stofnanir, samtök og félög sem eru virk á sviði persónuverndar geta sent inn tilkynningu án umboðs að uppfylltum skilyrðum 80. gr. reglugerðar (ESB) 2016/679 (almennu persónuverndarreglugerðarinnar).`, description: 'Description for who is the notifaction for', }, + procureDescription: { + id: 'an.application:whoIsTheNotificationFor.procureDescription', + defaultMessage: `Í umboði er hægt að tilkynna slys fyrir einstaklinga sem þú ert með umboð frá eða fyrir starfsmann lögaðila. Foreldrar og forráðamenn geta líka sent inn tilkynningu fyrir hönd barna sem þeir fara með forsjá yfir. Stofnanir, samtök og félög sem eru virk á sviði persónuverndar geta sent inn tilkynningu án umboðs að uppfylltum skilyrðum 80. gr. reglugerðar (ESB) 2016/679 (almennu persónuverndarreglugerðarinnar).`, + description: 'Description for who is the notifaction for', + }, }), labels: defineMessages({ juridicalPerson: { @@ -34,6 +39,11 @@ export const whoIsTheNotificationFor = { defaultMessage: 'Í umboði fyrir annan einstakling', description: 'Label for power of attorney option', }, + powerOfAttorneyProcure: { + id: 'an.application:whoIsTheNotificationFor.labels.powerOfAttorneyProcure', + defaultMessage: 'Einstakling', + description: 'Label for power of attorney option', + }, childInCustody: { id: 'an.application:whoIsTheNotificationFor.labels.childInCustody', defaultMessage: 'Fyrir barn í minni forsjá', diff --git a/libs/application/templates/accident-notification/src/types/index.ts b/libs/application/templates/accident-notification/src/types/index.ts index 1b3694a9b695..da316a4fd5f7 100644 --- a/libs/application/templates/accident-notification/src/types/index.ts +++ b/libs/application/templates/accident-notification/src/types/index.ts @@ -1,4 +1,4 @@ -import { NO, YES } from './../constants' +import { NO, YES } from '../utils/constants' export type CompanyInfo = { nationalRegistrationId: string @@ -58,11 +58,6 @@ export enum ChoiceEnum { NO = 'no', } -export enum DataProviderTypes { - NationalRegistry = 'NationalRegistryProvider', - UserProfile = 'UserProfileProvider', -} - export enum WhoIsTheNotificationForEnum { JURIDICALPERSON = 'juridicalPerson', ME = 'me', diff --git a/libs/application/templates/accident-notification/src/constants/index.ts b/libs/application/templates/accident-notification/src/utils/constants/index.ts similarity index 90% rename from libs/application/templates/accident-notification/src/constants/index.ts rename to libs/application/templates/accident-notification/src/utils/constants/index.ts index f17e43d36595..c13413335ab9 100644 --- a/libs/application/templates/accident-notification/src/constants/index.ts +++ b/libs/application/templates/accident-notification/src/utils/constants/index.ts @@ -7,6 +7,7 @@ export const FILE_SIZE_LIMIT = 10000000 // 10MB export enum States { // Draft flow + PREREQUISITES = 'prerequisites', DRAFT = 'draft', REVIEW = 'review', REVIEW_ADD_ATTACHMENT = 'reviewAddAttachment', diff --git a/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts b/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts new file mode 100644 index 000000000000..28910229cf83 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts @@ -0,0 +1,32 @@ +import { WhoIsTheNotificationForEnum } from '../types' +import { whoIsTheNotificationFor } from '../lib/messages' + +export const whoIsTheNotificationForOptions = [ + { + value: WhoIsTheNotificationForEnum.ME, + label: whoIsTheNotificationFor.labels.me, + }, + { + value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + label: whoIsTheNotificationFor.labels.powerOfAttorney, + }, + { + value: WhoIsTheNotificationForEnum.JURIDICALPERSON, + label: whoIsTheNotificationFor.labels.juridicalPerson, + }, + { + value: WhoIsTheNotificationForEnum.CHILDINCUSTODY, + label: whoIsTheNotificationFor.labels.childInCustody, + }, +] + +export const whoIsTheNotificationForProcureOptions = [ + { + value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + label: whoIsTheNotificationFor.labels.powerOfAttorneyProcure, + }, + { + value: WhoIsTheNotificationForEnum.JURIDICALPERSON, + label: whoIsTheNotificationFor.labels.juridicalPerson, + }, +] diff --git a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts b/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts index 83bd9755d9ad..45a3cb6d6a11 100644 --- a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts @@ -1,5 +1,5 @@ import { FormValue } from '@island.is/application/types' -import { YES } from '../constants' +import { YES } from './constants' import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' import { getWorkplaceData } from './getWorkplaceData' diff --git a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts index b36f131d049a..945c4858ce4f 100644 --- a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts @@ -4,7 +4,7 @@ import { hasReceivedAllDocuments, } from './hasMissingDocuments' import { WhoIsTheNotificationForEnum, AttachmentsEnum } from '../types' -import { NO, YES } from '../constants' +import { NO, YES } from './constants' import { FormatMessage } from '@island.is/localization' import { FormValue } from '@island.is/application/types' import { AccidentNotification } from '../lib/dataSchema' diff --git a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts index 3c53fe8daf71..d262c07b6226 100644 --- a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts +++ b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts @@ -2,7 +2,7 @@ import { getValueViaPath } from '@island.is/application/core' import { FormValue } from '@island.is/application/types' import { FormatMessage } from '@island.is/localization' import { AttachmentsEnum, FileType, WhoIsTheNotificationForEnum } from '..' -import { YES } from '../constants' +import { YES } from './constants' import { attachments } from '../lib/messages' import { AccidentNotificationAttachmentStatus, diff --git a/libs/application/templates/accident-notification/src/utils/index.spec.ts b/libs/application/templates/accident-notification/src/utils/index.spec.ts index 33d834780e7d..9bde4080715f 100644 --- a/libs/application/templates/accident-notification/src/utils/index.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/index.spec.ts @@ -1,5 +1,5 @@ import { FormatMessage } from '@island.is/localization' -import { YES } from '../constants' +import { YES } from './constants' import { AccidentNotification } from '../lib/dataSchema' import { AttachmentsEnum, WhoIsTheNotificationForEnum } from '../types' import { diff --git a/libs/application/templates/accident-notification/src/utils/index.ts b/libs/application/templates/accident-notification/src/utils/index.ts index 969019bb45bf..2c1059df92f6 100644 --- a/libs/application/templates/accident-notification/src/utils/index.ts +++ b/libs/application/templates/accident-notification/src/utils/index.ts @@ -1,6 +1,6 @@ import { AttachmentsEnum, FileType, WhoIsTheNotificationForEnum } from '..' import { getValueViaPath } from '@island.is/application/core' -import { YES } from '../constants' +import { YES } from './constants' import { AccidentNotification } from '../lib/dataSchema' import { attachments, overview } from '../lib/messages' import { FormatMessage } from '@island.is/localization' diff --git a/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts index e1e2118355d3..67b9f7bb25ec 100644 --- a/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts @@ -1,6 +1,6 @@ import { FormValue } from '@island.is/application/types' import { isFatalAccident } from './isFatalAccident' -import { NO, YES } from '../constants' +import { NO, YES } from './constants' describe('isFatalAccident', () => { const fatal: FormValue = { diff --git a/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts b/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts index 3866ad16930f..4094c3efbc99 100644 --- a/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts +++ b/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts @@ -1,6 +1,6 @@ import { getValueViaPath } from '@island.is/application/core' import { FormValue } from '@island.is/application/types' -import { YES } from '../constants' +import { YES } from './constants' import { YesOrNo } from '../types' export const isFatalAccident = (formValue: FormValue) => { diff --git a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts index 6a66f77d0ad2..017a1e679a26 100644 --- a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts @@ -1,5 +1,5 @@ import { FormValue } from '@island.is/application/types' -import { NO, YES } from '../constants' +import { NO, YES } from './constants' import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' import { isMachineRelatedAccident } from './isMachineRelatedAccident' describe('isMachineRelatedAccident', () => { diff --git a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts index 627f2da6c98b..fd3cabc5347b 100644 --- a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts +++ b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts @@ -1,6 +1,6 @@ import { getValueViaPath } from '@island.is/application/core' import { FormValue } from '@island.is/application/types' -import { YES } from '../constants' +import { YES } from './constants' import { YesOrNo } from '../types' import { isGeneralWorkplaceAccident } from './isGeneralWorkplaceAccident' diff --git a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts index f1ce2bcfd63c..aeff9475efef 100644 --- a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts @@ -5,7 +5,7 @@ import { isInjuredAndRepresentativeOfCompanyOrInstitute, isRepresentativeOfCompanyOrInstitute, } from './isRepresentativeOfCompanyOrInstitute' -import { NO, YES } from '../constants' +import { NO, YES } from './constants' const emptyObject = {} diff --git a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts index 77ba93c9a40a..f8c98b7b61f5 100644 --- a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts +++ b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts @@ -1,6 +1,6 @@ import { getValueViaPath } from '@island.is/application/core' import { FormValue } from '@island.is/application/types' -import { YES } from '../constants' +import { YES } from './constants' import { WhoIsTheNotificationForEnum } from '../types' export const isRepresentativeOfCompanyOrInstitute = (formValue: FormValue) => { diff --git a/libs/application/templates/announcement-of-death/src/types/index.ts b/libs/application/templates/announcement-of-death/src/types/index.ts index 191ffbeb2b7c..537b31b4a217 100644 --- a/libs/application/templates/announcement-of-death/src/types/index.ts +++ b/libs/application/templates/announcement-of-death/src/types/index.ts @@ -22,7 +22,3 @@ export interface Child { export interface NationalRegistry extends Person { children: Child[] } - -export enum DataProviderTypes { - NationalRegistry = 'NationalRegistryProvider', -} diff --git a/libs/application/templates/family-matters/children-residence-change-v2/src/types/index.ts b/libs/application/templates/family-matters/children-residence-change-v2/src/types/index.ts index 0a917b6ab728..9c90065864d8 100644 --- a/libs/application/templates/family-matters/children-residence-change-v2/src/types/index.ts +++ b/libs/application/templates/family-matters/children-residence-change-v2/src/types/index.ts @@ -23,9 +23,3 @@ export type CRCFieldBaseProps = Override< FieldBaseProps, { application: CRCApplication; errors: ErrorSchema } > - -export enum DataProviderTypes { - MockNationalRegistry = 'MockNationalRegistryProvider', - NationalRegistry = 'NationalRegistryProvider', - UserProfile = 'UserProfileProvider', -} diff --git a/libs/application/templates/general-fishing-license/src/dataProviders/index.ts b/libs/application/templates/general-fishing-license/src/dataProviders/index.ts index 90bb14e08174..57a090f5ae3d 100644 --- a/libs/application/templates/general-fishing-license/src/dataProviders/index.ts +++ b/libs/application/templates/general-fishing-license/src/dataProviders/index.ts @@ -20,5 +20,5 @@ export const ShipRegistryApi = defineTemplateApi({ }) export const IdentityApi = IdsApi.configure({ - externalDataId: 'identityRegistry', + externalDataId: 'identity', }) diff --git a/libs/application/templates/general-fishing-license/src/lib/dataSchema.ts b/libs/application/templates/general-fishing-license/src/lib/dataSchema.ts index 693e7797bf0b..90cfc3b6e76b 100644 --- a/libs/application/templates/general-fishing-license/src/lib/dataSchema.ts +++ b/libs/application/templates/general-fishing-license/src/lib/dataSchema.ts @@ -16,7 +16,7 @@ const FileSchema = z.object({ export const GeneralFishingLicenseSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), externalData: z.object({ - identityRegistry: z.object({ + identity: z.object({ data: z.object({ date: z.string(), status: z.enum(['success', 'failure']), diff --git a/libs/application/templates/general-fishing-license/src/types/index.ts b/libs/application/templates/general-fishing-license/src/types/index.ts index 5c7c341f29b7..d5b63ee5f9d5 100644 --- a/libs/application/templates/general-fishing-license/src/types/index.ts +++ b/libs/application/templates/general-fishing-license/src/types/index.ts @@ -1,9 +1,3 @@ -export enum DataProviderTypes { - NationalRegistry = 'NationalRegistryProvider', - UserProfile = 'UserProfileProvider', - IdentityRegistry = 'IdentityProvider', -} - export enum FishingLicenseEnum { HOOKCATCHLIMIT = 'hookCatchLimit', FISHWITHDANISHSEINE = 'fishWithDanishSeine', // Dragnótaveiðileyfi diff --git a/libs/application/templates/public-debt-payment-plan/src/fields/Overview/Overview.tsx b/libs/application/templates/public-debt-payment-plan/src/fields/Overview/Overview.tsx index dc2d8f8c5f84..59646a7a88ad 100644 --- a/libs/application/templates/public-debt-payment-plan/src/fields/Overview/Overview.tsx +++ b/libs/application/templates/public-debt-payment-plan/src/fields/Overview/Overview.tsx @@ -53,7 +53,7 @@ export const Overview = ({ application, goToScreen }: FieldBaseProps) => { 'paymentPlans', ) as PaymentPlan[] - const identityRegistry = getValueViaPath( + const identity = getValueViaPath( application.externalData, 'identity', ) as IdentityResult @@ -138,14 +138,14 @@ export const Overview = ({ application, goToScreen }: FieldBaseProps) => { editAction('applicantSection')}> - {identityRegistry?.data?.name && ( + {identity?.data?.name && ( - {identityRegistry.data.name} + {identity.data.name} )} {applicant?.phoneNumber && ( @@ -158,12 +158,12 @@ export const Overview = ({ application, goToScreen }: FieldBaseProps) => { )} - {identityRegistry?.data?.address?.streetAddress && - identityRegistry?.data?.address?.postalCode && - identityRegistry?.data?.address?.city && ( + {identity?.data?.address?.streetAddress && + identity?.data?.address?.postalCode && + identity?.data?.address?.city && ( - {`${identityRegistry?.data?.address?.streetAddress}, ${identityRegistry?.data?.address?.postalCode} ${identityRegistry?.data?.address?.city}`} + {`${identity?.data?.address?.streetAddress}, ${identity?.data?.address?.postalCode} ${identity?.data?.address?.city}`} )} {applicant?.email && ( diff --git a/libs/application/ui-forms/src/lib/applicantInformationMultiField/applicantInformationMultiField.ts b/libs/application/ui-forms/src/lib/applicantInformationMultiField/applicantInformationMultiField.ts index 48052a903ad8..eaa4840bacd7 100644 --- a/libs/application/ui-forms/src/lib/applicantInformationMultiField/applicantInformationMultiField.ts +++ b/libs/application/ui-forms/src/lib/applicantInformationMultiField/applicantInformationMultiField.ts @@ -35,7 +35,7 @@ export const applicantInformationMultiField = ( disabled: true, defaultValue: (application: ApplicantInformationInterface) => application.externalData?.nationalRegistry?.data?.fullName ?? - application.externalData?.identityRegistry?.data?.name ?? + application.externalData?.identity?.data?.name ?? '', }), buildTextField({ @@ -47,7 +47,7 @@ export const applicantInformationMultiField = ( disabled: true, defaultValue: (application: ApplicantInformationInterface) => application.externalData?.nationalRegistry?.data?.nationalId ?? - application.externalData?.identityRegistry?.data?.nationalId ?? + application.externalData?.identity?.data?.nationalId ?? '', }), buildTextField({ @@ -59,8 +59,7 @@ export const applicantInformationMultiField = ( defaultValue: (application: ApplicantInformationInterface) => application.externalData?.nationalRegistry?.data?.address ?.streetAddress ?? - application.externalData?.identityRegistry?.data?.address - ?.streetAddress ?? + application.externalData?.identity?.data?.address?.streetAddress ?? '', }), buildTextField({ @@ -74,8 +73,7 @@ export const applicantInformationMultiField = ( return ( application.externalData?.nationalRegistry?.data?.address ?.postalCode ?? - application.externalData?.identityRegistry?.data?.address - ?.postalCode ?? + application.externalData?.identity?.data?.address?.postalCode ?? '' ) }, @@ -88,7 +86,7 @@ export const applicantInformationMultiField = ( disabled: true, defaultValue: (application: ApplicantInformationInterface) => application.externalData?.nationalRegistry?.data?.address?.city ?? - application.externalData?.identityRegistry?.data?.address?.city ?? + application.externalData?.identity?.data?.address?.city ?? '', }), buildTextField({ diff --git a/libs/application/ui-forms/src/lib/applicantInformationMultiField/types.ts b/libs/application/ui-forms/src/lib/applicantInformationMultiField/types.ts index eccb0b392c5d..e2f87089ef71 100644 --- a/libs/application/ui-forms/src/lib/applicantInformationMultiField/types.ts +++ b/libs/application/ui-forms/src/lib/applicantInformationMultiField/types.ts @@ -2,7 +2,7 @@ import { FormText } from '@island.is/application/types' export interface ApplicantInformationInterface { externalData: { // new dataprovider - identityRegistry: { + identity: { data: { name: 'string' nationalId: 'string' From de0bf4ccecc86a77600fc42e6e065da7cf7c7ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Thu, 12 Dec 2024 21:12:47 +0000 Subject: [PATCH 05/32] =?UTF-8?q?feat(web):=20Global=20search=20alias=20fo?= =?UTF-8?q?r=20'Vinnum=C3=A1lastofnun'=20(#17204)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- libs/content-search-toolkit/src/queries/search.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/content-search-toolkit/src/queries/search.ts b/libs/content-search-toolkit/src/queries/search.ts index d8bde3c182ea..82cdb3f98f53 100644 --- a/libs/content-search-toolkit/src/queries/search.ts +++ b/libs/content-search-toolkit/src/queries/search.ts @@ -35,6 +35,8 @@ export const searchQuery = ( // Handle aliases since the search engine has not been configured to support organization aliases if (queryString.trim().toLowerCase() === 'tr') { queryString = 'Tryggingastofnun' + } else if (queryString.trim().toLowerCase() === 'vmst') { + queryString = 'Vinnumálastofnun' } // * wildcard support for internal clients - eg. used by island.is app From 992ef025b28aadf8941bebe05e3c88d54ec19a4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Eorkell=20M=C3=A1ni=20=C3=9Eorkelsson?= Date: Thu, 12 Dec 2024 21:55:36 +0000 Subject: [PATCH 06/32] feat(web): updated grant status logic (#17127) * feat: updated status logic * feat: add time values * feat: add time part * chore: remove conidtional * chore: remove imports * fix: wrong message id * fix: add /en locale * fix: undefined if empty array --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/web/pages/en/grants-plaza/grant/[id].ts | 12 ++ .../web/pages/en/grants-plaza/grants/index.ts | 12 ++ apps/web/pages/en/grants-plaza/index.ts | 11 ++ .../web/screens/Grants/Grant/GrantSidebar.tsx | 23 ++- apps/web/screens/Grants/Home/GrantsHome.tsx | 3 +- .../SearchResults/SearchResultsContent.tsx | 22 +-- apps/web/screens/Grants/messages.ts | 30 +++- apps/web/screens/Grants/utils.ts | 138 ++++++++++++++-- apps/web/screens/queries/Grants.ts | 5 +- libs/cms/src/lib/cms.elasticsearch.service.ts | 30 +--- .../src/lib/generated/contentfulTypes.d.ts | 23 ++- libs/cms/src/lib/models/grant.model.ts | 156 ++++++++++++------ .../lib/search/importers/grants.service.ts | 12 +- 13 files changed, 347 insertions(+), 130 deletions(-) create mode 100644 apps/web/pages/en/grants-plaza/grant/[id].ts create mode 100644 apps/web/pages/en/grants-plaza/grants/index.ts create mode 100644 apps/web/pages/en/grants-plaza/index.ts diff --git a/apps/web/pages/en/grants-plaza/grant/[id].ts b/apps/web/pages/en/grants-plaza/grant/[id].ts new file mode 100644 index 000000000000..bc85b78454d8 --- /dev/null +++ b/apps/web/pages/en/grants-plaza/grant/[id].ts @@ -0,0 +1,12 @@ +import withApollo from '@island.is/web/graphql/withApollo' +import { withLocale } from '@island.is/web/i18n' +import GrantSinglePage from '@island.is/web/screens/Grants/Grant/Grant' +import { getServerSidePropsWrapper } from '@island.is/web/utils/getServerSidePropsWrapper' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore make web strict +// +const Screen = withApollo(withLocale('en')(GrantSinglePage)) + +export default Screen + +export const getServerSideProps = getServerSidePropsWrapper(Screen) diff --git a/apps/web/pages/en/grants-plaza/grants/index.ts b/apps/web/pages/en/grants-plaza/grants/index.ts new file mode 100644 index 000000000000..15cf49a9aa93 --- /dev/null +++ b/apps/web/pages/en/grants-plaza/grants/index.ts @@ -0,0 +1,12 @@ +import withApollo from '@island.is/web/graphql/withApollo' +import { withLocale } from '@island.is/web/i18n' +import GrantsSearchResults from '@island.is/web/screens/Grants/SearchResults/SearchResults' +import { getServerSidePropsWrapper } from '@island.is/web/utils/getServerSidePropsWrapper' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore make web strict +// +const Screen = withApollo(withLocale('en')(GrantsSearchResults)) + +export default Screen + +export const getServerSideProps = getServerSidePropsWrapper(Screen) diff --git a/apps/web/pages/en/grants-plaza/index.ts b/apps/web/pages/en/grants-plaza/index.ts new file mode 100644 index 000000000000..a95dff22d022 --- /dev/null +++ b/apps/web/pages/en/grants-plaza/index.ts @@ -0,0 +1,11 @@ +import withApollo from '@island.is/web/graphql/withApollo' +import { withLocale } from '@island.is/web/i18n' +import GrantsHome from '@island.is/web/screens/Grants/Home/GrantsHome' +import { getServerSidePropsWrapper } from '@island.is/web/utils/getServerSidePropsWrapper' +// eslint-disable-next-line @typescript-eslint/ban-ts-comment +// @ts-ignore make web strict +const Screen = withApollo(withLocale('en')(GrantsHome)) + +export default Screen + +export const getServerSideProps = getServerSidePropsWrapper(Screen) diff --git a/apps/web/screens/Grants/Grant/GrantSidebar.tsx b/apps/web/screens/Grants/Grant/GrantSidebar.tsx index fa83f4377950..77ac8aa2ac73 100644 --- a/apps/web/screens/Grants/Grant/GrantSidebar.tsx +++ b/apps/web/screens/Grants/Grant/GrantSidebar.tsx @@ -1,4 +1,5 @@ import { useMemo } from 'react' +import { useIntl } from 'react-intl' import { Box, @@ -16,7 +17,7 @@ import { Grant } from '@island.is/web/graphql/schema' import { LinkType, useLinkResolver } from '@island.is/web/hooks' import { m } from '../messages' -import { generateStatusTag } from '../utils' +import { generateStatusTag, parseStatus } from '../utils' interface Props { grant: Grant @@ -41,7 +42,7 @@ const generateSidebarPanel = ( data: Array, background: BoxProps['background'], ) => { - if (!data) { + if (!data.length) { return undefined } return ( @@ -53,7 +54,12 @@ const generateSidebarPanel = ( export const GrantSidebar = ({ grant, locale }: Props) => { const { linkResolver } = useLinkResolver() - const { formatMessage } = useLocale() + const { formatMessage } = useIntl() + + const status = useMemo( + () => parseStatus(grant, formatMessage, locale), + [grant, formatMessage, locale], + ) const detailPanelData = useMemo( () => @@ -95,20 +101,23 @@ export const GrantSidebar = ({ grant, locale }: Props) => { ), generateLine( formatMessage(m.single.deadline), - grant?.applicationDeadlineStatus ? ( - {grant.applicationDeadlineStatus} + status.deadlineStatus ? ( + {status.deadlineStatus} ) : undefined, ), generateLine( formatMessage(m.single.status), grant?.status ? ( - {generateStatusTag(grant.status, formatMessage)?.label} + { + generateStatusTag(status.applicationStatus, formatMessage) + ?.label + } ) : undefined, ), ].filter(isDefined) ?? [], - [grant, formatMessage, linkResolver], + [grant, formatMessage, linkResolver, status], ) const filesPanelData = useMemo( diff --git a/apps/web/screens/Grants/Home/GrantsHome.tsx b/apps/web/screens/Grants/Home/GrantsHome.tsx index 83ed0453f013..0b75b23ec399 100644 --- a/apps/web/screens/Grants/Home/GrantsHome.tsx +++ b/apps/web/screens/Grants/Home/GrantsHome.tsx @@ -42,8 +42,9 @@ const GrantsHomePage: CustomScreen = ({ locale, customPageData, }) => { - const { formatMessage } = useIntl() + const intl = useIntl() const { linkResolver } = useLinkResolver() + const { formatMessage } = intl const baseUrl = linkResolver('styrkjatorg', [], locale).href const searchUrl = linkResolver('styrkjatorgsearch', [], locale).href diff --git a/apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx b/apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx index 071b7f063483..d57cece2196d 100644 --- a/apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx +++ b/apps/web/screens/Grants/SearchResults/SearchResultsContent.tsx @@ -1,4 +1,3 @@ -import { useIntl } from 'react-intl' import { useWindowSize } from 'react-use' import format from 'date-fns/format' import { useRouter } from 'next/router' @@ -13,7 +12,7 @@ import { Grant } from '@island.is/web/graphql/schema' import { useLinkResolver } from '@island.is/web/hooks' import { m } from '../messages' -import { generateStatusTag } from '../utils' +import { generateStatusTag, parseStatus } from '../utils' interface Props { grants?: Array @@ -44,6 +43,7 @@ export const SearchResultsContent = ({ grants, subheader, locale }: Props) => { return null } + const status = parseStatus(grant, formatMessage, locale) return ( {grant.applicationId && ( @@ -54,11 +54,10 @@ export const SearchResultsContent = ({ grants, subheader, locale }: Props) => { text={grant.description ?? ''} logo={grant.fund?.parentOrganization?.logo?.url ?? ''} logoAlt={grant.fund?.parentOrganization?.logo?.title ?? ''} - tag={ - grant.status - ? generateStatusTag(grant.status, formatMessage) - : undefined - } + tag={generateStatusTag( + status.applicationStatus, + formatMessage, + )} cta={{ label: formatMessage(m.general.seeMore), variant: 'text', @@ -80,14 +79,17 @@ export const SearchResultsContent = ({ grants, subheader, locale }: Props) => { text: `${format( new Date(grant.dateFrom), 'dd.MM.', - )}-${format(new Date(grant.dateTo), 'dd.MM.yyyy')}`, + )} - ${format( + new Date(grant.dateTo), + 'dd.MM.yyyy', + )}`, } : null, - grant.applicationDeadlineStatus + status.deadlineStatus ? { icon: 'time' as const, //todo: fix when the text is ready - text: grant.applicationDeadlineStatus, + text: status.deadlineStatus, } : undefined, grant.categoryTags diff --git a/apps/web/screens/Grants/messages.ts b/apps/web/screens/Grants/messages.ts index 3cc01d29b27d..4cb32b60e623 100644 --- a/apps/web/screens/Grants/messages.ts +++ b/apps/web/screens/Grants/messages.ts @@ -34,7 +34,7 @@ export const m = { }, applicationStatus: { id: 'web.grants:search.applicationStatus', - defaultMessage: 'Staða umsóknar', + defaultMessage: 'Staða umsókna', }, applicationOpen: { id: 'web.grants:search.applicationOpen', @@ -52,6 +52,34 @@ export const m = { id: 'web.grants:search.applicationSeeDescription', defaultMessage: 'Sjá lýsingu', }, + applicationOpensAt: { + id: 'web.grants:search.applicationOpensAt', + defaultMessage: 'Opnar {arg}', + }, + applicationEstimatedOpensAt: { + id: 'web.grants:search.applicationEstimatedOpensAt', + defaultMessage: 'Áætlað næst í {arg}', + }, + applicationOpensTo: { + id: 'web.grants:search.applicationOpensTo', + defaultMessage: 'Frestur til {arg}', + }, + applicationOpensToWithDay: { + id: 'web.grants:search.applicationOpensToWithDay', + defaultMessage: 'Frestur til og með {arg}', + }, + applicationWasOpenTo: { + id: 'web.grants:search.applicationWasOpenTo', + defaultMessage: 'Frestur var til {arg}', + }, + applicationWasOpenToAndWith: { + id: 'web.grants:search.applicationWasOpenToAndWith', + defaultMessage: 'Frestur var til og með {arg}', + }, + applicationAlwaysOpen: { + id: 'web.grants:search.applicationAlwaysOpen', + defaultMessage: 'Opið er allt árið', + }, category: { id: 'web.grants:search.category', defaultMessage: 'Flokkun', diff --git a/apps/web/screens/Grants/utils.ts b/apps/web/screens/Grants/utils.ts index 23ac43a63f74..86920ea957a4 100644 --- a/apps/web/screens/Grants/utils.ts +++ b/apps/web/screens/Grants/utils.ts @@ -1,29 +1,131 @@ -import { TagVariant } from '@island.is/island-ui/core' +import format from 'date-fns/format' +import localeEn from 'date-fns/locale/en-GB' +import localeIS from 'date-fns/locale/is' + import { FormatMessage } from '@island.is/localization' -import { GrantStatus } from '@island.is/web/graphql/schema' +import { Locale } from '@island.is/shared/types' +import { Grant, GrantStatus } from '@island.is/web/graphql/schema' + import { m } from './messages' +import { IntlFormatters, IntlShape } from 'react-intl' -export const generateStatusTag = ( - status: GrantStatus, - formatMessage: FormatMessage, -): { label: string; variant: TagVariant } | undefined => { - switch (status) { - case GrantStatus.Open: +interface Status { + applicationStatus: 'open' | 'closed' | 'unknown' + deadlineStatus: string + note?: string +} + +const formatDate = ( + date: Date, + locale: Locale, + stringFormat = 'dd.MMMM yyyy', +) => + format(date, stringFormat, { + locale: locale === 'is' ? localeIS : localeEn, + }) + +export const containsTimePart = (date: string) => date.includes('T') + +export const parseStatus = ( + grant: Grant, + formatMessage: IntlShape['formatMessage'], + locale: Locale, +): Status => { + switch (grant.status) { + case GrantStatus.Closed: { + return { + applicationStatus: 'closed', + deadlineStatus: grant.dateTo + ? formatMessage( + containsTimePart(grant.dateTo) + ? m.search.applicationWasOpenToAndWith + : m.search.applicationWasOpenTo, + { + arg: formatDate(new Date(grant.dateTo), locale), + }, + ) + : formatMessage(m.search.applicationClosed), + note: grant.statusText ?? undefined, + } + } + case GrantStatus.ClosedOpeningSoon: { + return { + applicationStatus: 'closed', + deadlineStatus: grant.dateFrom + ? formatMessage(m.search.applicationOpensAt, { + arg: formatDate(new Date(grant.dateFrom), locale), + }) + : formatMessage(m.search.applicationClosed), + note: grant.statusText ?? undefined, + } + } + case GrantStatus.ClosedOpeningSoonWithEstimation: { + return { + applicationStatus: 'closed', + deadlineStatus: grant.dateFrom + ? formatMessage(m.search.applicationEstimatedOpensAt, { + arg: formatDate(new Date(grant.dateFrom), locale, 'MMMM yyyy'), + }) + : formatMessage(m.search.applicationClosed), + note: grant.statusText ?? undefined, + } + } + case GrantStatus.ClosedWithNote: { + return { + applicationStatus: 'closed', + deadlineStatus: formatMessage(m.search.applicationSeeDescription), + note: grant.statusText ?? undefined, + } + } + case GrantStatus.AlwaysOpen: { return { - label: formatMessage(m.search.applicationOpen), - variant: 'mint', + applicationStatus: 'open', + deadlineStatus: formatMessage(m.search.applicationAlwaysOpen), + note: grant.statusText ?? undefined, } - case GrantStatus.Closed: + } + case GrantStatus.Open: { return { - label: formatMessage(m.search.applicationClosed), - variant: 'rose', + applicationStatus: 'open', + deadlineStatus: grant.dateTo + ? formatMessage( + containsTimePart(grant.dateTo) + ? m.search.applicationOpensToWithDay + : m.search.applicationOpensTo, + { + arg: formatDate(new Date(grant.dateTo), locale, 'dd.MMMM.'), + }, + ) + : formatMessage(m.search.applicationOpen), + note: grant.statusText ?? undefined, } - case GrantStatus.SeeDescription: + } + case GrantStatus.OpenWithNote: { return { - label: formatMessage(m.search.applicationSeeDescription), - variant: 'purple', + applicationStatus: 'open', + deadlineStatus: formatMessage(m.search.applicationSeeDescription), + note: grant.statusText ?? undefined, } - default: - return + } + default: { + return { + applicationStatus: 'unknown', + deadlineStatus: '', + } + } } } + +export const generateStatusTag = ( + status: Status['applicationStatus'], + formatMessage: IntlShape['formatMessage'], +) => + status !== 'unknown' + ? { + label: + status === 'open' + ? formatMessage(m.search.applicationOpen) + : formatMessage(m.search.applicationClosed), + variant: status === 'open' ? ('mint' as const) : ('rose' as const), + } + : undefined diff --git a/apps/web/screens/queries/Grants.ts b/apps/web/screens/queries/Grants.ts index 59160d38847b..cd120b0afcdc 100644 --- a/apps/web/screens/queries/Grants.ts +++ b/apps/web/screens/queries/Grants.ts @@ -16,8 +16,8 @@ export const GET_GRANTS_QUERY = gql` } dateFrom dateTo - isOpen status + statusText categoryTags { id title @@ -69,6 +69,9 @@ export const GET_GRANT_QUERY = gql` } applicationDeadlineStatus status + statusText + dateFrom + dateTo categoryTags { id title diff --git a/libs/cms/src/lib/cms.elasticsearch.service.ts b/libs/cms/src/lib/cms.elasticsearch.service.ts index e35685d85964..0a20025d9ed0 100644 --- a/libs/cms/src/lib/cms.elasticsearch.service.ts +++ b/libs/cms/src/lib/cms.elasticsearch.service.ts @@ -47,11 +47,8 @@ import { GenericListItem } from './models/genericListItem.model' import { GetTeamMembersInput } from './dto/getTeamMembers.input' import { TeamMemberResponse } from './models/teamMemberResponse.model' import { GetGrantsInput } from './dto/getGrants.input' -import { Grant, GrantStatus } from './models/grant.model' +import { Grant } from './models/grant.model' import { GrantList } from './models/grantList.model' -import { logger } from '@island.is/logging' -import { IGrantFields } from './generated/contentfulTypes' -import { isDefined } from '@island.is/shared/utils' @Injectable() export class CmsElasticsearchService { @@ -614,7 +611,6 @@ export class CmsElasticsearchService { search, page = 1, size = 8, - statuses, categories, types, organizations, @@ -719,30 +715,6 @@ export class CmsElasticsearchService { }) } - if (statuses) { - must.push({ - nested: { - path: 'tags', - query: { - bool: { - must: [ - { - terms: { - 'tags.key': statuses, - }, - }, - { - term: { - 'tags.type': 'status', - }, - }, - ], - }, - }, - }, - }) - } - const grantListResponse: ApiResponse> = await this.elasticService.findByQuery(index, { query: { diff --git a/libs/cms/src/lib/generated/contentfulTypes.d.ts b/libs/cms/src/lib/generated/contentfulTypes.d.ts index ec191a4968b0..aeb745479f33 100644 --- a/libs/cms/src/lib/generated/contentfulTypes.d.ts +++ b/libs/cms/src/lib/generated/contentfulTypes.d.ts @@ -1838,17 +1838,30 @@ export interface IGrantFields { /** Application hints */ grantApplicationHints?: Document | undefined - /** Date from */ + /** Open from */ grantDateFrom?: string | undefined - /** Date to */ + /** Open from hour */ + grantOpenFromHour?: number | undefined + + /** Open to */ grantDateTo?: string | undefined - /** Is open? */ - grantIsOpen?: boolean | undefined + /** Open to hour */ + grantOpenToHour?: number | undefined + + /** From date is estimated */ + grantFromDateIsEstimated?: boolean | undefined /** Status */ - grantStatus: 'open' | 'closed' | 'see_description' + grantStatus: + | 'Automatic' + | 'Always open' + | 'Open with note' + | 'Closed with note' + + /** Status Note */ + grantStatusNote?: string | undefined /** Files */ grantFiles?: Asset[] | undefined diff --git a/libs/cms/src/lib/models/grant.model.ts b/libs/cms/src/lib/models/grant.model.ts index b1f21752a40a..bd5f7247cc9b 100644 --- a/libs/cms/src/lib/models/grant.model.ts +++ b/libs/cms/src/lib/models/grant.model.ts @@ -1,6 +1,6 @@ import { Field, ObjectType, ID, registerEnumType } from '@nestjs/graphql' -import { IGrant } from '../generated/contentfulTypes' +import { IGrant, IGrantFields } from '../generated/contentfulTypes' import { GenericTag, mapGenericTag } from './genericTag.model' import { CacheField } from '@island.is/nest/graphql' import { mapDocument, SliceUnion } from '../unions/slice.union' @@ -9,10 +9,20 @@ import { ReferenceLink, mapReferenceLink } from './referenceLink.model' import { Fund, mapFund } from './fund.model' import { Link, mapLink } from './link.model' +import format from 'date-fns/format' +import addHours from 'date-fns/addHours' +import { isValidDate } from '@island.is/shared/utils' + export enum GrantStatus { CLOSED, + CLOSED_OPENING_SOON, + CLOSED_OPENING_SOON_WITH_ESTIMATION, + CLOSED_WITH_NOTE, OPEN, - SEE_DESCRIPTION, + OPEN_WITH_NOTE, + ALWAYS_OPEN, + INVALID, + UNKNOWN, } registerEnumType(GrantStatus, { name: 'GrantStatus' }) @@ -58,12 +68,12 @@ export class Grant { @Field({ nullable: true }) dateTo?: string - @Field({ nullable: true }) - isOpen?: boolean - @CacheField(() => GrantStatus, { nullable: true }) status?: GrantStatus + @Field({ nullable: true }) + statusText?: string + @CacheField(() => [Asset], { nullable: true }) files?: Array @@ -80,50 +90,94 @@ export class Grant { fund?: Fund } -export const mapGrant = ({ fields, sys }: IGrant): Grant => ({ - id: sys.id, - name: fields.grantName, - description: fields.grantDescription, - applicationId: fields.grantApplicationId, - applicationDeadlineStatus: fields.grantApplicationDeadlineStatus, - applicationUrl: fields.granApplicationUrl?.fields - ? mapReferenceLink(fields.granApplicationUrl) - : undefined, - specialEmphasis: fields.grantSpecialEmphasis - ? mapDocument(fields.grantSpecialEmphasis, sys.id + ':special-emphasis') - : [], - whoCanApply: fields.grantWhoCanApply - ? mapDocument(fields.grantWhoCanApply, sys.id + ':who-can-apply') - : [], - howToApply: fields.grantHowToApply - ? mapDocument(fields.grantHowToApply, sys.id + ':how-to-apply') - : [], - applicationDeadline: fields.grantApplicationDeadline - ? mapDocument( - fields.grantApplicationDeadline, - sys.id + ':application-deadline', - ) - : [], - applicationHints: fields.grantApplicationHints - ? mapDocument(fields.grantApplicationHints, sys.id + ':application-hints') - : [], - dateFrom: fields.grantDateFrom, - dateTo: fields.grantDateTo, - isOpen: fields.grantIsOpen ?? undefined, - status: - fields.grantStatus === 'open' - ? GrantStatus.OPEN - : fields.grantStatus === 'closed' - ? GrantStatus.CLOSED - : fields.grantStatus === 'see_description' - ? GrantStatus.SEE_DESCRIPTION +const parseStatus = (fields: IGrantFields): GrantStatus => { + switch (fields.grantStatus) { + case 'Automatic': { + const parsedDateTo = new Date(fields.grantDateTo ?? '') + const parsedDateFrom = new Date(fields.grantDateFrom ?? '') + + if (!isValidDate(parsedDateTo) || !isValidDate(parsedDateFrom)) { + return GrantStatus.INVALID + } + + const today = new Date() + + //opens soon! + if (today <= parsedDateFrom) { + return fields.grantFromDateIsEstimated + ? GrantStatus.CLOSED_OPENING_SOON_WITH_ESTIMATION + : GrantStatus.CLOSED_OPENING_SOON + } + if (today <= parsedDateTo) { + return GrantStatus.OPEN + } + return GrantStatus.CLOSED + } + case 'Always open': + return GrantStatus.ALWAYS_OPEN + case 'Closed with note': + return GrantStatus.CLOSED_WITH_NOTE + case 'Open with note': + return GrantStatus.OPEN_WITH_NOTE + default: + return GrantStatus.UNKNOWN + } +} + +const parseDate = (date?: string, time?: number): string | undefined => { + if (!date) { + return + } + const parsedDate = new Date(date) + if (!time) { + return format(parsedDate, 'yyyy-MM-dd') + } + return addHours(new Date(date), time).toISOString() +} + +export const mapGrant = ({ fields, sys }: IGrant): Grant => { + return { + id: sys.id, + name: fields.grantName, + description: fields.grantDescription, + applicationId: fields.grantApplicationId, + applicationDeadlineStatus: fields.grantApplicationDeadlineStatus, + applicationUrl: fields.granApplicationUrl?.fields + ? mapReferenceLink(fields.granApplicationUrl) + : undefined, + + specialEmphasis: fields.grantSpecialEmphasis + ? mapDocument(fields.grantSpecialEmphasis, sys.id + ':special-emphasis') + : [], + whoCanApply: fields.grantWhoCanApply + ? mapDocument(fields.grantWhoCanApply, sys.id + ':who-can-apply') + : [], + howToApply: fields.grantHowToApply + ? mapDocument(fields.grantHowToApply, sys.id + ':how-to-apply') + : [], + applicationDeadline: fields.grantApplicationDeadline + ? mapDocument( + fields.grantApplicationDeadline, + sys.id + ':application-deadline', + ) + : [], + applicationHints: fields.grantApplicationHints + ? mapDocument(fields.grantApplicationHints, sys.id + ':application-hints') + : [], + dateFrom: parseDate(fields.grantDateFrom, fields.grantOpenFromHour), + dateTo: parseDate(fields.grantDateTo, fields.grantOpenToHour), + status: parseStatus(fields), + statusText: fields.grantStatusNote, + fund: fields.grantFund ? mapFund(fields.grantFund) : undefined, + files: (fields.grantFiles ?? []).map((file) => mapAsset(file)) ?? [], + supportLinks: + (fields.grantSupportLinks ?? []).map((link) => mapLink(link)) ?? [], + + categoryTags: fields.grantCategoryTags + ? fields.grantCategoryTags.map((tag) => mapGenericTag(tag)) + : undefined, + typeTag: fields.grantTypeTag + ? mapGenericTag(fields.grantTypeTag) : undefined, - fund: fields.grantFund ? mapFund(fields.grantFund) : undefined, - files: (fields.grantFiles ?? []).map((file) => mapAsset(file)) ?? [], - supportLinks: - (fields.grantSupportLinks ?? []).map((link) => mapLink(link)) ?? [], - categoryTags: fields.grantCategoryTags - ? fields.grantCategoryTags.map((tag) => mapGenericTag(tag)) - : undefined, - typeTag: fields.grantTypeTag ? mapGenericTag(fields.grantTypeTag) : undefined, -}) + } +} diff --git a/libs/cms/src/lib/search/importers/grants.service.ts b/libs/cms/src/lib/search/importers/grants.service.ts index 7df8c4328ef6..3a58a59778d5 100644 --- a/libs/cms/src/lib/search/importers/grants.service.ts +++ b/libs/cms/src/lib/search/importers/grants.service.ts @@ -109,14 +109,9 @@ export class GrantsSyncService implements CmsSyncProvider { } switch (mapped.status) { - case GrantStatus.SEE_DESCRIPTION: - tags.push({ - key: 'see_description', - type: 'status', - value: 'see_description', - }) - break case GrantStatus.OPEN: + case GrantStatus.ALWAYS_OPEN: + case GrantStatus.OPEN_WITH_NOTE: tags.push({ key: 'open', type: 'status', @@ -124,6 +119,9 @@ export class GrantsSyncService implements CmsSyncProvider { }) break case GrantStatus.CLOSED: + case GrantStatus.CLOSED_OPENING_SOON: + case GrantStatus.CLOSED_OPENING_SOON_WITH_ESTIMATION: + case GrantStatus.CLOSED_WITH_NOTE: tags.push({ key: 'closed', type: 'status', From b22fd0a545d8de86e1a31e82029afd404d91fc07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3nas=20G=2E=20Sigur=C3=B0sson?= Date: Thu, 12 Dec 2024 22:26:22 +0000 Subject: [PATCH 07/32] chore(inao-cem): Refactor custom components and fetch tax data (#17195) * chore: houskeeping, split up files and make code more radable * chore: refactor out custom components * fix: remove imports from codeowners * chore: remove console.log * chore: add loading state * chore: simplify logic * fix: coderabbit comments * fix: match indentation to lint * fix: codeowners * chore: add space to match indentation * chore: remove the inao folder from codeowners * chore: . * fix: typo in path * fix: indentation --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .github/CODEOWNERS | 780 +++++++++--------- .../src/dataProviders/index.ts | 13 +- .../src/fields/CemeteryIncomeLimit/index.tsx | 43 - .../fields/CemeteryOverview/AboutOverview.tsx | 48 +- .../CapitalNumbersOverview.tsx | 37 +- .../src/fields/CemeteryOverview/index.tsx | 153 +--- .../FetchDataBasedOnSelectedYear/index.tsx | 123 +++ .../src/fields/PowerOfAttorney/index.tsx | 96 --- .../src/fields/index.ts | 3 +- .../caretakerMultiField.ts | 17 - .../cemeteryCaretakerSection/index.ts | 29 +- .../index.ts | 22 +- .../capitalNumberSubSection.ts | 2 +- .../equityAndLiabilitySubSection.ts | 8 +- .../opperatingCostSubSection.ts | 6 +- .../clientInfoSection/index.ts | 62 +- .../src/hooks/useTotals.ts | 21 - .../src/lib/dataSchema.ts | 6 +- .../src/types/types.ts | 16 + .../src/utils/constants.ts | 1 + .../src/utils/currency.ts | 16 + .../src/utils/helpers.ts | 312 ++----- .../src/utils/overviewUtils.ts | 189 +++++ .../src/utils/sums.ts | 225 +++++ 24 files changed, 1190 insertions(+), 1038 deletions(-) delete mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx create mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/fields/FetchDataBasedOnSelectedYear/index.tsx delete mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx delete mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts delete mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/hooks/useTotals.ts create mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/utils/currency.ts create mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/utils/overviewUtils.ts create mode 100644 libs/application/templates/inao/financial-statement-cemetery/src/utils/sums.ts diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d9d7ad29b0f6..f4bc0d23934e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -6,401 +6,409 @@ # Organisation name is @island-is, not @island.is # Fallback. If there is no owner, assign to core maintainers. -* @island-is/core +* @island-is/core # Top level project ownership. When a project contains, for example, templates or modules # that are developed by others teams, we first list down the team working on the core and # further below the other team working on other part of the project. -/apps/application-system/ @island-is/norda-applications -/apps/web*/ @island-is/juni @island-is/stefna -/libs/application/ @island-is/norda-applications -/libs/portals/my-pages/ @island-is/hugsmidjan -/libs/portals/admin/ @island-is/aranja -/libs/portals/core/ @island-is/aranja @island-is/hugsmidjan -/libs/shared/connected/ @island-is/stefna - -/* @island-is/core -/libs/api/domains/identity/ @island-is/core +/apps/application-system/ @island-is/norda-applications +/apps/web*/ @island-is/juni @island-is/stefna +/libs/application/ @island-is/norda-applications +/libs/portals/my-pages/ @island-is/hugsmidjan +/libs/portals/admin/ @island-is/aranja +/libs/portals/core/ @island-is/aranja @island-is/hugsmidjan +/libs/shared/connected/ @island-is/stefna + +/* @island-is/core +/libs/api/domains/identity/ @island-is/core # Edge case escaping the /infra/ and **/infra/ devops patterns below -/libs/infra-nest-server/src/lib/infra/ @island-is/core -/libs/testing/ @island-is/core -/libs/nest/swagger/ @island-is/core - -/apps/services/endorsements/ @island-is/juni -/apps/icelandic-names-registry*/ @island-is/juni -/apps/web/screens/PetitionView/ @island-is/juni -/libs/cms/ @island-is/juni @island-is/stefna -/libs/clients/cms/ @island-is/juni @island-is/aranja -/libs/residence-history @island-is/juni -/libs/api/domains/endorsement-system @island-is/juni -/libs/api/domains/icelandic-names-registry/ @island-is/juni -/libs/clients/rsk/ @island-is/juni -/libs/clients/zendesk/ @island-is/juni -/libs/icelandic-names-registry/ @island-is/juni -/libs/portals/my-pages/petitions/ @island-is/juni -/libs/portals/my-pages/signature-collection/ @island-is/juni -/libs/portals/my-pages/education/ @island-is/juni @island-is/hugsmidjan -/libs/portals/my-pages/education-career/ @island-is/juni @island-is/hugsmidjan -/libs/portals/my-pages/education-degree/ @island-is/juni @island-is/hugsmidjan -/libs/portals/my-pages/education-license/ @island-is/juni @island-is/hugsmidjan -/libs/portals/my-pages/education-student-assessment/ @island-is/juni @island-is/norda @island-is/hugsmidjan -/libs/clients/driving-license/ @island-is/juni -/libs/clients/judicial-administration/ @island-is/juni -/libs/application/templates/announcement-of-death/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death @island-is/juni -/libs/application/templates/driving-license/ @island-is/juni -/libs/application/templates/driving-assessment-approval/ @island-is/juni -/libs/application/templates/driving-learners-permit/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/driving-learners-permit/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/driving-license-submission @island-is/juni -/libs/api/domains/driving-license/ @island-is/juni -/libs/api/domains/education/ @island-is/juni @island-is/hugsmidjan @island-is/deloitte -/libs/application/templates/estate/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/estate @island-is/juni -/libs/application/templates/general-petition/ @island-is/juni -/libs/shared/connected/src/lib/generalPetition/GeneralPetitionLists/ @island-is/juni -/libs/shared/connected/src/lib/SignatureLists/ @island-is/juni -/libs/api/domains/communications/ @island-is/juni @island-is/stefna -/apps/services/user-notification/ @island-is/juni @island-is/aranja -/apps/air-discount-scheme/ @island-is/hugsmidjan -/libs/air-discount-scheme/ @island-is/hugsmidjan -/libs/application/templates/p-sign/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/p-sign-submission @island-is/juni -/libs/application/templates/marriage-conditions/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/marriage-conditions-submission @island-is/juni -/libs/message-queue/ @island-is/juni -/libs/application/templates/example-payment/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/example-payment-actions @island-is/juni -/libs/application/templates/driving-school-confirmation/ @island-is/juni -/libs/application/templates/driving-instructor-registrations/ @island-is/juni -/libs/api/domains/driving-license-book/ @island-is/juni -/libs/clients/driving-license-book/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/passport @island-is/juni -/libs/application/templates/passport/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/passport-annulment @island-is/juni -/libs/application/templates/passport-annulment/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/driving-school-confirmation/ @island-is/juni -/libs/application/templates/operating-license/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/operating-license/ @island-is/juni -/libs/application/templates/driving-license-duplicate/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/driving-license-duplicate/ @island-is/juni -/libs/application/templates/inheritance-report/ @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/inheritance-report @island-is/juni -/libs/application/templates/signature-collection @island-is/juni -/libs/api/domains/disability-license @island-is/juni -/libs/portals/admin/petition @island-is/juni -/libs/portals/admin/signature-collection @island-is/juni -/libs/portals/admin/icelandic-names-registry @island-is/juni -/libs/api/domains/signature-collection @island-is/juni -/libs/clients/signature-collection @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/signature-collection @island-is/juni -/libs/application/template-api-modules/src/lib/modules/templates/general-petition @island-is/juni - -/apps/portals/admin/ @island-is/aranja -/libs/api/domains/auth-admin/ @island-is/aranja -/libs/api/domains/sessions/ @island-is/aranja -/libs/clients/auth/ @island-is/aranja -/libs/clients/middlewares/ @island-is/aranja -libs/clients/rsk/relationships/ @island-is/aranja -/libs/clients/sessions @island-is/aranja -/libs/portals/shared-modules/delegations @island-is/aranja -/libs/portals/admin/ids-admin @island-is/aranja -/libs/portals/my-pages/consent @island-is/aranja -/libs/portals/my-pages/restrictions @island-is/aranja -/libs/portals/my-pages/sessions @island-is/aranja -/apps/native/app/ @island-is/aranja-app -codemagic.yaml @island-is/aranja-app -/apps/web/public/.well-known/ @island-is/aranja-app - -/apps/judicial-system/ @island-is/kolibri-justice-league -/libs/judicial-system/ @island-is/kolibri-justice-league -/libs/nova-sms/ @island-is/kolibri-justice-league -/libs/dokobit-signing/ @island-is/kolibri-justice-league -/libs/email-service/ @island-is/kolibri-justice-league - -/apps/financial-aid/ @island-is/kolibri-robin-hood -/libs/financial-aid/ @island-is/kolibri-robin-hood -/libs/next-ids-auth/ @island-is/kolibri-robin-hood -/libs/clients/rsk/personal-tax-return @island-is/kolibri-robin-hood -/libs/application/templates/financial-aid/ @island-is/kolibri-robin-hood -/libs/api/domains/municipalities-financial-aid @island-is/kolibri-robin-hood -/libs/clients/municipalities-financial-aid @island-is/kolibri-robin-hood -/libs/application/template-api-modules/src/lib/modules/templates/financial-aid @island-is/kolibri-robin-hood - -/apps/download-service/ @island-is/hugsmidjan -/apps/portals/my-pages*/ @island-is/hugsmidjan -/apps/services/regulations-admin-backend/ @island-is/hugsmidjan -/apps/services/user-profile/ @island-is/hugsmidjan @island-is/juni @island-is/aranja -/apps/web/components/Grant/ @island-is/hugsmidjan -/apps/web/components/PlazaCard/ @island-is/hugsmidjan -/apps/web/screens/Grants/ @island-is/hugsmidjan -/apps/web/screens/Regulations/ @island-is/hugsmidjan -/apps/web/components/Regulations/ @island-is/hugsmidjan -/apps/web/screens/OfficialJournalOfIceland/ @island-is/hugsmidjan -/apps/web/components/OfficialJournalOfIceland/ @island-is/hugsmidjan -/libs/api/domains/air-discount-scheme @island-is/hugsmidjan -/libs/api/domains/documents/ @island-is/hugsmidjan -/libs/api/domains/finance/ @island-is/hugsmidjan -/libs/api/domains/assets/ @island-is/hugsmidjan -/libs/api/domains/health-directorate/ @island-is/hugsmidjan -/libs/api/domains/hms-loans/ @island-is/hugsmidjan -/libs/api/domains/license-service/ @island-is/hugsmidjan @island-is/aranja -/libs/api/domains/work-machines/ @island-is/hugsmidjan @island-is/origo -/libs/api/domains/national-registry/ @island-is/hugsmidjan -/libs/api/domains/notifications/ @island-is/hugsmidjan -/libs/api/domains/user-profile/ @island-is/hugsmidjan @island-is/juni @island-is/aranja -/libs/api/domains/passport/ @island-is/hugsmidjan -/libs/api/domains/vehicles/ @island-is/hugsmidjan -/libs/api/domains/university-careers/ @island-is/hugsmidjan -/libs/api/domains/regulations/ @island-is/hugsmidjan -/libs/api/domains/regulations-admin/ @island-is/hugsmidjan -/libs/api/domains/rights-portal @island-is/hugsmidjan -/libs/api/domains/social-insurance @island-is/hugsmidjan @island-is/stefna -/libs/api/domains/occupational-licenses/ @island-is/hugsmidjan -/libs/api/domains/occupational-licenses-v2/ @island-is/hugsmidjan -/libs/api/domains/intellectual-properties/ @island-is/hugsmidjan -/libs/api/domains/official-journal-of-iceland/ @island-is/hugsmidjan -/libs/api/domains/official-journal-of-iceland-application/ @island-is/hugsmidjan -/libs/api/domains/document-provider/ @island-is/hugsmidjan @island-is/core -/libs/api/domains/housing-benefits/ @island-is/hugsmidjan -/libs/api/domains/law-and-order/ @island-is/hugsmidjan -/libs/clients/documents/ @island-is/hugsmidjan -/libs/clients/documents-v2/ @island-is/hugsmidjan -/libs/clients/finance/ @island-is/hugsmidjan -/libs/clients/finance-v2/ @island-is/hugsmidjan -/libs/clients/adr-and-machine-license/ @island-is/hugsmidjan -/libs/clients/work-machines/ @island-is/hugsmidjan @island-is/origo -/libs/clients/disability-license/ @island-is/hugsmidjan -/libs/clients/firearm-license/ @island-is/hugsmidjan -/libs/clients/hunting-license/ @island-is/hugsmidjan -/libs/clients/smartsolutions/ @island-is/hugsmidjan -/libs/clients/smart-solutions-v2/ @island-is/hugsmidjan -/libs/clients/license-client/ @island-is/hugsmidjan @island-is/aranja -/libs/clients/intellectual-properties/ @island-is/hugsmidjan -/libs/clients/islykill/ @island-is/hugsmidjan -/libs/clients/national-registry/v3/ @island-is/hugsmidjan -/libs/clients/district-commissioners-licenses/ @island-is/hugsmidjan -/libs/clients/regulations/ @island-is/hugsmidjan -/libs/clients/vehicles/ @island-is/hugsmidjan @island-is/stefna -/libs/clients/vehicles-mileage/ @island-is/hugsmidjan -/libs/clients/user-notification/ @island-is/hugsmidjan -/libs/clients/passports/ @island-is/hugsmidjan -/libs/clients/p-card/ @island-is/hugsmidjan -/libs/clients/assets/ @island-is/hugsmidjan -/libs/clients/university-careers/ @island-is/hugsmidjan -/libs/clients/regulations-admin/ @island-is/hugsmidjan -/libs/clients/inna/ @island-is/hugsmidjan -/libs/clients/hms-loans/ @island-is/hugsmidjan -/libs/clients/official-journal-of-iceland/ @island-is/hugsmidjan -/libs/clients/hms-housing-benefits/ @island-is/hugsmidjan -/apps/services/license-api/ @island-is/hugsmidjan -/libs/regulations/ @island-is/hugsmidjan -/libs/portals/admin/regulations-admin/ @island-is/hugsmidjan -/libs/portals/admin/document-provider/ @island-is/hugsmidjan @island-is/core -/libs/clients/icelandic-health-insurance/rights-portal/ @island-is/hugsmidjan -/libs/clients/health-directorate @island-is/hugsmidjan -/libs/clients/health-directorate/src/lib/clients/occupational-license @island-is/hugsmidjan @island-is/origo -/libs/clients/mms/grade @island-is/hugsmidjan -/libs/portals/admin/air-discount-scheme @island-is/hugsmidjan -/libs/application/templates/official-journal-of-iceland/ @island-is/hugsmidjan -/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/ @island-is/hugsmidjan -/libs/clients/judicial-system-sp/ @island-is/hugsmidjan -/libs/application/templates/data-protection-complaint/ @island-is/norda -/libs/application/templates/institution-collaboration/ @island-is/norda @island-is/fuglar -/libs/application/templates/login-service/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/login-service/ @island-is/norda -/libs/clients/payment-schedule/ @island-is/norda -/libs/api/domains/payment-schedule/ @island-is/norda -/libs/application/templates/funding-government-projects/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/funding-government-projects/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/institution-collaboration/ @island-is/norda -/libs/application/templates/public-debt-payment-plan/ @island-is/norda -/libs/application/templates/complaints-to-althingi-ombudsman/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/complaints-to-althingi-ombudsman/ @island-is/norda -/libs/application/templates/accident-notification/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/accident-notification/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/health-insurance/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/public-debt-payment-plan @island-is/norda -/libs/api/domains/health-insurance/ @island-is/norda -/libs/application/templates/health-insurance/ @island-is/norda -/libs/clients/rsk/company-registry @island-is/norda -/libs/clients/althingi-ombudsman/ @island-is/norda -/libs/api/domains/company-registry @island-is/norda -/libs/clients/icelandic-health-insurance/health-insurance/ @island-is/norda -/libs/clients/data-protection-complaint/ @island-is/norda -/libs/clients/fishing-license/ @island-is/norda -/libs/api/domains/fishing-license/ @island-is/norda -/libs/application/templates/general-fishing-license/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/general-fishing-license/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/data-protection-complaint/ @island-is/norda -/libs/shared/form-fields/ @island-is/norda @island-is/island-ui -/libs/clients/financial-statements-inao @island-is/norda -/libs/api/domains/financial-statements-inao/ @island-is/norda -/libs/application/templates/financial-statements-inao/ @island-is/norda -/libs/application/template-api-modules/src/lib/modules/templates/financial-statements-inao @island-is/norda - -/libs/portals/my-pages/applications/ @island-is/norda-applications -/libs/portals/admin/application-system/ @island-is/norda-applications -/libs/api/domains/application/ @island-is/norda-applications -/libs/api/domains/payment/ @island-is/norda-applications - -/apps/contentful-apps/ @island-is/stefna -/apps/services/search-indexer/ @island-is/stefna @island-is/juni -/apps/services/contentful-entry-tagger/ @island-is/stefna -/apps/tools/contentful-role-permissions/ @island-is/stefna -/apps/web/screens/Organization/ @island-is/stefna -/apps/web/screens/Project/ @island-is/stefna -/apps/web/components/Organization/ @island-is/stefna -/apps/web/components/ChatPanel/ @island-is/stefna -/apps/web/components/Form/ @island-is/stefna -/apps/web/components/Stepper/ @island-is/stefna -/libs/content-search-toolkit/ @island-is/stefna @island-is/juni -/libs/content-search-index-manager/ @island-is/stefna @island-is/juni -/libs/content-search-metrics/ @island-is/stefna @island-is/juni -/libs/content-search-indexer/ @island-is/stefna @island-is/juni -/libs/api/domains/content-search/ @island-is/stefna @island-is/juni -/libs/api/domains/syslumenn/ @island-is/stefna -/libs/api/domains/email-signup/ @island-is/stefna -/libs/api/domains/electronic-registration-statistics/ @island-is/stefna -/libs/clients/electronic-registration-statistics/ @island-is/stefna -/libs/api/domains/fiskistofa/ @island-is/stefna -/libs/clients/fiskistofa/ @island-is/stefna -/libs/clients/syslumenn/ @island-is/stefna @island-is/juni -/libs/api/domains/watson-assistant-chat/ @island-is/stefna -/libs/clients/icelandic-government-institution-vacancies/ @island-is/stefna -/libs/api/domains/icelandic-government-institution-vacancies/ @island-is/stefna -/libs/clients/aircraft-registry/ @island-is/stefna -/libs/api/domains/aircraft-registry/ @island-is/stefna -/libs/api/domains/housing-benefit-calculator/ @island-is/stefna -/libs/clients/housing-benefit-calculator/ @island-is/stefna -/libs/clients/ship-registry/ @island-is/stefna -/libs/api/domains/ship-registry/ @island-is/stefna -/libs/clients/administration-of-occupational-safety-and-health/ @island-is/stefna -/libs/api/domains/administration-of-occupational-safety-and-health/ @island-is/stefna -/libs/clients/ultraviolet-radiation/ @island-is/stefna -/libs/clients/ums-cost-of-living-calculator/ @island-is/stefna -/libs/api/domains/umbodsmadur-skuldara/ @island-is/stefna - -/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 - -/apps/skilavottord/ @island-is/deloitte -/libs/skilavottord/ @island-is/deloitte -/libs/application/templates/parental-leave/ @island-is/deloitte -/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/ @island-is/deloitte -/libs/clients/vmst/ @island-is/deloitte -/libs/api/domains/directorate-of-labour/ @island-is/deloitte -/libs/application/template-api-modules/src/lib/modules/templates/social-insurance-administration @island-is/deloitte -/libs/application/templates/social-insurance-administration/ @island-is/deloitte -/libs/clients/social-insurance-administration/ @island-is/deloitte @island-is/stefna @island-is/hugsmidjan -/libs/application/templates/car-recycling/ @island-is/deloitte -/libs/application/template-api-modules/src/lib/modules/templates/car-recycling/ @island-is/deloitte -/libs/clients/car-recycling/ @island-is/deloitte -/libs/application/templates/new-primary-school/ @island-is/deloitte -/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/ @island-is/deloitte -/libs/clients/mms/frigg @island-is/deloitte - -/apps/services/auth/ids-api/ @island-is/fuglar @island-is/aranja -/apps/services/auth/admin-api/ @island-is/fuglar @island-is/aranja -/apps/services/auth/public-api/ @island-is/fuglar @island-is/aranja -/apps/services/auth/delegation-api/ @island-is/fuglar @island-is/aranja -/apps/services/sessions/ @island-is/fuglar @island-is/aranja -/apps/auth-admin-web/ @island-is/fuglar @island-is/aranja -/libs/auth-api-lib/ @island-is/fuglar @island-is/aranja -/libs/auth-api-lib/seeders/ @island-is/fuglar @island-is/aranja @island-is/origo-auth -/libs/auth-nest-tools/ @island-is/fuglar @island-is/aranja -/libs/application/templates/european-health-insurance-card/ @island-is/fuglar -/libs/application/template-api-modules/src/lib/modules/templates/european-health-insurance-card/ @island-is/fuglar -/libs/clients/ehic-client-v1 @island-is/fuglar - -/apps/services/auth/personal-representative/ @island-is/programm @island-is/aranja -/apps/services/auth/personal-representative-public/ @island-is/programm @island-is/aranja - -/libs/application/templates/criminal-record/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/criminal-record-submission/ @island-is/origo -/libs/api/domains/criminal-record/ @island-is/origo -/libs/clients/criminal-record/ @island-is/origo - -/libs/application/templates/mortgage-certificate/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/mortgage-certificate-submission/ @island-is/origo -/libs/api/domains/mortgage-certificate/ @island-is/origo - -/libs/application/templates/no-debt-certificate/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/no-debt-certificate/ @island-is/origo - -/libs/application/templates/id-card/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/id-card/ @island-is/origo - -/libs/clients/charge-fjs-v2/ @island-is/origo -/libs/clients/vehicle-service-fjs-v1/ @island-is/origo - -/libs/application/templates/transport-authority/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/ @island-is/origo -/libs/api/domains/transport-authority/ @island-is/origo -/libs/clients/transport-authority/ @island-is/origo - -/libs/application/templates/driving-license-book-update-instructor/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/driving-license-book-update-instructor/ @island-is/origo - -/apps/services/university-gateway/ @island-is/origo -/libs/clients/university-application/ @island-is/origo -/libs/clients/university-gateway-api/ @island-is/origo -/libs/api/domains/university-gateway/ @island-is/origo -/libs/university-gateway/ @island-is/origo -/apps/web/screens/UniversitySearch/ @island-is/origo -/apps/web/screens/queries/UniversityGateway.ts @island-is/origo -/apps/web/components/ListViewCard/ @island-is/origo - -/libs/application/templates/directorate-of-immigration/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/directorate-of-immigration/ @island-is/origo -/libs/clients/directorate-of-immigration/ @island-is/origo - -/libs/application/templates/aosh/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/aosh @island-is/origo - -/libs/application/templates/healthcare-license-certificate/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/healthcare-license-certificate/ @island-is/origo - - -/libs/application/templates/healthcare-work-permit/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/healthcare-work-permit/ @island-is/origo - -/libs/application/templates/energy-funds/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/energy-funds/ @island-is/origo -/libs/api/domains/energy-funds/ @island-is/origo -/libs/clients/energy-funds/ @island-is/origo - -/libs/application/templates/university/ @island-is/origo -/libs/application/template-api-modules/src/lib/modules/templates/university/ @island-is/origo +/libs/infra-nest-server/src/lib/infra/ @island-is/core +/libs/testing/ @island-is/core +/libs/nest/swagger/ @island-is/core + +/apps/services/endorsements/ @island-is/juni +/apps/icelandic-names-registry*/ @island-is/juni +/apps/web/screens/PetitionView/ @island-is/juni +/libs/cms/ @island-is/juni @island-is/stefna +/libs/clients/cms/ @island-is/juni @island-is/aranja +/libs/residence-history @island-is/juni +/libs/api/domains/endorsement-system @island-is/juni +/libs/api/domains/icelandic-names-registry/ @island-is/juni +/libs/clients/rsk/ @island-is/juni +/libs/clients/zendesk/ @island-is/juni +/libs/icelandic-names-registry/ @island-is/juni +/libs/portals/my-pages/petitions/ @island-is/juni +/libs/portals/my-pages/signature-collection/ @island-is/juni +/libs/portals/my-pages/education/ @island-is/juni @island-is/hugsmidjan +/libs/portals/my-pages/education-career/ @island-is/juni @island-is/hugsmidjan +/libs/portals/my-pages/education-degree/ @island-is/juni @island-is/hugsmidjan +/libs/portals/my-pages/education-license/ @island-is/juni @island-is/hugsmidjan +/libs/portals/my-pages/education-student-assessment/ @island-is/juni @island-is/norda @island-is/hugsmidjan +/libs/clients/driving-license/ @island-is/juni +/libs/clients/judicial-administration/ @island-is/juni +/libs/application/templates/announcement-of-death/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/announcement-of-death @island-is/juni +/libs/application/templates/driving-license/ @island-is/juni +/libs/application/templates/driving-assessment-approval/ @island-is/juni +/libs/application/templates/driving-learners-permit/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/driving-learners-permit/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/driving-license-submission @island-is/juni +/libs/api/domains/driving-license/ @island-is/juni +/libs/api/domains/education/ @island-is/juni @island-is/hugsmidjan @island-is/deloitte +/libs/application/templates/estate/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/estate @island-is/juni +/libs/application/templates/general-petition/ @island-is/juni +/libs/shared/connected/src/lib/generalPetition/GeneralPetitionLists/ @island-is/juni +/libs/shared/connected/src/lib/SignatureLists/ @island-is/juni +/libs/api/domains/communications/ @island-is/juni @island-is/stefna +/apps/services/user-notification/ @island-is/juni @island-is/aranja +/apps/air-discount-scheme/ @island-is/hugsmidjan +/libs/air-discount-scheme/ @island-is/hugsmidjan +/libs/application/templates/p-sign/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/p-sign-submission @island-is/juni +/libs/application/templates/marriage-conditions/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/marriage-conditions-submission @island-is/juni +/libs/message-queue/ @island-is/juni +/libs/application/templates/example-payment/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/example-payment-actions @island-is/juni +/libs/application/templates/driving-school-confirmation/ @island-is/juni +/libs/application/templates/driving-instructor-registrations/ @island-is/juni +/libs/api/domains/driving-license-book/ @island-is/juni +/libs/clients/driving-license-book/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/passport @island-is/juni +/libs/application/templates/passport/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/passport-annulment @island-is/juni +/libs/application/templates/passport-annulment/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/driving-school-confirmation/ @island-is/juni +/libs/application/templates/operating-license/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/operating-license/ @island-is/juni +/libs/application/templates/driving-license-duplicate/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/driving-license-duplicate/ @island-is/juni +/libs/application/templates/inheritance-report/ @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/inheritance-report @island-is/juni +/libs/application/templates/signature-collection @island-is/juni +/libs/api/domains/disability-license @island-is/juni +/libs/portals/admin/petition @island-is/juni +/libs/portals/admin/signature-collection @island-is/juni +/libs/portals/admin/icelandic-names-registry @island-is/juni +/libs/api/domains/signature-collection @island-is/juni +/libs/clients/signature-collection @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/signature-collection @island-is/juni +/libs/application/template-api-modules/src/lib/modules/templates/general-petition @island-is/juni + +/apps/portals/admin/ @island-is/aranja +/libs/api/domains/auth-admin/ @island-is/aranja +/libs/api/domains/sessions/ @island-is/aranja +/libs/clients/auth/ @island-is/aranja +/libs/clients/middlewares/ @island-is/aranja +libs/clients/rsk/relationships/ @island-is/aranja +/libs/clients/sessions @island-is/aranja +/libs/portals/shared-modules/delegations @island-is/aranja +/libs/portals/admin/ids-admin @island-is/aranja +/libs/portals/my-pages/consent @island-is/aranja +/libs/portals/my-pages/restrictions @island-is/aranja +/libs/portals/my-pages/sessions @island-is/aranja +/apps/native/app/ @island-is/aranja-app +codemagic.yaml @island-is/aranja-app +/apps/web/public/.well-known/ @island-is/aranja-app + +/apps/judicial-system/ @island-is/kolibri-justice-league +/libs/judicial-system/ @island-is/kolibri-justice-league +/libs/nova-sms/ @island-is/kolibri-justice-league +/libs/dokobit-signing/ @island-is/kolibri-justice-league +/libs/email-service/ @island-is/kolibri-justice-league + +/apps/financial-aid/ @island-is/kolibri-robin-hood +/libs/financial-aid/ @island-is/kolibri-robin-hood +/libs/next-ids-auth/ @island-is/kolibri-robin-hood +/libs/clients/rsk/personal-tax-return @island-is/kolibri-robin-hood +/libs/application/templates/financial-aid/ @island-is/kolibri-robin-hood +/libs/api/domains/municipalities-financial-aid @island-is/kolibri-robin-hood +/libs/clients/municipalities-financial-aid @island-is/kolibri-robin-hood +/libs/application/template-api-modules/src/lib/modules/templates/financial-aid @island-is/kolibri-robin-hood + +/apps/download-service/ @island-is/hugsmidjan +/apps/portals/my-pages*/ @island-is/hugsmidjan +/apps/services/regulations-admin-backend/ @island-is/hugsmidjan +/apps/services/user-profile/ @island-is/hugsmidjan @island-is/juni @island-is/aranja +/apps/web/components/Grant/ @island-is/hugsmidjan +/apps/web/components/PlazaCard/ @island-is/hugsmidjan +/apps/web/screens/Grants/ @island-is/hugsmidjan +/apps/web/screens/Regulations/ @island-is/hugsmidjan +/apps/web/components/Regulations/ @island-is/hugsmidjan +/apps/web/screens/OfficialJournalOfIceland/ @island-is/hugsmidjan +/apps/web/components/OfficialJournalOfIceland/ @island-is/hugsmidjan +/libs/api/domains/air-discount-scheme @island-is/hugsmidjan +/libs/api/domains/documents/ @island-is/hugsmidjan +/libs/api/domains/finance/ @island-is/hugsmidjan +/libs/api/domains/assets/ @island-is/hugsmidjan +/libs/api/domains/health-directorate/ @island-is/hugsmidjan +/libs/api/domains/hms-loans/ @island-is/hugsmidjan +/libs/api/domains/license-service/ @island-is/hugsmidjan @island-is/aranja +/libs/api/domains/work-machines/ @island-is/hugsmidjan @island-is/origo +/libs/api/domains/national-registry/ @island-is/hugsmidjan +/libs/api/domains/notifications/ @island-is/hugsmidjan +/libs/api/domains/user-profile/ @island-is/hugsmidjan @island-is/juni @island-is/aranja +/libs/api/domains/passport/ @island-is/hugsmidjan +/libs/api/domains/vehicles/ @island-is/hugsmidjan +/libs/api/domains/university-careers/ @island-is/hugsmidjan +/libs/api/domains/regulations/ @island-is/hugsmidjan +/libs/api/domains/regulations-admin/ @island-is/hugsmidjan +/libs/api/domains/rights-portal @island-is/hugsmidjan +/libs/api/domains/social-insurance @island-is/hugsmidjan @island-is/stefna +/libs/api/domains/occupational-licenses/ @island-is/hugsmidjan +/libs/api/domains/occupational-licenses-v2/ @island-is/hugsmidjan +/libs/api/domains/intellectual-properties/ @island-is/hugsmidjan +/libs/api/domains/official-journal-of-iceland/ @island-is/hugsmidjan +/libs/api/domains/official-journal-of-iceland-application/ @island-is/hugsmidjan +/libs/api/domains/document-provider/ @island-is/hugsmidjan @island-is/core +/libs/api/domains/housing-benefits/ @island-is/hugsmidjan +/libs/api/domains/law-and-order/ @island-is/hugsmidjan +/libs/clients/documents/ @island-is/hugsmidjan +/libs/clients/documents-v2/ @island-is/hugsmidjan +/libs/clients/finance/ @island-is/hugsmidjan +/libs/clients/finance-v2/ @island-is/hugsmidjan +/libs/clients/adr-and-machine-license/ @island-is/hugsmidjan +/libs/clients/work-machines/ @island-is/hugsmidjan @island-is/origo +/libs/clients/disability-license/ @island-is/hugsmidjan +/libs/clients/firearm-license/ @island-is/hugsmidjan +/libs/clients/hunting-license/ @island-is/hugsmidjan +/libs/clients/smartsolutions/ @island-is/hugsmidjan +/libs/clients/smart-solutions-v2/ @island-is/hugsmidjan +/libs/clients/license-client/ @island-is/hugsmidjan @island-is/aranja +/libs/clients/intellectual-properties/ @island-is/hugsmidjan +/libs/clients/islykill/ @island-is/hugsmidjan +/libs/clients/national-registry/v3/ @island-is/hugsmidjan +/libs/clients/district-commissioners-licenses/ @island-is/hugsmidjan +/libs/clients/regulations/ @island-is/hugsmidjan +/libs/clients/vehicles/ @island-is/hugsmidjan @island-is/stefna +/libs/clients/vehicles-mileage/ @island-is/hugsmidjan +/libs/clients/user-notification/ @island-is/hugsmidjan +/libs/clients/passports/ @island-is/hugsmidjan +/libs/clients/p-card/ @island-is/hugsmidjan +/libs/clients/assets/ @island-is/hugsmidjan +/libs/clients/university-careers/ @island-is/hugsmidjan +/libs/clients/regulations-admin/ @island-is/hugsmidjan +/libs/clients/inna/ @island-is/hugsmidjan +/libs/clients/hms-loans/ @island-is/hugsmidjan +/libs/clients/official-journal-of-iceland/ @island-is/hugsmidjan +/libs/clients/hms-housing-benefits/ @island-is/hugsmidjan +/apps/services/license-api/ @island-is/hugsmidjan +/libs/regulations/ @island-is/hugsmidjan +/libs/portals/admin/regulations-admin/ @island-is/hugsmidjan +/libs/portals/admin/document-provider/ @island-is/hugsmidjan @island-is/core +/libs/clients/icelandic-health-insurance/rights-portal/ @island-is/hugsmidjan +/libs/clients/health-directorate @island-is/hugsmidjan +/libs/clients/health-directorate/src/lib/clients/occupational-license @island-is/hugsmidjan @island-is/origo +/libs/clients/mms/grade @island-is/hugsmidjan +/libs/portals/admin/air-discount-scheme @island-is/hugsmidjan +/libs/application/templates/official-journal-of-iceland/ @island-is/hugsmidjan +/libs/application/template-api-modules/src/lib/modules/templates/official-journal-of-iceland/ @island-is/hugsmidjan +/libs/clients/judicial-system-sp/ @island-is/hugsmidjan +/libs/application/templates/data-protection-complaint/ @island-is/norda +/libs/application/templates/institution-collaboration/ @island-is/norda @island-is/fuglar +/libs/application/templates/login-service/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/login-service/ @island-is/norda +/libs/clients/payment-schedule/ @island-is/norda +/libs/api/domains/payment-schedule/ @island-is/norda +/libs/application/templates/funding-government-projects/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/funding-government-projects/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/institution-collaboration/ @island-is/norda +/libs/application/templates/public-debt-payment-plan/ @island-is/norda +/libs/application/templates/complaints-to-althingi-ombudsman/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/complaints-to-althingi-ombudsman/ @island-is/norda +/libs/application/templates/accident-notification/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/accident-notification/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/health-insurance/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/public-debt-payment-plan @island-is/norda +/libs/api/domains/health-insurance/ @island-is/norda +/libs/application/templates/health-insurance/ @island-is/norda +/libs/clients/rsk/company-registry @island-is/norda +/libs/clients/althingi-ombudsman/ @island-is/norda +/libs/api/domains/company-registry @island-is/norda +/libs/clients/icelandic-health-insurance/health-insurance/ @island-is/norda +/libs/clients/data-protection-complaint/ @island-is/norda +/libs/clients/fishing-license/ @island-is/norda +/libs/api/domains/fishing-license/ @island-is/norda +/libs/application/templates/general-fishing-license/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/general-fishing-license/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/data-protection-complaint/ @island-is/norda +/libs/shared/form-fields/ @island-is/norda @island-is/island-ui +/libs/clients/financial-statements-inao @island-is/norda +/libs/api/domains/financial-statements-inao/ @island-is/norda +/libs/application/templates/financial-statements-inao/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/financial-statements-inao @island-is/norda +/libs/application/templates/inao/ @island-is/norda +/libs/application/templates/inao/financial-statement-cemetery/ @island-is/norda +/libs/application/templates/inao/financial-statement-individual-election/ @island-is/norda +/libs/application/templates/inao/financial-statement-political-party/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-cemetery/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-individual-election/ @island-is/norda +/libs/application/template-api-modules/src/lib/modules/templates/financial-statement-political-party/ @island-is/norda + + +/libs/portals/my-pages/applications/ @island-is/norda-applications +/libs/portals/admin/application-system/ @island-is/norda-applications +/libs/api/domains/application/ @island-is/norda-applications +/libs/api/domains/payment/ @island-is/norda-applications + +/apps/contentful-apps/ @island-is/stefna +/apps/services/search-indexer/ @island-is/stefna @island-is/juni +/apps/services/contentful-entry-tagger/ @island-is/stefna +/apps/tools/contentful-role-permissions/ @island-is/stefna +/apps/web/screens/Organization/ @island-is/stefna +/apps/web/screens/Project/ @island-is/stefna +/apps/web/components/Organization/ @island-is/stefna +/apps/web/components/ChatPanel/ @island-is/stefna +/apps/web/components/Form/ @island-is/stefna +/apps/web/components/Stepper/ @island-is/stefna +/libs/content-search-toolkit/ @island-is/stefna @island-is/juni +/libs/content-search-index-manager/ @island-is/stefna @island-is/juni +/libs/content-search-metrics/ @island-is/stefna @island-is/juni +/libs/content-search-indexer/ @island-is/stefna @island-is/juni +/libs/api/domains/content-search/ @island-is/stefna @island-is/juni +/libs/api/domains/syslumenn/ @island-is/stefna +/libs/api/domains/email-signup/ @island-is/stefna +/libs/api/domains/electronic-registration-statistics/ @island-is/stefna +/libs/clients/electronic-registration-statistics/ @island-is/stefna +/libs/api/domains/fiskistofa/ @island-is/stefna +/libs/clients/fiskistofa/ @island-is/stefna +/libs/clients/syslumenn/ @island-is/stefna @island-is/juni +/libs/api/domains/watson-assistant-chat/ @island-is/stefna +/libs/clients/icelandic-government-institution-vacancies/ @island-is/stefna +/libs/api/domains/icelandic-government-institution-vacancies/ @island-is/stefna +/libs/clients/aircraft-registry/ @island-is/stefna +/libs/api/domains/aircraft-registry/ @island-is/stefna +/libs/api/domains/housing-benefit-calculator/ @island-is/stefna +/libs/clients/housing-benefit-calculator/ @island-is/stefna +/libs/clients/ship-registry/ @island-is/stefna +/libs/api/domains/ship-registry/ @island-is/stefna +/libs/clients/administration-of-occupational-safety-and-health/ @island-is/stefna +/libs/api/domains/administration-of-occupational-safety-and-health/ @island-is/stefna +/libs/clients/ultraviolet-radiation/ @island-is/stefna +/libs/clients/ums-cost-of-living-calculator/ @island-is/stefna +/libs/api/domains/umbodsmadur-skuldara/ @island-is/stefna + +/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 + +/apps/skilavottord/ @island-is/deloitte +/libs/skilavottord/ @island-is/deloitte +/libs/application/templates/parental-leave/ @island-is/deloitte +/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/ @island-is/deloitte +/libs/clients/vmst/ @island-is/deloitte +/libs/api/domains/directorate-of-labour/ @island-is/deloitte +/libs/application/template-api-modules/src/lib/modules/templates/social-insurance-administration @island-is/deloitte +/libs/application/templates/social-insurance-administration/ @island-is/deloitte +/libs/clients/social-insurance-administration/ @island-is/deloitte @island-is/stefna @island-is/hugsmidjan +/libs/application/templates/car-recycling/ @island-is/deloitte +/libs/application/template-api-modules/src/lib/modules/templates/car-recycling/ @island-is/deloitte +/libs/clients/car-recycling/ @island-is/deloitte +/libs/application/templates/new-primary-school/ @island-is/deloitte +/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/ @island-is/deloitte +/libs/clients/mms/frigg @island-is/deloitte + +/apps/services/auth/ids-api/ @island-is/fuglar @island-is/aranja +/apps/services/auth/admin-api/ @island-is/fuglar @island-is/aranja +/apps/services/auth/public-api/ @island-is/fuglar @island-is/aranja +/apps/services/auth/delegation-api/ @island-is/fuglar @island-is/aranja +/apps/services/sessions/ @island-is/fuglar @island-is/aranja +/apps/auth-admin-web/ @island-is/fuglar @island-is/aranja +/libs/auth-api-lib/ @island-is/fuglar @island-is/aranja +/libs/auth-api-lib/seeders/ @island-is/fuglar @island-is/aranja @island-is/origo-auth +/libs/auth-nest-tools/ @island-is/fuglar @island-is/aranja +/libs/application/templates/european-health-insurance-card/ @island-is/fuglar +/libs/application/template-api-modules/src/lib/modules/templates/european-health-insurance-card/ @island-is/fuglar +/libs/clients/ehic-client-v1 @island-is/fuglar + +/apps/services/auth/personal-representative/ @island-is/programm @island-is/aranja +/apps/services/auth/personal-representative-public/ @island-is/programm @island-is/aranja + +/libs/application/templates/criminal-record/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/criminal-record-submission/ @island-is/origo +/libs/api/domains/criminal-record/ @island-is/origo +/libs/clients/criminal-record/ @island-is/origo + +/libs/application/templates/mortgage-certificate/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/mortgage-certificate-submission/ @island-is/origo +/libs/api/domains/mortgage-certificate/ @island-is/origo + +/libs/application/templates/no-debt-certificate/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/no-debt-certificate/ @island-is/origo + +/libs/application/templates/id-card/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/id-card/ @island-is/origo + +/libs/clients/charge-fjs-v2/ @island-is/origo +/libs/clients/vehicle-service-fjs-v1/ @island-is/origo + +/libs/application/templates/transport-authority/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/transport-authority/ @island-is/origo +/libs/api/domains/transport-authority/ @island-is/origo +/libs/clients/transport-authority/ @island-is/origo + +/libs/application/templates/driving-license-book-update-instructor/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/driving-license-book-update-instructor/ @island-is/origo + +/apps/services/university-gateway/ @island-is/origo +/libs/clients/university-application/ @island-is/origo +/libs/clients/university-gateway-api/ @island-is/origo +/libs/api/domains/university-gateway/ @island-is/origo +/libs/university-gateway/ @island-is/origo +/apps/web/screens/UniversitySearch/ @island-is/origo +/apps/web/screens/queries/UniversityGateway.ts @island-is/origo +/apps/web/components/ListViewCard/ @island-is/origo + +/libs/application/templates/directorate-of-immigration/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/directorate-of-immigration/ @island-is/origo +/libs/clients/directorate-of-immigration/ @island-is/origo + +/libs/application/templates/aosh/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/aosh @island-is/origo + +/libs/application/templates/healthcare-license-certificate/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/healthcare-license-certificate/ @island-is/origo + + +/libs/application/templates/healthcare-work-permit/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/healthcare-work-permit/ @island-is/origo + +/libs/application/templates/energy-funds/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/energy-funds/ @island-is/origo +/libs/api/domains/energy-funds/ @island-is/origo +/libs/clients/energy-funds/ @island-is/origo + +/libs/application/templates/university/ @island-is/origo +/libs/application/template-api-modules/src/lib/modules/templates/university/ @island-is/origo # DevOps -/.github/ @island-is/devops -/.githooks/ @island-is/devops -/apps/reference-backend/ @island-is/devops -/apps/github-actions-cache/ @island-is/devops -/infra/ @island-is/devops -**/infra/ @island-is/devops -/libs/logging/ @island-is/devops -/scripts/ @island-is/devops -/scripts/postinstall.js @island-is/devops @island-is/core -/scripts/codegen.js @island-is/devops @island-is/core -/charts/ @island-is/devops -.dockerignore @island-is/devops +/.github/ @island-is/devops +/.githooks/ @island-is/devops +/apps/reference-backend/ @island-is/devops +/apps/github-actions-cache/ @island-is/devops +/infra/ @island-is/devops +**/infra/ @island-is/devops +/libs/logging/ @island-is/devops +/scripts/ @island-is/devops +/scripts/postinstall.js @island-is/devops @island-is/core +/scripts/codegen.js @island-is/devops @island-is/core +/charts/ @island-is/devops +.dockerignore @island-is/devops # QA -/apps/system-e2e/ @island-is/qa -/libs/testing/e2e @island-is/qa +/apps/system-e2e/ @island-is/qa +/libs/testing/e2e @island-is/qa # Islandis -/apps/system-e2e/src/tests/islandis/admin-portal/ @island-is/aranja -/apps/system-e2e/src/tests/islandis/application-system/ @island-is/norda-applications -/apps/system-e2e/src/tests/islandis/application-system/acceptance/parental-leave.spec.ts @island-is/deloitte -/apps/system-e2e/src/tests/islandis/consultation-portal/ @island-is/advania -/apps/system-e2e/src/tests/islandis/service-portal/ @island-is/hugsmidjan @island-is/juni @island-is/norda-applications -/apps/system-e2e/src/tests/islandis/web/ @island-is/hugsmidjan @island-is/juni @island-is/stefna +/apps/system-e2e/src/tests/islandis/admin-portal/ @island-is/aranja +/apps/system-e2e/src/tests/islandis/application-system/ @island-is/norda-applications +/apps/system-e2e/src/tests/islandis/application-system/acceptance/parental-leave.spec.ts @island-is/deloitte +/apps/system-e2e/src/tests/islandis/consultation-portal/ @island-is/advania +/apps/system-e2e/src/tests/islandis/service-portal/ @island-is/hugsmidjan @island-is/juni @island-is/norda-applications +/apps/system-e2e/src/tests/islandis/web/ @island-is/hugsmidjan @island-is/juni @island-is/stefna # Judicial system -/apps/system-e2e/src/tests/judicial-system/ @island-is/kolibri-justice-league +/apps/system-e2e/src/tests/judicial-system/ @island-is/kolibri-justice-league diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/dataProviders/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/dataProviders/index.ts index dd52c79ad7f2..b0b604d16ca3 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/dataProviders/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/dataProviders/index.ts @@ -1,10 +1,7 @@ import { defineTemplateApi } from '@island.is/application/types' import { UserProfileApi } from '@island.is/application/types' - -export { - NationalRegistryUserApi, - IdentityApi as IdentityApiProvider, -} from '@island.is/application/types' +import { IdentityApi } from '@island.is/application/types' +export { NationalRegistryUserApi } from '@island.is/application/types' export const CurrentUserTypeProvider = defineTemplateApi({ action: 'getUserType', @@ -16,3 +13,9 @@ export const UserInfoApi = UserProfileApi.configure({ catchMock: true, }, }) + +export const IdentityApiProvider = IdentityApi.configure({ + params: { + includeActorInfo: true, + }, +}) diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx deleted file mode 100644 index 3e78d43e4af1..000000000000 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryIncomeLimit/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { useEffect } from 'react' -import { AlertMessage, ContentBlock } from '@island.is/island-ui/core' -import { useLocale } from '@island.is/localization' -import { useQuery } from '@apollo/client' -import { useFormContext } from 'react-hook-form' -import { m } from '../../lib/messages' -import { financialLimitQuery } from '../../graphql' -import { CEMETERYOPERATIONIDS } from '../../utils/constants' -import { FSIUSERTYPE } from '../../types/types' - -export const CemeteryIncomeLimit = () => { - const { getValues, setValue } = useFormContext() - const { formatMessage } = useLocale() - - const values = getValues() - const year: string = values?.conditionalAbout?.operatingYear - - const { data, error } = useQuery(financialLimitQuery, { - variables: { input: { year, clientType: `${FSIUSERTYPE.CEMETRY}` } }, - }) - - useEffect(() => { - const limit = data?.financialStatementsInaoClientFinancialLimit?.toString() - - if (limit) { - setValue(CEMETERYOPERATIONIDS.incomeLimit, limit) - } - }, [data, setValue]) - - if (error) { - return ( - - - - ) - } - - return null -} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx index 926d2038faba..f0d0177b8a94 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx +++ b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/AboutOverview.tsx @@ -1,61 +1,61 @@ import { GridColumn, GridRow } from '@island.is/island-ui/core' -import { formatPhoneNumber } from '@island.is/application/ui-components' - import { format as formatNationalId } from 'kennitala' -import { m } from '../../lib/messages' import { sectionColumn } from './overviewStyles.css' -import { FinancialStatementCemetery } from '../../lib/dataSchema' import { ValueLine } from './ValueLine' +import { FormValue } from '@island.is/application/types' +import { getAboutOverviewNumbers } from '../../utils/overviewUtils' +import { m } from '../../lib/messages' -export const AboutOverview = ({ - answers, -}: { - answers: FinancialStatementCemetery -}) => { +type Props = { + answers: FormValue +} + +export const AboutOverview = ({ answers }: Props) => { + const { + fullName, + nationalId, + powerOfAttorneyName, + powerOfAttorneyNationalId, + email, + phoneNumber, + } = getAboutOverviewNumbers(answers) return ( <> - + - {answers.about.powerOfAttorneyName ? ( + {powerOfAttorneyName ? ( ) : null} - {answers.about.powerOfAttorneyNationalId ? ( + {powerOfAttorneyNationalId ? ( ) : null} - + - + diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx index f3e18079a7cf..8814e7cb42b8 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx +++ b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/CapitalNumbersOverview.tsx @@ -1,18 +1,19 @@ import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core' - -import { m } from '../../lib/messages' import { ValueLine } from './ValueLine' import { sectionColumn, starterColumnStyle } from './overviewStyles.css' import { useLocale } from '@island.is/localization' -import { FinancialStatementCemetery } from '../../lib/dataSchema' -import { formatCurrency } from '../../utils/helpers' +import { FormValue } from '@island.is/application/types' +import { getCapitalNumbersOverviewNumbers } from '../../utils/overviewUtils' +import { m } from '../../lib/messages' + +type Props = { + answers: FormValue +} -export const CapitalNumberOverview = ({ - answers, -}: { - answers: FinancialStatementCemetery -}) => { +export const CapitalNumberOverview = ({ answers }: Props) => { const { formatMessage } = useLocale() + const { capitalIncome, capitalCost, totalCapital } = + getCapitalNumbersOverviewNumbers(answers) return ( <> @@ -22,27 +23,17 @@ export const CapitalNumberOverview = ({ - + - {answers.capitalNumbers?.capitalCost ? ( + {capitalCost ? ( - + ) : null} - + diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx index 0f8c89f2c9f0..b5e45641c1fd 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx +++ b/libs/application/templates/inao/financial-statement-cemetery/src/fields/CemeteryOverview/index.tsx @@ -1,6 +1,5 @@ import { Fragment } from 'react' import { FieldBaseProps } from '@island.is/application/types' -import { getValueViaPath } from '@island.is/application/core' import { AlertBanner, Box, @@ -11,9 +10,6 @@ import { } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' import { format as formatNationalId } from 'kennitala' -import { m } from '../../lib/messages' -import { FinancialStatementCemetery } from '../../lib/dataSchema' -import { formatCurrency } from '../../utils/helpers' import { AboutOverview } from './AboutOverview' import { ValueLine } from './ValueLine' import { CapitalNumberOverview } from './CapitalNumbersOverview' @@ -24,117 +20,53 @@ import { sectionColumn, starterColumnStyle, } from './overviewStyles.css' +import { formatCurrency } from '../../utils/currency' +import { isCemetryUnderFinancialLimit } from '../../utils/helpers' +import { getOverviewNumbers } from '../../utils/overviewUtils' +import { m } from '../../lib/messages' export const CemeteryOverview = ({ application }: FieldBaseProps) => { const { formatMessage } = useLocale() - - const answers = application.answers as FinancialStatementCemetery - const file = getValueViaPath>(answers, 'attachments.file') - const fileName = file?.[0]?.name - const incomeLimit = - getValueViaPath(answers, 'cemeteryOperations.incomeLimit') ?? '0' - const email = getValueViaPath(answers, 'about.email') - const cemeteryCaretakers = answers.cemeteryCaretaker - - const careIncome = getValueViaPath( - answers, - 'cemeteryIncome.careIncome', - ) - const burialRevenue = getValueViaPath( - answers, - 'cemeteryIncome.burialRevenue', - ) - const grantFromTheCemeteryFund = getValueViaPath( - answers, - 'cemeteryIncome.grantFromTheCemeteryFund', - ) - const otherIncome = getValueViaPath( - answers, - 'cemeteryIncome.otherIncome', - ) - const totalIncome = getValueViaPath(answers, 'cemeteryIncome.total') - - const payroll = getValueViaPath(answers, 'cemeteryExpense.payroll') - const funeralCost = getValueViaPath( - answers, - 'cemeteryExpense.funeralCost', - ) - const chapelExpense = getValueViaPath( - answers, - 'cemeteryExpense.chapelExpense', - ) - const donationsToCemeteryFund = getValueViaPath( - answers, - 'cemeteryExpense.cemeteryFundExpense', - ) - const donationsToOther = getValueViaPath( - answers, - 'cemeteryExpense.donationsToOther', - ) - const otherOperationCost = getValueViaPath( - answers, - 'cemeteryExpense.otherOperationCost', - ) - const depreciation = getValueViaPath( - answers, - 'cemeteryExpense.depreciation', - ) - const totalExpenses = getValueViaPath( - answers, - 'cemeteryExpense.total', - ) - - const fixedAssetsTotal = getValueViaPath( - answers, - 'cemeteryAsset.fixedAssetsTotal', - ) - const currentAssets = getValueViaPath( - answers, - 'cemeteryAsset.currentAssets', - ) - const totalAssets = getValueViaPath(answers, 'assetsTotal') - - const longTerm = getValueViaPath( - answers, - 'cemeteryLiability.longTerm', - ) - const shortTerm = getValueViaPath( - answers, - 'cemeteryLiability.shortTerm', - ) - const totalLiabilities = getValueViaPath( - answers, - 'equityAndLiabilitiesTotals.liabilitiesTotal', - ) - - const equityAtTheBeginningOfTheYear = getValueViaPath( - answers, - 'cemeteryEquity.equityAtTheBeginningOfTheYear', - ) - const revaluationDueToPriceChanges = getValueViaPath( - answers, - 'cemeteryEquity.revaluationDueToPriceChanges', - ) - const reevaluateOther = getValueViaPath( - answers, - 'cemeteryEquity.reevaluateOther', - ) - const operationResult = getValueViaPath( - answers, - 'cemeteryEquity.operationResult', - ) - const totalEquity = getValueViaPath(answers, 'cemeteryEquity.total') - - const debtsAndCash = getValueViaPath( - answers, - 'equityAndLiabilitiesTotals.equityAndLiabilitiesTotal', + const cemeteryUnderFinancialLimit = isCemetryUnderFinancialLimit( + application.answers, ) + const { + careIncome, + burialRevenue, + grantFromTheCemeteryFund, + otherIncome, + totalIncome, + payroll, + funeralCost, + chapelExpense, + donationsToCemeteryFund, + donationsToOther, + otherOperationCost, + depreciation, + totalExpenses, + fixedAssetsTotal, + currentAssets, + totalAssets, + longTerm, + shortTerm, + totalLiabilities, + equityAtTheBeginningOfTheYear, + revaluationDueToPriceChanges, + reevaluateOther, + operationResult, + totalEquity, + debtsAndCash, + email, + fileName, + incomeLimit, + cemeteryCaretakers, + } = getOverviewNumbers(application.answers) return ( - + @@ -214,7 +146,7 @@ export const CemeteryOverview = ({ application }: FieldBaseProps) => { - + @@ -294,8 +226,9 @@ export const CemeteryOverview = ({ application }: FieldBaseProps) => { - {Number(totalIncome) < Number(incomeLimit) && - cemeteryCaretakers?.length > 0 ? ( + {cemeteryUnderFinancialLimit && + cemeteryCaretakers && + cemeteryCaretakers.length > 0 ? ( <> @@ -338,7 +271,7 @@ export const CemeteryOverview = ({ application }: FieldBaseProps) => { ) : null} {fileName ? ( <> - + ) : null} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/FetchDataBasedOnSelectedYear/index.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/FetchDataBasedOnSelectedYear/index.tsx new file mode 100644 index 000000000000..1fbb78acc661 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-cemetery/src/fields/FetchDataBasedOnSelectedYear/index.tsx @@ -0,0 +1,123 @@ +import { useEffect } from 'react' +import { + AlertMessage, + ContentBlock, + LoadingDots, +} from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { useQuery } from '@apollo/client' +import { useFormContext } from 'react-hook-form' +import { financialLimitQuery, taxInfoQuery } from '../../graphql' +import { CEMETERYOPERATIONIDS } from '../../utils/constants' +import { FSIUSERTYPE, TaxInfoData } from '../../types/types' +import { + getCareIncomeAndBurialRevenueAndGrant, + getTaxInfoFromAnswers, +} from '../../utils/helpers' +import { m } from '../../lib/messages' + +export const FetchDataBasedOnSelectedYear = () => { + const { getValues, setValue } = useFormContext() + const { formatMessage } = useLocale() + + const values = getValues() + const year: string = values?.conditionalAbout?.operatingYear + + const { data, error, loading } = useQuery(financialLimitQuery, { + variables: { input: { year, clientType: `${FSIUSERTYPE.CEMETRY}` } }, + }) + + const { data: taxInfoData, loading: taxInfoLoading } = useQuery( + taxInfoQuery, + { + variables: { year }, + }, + ) + + const { + careIncomeFromAnswers, + burialRevenueFromAnswers, + grantFromTheCemeteryFundFromAnswers, + donationsToCemeteryFundFromAnswers, + } = getTaxInfoFromAnswers(values) + + useEffect(() => { + const limit = data?.financialStatementsInaoClientFinancialLimit?.toString() + + if (limit) { + setValue(CEMETERYOPERATIONIDS.incomeLimit, limit) + } + }, [data, setValue]) + + useEffect(() => { + if (!taxInfoData) return + + const { + careIncome, + burialRevenue, + grantFromTheCemeteryFund, + donationsToCemeteryFund, + } = getCareIncomeAndBurialRevenueAndGrant( + taxInfoData.financialStatementsInaoTaxInfo, + ) + + const updates = [ + { + id: CEMETERYOPERATIONIDS.careIncome, + value: careIncome, + exists: careIncomeFromAnswers, + }, + { + id: CEMETERYOPERATIONIDS.burialRevenue, + value: burialRevenue, + exists: burialRevenueFromAnswers, + }, + { + id: CEMETERYOPERATIONIDS.grantFromTheCemeteryFund, + value: grantFromTheCemeteryFund, + exists: grantFromTheCemeteryFundFromAnswers, + }, + { + id: CEMETERYOPERATIONIDS.donationsToCemeteryFund, + value: donationsToCemeteryFund, + exists: donationsToCemeteryFundFromAnswers, + }, + ] + + updates.forEach((update) => { + if (!update.exists) { + setValue(update.id, update.value) + } + }) + }, [ + taxInfoData, + setValue, + careIncomeFromAnswers, + burialRevenueFromAnswers, + grantFromTheCemeteryFundFromAnswers, + donationsToCemeteryFundFromAnswers, + CEMETERYOPERATIONIDS, + ]) + + if (loading || taxInfoLoading) { + return ( + + + + ) + } + + if (error) { + return ( + + + + ) + } + + return null +} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx b/libs/application/templates/inao/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx deleted file mode 100644 index f4dcf6f77248..000000000000 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/PowerOfAttorney/index.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import { useEffect } from 'react' -import { useFormContext } from 'react-hook-form' -import { useLazyQuery } from '@apollo/client' -import { - Box, - GridColumn, - GridContainer, - GridRow, - InputError, -} from '@island.is/island-ui/core' -import { InputController } from '@island.is/shared/form-fields' -import { useLocale } from '@island.is/localization' -import { IdentityInput, Query } from '@island.is/api/schema' -import { m } from '../../lib/messages' -import { FieldBaseProps } from '@island.is/application/types' -import { getErrorViaPath } from '@island.is/application/core' -import { IdentityQuery } from '../../graphql' -import { ABOUTIDS } from '../../utils/constants' - -export const PowerOfAttorneyFields = ({ application }: FieldBaseProps) => { - const { formatMessage } = useLocale() - const { - formState: { errors }, - setValue, - } = useFormContext() - - const currentActor = - application.applicantActors[application.applicantActors.length - 1] - - const [getIdentity, { loading, error: queryError }] = useLazyQuery< - Query, - { input: IdentityInput } - >(IdentityQuery, { - onCompleted: (data) => { - setValue(ABOUTIDS.powerOfAttorneyName, data.identity?.name ?? '') - }, - }) - - useEffect(() => { - if (currentActor) { - getIdentity({ - variables: { - input: { - nationalId: currentActor, - }, - }, - }) - } - }, []) - - if (application.applicantActors.length === 0) { - return null - } - - return ( - - - - - - - - - - - {queryError ? ( - - ) : null} - - - - - ) -} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/fields/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/fields/index.ts index 9903bafb3734..5c8739dcdcab 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/fields/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/fields/index.ts @@ -1,4 +1,3 @@ export { CemeteryCaretaker } from './CemeteryCareteker' -export { PowerOfAttorneyFields } from './PowerOfAttorney' export { CemeteryOverview } from './CemeteryOverview' -export { CemeteryIncomeLimit } from './CemeteryIncomeLimit' +export { FetchDataBasedOnSelectedYear } from './FetchDataBasedOnSelectedYear' diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts deleted file mode 100644 index 21b59e7439fe..000000000000 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/caretakerMultiField.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { buildCustomField, buildMultiField } from '@island.is/application/core' -import { m } from '../../../lib/messages' -import { CEMETERYCARETAKER } from '../../../utils/constants' - -export const caretakerMultiField = buildMultiField({ - id: 'caretakers', - title: m.cemeteryBoardmembers, - description: m.cemeteryRegisterCaretakers, - children: [ - buildCustomField({ - id: 'cemeteryCaretaker', - title: m.cemeteryBoardmembers, - component: 'CemeteryCaretaker', - childInputIds: Object.values(CEMETERYCARETAKER), - }), - ], -}) diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts index a5805af6e458..384036b026d1 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryCaretakerSection/index.ts @@ -1,9 +1,32 @@ -import { buildSection } from '@island.is/application/core' +import { + buildCustomField, + buildMultiField, + buildSection, +} from '@island.is/application/core' import { m } from '../../../lib/messages' -import { caretakerMultiField } from './caretakerMultiField' +import { CEMETERYCARETAKER } from '../../../utils/constants' +import { isCemetryUnderFinancialLimit } from '../../../utils/helpers' +// This section should appear if the cemetries total income is under the income limit export const cemeteryCaretekerSection = buildSection({ + condition: (answers) => { + return isCemetryUnderFinancialLimit(answers) + }, id: 'cemeteryCaretekerSection', title: m.cemeteryCaretakers, - children: [caretakerMultiField], + children: [ + buildMultiField({ + id: 'caretakers', + title: m.cemeteryBoardmembers, + description: m.cemeteryRegisterCaretakers, + children: [ + buildCustomField({ + id: 'cemeteryCaretaker', + title: m.cemeteryBoardmembers, + component: 'CemeteryCaretaker', + childInputIds: Object.values(CEMETERYCARETAKER), + }), + ], + }), + ], }) diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts index 8df2c99ea9cd..b46b820b5714 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryFinancialStatementSection/index.ts @@ -1,30 +1,18 @@ import { buildFileUploadField, buildSection } from '@island.is/application/core' import { m } from '../../../lib/messages' -import { currencyStringToNumber } from '../../../utils/helpers' -import { FinancialStatementCemetery } from '../../../lib/dataSchema' +import { isCemetryUnderFinancialLimit } from '../../../utils/helpers' +// This section should appear if the cemetries total income is over the income limit export const cemeteryFinancialStatementSection = buildSection({ + condition: (answers) => { + return !isCemetryUnderFinancialLimit(answers) + }, id: 'documents', title: m.financialStatement, children: [ buildFileUploadField({ id: 'attachments.file', title: m.upload, - condition: (answers) => { - const applicationAnswers = answers as FinancialStatementCemetery - const careTakerLimit = - applicationAnswers.cemeteryOperation?.incomeLimit ?? '0' - const fixedAssetsTotal = - applicationAnswers.cemeteryAsset?.fixedAssetsTotal - const totalIncome = applicationAnswers.cemeteryIncome?.total - const longTermDebt = applicationAnswers.cemeteryLiability?.longTerm - const isUnderLimit = - currencyStringToNumber(totalIncome) < careTakerLimit - if (isUnderLimit && fixedAssetsTotal === '0' && longTermDebt === '0') { - return false - } - return true - }, introduction: m.uploadIntro, description: m.uploadDescription, uploadHeader: m.uploadHeader, diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts index 86bc4ae3eaa0..c8f3ff8e67a3 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/capitalNumberSubSection.ts @@ -6,7 +6,7 @@ import { } from '@island.is/application/core' import { m } from '../../../lib/messages' import { CAPITALNUMBERS } from '../../../utils/constants' -import { sumCapitalNumbers } from '../../../utils/helpers' +import { sumCapitalNumbers } from '../../../utils/sums' export const capitalNumberSubSection = buildSubSection({ id: 'keynumbers.capitalNumbers', diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts index 1e0f6a2987f2..5a1b3b970132 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/equityAndLiabilitySubSection.ts @@ -13,12 +13,12 @@ import { } from '../../../utils/constants' import { operationResult, - showEquitiesAndLiabilitiesAlert, - sumAssets, sumLiabilities, - sumTotalEquity, sumTotalEquityAndLiabilities, -} from '../../../utils/helpers' + sumTotalEquity, + showEquitiesAndLiabilitiesAlert, + sumAssets, +} from '../../../utils/sums' export const equityAndLiabilitiesSubSection = buildSubSection({ id: 'keyNumbers.cemetryEquitiesAndLiabilities', diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts index 34329fa8ee15..d15128bfd667 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/cemeteryKeyNumbersSection/opperatingCostSubSection.ts @@ -12,7 +12,7 @@ import { sumExpenses, sumIncome, sumOperatingResults, -} from '../../../utils/helpers' +} from '../../../utils/sums' export const opperatingCostSubSection = buildSubSection({ id: 'operatingCost', @@ -24,9 +24,9 @@ export const opperatingCostSubSection = buildSubSection({ description: m.fillOutAppopriate, children: [ buildCustomField({ - id: 'cemetryIncomeLimit', + id: 'fetchDataBasedOnYear', title: '', - component: 'CemeteryIncomeLimit', + component: 'FetchDataBasedOnSelectedYear', }), // Income buildDescriptionField({ diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts index 9916366fd934..718b55a3d021 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/forms/applicationForm/clientInfoSection/index.ts @@ -1,12 +1,13 @@ import { buildAsyncSelectField, - buildCustomField, buildDescriptionField, buildMultiField, + buildPhoneField, buildSection, buildTextField, + getValueViaPath, } from '@island.is/application/core' -import { Application, UserProfile } from '@island.is/application/types' +import { Application } from '@island.is/application/types' import { m } from '../../../lib/messages' import { ABOUTIDS } from '../../../utils/constants' import { Identity } from '@island.is/api/schema' @@ -58,42 +59,49 @@ export const clientInfoSection = buildSection({ return nationalRegistry.name }, }), - buildDescriptionField({ - id: 'about.description2', - title: '', + buildTextField({ + id: ABOUTIDS.powerOfAttorneyNationalId, + title: m.powerOfAttorneyNationalId, + width: 'half', + readOnly: true, + format: '######-####', + defaultValue: (application: Application) => + getValueViaPath( + application.externalData, + 'identity.data.actor.nationalId', + ), }), - buildCustomField({ - id: 'powerOfAttorney', - title: '', - description: '', - component: 'PowerOfAttorneyFields', - childInputIds: [ - ABOUTIDS.powerOfAttorneyNationalId, - ABOUTIDS.powerOfAttorneyName, - ], + buildTextField({ + id: ABOUTIDS.powerOfAttorneyName, + title: m.powerOfAttorneyName, + width: 'half', + readOnly: true, + defaultValue: (application: Application) => + getValueViaPath( + application.externalData, + 'identity.data.actor.name', + ), }), - buildTextField({ id: 'about.email', title: m.email, width: 'half', variant: 'email', - defaultValue: (application: Application) => { - const userProfile = application.externalData.userProfile - .data as UserProfile - return userProfile.email - }, + defaultValue: (application: Application) => + getValueViaPath( + application.externalData, + 'userProfile.data.email', + ), }), - buildTextField({ + buildPhoneField({ id: 'about.phoneNumber', title: m.phoneNumber, width: 'half', - variant: 'tel', - defaultValue: (application: Application) => { - const userProfile = application.externalData.userProfile - .data as UserProfile - return userProfile.mobilePhoneNumber - }, + defaultValue: (application: Application) => + getValueViaPath( + application.externalData, + 'userProfile.data.mobilePhoneNumber', + ), }), ], }), diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/hooks/useTotals.ts b/libs/application/templates/inao/financial-statement-cemetery/src/hooks/useTotals.ts deleted file mode 100644 index 15a5873fdd5e..000000000000 --- a/libs/application/templates/inao/financial-statement-cemetery/src/hooks/useTotals.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { useCallback, useEffect, useState } from 'react' -import { useFormContext } from 'react-hook-form' -import { getTotal } from '../utils/helpers' - -const useTotals = (key: string): [() => void, number] => { - const [total, setTotal] = useState(0) - const { getValues } = useFormContext() - const getSum = useCallback(() => { - const values = getValues() - const sum = getTotal(values, key) - setTotal(sum) - }, [key, getValues, setTotal]) - - useEffect(() => { - getSum() - }, [getSum]) - - return [getSum, total] -} - -export { useTotals } diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/lib/dataSchema.ts b/libs/application/templates/inao/financial-statement-cemetery/src/lib/dataSchema.ts index 97379678b103..35a8aefa428f 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/lib/dataSchema.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/lib/dataSchema.ts @@ -3,11 +3,9 @@ import { m } from './messages' import * as kennitala from 'kennitala' import { parsePhoneNumberFromString } from 'libphonenumber-js' import { BOARDMEMEBER, CARETAKER } from '../utils/constants' -import { - isPositiveNumberInString, - getBoardmembersAndCaretakers, -} from '../utils/helpers' +import { getBoardmembersAndCaretakers } from '../utils/helpers' import { YES } from '@island.is/application/types' +import { isPositiveNumberInString } from '../utils/currency' const FileSchema = z.object({ name: z.string(), diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/types/types.ts b/libs/application/templates/inao/financial-statement-cemetery/src/types/types.ts index 53e29233513f..edd111488a8c 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/types/types.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/types/types.ts @@ -46,3 +46,19 @@ type InaoConfigItem = { export type AuditConfig = { financialStatementsInaoConfig: Array } + +export type CareTaker = { + nationalId: string + name: string + role: string +} + +export type TaxInfoItem = { + __typename: string + key: number + value: string +} + +export type TaxInfoData = { + financialStatementsInaoTaxInfo: Array +} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/utils/constants.ts b/libs/application/templates/inao/financial-statement-cemetery/src/utils/constants.ts index 2c0cb3bb6afe..190000af6700 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/utils/constants.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/utils/constants.ts @@ -26,6 +26,7 @@ export enum TaxInfoTypes { CARE_INCOME = 300, BURIAL_REVENUE = 301, GRANT_FROM_THE_CEMETERY_FUND = 302, + DONATIONS_TO_CEMETERYFUND = 334, } export const CEMETERYOPERATIONIDS = { diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/utils/currency.ts b/libs/application/templates/inao/financial-statement-cemetery/src/utils/currency.ts new file mode 100644 index 000000000000..7ffe7149224c --- /dev/null +++ b/libs/application/templates/inao/financial-statement-cemetery/src/utils/currency.ts @@ -0,0 +1,16 @@ +export const currencyStringToNumber = (str: string) => { + if (!str) { + return str + } + const cleanString = str.replace(/[,\s]+|[.\s]+/g, '') + return parseInt(cleanString, 10) +} + +export const formatCurrency = (answer?: string) => { + if (!answer) return '0. kr' + return answer.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' kr.' +} + +export const isPositiveNumberInString = (input: string) => { + return Number(input) >= 0 +} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/utils/helpers.ts b/libs/application/templates/inao/financial-statement-cemetery/src/utils/helpers.ts index aec943d790e8..9a6d72727122 100644 --- a/libs/application/templates/inao/financial-statement-cemetery/src/utils/helpers.ts +++ b/libs/application/templates/inao/financial-statement-cemetery/src/utils/helpers.ts @@ -1,42 +1,16 @@ -import { ExternalData, FormValue } from '@island.is/application/types' +import { FormValue } from '@island.is/application/types' import { getValueViaPath } from '@island.is/application/core' import { BOARDMEMEBER, - CAPITALNUMBERS, CARETAKER, CemeteriesBackwardLimit, CemeteriesYearAllowed, - CEMETERYEQUITIESANDLIABILITIESIDS, CEMETERYOPERATIONIDS, - EQUITYANDLIABILITIESTOTALS, - OPERATINGCOST, - TOTAL, + TaxInfoTypes, } from './constants' -import { FinancialStatementCemetery } from '../lib/dataSchema' import getYear from 'date-fns/getYear' import subYears from 'date-fns/subYears' -import { AuditConfig, BoardMember, Config, FSIUSERTYPE } from '../types/types' - -export const getTotal = (values: Record, key: string) => { - if (!values[key]) { - return 0 - } - const total = Object.entries(values[key]) - .filter(([k, v]) => k !== TOTAL && !isNaN(Number(v))) - .map(([_k, v]) => Number(v)) - .reduce((prev, current) => { - return (prev += current) - }, 0) - return total -} - -export const currencyStringToNumber = (str: string) => { - if (!str) { - return str - } - const cleanString = str.replace(/[,\s]+|[.\s]+/g, '') - return parseInt(cleanString, 10) -} +import { AuditConfig, BoardMember, TaxInfoItem } from '../types/types' export const getBoardmembersAndCaretakers = (members: Array) => { const careTakers = members @@ -60,11 +34,7 @@ export const isCemetryUnderFinancialLimit = (answers: FormValue) => { getValueViaPath(answers, 'cemeteryLiability.longTerm') || '0' const isUnderLimit = Number(totalIncome) < Number(incomeLimit) - if (isUnderLimit && fixedAssetsTotal === '0' && longTermDebt === '0') { - return true - } - - return false + return isUnderLimit && fixedAssetsTotal === '0' && longTermDebt === '0' } export const getYearOptions = (data: AuditConfig) => { @@ -103,226 +73,64 @@ export const possibleOperatingYears = ( return operationYears } -export const getConfigInfoForKey = (config: Config[], configKey: string) => { - return config?.filter((config: Config) => config.key === configKey)[0].value -} - -export const formatCurrency = (answer?: string) => { - if (!answer) return '0. kr' - return answer.replace(/\B(?=(\d{3})+(?!\d))/g, '.') + ' kr.' -} - -export const isPositiveNumberInString = (input: string) => { - return Number(input) > 0 -} - -export const sumIncome = (answers: FormValue) => { - const careIncome = - getValueViaPath(answers, CEMETERYOPERATIONIDS.careIncome) || '0' - const burialRevenue = - getValueViaPath(answers, CEMETERYOPERATIONIDS.burialRevenue) || '0' - const grantFromTheCemeteryFund = - getValueViaPath( - answers, - CEMETERYOPERATIONIDS.grantFromTheCemeteryFund, - ) || '0' - const otherIncome = - getValueViaPath(answers, CEMETERYOPERATIONIDS.otherIncome) || '0' - - return `${ - Number(careIncome) + - Number(burialRevenue) + - Number(grantFromTheCemeteryFund) + - Number(otherIncome) - }` -} - -export const sumExpenses = (answers: FormValue) => { - const payroll = getValueViaPath(answers, CEMETERYOPERATIONIDS.payroll) - const funeralCost = - getValueViaPath(answers, CEMETERYOPERATIONIDS.funeralCost) || '0' - const chapelExpense = - getValueViaPath(answers, CEMETERYOPERATIONIDS.chapelExpense) || '0' - const donationsToCemeteryFund = - getValueViaPath( - answers, - CEMETERYOPERATIONIDS.donationsToCemeteryFund, - ) || '0' - const donationsToOther = - getValueViaPath(answers, CEMETERYOPERATIONIDS.donationsToOther) || - '0' - const otherOperationCost = - getValueViaPath(answers, CEMETERYOPERATIONIDS.otherOperationCost) || - '0' - const depreciation = - getValueViaPath(answers, CEMETERYOPERATIONIDS.depreciation) || '0' - - return `${ - Number(payroll) + - Number(funeralCost) + - Number(chapelExpense) + - Number(donationsToCemeteryFund) + - Number(donationsToOther) + - Number(otherOperationCost) + - Number(depreciation) - }` -} - -export const sumOperatingResults = (answers: FormValue) => { - const income = - getValueViaPath(answers, CEMETERYOPERATIONIDS.totalIncome) || '0' - const expenses = - getValueViaPath(answers, CEMETERYOPERATIONIDS.totalExpense) || '0' - - return `${Number(income) - Number(expenses)}` -} - -export const sumCapitalNumbers = (answers: FormValue) => { - const capitalIncome = - getValueViaPath(answers, CAPITALNUMBERS.capitalIncome) || '0' - const capitalCost = - getValueViaPath(answers, CAPITALNUMBERS.capitalCost) || '0' - return `${Number(capitalIncome) - Number(capitalCost)}` -} - -export const sumAssets = (answers: FormValue) => { - const fixedAssetsTotal = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.fixedAssetsTotal, - ) || '0' - const currentAssets = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets, - ) || '0' - return `${Number(fixedAssetsTotal) + Number(currentAssets)}` -} - -export const sumLiabilities = (answers: FormValue) => { - const longTerm = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.longTerm, - ) || '0' - const shortTerm = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm, - ) || '0' - return `${Number(longTerm) + Number(shortTerm)}` -} - -export const operationResult = (answers: FormValue) => { - const operatingTotalCost = - getValueViaPath(answers, OPERATINGCOST.total) || '0' - const capitalTotal = - getValueViaPath(answers, CAPITALNUMBERS.total) || '0' - return `${Number(operatingTotalCost) + Number(capitalTotal)}` -} - -export const sumTotalEquity = (answers: FormValue) => { - const equityAtTheBeginningOfTheYear = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear, - ) || '0' - const revaluationDueToPriceChanges = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges, - ) || '0' - const reevaluateOther = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther, - ) || '0' - const operationResult = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.operationResult, - ) || '0' - - return `${ - Number(equityAtTheBeginningOfTheYear) + - Number(revaluationDueToPriceChanges) + - Number(reevaluateOther) + - Number(operationResult) - }` -} - -export const sumTotalEquityAndLiabilities = (answers: FormValue) => { - const liabilityTotal = - getValueViaPath( - answers, - EQUITYANDLIABILITIESTOTALS.liabilitiesTotal, - ) || '0' - const totalEquity = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.equityTotal, - ) || '0' +export const getCareIncomeAndBurialRevenueAndGrant = ( + taxInfo?: Array, +) => { + if (!taxInfo) { + return { + careIncome: undefined, + burialRevenue: undefined, + grantFromTheCemeteryFund: undefined, + } + } - return `${Number(totalEquity) + Number(liabilityTotal)}` + const careIncome = taxInfo.find( + (item) => item.key === TaxInfoTypes.CARE_INCOME, + ) + const burialRevenue = taxInfo.find( + (item) => item.key === TaxInfoTypes.BURIAL_REVENUE, + ) + const grantFromTheCemeteryFund = taxInfo.find( + (item) => item.key === TaxInfoTypes.GRANT_FROM_THE_CEMETERY_FUND, + ) + const donationsToCemeteryFund = taxInfo.find( + (item) => item.key === TaxInfoTypes.DONATIONS_TO_CEMETERYFUND, + ) + + return { + careIncome: careIncome ? careIncome.value : undefined, + burialRevenue: burialRevenue ? burialRevenue.value : undefined, + grantFromTheCemeteryFund: grantFromTheCemeteryFund + ? grantFromTheCemeteryFund.value + : undefined, + donationsToCemeteryFund: donationsToCemeteryFund + ? donationsToCemeteryFund.value + : undefined, + } } -export const showEquitiesAndLiabilitiesAlert = (answers: FormValue) => { - const fixedAssetsTotal = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.fixedAssetsTotal, - ) || '0' - const currentAssets = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets, - ) || '0' - const longTerm = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.longTerm, - ) || '0' - const shortTerm = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm, - ) || '0' - const equityAtTheBeginningOfTheYear = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear, - ) || '0' - const revaluationDueToPriceChanges = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges, - ) || '0' - const reevaluateOther = - getValueViaPath( - answers, - CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther, - ) || '0' - - const totalAssets = - getValueViaPath(answers, EQUITYANDLIABILITIESTOTALS.assetsTotal) || - '0' - const totalEquityAndLiabilities = - getValueViaPath( - answers, - EQUITYANDLIABILITIESTOTALS.equityAndLiabilitiesTotal, - ) || '0' - - if ( - !fixedAssetsTotal || - !currentAssets || - !longTerm || - !shortTerm || - !equityAtTheBeginningOfTheYear || - !revaluationDueToPriceChanges || - !reevaluateOther || - !operationResult - ) { - return false +export const getTaxInfoFromAnswers = (answers: FormValue) => { + const careIncome = getValueViaPath( + answers, + CEMETERYOPERATIONIDS.careIncome, + ) + const burialRevenue = getValueViaPath( + answers, + CEMETERYOPERATIONIDS.burialRevenue, + ) + const grantFromTheCemeteryFund = getValueViaPath( + answers, + CEMETERYOPERATIONIDS.grantFromTheCemeteryFund, + ) + const donationsToCemeteryFund = getValueViaPath( + answers, + CEMETERYOPERATIONIDS.donationsToCemeteryFund, + ) + + return { + careIncomeFromAnswers: careIncome, + burialRevenueFromAnswers: burialRevenue, + grantFromTheCemeteryFundFromAnswers: grantFromTheCemeteryFund, + donationsToCemeteryFundFromAnswers: donationsToCemeteryFund, } - return totalAssets !== totalEquityAndLiabilities } diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/utils/overviewUtils.ts b/libs/application/templates/inao/financial-statement-cemetery/src/utils/overviewUtils.ts new file mode 100644 index 000000000000..f27cb0ef6f96 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-cemetery/src/utils/overviewUtils.ts @@ -0,0 +1,189 @@ +import { FormValue } from '@island.is/application/types' +import { getValueViaPath } from '@island.is/application/core' +import { CareTaker } from '../types/types' +import { formatPhoneNumber } from '@island.is/application/ui-components' +import { format as formatNationalId } from 'kennitala' +import { formatCurrency } from './currency' + +export const getOverviewNumbers = (answers: FormValue) => { + const file = getValueViaPath>(answers, 'attachments.file') + const fileName = file?.[0]?.name + const incomeLimit = + getValueViaPath(answers, 'cemeteryOperations.incomeLimit') ?? '0' + const email = getValueViaPath(answers, 'about.email') + const careIncome = getValueViaPath( + answers, + 'cemeteryIncome.careIncome', + ) + const cemeteryCaretakers = getValueViaPath>( + answers, + 'cemeteryCaretaker', + ) + const burialRevenue = getValueViaPath( + answers, + 'cemeteryIncome.burialRevenue', + ) + const grantFromTheCemeteryFund = getValueViaPath( + answers, + 'cemeteryIncome.grantFromTheCemeteryFund', + ) + const otherIncome = getValueViaPath( + answers, + 'cemeteryIncome.otherIncome', + ) + const totalIncome = getValueViaPath(answers, 'cemeteryIncome.total') + + const payroll = getValueViaPath(answers, 'cemeteryExpense.payroll') + const funeralCost = getValueViaPath( + answers, + 'cemeteryExpense.funeralCost', + ) + const chapelExpense = getValueViaPath( + answers, + 'cemeteryExpense.chapelExpense', + ) + const donationsToCemeteryFund = getValueViaPath( + answers, + 'cemeteryExpense.cemeteryFundExpense', + ) + const donationsToOther = getValueViaPath( + answers, + 'cemeteryExpense.donationsToOther', + ) + const otherOperationCost = getValueViaPath( + answers, + 'cemeteryExpense.otherOperationCost', + ) + const depreciation = getValueViaPath( + answers, + 'cemeteryExpense.depreciation', + ) + const totalExpenses = getValueViaPath( + answers, + 'cemeteryExpense.total', + ) + + const fixedAssetsTotal = getValueViaPath( + answers, + 'cemeteryAsset.fixedAssetsTotal', + ) + const currentAssets = getValueViaPath( + answers, + 'cemeteryAsset.currentAssets', + ) + const totalAssets = getValueViaPath(answers, 'assetsTotal') + + const longTerm = getValueViaPath( + answers, + 'cemeteryLiability.longTerm', + ) + const shortTerm = getValueViaPath( + answers, + 'cemeteryLiability.shortTerm', + ) + const totalLiabilities = getValueViaPath( + answers, + 'equityAndLiabilitiesTotals.liabilitiesTotal', + ) + + const equityAtTheBeginningOfTheYear = getValueViaPath( + answers, + 'cemeteryEquity.equityAtTheBeginningOfTheYear', + ) + const revaluationDueToPriceChanges = getValueViaPath( + answers, + 'cemeteryEquity.revaluationDueToPriceChanges', + ) + const reevaluateOther = getValueViaPath( + answers, + 'cemeteryEquity.reevaluateOther', + ) + const operationResult = getValueViaPath( + answers, + 'cemeteryEquity.operationResult', + ) + const totalEquity = getValueViaPath(answers, 'cemeteryEquity.total') + + const debtsAndCash = getValueViaPath( + answers, + 'equityAndLiabilitiesTotals.equityAndLiabilitiesTotal', + ) + + return { + file, + fileName, + incomeLimit, + email, + cemeteryCaretakers, + careIncome, + burialRevenue, + grantFromTheCemeteryFund, + otherIncome, + totalIncome, + payroll, + funeralCost, + chapelExpense, + donationsToCemeteryFund, + donationsToOther, + otherOperationCost, + depreciation, + totalExpenses, + fixedAssetsTotal, + currentAssets, + totalAssets, + longTerm, + shortTerm, + totalLiabilities, + equityAtTheBeginningOfTheYear, + revaluationDueToPriceChanges, + reevaluateOther, + operationResult, + totalEquity, + debtsAndCash, + } +} + +export const getAboutOverviewNumbers = (answers: FormValue) => { + const fullName = getValueViaPath(answers, 'about.fullName') + const nationalId = formatNationalId( + getValueViaPath(answers, 'about.nationalId') ?? '', + ) + const powerOfAttorneyName = getValueViaPath( + answers, + 'about.powerOfAttorneyName', + ) + const powerOfAttorneyNationalId = formatNationalId( + getValueViaPath(answers, 'about.powerOfAttorneyNationalId') ?? '', + ) + const email = getValueViaPath(answers, 'about.email') + const phoneNumber = formatPhoneNumber( + getValueViaPath(answers, 'about.phoneNumber') ?? '', + ) + + return { + fullName, + nationalId, + powerOfAttorneyName, + powerOfAttorneyNationalId, + email, + phoneNumber, + } +} + +export const getCapitalNumbersOverviewNumbers = (answers: FormValue) => { + const capitalIncome = formatCurrency( + getValueViaPath(answers, 'capitalNumbers.capitalIncome'), + ) + const capitalCost = formatCurrency( + getValueViaPath(answers, 'capitalNumbers.capitalCost'), + ) + const totalCapital = formatCurrency( + getValueViaPath(answers, 'capitalNumbers.total'), + ) + + return { + capitalIncome, + capitalCost, + totalCapital, + } +} diff --git a/libs/application/templates/inao/financial-statement-cemetery/src/utils/sums.ts b/libs/application/templates/inao/financial-statement-cemetery/src/utils/sums.ts new file mode 100644 index 000000000000..4b8e6c2e1738 --- /dev/null +++ b/libs/application/templates/inao/financial-statement-cemetery/src/utils/sums.ts @@ -0,0 +1,225 @@ +import { FormValue } from '@island.is/application/types' +import { getValueViaPath } from '@island.is/application/core' +import { + CAPITALNUMBERS, + CEMETERYEQUITIESANDLIABILITIESIDS, + CEMETERYOPERATIONIDS, + EQUITYANDLIABILITIESTOTALS, + OPERATINGCOST, +} from './constants' + +export const sumIncome = (answers: FormValue) => { + const careIncome = + getValueViaPath(answers, CEMETERYOPERATIONIDS.careIncome) || '0' + const burialRevenue = + getValueViaPath(answers, CEMETERYOPERATIONIDS.burialRevenue) || '0' + const grantFromTheCemeteryFund = + getValueViaPath( + answers, + CEMETERYOPERATIONIDS.grantFromTheCemeteryFund, + ) || '0' + const otherIncome = + getValueViaPath(answers, CEMETERYOPERATIONIDS.otherIncome) || '0' + + return `${ + Number(careIncome) + + Number(burialRevenue) + + Number(grantFromTheCemeteryFund) + + Number(otherIncome) + }` +} + +export const sumExpenses = (answers: FormValue) => { + const payroll = getValueViaPath(answers, CEMETERYOPERATIONIDS.payroll) + const funeralCost = + getValueViaPath(answers, CEMETERYOPERATIONIDS.funeralCost) || '0' + const chapelExpense = + getValueViaPath(answers, CEMETERYOPERATIONIDS.chapelExpense) || '0' + const donationsToCemeteryFund = + getValueViaPath( + answers, + CEMETERYOPERATIONIDS.donationsToCemeteryFund, + ) || '0' + const donationsToOther = + getValueViaPath(answers, CEMETERYOPERATIONIDS.donationsToOther) || + '0' + const otherOperationCost = + getValueViaPath(answers, CEMETERYOPERATIONIDS.otherOperationCost) || + '0' + const depreciation = + getValueViaPath(answers, CEMETERYOPERATIONIDS.depreciation) || '0' + + return `${ + Number(payroll) + + Number(funeralCost) + + Number(chapelExpense) + + Number(donationsToCemeteryFund) + + Number(donationsToOther) + + Number(otherOperationCost) + + Number(depreciation) + }` +} + +export const sumOperatingResults = (answers: FormValue) => { + const income = + getValueViaPath(answers, CEMETERYOPERATIONIDS.totalIncome) || '0' + const expenses = + getValueViaPath(answers, CEMETERYOPERATIONIDS.totalExpense) || '0' + + return `${Number(income) - Number(expenses)}` +} + +export const sumCapitalNumbers = (answers: FormValue) => { + const capitalIncome = + getValueViaPath(answers, CAPITALNUMBERS.capitalIncome) || '0' + const capitalCost = + getValueViaPath(answers, CAPITALNUMBERS.capitalCost) || '0' + return `${Number(capitalIncome) - Number(capitalCost)}` +} + +export const sumAssets = (answers: FormValue) => { + const fixedAssetsTotal = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.fixedAssetsTotal, + ) || '0' + const currentAssets = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets, + ) || '0' + return `${Number(fixedAssetsTotal) + Number(currentAssets)}` +} + +export const sumLiabilities = (answers: FormValue) => { + const longTerm = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.longTerm, + ) || '0' + const shortTerm = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm, + ) || '0' + return `${Number(longTerm) + Number(shortTerm)}` +} + +export const operationResult = (answers: FormValue) => { + const operatingTotalCost = + getValueViaPath(answers, OPERATINGCOST.total) || '0' + const capitalTotal = + getValueViaPath(answers, CAPITALNUMBERS.total) || '0' + return `${Number(operatingTotalCost) + Number(capitalTotal)}` +} + +export const sumTotalEquity = (answers: FormValue) => { + const equityAtTheBeginningOfTheYear = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear, + ) || '0' + const revaluationDueToPriceChanges = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges, + ) || '0' + const reevaluateOther = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther, + ) || '0' + const operationResult = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.operationResult, + ) || '0' + + return `${ + Number(equityAtTheBeginningOfTheYear) + + Number(revaluationDueToPriceChanges) + + Number(reevaluateOther) + + Number(operationResult) + }` +} + +export const sumTotalEquityAndLiabilities = (answers: FormValue) => { + const liabilityTotal = + getValueViaPath( + answers, + EQUITYANDLIABILITIESTOTALS.liabilitiesTotal, + ) || '0' + const totalEquity = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.equityTotal, + ) || '0' + + return `${Number(totalEquity) + Number(liabilityTotal)}` +} + +export const showEquitiesAndLiabilitiesAlert = (answers: FormValue) => { + const fixedAssetsTotal = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.fixedAssetsTotal, + ) || '0' + const currentAssets = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.currentAssets, + ) || '0' + const longTerm = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.longTerm, + ) || '0' + const shortTerm = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.shortTerm, + ) || '0' + const equityAtTheBeginningOfTheYear = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.equityAtTheBeginningOfTheYear, + ) || '0' + const revaluationDueToPriceChanges = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.revaluationDueToPriceChanges, + ) || '0' + const reevaluateOther = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.reevaluateOther, + ) || '0' + + const totalAssets = + getValueViaPath(answers, EQUITYANDLIABILITIESTOTALS.assetsTotal) || + '0' + const totalEquityAndLiabilities = + getValueViaPath( + answers, + EQUITYANDLIABILITIESTOTALS.equityAndLiabilitiesTotal, + ) || '0' + const operationResult = + getValueViaPath( + answers, + CEMETERYEQUITIESANDLIABILITIESIDS.operationResult, + ) || '0' + + if ( + !fixedAssetsTotal || + !currentAssets || + !longTerm || + !shortTerm || + !equityAtTheBeginningOfTheYear || + !revaluationDueToPriceChanges || + !reevaluateOther || + !operationResult + ) { + return false + } + return totalAssets !== totalEquityAndLiabilities +} From 04563fd4d14e94693b0ef6edba5c1bde1ccf13d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dvar=20Oddsson?= Date: Thu, 12 Dec 2024 22:43:52 +0000 Subject: [PATCH 08/32] feat(j-s): Add court name abbr. to prison cases table (#17171) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/routes/Shared/Cases/PrisonCases.tsx | 31 ++++++++++++++----- .../routes/Shared/Cases/prisonCases.graphql | 4 +++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx index ad91229428cb..3027b2e998f6 100644 --- a/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx +++ b/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx @@ -3,7 +3,10 @@ import { useIntl } from 'react-intl' import partition from 'lodash/partition' import { AlertMessage, Box, Tag, Text } from '@island.is/island-ui/core' -import { capitalize } from '@island.is/judicial-system/formatters' +import { + capitalize, + districtCourtAbbreviation, +} from '@island.is/judicial-system/formatters' import { core, errors, @@ -166,6 +169,10 @@ export const PrisonCases: FC = () => { thead={[ { title: formatMessage(tables.caseNumber), + sortable: { + isSortable: true, + key: 'courtCaseNumber', + }, }, { title: capitalize(formatMessage(core.defendant, { suffix: 'i' })), @@ -182,13 +189,21 @@ export const PrisonCases: FC = () => { data={cases} columns={[ { - cell: (row) => ( - - ), + cell: (row) => { + const courtAbbreviation = districtCourtAbbreviation( + row.court?.name, + ) + + return ( + + ) + }, }, { cell: (row) => , diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql b/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql index 23b25b22538c..04f635815e1e 100644 --- a/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql +++ b/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql @@ -44,6 +44,10 @@ query PrisonCases { role active } + court { + id + name + } prosecutor { id created From 4241fe5d49e70332323c2f27eb40f13ae7bd2b0c Mon Sep 17 00:00:00 2001 From: HjorturJ <34068269+HjorturJ@users.noreply.github.com> Date: Thu, 12 Dec 2024 22:54:01 +0000 Subject: [PATCH 09/32] fix(application-system): Possible to go back to hidden screens (#17162) * Early investigation * chore: nx format:write update dirty files * More investigation and testing * Cleaning up a bit * chore: nx format:write update dirty files * Changing into a 1 liner change * chore: nx format:write update dirty files * Reverting test changes * Going another route to avoid bugs * Removing whitespace --------- Co-authored-by: andes-it Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../ui-shell/src/components/Screen.tsx | 3 +++ .../ui-shell/src/components/ScreenFooter.tsx | 5 +++-- .../ui-shell/src/lib/FormShell.tsx | 2 ++ .../ui-shell/src/reducer/reducerUtils.ts | 19 +++++++++++++++++++ 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/libs/application/ui-shell/src/components/Screen.tsx b/libs/application/ui-shell/src/components/Screen.tsx index 52bcbcce6625..907a34d76624 100644 --- a/libs/application/ui-shell/src/components/Screen.tsx +++ b/libs/application/ui-shell/src/components/Screen.tsx @@ -76,6 +76,7 @@ type ScreenProps = { renderLastScreenBackButton?: boolean goToScreen: (id: string) => void setUpdateForbidden: (value: boolean) => void + canGoBack: boolean } const getServerValidationErrors = (error: ApolloError | undefined) => { @@ -107,6 +108,7 @@ const Screen: FC> = ({ renderLastScreenBackButton, screen, sections, + canGoBack, }) => { const { answers: formValue, externalData, id: applicationId } = application const { lang: locale, formatMessage } = useLocale() @@ -416,6 +418,7 @@ const Screen: FC> = ({ numberOfScreens={numberOfScreens} mode={mode} goBack={goBack} + canGoBack={canGoBack} submitField={submitField} loading={loading} canProceed={!isLoadingOrPending} diff --git a/libs/application/ui-shell/src/components/ScreenFooter.tsx b/libs/application/ui-shell/src/components/ScreenFooter.tsx index 253e4665c354..2c6b653dada9 100644 --- a/libs/application/ui-shell/src/components/ScreenFooter.tsx +++ b/libs/application/ui-shell/src/components/ScreenFooter.tsx @@ -27,6 +27,7 @@ interface FooterProps { renderLastScreenBackButton?: boolean submitButtonDisabled?: boolean nextButtonText?: FormText + canGoBack: boolean } type SubmitButton = Omit & { @@ -68,13 +69,13 @@ export const ScreenFooter: FC> = ({ renderLastScreenBackButton, submitButtonDisabled, nextButtonText, + canGoBack, }) => { const { formatMessage } = useLocale() const user = useUserInfo() const hasSubmitField = submitField !== undefined const isLastScreen = activeScreenIndex === numberOfScreens - 1 - const showGoBack = - activeScreenIndex > 0 && (!isLastScreen || renderLastScreenBackButton) + const showGoBack = canGoBack && (!isLastScreen || renderLastScreenBackButton) if ( (isLastScreen && !renderLastScreenButton) || diff --git a/libs/application/ui-shell/src/lib/FormShell.tsx b/libs/application/ui-shell/src/lib/FormShell.tsx index d3be0a1e4747..8e1beef1c9ee 100644 --- a/libs/application/ui-shell/src/lib/FormShell.tsx +++ b/libs/application/ui-shell/src/lib/FormShell.tsx @@ -25,6 +25,7 @@ import { } from '../reducer/ApplicationFormReducer' import { ActionTypes } from '../reducer/ReducerTypes' import * as styles from './FormShell.css' +import { canGoBack } from '../reducer/reducerUtils' export const FormShell: FC< React.PropsWithChildren<{ @@ -142,6 +143,7 @@ export const FormShell: FC< payload, }) }} + canGoBack={canGoBack(screens, activeScreen)} prevScreen={() => dispatch({ type: ActionTypes.PREV_SCREEN })} activeScreenIndex={activeScreen} numberOfScreens={screens.length} diff --git a/libs/application/ui-shell/src/reducer/reducerUtils.ts b/libs/application/ui-shell/src/reducer/reducerUtils.ts index 72c76a0f9c92..8b3a0b6f38ed 100644 --- a/libs/application/ui-shell/src/reducer/reducerUtils.ts +++ b/libs/application/ui-shell/src/reducer/reducerUtils.ts @@ -181,6 +181,25 @@ export const moveToScreen = ( return screenIndex } +export const canGoBack = ( + screens: FormScreen[], + screenIndex: number, +): boolean => { + // Check if we're already at the start + if (screenIndex <= 0) { + return false + } + + // Look for any navigable screen behind where we are + for (let i = screenIndex - 1; i >= 0; i--) { + if (screens[i].isNavigable) { + return true + } + } + + return false +} + const convertFieldToScreen = ( field: Field, answers: FormValue, From 920eb26f9a2623282f59c066d49760907289a40d Mon Sep 17 00:00:00 2001 From: unakb Date: Thu, 12 Dec 2024 23:29:47 +0000 Subject: [PATCH 10/32] fix(j-s): Police case number in robot e-mail (#17218) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../backend/src/app/modules/court/court.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/judicial-system/backend/src/app/modules/court/court.service.ts b/apps/judicial-system/backend/src/app/modules/court/court.service.ts index df13b35a90be..33f9c74c7c83 100644 --- a/apps/judicial-system/backend/src/app/modules/court/court.service.ts +++ b/apps/judicial-system/backend/src/app/modules/court/court.service.ts @@ -577,12 +577,12 @@ export class CourtService { try { const subject = `${courtName} - ${courtCaseNumber} - upplýsingar` - const sanitizedPoliceCaseNumber = policeCaseNumber?.replace(/-/g, '') + policeCaseNumber = policeCaseNumber?.replace(/-/g, '') const content = JSON.stringify({ receivedByCourtDate, indictmentDate, - sanitizedPoliceCaseNumber, + policeCaseNumber, subtypes, defendants, prosecutor, From 09111419376a00eab84eeddea3bbc363840ab01f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafn=20=C3=81rnason?= Date: Fri, 13 Dec 2024 00:09:41 +0000 Subject: [PATCH 11/32] feat(user-notification): Firebase Credentials Setup for Local Development (#17199) * fix get-secrets and env cleanup * chore: nx format:write update dirty files * string cleaner for local * chore: nx format:write update dirty files * update get-secrets * cleanup * cleanup * move logic to render-secrets --------- Co-authored-by: andes-it Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- infra/src/cli/render-secrets.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/infra/src/cli/render-secrets.ts b/infra/src/cli/render-secrets.ts index 9c859e2afba8..0ba1ba705b36 100644 --- a/infra/src/cli/render-secrets.ts +++ b/infra/src/cli/render-secrets.ts @@ -68,9 +68,7 @@ export const renderSecrets = async (service: string) => { logger.debug('env when rendering', { envMap }) Object.entries(envMap).forEach(([key, value]) => { - const escapedValue = (value ?? '') - .replace(/\n/g, '\\n') - .replace(/"/g, '\\"') + const escapedValue = (value ?? '').replace(/'/g, "\\'") console.log(`export ${key}='${escapedValue}'`) }) return envMap From 1e607631e6e0c35f89b044cc2a6bd553598aa872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9E=C3=B3rey=20J=C3=B3na?= Date: Fri, 13 Dec 2024 00:17:25 +0000 Subject: [PATCH 12/32] feat(native-app): Update passkey information link (#17221) * chore: update podfile.lock * feat: update link address for further info about passkeys --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/native/app/ios/Podfile.lock | 70 ++++++++++++++++++- .../app/src/screens/passkey/passkey.tsx | 5 +- 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/apps/native/app/ios/Podfile.lock b/apps/native/app/ios/Podfile.lock index 4a489728f683..8223c8bef141 100644 --- a/apps/native/app/ios/Podfile.lock +++ b/apps/native/app/ios/Podfile.lock @@ -1531,7 +1531,73 @@ PODS: - React-Core - RNQuickAction (0.3.13): - React - - RNReanimated (3.12.1): + - RNReanimated (3.16.5): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated (= 3.16.5) + - RNReanimated/worklets (= 3.16.5) + - Yoga + - RNReanimated/reanimated (3.16.5): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - RNReanimated/reanimated/apple (= 3.16.5) + - Yoga + - RNReanimated/reanimated/apple (3.16.5): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga + - RNReanimated/worklets (3.16.5): - DoubleConversion - glog - hermes-engine @@ -2030,7 +2096,7 @@ SPEC CHECKSUMS: RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364 RNKeychain: ff836453cba46938e0e9e4c22e43d43fa2c90333 RNQuickAction: 6d404a869dc872cde841ad3147416a670d13fa93 - RNReanimated: d093daf3973a7ee9f77c10a9337e10390b2969e2 + RNReanimated: 73acffa7201bc9caee34b6f26878342cc9d8ab47 RNShare: 0fad69ae2d71de9d1f7b9a43acf876886a6cb99c RNSVG: 43b64ed39c14ce830d840903774154ca0c1f27ec SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d diff --git a/apps/native/app/src/screens/passkey/passkey.tsx b/apps/native/app/src/screens/passkey/passkey.tsx index a6ba79951324..ead1271ebc47 100644 --- a/apps/native/app/src/screens/passkey/passkey.tsx +++ b/apps/native/app/src/screens/passkey/passkey.tsx @@ -150,7 +150,10 @@ export const PasskeyScreen: NavigationFunctionComponent<{ - openBrowser('https://island.is/adgangslyklar', componentId) + openBrowser( + 'https://island.is/innskraning-umbod-og-adgangsstyring-a-island-is#innskraning-med-adgangslykli-i-island-is-appinu', + componentId, + ) } > From 2523e39cb434d95322738b4fe2078b2552cbee98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Fri, 13 Dec 2024 00:29:39 +0000 Subject: [PATCH 13/32] =?UTF-8?q?feat(web):=20Service=20web=20contact=20fo?= =?UTF-8?q?rm=20-=20Add=20custom=20fields=20for=20'Vinnueftirliti=C3=B0'?= =?UTF-8?q?=20(#17202)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../Forms/StandardForm/StandardForm.tsx | 172 +++++++++++++++++- .../ServiceWeb/Forms/StandardForm/types.ts | 2 + apps/web/screens/ServiceWeb/Forms/utils.ts | 15 ++ 3 files changed, 187 insertions(+), 2 deletions(-) diff --git a/apps/web/components/ServiceWeb/Forms/StandardForm/StandardForm.tsx b/apps/web/components/ServiceWeb/Forms/StandardForm/StandardForm.tsx index 3f469edd3828..3054bbc88e70 100644 --- a/apps/web/components/ServiceWeb/Forms/StandardForm/StandardForm.tsx +++ b/apps/web/components/ServiceWeb/Forms/StandardForm/StandardForm.tsx @@ -26,7 +26,10 @@ import { Stack, Text, } from '@island.is/island-ui/core' -import { InputController } from '@island.is/shared/form-fields' +import { + CheckboxController, + InputController, +} from '@island.is/shared/form-fields' import { sortAlpha } from '@island.is/shared/utils' import { ContentLanguage, @@ -42,6 +45,7 @@ import { GET_SUPPORT_SEARCH_RESULTS_QUERY } from '@island.is/web/screens/queries import { FiskistofaCategories, SjukratryggingarCategories, + VinnueftirlitidCategories, } from '@island.is/web/screens/ServiceWeb/Forms/utils' import { getServiceWebSearchTagQuery } from '@island.is/web/screens/ServiceWeb/utils' @@ -93,6 +97,14 @@ const labels: Record = { malsnumer_ef_til_stadar: 'Málsnúmer (ef til staðar)', faedingardagur_eda_kennitala_malsadila: 'Fæðingardagur/Kennitala málsaðila', skipaskrarnumer: 'Skipaskrárnúmer', + vinnuvelanumer_kaupanda: 'Vinnuvélanúmer kaupanda', + vinnuvelanumer_seljanda: 'Vinnuvélanúmer seljanda', + vinnuvelanumer_vegna_skodunar: 'Vinnuvélanúmer vegna skoðunar', + stadsetning_taekis: 'Staðsetning tækis', + stadsetning_verkstadar: 'Staðsetning verkstaðar', + nafn_fyrirtaekis: 'Nafn fyrirtækis', + starfsstod: 'Starfsstöð', + oska_eftir_vernd_uppljostrara: 'Óska eftir vernd uppljóstrara', } // these should be skipped in the message itself @@ -154,6 +166,35 @@ const BasicInput = ({ ) } +interface BasicCheckboxProps { + name: keyof typeof labels + label: string +} + +const BasicCheckbox = ({ name, label }: BasicCheckboxProps) => { + const { + formState: { errors }, + register, + } = useFormContext() + + return ( + + ) +} + const MIN_SEARCH_QUERY_LENGTH = 1 export const StandardForm = ({ @@ -482,6 +523,129 @@ export const StandardForm = ({ ) break + case VinnueftirlitidCategories.NAMSKEID: + case VinnueftirlitidCategories.VINNUSLYS: + case VinnueftirlitidCategories.VINNUVELARETTINDI: + case VinnueftirlitidCategories.VINNUVERND: + case VinnueftirlitidCategories.MARKADSEFTIRLIT: + case VinnueftirlitidCategories.EKKO_OG_SAMSKIPTI: + case VinnueftirlitidCategories.LOG_OG_REGLUGERDIR: + case VinnueftirlitidCategories.LEYFI_OG_UMSAGNIR: + case VinnueftirlitidCategories.ONNUR_THJONUSTA: + fields = ( + + + + ) + break + case VinnueftirlitidCategories.SKRANING_OG_SKODUN_VINNUVELA: + fields = ( + <> + + + + + + + + + + + + + + + + + ) + break + case VinnueftirlitidCategories.MANNVIRKJAGERD: + fields = ( + <> + + + + + + + + ) + break + case VinnueftirlitidCategories.VINNUADSTADA: + fields = ( + <> + + + + + + + + ) + break default: break } @@ -571,7 +735,11 @@ export const StandardForm = ({ const label = labels[k] const value = values[k] - if (label && value) { + if ( + label && + ((Array.isArray(value) && value.length > 0) || + (!Array.isArray(value) && Boolean(value))) + ) { message += `${label}:\n${value}\n\n` } diff --git a/apps/web/components/ServiceWeb/Forms/StandardForm/types.ts b/apps/web/components/ServiceWeb/Forms/StandardForm/types.ts index 26ca5c2e89a1..0934e1dc2baf 100644 --- a/apps/web/components/ServiceWeb/Forms/StandardForm/types.ts +++ b/apps/web/components/ServiceWeb/Forms/StandardForm/types.ts @@ -1,12 +1,14 @@ import type { FiskistofaCategories, SjukratryggingarCategories, + VinnueftirlitidCategories, } from '@island.is/web/screens/ServiceWeb/Forms/utils' export type CategoryId = | SyslumennCategories | SjukratryggingarCategories | FiskistofaCategories + | VinnueftirlitidCategories export enum SyslumennCategories { FJOLSKYLDUMAL = '4vQ4htPOAZvzcXBcjx06SH', diff --git a/apps/web/screens/ServiceWeb/Forms/utils.ts b/apps/web/screens/ServiceWeb/Forms/utils.ts index e84d8a93ed75..4a0b84c7c836 100644 --- a/apps/web/screens/ServiceWeb/Forms/utils.ts +++ b/apps/web/screens/ServiceWeb/Forms/utils.ts @@ -97,6 +97,21 @@ export enum FiskistofaCategories { VEIDIHEIMILDIR = '1agbWJCHTDVfVR4yQZPaEK', } +export enum VinnueftirlitidCategories { + NAMSKEID = '41SeTRazu0qKIixRhWpDLA', + SKRANING_OG_SKODUN_VINNUVELA = '1ulMblBQwDkfSNgh2NyKpw', + VINNUSLYS = '3VY4skpcXo7XyniStyxrVc', + VINNUVELARETTINDI = '1AkjZQc1CO6hMPXYaLSqTw', + VINNUVERND = '4Wmxb25h9R7L0kuYsz19jG', + MARKADSEFTIRLIT = '61OI7gY23wC80mRRA4yrbA', + MANNVIRKJAGERD = '7fLoJqpyojUHgdDofIpqlU', + EKKO_OG_SAMSKIPTI = '3SAlg8Xt7AKBQFrGUCTkG1', + VINNUADSTADA = '7FPsjPxRHA2aIOUXY3Xr3V', + LOG_OG_REGLUGERDIR = '7vb5yId3HMigcXEDMYN9uN', + LEYFI_OG_UMSAGNIR = '7nLIjBeO5EovoPYwINWoyv', + ONNUR_THJONUSTA = 'fdkCIdREoNlYmgkr37DTl', +} + export const filterSupportCategories = ( supportCategories: SupportCategory[] | undefined, slug: string, From c4977d1f3acb9289177800da42c99b9bac3a5d78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gunnlaugur=20Gu=C3=B0mundsson?= <34029342+GunnlaugurG@users.noreply.github.com> Date: Fri, 13 Dec 2024 08:59:52 +0000 Subject: [PATCH 14/32] feat(user-notification): Change action button text (#17194) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/assets/images/en-button-open.png | Bin 3396 -> 4123 bytes .../src/assets/images/is-button-open.png | Bin 3690 -> 4493 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/services/user-notification/src/assets/images/en-button-open.png b/apps/services/user-notification/src/assets/images/en-button-open.png index ab0144dc9ec9bdbc9db4597ffb0d2ba0e99efaee..b5ce25afbdbcbac88cf42c25b859aef33f2de2ca 100644 GIT binary patch literal 4123 zcmd6qXIqoa)`o9H1(ariNR#r=q$;A38jz0kE>%T}f(bn|13ZFC6A?ub2uU_j90 zNapkOnf1;YVfw=2qyNw!0Jz2eI~WWsM7QW7gTIB|eW1Lbf0dq`_0Tld1c0ifizkoI z0RTs(fwrbqFvCWs+WV_rTwP%m858W`*7%%nmeC6L3M{xdCC|IrbUgkZ6m?l?iP`vx zq|&Ew?Vxxs4PHg#hs@EZy3oy%mCU6cR-{E@i_MZ9a1RE3?Yvp}NTeQqjm?zRrjz}FMu zysgcXZ>i22D-6KcXY+fWasd46#TN5}X}=oo(+%A%7~TE^zwW&AVZh$wQ#X!>fAh8^ zYc~1ms_Hx5c50jl71q}n2n)Y7$OKFT+cP?Ug?_;tR_!qWhOYRXh#Mz6t4VFB$Q4H5 zOu~<8 zEC67p+*N&4Ycg~b05tv@S&)B>`rn|3vW`>A26gn#-1+5+lR3?#A46CEGcU0y4rr)( z|JQoqg=j$_TY(b+MD}PLG5}JH^GrY?>;H|&T3hkD@*oJ1Of|2&b)5~DjZt(f_Z_sGx35#nqvrUP!yzT?)01_OSIshvn-8)+dmdQ6FAH+GecTfiqP`x zr#x*<%}kLC^jEc&qUEJ&?ak*RMKli?c%e-y)I&p5OW4UAU?vJ-0dD%P>aSFQZD_9w z4kwepy62SRe_9&oyFbH(OpWphJ$n z5^CImwFhBjBM6+h8yek{>QpLn!dr0MEz-1hkWRig}@$!t`H=UbT7y6QXXx?WohxUHoWnkrNu9Nn~Fj}x>qLx+5 z(H^H3Eb`qCNjO3)MUtAx>1{_+Nr$FOQ9@rcuPs11Mad#-arj z>m_k@LJNu__~s>Wg#b{vKW9)brrSHdt6Q^*vVJ_`_wb$=bFdVtcfD})xLCc8B( z)2x?Zq+CW$=yFES;X~7+Z4rE9skXln9tOACA`Uxiw&FuJk?K(7p*qRX!n-m*S?P&t zRZw(jPOh>`%tlD&1A$+7aPQI2K<$@$ycg96>_@AHCkLr`Wo1XdzWZIVzQdS|L8lMW z9@?Z^cZ;QvmZf1~QK{+fv%W6pwojJM|3vRnBLWUS>6kltWO4hVUuZ zg0Nxh__U04527vVl@WJ1J6lf}8QvA!i_RA81Wjvlj$auX@Zwy~uQ*a~(8!#wx!gRB zgYzg>a^239CW_MfR5s4px&6$fJq>bSvwdakcDjCW>apO<6%=M;^X;rF?fEICCewP~ z8cbac&Z72%PWIG_LDZkeCb8etQm57j^$=2Pv6?%Y%&-g+_hv}f1Z0vmgaEyk;pnon zGK{E_bMyRIbE&k@Q4JF%QJ(Scn)4mc9!}`>*!fl_YP-Scwm0(HW7&?2X_8{{QU*(# zLT)52P?}q*IosFrcn8B8p(elO;Ki9z!mE9*cv43U_yAtY66186B;?f4N zQ(`dwsN9fIY-H?;RJFipKR;5&+`ZvcXehJ)(nD)MHthiQBk!ymxPBMtg|O|Rn7~1F zM$Wbz29p^x6I`#M{~i`zZ7+3(Wjjo;mQob@v7|F!_?Ij8UyB@MopjLgF~RzLdYTor ze}CMOw&VVF7OM;Y_0aCu=Yav|jFEA6{-h{(u{D@8&)u|zAq9sLr_>masEJl-ucus% z4d8D16|A}F?AXz8$dt}a>77{_F?8gx=E{pFyC+%k7xFbi30N}m3M=ww#33a_eVpXVG(gx5T-37W&&MO69{utvdY0oTl0QyZf}C;5$DC)=6wqYIiHxu!p6tft`h6)HRSm z6!Sg`d-~^7>vH9e+)by&=b8JR0oY8#nP$t3Ej_qt9NKJSF_z|QJwIS)oig!=*tN?Q zsy=g7dTG^Ffc$55uLTVia@cg6QFT^oI6=m}+4N7)x#tBbktnzS^_g_PT%hknE(^j3 z#!HpjSInN9@S>sc4R5=@=k3R9GN(@<;?0&4?Vd*E+xn1*&5D)jdcm29}i@P3lnw3g4+ zT3{h4%e}^TlGHZ}FsTkfKlUA%;u)`Cig|8ZE65bh{Lx{|pdc52)?0LBuI)}4Nlo@JK`sdi5%W2|gUKRhdd(Z1xdQDsxkINoBnta#~W<2zM&>iI$?gzR{{gM4P zeO0b;8CGhUzJhg=tH1CHoht~}n#O^}v5qiylNq09$K8ZAoeJZ9r3?-onSJinwM%#9 z;jI6tve9rWS16UNK~>6l(*o}1K=L;b>Tvc!8c$oUjFi2zz{f8qh8q=Wd2(m!|MV*C z4e>fUK1uBGH^txV4&2EJd%3tE&5m|Tt)VXAhkyRO2zGi(+*7tJ-3sI3Cy+5V6K2rs z(^YX{R``uJO5|Z;_`emLhMdLif@5ge$C6j*m z4#(;xLB#y$Th)fRufpc(-&RH4og+#Tm)?4=3F@dA|H`i)Jsugi&=OgGYPen99Qr~+ zb7a?Vl2B?w@j}1MP%~DDLdsZ$MzJZ#1t1EPrsMuXy|Ihe-pc7y*yI!8@4jeBisk3p zEx(q=P)9fvZ-;zYN*>ys^=|w)`FyZVQ1-ne6JPzMJB4C#nD&m5MyCX2XG@-S0lbLP zrGv|3IyS!ziv0{*h8MdU#hrLS)?kvN&yluYaPW)Kg2X0K7wDPRr}OIKb|_!sGxwny zSVw?RQ4Z&@Yp+_s6h&SbxB0f-7E*85UvfM7K@`qAxO5zGi|Pj|9=C9Wbk>JP6A`gX zG6d`G9nwIa>6yZe79#gEe|V9-xbdqueqUssG?ALVFRAcUCoZ1P2?^NXs|1fKJ(vra z<5x{duMfW-nmkQySUDJv4g87_0t$|J|e! zC1O0xl&??93XI(`T3dqB;!{40nhcaFgqf>7OW1z~LHEt_ihbn!_kVx%dw0aES}XdX z$PZkWJ@=EhdWt6XyANa&JB$j82m)~3EM30o`u^WaP=QKfyekzZB&oGY_FNu-Qeu%ct^; z05H-jsXF%@p~g|&-4t*8vky&)K;%2XHYt_%C3DI$EGNCO>v6+p?|0aw90D6|+ z_~=F0&qJ;W+-W8=0f1zRZ{BvW1HujE_a_2j+DPCnN`zvQgFF~oOUTX)mp0I$*~o%EF!bOr#tMFxi;)$)f1Q}(?P z;L1N2fyxk1VO!qKx43J4Y8qZtGMMJX0RWZdHDT3Pky)2ceuU2_(Fr+yZv3mMBlOgn xxs1oy3 z&J#sQa@gj)GIQF6ltT!&`{(=T@AsGYP?=4M8A0KjE_ zlw){L9^C}7T=%1%-`q&wKAdZ1S~vLof_TsR!fSP;m$#Jcyo)|hQN2%0tk}>8;bTx$ zJywR9_mq?zJRqrWNvTO7n`>YUq#|yg$I^UZ{H>8iro!@l*P0Fwg0@2v8yDK~7yr7s zf?Gx6_jRjUHVi}%U75i$6&IK|{;uGXUoCEE(g`4(x+3fr_l4g&i5k|GTP@yziVVmf zL)6;-@pAvl<)91i8ZYn~1KNx6q$^5V&#N#0%8ejkS-7JYH}KI`#Xq4cl9C%eWkl+6 z4HqRSYXEcpHtHu;oJf6F=jRb!YA0l3WbHKgGBN+GV`V^QKtH0wSX(SjEbiZU`M+XL zRJWeb@L~PC?Hl$WUHyn<)1!0ai}$e)X#-Ig0pP8#WmG}nc9aDfn+H^HplHKA1X<@~ zNFaX%?i>6JD^8nqX z%cp=ClV>u(O#SSStnDka0!p>K99CNA{^z$1MMIBjqixcvVJ{8k2nH&fz+x2>h~ zc5Xg<7j4jZ=*9a0{4$8L1?OF`dU*%AiP+PiHfipzO^a+HX1{|R%<{Eeg+qjQeb=bc zxA((%Q(RAUY)mH;rvC2xymQ~dsl?kP#cd~KqoyR)WzYZj4TB&185pxlv}or*lJr!w z6NXu&v@vKn_N#qY;%`qqx`I%-Q5%s_*iO!r*jw;p! zSDhSLLV00I#VC+LBescGVx3HuDONgSVL1GIxed{{ddIyr1_4pUygUX`OBHDs&>MeJ zwAq+P=I?#tKeVWL?cY(c>N4*)`oH8kg(T}_>wK{GG|=W+8eO-$w=~Fuh*(r3p>5je zUupgiDBc#kzMBUd6Ke(WqoK@EW?=)~1TCojk<)tZry@A%`#4i;JbrE`ot09)Id(qv zRjg0pB4m0Wy|GRMPe_-qqH)dh%h+-~0yiP1-j%wddL{_s%8l7upUVyhMcf6aKu7%k zAmx*wgG--Q=x2EF-x!hYA;^sz4tBejcX5RG%lO_2ElWJLKg!LqOQN8yvQ{j60)wtduWq#5iW@~IOij3n3N(xZ?l47B|i zBzAdxeAaml!Vtrj_Ypmx~4Z|&ax+D~2&NbKFEh$_Po>cuNL^v}k(q&4K0+pLP* zAs%&q%19h|Z`2Uo;=d0i(l}Z}?RLEPE@eDm^cWV0ktVe0Pjdc@!fK`m&MaJTIL$Yv zd0ua~)sm|^s+@1Kd8U4SCFc(1gCcnQfOZ=zQQpZ|=1)0hv9=?{Hf6KsKOm_OdX~KH z;B^WMNmp9N1BfRBBgsAHxMuR?$dd%L9hV45t(kKo!%7wBAHdh>BwxMo{sve|wjsgC z93-Y9WsENt*t$SGJKKO&=2CcEKISnJ`8s4O2(|&v?K7C#A6W6uIJ2@@My#N`;1&E=(v_G(J?uDdW(WMvk=^_4- z&y-x@Z!1ML*<{-o6Duh*_jh$zufwd!%Yoa6Lh}WdX3KMRRwlZEg5jlJj=SPZ6|LQ& z6{qCe9yND3$5RIOMiJ1sLr!<&=s$%XkLu10^ATMfzN68Tf`!D=i_Z1c%Q*=Ko;H4x zB#gHs8tyHZo^X6#0V~OQj7a+v1f~;SmUxMGRavonCbA$D9px;GtO0mSs83$F?PFry z#fW(&qRqE)b3ew$2}(C(RYxrw5`aUhfm#GX#ZOM94qxR;eu^zl^(3AqI4^YRMY94fgf9`99eVVAO~Kr4?cdSE3JK%`g{3sYI%!c z9ZVEH7dN^~PPlNoR#u&)EKi#W@_;*M_L|8?`u$!w?uFhz1grJ2mRMU2kbX6i9*G{U zOcqO@+SB;-q1CU4{HCo8ga6WKDf7QrVlB=;*#nbCk4~5hCYBw4nFvH>H zC*jlBi0A!L6R2+Xqg8{DmHrU6zH(H~(~HTD-<>8ZE1c}dVc0VFa*9+)um(hHiEL!s z2+caz5V5Mh46-NI`wj4R`Ako}hvvxAY0gOmPHHO63$^lM2fC**d}lO`;LL*jjrL~KE&MQ4RxE$SXUc0C-1MCBKYoSeJTlKSHKCk5CU(!1Yv z*SmE_7WuF>3%|d#w-D27mvSa{i;=d?^MlQSE{q7R_{a!qKZh1cSsf!+44~n=Orq%YNRZ{L&_m6Wa^)G+= zb&)R-{Y%)Uc+*TON&)H=n2FncdLN?I(k`Kz@3YxglJ_1SA^Df_D{nJG46TZ3Y3ZlG zxC4{7w7=e$E0dRV`{J7m1c$#jUh{cC`+I`7TR(rln+Pw9y}M2AGs(glAaYM~0L+ka$og?E2uLG8s&yzY%Bk#bO1GuxaQe>*n-PZ2yQcG1MO8v= zwH9&6-V`Wb)**fBn1jdNwP#+oU*S4yx;-~O@kh%_aXeKDmYUh3CO1UYxgJL+9M)vT zKJ@ZwRxOHgbgu6+MKc2`Qy>vvIN@v3Se!eeC}o|;-?Zg<(HeD zjx!-Ouh?Arl+>9iZr=ZOzE^Bvt+iPCYnnJ+SDx#Wh(!$0p&xeXf5HDFd-OD0J#tw; zm4rE|BY}+*O&dH0xZA7T*8Q=SYsv*&U$z|kZ(QkUlmUtwh^bS{3Q}u4fL^gkLq_tR zMNEQ+8UQE;btW84oarUay!rLh6^QZHQX*IPy?=OP=XwPX_BfYQVB9Q1_rObCMnh9u zK;)SIDR*tbK7opP_+3_(Ea4w*fvn?4U6cLzc0;cCrkIx7rL83V9i?^-5AgAUzy9fA zNp_24Vbpd&*#DCP(vQc91sf zypTk-P9$7wKMQ=_FR{722=#~gIiaaAeBS!+GdbK}PTJ2*{dXM!=Ehb=l?Lvy{{e}A Bkg@;( diff --git a/apps/services/user-notification/src/assets/images/is-button-open.png b/apps/services/user-notification/src/assets/images/is-button-open.png index 5d2a07e9db641a2781aabfb954ba30de9f9a1917..0d800da8faf6555a5c8ffe0e96699c112ff92ae9 100644 GIT binary patch literal 4493 zcmd6r_cz>Kw1>ZWB_Sd@L5S!zddm=#L=PbZgQyV_LDWH%8Idu1i-=CtsDp@J=2b@> zy+n;VdS{HmT=)Ga?)~BHv-jt$ebzo@t+SpJ_EJ~l4ka5U004KiG*t}%;2P}852Uzx zWvOKU;kxQ>xoVnv001-J|F&yd2E2P$;x!Kgjb{J~%f5aUTz~iU#Zv&Nh`D`ka{~bA zxV2QD8v0z@PJbNB-ob?ND@(H`Zx-I_3*wQ)>T>@!hZ;NxQI1Pq(~V6Tj{Ezvn3i7K z&fqU&H!FSNKe@uaTtQT6uE;?zH)h?I zTY@4v0LaC}x4NR)DlcpDU?G5BG$-&qqy{n&O}3I_{t)o=Nj+?&RUnad{8I~D-*cd^9-qi)S%hDw-v3F_h|I`T03eh% ztpLCS5n31!*!Sf08X!fsKn`?KAvl2t(*HN&-XtN}gY%-LPDETWa4u+%%!l3FYv)V^ z8*qSGJeK1Cj^a5V0fKQ=a38`JNd#R41H&e+9Z`zH0wsT)@LhIxqthDpKa;I-P=Etd zt4}&!<3;w#*X~h(pR|--XgQKjRB-o|JbMf_=RPeO%||MAXI?q;41-*756eIkvx?(vQUzkIPj$CG%Y z!q<s*82pE=qORcr7tWKh2s(D zM-3kq^xxmwoUvj@%g>a-dVQw)y0FY?wqa4;-XRgA7?Odi@Bb)e>S?7QL(l2Q<>*ZEa&hV z+V3Ivq}*67Bh-bRza@xnj|vK@zKJBhlMbx|dhxWEw|sF+5H9dN<2MuS+3_7*kY|Dt zsp0&5WzF%-7zoMSGZZi1_JZDwNTX~w%(VKGMy#cJJz-CqSB6m2)t(6oA526SZZ*g5 z9LW`aQKaB@o;!;mE8z3ADw^xcyB&YjGZr6yA{gLrWeC@%Rmnu#?79?9YfR)v>rL2n zP3Z=gGsRr{1LqlvyVBSQRy0BxcU&0JH5_ntmBrCUqr0fVO@&J% z(cLl?CJUwk0lu>-FB9n@vwBpg7zJS|mC9lTE2Q{UJ6=pQ0D{Y!c(HqaR09f2vKx7u zJ%iO3hd$^PqZ}dhg?A3ie)yeD{CTqpb@R{i<(m1i0c$mv*A&F5RNco?n1+>MW9!wi zI$nWM@!`p<*|^&>$ZAM?T6X6Kzs}}HHCAusXB8jGq-7>-cGuJd1F3PIK5o!H;x7{5 z2k5^Z(vwW=CU{4NF6^iC1v4p*?Z+OxhS~p5;drZLz0*oR>SC;bdqS6igydSW?1_1`J8siVZT-+eVqZ+lCxVLg$V2Qb(Pg zEAiSja*Qn#xnCrZ#NGs}iM6N>E0pCOZj(_>#+))WGqdvFMT26de{Ad$^Ei4}U_OuL zBxG{^r7~hBBWkHfLpjkLHP}>7-ukfgd(9@D>((yNlRtZL^ zNRzbsI}=n!&!B*_YIPU=$n}aCVXY6p6qLZza%nNKKL}BpQ40L-MY)ng_+Srw>mOPL zcGhjR63;rgr&7A3u+;Nu1am>1TuNUlLNiU~sCsuZ1A!~LxjFDE7YiRlD8KFHVB~iD zEoDCbFi)0>{!M~b5q5G>4gKY1@-$*a^eCWCx)qckH`)L1)K~ybFsY|^gyT)oCE}Q< z6cz?6@pm#58ecayztMECuN^rmcrn<)@`1{?@Zh2JpSLutCt60?2eom?EL#j>7}Ze& zdZSD*(fFxV?+Qh+!9`y@W$mXmZTQjY@+j&}dQLS&tiffYeQS~n6yw@1 zRa^pj+IJAmb$duX$vG5x>%fgWGit?(Qq62-I#)+VDmp6TXs%^t{rCY_)(^^ly^f6- z7xOfE8$yD|O&A@iqz+E@<%Jt&<{ca*v0cBWw<8K)nyfB{tOA@t1N0 zc-^V!-XF^tlgx^5RA=CXBCZwk=EH)^b7s0z&<1vhLg4zu!V=AZ-b%_rQ?b$%W7I;V zxtb(o^~3{3SJ*wCB+g{g;u=puqe^PtQ^U zqBu0TsQ>wc>U(sP_1k)vk1jG?92~CG$^9E5E5dXP6Xn6x^J~f{nBaI41J&V0DjSiw zWW(9(DYfCP`cEJ?q(`qO%tLl{zt1Pg*3u5d&mlchRz&&?jLT3xtf}Sn(1j>vxkpUI zX0)qt?w!wf1a_a!UBE!`~&v};+Ht@g3yiWo1j zClFu#Q-C+hGWg^=_5RzXiefc<(HOb&#oQXl$Gf^ai-@h0vYENC&x*k{VXxWqJRW2V z;Xj@RkwH&VW9N&6{wVuaq>WzqoLzhpxUHhC+gjCQ)6A_n#ou`ImX5ITwEwtomBUaW zLv&a(!35&gXBSI5xx|+Gphej!i3C=k1%-&sWukJzy!*-L{HC@tI4pRg(emxtlCUXP zZXJ`(E{S#tCPin-*52}PjNbyb9)Goudtrq%!ruaef zdFO-L_|{(y!uVIBWF=U?p|uJdUMdA+em08|ktUzo==@C{1`)7Zhe!IhWoV++AHvD< z`uipZ7(+1s_ar{{Lx=iE^EPG2cALYHD6kpDV2*rWVN|*54GGJk7=`dgiWW#*iiQ+bN@^T&+* zO5lg(x6qu?PH&C!&AI4{BtB$ycM0+t`*|#bl0!glGn-G6(r?`C;x5rnsU}8rlcpnY z>3#2J+tn-C&fV~ij~yYbo- zrQvjS-{E}+g&Iz=k6InZ^3UIn?VsLxhS|$`s-x=E|G8QGX_SSYlav`x%w8?q{#xx6 zZrwYLW8ZY6+ zSrwHz-ik2%m{qRh$w9uP0YSOv{@8q_Tp(ffeJ62+NqDzEm~e2^Zs7S^^SF`2;q)6w z8+P|0`iJeXTtKqYZt&i8_#eZQRujr8+FNr{-OUDdL9OH&?FN!tGF{UkYd;uc#8T@ly&xmHe_N$9NKRHOa}UWRA`7rnHntn=pnG_ygV+c9ftQE80z! zBidPr@grRF^bEz#EZ?UCUdqnd>A#B?mWO-hV+q(Cf`R+*s1?TNE4VQI#2%Fi>EbUk zPoowR!-56Nq+J?OKfCvhkb0LpY;h^xuX7nHe`)XfI{Eth*^(ikE zx0M~``BN5D{`N)&@Aji~ykIZXxnC^xROvxup*9ZmZ|n?p(q9w&7ri_61le2~oDg9> zrMeQM`ewKiq8mQ$^>q1kJK8_rtsgoq_!8fs+o%(|u@Tf$jA~BWe`EJcH_L#K8|{)l zImC{9E-ExDwc-NON48BKMZW=~4L7d{b7v*Nhj+dkuA!K*Z();o;GjMr5KKi-`J z51<@Wr;jYJAkX@%(<`|v9;9rg0b*Gxz`zsx2j>8g{CSTIczg5zpNK?|Mz6?MEbaNJ z-hcEOh9G%dvGpej*Gy+7@O?!9==!od8(+GJAq&a8Lf5M&!vr@?P%* z*d4;LNCONC=stHYTlLW9eabp=7T$!LoJ0Qtz>i`>$6t&YnY8}4)qD3s za<&(7$BXwM;qwhBcQWUz6`7FJpE0b=>9ZjhcgZiWf8-#Md!99?visI`Uj3c`T57tg JsAtwe{{vPZ!jb?0 literal 3690 zcmchaYdq79|Hi+_;Z~&5NlFJ2G2Pvm!;qYEnnTWV=vNMNxQR_{=FssjIaK7fZnS1w zHcSqa*(j3A?Xvg@Z*Y)6f^m)BM_q?GlYN}eQ005}D zUU2jU06EVspQEC*rG<;uS^%K_yQ`zUU%H%d%qCfT`f$(UEChDpO5Zse@cejrZE^0w zvQAhO&D-^4;#u>21LKmxNUvDA*5ilGjc+e{TsX)Jdr|Yoxa^eEqyC=Fw3XQk)Ix{J z0L+WVlVwHsTUA0)vNc{zbtJEb2n>!@}0Z=i?Wn(hMt zL8RuwtpOLE;a{`@w^H1XGk&F$Ks~hJe&<)~@ap9oG6`cbN`B94EwXC<$IiD2u8()0 z1pY4DJqwQ|si$flQI_8WJh+kC8^R%)42*nth?GB4uC8p%i6LP@HN8WqkQs!1Vnh=N$R%@37VtudT zOH9EEz_UKW?UN_=%bjb>-!2CX9>o3z98~cH-k*z=Kc{ql4{%lk0~F;BZp+zm>m+dX zsHxmhh5udU-kVp9i#FyFza_^qATotUp2x_7Pq)T$GpG?^#WAK3d$^)AX?TLsf01QR3LHZy__gz7K;GU*6_z=B*# zBhvB zV$m+ImzZgcrKfyOT{iVI-lI?SXG$6U{h(j7lZRktrnD~`_wA}k$mbm4Tfi&=;F;(Z z{f_%nyzJeW)AonLV|t$k61&cJ>y6F1DcF~m|Fcb>=}S;m6=iB8i38Q!|2=jP?oiZ^ zER;HYnt-W$4BcVNj*OE)?)6$*y*e$4&aFSL2MzBpu&abfu6HtjKn?Rw9f%FBaX9fg z(jBAfp%@t&L}(h)$qM@Co}Hok>sdK>P+jUp4Y~|=u8RJ)z^&|VcIaolln|%mIBD19 zj)p2&>2KkYbIhqtJ5sp|!e}kqEt@!5CHS~>@j}SP^m8|FvWHB1sO97cRA=36vREmY zDPEg{%?{a5mq#H^ZcZ`yMI*~zo98}6?R^2l)cvud`2ICQJ^v4jujOL=nz98aCxfvU5K64M!p*pfqza|y>G`O;8z8-enfP1NweW6}1AbcCRLuAOnyCVXFLg;-sS5dhYSGWdNh zj8h=l8mUu1e%LUBx-u(<*7KX1+E)gtww_(yW47^_tQL~eh(=Ypt_=Wp79!1?3l?53 zF$q_;)6c&YGQgBI{1+=#I(6YRriW)HGC=Lh{DeMeYHaK>F;?dn^O;>Ao%;!1-=Y}p zfgLnuG@!Wg*gc^pmON0YTVmodTvQxJS*Uz{T+q&F4%^r2;b8jW5#jo?+3>9I0Tl5$ zrW`APQoZIy-pE+=YS9PaZoejL<3Rhr!NjjUVzgp`&Iw)XTC z3`rkH@t|v*lKe=~3QsO1H&S2E_%1u2ol4VQ>v+iwQ|VoyHenIgG+SPqczmMFSZ^ZvJZrn@byqVkEQDBDOe8+FcZ8(mYz0B}> zq?)un8S%qQFg5XNuhL!Y7v%G!OAFJ@H-B&DT}!W{g~~IOa%sH*eWl}+)gPS^%YU<5 zxw+g@8qG~H&&`q_L&R^u(IW_4wP3O${02eqInm5UyJ^8pl!&NB4`vc8vA-q|ZY6<_ zXei2`FX!{-=dBHmiL$~?bE$I?!tBMMpWf1vtMR9csD4rV+U&Z_3!rNJ}WzMAHk zo7v)JxHJ9H;G3$REB2x9;V6qp`c1m~0Z!PFo%pN^bOnprQjcauS6UVmR>kWIks@Fe zLxr%;I_80G<5qE2N9YsRlrMoF5V`g`a?|5=+$*ki`T5sk^+;kMnCjk`H$>yd+jOtw zkYtQ&2npzn+2`*3>z3%t11$Uz`HI2$Xm70LK)H2wUcVe|4o{HTHMw{8Wh}(ZECu*07D=W#AU7nMMOu4LCHnij&gG?Q zz3bf$Ur9AXkNBhX{o`+Qx|}5(Bw28xI$%9Y8x0AMSVn&I{;PaPUGI>>tfZq3uOO@}##ll>>-Zh>JlNs%1l@`tF2&3;hqXJKwILagsa~<( zK*Myw^v8s?V->*~9wc8st(4C(n& zrw}jgnR$4F*5LC14*tl}Aq@=CNQXv^qrz@|MZj>IpVk6Cj6RJhnV+-=a)9awpkWTeHGX&blixZrlNPm`|0^WrdiqJD93D02`#rvR!$wW9Pgq5MI3o;(7dCG|my5&Mqp6DP zu$}3Lo2({B=Sl_8fV7>P-){0bwbtGXV&BDN7~xVgw$lU9H6c*8ZzoRi3*81aE8o`P>Xj?t^d?K>Do!+(`D9_A_SJDAcjoS}w% ztuCC5lk?yIl*+ys*7+Un8Id>SobN5si!j)JCP}y4DGsAQloDG1o!QD~5HH*N2bRV! z4^hia3rC$jb7KTFSZGKfj*50*`5Ihe#l>k3ixb-W+xjoQ;ZiS6uWi29xq32M<~UZW zQHS$c6|F2<)a0g!{|O|TaC@I{Ma$R!x^@;xRj)~R6#le+HoNhl9Y5h-n-TI>Zb5C= zzU&e*)jsnBSdxiwnaJ>y451N{(I=87+v68Zf4J9)#Cg zkOw}zG+M4YI)^Ka%ZNz#+K3&9)5SHK4^LZpJs|!!M!sB2(_S&yfbK)2VoMr)3$_(M zxb!ws)?C#K^bcg!8~`v3mBKCC zs`G-gEyr9+9)xHcoDnGkIZ2x8B_)qRF5i;%0U*<)GdIiQ{BknfZyf~&078CVLe1H; z{Li-PvfKq1K*QSbh)hz+AM_iWv7ql!fdWOivwO&CmCX6XV#6B+U2VCO+v>+jMvzt` zFmAL(ln>6Eur;bkR04ub0y-gX** Date: Fri, 13 Dec 2024 09:23:18 +0000 Subject: [PATCH 15/32] feat(ids-api): Enable getting fake users in v3 client. Configure for ids-api envs. (#17201) * Enable getting fake users in v3 client. Configure for ids-api envs. * Remove configmodule import. * Declare property in constructor, use optional chaining. * Fix optional decorator. * Move declaration. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/services/auth/ids-api/infra/ids-api.ts | 5 +++ .../auth/ids-api/src/app/app.module.ts | 2 +- .../app/user-profile/user-profile.service.ts | 12 +++++-- charts/identity-server/values.dev.yaml | 1 + charts/identity-server/values.prod.yaml | 1 + charts/identity-server/values.staging.yaml | 1 + .../services-auth-ids-api/values.dev.yaml | 1 + .../services-auth-ids-api/values.prod.yaml | 1 + .../services-auth-ids-api/values.staging.yaml | 1 + .../lib/delegations/alive-status.service.ts | 18 ++++++++-- .../v3/src/lib/nationalRegistryV3.service.ts | 35 +++++++++++++------ 11 files changed, 62 insertions(+), 16 deletions(-) diff --git a/apps/services/auth/ids-api/infra/ids-api.ts b/apps/services/auth/ids-api/infra/ids-api.ts index 1afda547b717..b4f06d72ee64 100644 --- a/apps/services/auth/ids-api/infra/ids-api.ts +++ b/apps/services/auth/ids-api/infra/ids-api.ts @@ -100,6 +100,11 @@ export const serviceSetup = (): ServiceBuilder<'services-auth-ids-api'> => { staging: 'digitaliceland', dev: 'digitaliceland', }, + ALSO_USE_FAKE_USER_API: { + dev: 'true', + staging: 'false', + prod: 'false', + }, }) .secrets({ ZENDESK_CONTACT_FORM_EMAIL: '/k8s/api/ZENDESK_CONTACT_FORM_EMAIL', diff --git a/apps/services/auth/ids-api/src/app/app.module.ts b/apps/services/auth/ids-api/src/app/app.module.ts index b1cfb1b1506c..16198e21f08d 100644 --- a/apps/services/auth/ids-api/src/app/app.module.ts +++ b/apps/services/auth/ids-api/src/app/app.module.ts @@ -13,6 +13,7 @@ import { NationalRegistryV3ClientConfig } from '@island.is/clients/national-regi import { CompanyRegistryConfig } from '@island.is/clients/rsk/company-registry' import { SyslumennClientConfig } from '@island.is/clients/syslumenn' import { UserProfileClientConfig } from '@island.is/clients/user-profile' +import { ZendeskServiceConfig } from '@island.is/clients/zendesk' import { AuditModule } from '@island.is/nest/audit' import { ConfigModule, @@ -35,7 +36,6 @@ import { ResourcesModule } from './resources/resources.module' import { TranslationModule } from './translation/translation.module' import { UserProfileModule } from './user-profile/user-profile.module' import { UsersModule } from './users/users.module' -import { ZendeskServiceConfig } from '@island.is/clients/zendesk' @Module({ imports: [ diff --git a/apps/services/auth/ids-api/src/app/user-profile/user-profile.service.ts b/apps/services/auth/ids-api/src/app/user-profile/user-profile.service.ts index 626b782bb437..9479bd021332 100644 --- a/apps/services/auth/ids-api/src/app/user-profile/user-profile.service.ts +++ b/apps/services/auth/ids-api/src/app/user-profile/user-profile.service.ts @@ -1,4 +1,5 @@ -import { Inject, Injectable } from '@nestjs/common' +import { Inject, Injectable, Optional } from '@nestjs/common' +import { ConfigService } from '@nestjs/config' import { AuthMiddleware } from '@island.is/auth-nest-tools' import { FetchError } from '@island.is/clients/middlewares' @@ -30,6 +31,7 @@ type CountryFormatter = { of: (countryCode: string) => string } @Injectable() export class UserProfileService { + alsoUseFakeApi: boolean // REMOVE these ignores after upgrading to TypeScript 4.5 // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore @@ -45,7 +47,12 @@ export class UserProfileService { private companyRegistryApi: CompanyRegistryClientService, @Inject(LOGGER_PROVIDER) private logger: Logger, - ) {} + @Optional() + readonly configService?: ConfigService, + ) { + this.alsoUseFakeApi = + configService?.get('ALSO_USE_FAKE_USER_API') ?? false + } userProfileApiWithAuth(auth: Auth) { return this.userProfileApi.withMiddleware(new AuthMiddleware(auth)) @@ -123,6 +130,7 @@ export class UserProfileService { const individual = await this.nationalRegistryV3.getAllDataIndividual( auth.nationalId, false, + this.alsoUseFakeApi, ) if (!individual) { diff --git a/charts/identity-server/values.dev.yaml b/charts/identity-server/values.dev.yaml index a5d5ce51e239..47834b587715 100644 --- a/charts/identity-server/values.dev.yaml +++ b/charts/identity-server/values.dev.yaml @@ -414,6 +414,7 @@ services-auth-delegation-api: services-auth-ids-api: enabled: true env: + ALSO_USE_FAKE_USER_API: 'true' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS-DEV/GOV/10006/Skatturinn/ft-v1' diff --git a/charts/identity-server/values.prod.yaml b/charts/identity-server/values.prod.yaml index 2f51a29e6326..a350ead4e04b 100644 --- a/charts/identity-server/values.prod.yaml +++ b/charts/identity-server/values.prod.yaml @@ -411,6 +411,7 @@ services-auth-delegation-api: services-auth-ids-api: enabled: true env: + ALSO_USE_FAKE_USER_API: 'false' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.dnugi2.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS/GOV/5402696029/Skatturinn/ft-v1' diff --git a/charts/identity-server/values.staging.yaml b/charts/identity-server/values.staging.yaml index 00cbc00e4a90..b02c94cd26d5 100644 --- a/charts/identity-server/values.staging.yaml +++ b/charts/identity-server/values.staging.yaml @@ -414,6 +414,7 @@ services-auth-delegation-api: services-auth-ids-api: enabled: true env: + ALSO_USE_FAKE_USER_API: 'false' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.ab9ckb.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS-TEST/GOV/5402696029/Skatturinn/ft-v1' diff --git a/charts/services/services-auth-ids-api/values.dev.yaml b/charts/services/services-auth-ids-api/values.dev.yaml index e1461ecdd4a9..12367bce8312 100644 --- a/charts/services/services-auth-ids-api/values.dev.yaml +++ b/charts/services/services-auth-ids-api/values.dev.yaml @@ -19,6 +19,7 @@ global: name: 'services-auth-ids-api' enabled: true env: + ALSO_USE_FAKE_USER_API: 'true' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS-DEV/GOV/10006/Skatturinn/ft-v1' diff --git a/charts/services/services-auth-ids-api/values.prod.yaml b/charts/services/services-auth-ids-api/values.prod.yaml index 48b414b22bb9..8f72bda2431f 100644 --- a/charts/services/services-auth-ids-api/values.prod.yaml +++ b/charts/services/services-auth-ids-api/values.prod.yaml @@ -19,6 +19,7 @@ global: name: 'services-auth-ids-api' enabled: true env: + ALSO_USE_FAKE_USER_API: 'false' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.dnugi2.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS/GOV/5402696029/Skatturinn/ft-v1' diff --git a/charts/services/services-auth-ids-api/values.staging.yaml b/charts/services/services-auth-ids-api/values.staging.yaml index 5b620fa22960..1e1e45950161 100644 --- a/charts/services/services-auth-ids-api/values.staging.yaml +++ b/charts/services/services-auth-ids-api/values.staging.yaml @@ -19,6 +19,7 @@ global: name: 'services-auth-ids-api' enabled: true env: + ALSO_USE_FAKE_USER_API: 'false' CODE_OWNER: 'aranja' COMPANY_REGISTRY_REDIS_NODES: '["clustercfg.general-redis-cluster-group.ab9ckb.euw1.cache.amazonaws.com:6379"]' COMPANY_REGISTRY_XROAD_PROVIDER_ID: 'IS-TEST/GOV/5402696029/Skatturinn/ft-v1' diff --git a/libs/auth-api-lib/src/lib/delegations/alive-status.service.ts b/libs/auth-api-lib/src/lib/delegations/alive-status.service.ts index e1e4aeceb170..c960148f83a9 100644 --- a/libs/auth-api-lib/src/lib/delegations/alive-status.service.ts +++ b/libs/auth-api-lib/src/lib/delegations/alive-status.service.ts @@ -1,4 +1,5 @@ -import { Inject, Injectable, Logger } from '@nestjs/common' +import { Inject, Injectable, Logger, Optional } from '@nestjs/common' +import { ConfigService } from '@nestjs/config' import * as kennitala from 'kennitala' import { NationalRegistryClientService } from '@island.is/clients/national-registry-v2' @@ -20,13 +21,20 @@ const decesead = 'LÉST' @Injectable() export class AliveStatusService { + alsoUseFakeApi: boolean + constructor( private readonly nationalRegistryClient: NationalRegistryClientService, private readonly nationalRegistryV3Client: NationalRegistryV3ClientService, private readonly companyRegistryClient: CompanyRegistryClientService, @Inject(LOGGER_PROVIDER) private logger: Logger, - ) {} + @Optional() + readonly configService?: ConfigService, + ) { + this.alsoUseFakeApi = + configService?.get('ALSO_USE_FAKE_USER_API') ?? false + } /** * Divides nationalIds into alive and deceased @@ -134,7 +142,11 @@ export class AliveStatusService { ): Promise { if (useNationalRegistryV3) { return await this.nationalRegistryV3Client - .getAllDataIndividual(individualInfo.nationalId) + .getAllDataIndividual( + individualInfo.nationalId, + false, + this.alsoUseFakeApi, + ) .then((individual) => { if ( individual && diff --git a/libs/clients/national-registry/v3/src/lib/nationalRegistryV3.service.ts b/libs/clients/national-registry/v3/src/lib/nationalRegistryV3.service.ts index 1f8e09ec369e..fec86cce0731 100644 --- a/libs/clients/national-registry/v3/src/lib/nationalRegistryV3.service.ts +++ b/libs/clients/national-registry/v3/src/lib/nationalRegistryV3.service.ts @@ -34,19 +34,34 @@ export class NationalRegistryV3ClientService { ) } - getAllDataIndividual( + async getAllDataIndividual( nationalId: string, - useFakeApi?: boolean, + useFakeApiOnly?: boolean, + alsoTryFakeApiWhenNotFound?: boolean, ): Promise { - return useFakeApi - ? this.fakeApi.midlunV1GerviEinstaklingarNationalIdGet({ + if (useFakeApiOnly) { + return handle204( + this.fakeApi.midlunV1GerviEinstaklingarNationalIdGetRaw({ nationalId, - }) - : handle204( - this.individualApi.midlunV1EinstaklingarNationalIdGetRaw({ - nationalId, - }), - ) + }), + ) + } + + const result = await handle204( + this.individualApi.midlunV1EinstaklingarNationalIdGetRaw({ + nationalId, + }), + ) + + if (!result && alsoTryFakeApiWhenNotFound) { + return handle204( + this.fakeApi.midlunV1GerviEinstaklingarNationalIdGetRaw({ + nationalId, + }), + ) + } + + return result } getBiologicalFamily( From 5a13f96b72351a9a62df896561eaff3052d7cb38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:57:40 +0000 Subject: [PATCH 16/32] fix(web): Sort by title for generic list and team list (#17226) * Add title.sort again * No need to have _score type --- libs/cms/src/lib/cms.elasticsearch.service.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/cms/src/lib/cms.elasticsearch.service.ts b/libs/cms/src/lib/cms.elasticsearch.service.ts index 0a20025d9ed0..2d1945a91db4 100644 --- a/libs/cms/src/lib/cms.elasticsearch.service.ts +++ b/libs/cms/src/lib/cms.elasticsearch.service.ts @@ -525,12 +525,14 @@ export class CmsElasticsearchService { const size = input.size ?? 10 - const sort: ('_score' | sortRule)[] = [ + const sort: sortRule[] = [ { [SortField.RELEASE_DATE]: { order: SortDirection.DESC, }, }, + // Sort items with equal values by ascending title order + { 'title.sort': { order: SortDirection.ASC } }, ] if (input.tags && input.tags.length > 0 && input.tagGroups) { From 444cedff2e7483d30e053c2558b7bb4b22e858eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B3nas=20G=2E=20Sigur=C3=B0sson?= Date: Fri, 13 Dec 2024 12:46:16 +0000 Subject: [PATCH 17/32] feat(app-sys): changes to app sys that were bundled with financial aid update (#17210) * feat: changes to app sys that were bundled with financial aid update * chore: add in line break * chore: add in line break * chore: undo changes to reference-template * chore: remove unused import --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../application/core/src/lib/fieldBuilders.ts | 43 ++++++++++ libs/application/core/src/lib/messages.ts | 15 ++++ libs/application/types/src/lib/Fields.ts | 28 +++++++ libs/application/types/src/lib/Form.ts | 2 +- .../AccordionFormField/AccordionFormField.tsx | 55 +++++++++++++ .../BankAccountFormField.tsx | 82 +++++++++++++++++++ libs/application/ui-fields/src/lib/index.ts | 2 + .../ui-shell/src/lib/FormShell.tsx | 3 +- libs/application/ui-shell/src/utils.ts | 33 ++++++++ 9 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 libs/application/ui-fields/src/lib/AccordionFormField/AccordionFormField.tsx create mode 100644 libs/application/ui-fields/src/lib/BankAccountFormField/BankAccountFormField.tsx diff --git a/libs/application/core/src/lib/fieldBuilders.ts b/libs/application/core/src/lib/fieldBuilders.ts index a1035cbc3b55..935a3062aab7 100644 --- a/libs/application/core/src/lib/fieldBuilders.ts +++ b/libs/application/core/src/lib/fieldBuilders.ts @@ -46,6 +46,8 @@ import { MaybeWithApplicationAndFieldAndLocale, DisplayField, FieldsRepeaterField, + AccordionField, + BankAccountField, } from '@island.is/application/types' import { Locale } from '@island.is/shared/types' import { Colors } from '@island.is/island-ui/theme' @@ -1010,3 +1012,44 @@ export const buildDisplayField = ( halfWidthOwnline, } } + +export const buildAccordionField = ( + data: Omit, +): AccordionField => { + const { + accordionItems, + title, + titleVariant, + id, + marginTop, + marginBottom, + condition, + } = data + return { + children: undefined, + id, + title, + titleVariant, + marginTop, + marginBottom, + accordionItems, + condition, + type: FieldTypes.ACCORDION, + component: FieldComponents.ACCORDION, + } +} +export const buildBankAccountField = ( + data: Omit, +): BankAccountField => { + const { title, id, marginBottom, marginTop, titleVariant } = data + return { + children: undefined, + id, + title, + marginBottom, + marginTop, + titleVariant, + type: FieldTypes.BANK_ACCOUNT, + component: FieldComponents.BANK_ACCOUNT, + } +} diff --git a/libs/application/core/src/lib/messages.ts b/libs/application/core/src/lib/messages.ts index aaaafd03dee2..65cb2f5cdd67 100644 --- a/libs/application/core/src/lib/messages.ts +++ b/libs/application/core/src/lib/messages.ts @@ -318,6 +318,21 @@ export const coreDefaultFieldMessages = defineMessages({ defaultMessage: 'Veljið skjöl til að hlaða upp', description: 'Default file upload button label', }, + defaultBankAccountBankNumber: { + id: 'application.system:core.default.bankAccount.bankNumber', + defaultMessage: 'Bankanúmer', + description: 'Bank account bank number', + }, + defaultBankAccountLedger: { + id: 'application.system:core.default.bankAccount.ledger', + defaultMessage: 'Höfuðbók', + description: 'Bank account ledger', + }, + defaultBankAccountAccountNumber: { + id: 'application.system:core.default.bankAccount.accountNumber', + defaultMessage: 'Reikningsnúmer', + description: 'Bank account account number', + }, defaultDownloadButtonTitle: { id: 'application.system:core.default.pdfLinkButtonField.downloadButtonTitle', defaultMessage: 'Hlaða niður skjali', diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts index f89d41400fcf..fafd82964b7c 100644 --- a/libs/application/types/src/lib/Fields.ts +++ b/libs/application/types/src/lib/Fields.ts @@ -261,6 +261,8 @@ export enum FieldTypes { STATIC_TABLE = 'STATIC_TABLE', SLIDER = 'SLIDER', DISPLAY = 'DISPLAY', + ACCORDION = 'ACCORDION', + BANK_ACCOUNT = 'BANK_ACCOUNT', } export enum FieldComponents { @@ -296,6 +298,8 @@ export enum FieldComponents { STATIC_TABLE = 'StaticTableFormField', SLIDER = 'SliderFormField', DISPLAY = 'DisplayFormField', + ACCORDION = 'AccordionFormField', + BANK_ACCOUNT = 'BankAccountFormField', } export interface CheckboxField extends InputField { @@ -675,6 +679,28 @@ export type FieldsRepeaterField = BaseField & { } } +export type AccordionItem = { + itemTitle: FormText + itemContent: FormText +} +export interface AccordionField extends BaseField { + readonly type: FieldTypes.ACCORDION + component: FieldComponents.ACCORDION + accordionItems: + | Array + | ((application: Application) => Array) + marginTop?: ResponsiveProp + marginBottom?: ResponsiveProp + titleVariant?: TitleVariants +} +export interface BankAccountField extends BaseField { + readonly type: FieldTypes.BANK_ACCOUNT + component: FieldComponents.BANK_ACCOUNT + marginTop?: ResponsiveProp + marginBottom?: ResponsiveProp + titleVariant?: TitleVariants +} + export interface FindVehicleField extends InputField { readonly type: FieldTypes.FIND_VEHICLE component: FieldComponents.FIND_VEHICLE @@ -824,3 +850,5 @@ export type Field = | StaticTableField | SliderField | DisplayField + | AccordionField + | BankAccountField diff --git a/libs/application/types/src/lib/Form.ts b/libs/application/types/src/lib/Form.ts index 379ccfa0cce4..e3656d70d405 100644 --- a/libs/application/types/src/lib/Form.ts +++ b/libs/application/types/src/lib/Form.ts @@ -79,7 +79,7 @@ export interface Form { children: FormChildren[] icon?: string id: string - logo?: React.FC> + logo?: FormComponent mode?: FormModes renderLastScreenBackButton?: boolean renderLastScreenButton?: boolean diff --git a/libs/application/ui-fields/src/lib/AccordionFormField/AccordionFormField.tsx b/libs/application/ui-fields/src/lib/AccordionFormField/AccordionFormField.tsx new file mode 100644 index 000000000000..fe29ba01be9d --- /dev/null +++ b/libs/application/ui-fields/src/lib/AccordionFormField/AccordionFormField.tsx @@ -0,0 +1,55 @@ +import { + AccordionField, + AccordionItem as AccordionItemType, + FieldBaseProps, +} from '@island.is/application/types' +import { Accordion, AccordionItem, Box, Text } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { formatText, formatTextWithLocale } from '@island.is/application/core' +import { Markdown } from '@island.is/shared/components' +import { useEffect, useState } from 'react' + +interface Props extends FieldBaseProps { + field: AccordionField +} +export const AccordionFormField = ({ field, application }: Props) => { + const [items, setItems] = useState>() + const { formatMessage, lang: locale } = useLocale() + const { accordionItems, marginBottom, marginTop, title, titleVariant } = field + useEffect(() => { + if (typeof accordionItems === 'function') { + setItems(accordionItems(application)) + } else { + setItems(accordionItems) + } + }, [accordionItems]) + if (!items || items.length === 0) { + return null + } + return ( + + {title && ( + + + {formatTextWithLocale(title, application, locale, formatMessage)} + + + )} + + {items.map((item, index) => { + return ( + + + {formatText(item.itemContent, application, formatMessage)} + + + ) + })} + + + ) +} diff --git a/libs/application/ui-fields/src/lib/BankAccountFormField/BankAccountFormField.tsx b/libs/application/ui-fields/src/lib/BankAccountFormField/BankAccountFormField.tsx new file mode 100644 index 000000000000..22d9b062d4f7 --- /dev/null +++ b/libs/application/ui-fields/src/lib/BankAccountFormField/BankAccountFormField.tsx @@ -0,0 +1,82 @@ +import { + coreDefaultFieldMessages, + formatText, + formatTextWithLocale, +} from '@island.is/application/core' +import { BankAccountField, FieldBaseProps } from '@island.is/application/types' +import { Box, GridColumn, GridRow, Text } from '@island.is/island-ui/core' +import { useLocale } from '@island.is/localization' +import { InputController } from '@island.is/shared/form-fields' + +interface Props extends FieldBaseProps { + field: BankAccountField +} +export const BankAccountFormField = ({ field, application }: Props) => { + const { formatMessage, lang: locale } = useLocale() + const { marginBottom, marginTop, title, titleVariant, id } = field + const bankNumber = formatText( + coreDefaultFieldMessages.defaultBankAccountBankNumber, + application, + formatMessage, + ) + const ledger = formatText( + coreDefaultFieldMessages.defaultBankAccountLedger, + application, + formatMessage, + ) + const accountNumber = formatText( + coreDefaultFieldMessages.defaultBankAccountAccountNumber, + application, + formatMessage, + ) + return ( + + {title && ( + + + {formatTextWithLocale(title, application, locale, formatMessage)} + + + )} + + + + + + + + + + + + + + + + + + + ) +} diff --git a/libs/application/ui-fields/src/lib/index.ts b/libs/application/ui-fields/src/lib/index.ts index d805491651c5..a6379668ef5a 100644 --- a/libs/application/ui-fields/src/lib/index.ts +++ b/libs/application/ui-fields/src/lib/index.ts @@ -30,3 +30,5 @@ export { VehicleRadioFormField } from './VehicleRadioFormField/VehicleRadioFormF export { StaticTableFormField } from './StaticTableFormField/StaticTableFormField' export { SliderFormField } from './SliderFormField/SliderFormField' export { DisplayFormField } from './DisplayFormField/DisplayFormField' +export { AccordionFormField } from './AccordionFormField/AccordionFormField' +export { BankAccountFormField } from './BankAccountFormField/BankAccountFormField' diff --git a/libs/application/ui-shell/src/lib/FormShell.tsx b/libs/application/ui-shell/src/lib/FormShell.tsx index 8e1beef1c9ee..31a047f6112c 100644 --- a/libs/application/ui-shell/src/lib/FormShell.tsx +++ b/libs/application/ui-shell/src/lib/FormShell.tsx @@ -25,6 +25,7 @@ import { } from '../reducer/ApplicationFormReducer' import { ActionTypes } from '../reducer/ReducerTypes' import * as styles from './FormShell.css' +import { getFormComponent } from '../utils' import { canGoBack } from '../reducer/reducerUtils' export const FormShell: FC< @@ -67,7 +68,7 @@ export const FormShell: FC< } = state.form const showProgressTag = mode !== FormModes.DRAFT const currentScreen = screens[activeScreen] - const FormLogo = form.logo + const FormLogo = getFormComponent(form.logo, storedApplication) const getDraftSectionCurrentScreen = (): number | undefined => { const currentDraftScreenSection = sections.find( diff --git a/libs/application/ui-shell/src/utils.ts b/libs/application/ui-shell/src/utils.ts index e027cfd073d5..4f63543491f5 100644 --- a/libs/application/ui-shell/src/utils.ts +++ b/libs/application/ui-shell/src/utils.ts @@ -1,8 +1,10 @@ import { getValueViaPath } from '@island.is/application/core' import { + Application, DataProviderItem, ExternalData, FieldTypes, + FormComponent, FormItemTypes, FormValue, RecordObject, @@ -154,3 +156,34 @@ export const parseMessage = (message?: string) => { return message } + +function isFunctionalComponent( + component: FormComponent | undefined, +): component is React.FC> { + if (!component) return false + return ( + typeof component === 'function' && + !(component.prototype && component.prototype.isReactComponent) && + component.length === 0 + ) +} +function isFunctionReturningComponent( + component: FormComponent | undefined, +): component is ( + application: Application, +) => React.FC> | null | undefined { + if (!component) return false + return typeof component === 'function' && component.length === 1 +} +export function getFormComponent( + component: FormComponent | undefined, + application: Application, +) { + if (isFunctionalComponent(component)) { + return component + } + if (isFunctionReturningComponent(component)) { + return component(application) + } + return null +} From c13fd916c3ba51b3ca9ce1aa15a6dc2d79fd7beb Mon Sep 17 00:00:00 2001 From: brynjarorng Date: Fri, 13 Dec 2024 13:22:08 +0000 Subject: [PATCH 18/32] chore: allow staging to scale down more (#17227) * chore: allow staging to scale down more * chore: nx format:write update dirty files * set overrides to 3 * fixed tests --------- Co-authored-by: andes-it Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- charts/identity-server/values.staging.yaml | 70 ++++---- charts/islandis/values.staging.yaml | 162 +++++++++--------- charts/judicial-system/values.staging.yaml | 24 +-- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- charts/services/api/values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../auth-admin-web/values.staging.yaml | 10 +- .../consultation-portal/values.staging.yaml | 10 +- .../judicial-system-api/values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 4 +- .../services/license-api/values.staging.yaml | 10 +- .../portals-admin/values.staging.yaml | 10 +- .../values.staging.yaml | 4 +- .../service-portal-api/values.staging.yaml | 10 +- .../service-portal/values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../services-auth-ids-api/values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../values.staging.yaml | 10 +- .../services-sessions/values.staging.yaml | 4 +- .../values.staging.yaml | 10 +- .../skilavottord-web/values.staging.yaml | 10 +- .../values.staging.yaml | 4 +- charts/services/web/values.staging.yaml | 10 +- infra/src/dsl/basic.spec.ts | 2 +- infra/src/dsl/hpa.spec.ts | 2 +- .../output-generators/map-to-helm-values.ts | 24 ++- 34 files changed, 274 insertions(+), 266 deletions(-) diff --git a/charts/identity-server/values.staging.yaml b/charts/identity-server/values.staging.yaml index b02c94cd26d5..7f6ac4dcf3fb 100644 --- a/charts/identity-server/values.staging.yaml +++ b/charts/identity-server/values.staging.yaml @@ -36,8 +36,8 @@ auth-admin-web: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/auth-admin-web' ingress: @@ -59,9 +59,9 @@ auth-admin-web: progressDeadlineSeconds: 1200 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -270,8 +270,8 @@ services-auth-admin-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-admin-api' ingress: @@ -289,9 +289,9 @@ services-auth-admin-api: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -369,8 +369,8 @@ services-auth-delegation-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-delegation-api' ingress: @@ -387,9 +387,9 @@ services-auth-delegation-api: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -476,8 +476,8 @@ services-auth-ids-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 15 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-ids-api' initContainer: @@ -522,9 +522,9 @@ services-auth-ids-api: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 15 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '800m' @@ -660,8 +660,8 @@ services-auth-personal-representative: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-personal-representative' ingress: @@ -678,9 +678,9 @@ services-auth-personal-representative: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -729,8 +729,8 @@ services-auth-personal-representative-public: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-personal-representative-public' ingress: @@ -747,9 +747,9 @@ services-auth-personal-representative-public: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -824,8 +824,8 @@ services-auth-public-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-public-api' ingress: @@ -846,9 +846,9 @@ services-auth-public-api: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index 2cd78ddb6714..541ee602df90 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -35,8 +35,8 @@ air-discount-scheme-api: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-api' ingress: @@ -58,9 +58,9 @@ air-discount-scheme-api: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -123,8 +123,8 @@ air-discount-scheme-backend: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-backend' ingress: @@ -170,9 +170,9 @@ air-discount-scheme-backend: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -223,8 +223,8 @@ air-discount-scheme-web: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-web' ingress: @@ -249,9 +249,9 @@ air-discount-scheme-web: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '200m' @@ -440,8 +440,8 @@ api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 50 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/api' ingress: @@ -460,9 +460,9 @@ api: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 50 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '1200m' @@ -713,8 +713,8 @@ application-system-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 60 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/application-system-api' ingress: @@ -763,9 +763,9 @@ application-system-api: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 60 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '600m' @@ -1023,8 +1023,8 @@ consultation-portal: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/consultation-portal' ingress: @@ -1043,9 +1043,9 @@ consultation-portal: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -1471,8 +1471,8 @@ license-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/license-api' ingress: @@ -1489,9 +1489,9 @@ license-api: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -1576,8 +1576,8 @@ portals-admin: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/portals-admin' ingress: @@ -1596,9 +1596,9 @@ portals-admin: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -1742,7 +1742,7 @@ search-indexer-service: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 1 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-search-indexer' @@ -1820,7 +1820,7 @@ search-indexer-service: pvcs: [] replicaCount: default: 1 - max: 1 + max: 3 min: 1 resources: limits: @@ -1873,8 +1873,8 @@ service-portal: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/service-portal' ingress: @@ -1893,9 +1893,9 @@ service-portal: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '300m' @@ -1962,8 +1962,8 @@ service-portal-api: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-user-profile' ingress: @@ -2005,9 +2005,9 @@ service-portal-api: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '800m' @@ -2080,8 +2080,8 @@ services-bff-portals-admin: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-bff' ingress: @@ -2103,9 +2103,9 @@ services-bff-portals-admin: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -2166,8 +2166,8 @@ services-bff-portals-my-pages: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-bff' ingress: @@ -2189,9 +2189,9 @@ services-bff-portals-my-pages: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -2323,7 +2323,7 @@ services-sessions: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-sessions' @@ -2342,7 +2342,7 @@ services-sessions: pvcs: [] replicaCount: default: 1 - max: 10 + max: 3 min: 1 resources: limits: @@ -2565,8 +2565,8 @@ services-university-gateway: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-university-gateway' ingress: @@ -2621,9 +2621,9 @@ services-university-gateway: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '200m' @@ -2755,8 +2755,8 @@ skilavottord-web: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/skilavottord-web' ingress: @@ -2775,9 +2775,9 @@ skilavottord-web: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -3155,7 +3155,7 @@ user-notification-worker: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 2 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-user-notification' @@ -3190,7 +3190,7 @@ user-notification-worker: pvcs: [] replicaCount: default: 1 - max: 2 + max: 3 min: 1 resources: limits: @@ -3251,8 +3251,8 @@ web: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 50 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/web' ingress: @@ -3271,9 +3271,9 @@ web: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 50 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '1000m' diff --git a/charts/judicial-system/values.staging.yaml b/charts/judicial-system/values.staging.yaml index e6b543a61ce6..6939b5a9fae4 100644 --- a/charts/judicial-system/values.staging.yaml +++ b/charts/judicial-system/values.staging.yaml @@ -53,8 +53,8 @@ judicial-system-api: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-api' ingress: @@ -78,9 +78,9 @@ judicial-system-api: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '350m' @@ -155,8 +155,8 @@ judicial-system-backend: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-backend' initContainer: @@ -189,9 +189,9 @@ judicial-system-backend: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' @@ -413,7 +413,7 @@ judicial-system-scheduler: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 1 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-scheduler' @@ -425,7 +425,7 @@ judicial-system-scheduler: pvcs: [] replicaCount: default: 1 - max: 1 + max: 3 min: 1 resources: limits: diff --git a/charts/services/air-discount-scheme-api/values.staging.yaml b/charts/services/air-discount-scheme-api/values.staging.yaml index 03dae66f38f1..b3ffdaf667ff 100644 --- a/charts/services/air-discount-scheme-api/values.staging.yaml +++ b/charts/services/air-discount-scheme-api/values.staging.yaml @@ -46,8 +46,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-api' ingress: @@ -69,9 +69,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/air-discount-scheme-backend/values.staging.yaml b/charts/services/air-discount-scheme-backend/values.staging.yaml index 2e45fbac3401..503a736d94f1 100644 --- a/charts/services/air-discount-scheme-backend/values.staging.yaml +++ b/charts/services/air-discount-scheme-backend/values.staging.yaml @@ -57,8 +57,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-backend' ingress: @@ -104,9 +104,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/air-discount-scheme-web/values.staging.yaml b/charts/services/air-discount-scheme-web/values.staging.yaml index d160667b9dd5..7185fc6bcd41 100644 --- a/charts/services/air-discount-scheme-web/values.staging.yaml +++ b/charts/services/air-discount-scheme-web/values.staging.yaml @@ -45,8 +45,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 20 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/air-discount-scheme-web' ingress: @@ -71,9 +71,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '200m' diff --git a/charts/services/api/values.staging.yaml b/charts/services/api/values.staging.yaml index d200690c8557..53c6e7b18726 100644 --- a/charts/services/api/values.staging.yaml +++ b/charts/services/api/values.staging.yaml @@ -189,8 +189,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 50 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/api' ingress: @@ -209,9 +209,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 50 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '1200m' diff --git a/charts/services/application-system-api/values.staging.yaml b/charts/services/application-system-api/values.staging.yaml index c47d9cd07c30..4b37d4cb9945 100644 --- a/charts/services/application-system-api/values.staging.yaml +++ b/charts/services/application-system-api/values.staging.yaml @@ -156,8 +156,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 60 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/application-system-api' ingress: @@ -206,9 +206,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 60 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '600m' diff --git a/charts/services/auth-admin-web/values.staging.yaml b/charts/services/auth-admin-web/values.staging.yaml index 846c0af6c998..44ac2b27f2d8 100644 --- a/charts/services/auth-admin-web/values.staging.yaml +++ b/charts/services/auth-admin-web/values.staging.yaml @@ -47,8 +47,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/auth-admin-web' ingress: @@ -70,9 +70,9 @@ podDisruptionBudget: progressDeadlineSeconds: 1200 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/consultation-portal/values.staging.yaml b/charts/services/consultation-portal/values.staging.yaml index e3547fb54d2e..198c3aefabfb 100644 --- a/charts/services/consultation-portal/values.staging.yaml +++ b/charts/services/consultation-portal/values.staging.yaml @@ -46,8 +46,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/consultation-portal' ingress: @@ -66,9 +66,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/judicial-system-api/values.staging.yaml b/charts/services/judicial-system-api/values.staging.yaml index 7533d12090a6..8ec818a14e50 100644 --- a/charts/services/judicial-system-api/values.staging.yaml +++ b/charts/services/judicial-system-api/values.staging.yaml @@ -53,8 +53,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-api' ingress: @@ -78,9 +78,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '350m' diff --git a/charts/services/judicial-system-backend/values.staging.yaml b/charts/services/judicial-system-backend/values.staging.yaml index 30787a83c52d..a4c0268de4d4 100644 --- a/charts/services/judicial-system-backend/values.staging.yaml +++ b/charts/services/judicial-system-backend/values.staging.yaml @@ -68,8 +68,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-backend' initContainer: @@ -102,9 +102,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/judicial-system-scheduler/values.staging.yaml b/charts/services/judicial-system-scheduler/values.staging.yaml index b62035e69488..c05114e58282 100644 --- a/charts/services/judicial-system-scheduler/values.staging.yaml +++ b/charts/services/judicial-system-scheduler/values.staging.yaml @@ -50,7 +50,7 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 1 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/judicial-system-scheduler' @@ -62,7 +62,7 @@ podSecurityContext: pvcs: [] replicaCount: default: 1 - max: 1 + max: 3 min: 1 resources: limits: diff --git a/charts/services/license-api/values.staging.yaml b/charts/services/license-api/values.staging.yaml index 6e7db7b9814d..81577da0aa8e 100644 --- a/charts/services/license-api/values.staging.yaml +++ b/charts/services/license-api/values.staging.yaml @@ -56,8 +56,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/license-api' ingress: @@ -74,9 +74,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/portals-admin/values.staging.yaml b/charts/services/portals-admin/values.staging.yaml index 7db3b0717c80..e993af124894 100644 --- a/charts/services/portals-admin/values.staging.yaml +++ b/charts/services/portals-admin/values.staging.yaml @@ -43,8 +43,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/portals-admin' ingress: @@ -63,9 +63,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/search-indexer-service/values.staging.yaml b/charts/services/search-indexer-service/values.staging.yaml index 39cebc125692..ba80482ce963 100644 --- a/charts/services/search-indexer-service/values.staging.yaml +++ b/charts/services/search-indexer-service/values.staging.yaml @@ -49,7 +49,7 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 1 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-search-indexer' @@ -127,7 +127,7 @@ progressDeadlineSeconds: 1500 pvcs: [] replicaCount: default: 1 - max: 1 + max: 3 min: 1 resources: limits: diff --git a/charts/services/service-portal-api/values.staging.yaml b/charts/services/service-portal-api/values.staging.yaml index f766121d5b5b..07671994d3f9 100644 --- a/charts/services/service-portal-api/values.staging.yaml +++ b/charts/services/service-portal-api/values.staging.yaml @@ -67,8 +67,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-user-profile' ingress: @@ -110,9 +110,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '800m' diff --git a/charts/services/service-portal/values.staging.yaml b/charts/services/service-portal/values.staging.yaml index 682ab594ddcd..65f13f82b35e 100644 --- a/charts/services/service-portal/values.staging.yaml +++ b/charts/services/service-portal/values.staging.yaml @@ -46,8 +46,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 30 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/service-portal' ingress: @@ -66,9 +66,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 30 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '300m' diff --git a/charts/services/services-auth-admin-api/values.staging.yaml b/charts/services/services-auth-admin-api/values.staging.yaml index b1c22013d7d8..1d972f8b160a 100644 --- a/charts/services/services-auth-admin-api/values.staging.yaml +++ b/charts/services/services-auth-admin-api/values.staging.yaml @@ -70,8 +70,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-admin-api' ingress: @@ -89,9 +89,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-auth-delegation-api/values.staging.yaml b/charts/services/services-auth-delegation-api/values.staging.yaml index 6547bd4e464b..03180c9e830d 100644 --- a/charts/services/services-auth-delegation-api/values.staging.yaml +++ b/charts/services/services-auth-delegation-api/values.staging.yaml @@ -71,8 +71,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-delegation-api' ingress: @@ -89,9 +89,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-auth-ids-api/values.staging.yaml b/charts/services/services-auth-ids-api/values.staging.yaml index 1e1e45950161..054896398d70 100644 --- a/charts/services/services-auth-ids-api/values.staging.yaml +++ b/charts/services/services-auth-ids-api/values.staging.yaml @@ -81,8 +81,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 15 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-ids-api' initContainer: @@ -127,9 +127,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 15 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '800m' diff --git a/charts/services/services-auth-personal-representative-public/values.staging.yaml b/charts/services/services-auth-personal-representative-public/values.staging.yaml index 5a132366628b..7f10d51b3fd0 100644 --- a/charts/services/services-auth-personal-representative-public/values.staging.yaml +++ b/charts/services/services-auth-personal-representative-public/values.staging.yaml @@ -44,8 +44,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-personal-representative-public' ingress: @@ -62,9 +62,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-auth-personal-representative/values.staging.yaml b/charts/services/services-auth-personal-representative/values.staging.yaml index 16fadeb06ab7..f6d9afc4f121 100644 --- a/charts/services/services-auth-personal-representative/values.staging.yaml +++ b/charts/services/services-auth-personal-representative/values.staging.yaml @@ -65,8 +65,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-personal-representative' ingress: @@ -83,9 +83,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-auth-public-api/values.staging.yaml b/charts/services/services-auth-public-api/values.staging.yaml index 31a9e6949e53..a2dbe2c7352a 100644 --- a/charts/services/services-auth-public-api/values.staging.yaml +++ b/charts/services/services-auth-public-api/values.staging.yaml @@ -77,8 +77,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-auth-public-api' ingress: @@ -99,9 +99,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-bff-portals-admin/values.staging.yaml b/charts/services/services-bff-portals-admin/values.staging.yaml index a8b5553f847b..b27a1436a50d 100644 --- a/charts/services/services-bff-portals-admin/values.staging.yaml +++ b/charts/services/services-bff-portals-admin/values.staging.yaml @@ -58,8 +58,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-bff' ingress: @@ -81,9 +81,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-bff-portals-my-pages/values.staging.yaml b/charts/services/services-bff-portals-my-pages/values.staging.yaml index e4ce58391d55..ad1f25068192 100644 --- a/charts/services/services-bff-portals-my-pages/values.staging.yaml +++ b/charts/services/services-bff-portals-my-pages/values.staging.yaml @@ -57,8 +57,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-bff' ingress: @@ -80,9 +80,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/services-sessions/values.staging.yaml b/charts/services/services-sessions/values.staging.yaml index adc3e526bdc1..fdf795c80439 100644 --- a/charts/services/services-sessions/values.staging.yaml +++ b/charts/services/services-sessions/values.staging.yaml @@ -50,7 +50,7 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-sessions' @@ -69,7 +69,7 @@ podDisruptionBudget: pvcs: [] replicaCount: default: 1 - max: 10 + max: 3 min: 1 resources: limits: diff --git a/charts/services/services-university-gateway/values.staging.yaml b/charts/services/services-university-gateway/values.staging.yaml index 975b21ae2937..313eda0fc537 100644 --- a/charts/services/services-university-gateway/values.staging.yaml +++ b/charts/services/services-university-gateway/values.staging.yaml @@ -66,8 +66,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-university-gateway' ingress: @@ -122,9 +122,9 @@ podSecurityContext: fsGroup: 65534 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '200m' diff --git a/charts/services/skilavottord-web/values.staging.yaml b/charts/services/skilavottord-web/values.staging.yaml index 592971c93b7c..59d876710b15 100644 --- a/charts/services/skilavottord-web/values.staging.yaml +++ b/charts/services/skilavottord-web/values.staging.yaml @@ -42,8 +42,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 8 replicas: - max: 10 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/skilavottord-web' ingress: @@ -62,9 +62,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 10 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '400m' diff --git a/charts/services/user-notification-worker/values.staging.yaml b/charts/services/user-notification-worker/values.staging.yaml index ce46946924d2..5f2f70af09e6 100644 --- a/charts/services/user-notification-worker/values.staging.yaml +++ b/charts/services/user-notification-worker/values.staging.yaml @@ -78,7 +78,7 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 2 + max: 3 min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/services-user-notification' @@ -113,7 +113,7 @@ podSecurityContext: pvcs: [] replicaCount: default: 1 - max: 2 + max: 3 min: 1 resources: limits: diff --git a/charts/services/web/values.staging.yaml b/charts/services/web/values.staging.yaml index 8e672b5827be..1c68d6367609 100644 --- a/charts/services/web/values.staging.yaml +++ b/charts/services/web/values.staging.yaml @@ -52,8 +52,8 @@ hpa: cpuAverageUtilization: 90 nginxRequestsIrate: 5 replicas: - max: 50 - min: 2 + max: 3 + min: 1 image: repository: '821090935708.dkr.ecr.eu-west-1.amazonaws.com/web' ingress: @@ -72,9 +72,9 @@ podDisruptionBudget: maxUnavailable: 1 pvcs: [] replicaCount: - default: 2 - max: 50 - min: 2 + default: 1 + max: 3 + min: 1 resources: limits: cpu: '1000m' diff --git a/infra/src/dsl/basic.spec.ts b/infra/src/dsl/basic.spec.ts index f3d24bb8d736..81a3e44397b7 100644 --- a/infra/src/dsl/basic.spec.ts +++ b/infra/src/dsl/basic.spec.ts @@ -9,7 +9,7 @@ const Staging: EnvironmentConfig = { auroraHost: 'a', redisHost: 'b', domain: 'staging01.devland.is', - type: 'staging', + type: 'prod', featuresOn: [], defaultMaxReplicas: 3, defaultMinReplicas: 2, diff --git a/infra/src/dsl/hpa.spec.ts b/infra/src/dsl/hpa.spec.ts index 6182c6fef66f..509c36fa5a57 100644 --- a/infra/src/dsl/hpa.spec.ts +++ b/infra/src/dsl/hpa.spec.ts @@ -9,7 +9,7 @@ const Staging: EnvironmentConfig = { auroraHost: 'a', redisHost: 'b', domain: 'staging01.devland.is', - type: 'staging', + type: 'prod', featuresOn: [], defaultMaxReplicas: 3, defaultMinReplicas: 2, diff --git a/infra/src/dsl/output-generators/map-to-helm-values.ts b/infra/src/dsl/output-generators/map-to-helm-values.ts index fdd6297613ba..e18e6ab23e21 100644 --- a/infra/src/dsl/output-generators/map-to-helm-values.ts +++ b/infra/src/dsl/output-generators/map-to-helm-values.ts @@ -109,17 +109,25 @@ const serializeService: SerializeMethod = async ( result.resources = serviceDef.resources // replicas - if (serviceDef.replicaCount) { + if (env1.type == 'staging') { result.replicaCount = { - min: serviceDef.replicaCount.min, - max: serviceDef.replicaCount.max, - default: serviceDef.replicaCount.default, + min: 1, + max: 3, + default: 1, } } else { - result.replicaCount = { - min: env1.defaultMinReplicas, - max: env1.defaultMaxReplicas, - default: env1.defaultMinReplicas, + if (serviceDef.replicaCount) { + result.replicaCount = { + min: serviceDef.replicaCount.min, + max: serviceDef.replicaCount.max, + default: serviceDef.replicaCount.default, + } + } else { + result.replicaCount = { + min: env1.defaultMinReplicas, + max: env1.defaultMaxReplicas, + default: env1.defaultMinReplicas, + } } } From 231b35f93d16bb544767ea5a7a80bff56bdc8489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:08:06 +0000 Subject: [PATCH 19/32] feat(web): Auto open livechat if query param present (#17223) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../LiveChatIncChatPanel/LiveChatIncChatPanel.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/web/components/ChatPanel/LiveChatIncChatPanel/LiveChatIncChatPanel.tsx b/apps/web/components/ChatPanel/LiveChatIncChatPanel/LiveChatIncChatPanel.tsx index 303b4036f181..116fec059775 100644 --- a/apps/web/components/ChatPanel/LiveChatIncChatPanel/LiveChatIncChatPanel.tsx +++ b/apps/web/components/ChatPanel/LiveChatIncChatPanel/LiveChatIncChatPanel.tsx @@ -38,7 +38,12 @@ export const LiveChatIncChatPanel = ({ const n = useNamespace(namespace) useEffect(() => { - if (!hasButtonBeenClicked && !showLauncher) { + const queryParam = new URLSearchParams(window.location.search).get('wa_lid') + if ( + !hasButtonBeenClicked && + !showLauncher && + !(queryParam && ['t10', 't11'].includes(queryParam)) + ) { return () => { // No need for cleanup if we don't initialize widget } From 55aae3d129b0ce17429d2bf35be1e45ab4c38433 Mon Sep 17 00:00:00 2001 From: helgifr Date: Fri, 13 Dec 2024 15:38:44 +0000 Subject: [PATCH 20/32] fix(parental-leave): pdf attachments not uploading (#17114) Co-authored-by: hfhelgason Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../parental-leave/parental-leave.service.ts | 72 ++++++++++--------- 1 file changed, 39 insertions(+), 33 deletions(-) diff --git a/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/parental-leave.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/parental-leave.service.ts index 8d064e4ce24f..2fdc49ef12d8 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/parental-leave.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/parental-leave/parental-leave.service.ts @@ -35,6 +35,7 @@ import { getAdditionalSingleParentRightsInMonths, clamp, getMultipleBirthsDaysInMonths, + Files, } from '@island.is/application/templates/parental-leave' import { Application, @@ -402,6 +403,23 @@ export class ParentalLeaveService extends BaseTemplateApiService { } } + async getPDFs( + application: Application, + documents: Files[], + attachmentType: string, + fileUpload: string, + ) { + const PDFs = [] + for (const index of documents.keys()) { + const pdf = await this.getPdf(application, index, fileUpload) + PDFs.push({ + attachmentType, + attachmentBytes: pdf, + }) + } + return PDFs + } + async getAttachments(application: Application): Promise { const attachments: Attachment[] = [] const { @@ -433,48 +451,36 @@ export class ParentalLeaveService extends BaseTemplateApiService { state === States.RESIDENCE_GRANT_APPLICATION ) { if (residenceGrantFiles) { - residenceGrantFiles.forEach(async (item, index) => { - const pdf = await this.getPdf( - application, - index, - 'fileUpload.residenceGrant', - ) - attachments.push({ - attachmentType: apiConstants.attachments.residenceGrant, - attachmentBytes: pdf, - }) - }) + const PDFs = await this.getPDFs( + application, + residenceGrantFiles, + apiConstants.attachments.residenceGrant, + 'fileUpload.residenceGrant', + ) + attachments.push(...PDFs) } } if (changeEmployerFile) { - changeEmployerFile.forEach(async (item, index) => { - const pdf = await this.getPdf( - application, - index, - 'fileUpload.changeEmployerFile', - ) - attachments.push({ - attachmentType: apiConstants.attachments.changeEmployer, - attachmentBytes: pdf, - }) - }) + const PDFs = await this.getPDFs( + application, + changeEmployerFile, + apiConstants.attachments.changeEmployer, + 'fileUpload.changeEmployerFile', + ) + attachments.push(...PDFs) } // We don't want to send old files to VMST again if (applicationFundId && applicationFundId !== '') { if (additionalDocuments) { - for (const index of additionalDocuments.keys()) { - const pdf = await this.getPdf( - application, - index, - 'fileUpload.additionalDocuments', - ) - attachments.push({ - attachmentType: apiConstants.attachments.other, - attachmentBytes: pdf, - }) - } + const PDFs = await this.getPDFs( + application, + additionalDocuments, + apiConstants.attachments.other, + 'fileUpload.additionalDocuments', + ) + attachments.push(...PDFs) } return attachments } From 28c639ff9e40999dd0e2d0f6fb5c2bbdfc1921dd Mon Sep 17 00:00:00 2001 From: birkirkristmunds <142495885+birkirkristmunds@users.noreply.github.com> Date: Fri, 13 Dec 2024 17:08:31 +0000 Subject: [PATCH 21/32] fix(skilavottord): Fix error message being shown if vehicle is not found for registration (#16852) * TS-933 Fix error msg being shown if vehicle is not found for registration * TS-933 Fixed typo --------- Co-authored-by: veronikasif <54938148+veronikasif@users.noreply.github.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/skilavottord/web/graphql/errorLink.ts | 7 +++++-- .../DeregisterVehicle/Confirm/Confirm.tsx | 3 +++ .../DeregisterVehicle/Overview/Overview.tsx | 20 +++++++++---------- apps/skilavottord/web/utils/roleUtils.ts | 4 +++- .../recyclingRequest.service.ts | 19 +++++++++++++++--- 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/apps/skilavottord/web/graphql/errorLink.ts b/apps/skilavottord/web/graphql/errorLink.ts index 59cdc715ed61..15c86f40a958 100644 --- a/apps/skilavottord/web/graphql/errorLink.ts +++ b/apps/skilavottord/web/graphql/errorLink.ts @@ -1,5 +1,5 @@ import { onError, ErrorResponse } from '@apollo/client/link/error' -import { signIn, signOut } from 'next-auth/client' +import { signIn } from 'next-auth/client' import { toast } from '@island.is/island-ui/core' @@ -22,7 +22,10 @@ export default onError(({ graphQLErrors, networkError }: ErrorResponse) => { }) } return - } else if (errorCodes.includes('FORBIDDEN')) { + } else if ( + errorCodes.includes('FORBIDDEN') || + (graphQLErrors[0]?.extensions as any)?.response?.error === 'NOT_FOUND' + ) { return } diff --git a/apps/skilavottord/web/screens/DeregisterVehicle/Confirm/Confirm.tsx b/apps/skilavottord/web/screens/DeregisterVehicle/Confirm/Confirm.tsx index a8b25824b009..c102ea78bf04 100644 --- a/apps/skilavottord/web/screens/DeregisterVehicle/Confirm/Confirm.tsx +++ b/apps/skilavottord/web/screens/DeregisterVehicle/Confirm/Confirm.tsx @@ -133,6 +133,9 @@ const Confirm: FC> = () => { SkilavottordVehicleReadyToDeregisteredQuery, { variables: { permno: id }, + onError: (_err) => { + // Do nothing error handled in ErrorLink + }, }, ) diff --git a/apps/skilavottord/web/screens/DeregisterVehicle/Overview/Overview.tsx b/apps/skilavottord/web/screens/DeregisterVehicle/Overview/Overview.tsx index 859ecd9b4dbf..ae383ea2a2f9 100644 --- a/apps/skilavottord/web/screens/DeregisterVehicle/Overview/Overview.tsx +++ b/apps/skilavottord/web/screens/DeregisterVehicle/Overview/Overview.tsx @@ -1,34 +1,32 @@ -import React, { FC, useContext, useEffect, useRef } from 'react' -import Link from 'next/link' -import { useRouter } from 'next/router' import { useQuery } from '@apollo/client' import gql from 'graphql-tag' +import Link from 'next/link' +import { useRouter } from 'next/router' +import React, { FC, useContext, useEffect, useRef } from 'react' import { Box, - Stack, - Text, BreadcrumbsDeprecated as Breadcrumbs, Button, GridColumn, LoadingDots, + Stack, + Text, } from '@island.is/island-ui/core' -import { useI18n } from '@island.is/skilavottord-web/i18n' -import { UserContext } from '@island.is/skilavottord-web/context' import { hasPermission } from '@island.is/skilavottord-web/auth/utils' import { - Sidenav, NotFound, PartnerPageLayout, + Sidenav, } from '@island.is/skilavottord-web/components' +import { UserContext } from '@island.is/skilavottord-web/context' import { - RecyclingPartner, - RecyclingRequest, - Vehicle, Query, Role, + Vehicle, } from '@island.is/skilavottord-web/graphql/schema' +import { useI18n } from '@island.is/skilavottord-web/i18n' import { BASE_PATH } from '@island.is/skilavottord/consts' import { CarsTable } from './components/CarsTable' diff --git a/apps/skilavottord/web/utils/roleUtils.ts b/apps/skilavottord/web/utils/roleUtils.ts index 2cf4bb6cfe9b..793c56126f3f 100644 --- a/apps/skilavottord/web/utils/roleUtils.ts +++ b/apps/skilavottord/web/utils/roleUtils.ts @@ -12,7 +12,9 @@ export const getRoleTranslation = (role: Role, locale: Locale): string => { case 'recyclingFund': return locale === 'is' ? 'Úrvinnslusjóður' : 'Recycling Fund' case 'recyclingCompanyAdmin': - return locale === 'is' ? 'Mótökuaðili umsýsla' : 'Recycling Company Admin' + return locale === 'is' + ? 'Móttökuaðili umsýsla' + : 'Recycling Company Admin' default: return startCase(role) } diff --git a/apps/skilavottord/ws/src/app/modules/recyclingRequest/recyclingRequest.service.ts b/apps/skilavottord/ws/src/app/modules/recyclingRequest/recyclingRequest.service.ts index b84bedcff8ea..afb5ea568a87 100644 --- a/apps/skilavottord/ws/src/app/modules/recyclingRequest/recyclingRequest.service.ts +++ b/apps/skilavottord/ws/src/app/modules/recyclingRequest/recyclingRequest.service.ts @@ -1,4 +1,9 @@ -import { Inject, Injectable, forwardRef } from '@nestjs/common' +import { + Inject, + Injectable, + NotFoundException, + forwardRef, +} from '@nestjs/common' import { HttpService } from '@nestjs/axios' import { InjectModel } from '@nestjs/sequelize' import format from 'date-fns/format' @@ -159,8 +164,12 @@ export class RecyclingRequestService { ) } } else { - throw new Error( - `Could not find any requestType for vehicle's number: ${loggedPermno} in database`, + this.logger.warn( + `car-recycling: Could not find any requestType for vehicle's number: ${loggedPermno} in database from partner ${user.partnerId}`, + ) + throw new NotFoundException( + `Could not find any requestType for vehicle's number: ${loggedPermno} in database from partner ${user.partnerId}`, + 'NOT_FOUND', ) } @@ -173,6 +182,10 @@ export class RecyclingRequestService { } return res } catch (err) { + if (err instanceof NotFoundException) { + throw err + } + throw new Error( `Failed on getVehicleInfoToDeregistered request from partner ${user.partnerId} with error: ${err}`, ) From 88f72f6b44c2ad4df0efcee707e79d3f2bfb0015 Mon Sep 17 00:00:00 2001 From: unakb Date: Fri, 13 Dec 2024 20:08:08 +0000 Subject: [PATCH 22/32] chore(j-s): Send signed court record to police for investigation cases (#17196) * chore(j-s): Send signed court record to police for investigation cases * Update case.service.ts * Update internalCase.controller.ts --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../src/app/modules/case/case.service.ts | 21 +++ .../modules/case/internalCase.controller.ts | 29 ++++ .../app/modules/case/internalCase.service.ts | 35 ++++- .../deliverSignedCourtRecordToPolice.spec.ts | 124 ++++++++++++++++++ ...verSignedCourtRecordToPoliceGuards.spec.ts | 66 ++++++++++ .../web/messages/Core/errors.ts | 4 +- .../message/src/lib/message.service.ts | 3 + .../message/src/lib/message.ts | 2 + 8 files changed, 281 insertions(+), 3 deletions(-) create mode 100644 apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPolice.spec.ts create mode 100644 apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPoliceGuards.spec.ts diff --git a/apps/judicial-system/backend/src/app/modules/case/case.service.ts b/apps/judicial-system/backend/src/app/modules/case/case.service.ts index c89bbc8c0e0c..b9980ed191fd 100644 --- a/apps/judicial-system/backend/src/app/modules/case/case.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/case.service.ts @@ -45,6 +45,7 @@ import { eventTypes, isCompletedCase, isIndictmentCase, + isInvestigationCase, isRequestCase, isTrafficViolationCase, notificationTypes, @@ -845,7 +846,25 @@ export class CaseService { this.getDeliverProsecutorToCourtMessages(theCase, user), ) } + private addMessagesForSignedCourtRecordToQueue( + theCase: Case, + user: TUser, + ): Promise { + const messages = [] + + if ( + theCase.origin === CaseOrigin.LOKE && + isInvestigationCase(theCase.type) + ) { + messages.push({ + type: MessageType.DELIVERY_TO_POLICE_SIGNED_COURT_RECORD, + user, + caseId: theCase.id, + }) + } + return this.messageService.sendMessagesToQueue(messages) + } private addMessagesForSignedRulingToQueue( theCase: Case, user: TUser, @@ -1899,6 +1918,8 @@ export class CaseService { false, ) + await this.addMessagesForSignedCourtRecordToQueue(theCase, user) + return { documentSigned: true } } catch (error) { this.eventService.postErrorEvent( diff --git a/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts b/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts index 60991a38b33f..d48a86633f14 100644 --- a/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts +++ b/apps/judicial-system/backend/src/app/modules/case/internalCase.controller.ts @@ -571,6 +571,35 @@ export class InternalCaseController { ) } + @UseGuards( + CaseExistsGuard, + new CaseTypeGuard([...restrictionCases, ...investigationCases]), + CaseCompletedGuard, + ) + @Post( + `case/:caseId/${ + messageEndpoint[MessageType.DELIVERY_TO_POLICE_SIGNED_COURT_RECORD] + }`, + ) + @ApiOkResponse({ + type: DeliverResponse, + description: 'Delivers a signed court record to police', + }) + deliverSignedCourtRecordToPolice( + @Param('caseId') caseId: string, + @CurrentCase() theCase: Case, + @Body() deliverDto: DeliverDto, + ): Promise { + this.logger.debug( + `Delivering the signed court record for case ${caseId} to police`, + ) + + return this.internalCaseService.deliverSignedCourtRecordToPolice( + theCase, + deliverDto.user, + ) + } + @UseGuards( CaseExistsGuard, new CaseTypeGuard([...restrictionCases, ...investigationCases]), diff --git a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts index 729645bb5f82..8a06a7825db3 100644 --- a/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/internalCase.service.ts @@ -307,6 +307,13 @@ export class InternalCaseService { ) } + private getSignedCourtRecordPdf(theCase: Case) { + return this.awsS3Service.getGeneratedRequestCaseObject( + theCase.type, + `${theCase.id}/courtRecord.pdf`, + ) + } + private async deliverSignedRulingPdfToCourt( theCase: Case, user: TUser, @@ -1100,6 +1107,32 @@ export class InternalCaseService { return { delivered } } + async deliverSignedCourtRecordToPolice( + theCase: Case, + user: TUser, + ): Promise { + const delivered = await this.getSignedCourtRecordPdf(theCase) + .then((pdf) => + this.deliverCaseToPoliceWithFiles(theCase, user, [ + { + type: PoliceDocumentType.RVTB, + courtDocument: Base64.btoa(pdf.toString('binary')), + }, + ]), + ) + .catch((reason) => { + // Tolerate failure, but log error + this.logger.error( + `Failed to deliver signed court record for case ${theCase.id} to police`, + { reason }, + ) + + return false + }) + + return { delivered } + } + async deliverSignedRulingToPolice( theCase: Case, user: TUser, @@ -1116,7 +1149,7 @@ export class InternalCaseService { .catch((reason) => { // Tolerate failure, but log error this.logger.error( - `Failed to deliver sigend ruling for case ${theCase.id} to police`, + `Failed to deliver signed ruling for case ${theCase.id} to police`, { reason }, ) diff --git a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPolice.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPolice.spec.ts new file mode 100644 index 000000000000..dabef1f9f88d --- /dev/null +++ b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPolice.spec.ts @@ -0,0 +1,124 @@ +import { Base64 } from 'js-base64' +import { uuid } from 'uuidv4' + +import { + CaseOrigin, + CaseState, + CaseType, + User, +} from '@island.is/judicial-system/types' + +import { createTestingCaseModule } from '../createTestingCaseModule' + +import { nowFactory } from '../../../../factories' +import { randomDate } from '../../../../test' +import { AwsS3Service } from '../../../aws-s3' +import { PoliceDocumentType, PoliceService } from '../../../police' +import { Case } from '../../models/case.model' +import { DeliverResponse } from '../../models/deliver.response' + +jest.mock('../../../../factories') + +interface Then { + result: DeliverResponse + error: Error +} + +type GivenWhenThen = (caseId: string, theCase: Case) => Promise + +describe('InternalCaseController - Deliver signed court record to police', () => { + const userId = uuid() + const user = { id: userId } as User + + let mockAwsS3Service: AwsS3Service + let mockPoliceService: PoliceService + let givenWhenThen: GivenWhenThen + + beforeEach(async () => { + const { awsS3Service, policeService, internalCaseController } = + await createTestingCaseModule() + + mockAwsS3Service = awsS3Service + mockPoliceService = policeService + + const mockGetGeneratedObject = + awsS3Service.getGeneratedRequestCaseObject as jest.Mock + mockGetGeneratedObject.mockRejectedValue(new Error('Some error')) + const mockUpdatePoliceCase = mockPoliceService.updatePoliceCase as jest.Mock + mockUpdatePoliceCase.mockRejectedValue(new Error('Some error')) + + givenWhenThen = async (caseId: string, theCase: Case) => { + const then = {} as Then + + await internalCaseController + .deliverSignedCourtRecordToPolice(caseId, theCase, { user }) + .then((result) => (then.result = result)) + .catch((error) => (then.error = error)) + + return then + } + }) + + describe('deliver case to police', () => { + const caseId = uuid() + const caseType = CaseType.PHONE_TAPPING + const caseState = CaseState.ACCEPTED + const policeCaseNumber = uuid() + const courtCaseNumber = uuid() + const defendantNationalId = '0123456789' + const validToDate = randomDate() + const caseConclusion = 'test conclusion' + const theCase = { + id: caseId, + origin: CaseOrigin.LOKE, + type: caseType, + state: caseState, + policeCaseNumbers: [policeCaseNumber], + courtCaseNumber, + defendants: [{ nationalId: defendantNationalId }], + validToDate, + conclusion: caseConclusion, + } as Case + const courtRecordPdf = 'test court record' + + let then: Then + + beforeEach(async () => { + const mockToday = nowFactory as jest.Mock + mockToday.mockReturnValueOnce(validToDate) + + const mockGetGeneratedObject = + mockAwsS3Service.getGeneratedRequestCaseObject as jest.Mock + mockGetGeneratedObject.mockResolvedValueOnce(courtRecordPdf) + const mockUpdatePoliceCase = + mockPoliceService.updatePoliceCase as jest.Mock + mockUpdatePoliceCase.mockResolvedValueOnce(true) + + then = await givenWhenThen(caseId, theCase) + }) + + it('should update the police case with a signed court record', async () => { + expect( + mockAwsS3Service.getGeneratedRequestCaseObject, + ).toHaveBeenCalledWith(caseType, `${caseId}/courtRecord.pdf`) + expect(mockPoliceService.updatePoliceCase).toHaveBeenCalledWith( + user, + caseId, + caseType, + caseState, + policeCaseNumber, + courtCaseNumber, + defendantNationalId, + validToDate, + caseConclusion, + [ + { + type: PoliceDocumentType.RVTB, + courtDocument: Base64.btoa(courtRecordPdf), + }, + ], + ) + expect(then.result.delivered).toEqual(true) + }) + }) +}) diff --git a/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPoliceGuards.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPoliceGuards.spec.ts new file mode 100644 index 000000000000..38394cc82fd3 --- /dev/null +++ b/apps/judicial-system/backend/src/app/modules/case/test/internalCaseController/deliverSignedCourtRecordToPoliceGuards.spec.ts @@ -0,0 +1,66 @@ +import { CanActivate } from '@nestjs/common' + +import { + investigationCases, + restrictionCases, +} from '@island.is/judicial-system/types' + +import { CaseCompletedGuard } from '../../guards/caseCompleted.guard' +import { CaseExistsGuard } from '../../guards/caseExists.guard' +import { CaseTypeGuard } from '../../guards/caseType.guard' +import { InternalCaseController } from '../../internalCase.controller' + +describe('InternalCaseController - Deliver signed court record to police guards', () => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let guards: any[] + + beforeEach(() => { + guards = Reflect.getMetadata( + '__guards__', + InternalCaseController.prototype.deliverSignedCourtRecordToPolice, + ) + }) + + it('should have three guards', () => { + expect(guards).toHaveLength(3) + }) + + describe('CaseExistsGuard', () => { + let guard: CanActivate + + beforeEach(() => { + guard = new guards[0]() + }) + + it('should have CaseExistsGuard as guard 1', () => { + expect(guard).toBeInstanceOf(CaseExistsGuard) + }) + }) + + describe('CaseTypeGuard', () => { + let guard: CanActivate + + beforeEach(() => { + guard = guards[1] + }) + + it('should have CaseTypeGuard as guard 2', () => { + expect(guard).toBeInstanceOf(CaseTypeGuard) + expect(guard).toEqual({ + allowedCaseTypes: [...restrictionCases, ...investigationCases], + }) + }) + }) + + describe('CaseCompletedGuard', () => { + let guard: CanActivate + + beforeEach(() => { + guard = new guards[2]() + }) + + it('should have CaseCompletedGuard as guard 3', () => { + expect(guard).toBeInstanceOf(CaseCompletedGuard) + }) + }) +}) diff --git a/apps/judicial-system/web/messages/Core/errors.ts b/apps/judicial-system/web/messages/Core/errors.ts index b2388cfda63e..02927f00f07f 100644 --- a/apps/judicial-system/web/messages/Core/errors.ts +++ b/apps/judicial-system/web/messages/Core/errors.ts @@ -43,8 +43,8 @@ export const errors = defineMessages({ 'Notaður sem villuskilaboð þegar ekki gengur að eyða kröfuhafa', }, createCase: { - id: 'judicial.system.core:errors.create_case', - defaultMessage: 'Upp kom villa við að stofnun máls', + id: 'judicial.system.core:errors.create_case_v1', + defaultMessage: 'Upp kom villa við stofnun máls', description: 'Notaður sem villuskilaboð þegar ekki gengur að stofna mál', }, updateCase: { diff --git a/libs/judicial-system/message/src/lib/message.service.ts b/libs/judicial-system/message/src/lib/message.service.ts index 671b1d099478..a457fc512d70 100644 --- a/libs/judicial-system/message/src/lib/message.service.ts +++ b/libs/judicial-system/message/src/lib/message.service.ts @@ -198,6 +198,9 @@ export class MessageService { ): Promise { const MAX_BATCH_SIZE = 10 + if (messages.length === 0) { + return // No messages to send + } if (messages.length <= MAX_BATCH_SIZE) { const queueUrl = await this.getQueueUrl() diff --git a/libs/judicial-system/message/src/lib/message.ts b/libs/judicial-system/message/src/lib/message.ts index c93854bab4e6..bb32cdc84e05 100644 --- a/libs/judicial-system/message/src/lib/message.ts +++ b/libs/judicial-system/message/src/lib/message.ts @@ -23,6 +23,7 @@ export enum MessageType { DELIVERY_TO_POLICE_INDICTMENT = 'DELIVERY_TO_POLICE_INDICTMENT', DELIVERY_TO_POLICE_CASE_FILES_RECORD = 'DELIVERY_TO_POLICE_CASE_FILES_RECORD', DELIVERY_TO_POLICE_SUBPOENA = 'DELIVERY_TO_POLICE_SUBPOENA', + DELIVERY_TO_POLICE_SIGNED_COURT_RECORD = 'DELIVERY_TO_POLICE_SIGNED_COURT_RECORD', DELIVERY_TO_POLICE_SIGNED_RULING = 'DELIVERY_TO_POLICE_SIGNED_RULING', DELIVERY_TO_POLICE_APPEAL = 'DELIVERY_TO_POLICE_APPEAL', NOTIFICATION = 'NOTIFICATION', @@ -62,6 +63,7 @@ export const messageEndpoint: { [key in MessageType]: string } = { DELIVERY_TO_POLICE_INDICTMENT: 'deliverIndictmentToPolice', DELIVERY_TO_POLICE_CASE_FILES_RECORD: 'deliverCaseFilesRecordToPolice', DELIVERY_TO_POLICE_SUBPOENA: 'deliverSubpoenaToPolice', + DELIVERY_TO_POLICE_SIGNED_COURT_RECORD: 'deliverSignedCourtRecordToPolice', DELIVERY_TO_POLICE_SIGNED_RULING: 'deliverSignedRulingToPolice', DELIVERY_TO_POLICE_APPEAL: 'deliverAppealToPolice', NOTIFICATION: 'notification', From 42c998d1f320518af37cae422eb06e98cba09dae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dvar=20Oddsson?= Date: Fri, 13 Dec 2024 22:18:33 +0000 Subject: [PATCH 23/32] chore(j-s): Show send to prison admin file (#17148) * Refactoring * Refactor * Refactor * Refactor * Refactor * Refactor * Fix typo * Add rulings under permissions * Fix lint --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../IndictmentCaseFilesList.strings.ts | 6 + .../IndictmentCaseFilesList.tsx | 258 +++++++++++------- libs/judicial-system/types/src/lib/user.ts | 16 +- 3 files changed, 167 insertions(+), 113 deletions(-) diff --git a/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.strings.ts b/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.strings.ts index ab0f020ba135..5a4b7ecb6bb6 100644 --- a/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.strings.ts +++ b/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.strings.ts @@ -51,4 +51,10 @@ export const strings = defineMessages({ description: 'Notaður sem texti á PDF takka til að sækja birtingarvottorð í ákærum.', }, + sentToPrisonAdmin: { + id: 'judicial.system.core:indictment_case_files_list.sent_to_prison_admin', + defaultMessage: 'Fullnusta', + description: + 'Notaður sem titill á fullnusta hluta á dómskjalaskjá í ákærum.', + }, }) diff --git a/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.tsx b/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.tsx index b9646bc28671..752011aac971 100644 --- a/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.tsx +++ b/apps/judicial-system/web/src/components/IndictmentCaseFilesList/IndictmentCaseFilesList.tsx @@ -1,4 +1,4 @@ -import { FC, useContext } from 'react' +import { FC, useContext, useMemo } from 'react' import { useIntl } from 'react-intl' import { AnimatePresence } from 'framer-motion' @@ -9,6 +9,7 @@ import { isCompletedCase, isDefenceUser, isDistrictCourtUser, + isPrisonAdminUser, isProsecutionUser, isPublicProsecutor, isPublicProsecutorUser, @@ -25,6 +26,7 @@ import { import { CaseFile, CaseFileCategory, + User, } from '@island.is/judicial-system-web/src/graphql/schema' import { TempCase as Case } from '@island.is/judicial-system-web/src/types' import { useFileList } from '@island.is/judicial-system-web/src/utils/hooks' @@ -45,6 +47,13 @@ interface RenderFilesProps { onOpenFile: (fileId: string) => void } +interface FileSection { + title: string + onOpenFile: (fileId: string) => void + files?: CaseFile[] + shouldRender?: boolean +} + export const RenderFiles: FC = ({ caseFiles, onOpenFile, @@ -65,6 +74,82 @@ export const RenderFiles: FC = ({ ) } +const FileSection: FC = (props: FileSection) => { + const { title, files, onOpenFile, shouldRender = true } = props + + if (!files?.length || !shouldRender) { + return null + } + + return ( + + + {title} + + + + ) +} + +const useFilteredCaseFiles = (caseFiles?: CaseFile[] | null) => { + return useMemo(() => { + const filterByCategories = ( + categories: CaseFileCategory | CaseFileCategory[], + ) => { + const categoryArray = Array.isArray(categories) + ? categories + : [categories] + + return ( + caseFiles?.filter( + (file) => file.category && categoryArray.includes(file.category), + ) ?? [] + ) + } + + return { + indictments: filterByCategories(CaseFileCategory.INDICTMENT), + criminalRecords: filterByCategories(CaseFileCategory.CRIMINAL_RECORD), + costBreakdowns: filterByCategories(CaseFileCategory.COST_BREAKDOWN), + others: filterByCategories(CaseFileCategory.CASE_FILE), + rulings: filterByCategories(CaseFileCategory.RULING), + courtRecords: filterByCategories(CaseFileCategory.COURT_RECORD), + criminalRecordUpdate: filterByCategories( + CaseFileCategory.CRIMINAL_RECORD_UPDATE, + ), + uploadedCaseFiles: filterByCategories([ + CaseFileCategory.PROSECUTOR_CASE_FILE, + CaseFileCategory.DEFENDANT_CASE_FILE, + ]), + civilClaims: filterByCategories(CaseFileCategory.CIVIL_CLAIM), + sentToPrisonAdminFiles: filterByCategories( + CaseFileCategory.SENT_TO_PRISON_ADMIN_FILE, + ), + } + }, [caseFiles]) +} + +const useFilePermissions = (workingCase: Case, user?: User) => { + return useMemo( + () => ({ + canViewCriminalRecordUpdate: + isDistrictCourtUser(user) || + isPublicProsecutor(user) || + isPublicProsecutorUser(user), + canViewCivilClaims: + Boolean(workingCase.hasCivilClaims) && + (isDistrictCourtUser(user) || + isProsecutionUser(user) || + isDefenceUser(user)), + canViewSentToPrisonAdminFiles: + isPrisonAdminUser(user) || isPublicProsecutorUser(user), + canViewRulings: + isDistrictCourtUser(user) || isCompletedCase(workingCase.state), + }), + [user, workingCase.hasCivilClaims, workingCase.state], + ) +} + const IndictmentCaseFilesList: FC = ({ workingCase, displayGeneratedPDFs = true, @@ -89,51 +174,19 @@ const IndictmentCaseFilesList: FC = ({ (defendant) => defendant.subpoenas && defendant.subpoenas.length > 0, ) - const cf = workingCase.caseFiles - - const indictments = cf?.filter( - (file) => file.category === CaseFileCategory.INDICTMENT, - ) - const criminalRecords = cf?.filter( - (file) => file.category === CaseFileCategory.CRIMINAL_RECORD, - ) - const costBreakdowns = cf?.filter( - (file) => file.category === CaseFileCategory.COST_BREAKDOWN, - ) - const others = cf?.filter( - (file) => file.category === CaseFileCategory.CASE_FILE, - ) - const rulings = cf?.filter( - (file) => file.category === CaseFileCategory.RULING, - ) - const courtRecords = cf?.filter( - (file) => file.category === CaseFileCategory.COURT_RECORD, - ) - const criminalRecordUpdate = cf?.filter( - (file) => file.category === CaseFileCategory.CRIMINAL_RECORD_UPDATE, - ) - const uploadedCaseFiles = cf?.filter( - (file) => - file.category === CaseFileCategory.PROSECUTOR_CASE_FILE || - file.category === CaseFileCategory.DEFENDANT_CASE_FILE, - ) - const civilClaims = cf?.filter( - (file) => file.category === CaseFileCategory.CIVIL_CLAIM, - ) + const filteredFiles = useFilteredCaseFiles(workingCase.caseFiles) + const permissions = useFilePermissions(workingCase, user) return ( <> {displayHeading && ( )} - {indictments && indictments.length > 0 && ( - - - {formatMessage(caseFiles.indictmentSection)} - - - - )} + {showTrafficViolationCaseFiles && displayGeneratedPDFs && ( @@ -150,42 +203,27 @@ const IndictmentCaseFilesList: FC = ({ )} - {criminalRecords && criminalRecords.length > 0 && ( - - - {formatMessage(caseFiles.criminalRecordSection)} - - - - )} - {criminalRecordUpdate && - criminalRecordUpdate.length > 0 && - (isDistrictCourtUser(user) || - isPublicProsecutor(user) || - isPublicProsecutorUser(user)) && ( - - - {formatMessage(caseFiles.criminalRecordUpdateSection)} - - - - )} - {costBreakdowns && costBreakdowns.length > 0 && ( - - - {formatMessage(caseFiles.costBreakdownSection)} - - - - )} - {others && others.length > 0 && ( - - - {formatMessage(caseFiles.otherDocumentsSection)} - - - - )} + + + + {displayGeneratedPDFs && ( @@ -207,34 +245,34 @@ const IndictmentCaseFilesList: FC = ({ ))} )} - {courtRecords?.length || rulings?.length ? ( + {filteredFiles.courtRecords?.length || filteredFiles.rulings?.length ? ( {formatMessage(strings.rulingAndCourtRecordsTitle)} - {courtRecords && courtRecords.length > 0 && ( - - )} - {(isDistrictCourtUser(user) || isCompletedCase(workingCase.state)) && - rulings && - rulings.length > 0 && ( - + {filteredFiles.courtRecords && + filteredFiles.courtRecords.length > 0 && ( + + )} + {permissions.canViewRulings && + filteredFiles.rulings && + filteredFiles.rulings.length > 0 && ( + )} ) : null} - {workingCase.hasCivilClaims && - civilClaims && - civilClaims.length > 0 && - (isDistrictCourtUser(user) || - isProsecutionUser(user) || - isDefenceUser(user)) && ( - - - {formatMessage(strings.civilClaimsTitle)} - - - - )} + {showSubpoenaPdf && ( @@ -273,14 +311,24 @@ const IndictmentCaseFilesList: FC = ({ )} )} - {uploadedCaseFiles && uploadedCaseFiles.length > 0 && ( - - - {formatMessage(strings.uploadedCaseFiles)} - - - - )} + {filteredFiles.uploadedCaseFiles && + filteredFiles.uploadedCaseFiles.length > 0 && ( + + + {formatMessage(strings.uploadedCaseFiles)} + + + + )} + {fileNotFound && } diff --git a/libs/judicial-system/types/src/lib/user.ts b/libs/judicial-system/types/src/lib/user.ts index 8c0dcb478e20..408c3136cebd 100644 --- a/libs/judicial-system/types/src/lib/user.ts +++ b/libs/judicial-system/types/src/lib/user.ts @@ -70,8 +70,8 @@ export const isPublicProsecutorUser = (user?: InstitutionUser): boolean => { return Boolean( user?.role && publicProsecutorRoles.includes(user.role) && - user?.institution?.type === InstitutionType.PROSECUTORS_OFFICE && - user?.institution?.id === '8f9e2f6d-6a00-4a5e-b39b-95fd110d762e', // TODO: Create a new institution type to avoid hardcoding + user.institution?.type === InstitutionType.PROSECUTORS_OFFICE && + user.institution?.id === '8f9e2f6d-6a00-4a5e-b39b-95fd110d762e', // TODO: Create a new institution type to avoid hardcoding ) } @@ -85,7 +85,7 @@ export const isDistrictCourtUser = (user?: InstitutionUser): boolean => { return Boolean( user?.role && districtCourtRoles.includes(user.role) && - user?.institution?.type === InstitutionType.DISTRICT_COURT, + user.institution?.type === InstitutionType.DISTRICT_COURT, ) } @@ -99,7 +99,7 @@ export const isCourtOfAppealsUser = (user?: InstitutionUser): boolean => { return Boolean( user?.role && courtOfAppealsRoles.includes(user.role) && - user?.institution?.type === InstitutionType.COURT_OF_APPEALS, + user.institution?.type === InstitutionType.COURT_OF_APPEALS, ) } @@ -109,14 +109,14 @@ export const isPrisonSystemUser = (user?: InstitutionUser): boolean => { return Boolean( user?.role && prisonSystemRoles.includes(user.role) && - (user?.institution?.type === InstitutionType.PRISON || - user?.institution?.type === InstitutionType.PRISON_ADMIN), + (user.institution?.type === InstitutionType.PRISON || + user.institution?.type === InstitutionType.PRISON_ADMIN), ) } -export const isPrisonAdminUser = (user: InstitutionUser): boolean => +export const isPrisonAdminUser = (user?: InstitutionUser): boolean => Boolean( - user.role && + user?.role && prisonSystemRoles.includes(user.role) && user.institution?.type === InstitutionType.PRISON_ADMIN, ) From 7cc039550bf2477b33c28a020d8890b020c578fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Mon, 16 Dec 2024 10:16:08 +0000 Subject: [PATCH 24/32] feat(web): Pension Calculator - "After September 1 2025" year option (#17117) * Add new options to base pension type * Update logic * Add more translation strings * Remove comment * Add text for 2025 calculator * Add translation string * Decrease font size and wrap text * Update title --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../PensionCalculator.tsx | 168 +++++++++++++++--- .../PensionCalculatorResults.tsx | 63 +++++-- .../translationStrings.ts | 61 +++++++ .../SocialInsuranceAdministration/utils.ts | 6 + .../src/lib/dtos/pensionCalculation.input.ts | 3 + .../domains/social-insurance/src/lib/utils.ts | 5 +- 6 files changed, 270 insertions(+), 36 deletions(-) diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx index af85afcd89db..143a47f3b0de 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx @@ -1,4 +1,4 @@ -import { PropsWithChildren, useMemo, useState } from 'react' +import { PropsWithChildren, useEffect, useMemo, useState } from 'react' import { Controller, FormProvider, useForm } from 'react-hook-form' import { useIntl } from 'react-intl' import add from 'date-fns/add' @@ -57,6 +57,8 @@ import { convertToQueryParams, extractSlug, getDateOfCalculationsOptions, + is2025FormPreviewActive, + NEW_SYSTEM_TAKES_PLACE_DATE, } from './utils' import * as styles from './PensionCalculator.css' @@ -70,7 +72,10 @@ const hasDisabilityAssessment = ( ) => { return ( typeOfBasePension === BasePensionType.Disability || - typeOfBasePension === BasePensionType.Rehabilitation + typeOfBasePension === BasePensionType.Rehabilitation || + typeOfBasePension === BasePensionType.NewSystemDisability || + typeOfBasePension === BasePensionType.NewSystemPartialDisability || + typeOfBasePension === BasePensionType.NewSystemMedicalAndRehabilitation ) } @@ -131,6 +136,15 @@ const PensionCalculator: CustomScreen = ({ defaultValues, }) + const [dateOfCalculations, setDateOfCalculations] = useQueryState( + 'dateOfCalculations', + { + defaultValue: + methods.formState.defaultValues?.dateOfCalculations ?? + dateOfCalculationsOptions[0].value, + }, + ) + const currencyInputMaxLength = customPageData?.configJson?.currencyInputMaxLength ?? 14 @@ -165,7 +179,47 @@ const PensionCalculator: CustomScreen = ({ ? maxMonthPensionDelayIfBorn1951OrEarlier : maxMonthPensionDelayIfBornAfter1951 + const allCalculatorsOptions = useMemo(() => { + const options = [...dateOfCalculationsOptions] + + if (is2025FormPreviewActive(customPageData)) { + options.unshift({ + label: formatMessage(translationStrings.form2025PreviewLabel), + value: NEW_SYSTEM_TAKES_PLACE_DATE.toISOString(), + }) + } + + return options + }, [customPageData, dateOfCalculationsOptions, formatMessage]) + + const isNewSystemActive = + is2025FormPreviewActive(customPageData) && + dateOfCalculations === NEW_SYSTEM_TAKES_PLACE_DATE.toISOString() + const basePensionTypeOptions = useMemo[]>(() => { + if (isNewSystemActive) { + const options = [ + { + label: formatMessage( + translationStrings.basePensionNewSystemDisabilityLabel, + ), + value: BasePensionType.NewSystemDisability, + }, + { + label: formatMessage( + translationStrings.basePensionNewSystemPartialDisabilityLabel, + ), + value: BasePensionType.NewSystemPartialDisability, + }, + { + label: formatMessage( + translationStrings.basePensionNewSystemMedicalAndRehabilitation, + ), + value: BasePensionType.NewSystemMedicalAndRehabilitation, + }, + ] + return options + } const options = [ { label: formatMessage(translationStrings.basePensionRetirementLabel), @@ -190,9 +244,10 @@ const PensionCalculator: CustomScreen = ({ value: BasePensionType.HalfRetirement, }, ] + options.sort(sortAlpha('label')) return options - }, [formatMessage]) + }, [formatMessage, isNewSystemActive]) const hasSpouseOptions = useMemo[]>(() => { return [ @@ -265,15 +320,6 @@ const PensionCalculator: CustomScreen = ({ ] }, [formatMessage]) - const [dateOfCalculations, setDateOfCalculations] = useQueryState( - 'dateOfCalculations', - { - defaultValue: - methods.formState.defaultValues?.dateOfCalculations ?? - dateOfCalculationsOptions[0].value, - }, - ) - const { linkResolver } = useLinkResolver() const router = useRouter() @@ -355,6 +401,30 @@ const PensionCalculator: CustomScreen = ({ ] }, [formatMessage]) + // Make sure we never enter an invalid state + useEffect(() => { + if (isNewSystemActive) { + if ( + typeOfBasePension !== BasePensionType.NewSystemDisability && + typeOfBasePension !== BasePensionType.NewSystemPartialDisability && + typeOfBasePension !== BasePensionType.NewSystemMedicalAndRehabilitation + ) { + methods.setValue( + 'typeOfBasePension', + BasePensionType.NewSystemDisability, + ) + } + } else { + if ( + typeOfBasePension === BasePensionType.NewSystemDisability || + typeOfBasePension === BasePensionType.NewSystemPartialDisability || + typeOfBasePension === BasePensionType.NewSystemMedicalAndRehabilitation + ) { + methods.setValue('typeOfBasePension', BasePensionType.Retirement) + } + } + }, [isNewSystemActive, methods, typeOfBasePension]) + const birthYearOptions = useMemo[]>(() => { const today = new Date() const options: Option[] = [] @@ -411,10 +481,17 @@ const PensionCalculator: CustomScreen = ({ return options }, [defaultPensionDate, maxMonthPensionDelay, maxMonthPensionHurry]) - const title = `${formatMessage(translationStrings.mainTitle)} ${ - dateOfCalculationsOptions.find((o) => o.value === dateOfCalculations) - ?.label ?? dateOfCalculationsOptions[0].label - }` + const title = `${formatMessage( + isNewSystemActive + ? translationStrings.form2025PreviewMainTitle + : translationStrings.mainTitle, + )}` + const titlePostfix = `${( + allCalculatorsOptions.find((o) => o.value === dateOfCalculations)?.label ?? + dateOfCalculationsOptions[0].label + ).toLowerCase()}` + + const titleVariant = isNewSystemActive ? 'h2' : 'h1' const startMonthOptions = useMemo(() => { if (!defaultPensionDate) { @@ -477,9 +554,16 @@ const PensionCalculator: CustomScreen = ({ > - - {title} - + {isNewSystemActive && ( + + {title}
{titlePostfix}
+
+ )} + {!isNewSystemActive && ( + + {title} {titlePostfix} + + )} {formatMessage(translationStrings.isTurnedOff)}
@@ -500,9 +584,16 @@ const PensionCalculator: CustomScreen = ({ - - {title} - + {isNewSystemActive && ( + + {title}
{titlePostfix}
+
+ )} + {!isNewSystemActive && ( + + {title} {titlePostfix} + + )}
= ({ translationStrings.dateOfCalculationsPlaceholder, )} size="sm" - options={dateOfCalculationsOptions} + options={allCalculatorsOptions} onSelect={(option) => { if (option) { setDateOfCalculations(option.value) + if (isNewSystemActive) { + if ( + option.value === + NEW_SYSTEM_TAKES_PLACE_DATE.toISOString() + ) { + // Date is being moved to the new system date + methods.setValue( + 'typeOfBasePension', + BasePensionType.NewSystemDisability, + ) + } else if ( + dateOfCalculations === + NEW_SYSTEM_TAKES_PLACE_DATE.toISOString() + ) { + // Date is being moved from new system date + methods.setValue( + 'typeOfBasePension', + BasePensionType.Retirement, + ) + } + } } }} /> @@ -827,6 +939,10 @@ const PensionCalculator: CustomScreen = ({ {(typeOfBasePension === BasePensionType.Disability || + typeOfBasePension === + BasePensionType.NewSystemDisability || + typeOfBasePension === + BasePensionType.NewSystemPartialDisability || typeOfBasePension === BasePensionType.Rehabilitation) && ( @@ -839,7 +955,11 @@ const PensionCalculator: CustomScreen = ({ } label={formatMessage( typeOfBasePension === - BasePensionType.Disability + BasePensionType.Disability || + typeOfBasePension === + BasePensionType.NewSystemDisability || + typeOfBasePension === + BasePensionType.NewSystemPartialDisability ? translationStrings.ageOfFirst75DisabilityAssessment : translationStrings.ageOfFirst75RehabilitationAssessment, )} diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorResults.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorResults.tsx index 8d0d36910b4a..4edace5cabe2 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorResults.tsx +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorResults.tsx @@ -1,4 +1,4 @@ -import { Fragment, useState } from 'react' +import { Fragment, useMemo, useState } from 'react' import { useIntl } from 'react-intl' import { @@ -58,7 +58,9 @@ import { convertToQueryParams, extractSlug, getDateOfCalculationsOptions, + is2025FormPreviewActive, is2025PreviewActive, + NEW_SYSTEM_TAKES_PLACE_DATE, } from './utils' import * as styles from './PensionCalculatorResults.css' @@ -285,11 +287,36 @@ const PensionCalculatorResults: CustomScreen = ({ const highlightedItems2025 = calculation2025.highlightedItems ?? [] - const title = `${formatMessage(translationStrings.mainTitle)} ${ - dateOfCalculationsOptions.find( + const allCalculatorsOptions = useMemo(() => { + const options = [...dateOfCalculationsOptions] + + if (is2025FormPreviewActive(customPageData)) { + options.unshift({ + label: formatMessage(translationStrings.form2025PreviewLabel), + value: NEW_SYSTEM_TAKES_PLACE_DATE.toISOString(), + }) + } + + return options + }, [customPageData, dateOfCalculationsOptions, formatMessage]) + + const isNewSystemActive = + is2025FormPreviewActive(customPageData) && + calculationInput.dateOfCalculations === + NEW_SYSTEM_TAKES_PLACE_DATE.toISOString() + + const title = `${formatMessage( + isNewSystemActive + ? translationStrings.form2025PreviewMainTitle + : translationStrings.mainTitle, + )}` + const titlePostfix = `${( + allCalculatorsOptions.find( (o) => o.value === calculationInput.dateOfCalculations, - )?.label ?? '' - }` + )?.label ?? dateOfCalculationsOptions[0].label + ).toLowerCase()}` + + const titleVariant = isNewSystemActive ? 'h2' : 'h1' const calculationIsPresent = typeof calculation.groups?.length === 'number' && @@ -334,9 +361,16 @@ const PensionCalculatorResults: CustomScreen = ({ > - - {title} - + {isNewSystemActive && ( + + {title}
{titlePostfix}
+
+ )} + {!isNewSystemActive && ( + + {title} {titlePostfix} + + )} {formatMessage(translationStrings.isTurnedOff)} @@ -357,9 +391,16 @@ const PensionCalculatorResults: CustomScreen = ({ - - {title} - + {isNewSystemActive && ( + + {title}
{titlePostfix}
+
+ )} + {!isNewSystemActive && ( + + {title} {titlePostfix} + + )} {formatMessage( diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts index 4c5373609c9f..8a273868f14b 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts @@ -17,6 +17,12 @@ export const translationStrings = defineMessages({ defaultMessage: 'Þú vilt hefja töku eftir 67 ára aldur', description: 'Upplýsingar sem birtast ef þú vilt seinka töku ellilífeyris', }, + form2025PreviewLabel: { + id: 'web.pensionCalculator:form2025PreviewLabel', + defaultMessage: 'Eftir 1. september 2025', + description: + 'Valmöguleiki í dropdown fyrir "Allar reiknivélar" ef það á að leyfa eftir 1. sept 2025 preview', + }, results2025ImageUrl: { id: 'web.pensionCalculator:results2025ImageUrl', defaultMessage: @@ -54,6 +60,24 @@ export const translationStrings = defineMessages({ defaultMessage: 'Ellilífeyrir', description: 'Tegund lífeyris, Ellilífeyrir', }, + basePensionNewSystemDisabilityLabel: { + id: 'web.pensionCalculator:basePensionNewSystemDisabilityLabel', + defaultMessage: 'Örorkulífeyrir', + description: + 'Tegund lífeyris fyrir nýtt kerfi þann 1. sept 2025, Örorkulífeyrir', + }, + basePensionNewSystemPartialDisabilityLabel: { + id: 'web.pensionCalculator:basePensionNewSystemPartialDisabilityLabel', + defaultMessage: 'Hlutaörorkulífeyrir', + description: + 'Tegund lífeyris fyrir nýtt kerfi þann 1. sept 2025, Hlutaörorkulífeyrir', + }, + basePensionNewSystemMedicalAndRehabilitation: { + id: 'web.pensionCalculator:basePensionNewSystemMedicalAndRehabilitation', + defaultMessage: 'Sjúkra- og endurhæfing', + description: + 'Tegund lífeyris fyrir nýtt kerfi þann 1. sept 2025, Sjúkra- og endurhæfing', + }, basePensionFishermanRetirementLabel: { id: 'web.pensionCalculator:basePensionFishermanRetirementLabel', defaultMessage: 'Ellilífeyrir sjómanna', @@ -429,6 +453,11 @@ export const translationStrings = defineMessages({ defaultMessage: 'Reiknivél lífeyris', description: 'Aðal titill', }, + form2025PreviewMainTitle: { + id: 'web.pensionCalculator:form2025PreviewMainTitle', + defaultMessage: 'Reiknivél örorku- og endurhæfingargreiðslna', + description: 'Aðal titill fyrir nýju eftir 1. sept 2025 reiknivél', + }, resultDisclaimer: { id: 'web.pensionCalculator:resultDisclaimer', defaultMessage: @@ -948,6 +977,38 @@ export const translationStrings = defineMessages({ defaultMessage: 'Örorkulífeyrir', description: 'Niðurstöðuskjár, Örorkulífeyrir 2025', }, + 'REIKNH.SJUKRAOGENDURH_HUPPBOT_2025': { + id: 'web.pensionCalculator:REIKNH.SJUKRAOGENDURH_HUPPBOT_2025', + defaultMessage: 'Sjúkra- og endurhæfingargreiðslur og heimilisuppbót', + description: + 'Niðurstöðuskjár, Sjúkra- og endurhæfingargreiðslur og heimilisuppbót', + }, + 'REIKNH.SJUKRAOGENDURH_2025': { + id: 'web.pensionCalculator:REIKNH.SJUKRAOGENDURH_2025', + defaultMessage: 'Sjúkra- og endurhæfingargreiðslur', + description: 'Niðurstöðuskjár, Sjúkra- og endurhæfingargreiðslur', + }, + 'REIKNH.HLUTAORORKA_ALDURSV_HUPPBOT_2025': { + id: 'web.pensionCalculator:REIKNH.HLUTAORORKA_ALDURSV_HUPPBOT_2025', + defaultMessage: 'Hlutaörorkulífeyrir, aldursviðbót og heimilisuppbót', + description: + 'Niðurstöðuskjár, Hlutaörorkulífeyrir, aldursviðbót og heimilisuppbót', + }, + 'REIKNH.HLUTAORORKA_ALDURSV_2025': { + id: 'web.pensionCalculator:REIKNH.HLUTAORORKA_ALDURSV_2025', + defaultMessage: 'Hlutaörorkulífeyrir og aldursviðbót', + description: 'Niðurstöðuskjár, Hlutaörorkulífeyrir og aldursviðbót', + }, + 'REIKNH.HLUTAORORKA_HUPPBOT_2025': { + id: 'web.pensionCalculator:REIKNH.HLUTAORORKA_HUPPBOT_2025', + defaultMessage: 'Hlutaörorkulífeyrir og heimilisuppbót', + description: 'Niðurstöðuskjár, Hlutaörorkulífeyrir og heimilisuppbót', + }, + 'REIKNH.HLUTAORORKA': { + id: 'web.pensionCalculator:REIKNH.HLUTAORORKA', + defaultMessage: 'Hlutaörorkulífeyrir', + description: 'Niðurstöðuskjár, Hlutaörorkulífeyrir', + }, highlighedResultItemHeadingForTotalAfterTaxFromTR: { id: 'web.pensionCalculator:REIKNH.highlighedResultItemHeadingForTotalAfterTaxFromTR', defaultMessage: 'Þar af greiðslur frá TR', diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/utils.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/utils.ts index 722370dda5ab..fb8cad0b51dc 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/utils.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/utils.ts @@ -153,3 +153,9 @@ export const extractSlug = ( export const is2025PreviewActive = (customPageData?: CustomPage | null) => { return Boolean(customPageData?.configJson?.show2025Preview) } + +export const is2025FormPreviewActive = (customPageData?: CustomPage | null) => { + return Boolean(customPageData?.configJson?.show2025FormPreview) +} + +export const NEW_SYSTEM_TAKES_PLACE_DATE = new Date(2025, 8, 2) diff --git a/libs/api/domains/social-insurance/src/lib/dtos/pensionCalculation.input.ts b/libs/api/domains/social-insurance/src/lib/dtos/pensionCalculation.input.ts index e6f73046d462..79b0efda8b55 100644 --- a/libs/api/domains/social-insurance/src/lib/dtos/pensionCalculation.input.ts +++ b/libs/api/domains/social-insurance/src/lib/dtos/pensionCalculation.input.ts @@ -7,6 +7,9 @@ export enum BasePensionType { Rehabilitation = 'Rehabilitation', HalfRetirement = 'HalfRetirement', NewSystem = 'NewSystem', + NewSystemDisability = 'NewSystemDisability', + NewSystemPartialDisability = 'NewSystemPartialDisability', + NewSystemMedicalAndRehabilitation = 'NewSystemMedicalAndRehabilitation', } registerEnumType(BasePensionType, { diff --git a/libs/api/domains/social-insurance/src/lib/utils.ts b/libs/api/domains/social-insurance/src/lib/utils.ts index 6341bbcd7ed0..8bd2d340f4b4 100644 --- a/libs/api/domains/social-insurance/src/lib/utils.ts +++ b/libs/api/domains/social-insurance/src/lib/utils.ts @@ -21,7 +21,10 @@ const basePensionTypeMapping: Record = { [BasePensionType.Disability]: 3, // Örorkulífeyrir [BasePensionType.Rehabilitation]: 4, // Endurhæfingarlífeyrir [BasePensionType.HalfRetirement]: 5, // Hálfur Ellilífeyrir - [BasePensionType.NewSystem]: 6, // Nýtt kerfi sem tekur gildi 1. september 2025 + [BasePensionType.NewSystem]: 6, // Örorkulífeyrir - Nýtt kerfi sem tekur gildi 1. september 2025 + [BasePensionType.NewSystemDisability]: 6, // Örorkulífeyrir - Nýtt kerfi sem tekur gildi 1. september 2025 + [BasePensionType.NewSystemPartialDisability]: 7, // Hlutaörorka - Nýtt kerfi sem tekur gildi 1. september 2025 + [BasePensionType.NewSystemMedicalAndRehabilitation]: 8, // Sjúkra- og endurhæfingargreiðslur - Nýtt kerfi sem tekur gildi 1. september 2025 } const livingConditionMapping: Record = { From 4fcc879014f5950209507d2773832c13b5b00308 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Eorkell=20M=C3=A1ni=20=C3=9Eorkelsson?= Date: Mon, 16 Dec 2024 10:59:18 +0000 Subject: [PATCH 25/32] feat(web): add button label (#17191) * fix: add label * chore: revert sdiebar * fix: add label * chore: wip * feat: use label --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- apps/web/screens/Grants/Grant/Grant.tsx | 34 ++++++++----------- .../web/screens/Grants/Grant/GrantSidebar.tsx | 6 ---- apps/web/screens/Grants/messages.ts | 6 +++- apps/web/screens/queries/Grants.ts | 8 ++--- .../src/lib/generated/contentfulTypes.d.ts | 23 ++++++------- libs/cms/src/lib/models/grant.model.ts | 18 +++------- .../lib/search/importers/grants.service.ts | 7 ---- 7 files changed, 36 insertions(+), 66 deletions(-) diff --git a/apps/web/screens/Grants/Grant/Grant.tsx b/apps/web/screens/Grants/Grant/Grant.tsx index 1a5f16e475fe..03184ecdfccc 100644 --- a/apps/web/screens/Grants/Grant/Grant.tsx +++ b/apps/web/screens/Grants/Grant/Grant.tsx @@ -105,7 +105,8 @@ const GrantSinglePage: CustomScreen = ({ grant, locale }) => { backgroundColor="blue" cta={{ disabled: !grant.applicationUrl?.slug, - label: formatMessage(m.single.apply), + label: + grant.applicationButtonLabel ?? formatMessage(m.single.apply), onClick: () => router.push(grant.applicationUrl?.slug ?? ''), icon: 'open', iconType: 'outline', @@ -139,26 +140,21 @@ const GrantSinglePage: CustomScreen = ({ grant, locale }) => { ) : undefined} {grant.howToApply?.length ? ( - - {formatMessage(m.single.howToApply)} - - {webRichText( - grant.howToApply as SliceType[], - undefined, - locale, - )} + <> + + {formatMessage(m.single.howToApply)} + + {webRichText( + grant.howToApply as SliceType[], + undefined, + locale, + )} + - - ) : undefined} - {grant.applicationDeadline?.length ? ( - - {webRichText( - grant.applicationDeadline as SliceType[], - undefined, - locale, - )} - + + ) : undefined} + {grant.applicationHints?.length ? ( {webRichText( diff --git a/apps/web/screens/Grants/Grant/GrantSidebar.tsx b/apps/web/screens/Grants/Grant/GrantSidebar.tsx index 77ac8aa2ac73..c2f9fe31939c 100644 --- a/apps/web/screens/Grants/Grant/GrantSidebar.tsx +++ b/apps/web/screens/Grants/Grant/GrantSidebar.tsx @@ -99,12 +99,6 @@ export const GrantSidebar = ({ grant, locale }: Props) => { {grant.typeTag?.title} ) : undefined, ), - generateLine( - formatMessage(m.single.deadline), - status.deadlineStatus ? ( - {status.deadlineStatus} - ) : undefined, - ), generateLine( formatMessage(m.single.status), grant?.status ? ( diff --git a/apps/web/screens/Grants/messages.ts b/apps/web/screens/Grants/messages.ts index 4cb32b60e623..63ef928f11e1 100644 --- a/apps/web/screens/Grants/messages.ts +++ b/apps/web/screens/Grants/messages.ts @@ -126,9 +126,13 @@ export const m = { id: 'web.grants:single.type', defaultMessage: 'Tegund', }, + applications: { + id: 'web.grants:single.applications', + defaultMessage: 'Umsóknir', + }, deadline: { id: 'web.grants:single.deadline', - defaultMessage: 'Umsóknarfrestur', + defaultMessage: 'Umsóknir', }, status: { id: 'web.grants:single.status', diff --git a/apps/web/screens/queries/Grants.ts b/apps/web/screens/queries/Grants.ts index cd120b0afcdc..7518d29e81d1 100644 --- a/apps/web/screens/queries/Grants.ts +++ b/apps/web/screens/queries/Grants.ts @@ -1,4 +1,5 @@ import gql from 'graphql-tag' + import { nestedFields, slices } from './fragments' export const GET_GRANTS_QUERY = gql` @@ -9,7 +10,6 @@ export const GET_GRANTS_QUERY = gql` name description applicationId - applicationDeadlineStatus applicationUrl { slug type @@ -67,7 +67,7 @@ export const GET_GRANT_QUERY = gql` slug type } - applicationDeadlineStatus + applicationButtonLabel status statusText dateFrom @@ -120,10 +120,6 @@ export const GET_GRANT_QUERY = gql` ...AllSlices ${nestedFields} } - applicationDeadline { - ...AllSlices - ${nestedFields} - } applicationHints { ...AllSlices ${nestedFields} diff --git a/libs/cms/src/lib/generated/contentfulTypes.d.ts b/libs/cms/src/lib/generated/contentfulTypes.d.ts index aeb745479f33..a5120aba2cfc 100644 --- a/libs/cms/src/lib/generated/contentfulTypes.d.ts +++ b/libs/cms/src/lib/generated/contentfulTypes.d.ts @@ -1814,14 +1814,11 @@ export interface IGrantFields { /** Description */ grantDescription?: string | undefined - /** Grant Application ID */ + /** Grant reference ID */ grantApplicationId?: string | undefined - /** Application Deadline Status */ - grantApplicationDeadlineStatus?: string | undefined - - /** Application Url */ - granApplicationUrl?: ILinkUrl | undefined + /** Fund */ + grantFund: IFund /** Special emphasis */ grantSpecialEmphasis?: Document | undefined @@ -1832,13 +1829,16 @@ export interface IGrantFields { /** How to apply? */ grantHowToApply?: Document | undefined - /** Application deadline */ - grantApplicationDeadline?: Document | undefined - /** Application hints */ grantApplicationHints?: Document | undefined - /** Open from */ + /** Application url */ + granApplicationUrl?: ILinkUrl | undefined + + /** Application button label */ + grantButtonLabel?: string | undefined + + /** Date from */ grantDateFrom?: string | undefined /** Open from hour */ @@ -1874,9 +1874,6 @@ export interface IGrantFields { /** Type tag */ grantTypeTag?: IGenericTag | undefined - - /** Fund */ - grantFund: IFund } /** Grant is a part of "Styrkjatorg". */ diff --git a/libs/cms/src/lib/models/grant.model.ts b/libs/cms/src/lib/models/grant.model.ts index bd5f7247cc9b..ba4238814907 100644 --- a/libs/cms/src/lib/models/grant.model.ts +++ b/libs/cms/src/lib/models/grant.model.ts @@ -41,12 +41,12 @@ export class Grant { @Field({ nullable: true }) applicationId?: string - @Field({ nullable: true }) - applicationDeadlineStatus?: string - @CacheField(() => ReferenceLink, { nullable: true }) applicationUrl?: ReferenceLink + @Field({ nullable: true }) + applicationButtonLabel?: string + @CacheField(() => [SliceUnion]) specialEmphasis?: Array @@ -56,9 +56,6 @@ export class Grant { @CacheField(() => [SliceUnion]) howToApply?: Array - @CacheField(() => [SliceUnion]) - applicationDeadline?: Array - @CacheField(() => [SliceUnion]) applicationHints?: Array @@ -141,11 +138,10 @@ export const mapGrant = ({ fields, sys }: IGrant): Grant => { name: fields.grantName, description: fields.grantDescription, applicationId: fields.grantApplicationId, - applicationDeadlineStatus: fields.grantApplicationDeadlineStatus, applicationUrl: fields.granApplicationUrl?.fields ? mapReferenceLink(fields.granApplicationUrl) : undefined, - + applicationButtonLabel: fields.grantButtonLabel, specialEmphasis: fields.grantSpecialEmphasis ? mapDocument(fields.grantSpecialEmphasis, sys.id + ':special-emphasis') : [], @@ -155,12 +151,6 @@ export const mapGrant = ({ fields, sys }: IGrant): Grant => { howToApply: fields.grantHowToApply ? mapDocument(fields.grantHowToApply, sys.id + ':how-to-apply') : [], - applicationDeadline: fields.grantApplicationDeadline - ? mapDocument( - fields.grantApplicationDeadline, - sys.id + ':application-deadline', - ) - : [], applicationHints: fields.grantApplicationHints ? mapDocument(fields.grantApplicationHints, sys.id + ':application-hints') : [], diff --git a/libs/cms/src/lib/search/importers/grants.service.ts b/libs/cms/src/lib/search/importers/grants.service.ts index 3a58a59778d5..3f2336eb2e1e 100644 --- a/libs/cms/src/lib/search/importers/grants.service.ts +++ b/libs/cms/src/lib/search/importers/grants.service.ts @@ -58,13 +58,6 @@ export class GrantsSyncService implements CmsSyncProvider { mapped?.howToApply?.map(pruneNonSearchableSliceUnionFields), ) : undefined, - mapped.applicationDeadline - ? extractStringsFromObject( - mapped?.applicationDeadline?.map( - pruneNonSearchableSliceUnionFields, - ), - ) - : undefined, mapped?.applicationHints ? extractStringsFromObject( mapped?.applicationHints?.map( From cfe3d0753aa82ea58c2f25a4e9475845a87a4075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dvar=20Oddsson?= Date: Mon, 16 Dec 2024 11:28:52 +0000 Subject: [PATCH 26/32] feat(j-s): Notifications sent when court officials are assigned (#17169) * Send notifications to court officials * Fix body * Send spesific judge notification * Send spesific registrar notifications * Send notifications in states received and submitted * Cleanup * Merge * Remove console.log * Refactor * Refactor * Rename variables * Remove redundant code --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../backend/src/app/messages/notifications.ts | 15 ++++++ .../src/app/modules/case/case.service.ts | 52 ++++++++++++++++++ .../modules/notification/guards/rolesRules.ts | 2 +- .../caseNotification.service.ts | 53 +++++++++++++++++++ .../types/src/lib/notification.ts | 2 + 5 files changed, 123 insertions(+), 1 deletion(-) diff --git a/apps/judicial-system/backend/src/app/messages/notifications.ts b/apps/judicial-system/backend/src/app/messages/notifications.ts index 43bda5af9fb3..ed00262e39d9 100644 --- a/apps/judicial-system/backend/src/app/messages/notifications.ts +++ b/apps/judicial-system/backend/src/app/messages/notifications.ts @@ -856,4 +856,19 @@ export const notifications = { description: 'Texti í pósti til aðila máls þegar ný gögn eru send', }, }), + courtOfficialAssignedEmail: defineMessages({ + subject: { + id: 'judicial.system.backend:notifications.court_official_assigned_email.subject', + defaultMessage: 'Úthlutun máls {courtCaseNumber}', + description: + 'Fyrirsögn í pósti til dómara og dómritara þegar máli er úthlutað á þau', + }, + body: { + id: 'judicial.system.backend:notifications.court_official_assigned_email.body', + defaultMessage: + 'Héraðsdómur hefur skráð þig sem {role, select, DISTRICT_COURT_JUDGE {dómara} DISTRICT_COURT_REGISTRAR {dómritara} other {óþekkt}} í máli {courtCaseNumber}. Hægt er að nálgast gögn málsins á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}', + description: + 'Texti í pósti til dómara og dómritara þegar máli er úthlutað á þau', + }, + }), } diff --git a/apps/judicial-system/backend/src/app/modules/case/case.service.ts b/apps/judicial-system/backend/src/app/modules/case/case.service.ts index b9980ed191fd..75fe945637d3 100644 --- a/apps/judicial-system/backend/src/app/modules/case/case.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/case.service.ts @@ -687,6 +687,34 @@ export class CaseService { ]) } + private addMessagesForDistrictCourtJudgeAssignedToQueue( + theCase: Case, + user: TUser, + ): Promise { + return this.messageService.sendMessagesToQueue([ + { + type: MessageType.NOTIFICATION, + user, + caseId: theCase.id, + body: { type: CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED }, + }, + ]) + } + + private addMessagesForDistrictCourtRegistrarAssignedToQueue( + theCase: Case, + user: TUser, + ): Promise { + return this.messageService.sendMessagesToQueue([ + { + type: MessageType.NOTIFICATION, + user, + caseId: theCase.id, + body: { type: CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED }, + }, + ]) + } + private addMessagesForReceivedCaseToQueue( theCase: Case, user: TUser, @@ -1403,6 +1431,30 @@ export class CaseService { } } + if ( + isIndictment && + [CaseState.SUBMITTED, CaseState.RECEIVED].includes(updatedCase.state) + ) { + const isJudgeChanged = + updatedCase.judge?.nationalId !== theCase.judge?.nationalId + const isRegistrarChanged = + updatedCase.registrar?.nationalId !== theCase.registrar?.nationalId + + if (isJudgeChanged) { + await this.addMessagesForDistrictCourtJudgeAssignedToQueue( + updatedCase, + user, + ) + } + + if (isRegistrarChanged) { + await this.addMessagesForDistrictCourtRegistrarAssignedToQueue( + updatedCase, + user, + ) + } + } + if ( isIndictment && ![ diff --git a/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts b/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts index 04cccc5de218..567e17620945 100644 --- a/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts +++ b/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts @@ -28,7 +28,7 @@ export const defenderNotificationRule: RolesRule = { ], } as RolesRule -// Allows district court judges to send notifiications +// Allows district court judges to send notifications export const districtCourtJudgeNotificationRule: RolesRule = { role: UserRole.DISTRICT_COURT_JUDGE, type: RulesType.FIELD_VALUES, diff --git a/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts index 0c4cbba076cb..fe2aa576b272 100644 --- a/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts +++ b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts @@ -21,6 +21,7 @@ import { INDICTMENTS_OVERVIEW_ROUTE, INVESTIGATION_CASE_POLICE_CONFIRMATION_ROUTE, RESTRICTION_CASE_OVERVIEW_ROUTE, + ROUTE_HANDLER_ROUTE, SIGNED_VERDICT_OVERVIEW_ROUTE, } from '@island.is/judicial-system/consts' import { @@ -46,6 +47,7 @@ import { RequestSharedWithDefender, SessionArrangements, type User, + UserRole, } from '@island.is/judicial-system/types' import { @@ -689,6 +691,28 @@ export class CaseNotificationService extends BaseNotificationService { }) } + private sendCourtOfficialAssignedEmailNotificationForIndictmentCase( + theCase: Case, + role: UserRole.DISTRICT_COURT_JUDGE | UserRole.DISTRICT_COURT_REGISTRAR, + ): Promise { + const official = + role === UserRole.DISTRICT_COURT_JUDGE ? theCase.judge : theCase.registrar + + return this.sendEmail( + this.formatMessage(notifications.courtOfficialAssignedEmail.subject, { + courtCaseNumber: theCase.courtCaseNumber, + }), + this.formatMessage(notifications.courtOfficialAssignedEmail.body, { + courtCaseNumber: theCase.courtCaseNumber, + role, + linkStart: ``, + linkEnd: '', + }), + official?.name, + official?.email, + ) + } + private sendCourtDateEmailNotificationForIndictmentCase( theCase: Case, user: User, @@ -810,6 +834,25 @@ export class CaseNotificationService extends BaseNotificationService { return result } + + private async sendDistrictCourtUserAssignedNotifications( + theCase: Case, + userRole: UserRole.DISTRICT_COURT_JUDGE | UserRole.DISTRICT_COURT_REGISTRAR, + ): Promise { + const recipient = + await this.sendCourtOfficialAssignedEmailNotificationForIndictmentCase( + theCase, + userRole, + ) + + return await this.recordNotification( + theCase.id, + userRole === UserRole.DISTRICT_COURT_JUDGE + ? CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED + : CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED, + [recipient], + ) + } //#endregion //#region RULING notifications @@ -2552,6 +2595,16 @@ export class CaseNotificationService extends BaseNotificationService { return this.sendReceivedByCourtNotifications(theCase) case CaseNotificationType.COURT_DATE: return this.sendCourtDateNotifications(theCase, user) + case CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED: + return this.sendDistrictCourtUserAssignedNotifications( + theCase, + UserRole.DISTRICT_COURT_JUDGE, + ) + case CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED: + return this.sendDistrictCourtUserAssignedNotifications( + theCase, + UserRole.DISTRICT_COURT_REGISTRAR, + ) case CaseNotificationType.RULING: return this.sendRulingNotifications(theCase) case CaseNotificationType.MODIFIED: diff --git a/libs/judicial-system/types/src/lib/notification.ts b/libs/judicial-system/types/src/lib/notification.ts index 347cef7b5852..ee863976b056 100644 --- a/libs/judicial-system/types/src/lib/notification.ts +++ b/libs/judicial-system/types/src/lib/notification.ts @@ -3,6 +3,8 @@ export enum CaseNotificationType { READY_FOR_COURT = 'READY_FOR_COURT', RECEIVED_BY_COURT = 'RECEIVED_BY_COURT', COURT_DATE = 'COURT_DATE', + DISTRICT_COURT_JUDGE_ASSIGNED = 'DISTRICT_COURT_JUDGE_ASSIGNED', + DISTRICT_COURT_REGISTRAR_ASSIGNED = 'DISTRICT_COURT_REGISTRAR_ASSIGNED', RULING = 'RULING', MODIFIED = 'MODIFIED', REVOKED = 'REVOKED', From 8aa0e52a9dfd19ad27258eb3d94c45a629e2d351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sn=C3=A6r=20Seljan=20=C3=9E=C3=B3roddsson?= Date: Mon, 16 Dec 2024 12:40:15 +0000 Subject: [PATCH 27/32] fix(services-bff): Add missing exp check on the user endpoint (#17247) * fix(user): enhance token refresh logic with expiration check Add a utility function to check if the access token has expired before attempting to refresh it. This change improves the efficiency of the token refresh process by ensuring that refresh operations are only triggered when necessary. * test: enhance user token refresh logic in tests Add tests to verify token refresh behavior based on token expiration and refresh query parameter. Ensure that the refreshToken service is called only when the token exists, is expired, and refresh is set to true. This improves test coverage and ensures correct handling of token refresh scenarios. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../app/modules/user/user.controller.spec.ts | 112 ++++++++++++++++++ .../bff/src/app/modules/user/user.service.ts | 7 +- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/apps/services/bff/src/app/modules/user/user.controller.spec.ts b/apps/services/bff/src/app/modules/user/user.controller.spec.ts index dba1a6918e0a..a6dfc9d72ef6 100644 --- a/apps/services/bff/src/app/modules/user/user.controller.spec.ts +++ b/apps/services/bff/src/app/modules/user/user.controller.spec.ts @@ -230,5 +230,117 @@ describe('UserController', () => { profile: expiredTokenResponse.userProfile, }) }) + + it('should not refresh token when token exists but is not expired', async () => { + // Arrange - Set up login attempt in cache + mockCacheStore.set( + `attempt::${mockConfig.name}::${SID_VALUE}`, + createLoginAttempt(mockConfig), + ) + + // Initialize session + await server.get('/login') + await server + .get('/callbacks/login') + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + .query({ code: 'some_code', state: SID_VALUE }) + + // Set valid (not expired) token in cache + const validTokenResponse = { + ...mockCachedTokenResponse, + accessTokenExp: Date.now() + 1000, // Future expiration + } + mockCacheStore.set( + `current::${mockConfig.name}::${SID_VALUE}`, + validTokenResponse, + ) + + // Act + const res = await server + .get('/user') + .query({ refresh: 'true' }) + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + + // Assert + expect(mockTokenRefreshService.refreshToken).not.toHaveBeenCalled() + expect(res.status).toEqual(HttpStatus.OK) + expect(res.body).toEqual({ + scopes: validTokenResponse.scopes, + profile: validTokenResponse.userProfile, + }) + }) + + it('should refresh token only when all conditions are met (token exists, is expired, and refresh=true)', async () => { + // Arrange - Set up login attempt in cache + mockCacheStore.set( + `attempt::${mockConfig.name}::${SID_VALUE}`, + createLoginAttempt(mockConfig), + ) + + const testCases = [ + { + exists: true, + expired: true, + refresh: true, + shouldCallRefresh: true, + }, + { + exists: true, + expired: true, + refresh: false, + shouldCallRefresh: false, + }, + { + exists: true, + expired: false, + refresh: true, + shouldCallRefresh: false, + }, + { + exists: false, + expired: true, + refresh: true, + shouldCallRefresh: false, + }, + ] + + for (const testCase of testCases) { + // Reset mocks + jest.clearAllMocks() + mockCacheStore.clear() + + if (testCase.exists) { + const tokenResponse = { + ...mockCachedTokenResponse, + accessTokenExp: testCase.expired + ? Date.now() - 1000 // Expired + : Date.now() + 1000, // Not expired + } + mockCacheStore.set( + `current::${mockConfig.name}::${SID_VALUE}`, + tokenResponse, + ) + } + + // Act + const res = await server + .get('/user') + .query({ refresh: testCase.refresh.toString() }) + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + + // Assert + if (testCase.shouldCallRefresh) { + expect(mockTokenRefreshService.refreshToken).toHaveBeenCalled() + } else { + expect(mockTokenRefreshService.refreshToken).not.toHaveBeenCalled() + } + + if (testCase.exists) { + expect(res.status).toEqual(HttpStatus.OK) + } else { + expect(res.status).toEqual(HttpStatus.UNAUTHORIZED) + } + } + }) }) }) diff --git a/apps/services/bff/src/app/modules/user/user.service.ts b/apps/services/bff/src/app/modules/user/user.service.ts index 4babb4df7a4e..74f576a5d8aa 100644 --- a/apps/services/bff/src/app/modules/user/user.service.ts +++ b/apps/services/bff/src/app/modules/user/user.service.ts @@ -5,6 +5,7 @@ import { BffUser } from '@island.is/shared/types' import { SESSION_COOKIE_NAME } from '../../constants/cookies' import { ErrorService } from '../../services/error.service' +import { hasTimestampExpiredInMS } from '../../utils/has-timestamp-expired-in-ms' import { CachedTokenResponse } from '../auth/auth.types' import { TokenRefreshService } from '../auth/token-refresh.service' import { CacheService } from '../cache/cache.service' @@ -58,7 +59,11 @@ export class UserService { false, ) - if (cachedTokenResponse && refresh) { + if ( + cachedTokenResponse && + hasTimestampExpiredInMS(cachedTokenResponse.accessTokenExp) && + refresh + ) { cachedTokenResponse = await this.tokenRefreshService.refreshToken({ sid, encryptedRefreshToken: cachedTokenResponse.encryptedRefreshToken, From 3314c57c5bd40570899c1ee0fb5f7d22dab2b960 Mon Sep 17 00:00:00 2001 From: norda-gunni <161026627+norda-gunni@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:12:04 +0000 Subject: [PATCH 28/32] feat(application-system): Add phone and email fields to tablerepeater (#17219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial field and validation * feat(ExampleForm): Update table repeater field and validation schema - Renamed 'rentalHousingLandlordInfoTable' to 'tableRepeaterField' in ExampleForm. - Updated ExampleSchema to include validation for the new 'tableRepeaterField' structure. - Enhanced NationalIdWithName component to accept phone and email default values. - Refactored error handling in NationalIdWithName for better validation feedback. - Cleaned up unused code in TableRepeaterFormField for improved readability. * fix lint * cleanup * Error message cleanup * cleanup * Refine dataschema * PR comment * Fix field layout * Cleanup types * Revert example form changes * Update libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx Add suggestion from jonni Co-authored-by: Jónas G. Sigurðsson --------- Co-authored-by: Jónas G. Sigurðsson Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../reference-template/src/lib/dataSchema.ts | 14 ++ libs/application/types/src/lib/Fields.ts | 6 + .../NationalIdWithName/NationalIdWithName.tsx | 202 ++++++++++++------ 3 files changed, 153 insertions(+), 69 deletions(-) diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index faa3b728cff4..e4945ef27981 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -15,6 +15,20 @@ const careerHistoryCompaniesValidation = (data: any) => { } export const ExampleSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), + tableRepeaterField: z.array( + z.object({ + nationalIdWithName: z.object({ + name: z.string().min(1).max(256), + nationalId: z.string().refine((n) => n && kennitala.isValid(n), { + params: m.dataSchemeNationalId, + }), + phone: z.string().refine(isValidNumber, { + params: m.dataSchemePhoneNumber, + }), + email: z.string().email(), + }), + }), + ), person: z.object({ name: z.string().min(1).max(256), age: z.string().refine((x) => { diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts index fafd82964b7c..24a2c9ac8884 100644 --- a/libs/application/types/src/lib/Fields.ts +++ b/libs/application/types/src/lib/Fields.ts @@ -89,6 +89,8 @@ export type RepeaterItem = { */ displayInTable?: boolean label?: StaticText + phoneLabel?: StaticText + emailLabel?: StaticText placeholder?: StaticText options?: TableRepeaterOptions backgroundColor?: 'blue' | 'white' @@ -99,6 +101,10 @@ export type RepeaterItem = { activeField?: Record, ) => boolean dataTestId?: string + showPhoneField?: boolean + phoneRequired?: boolean + showEmailField?: boolean + emailRequired?: boolean readonly?: | boolean | (( diff --git a/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx b/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx index fb42f7b19422..e2786a44a3bd 100644 --- a/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx +++ b/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx @@ -1,11 +1,7 @@ import { FC, useEffect, useState } from 'react' import { GridRow, GridColumn } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' -import { - coreErrorMessages, - getErrorViaPath, - getValueViaPath, -} from '@island.is/application/core' +import { coreErrorMessages, getValueViaPath } from '@island.is/application/core' import { Application, StaticText } from '@island.is/application/types' import { gql, useLazyQuery } from '@apollo/client' import { @@ -13,7 +9,10 @@ import { Query, RskCompanyInfoInput, } from '@island.is/api/schema' -import { InputController } from '@island.is/shared/form-fields' +import { + InputController, + PhoneInputController, +} from '@island.is/shared/form-fields' import { useFormContext } from 'react-hook-form' import * as kennitala from 'kennitala' import debounce from 'lodash/debounce' @@ -27,14 +26,23 @@ interface NationalIdWithNameProps { customId?: string customNationalIdLabel?: StaticText customNameLabel?: StaticText + phoneLabel?: StaticText + emailLabel?: StaticText + phoneRequired?: boolean + emailRequired?: boolean onNationalIdChange?: (s: string) => void onNameChange?: (s: string) => void nationalIdDefaultValue?: string nameDefaultValue?: string + phoneDefaultValue?: string + emailDefaultValue?: string errorMessage?: string minAgePerson?: number searchPersons?: boolean searchCompanies?: boolean + showPhoneField?: boolean + showEmailField?: boolean + error?: string } export const NationalIdWithName: FC< @@ -46,19 +54,30 @@ export const NationalIdWithName: FC< required, customId = '', customNationalIdLabel = '', + phoneLabel = '', + emailLabel = '', + phoneRequired = false, + emailRequired = false, customNameLabel = '', onNationalIdChange, onNameChange, nationalIdDefaultValue, nameDefaultValue, + phoneDefaultValue, + emailDefaultValue, errorMessage, minAgePerson, searchPersons = true, searchCompanies = false, + showPhoneField = false, + showEmailField = false, + error, }) => { const fieldId = customId.length > 0 ? customId : id const nameField = `${fieldId}.name` const nationalIdField = `${fieldId}.nationalId` + const emailField = `${fieldId}.email` + const phoneField = `${fieldId}.phone` const { formatMessage } = useLocale() const { @@ -69,12 +88,18 @@ export const NationalIdWithName: FC< const [personName, setPersonName] = useState('') const [companyName, setCompanyName] = useState('') - // get name validation errors - const nameFieldErrors = errorMessage - ? nameDefaultValue?.length === 0 - ? errorMessage - : undefined - : getErrorViaPath(errors, nameField) + const getFieldErrorString = ( + error: unknown, + id: string, + ): string | undefined => { + if (!error || typeof error !== 'object') return undefined + + const errorList = error as Record[] + if (!Array.isArray(errorList)) return undefined + + const fieldError = errorList[id as any] + return typeof fieldError === 'string' ? fieldError : undefined + } // get national id validation errors let nationalIdFieldErrors: string | undefined @@ -91,7 +116,7 @@ export const NationalIdWithName: FC< { minAge: minAgePerson }, ) } else if (!errorMessage) { - nationalIdFieldErrors = getErrorViaPath(errors, nationalIdField) + nationalIdFieldErrors = getFieldErrorString(error, 'nationalId') } // get default values @@ -101,6 +126,12 @@ export const NationalIdWithName: FC< const defaultName = nameDefaultValue ? nameDefaultValue : getValueViaPath(application.answers, nameField, '') + const defaultPhone = phoneDefaultValue + ? phoneDefaultValue + : getValueViaPath(application.answers, phoneField, '') + const defaultEmail = emailDefaultValue + ? emailDefaultValue + : getValueViaPath(application.answers, emailField, '') // query to get name by national id const [getIdentity, { data, loading: queryLoading, error: queryError }] = @@ -180,62 +211,95 @@ export const NationalIdWithName: FC< }, [personName, companyName, setValue, nameField, application.answers]) return ( - - - { - setNationalIdInput(v.target.value.replace(/\W/g, '')) - onNationalIdChange && - onNationalIdChange(v.target.value.replace(/\W/g, '')) - })} - loading={searchPersons ? queryLoading : companyQueryLoading} - error={nationalIdFieldErrors} - disabled={disabled} - /> - - - + + + { + setNationalIdInput(v.target.value.replace(/\W/g, '')) + onNationalIdChange && + onNationalIdChange(v.target.value.replace(/\W/g, '')) + })} + loading={searchPersons ? queryLoading : companyQueryLoading} + error={nationalIdFieldErrors} + disabled={disabled} + /> + + + - - + } + disabled + /> + + + {(showPhoneField || showEmailField) && ( + + {showPhoneField && ( + + + + )} + {showEmailField && ( + + + + )} + + )} + ) } From 271e5d2354358e14dfcf8a3610830f805b419145 Mon Sep 17 00:00:00 2001 From: helgifr Date: Mon, 16 Dec 2024 13:44:03 +0000 Subject: [PATCH 29/32] feat(new-primary-school): Add mock users for testing application hotfix (#17220) * feat(new-primary-school): Add mock users for testing application * remove console log * Removed mock user file --------- Co-authored-by: hfhelgason Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../new-primary-school.service.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts index 80ce338d5cd2..15b415938eec 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts @@ -13,6 +13,7 @@ import { TemplateApiModuleActionProps } from '../../../types' import { BaseTemplateApiService } from '../../base-template-api.service' import { transformApplicationToNewPrimarySchoolDTO } from './new-primary-school.utils' import { isRunningOnEnvironment } from '@island.is/shared/utils' +import { isRunningInProduction } from '../parental-leave/constants' @Injectable() export class NewPrimarySchoolService extends BaseTemplateApiService { @@ -38,6 +39,66 @@ export class NewPrimarySchoolService extends BaseTemplateApiService { } async getChildren({ auth }: TemplateApiModuleActionProps) { + if (!isRunningInProduction) { + if (auth.nationalId === '0101303019') { + return [ + { + nationalId: '1111111119', + fullName: 'Stubbur Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + if (auth.nationalId === '0101302989') { + return [ + { + nationalId: '2222222229', + fullName: 'Stúfur Maack ', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + otherParent: { + nationalId: '0101302399', + fullName: 'Gervimaður Færeyjar', + address: { + streetName: 'Hvassaleiti 5', + postalCode: '103', + city: 'Reykjavík', + municipalityCode: '0000', + }, + genderCode: '2', + }, + }, + { + nationalId: '5555555559', + fullName: 'Bína Maack ', + genderCode: '4', + livesWithApplicant: true, + livesWithBothParents: true, + }, + { + nationalId: '6666666669', + fullName: 'Snúður Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + if (auth.nationalId === '0101304929') { + return [ + { + nationalId: '6666666669', + fullName: 'Snúður Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + } const children = await this.nationalRegistryService.getChildrenCustodyInformation(auth) From 0c7df8f3604c0a08e9329b881e1ba2a4618baf7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:23:51 +0000 Subject: [PATCH 30/32] feat(web): Pension Calculator - Display icon to left of title for 2025 preview (#17251) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../PensionCalculator.css.ts | 4 ++ .../PensionCalculator.tsx | 33 ++++++-------- .../PensionCalculatorResults.tsx | 33 ++++++-------- .../PensionCalculatorTitle.tsx | 45 +++++++++++++++++++ .../translationStrings.ts | 7 +++ 5 files changed, 82 insertions(+), 40 deletions(-) create mode 100644 apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts index 66a268028923..8550d211f92b 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts @@ -46,3 +46,7 @@ export const yearSelectContainer = style({ md: { width: '204px' }, }), }) + +export const noWrap = style({ + flexWrap: 'nowrap', +}) diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx index 143a47f3b0de..2dfab0c78d4e 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx @@ -50,6 +50,7 @@ import { GET_ORGANIZATION_PAGE_QUERY, GET_ORGANIZATION_QUERY, } from '../../queries' +import { PensionCalculatorTitle } from './PensionCalculatorTitle' import { PensionCalculatorWrapper } from './PensionCalculatorWrapper' import { translationStrings } from './translationStrings' import { @@ -554,16 +555,12 @@ const PensionCalculator: CustomScreen = ({ > - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage(translationStrings.isTurnedOff)}
@@ -584,16 +581,12 @@ const PensionCalculator: CustomScreen = ({ - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} +
= ({ > - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage(translationStrings.isTurnedOff)} @@ -391,16 +388,12 @@ const PensionCalculatorResults: CustomScreen = ({ - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage( diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx new file mode 100644 index 000000000000..4a61eb3b61fb --- /dev/null +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx @@ -0,0 +1,45 @@ +import { useIntl } from 'react-intl' + +import { GridColumn, GridRow, Text } from '@island.is/island-ui/core' + +import { translationStrings } from './translationStrings' +import * as styles from './PensionCalculator.css' + +interface PensionCalculatorTitleProps { + isNewSystemActive: boolean + title: string + titlePostfix: string + titleVariant: 'h1' | 'h2' +} + +export const PensionCalculatorTitle = ({ + isNewSystemActive, + title, + titlePostfix, + titleVariant, +}: PensionCalculatorTitleProps) => { + const { formatMessage } = useIntl() + if (isNewSystemActive) + return ( + + + + + + + {title}
{titlePostfix}
+
+
+
+ ) + return ( + + {title} {titlePostfix} + + ) +} diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts index 8a273868f14b..89f5b13b9202 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts @@ -625,6 +625,13 @@ export const translationStrings = defineMessages({ defaultMessage: 'Eftir 1. september 2025', description: 'Eftir 1. september 2025', }, + after1stSeptember2025IconUrl: { + id: 'web.pensionCalculator:after1stSeptember2025IconUrl', + defaultMessage: + 'https://images.ctfassets.net/8k0h54kbe6bj/5RIwKVet87Nm4ycltkzjnX/9c594855a9b2f90dde63766ee87a09ca/58dd40fbf365769d984be22a9b64bc29.png', + description: + 'Mynd vinstra megin við titil "Reiknivél örorku- og endurhæfingargreiðslna eftir 1. september 2025"', + }, after1stSeptember2025Calculate: { id: 'web.pensionCalculator:after1stSeptember2025Calculate', defaultMessage: 'Reikna', From 65767dcb54a01134fb1c6d12c40268fb28d81eed Mon Sep 17 00:00:00 2001 From: Ylfa <55542991+ylfahfa@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:35:22 +0000 Subject: [PATCH 31/32] feat(income-plan): Remove edit function after submission (#17246) * remove edit function after submission * format * remove unit test --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../income-plan/src/fields/Review/index.tsx | 15 --------------- .../src/lib/IncomePlanTemplate.spec.ts | 17 ----------------- .../income-plan/src/lib/IncomePlanTemplate.ts | 8 -------- .../income-plan/src/lib/messages.ts | 11 ++--------- 4 files changed, 2 insertions(+), 49 deletions(-) diff --git a/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx b/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx index 9a420ccf1e56..4dbb1ffe6f0c 100644 --- a/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx +++ b/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx @@ -126,21 +126,6 @@ export const Review: FC = ({
- {state === `${States.TRYGGINGASTOFNUN_SUBMITTED}` && ( - - )}