From e947ab4b3946d47fd4108c2b3a30187bb7288c14 Mon Sep 17 00:00:00 2001 From: Daniel Appelgren Date: Fri, 12 Nov 2021 09:28:42 +0100 Subject: [PATCH] =?UTF-8?q?feature(Slutredovisning):=20Formul=C3=A4r=20f?= =?UTF-8?q?=C3=B6r=20att=20skapa=20och=20skicka=20in=20slutredovisning=20(?= =?UTF-8?q?TV-533)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Squashed commit of the following: commit 5b427cdd62b881cc32d408beaf92f8e3c22a9bd4 Author: Daniel Appelgren Date: Fri Nov 12 09:24:18 2021 +0100 refactor commit b51af1b25b573a3203f3dd7e8e1c3e1401f0d228 Author: Daniel Appelgren Date: Fri Nov 12 09:20:58 2021 +0100 add yrke names commit 1ed3a33fb997669bf1af0be52347b371af0177ba Merge: 4d9d2522 0235f1f9 Author: Daniel Appelgren Date: Fri Nov 12 07:40:48 2021 +0100 Merge branch 'develop' into feature/tv-533-Skapa-slutredovisning-2 # Conflicts: # apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts commit 4d9d25226fc3b91386832b1367edcf016d336c03 Author: Erik Tiekstra Date: Thu Nov 11 16:34:24 2021 +0100 Fixed switch functionality inside slutredovisning model commit cce93c169e39bba681e4e25f511fa42686134f97 Merge: b56ce52f 51ed2e84 Author: Erik Tiekstra Date: Thu Nov 11 16:15:46 2021 +0100 Fixed conflicts and added deltid percent commit 51ed2e841e00e8d7cea9225bd9cfeab8b783efbd Author: Daniel Appelgren Date: Thu Nov 11 14:49:40 2021 +0100 hide description on step 1 and 2 commit 269708be2f7fec84815b3e7f91e33d4c305b0846 Author: Daniel Appelgren Date: Thu Nov 11 14:04:59 2021 +0100 cleanup commit 05df3acf97f6115ec15cd295c1ed12721592f867 Merge: 3c803f38 c6adc71f Author: Daniel Appelgren Date: Thu Nov 11 13:47:22 2021 +0100 Merge branch 'develop' into feature/tv-533-Skapa-slutredovisning-2 commit 3c803f3883b23065c2e0c15f6946213e5972576b Merge: c2724aa6 f332dd41 Author: Daniel Appelgren Date: Thu Nov 11 12:38:53 2021 +0100 Merge branch 'develop' into feature/tv-533-Skapa-slutredovisning-2 # Conflicts: # apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/components/reports-list/reports-list.component.ts # apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts commit c2724aa654483001d48ca1c2d0a5bfc1b2552c89 Author: Daniel Appelgren Date: Thu Nov 11 12:22:05 2021 +0100 add loader commit b97b45fb22260dbdc9f9792e027b7bda68150ead Author: Daniel Appelgren Date: Thu Nov 11 12:09:09 2021 +0100 move formgroups to parent to persist stat commit 37feaab19309777ef96fb70be62ede9e26498b89 Author: Daniel Appelgren Date: Thu Nov 11 10:43:53 2021 +0100 fix radiobuttons commit 644b9fd6288589cc3a66ceb8beefb623345e4308 Author: Daniel Appelgren Date: Thu Nov 11 09:30:31 2021 +0100 . commit 28875f21a381a966054523ff7ccb7df126b30120 Author: Daniel Appelgren Date: Thu Nov 11 08:20:07 2021 +0100 move submit logic to step3 commit eef52c39dd970abbedc413b4c348098e07abe036 Author: Daniel Appelgren Date: Thu Nov 11 07:40:56 2021 +0100 submit button commit 4d732240e0ff6196d827572ff865392d6aaa0a9c Author: Daniel Appelgren Date: Wed Nov 10 12:47:43 2021 +0100 fix some bugs commit 642cc2b24fd3a5def8abb9ae45595d101ccdcfb7 Merge: c4d53407 2dc56685 Author: Daniel Appelgren Date: Wed Nov 10 12:24:18 2021 +0100 Merge branch 'develop' into feature/tv-533-Skapa-slutredovisning-2 commit c4d53407399d695f58e5a0be074d81bbc1b1cb21 Author: Daniel Appelgren Date: Wed Nov 10 12:24:09 2021 +0100 wip commit 808810699850e611ead2ee7ed1b728acc3d93dd5 Author: Daniel Appelgren Date: Wed Nov 10 12:02:01 2021 +0100 slutredovisning commit fa446717acc66e779ecdb87ba7a5b2224eeca9fe Author: Daniel Appelgren Date: Wed Nov 10 11:00:44 2021 +0100 view for utbildning done ... and 64 more commits --- .../report-layout.component.html | 2 +- .../report-layout/report-layout.component.ts | 1 + ...isning-view-description-list.component.css | 0 ...sning-view-description-list.component.html | 79 + ...ng-view-description-list.component.spec.ts | 25 + ...visning-view-description-list.component.ts | 65 + ...edovisning-view-description-list.module.ts | 15 + .../deltagare-details.module.ts | 20 + .../reports-list/reports-list.component.ts | 2 + .../deltagare-tab-reports.component.html | 7 + .../deltagare-tab-reports.component.ts | 3 + .../models/slutredovisning-form-data.model.ts | 68 + ...isning-form-step0-education.component.html | 46 + ...isning-form-step0-education.component.scss | 14 + ...ing-form-step0-education.component.spec.ts | 24 + ...ovisning-form-step0-education.component.ts | 102 + ...ovisning-form-step0-education.validator.ts | 26 + ...edovisning-form-step0-other.component.html | 13 + ...edovisning-form-step0-other.component.scss | 26 + ...visning-form-step0-other.component.spec.ts | 24 + ...tredovisning-form-step0-other.component.ts | 51 + ...form-step0-still-unemployed.component.html | 36 + ...form-step0-still-unemployed.component.scss | 26 + ...m-step0-still-unemployed.component.spec.ts | 24 + ...g-form-step0-still-unemployed.component.ts | 97 + ...g-form-step0-still-unemployed.validator.ts | 41 + ...edovisning-form-step0-work-errors.model.ts | 8 + ...redovisning-form-step0-work.component.html | 111 + ...redovisning-form-step0-work.component.scss | 30 + ...ovisning-form-step0-work.component.spec.ts | 23 + ...utredovisning-form-step0-work.component.ts | 116 + .../slutredovisning-form-step0-work.model.ts | 10 + ...utredovisning-form-step0-work.validator.ts | 69 + .../slutredovisning-form-step0.component.html | 50 + .../slutredovisning-form-step0.component.scss | 7 + ...utredovisning-form-step0.component.spec.ts | 24 + .../slutredovisning-form-step0.component.ts | 87 + .../slutredovisning-form-step1.component.html | 35 + .../slutredovisning-form-step1.component.scss | 6 + ...utredovisning-form-step1.component.spec.ts | 24 + .../slutredovisning-form-step1.component.ts | 83 + .../slutredovisning-form-step2.component.html | 47 + .../slutredovisning-form-step2.component.scss | 13 + ...utredovisning-form-step2.component.spec.ts | 24 + .../slutredovisning-form-step2.component.ts | 65 + .../slutredovisning-form-step3.component.html | 52 + .../slutredovisning-form-step3.component.scss | 18 + ...utredovisning-form-step3.component.spec.ts | 25 + .../slutredovisning-form-step3.component.ts | 71 + .../slutredovisning-form.component.html | 95 + .../slutredovisning-form.component.scss | 19 + .../slutredovisning-form.component.spec.ts | 40 + .../slutredovisning-form.component.ts | 136 ++ .../slutredovisning-form.model.ts | 1 + .../slutredovisning-form.module.ts | 82 + .../slutredovisning-form.service.ts | 76 + .../form-data-to-slutredovisning.util.ts | 94 + .../slutredovisning-view.component.html | 19 + .../slutredovisning-view.component.scss | 31 + .../slutredovisning-view.component.spec.ts | 31 + .../slutredovisning-view.component.ts | 36 + .../slutredovisning-view.module.ts | 29 + .../slutredovisning-view.service.ts | 25 + .../error-list/error-list.component.html | 46 +- .../error-list/error-list.component.ts | 20 +- .../src/app/shared/constants/navigation.ts | 1 + .../src/app/shared/constants/yrken.ts | 2130 +++++++++++++++++ .../directives/anchor-link.directive.ts | 16 +- .../src/app/shared/enums/feature.enum.ts | 1 + .../src/app/shared/enums/report-type.enum.ts | 1 + .../api/slutredovisning.request.model.ts | 68 + .../api/slutredovisning.response.model.ts | 70 + .../models/api/yrkesgrupp.response.model.ts | 5 + .../models/api/yrkesomrade.response.model.ts | 7 + .../shared/models/slutredovisning.model.ts | 108 + .../src/app/shared/models/yrkesgrupp.model.ts | 13 + .../app/shared/models/yrkesomrade.model.ts | 26 + .../services/api/handlingar.api.service.ts | 5 + .../api/slutredovisning.api.service.ts | 43 + .../shared/utils/capitalize-sentence.util.ts | 3 + .../src/environments/active-features.ts | 1 + libs/ui/src/error-list/error-link.model.ts | 4 + .../src/error-list/error-list.component.html | 11 + .../src/error-list/error-list.component.scss | 0 .../error-list/error-list.component.spec.ts | 25 + .../ui/src/error-list/error-list.component.ts | 33 + libs/ui/src/error-list/error-list.module.ts | 11 + libs/ui/src/input/input-type.enum.ts | 16 + libs/ui/src/input/input-variation.enum.ts | 5 + libs/ui/src/input/input.component.html | 23 + libs/ui/src/input/input.component.scss | 8 + libs/ui/src/input/input.component.spec.ts | 23 + libs/ui/src/input/input.component.stories.ts | 16 + libs/ui/src/input/input.component.ts | 100 + libs/ui/src/input/input.module.ts | 11 + .../radiobutton-group.component.html | 3 +- .../radiobutton-group.component.ts | 7 +- libs/ui/src/select/select-option.model.ts | 4 + libs/ui/src/select/select.component.html | 45 + libs/ui/src/select/select.component.scss | 45 + libs/ui/src/select/select.component.spec.ts | 26 + .../ui/src/select/select.component.stories.ts | 16 + libs/ui/src/select/select.component.ts | 111 + libs/ui/src/select/select.module.ts | 11 + .../scripts/deltagare-handelser.js | 1 + 105 files changed, 5624 insertions(+), 44 deletions(-) create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.css create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.module.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/models/slutredovisning-form-data.model.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.validator.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.validator.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work-errors.model.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.model.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.validator.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.model.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.module.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/utils/form-data-to-slutredovisning.util.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.html create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.scss create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.spec.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.module.ts create mode 100644 apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/constants/yrken.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.request.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.response.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/api/yrkesgrupp.response.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/api/yrkesomrade.response.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/slutredovisning.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/yrkesgrupp.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/models/yrkesomrade.model.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts create mode 100644 apps/mina-sidor-fa/src/app/shared/utils/capitalize-sentence.util.ts create mode 100644 libs/ui/src/error-list/error-link.model.ts create mode 100644 libs/ui/src/error-list/error-list.component.html create mode 100644 libs/ui/src/error-list/error-list.component.scss create mode 100644 libs/ui/src/error-list/error-list.component.spec.ts create mode 100644 libs/ui/src/error-list/error-list.component.ts create mode 100644 libs/ui/src/error-list/error-list.module.ts create mode 100644 libs/ui/src/input/input-type.enum.ts create mode 100644 libs/ui/src/input/input-variation.enum.ts create mode 100644 libs/ui/src/input/input.component.html create mode 100644 libs/ui/src/input/input.component.scss create mode 100644 libs/ui/src/input/input.component.spec.ts create mode 100644 libs/ui/src/input/input.component.stories.ts create mode 100644 libs/ui/src/input/input.component.ts create mode 100644 libs/ui/src/input/input.module.ts create mode 100644 libs/ui/src/select/select-option.model.ts create mode 100644 libs/ui/src/select/select.component.html create mode 100644 libs/ui/src/select/select.component.scss create mode 100644 libs/ui/src/select/select.component.spec.ts create mode 100644 libs/ui/src/select/select.component.stories.ts create mode 100644 libs/ui/src/select/select.component.ts create mode 100644 libs/ui/src/select/select.module.ts diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.html index 3d09270..9ebc608 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.html @@ -2,7 +2,7 @@

{{ reportTitle }}

{{description}}

- +
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.ts index e56c875..ada2f50 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/report-layout/report-layout.component.ts @@ -14,4 +14,5 @@ export class ReportLayoutComponent { @Input() startDate: string; @Input() endDate: string; @Input() avrop: Avrop; + @Input() showAvropDetails = true; } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.css b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.css new file mode 100644 index 0000000..e69de29 diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.html new file mode 100644 index 0000000..4297f59 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.html @@ -0,0 +1,79 @@ +

Huvudsysselsättning

+
+
Vilken är deltagarens huvudsakliga sysselsättning just nu?
+
{{mainOccupationName}}
+ + +
Utbildningsnivå
+
{{educationLevel }}
+ +
Beskrivning av Annat
+
{{education.otherExplanation }}
+
+ +
Utbildningens längd
+
{{educationLength }}
+
Inriktning på utbildningen
+
{{education.educationSpecification }}
+
+ + + +
Yrkesområde
+
{{workItem.yrkesomradeName }}
+
Yrkesgrupp
+
{{workItem.yrkesgruppName }}
+
Anställningsform
+
{{workItem.anstallningsform }}
+ +
Beskrivning av Annat
+
{{workItem.otherExplanation }}
+
+ +
Omfattning
+
{{omfattningToString(workItem.omfattning) }}
+
Omfattning i procent
+
{{workItem.omfattningPercent }}
+
+
+ + +
Anledning till att arbetssökanden under tjänstens gång inte nått målet:
+ +
    + +
  • {{capitalizeSentence(reason) }}
  • +
    +
+ + +
Beskrivning av Annat
+
{{stillUnemployed.otherExplanation }}
+
+
+ + +
Förtydling av Annan huvudsysselsättning:
+
{{other.otherExplanation }}
+
+
+ +

Aktiviteter

+
+ +
{{activity.name}}
+
+
{{activity.whatHasBeenDone}}
+
+
+
+ +

Deltagarens framsteg och utveckling

+
+
Beskriv deltagarens framsteg och utveckling under perioden
+
{{slutredovisning.progressDescription}}
+
Information om lämpligt nästa steg för deltagaren
+
{{slutredovisning.nextStepDescription}}
+
Övrig information
+
{{slutredovisning.otherInformation}}
+
diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.spec.ts new file mode 100644 index 0000000..09e5479 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningViewDescriptionListComponent } from './slutredovisning-view-description-list.component'; + +describe('SlutredovisningViewDescriptionListComponent', () => { + let component: SlutredovisningViewDescriptionListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SlutredovisningViewDescriptionListComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningViewDescriptionListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.ts new file mode 100644 index 0000000..43105bf --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.component.ts @@ -0,0 +1,65 @@ +import { Component, Input } from '@angular/core'; +import { + educationLengthToString, + educationLevelToString, + MainOccupation, + mainOccupationToString, + Omfattning, + omfattningToString, + Slutredovisning, +} from '@msfa-models/slutredovisning.model'; +import { capitalizeSentence } from '@msfa-utils/capitalize-sentence.util'; +import { + SlutredovisningResponseMainOccupationEducationDetails, + SlutredovisningResponseMainOccupationOtherDetails, + SlutredovisningResponseMainOccupationStillUnemployedDetails, + SlutredovisningResponseMainOccupationWorkDetails, +} from '@msfa-models/api/slutredovisning.response.model'; + +@Component({ + selector: 'msfa-slutredovisning-view-description-list', + templateUrl: './slutredovisning-view-description-list.component.html', + styleUrls: ['./slutredovisning-view-description-list.component.css'], +}) +export class SlutredovisningViewDescriptionListComponent { + capitalizeSentence = capitalizeSentence; + @Input() slutredovisning: Slutredovisning; + + get mainOccupationName(): string | null { + return mainOccupationToString(this.slutredovisning?.mainOccupation?.type); + } + + get education(): SlutredovisningResponseMainOccupationEducationDetails { + return this.slutredovisning?.mainOccupation?.type === MainOccupation.Education + ? this.slutredovisning.mainOccupation.education + : undefined; + } + + get work(): SlutredovisningResponseMainOccupationWorkDetails[] { + return this.slutredovisning?.mainOccupation?.type === MainOccupation.Work + ? this.slutredovisning.mainOccupation.work + : undefined; + } + + get stillUnemployed(): SlutredovisningResponseMainOccupationStillUnemployedDetails { + return this.slutredovisning?.mainOccupation?.type === MainOccupation.StillUnemployed + ? this.slutredovisning.mainOccupation.stillUnemployed + : undefined; + } + + get other(): SlutredovisningResponseMainOccupationOtherDetails { + return this.slutredovisning?.mainOccupation?.type === MainOccupation.Other + ? this.slutredovisning.mainOccupation.other + : undefined; + } + + get educationLevel(): string { + return educationLevelToString(this.education.educationLevel); + } + get educationLength(): string { + return educationLengthToString(this.education.educationLength); + } + omfattningToString(omfattning: Omfattning): string { + return omfattningToString(omfattning); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.module.ts new file mode 100644 index 0000000..8967d03 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/components/slutredovisning-view-description-list/slutredovisning-view-description-list.module.ts @@ -0,0 +1,15 @@ +import { SlutredovisningViewService } from '../../pages/report-views/slutredovisning-view/slutredovisning-view.service'; +import { UiLoaderModule } from '@ui/loader/loader.module'; +import { CommonModule } from '@angular/common'; +import { UiSkeletonModule } from '@ui/skeleton/skeleton.module'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { SlutredovisningViewDescriptionListComponent } from './slutredovisning-view-description-list.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [SlutredovisningViewDescriptionListComponent], + imports: [CommonModule, UiLoaderModule, UiSkeletonModule], + providers: [SlutredovisningViewService], + exports: [SlutredovisningViewDescriptionListComponent], +}) +export class SlutredovisningViewDescriptionListModule {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts index e334a2c..98058b9 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/deltagare-details.module.ts @@ -110,6 +110,26 @@ activeFeatures.forEach(feature => { } ); break; + case Feature.SLUTREDOVISNING: + routes.push( + { + path: 'slutredovisning', + data: { title: 'Skapa slutredovisning' }, + loadChildren: () => + import('./pages/report-forms/slutredovisning-form/slutredovisning-form.module').then( + m => m.SlutredovisningFormModule + ), + }, + { + path: 'slutredovisning/:handlingId', + data: { title: 'Slutredovisning' }, + loadChildren: () => + import('./pages/report-views/slutredovisning-view/slutredovisning-view.module').then( + m => m.SlutredovisningViewModule + ), + } + ); + break; default: break; } diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/components/reports-list/reports-list.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/components/reports-list/reports-list.component.ts index dae9404..b2462c1 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/components/reports-list/reports-list.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/components/reports-list/reports-list.component.ts @@ -60,6 +60,8 @@ export class ReportsListComponent { return `./avvikelserapport/${report.id}`; case ReportType.PeriodiskRedovisning: return `./periodisk-redovisning/${report.id}`; + case ReportType.Slutredovisning: + return `./slutredovisning/${report.id}`; case ReportType.InformativRapport: case ReportType.InformativRedovisning: return `./informativ-rapport/${report.id}`; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html index 142b2b3..71c9b67 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.html @@ -45,6 +45,13 @@ afText="Informativ rapport" > +
  • + +
  • diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.ts index 8f0a38a..b93f17e 100644 --- a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.ts +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/deltagare-card/components/deltagare-tab-reports/deltagare-tab-reports.component.ts @@ -36,6 +36,9 @@ export class DeltagareTabReportsComponent { get informativRapportButtonVisible(): boolean { return this._activeFeatures.includes(Feature.REPORTING_INFORMATIV_RAPPORT); } + get slutredovisningButtonVisible(): boolean { + return this._activeFeatures.includes(Feature.SLUTREDOVISNING); + } constructor(private activatedRoute: ActivatedRoute, private deltagareApiService: DeltagareApiService) {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/models/slutredovisning-form-data.model.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/models/slutredovisning-form-data.model.ts new file mode 100644 index 0000000..7a2e3a2 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/models/slutredovisning-form-data.model.ts @@ -0,0 +1,68 @@ +import { + Anstallningsform, + EducationLength, + EducationLevel, + MainOccupation, + Omfattning, + StillUnemployedReason, +} from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningFormDataMainOccupationWorkDetails { + yrkesomrade: string; + yrkesgrupp: string; + anstallningsform: Anstallningsform; + otherExplanation: string; + omfattning: Omfattning; + omfattningPercent: number; +} + +export interface SlutredovisningFormDataMainOccupationWork { + type: MainOccupation.Work; + work: SlutredovisningFormDataMainOccupationWorkDetails[]; +} + +export interface SlutredovisningFormDataMainOccupationEducationDetails { + educationLevel: EducationLevel; + otherExplanation: string; + educationLength: EducationLength; + educationSpecification: string; +} + +export interface SlutredovisningFormDataMainOccupationEducation { + type: MainOccupation.Education; + education: SlutredovisningFormDataMainOccupationEducationDetails; +} + +export interface SlutredovisningFormDataMainOccupationOtherDetails { + otherExplanation: string; +} + +export interface SlutredovisningFormDataMainOccupationOther { + type: MainOccupation.Other; + other: SlutredovisningFormDataMainOccupationOtherDetails; +} + +export interface SlutredovisningFormDataMainOccupationStillUnemployedDetails { + reasonsGoalNotReached: StillUnemployedReason[]; + otherExplanation: string; +} + +export interface SlutredovisningFormDataMainOccupationStillUnemployed { + type: MainOccupation.StillUnemployed; + stillUnemployed: SlutredovisningFormDataMainOccupationStillUnemployedDetails; +} + +export type SlutredovisningFormDataMainOccupationDetails = + | SlutredovisningFormDataMainOccupationWork + | SlutredovisningFormDataMainOccupationEducation + | SlutredovisningFormDataMainOccupationOther + | SlutredovisningFormDataMainOccupationStillUnemployed; + +export interface SlutredovisningFormData { + genomforandereferens: number; + mainOccupation: SlutredovisningFormDataMainOccupationDetails; + activities: { id: string; whatHasBeenDone: string; name: string }[]; + progressDescription: string; + nextStepDescription: string; + otherInformation: string; +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.html new file mode 100644 index 0000000..163c720 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.html @@ -0,0 +1,46 @@ +
    +
    + + + + + +
    + + + + + + +
    diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.scss new file mode 100644 index 0000000..6a9f546 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.scss @@ -0,0 +1,14 @@ +@import 'mixins/list'; +@import 'variables/gutters'; + +.slutredovisning-form-step0-education { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + + &__level { + display: flex; + flex-direction: column; + gap: var(--digi--layout--gutter); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.spec.ts new file mode 100644 index 0000000..8757fb5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep0EducationComponent } from './slutredovisning-form-step0-education.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep0EducationComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep0EducationComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep0EducationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.ts new file mode 100644 index 0000000..7d099f0 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component.ts @@ -0,0 +1,102 @@ +import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { RequiredValidator } from '@msfa-validators/required.validator'; +import { SlutredovisningFormStep0Education } from './slutredovisning-form-step0-education.validator'; +import { EducationLength, EducationLevel, MainOccupation } from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningFormStep0EducationFormData { + educationLevel: EducationLevel; + educationLength: EducationLength; + otherExplanation?: string; + educationSpecification: string; +} + +type FormKeys = keyof SlutredovisningFormStep0EducationFormData; + +@Component({ + selector: 'msfa-slutredovisning-form-step0-education', + templateUrl: './slutredovisning-form-step0-education.component.html', + styleUrls: ['./slutredovisning-form-step0-education.component.scss'], +}) +export class SlutredovisningFormStep0EducationComponent implements OnInit { + readonly formGroupKey: MainOccupation = MainOccupation.Education; + @Input() formGroupRef: FormGroup; + + @Input() formData: SlutredovisningFormStep0EducationFormData; + EducationLevel = EducationLevel; + @Input() shouldValidate: boolean; + @Output() nextClick = new EventEmitter(); + @Output() backClick = new EventEmitter(); + + private educationLevelFormControlName: FormKeys = 'educationLevel'; + private educationLengthFormControlName: FormKeys = 'educationLength'; + private otherExplanationFormControlName: FormKeys = 'otherExplanation'; + private educationSpecificationFormControlName: FormKeys = 'educationSpecification'; + + // utbildningsniva + educationLevelOptions: RadiobuttonModel[] = [ + { label: 'Högskola eller universitet', value: EducationLevel.HogskolaEllerUniversitet }, + { label: 'Yrkeshögskola', value: EducationLevel.Yrkeshogskola }, + { label: 'Komvux, gymnasium eller folkhögskola', value: EducationLevel.KomvuxGymnasiumFolkhogskola }, + { + label: 'Vet ej', + value: EducationLevel.VetEj, + }, + { + label: 'Annat', + value: EducationLevel.Annat, + }, + ]; + + // langd_utbildning + educationLengthOptions: RadiobuttonModel[] = [ + { label: 'Upp till ett år', value: EducationLength.UpToOneYear }, + { label: 'Ett år till två år', value: EducationLength.OneToTwoYears }, + { label: 'Två år eller längre', value: EducationLength.OverTwoYears }, + ]; + + formGroup: FormGroup | AbstractControl; + + get educationLevelFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.educationLevelFormControlName); + } + + get educationLengthFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.educationLengthFormControlName); + } + + get otherExplanationFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.otherExplanationFormControlName); + } + get educationSpecificationFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.educationSpecificationFormControlName); + } + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate); + } + + ngOnInit(): void { + if (this.formGroupRef.get(this.formGroupKey)) { + this.formGroup = this.formGroupRef.get(this.formGroupKey); + } else { + this.formGroup = new FormGroup( + { + [this.educationLevelFormControlName]: new FormControl(null, [ + RequiredValidator('Utbildningsnivå är obligatoriskt'), + ]), + [this.otherExplanationFormControlName]: new FormControl(null), + [this.educationLengthFormControlName]: new FormControl(null, [ + RequiredValidator('Utbildningens längd är obligatorisk'), + ]), + [this.educationSpecificationFormControlName]: new FormControl(null, [ + RequiredValidator('Utbildningens inriktning är obligatorisk'), + ]), + }, + [SlutredovisningFormStep0Education.slutredovisningFormStep1EducationIsValid()] + ); + this.formGroupRef.addControl(this.formGroupKey, this.formGroup); + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.validator.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.validator.ts new file mode 100644 index 0000000..77bc1f1 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.validator.ts @@ -0,0 +1,26 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { SlutredovisningFormStep0EducationFormData } from './slutredovisning-form-step0-education.component'; +import { EducationLevel } from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningFormErrors { + needDescriptionOfOther?: string; +} + +export class SlutredovisningFormStep0Education { + static slutredovisningFormStep1EducationIsValid(): ValidatorFn { + return (c: AbstractControl): SlutredovisningFormErrors => { + let errors: SlutredovisningFormErrors = {}; + + const { educationLevel, otherExplanation } = c.value as SlutredovisningFormStep0EducationFormData; + + if (educationLevel === EducationLevel.Annat && (!otherExplanation || otherExplanation?.length <= 0)) { + errors = { + ...errors, + needDescriptionOfOther: 'Ifall Annat är valt som utbildningsnivå krävs en beskrivning.', + }; + } + + return errors; + }; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.html new file mode 100644 index 0000000..3c38d28 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.html @@ -0,0 +1,13 @@ +
    +
    + +
    +
    diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.scss new file mode 100644 index 0000000..cdce882 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.scss @@ -0,0 +1,26 @@ +@import 'mixins/list'; +@import 'variables/gutters'; + +.slutredovisning-report-form-step0-still-unemployed { + max-width: var(--digi--typography--text--max-width); + + &__confirmation, + &__warning, + &__form { + position: relative; + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + } + + &__footer { + display: flex; + flex-direction: column; + gap: var(--digi--layout--gutter); + } + + &__cta-wrapper { + display: flex; + gap: var(--digi--layout--gutter); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.spec.ts new file mode 100644 index 0000000..35c5f99 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep0OtherComponent } from './slutredovisning-form-step0-other.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep0OtherComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep0OtherComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep0OtherComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.ts new file mode 100644 index 0000000..5572384 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component.ts @@ -0,0 +1,51 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { RequiredValidator } from '@msfa-validators/required.validator'; +import { MainOccupation } from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningFormStep0OtherFormData { + otherExplanation: string; +} + +type FormKeys = keyof SlutredovisningFormStep0OtherFormData; + +@Component({ + selector: 'msfa-slutredovisning-form-step0-other', + templateUrl: './slutredovisning-form-step0-other.component.html', + styleUrls: ['./slutredovisning-form-step0-other.component.scss'], +}) +export class SlutredovisningFormStep0OtherComponent implements OnInit { + readonly formGroupKey: MainOccupation = MainOccupation.Other; + @Input() formGroupRef: FormGroup; + + @Input() formData: SlutredovisningFormStep0OtherFormData; + @Input() shouldValidate: boolean; + @Output() nextClick = new EventEmitter(); + @Output() backClick = new EventEmitter(); + + private otherExplanationFormControlName: FormKeys = 'otherExplanation'; + + formGroup: FormGroup | AbstractControl; + + get otherExplanationFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.otherExplanationFormControlName); + } + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate); + } + + ngOnInit(): void { + if (this.formGroupRef.get(this.formGroupKey)) { + this.formGroup = this.formGroupRef.get(this.formGroupKey); + } else { + this.formGroup = new FormGroup({ + [this.otherExplanationFormControlName]: new FormControl( + null, + RequiredValidator('En beskrivning av Annat är obligatoriskt.') + ), + }); + this.formGroupRef.addControl(this.formGroupKey, this.formGroup); + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.html new file mode 100644 index 0000000..a638c8f --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.html @@ -0,0 +1,36 @@ +
    +
    +
    + + + +
    + {{formGroup?.errors?.atLeastOneSelected}} +
    +
    + + +
    +
    diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.scss new file mode 100644 index 0000000..cdce882 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.scss @@ -0,0 +1,26 @@ +@import 'mixins/list'; +@import 'variables/gutters'; + +.slutredovisning-report-form-step0-still-unemployed { + max-width: var(--digi--typography--text--max-width); + + &__confirmation, + &__warning, + &__form { + position: relative; + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + } + + &__footer { + display: flex; + flex-direction: column; + gap: var(--digi--layout--gutter); + } + + &__cta-wrapper { + display: flex; + gap: var(--digi--layout--gutter); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.spec.ts new file mode 100644 index 0000000..d441d1d --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep0StillUnemployedComponent } from './slutredovisning-form-step0-still-unemployed.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep0StillUnemployedComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep0StillUnemployedComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep0StillUnemployedComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.ts new file mode 100644 index 0000000..5cc08ff --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component.ts @@ -0,0 +1,97 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { SlutredovisningFormStep0StillUnemployed } from './slutredovisning-form-step0-still-unemployed.validator'; +import { MainOccupation, StillUnemployedReason } from '@msfa-models/slutredovisning.model'; + +type ReasonCheckboxValues = { [key: string]: boolean }; + +export interface SlutredovisningFormStep0StillUnemployedFormData { + reasonsGoalNotReached: ReasonCheckboxValues; + stillUnemployedExplanation?: string; +} + +type FormKeys = keyof SlutredovisningFormStep0StillUnemployedFormData; + +interface CheckboxModel { + label: string; + formControlName: string; +} + +@Component({ + selector: 'msfa-slutredovisning-form-step0-still-unemployed', + templateUrl: './slutredovisning-form-step0-still-unemployed.component.html', + styleUrls: ['./slutredovisning-form-step0-still-unemployed.component.scss'], +}) +export class SlutredovisningFormStep0StillUnemployedComponent implements OnInit { + readonly formGroupKey: MainOccupation = MainOccupation.StillUnemployed; + @Input() formGroupRef: FormGroup; + + @Input() formData: SlutredovisningFormStep0StillUnemployedFormData; + StillUnemployedReason = StillUnemployedReason; + @Input() shouldValidate: boolean; + @Output() nextClick = new EventEmitter(); + @Output() backClick = new EventEmitter(); + + private stillUnemployedReasonFormControlName: FormKeys = 'reasonsGoalNotReached'; + private stillUnemployedExplanationFormControlName: FormKeys = 'stillUnemployedExplanation'; + + //anledning_mal_ej_uppnatt + stillUnemployedReasonOptions: CheckboxModel[] = [ + { label: 'Saknar relevant utbildning', formControlName: StillUnemployedReason.SaknarRelevantUtbildning }, + { label: 'Saknar arbetslivserfarenhet', formControlName: StillUnemployedReason.SaknarArbetslivserfarenhet }, + { label: 'Saknar nätverk och kontakter', formControlName: StillUnemployedReason.SaknarNatverkOchKontakter }, + { + label: 'Bristande språkkunskaper i svenska', + formControlName: StillUnemployedReason.BristandeSprakkunskaperISvenska, + }, + { + label: 'Konjunkturläget', + formControlName: StillUnemployedReason.KonjukturLaget, + }, + { + label: 'Annat', + formControlName: StillUnemployedReason.Annat, + }, + ]; + + formGroup: FormGroup | AbstractControl; + + get showExplanationTextArea(): boolean { + const reasonsValue: ReasonCheckboxValues | undefined = this.stillUnemployedReasonFormControl + ?.value as ReasonCheckboxValues; + return reasonsValue[StillUnemployedReason.Annat] === true; + } + + get stillUnemployedReasonFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.stillUnemployedReasonFormControlName); + } + + get stillUnemployedReasonDescriptionFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.stillUnemployedExplanationFormControlName); + } + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate); + } + + ngOnInit(): void { + if (this.formGroupRef.get(this.formGroupKey)) { + this.formGroup = this.formGroupRef.get(this.formGroupKey); + } else { + const reasonsFormControls: { [key: string]: AbstractControl } = {}; + + this.stillUnemployedReasonOptions.forEach(reason => { + reasonsFormControls[reason.formControlName] = new FormControl(false); + }); + + this.formGroup = new FormGroup( + { + [this.stillUnemployedReasonFormControlName]: new FormGroup(reasonsFormControls), + [this.stillUnemployedExplanationFormControlName]: new FormControl(null), + }, + [SlutredovisningFormStep0StillUnemployed.slutredovisningFormStep0StillUnemployedIsValid()] + ); + this.formGroupRef.addControl(this.formGroupKey, this.formGroup); + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.validator.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.validator.ts new file mode 100644 index 0000000..4116ac9 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.validator.ts @@ -0,0 +1,41 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { SlutredovisningFormStep0StillUnemployedFormData } from './slutredovisning-form-step0-still-unemployed.component'; +import { StillUnemployedReason } from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningStillUnemployedFormErrors { + needDescriptionOfOther?: string; + atLeastOneSelected?: string; +} + +export class SlutredovisningFormStep0StillUnemployed { + static slutredovisningFormStep0StillUnemployedIsValid(): ValidatorFn { + return (c: AbstractControl): SlutredovisningStillUnemployedFormErrors => { + let errors: SlutredovisningStillUnemployedFormErrors = {}; + + const { + reasonsGoalNotReached, + stillUnemployedExplanation, + } = c.value as SlutredovisningFormStep0StillUnemployedFormData; + + if (Object.values(reasonsGoalNotReached).every(reasonIsChecked => !reasonIsChecked)) { + errors = { + ...errors, + atLeastOneSelected: 'Minst en anledning måste väljas.', + }; + } + + // TODO: Is it required that at least one reason is chosen? Check with Bea and Kia + if ( + reasonsGoalNotReached[StillUnemployedReason.Annat] === true && + (!stillUnemployedExplanation || stillUnemployedExplanation?.length <= 0) + ) { + errors = { + ...errors, + needDescriptionOfOther: 'Ifall Annat är valt som utbildningsnivå krävs en beskrivning.', + }; + } + + return errors; + }; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work-errors.model.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work-errors.model.ts new file mode 100644 index 0000000..50e560f --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work-errors.model.ts @@ -0,0 +1,8 @@ +export interface SlutredovisningFormStep0WorkErrors { + yrkesomrade?: string; + yrkesgrupp?: string; + anstallningsform?: string; + annatAnstallningComment?: string; + omfattning?: string; + omfattningPercent?: string; +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.html new file mode 100644 index 0000000..0324e85 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.html @@ -0,0 +1,111 @@ +
    + + +

    Inom vilket/vilka yrken

    +
    +
    +

    Yrke {{index + 1}}

    + + + Lägg till yrke + + + + Ta bort yrket + +
    + + + + + + + + + + +
    + + +
    +
    +
    +
    +
    diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.scss new file mode 100644 index 0000000..e95c370 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.scss @@ -0,0 +1,30 @@ +@import 'variables/gutters'; + +.slutredovisning-form-step0-work { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + + &__group, + &__fieldset-content { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter; + } + + &__group-header { + display: flex; + gap: $digi--layout--gutter; + align-items: center; + } + + &__heading { + margin: 0; + } + + &__number-input { + ::ng-deep input { + width: auto !important; + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.spec.ts new file mode 100644 index 0000000..7bf5f87 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { SlutredovisningFormStep0WorkComponent } from './slutredovisning-form-step0-work.component'; + +describe('SlutredovisningFormStep0WorkComponent', () => { + let component: SlutredovisningFormStep0WorkComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep0WorkComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep0WorkComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.ts new file mode 100644 index 0000000..dafbe49 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component.ts @@ -0,0 +1,116 @@ +import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; +import { Component, Input, OnInit } from '@angular/core'; +import { FormArray, FormControl, FormGroup } from '@angular/forms'; +import { Anstallningsform, MainOccupation, Omfattning } from '@msfa-models/slutredovisning.model'; +import { Yrkesgrupp } from '@msfa-models/yrkesgrupp.model'; +import { Yrkesomrade } from '@msfa-models/yrkesomrade.model'; +import { capitalizeSentence } from '@msfa-utils/capitalize-sentence.util'; +import { ErrorLink } from '@ui/error-list/error-link.model'; +import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; +import { SlutredovisningFormService } from '../../slutredovisning-form.service'; +import { SlutredovisningFormStep0WorkFormData } from './slutredovisning-form-step0-work.model'; +import { SlutredovisningFormStep0WorkValidator } from './slutredovisning-form-step0-work.validator'; + +@Component({ + selector: 'msfa-slutredovisning-form-step0-work', + templateUrl: './slutredovisning-form-step0-work.component.html', + styleUrls: ['./slutredovisning-form-step0-work.component.scss'], +}) +export class SlutredovisningFormStep0WorkComponent implements OnInit { + readonly formGroupKey: MainOccupation = MainOccupation.Work; + @Input() formGroupRef: FormGroup; + @Input() formData: SlutredovisningFormStep0WorkFormData; + @Input() shouldValidate: boolean; + MainOccupation = MainOccupation; + Anstallningsform = Anstallningsform; + Omfattning = Omfattning; + + yrkesomradeSelectOptions$: Observable = this.slutredovisningFormService.yrkesomraden$; + formArray: FormArray; + + anstallningsformOptions: RadiobuttonModel[] = Object.values(Anstallningsform).map(value => ({ + label: capitalizeSentence(value), + value, + })); + omfattningOptions: RadiobuttonModel[] = Object.values(Omfattning).map(value => ({ + label: capitalizeSentence(value), + value, + })); + + constructor(private slutredovisningFormService: SlutredovisningFormService) {} + + getYrkesgruppSelectOptions$(index: number): Observable { + const yrkesomradeId = this.formArray.controls[index].get('yrkesomrade').value as string; + + return this.yrkesomradeSelectOptions$.pipe( + map(yrkesomraden => + yrkesomradeId + ? yrkesomraden + .filter(yo => yo.value === yrkesomradeId) + .reduce((yrkesgrupper: Yrkesgrupp[], yo: Yrkesomrade) => { + yrkesgrupper.push(...yo.items); + return yrkesgrupper; + }, []) + : null + ) + ); + } + + get errorListErrors(): ErrorLink[] { + const formControlErrors: ErrorLink[] = []; + if (this.shouldValidate) { + this.formArray.controls.forEach(arrayControl => { + if (arrayControl.errors) { + Object.entries(arrayControl.errors).forEach(([key, value]) => { + formControlErrors.push({ + elementId: `slutredovisning-${key}-control`, + text: value as string, + }); + }); + } + }); + } + return formControlErrors; + } + + formControlIsInvalid(formControlName: string, index: number): boolean { + const errors = this.formArray.controls[index].errors; + return errors && errors[formControlName] && this.shouldValidate; + } + + formControlError(formControlName: string, index: number): string { + const errors = this.formArray.controls[index].errors; + return errors && (errors[formControlName] as string); + } + + addNewFormGroupToFormArray(): void { + this.formArray.push( + new FormGroup( + { + yrkesomrade: new FormControl(null), + yrkesgrupp: new FormControl(null), + anstallningsform: new FormControl(null), + annatAnstallningComment: new FormControl(null), + omfattning: new FormControl(null), + omfattningPercent: new FormControl(null), + }, + [SlutredovisningFormStep0WorkValidator.slutredovisningFormStep0WorkIsValid()] + ) + ); + } + + removeGroup(index: number): void { + this.formArray.removeAt(index); + } + + ngOnInit(): void { + if (this.formGroupRef.get(this.formGroupKey)) { + this.formArray = this.formGroupRef.get(this.formGroupKey) as FormArray; + } else { + this.formArray = new FormArray([]); + this.addNewFormGroupToFormArray(); + this.formGroupRef.addControl(this.formGroupKey, this.formArray); + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.model.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.model.ts new file mode 100644 index 0000000..fed71ad --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.model.ts @@ -0,0 +1,10 @@ +export interface SlutredovisningFormStep0WorkFormData { + yrkesomrade: string; + yrkesgrupp: string; + anstallningsform: string; + otherExplanation: string; + omfattning: string; + omfattningPercent: number; +} + +export type FormKeys = keyof SlutredovisningFormStep0WorkFormData; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.validator.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.validator.ts new file mode 100644 index 0000000..ba1032b --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.validator.ts @@ -0,0 +1,69 @@ +import { AbstractControl, ValidatorFn } from '@angular/forms'; +import { Anstallningsform, Omfattning } from '@msfa-models/slutredovisning.model'; +import { SlutredovisningFormStep0WorkErrors } from './slutredovisning-form-step0-work-errors.model'; +import { SlutredovisningFormStep0WorkFormData } from './slutredovisning-form-step0-work.model'; + +export class SlutredovisningFormStep0WorkValidator { + static slutredovisningFormStep0WorkIsValid(): ValidatorFn { + return (c: AbstractControl): SlutredovisningFormStep0WorkErrors => { + let errors: SlutredovisningFormStep0WorkErrors = {}; + const { + yrkesomrade, + yrkesgrupp, + anstallningsform, + otherExplanation, + omfattning, + omfattningPercent, + } = c.value as SlutredovisningFormStep0WorkFormData; + + if (!yrkesomrade) { + errors = { + ...errors, + yrkesomrade: 'Yrkesområde måste väljas', + }; + } + if (yrkesomrade && !yrkesgrupp) { + errors = { + ...errors, + yrkesgrupp: 'Yrkesgrupp måste väljas', + }; + } + if (!anstallningsform) { + errors = { + ...errors, + anstallningsform: 'Anställningsform måste väljas', + }; + } else if (anstallningsform === Anstallningsform.Annat && !otherExplanation) { + errors = { + ...errors, + annatAnstallningComment: 'Beskrivning av annat är obligatorisk om "annat" är vald under anställningsform', + }; + } + if (!omfattning) { + errors = { + ...errors, + omfattning: 'Omfattning måste väljas', + }; + } else if (omfattning === Omfattning.Deltid) { + if (omfattningPercent === undefined || omfattningPercent === null) { + errors = { + ...errors, + omfattningPercent: 'Anställningens omfattning i procent är obligatoriskt', + }; + } else if (omfattningPercent < 1) { + errors = { + ...errors, + omfattningPercent: 'Anställningens omfattning i procent får inte vara mindre än 1% om deltid har valts', + }; + } else if (omfattningPercent > 99) { + errors = { + ...errors, + omfattningPercent: 'Anställningens omfattning i procent får inte vara mer än 99% om deltid har valts', + }; + } + } + + return errors; + }; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.html new file mode 100644 index 0000000..23f3b08 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.html @@ -0,0 +1,50 @@ +

    Huvudsaklig sysselsättning

    + +
    + + + + + + + + + + + + + Vidare till steg 2 +
    diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.scss new file mode 100644 index 0000000..bae0d16 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.scss @@ -0,0 +1,7 @@ +@import 'variables/gutters'; + +.slutredovisning-form-step0 { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.spec.ts new file mode 100644 index 0000000..6812eda --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep0Component } from './slutredovisning-form-step0.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep0Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep0Component], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep0Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.ts new file mode 100644 index 0000000..61a2779 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step0/slutredovisning-form-step0.component.ts @@ -0,0 +1,87 @@ +import { RadiobuttonModel } from '@af/digi-ng/_form/form-radiobutton-group'; +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; +import { RequiredValidator } from '@msfa-validators/required.validator'; +import { BehaviorSubject } from 'rxjs'; +import { SlutredovisningFormStep0EducationFormData } from './slutredovisning-form-step0-education/slutredovisning-form-step0-education.component'; +import { SlutredovisningFormStep0WorkFormData } from './slutredovisning-form-step0-work/slutredovisning-form-step0-work.model'; +import { SlutredovisningFormStep0StillUnemployedFormData } from './slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component'; +import { SlutredovisningFormStep0OtherFormData } from './slutredovisning-form-step0-other/slutredovisning-form-step0-other.component'; +import { MainOccupation } from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningStep0FormData { + mainOccupation: MainOccupation; + education: SlutredovisningFormStep0EducationFormData; + work: SlutredovisningFormStep0WorkFormData[]; + stillUnemployed: SlutredovisningFormStep0StillUnemployedFormData; + other: SlutredovisningFormStep0OtherFormData; +} + +interface MainOccupationWithLabel { + label: string; + key: string; +} + +type FormKeys = keyof SlutredovisningStep0FormData; + +@Component({ + selector: 'msfa-slutredovisning-form-step0', + templateUrl: './slutredovisning-form-step0.component.html', + styleUrls: ['./slutredovisning-form-step0.component.scss'], +}) +export class SlutredovisningFormStep0Component implements OnInit { + shouldValidate$ = new BehaviorSubject(false); + @Output() nextClick = new EventEmitter(); + @Input() formGroup: FormGroup; + MainOccupation = MainOccupation; + + private mainOccupationFormControlName: FormKeys = 'mainOccupation'; + + mainOccupations: MainOccupationWithLabel[] = [ + { label: 'Arbete', key: MainOccupation.Work }, + { label: 'Utbildning', key: MainOccupation.Education }, + { label: 'Fortsatt arbetssökande', key: MainOccupation.StillUnemployed }, + { + label: 'Byte till ny leverantör i rusta och matcha', + key: MainOccupation.ByteTillNyLeverantorIRustaOchMatcha, + }, + { label: 'Annat', key: MainOccupation.Other }, + ]; + + get mainOccupationRadioButtonGroup(): RadiobuttonModel[] { + return this.mainOccupations.map(mainOccupation => ({ label: mainOccupation.label, value: mainOccupation.key })); + } + + get mainOccupationFormControl(): AbstractControl | undefined { + return this.formGroup.get(this.mainOccupationFormControlName); + } + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate$.value); + } + + verifyAndEmitData(): void { + this.mainOccupations + .map(mainOccupations => mainOccupations.key) + .filter(formGroupKey => this.mainOccupationFormControl.value !== formGroupKey) + .forEach(notSelectedFormGroupKey => this.formGroup.removeControl(notSelectedFormGroupKey)); + + this.shouldValidate$.next(true); + markControlsAsDirty(Object.values(this.formGroup.controls)); + this.formGroup.markAllAsTouched(); + + if (this.formGroup.valid) { + this.nextClick.emit(this.formGroup.value); + } + } + + ngOnInit(): void { + if (!this.mainOccupationFormControl) { + this.formGroup.addControl( + this.mainOccupationFormControlName, + new FormControl(null, [RequiredValidator('Val av huvudsysselsättning är obligatoriskt')]) + ); + } + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.html new file mode 100644 index 0000000..1e1e1f1 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.html @@ -0,0 +1,35 @@ +

    Aktiviteter

    +
    + +
    +

    {{activityFormGroup.get('name').value}}

    + +
    + + +
    + + + Tillbaka + + Nästa +
    +
    +
    + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.scss new file mode 100644 index 0000000..0848389 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.scss @@ -0,0 +1,6 @@ +.slutredovisning-report-form-step1 { + &__footer { + display: flex; + justify-content: space-between; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.spec.ts new file mode 100644 index 0000000..18d3997 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep1Component } from './slutredovisning-form-step1.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep1Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep1Component], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep1Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.ts new file mode 100644 index 0000000..cf72053 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step1/slutredovisning-form-step1.component.ts @@ -0,0 +1,83 @@ +import { ChangeDetectorRef, Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; +import { BehaviorSubject } from 'rxjs'; +import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; +import { Activity } from '@msfa-models/activity.model'; +import { SlutredovisningFormService } from '../slutredovisning-form.service'; +import { take } from 'rxjs/operators'; +import { RequiredValidator } from '@msfa-validators/required.validator'; + +export interface SlutredovisningStep1FormData { + activities: { whatHasBeenDone: string; id: string; name: string }[]; +} + +type FormControlNames = keyof SlutredovisningStep1FormData; + +@Component({ + selector: 'msfa-slutredovisning-form-step1', + templateUrl: './slutredovisning-form-step1.component.html', + styleUrls: ['./slutredovisning-form-step1.component.scss'], +}) +export class SlutredovisningFormStep1Component implements OnInit { + readonly ACTIVITES_FORM_NAME: FormControlNames = 'activities'; + shouldValidate$ = new BehaviorSubject(false); + @Output() nextClick = new EventEmitter(); + @Output() backClick = new EventEmitter(); + @Input() genomforandereferens: number; + @Input() formGroup: FormGroup; + + constructor( + private slutredovisningFormService: SlutredovisningFormService, + private changeDetectionRef: ChangeDetectorRef + ) {} + + private clearActivities(): void { + this.activitiesFormArray.clear(); + } + + private addActivityToForm(activity: Activity): void { + this.activitiesFormArray.push( + new FormGroup({ + name: new FormControl(activity.name), + id: new FormControl(activity.id), + whatHasBeenDone: new FormControl('temp', RequiredValidator('Beskrivning är obligatorisk')), + }) + ); + this.changeDetectionRef.detectChanges(); + } + + ngOnInit(): void { + if (!this.activitiesFormArray) { + this.formGroup.addControl(this.ACTIVITES_FORM_NAME, new FormArray([])); + + this.slutredovisningFormService + .getAllChosenActivities(this.genomforandereferens) + .pipe(take(1)) + .subscribe(activities => { + this.clearActivities(); + activities.forEach(activity => this.addActivityToForm(activity)); + }); + } + } + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate$.value); + } + + get activitiesFormArray(): FormArray { + return this.formGroup.get(this.ACTIVITES_FORM_NAME) as FormArray; + } + + verifyAndEmitData(): void { + this.shouldValidate$.next(true); + markControlsAsDirty(Object.values(this.formGroup.controls)); + this.formGroup.markAllAsTouched(); + + if (this.formGroup.valid) { + this.nextClick.emit(this.formGroup.value); + } + } + + goBack(): void { + this.backClick.emit(); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.html new file mode 100644 index 0000000..56784c3 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.html @@ -0,0 +1,47 @@ +

    Deltagarens framsteg och utveckling

    +
    + + + + + + +
    + + + Tillbaka + + Nästa +
    +
    + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.scss new file mode 100644 index 0000000..b42fcef --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.scss @@ -0,0 +1,13 @@ +@import 'variables/gutters'; + +.slutredovisning-report-form-step1 { + &__form { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + } + &__footer { + display: flex; + justify-content: space-between; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.spec.ts new file mode 100644 index 0000000..674e5b4 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.spec.ts @@ -0,0 +1,24 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep2Component } from './slutredovisning-form-step2.component'; + +describe('SlutredovisningFormStep1Component', () => { + let component: SlutredovisningFormStep2Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SlutredovisningFormStep2Component], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep2Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.ts new file mode 100644 index 0000000..c4d3375 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step2/slutredovisning-form-step2.component.ts @@ -0,0 +1,65 @@ +import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; +import { BehaviorSubject } from 'rxjs'; +import { markControlsAsDirty } from '@msfa-utils/mark-controls-as-dirty.util'; +import { RequiredValidator } from '@msfa-validators/required.validator'; + +export interface SlutredovisningStep2FormData { + progressDescription: string; + nextStepDescription: string; + otherInformation: string; +} + +type FormControlNames = keyof SlutredovisningStep2FormData; + +@Component({ + selector: 'msfa-slutredovisning-form-step2', + templateUrl: './slutredovisning-form-step2.component.html', + styleUrls: ['./slutredovisning-form-step2.component.scss'], +}) +export class SlutredovisningFormStep2Component implements OnInit { + readonly framstegFormName: FormControlNames = 'progressDescription'; + readonly nastaStegFormName: FormControlNames = 'nextStepDescription'; + readonly ovrigtFormName: FormControlNames = 'otherInformation'; + shouldValidate$ = new BehaviorSubject(false); + @Output() nextClick = new EventEmitter(); + @Output() backClick = new EventEmitter(); + @Input() formGroup: FormGroup; + @Input() genomforandereferens: number; + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate$.value); + } + + get framstegFormControl(): FormControl { + return this.formGroup.get(this.framstegFormName) as FormControl; + } + get nastaStegFormControl(): FormControl { + return this.formGroup.get(this.nastaStegFormName) as FormControl; + } + get ovrigtFormControl(): FormControl { + return this.formGroup.get(this.ovrigtFormName) as FormControl; + } + + verifyAndEmitData(): void { + this.shouldValidate$.next(true); + markControlsAsDirty(Object.values(this.formGroup.controls)); + this.formGroup.markAllAsTouched(); + + if (this.formGroup.valid) { + this.nextClick.emit(this.formGroup.value); + } + } + + ngOnInit(): void { + if (!this.framstegFormControl) { + this.formGroup.addControl(this.framstegFormName, new FormControl(null, RequiredValidator())); + this.formGroup.addControl(this.nastaStegFormName, new FormControl(null, RequiredValidator())); + this.formGroup.addControl(this.ovrigtFormName, new FormControl(null, RequiredValidator())); + } + } + + goBack(): void { + this.backClick.emit(); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.html new file mode 100644 index 0000000..d5728be --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.html @@ -0,0 +1,52 @@ +
    +

    Förhandsgranskning

    + +
    + +

    Slutredovisning för deltagare {{avrop.fullName}} är nu inskickad till Arbetsförmedlingen.

    +
    +
    Datum
    +
    {{submittedDate | date:'longDate'}} kl {{submittedDate | date:'shortTime'}}
    +
    +
    + Tillbaka till deltagaren +
    + + + + + + +

    Kunde inte skicka in Slutredovisning. Försök igen om en stund.

    +

    {{error.message}}

    +
    + +
    + + + Tillbaka + + Skicka in Slutredovisning +
    +
    +
    + + + + + + + + + + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.scss new file mode 100644 index 0000000..bfb85cc --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.scss @@ -0,0 +1,18 @@ +@import 'variables/gutters'; + +.slutredovisning-report-form-step3 { + &__view { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + } + //&__form { + // display: flex; + // flex-direction: column; + // gap: $digi--layout--gutter--l; + //} + &__footer { + display: flex; + justify-content: space-between; + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.spec.ts new file mode 100644 index 0000000..bb780a5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SlutredovisningFormStep3Component } from './slutredovisning-form-step3.component'; + +describe('SlutredovisningFormStep3Component', () => { + let component: SlutredovisningFormStep3Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ SlutredovisningFormStep3Component ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormStep3Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.ts new file mode 100644 index 0000000..2447ecd --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form-step3/slutredovisning-form-step3.component.ts @@ -0,0 +1,71 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { slutredovisningFormDataToSlutredovisningRequest } from '../utils/form-data-to-slutredovisning.util'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { BehaviorSubject } from 'rxjs'; +import { SlutredovisningFormService } from '../slutredovisning-form.service'; +import { SlutredovisningResponseMainOccupationDetails } from '@msfa-models/api/slutredovisning.response.model'; +import { Avrop } from '@msfa-models/avrop.model'; +import { map } from 'rxjs/operators'; +import { MainOccupation, Slutredovisning } from '@msfa-models/slutredovisning.model'; +import { SlutredovisningFormData } from '../models/slutredovisning-form-data.model'; + +@Component({ + selector: 'msfa-slutredovisning-form-step3', + templateUrl: './slutredovisning-form-step3.component.html', + styleUrls: ['./slutredovisning-form-step3.component.scss'], +}) +export class SlutredovisningFormStep3Component { + @Output() backClick = new EventEmitter(); + @Input() slutredovisningFormData: SlutredovisningFormData; + @Input() avrop: Avrop; + + submitIsLoading$ = new BehaviorSubject(false); + submitError$ = new BehaviorSubject(null); + submittedDate$ = new BehaviorSubject(null); + + slutredovisning$ = this.slutredovisningFormService.yrkeToTextMap$.pipe( + map(yrkeToText => this._appendYrkeNames(this.slutredovisningFormData, yrkeToText)) + ); + + private _appendYrkeNames( + slutredovisningFormData: SlutredovisningFormData, + yrkeToText: { [key: string]: string } + ): Slutredovisning { + if (slutredovisningFormData.mainOccupation.type !== MainOccupation.Work) { + return slutredovisningFormData as Slutredovisning; + } + + const newMainOccupation: SlutredovisningResponseMainOccupationDetails = { + ...slutredovisningFormData.mainOccupation, + work: slutredovisningFormData.mainOccupation.work.map(yrke => ({ + ...yrke, + yrkesomradeName: yrkeToText[yrke.yrkesomrade], + yrkesgruppName: yrkeToText[yrke.yrkesgrupp], + })), + }; + return { ...slutredovisningFormData, mainOccupation: newMainOccupation }; + } + + goBack(): void { + this.backClick.emit(); + } + + constructor(private slutredovisningFormService: SlutredovisningFormService) {} + + submitSlutredovisning(): void { + this.submitIsLoading$.next(true); + + const toBeSubmitted = slutredovisningFormDataToSlutredovisningRequest(this.slutredovisningFormData); + this.slutredovisningFormService.submitSlutredovisning$(toBeSubmitted).subscribe({ + next: () => { + this.submitIsLoading$.next(false); + this.submittedDate$.next(new Date()); + }, + error: (customError: CustomError) => { + this.submitError$.next({ ...customError, message: customError.error.message }); + this.submitIsLoading$.next(false); + throw { ...customError, avoidToast: true }; + }, + }); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.html new file mode 100644 index 0000000..9f1abd8 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.html @@ -0,0 +1,95 @@ + + +
    +
    + +

    {{notAllowedToReportWarning(avrop)}}

    +
    + + Tillbaka till deltagaren +
    + + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.scss new file mode 100644 index 0000000..b9361fe --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.scss @@ -0,0 +1,19 @@ +@import 'variables/gutters'; + +.slutredovisning-form { + max-width: var(--digi--typography--text--max-width); + + &__confirmation, + &__textareas, + &__warning, + &__form { + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + } + + &__cta-wrapper { + display: flex; + gap: var(--digi--layout--gutter); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.spec.ts new file mode 100644 index 0000000..39600d6 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.spec.ts @@ -0,0 +1,40 @@ +import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker'; +import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; +import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; +import { SlutredovisningFormComponent } from './slutredovisning-form.component'; +import { SlutredovisningFormService } from './slutredovisning-form.service'; + +describe('SlutredovisningReportFormComponent', () => { + let component: SlutredovisningFormComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [SlutredovisningFormComponent, LayoutComponent], + imports: [ + RouterTestingModule, + HttpClientTestingModule, + ReactiveFormsModule, + DigiNgFormRadiobuttonGroupModule, + DigiNgFormDatepickerModule, + ], + providers: [SlutredovisningFormService], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningFormComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.ts new file mode 100644 index 0000000..171c1b2 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.component.ts @@ -0,0 +1,136 @@ +import { ChangeDetectionStrategy, Component, OnDestroy } from '@angular/core'; +import { AbstractControl, FormGroup } from '@angular/forms'; +import { ActivatedRoute } from '@angular/router'; +import { Avrop } from '@msfa-models/avrop.model'; +import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs'; +import { map, shareReplay, switchMap } from 'rxjs/operators'; +import { SlutredovisningFormService } from './slutredovisning-form.service'; +import { addDays } from 'date-fns'; +import { SlutredovisningStep } from './slutredovisning-form.model'; +import { SlutredovisningStep0FormData } from './slutredovisning-form-step0/slutredovisning-form-step0.component'; +import { SlutredovisningStep1FormData } from './slutredovisning-form-step1/slutredovisning-form-step1.component'; +import { SlutredovisningStep2FormData } from './slutredovisning-form-step2/slutredovisning-form-step2.component'; +import { formsToSlutredovisningFormData } from './utils/form-data-to-slutredovisning.util'; +import { SlutredovisningFormData } from './models/slutredovisning-form-data.model'; + +interface Params { + genomforandeReferens: string; +} + +@Component({ + selector: 'msfa-slutredovisning-form', + templateUrl: './slutredovisning-form.component.html', + styleUrls: ['./slutredovisning-form.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [SlutredovisningFormService], +}) +export class SlutredovisningFormComponent implements OnDestroy { + totalSteps = 4; + currentStep$ = this.slutredovisningFormService.currentStep$; + showAvropDetails$ = this.currentStep$.pipe(map(step => step === 'step0' || step === 'step3')); + + step0FormGroup: FormGroup = new FormGroup({}); + step1FormGroup: FormGroup = new FormGroup({}); + step2FormGroup: FormGroup = new FormGroup({}); + + step0FormData$: Observable = this.slutredovisningFormService.step0FormData$; + step1FormData$: Observable = this.slutredovisningFormService.step1FormData$; + step2FormData$: Observable = this.slutredovisningFormService.step2FormData$; + + shouldValidate$ = new BehaviorSubject(false); + + genomforandeReferens$: Observable = this.activatedRoute.params.pipe( + map((params: Params) => +params.genomforandeReferens) + ); + + slutredovisningFormData$: Observable = combineLatest([ + this.genomforandeReferens$, + this.step0FormData$, + this.step1FormData$, + this.step2FormData$, + ]).pipe( + map(([genomforandereferens, step0, step1, step2]) => + formsToSlutredovisningFormData(genomforandereferens, step0, step1, step2) + ) + ); + + avrop$: Observable = this.genomforandeReferens$.pipe( + switchMap(genomforandeReferens => this.slutredovisningFormService.fetchAvropInformation$(genomforandeReferens)), + shareReplay(1) + ); + + private subscriptions: Subscription[] = []; + + constructor(private slutredovisningFormService: SlutredovisningFormService, private activatedRoute: ActivatedRoute) {} + + formControlIsInvalid(formControl: AbstractControl): boolean { + return formControl.invalid && (formControl.touched || this.shouldValidate$.value); + } + + openConfirmDialog(): void { + this.shouldValidate$.next(true); + } + + private _isAfterStartDate(startDate: Date): boolean { + return new Date() > startDate; + } + + private _isBeforeLastPossibleReportDay(endDate: Date): boolean { + const lastPossibleReportDay = addDays(endDate, 5); // Reporting is allowed at latest 5 days past avrop end date. + return lastPossibleReportDay > new Date(); + } + + isAllowedToReport(avrop: Avrop): boolean { + return this._isAfterStartDate(avrop.startDate) && this._isBeforeLastPossibleReportDay(avrop.endDate); + } + + notAllowedToReportWarning(avrop: Avrop): string { + if (!this._isBeforeLastPossibleReportDay(avrop.endDate)) { + return 'Det går inte att göra Slutredovisning eftersom tjänsten har avslutats.'; + } + if (!this._isAfterStartDate(avrop.startDate)) { + return 'Det går inte att göra Slutredovisning eftersom tjänsten inte har startat ännu.'; + } + } + + ngOnDestroy(): void { + this.subscriptions.forEach(subscription => subscription.unsubscribe()); + } + + getStepIndex(step: SlutredovisningStep): number { + switch (step) { + case 'step0': + return 0; + case 'step1': + return 1; + case 'step2': + return 2; + case 'step3': + return 3; + } + } + + backFromStep1() { + this.slutredovisningFormService.setStep('step0'); + } + + backFromStep2() { + this.slutredovisningFormService.setStep('step1'); + } + + backFromStep3() { + this.slutredovisningFormService.setStep('step2'); + } + + processStep0Data(formData: SlutredovisningStep0FormData): void { + this.slutredovisningFormService.processStep0Data(formData); + } + + processStep1Data(formData: SlutredovisningStep1FormData) { + this.slutredovisningFormService.processStep1Data(formData); + } + + processStep2Data(formData: SlutredovisningStep2FormData) { + this.slutredovisningFormService.processStep2Data(formData); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.model.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.model.ts new file mode 100644 index 0000000..079cd03 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.model.ts @@ -0,0 +1 @@ +export type SlutredovisningStep = 'step0' | 'step1' | 'step2' | 'step3'; diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.module.ts new file mode 100644 index 0000000..437d578 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.module.ts @@ -0,0 +1,82 @@ +import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog'; +import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker'; +import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; +import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; +import { DigiNgFormRangeModule } from '@af/digi-ng/_form/form-range'; +import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; +import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar'; +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { ReactiveFormsModule } from '@angular/forms'; +import { RouterModule } from '@angular/router'; +import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; +import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module'; +import { IconModule } from '@msfa-shared/components/icon/icon.module'; +import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; +import { UiCheckboxModule } from '@ui/checkbox/checkbox.module'; +import { UiErrorListModule } from '@ui/error-list/error-list.module'; +import { UiInputModule } from '@ui/input/input.module'; +import { UiLoaderModule } from '@ui/loader/loader.module'; +import { UiRadiobuttonGroupModule } from '@ui/radiobutton-group/radiobutton-group.module'; +import { UiSelectModule } from '@ui/select/select.module'; +import { UiSkeletonModule } from '@ui/skeleton/skeleton.module'; +import { UiTextareaModule } from '@ui/textarea/textarea.module'; +import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module'; +import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module'; +import { SlutredovisningViewDescriptionListModule } from '../../../components/slutredovisning-view-description-list/slutredovisning-view-description-list.module'; +import { SlutredovisningFormStep0EducationComponent } from './slutredovisning-form-step0/slutredovisning-form-step0-education/slutredovisning-form-step0-education.component'; +import { SlutredovisningFormStep0OtherComponent } from './slutredovisning-form-step0/slutredovisning-form-step0-other/slutredovisning-form-step0-other.component'; +import { SlutredovisningFormStep0StillUnemployedComponent } from './slutredovisning-form-step0/slutredovisning-form-step0-still-unemployed/slutredovisning-form-step0-still-unemployed.component'; +import { SlutredovisningFormStep0WorkComponent } from './slutredovisning-form-step0/slutredovisning-form-step0-work/slutredovisning-form-step0-work.component'; +import { SlutredovisningFormStep0Component } from './slutredovisning-form-step0/slutredovisning-form-step0.component'; +import { SlutredovisningFormStep1Component } from './slutredovisning-form-step1/slutredovisning-form-step1.component'; +import { SlutredovisningFormStep2Component } from './slutredovisning-form-step2/slutredovisning-form-step2.component'; +import { SlutredovisningFormStep3Component } from './slutredovisning-form-step3/slutredovisning-form-step3.component'; +import { SlutredovisningFormComponent } from './slutredovisning-form.component'; +import { SlutredovisningFormService } from './slutredovisning-form.service'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [ + SlutredovisningFormComponent, + SlutredovisningFormStep0Component, + SlutredovisningFormStep0EducationComponent, + SlutredovisningFormStep0StillUnemployedComponent, + SlutredovisningFormStep1Component, + SlutredovisningFormStep0WorkComponent, + SlutredovisningFormStep1Component, + SlutredovisningFormStep0OtherComponent, + SlutredovisningFormStep2Component, + SlutredovisningFormStep3Component, + ], + imports: [ + CommonModule, + RouterModule.forChild([{ path: '', component: SlutredovisningFormComponent }]), + UiCheckboxModule, + LayoutModule, + ReactiveFormsModule, + DigiNgFormRadiobuttonGroupModule, + UiRadiobuttonGroupModule, + DigiNgFormDatepickerModule, + UiTextareaModule, + DigiNgProgressProgressbarModule, + ReportLayoutModule, + ConfirmDialogModule, + BackLinkModule, + UiSkeletonModule, + DigiNgFormSelectModule, + UiLoaderModule, + UiSelectModule, + ReportDescriptionListModule, + DigiNgFormInputModule, + DigiNgDialogModule, + DigiNgFormRangeModule, + IconModule, + UiErrorListModule, + UiInputModule, + SlutredovisningViewDescriptionListModule, + ], + providers: [SlutredovisningFormService], + exports: [SlutredovisningFormComponent], +}) +export class SlutredovisningFormModule {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts new file mode 100644 index 0000000..76ec493 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/slutredovisning-form.service.ts @@ -0,0 +1,76 @@ +import { Injectable } from '@angular/core'; +import { Activity, mapResponseToActivity } from '@msfa-models/activity.model'; +import { Avrop } from '@msfa-models/avrop.model'; +import { mapResponseToYrkesomrade, Yrkesomrade, yrkeToTextMap } from '@msfa-models/yrkesomrade.model'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { GemensamPlaneringApiService } from '@msfa-services/api/gemensam-planering-api.service'; +import { SlutredovisningApiService } from '@msfa-services/api/slutredovisning.api.service'; +import { BehaviorSubject, Observable } from 'rxjs'; +import { map, shareReplay } from 'rxjs/operators'; +import { SlutredovisningStep0FormData } from './slutredovisning-form-step0/slutredovisning-form-step0.component'; +import { SlutredovisningStep1FormData } from './slutredovisning-form-step1/slutredovisning-form-step1.component'; +import { SlutredovisningStep } from './slutredovisning-form.model'; +import { SlutredovisningStep2FormData } from './slutredovisning-form-step2/slutredovisning-form-step2.component'; +import { SlutredovisningRequest } from '@msfa-models/api/slutredovisning.request.model'; + +@Injectable() +export class SlutredovisningFormService { + private _currentStep$ = new BehaviorSubject('step0'); + currentStep$ = this._currentStep$.asObservable(); + + private _step0FormData$ = new BehaviorSubject(null); + step0FormData$ = this._step0FormData$.asObservable(); + private _step1FormData$ = new BehaviorSubject(null); + step1FormData$ = this._step1FormData$.asObservable(); + + private _step2FormData$ = new BehaviorSubject(null); + + yrkesomraden$: Observable = this.slutredovisningApiService.fetchYrken$().pipe( + map(({ data }) => data.map(yo => mapResponseToYrkesomrade(yo))), + shareReplay(1) + ); + + yrkeToTextMap$: Observable<{ [key: string]: string }> = this.yrkesomraden$.pipe( + map(yrkesomraden => yrkeToTextMap(yrkesomraden)) + ); + + step2FormData$ = this._step2FormData$.asObservable(); + + constructor( + private slutredovisningApiService: SlutredovisningApiService, + private deltagareApiService: DeltagareApiService, + private gemensamPlaneringApiService: GemensamPlaneringApiService + ) {} + setStep(step: SlutredovisningStep) { + this._currentStep$.next(step); + } + + submitSlutredovisning$(slutredovisning: SlutredovisningRequest): Observable { + return this.slutredovisningApiService.submitSlutredovisning$(slutredovisning); + } + + fetchAvropInformation$(genomforandeReferens: number): Observable { + return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); + } + + processStep0Data(formData: SlutredovisningStep0FormData) { + this._step0FormData$.next(formData); + this.setStep('step1'); + } + + processStep1Data(formData: SlutredovisningStep1FormData) { + this._step1FormData$.next(formData); + this.setStep('step2'); + } + + processStep2Data(formData: SlutredovisningStep2FormData) { + this._step2FormData$.next(formData); + this.setStep('step3'); + } + + getAllChosenActivities(genomforandeReferens: number): Observable { + return this.gemensamPlaneringApiService + .fetchAllChosenActivities(genomforandeReferens) + .pipe(map(({ data }) => data.map(activity => mapResponseToActivity(activity)))); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/utils/form-data-to-slutredovisning.util.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/utils/form-data-to-slutredovisning.util.ts new file mode 100644 index 0000000..debf9f6 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-forms/slutredovisning-form/utils/form-data-to-slutredovisning.util.ts @@ -0,0 +1,94 @@ +import { SlutredovisningStep0FormData } from '../slutredovisning-form-step0/slutredovisning-form-step0.component'; +import { SlutredovisningStep1FormData } from '../slutredovisning-form-step1/slutredovisning-form-step1.component'; +import { SlutredovisningStep2FormData } from '../slutredovisning-form-step2/slutredovisning-form-step2.component'; + +import { + Anstallningsform, + MainOccupation, + Omfattning, + StillUnemployedReason, +} from '@msfa-models/slutredovisning.model'; +import { + SlutredovisningRequest, + SlutredovisningRequestMainOccupationDetails, +} from '@msfa-models/api/slutredovisning.request.model'; +import { SlutredovisningFormData } from '../models/slutredovisning-form-data.model'; + +export function formsToSlutredovisningFormData( + genomforandereferens: number, + step0FormData: SlutredovisningStep0FormData, + step1FormData: SlutredovisningStep1FormData, + step2FormData: SlutredovisningStep2FormData +): SlutredovisningFormData { + if (!genomforandereferens || !step0FormData || !step1FormData || !step2FormData) { + return; + } + + let mainOccupation: SlutredovisningRequestMainOccupationDetails; + if (step0FormData.mainOccupation === MainOccupation.Other) { + mainOccupation = { + type: MainOccupation.Other, + other: { + otherExplanation: step0FormData.other.otherExplanation, + }, + }; + } + + if (step0FormData.mainOccupation === MainOccupation.Work) { + mainOccupation = { + type: MainOccupation.Work, + work: step0FormData.work.map(workItem => { + return { + yrkesomrade: workItem.yrkesomrade, + yrkesgrupp: workItem.yrkesgrupp, + omfattning: workItem.omfattning as Omfattning, + omfattningPercent: workItem.omfattningPercent, + otherExplanation: workItem.otherExplanation, + anstallningsform: workItem.anstallningsform as Anstallningsform, + }; + }), + }; + } + + if (step0FormData.mainOccupation === MainOccupation.Education) { + mainOccupation = { + type: MainOccupation.Education, + education: { + educationLength: step0FormData.education.educationLength, + educationLevel: step0FormData.education.educationLevel, + otherExplanation: step0FormData.education.otherExplanation, + educationSpecification: step0FormData.education.educationSpecification, + }, + }; + } + if (step0FormData.mainOccupation === MainOccupation.StillUnemployed) { + mainOccupation = { + type: MainOccupation.StillUnemployed, + [MainOccupation.StillUnemployed]: { + reasonsGoalNotReached: Object.entries(step0FormData.stillUnemployed.reasonsGoalNotReached) + .map(([reason, isChecked]) => ({ reason: reason as StillUnemployedReason, isChecked })) + .filter(reasonChecked => !!reasonChecked.isChecked) + .map(({ reason }) => reason), + otherExplanation: step0FormData.stillUnemployed.stillUnemployedExplanation, + }, + }; + } + + return { + genomforandereferens: genomforandereferens, + mainOccupation: mainOccupation, + activities: step1FormData.activities, + progressDescription: step2FormData.progressDescription, + nextStepDescription: step2FormData.nextStepDescription, + otherInformation: step2FormData.otherInformation, + }; +} + +export function slutredovisningFormDataToSlutredovisningRequest( + slutredovisningResponse: SlutredovisningFormData +): SlutredovisningRequest { + return { + ...slutredovisningResponse, + activities: slutredovisningResponse.activities.map(({ whatHasBeenDone, id }) => ({ whatHasBeenDone, id })), + }; +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.html b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.html new file mode 100644 index 0000000..8b27aab --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.html @@ -0,0 +1,19 @@ + + + + + + + + + + + + + diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.scss b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.scss new file mode 100644 index 0000000..95bf4e8 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.scss @@ -0,0 +1,31 @@ +@import 'mixins/list'; +@import 'variables/gutters'; + +.gemensam-planering-view { + max-width: var(--digi--typography--text--max-width); + display: flex; + flex-direction: column; + gap: $digi--layout--gutter--l; + + &__activity-list { + @include msfa__reset-list; + margin-bottom: var(--digi--layout--gutter--s); + } + + &__activity-item { + display: flex; + align-items: center; + gap: var(--digi--layout--gutter--s); + margin-top: var(--digi--layout--gutter--s); + } + + &__activity-check { + color: var(--digi--ui--color--border--success); + } + + &__footer { + display: flex; + flex-direction: column; + gap: var(--digi--layout--gutter); + } +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.spec.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.spec.ts new file mode 100644 index 0000000..11a52b5 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.spec.ts @@ -0,0 +1,31 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { LayoutComponent } from '@msfa-shared/components/layout/layout.component'; +import { SlutredovisningViewComponent } from './slutredovisning-view.component'; +import { SlutredovisningViewService } from './slutredovisning-view.service'; + +describe('GemensamPlaneringViewComponent', () => { + let component: SlutredovisningViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [SlutredovisningViewComponent, LayoutComponent], + imports: [RouterTestingModule, HttpClientTestingModule], + providers: [SlutredovisningViewService], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SlutredovisningViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.ts new file mode 100644 index 0000000..071ab4d --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.component.ts @@ -0,0 +1,36 @@ +import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { Params } from '@msfa-models/api/params.model'; +import { Avrop } from '@msfa-models/avrop.model'; +import { Observable } from 'rxjs'; +import { map, shareReplay, switchMap } from 'rxjs/operators'; +import { SlutredovisningViewService } from './slutredovisning-view.service'; +import { Slutredovisning } from '@msfa-models/slutredovisning.model'; + +@Component({ + selector: 'msfa-slutredovisning-view', + templateUrl: './slutredovisning-view.component.html', + styleUrls: ['./slutredovisning-view.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class SlutredovisningViewComponent { + params$: Observable = this.activatedRoute.params.pipe( + map(params => ({ + handlingId: params.handlingId as string, + genomforandeReferens: params.genomforandeReferens as string, + })) + ); + avrop$: Observable = this.params$.pipe( + switchMap(({ genomforandeReferens }) => + this.slutredovisningViewService.fetchAvropInformation$(+genomforandeReferens) + ), + shareReplay(1) + ); + + slutredovisning$: Observable = this.params$.pipe( + switchMap(({ handlingId }) => this.slutredovisningViewService.fetchSlutredovisning$(handlingId as string)), + shareReplay(1) + ); + + constructor(private slutredovisningViewService: SlutredovisningViewService, private activatedRoute: ActivatedRoute) {} +} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.module.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.module.ts new file mode 100644 index 0000000..40319a6 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.module.ts @@ -0,0 +1,29 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; +import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; +import { UiLoaderModule } from '@ui/loader/loader.module'; +import { UiSkeletonModule } from '@ui/skeleton/skeleton.module'; +import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module'; +import { SlutredovisningViewComponent } from './slutredovisning-view.component'; +import { SlutredovisningViewService } from './slutredovisning-view.service'; +import { SlutredovisningViewDescriptionListModule } from '../../../components/slutredovisning-view-description-list/slutredovisning-view-description-list.module'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [SlutredovisningViewComponent], + imports: [ + CommonModule, + RouterModule.forChild([{ path: '', component: SlutredovisningViewComponent }]), + LayoutModule, + ReportLayoutModule, + BackLinkModule, + UiLoaderModule, + UiSkeletonModule, + SlutredovisningViewDescriptionListModule, + ], + providers: [SlutredovisningViewService], + exports: [SlutredovisningViewComponent], +}) +export class SlutredovisningViewModule {} diff --git a/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.service.ts b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.service.ts new file mode 100644 index 0000000..36bcd5b --- /dev/null +++ b/apps/mina-sidor-fa/src/app/pages/deltagare/pages/deltagare-details/pages/report-views/slutredovisning-view/slutredovisning-view.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core'; +import { Avrop } from '@msfa-models/avrop.model'; +import { HandlingarApiService } from '@msfa-services/api/handlingar.api.service'; +import { Observable } from 'rxjs'; +import { DeltagareApiService } from '@msfa-services/api/deltagare.api.service'; +import { SlutredovisningApiService } from '@msfa-services/api/slutredovisning.api.service'; +import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; +import { map } from 'rxjs/operators'; + +@Injectable() +export class SlutredovisningViewService { + constructor( + private handlingarApiService: HandlingarApiService, + private deltagareApiService: DeltagareApiService, + private gemensamPlaneringApiService: SlutredovisningApiService + ) {} + + public fetchAvropInformation$(genomforandeReferens: number): Observable { + return this.deltagareApiService.fetchAvropInformation$(genomforandeReferens); + } + + public fetchSlutredovisning$(handlingId: string): Observable { + return this.handlingarApiService.fetchSlutredovisning$(handlingId).pipe(map(({ data }) => data)); + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.html b/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.html index bd54c34..5447103 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.html +++ b/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.html @@ -1,34 +1,14 @@ - - + {{ validationErrorLink.text }} + + diff --git a/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.ts b/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.ts index 727fe65..57d9374 100644 --- a/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.ts +++ b/apps/mina-sidor-fa/src/app/shared/components/error-list/error-list.component.ts @@ -1,5 +1,5 @@ import { TypographyDynamicHeadingLevel } from '@af/digi-ng/_typography/typography-dynamic-heading'; -import { Component, ChangeDetectionStrategy, Input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; export interface ValidationErrorLink { elementId: string; @@ -16,4 +16,22 @@ export class ErrorListComponent { @Input() validationErrorLinks: ValidationErrorLink[] = []; @Input() headingText: string; @Input() headingLevel: TypographyDynamicHeadingLevel = TypographyDynamicHeadingLevel.H3; + + setFocusOnFormElement(element: HTMLElement): void { + const id = element.getAttribute('href').replace('#', ''); + const target = document.getElementById(id); + + if (target) { + const targetPosition: DOMRect = target.getBoundingClientRect(); + const absoluteElementPosition = targetPosition.top + window.scrollY; + const newPosition = absoluteElementPosition - window.innerHeight / 2; + + if (target.focus) { + target.tabIndex = -1; + target.focus(); + window.scrollTo(0, newPosition); + target.tabIndex = 0; + } + } + } } diff --git a/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts b/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts index 1b3efbf..8bfd523 100644 --- a/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts +++ b/apps/mina-sidor-fa/src/app/shared/constants/navigation.ts @@ -5,6 +5,7 @@ export const DELTAGARE_REPORTING_ROUTES = { avvikelserapport: 'Avvikelserapport (avvikelse)', signal: 'Signal om arbete eller studier', 'informativ-rapport': 'Informativ rapport', + slutredovisning: 'Slutredovisning', }; export const NAVIGATION = { diff --git a/apps/mina-sidor-fa/src/app/shared/constants/yrken.ts b/apps/mina-sidor-fa/src/app/shared/constants/yrken.ts new file mode 100644 index 0000000..80d7975 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/constants/yrken.ts @@ -0,0 +1,2130 @@ +import { YrkesomradeResponse } from '@msfa-models/api/yrkesomrade.response.model'; + +export const YRKEN: YrkesomradeResponse[] = [ + { + id: 'X82t_awd_Qyc', + name: 'Administration, ekonomi, juridik', + items: [ + { + id: 'q8wL_kdi_WaW', + name: 'Advokater', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'DZVN_v5g_Fco', + name: 'Affärs- och företagsjurister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'fsnw_ZCu_v2U', + name: 'Arbetsförmedlare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'sXgV_QFg_vpb', + name: 'Arkeologer och specialister inom humaniora m.m.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'TQkt_eeK_eNp', + name: 'Arkiv- och biblioteksassistenter m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'MGk3_LvL_AU2', + name: 'Backofficepersonal m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'vCAb_uuo_ek5', + name: 'Chefssekreterare och VD-assistenter m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'Uw4n_UB2_RCW', + name: 'Controller', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'qsJJ_EYo_fzA', + name: 'Domare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'zKvJ_GnC_Szx', + name: 'Domstols- och juristsekreterare m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'ij8k_EwC_zyB', + name: 'Ekonomiassistenter m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'pTr9_RBT_9ur', + name: 'Finansanalytiker och investeringsrådgivare m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: '9dLz_BCK_oDA', + name: 'Försäkringssäljare och försäkringsrådgivare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'JfYV_ZGg_6rm', + name: 'Förvaltnings- och organisationsjurister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'H2Zj_eL9_x28', + name: 'Gruppledare för kontorspersonal', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'k1Nx_auG_sNh', + name: 'Informatörer, kommunikatörer och PR-specialister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'JAFv_ZaP_tDG', + name: 'Inkasserare och pantlånare m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'ByrL_ANp_UwV', + name: 'Kontorsreceptionister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'Qo7p_wjf_gtv', + name: 'Lednings- och organisationsutvecklare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'L7eh_ihX_vM5', + name: 'Löne- och personaladministratörer', + parentId: 'X82t_awd_Qyc', + }, + { + id: '2kLc_pto_DpV', + name: 'Medicinska sekreterare, vårdadministratörer m fl', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'aQpg_E2T_cWq', + name: 'Mäklare inom finans', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'WZCM_nfS_eAk', + name: 'Nationalekonomer och makroanalytiker m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'bjqk_F3A_5Hk', + name: 'Personal- och HR-specialister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'vPP6_rsw_dck', + name: 'Planerare och utredare m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'q81z_3oD_1qu', + name: 'Redovisningsekonomer', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'cRmd_536_pT1', + name: 'Revisorer m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'Ru4W_zn2_LEz', + name: 'Skadereglerare och värderare', + parentId: 'X82t_awd_Qyc', + }, + { + id: '4W6S_1kA_nrv', + name: 'Skattehandläggare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'ZQTR_hVC_QhJ', + name: 'Skolassistenter m.fl.', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'ZQiZ_6Kd_D3a', + name: 'Socialförsäkringshandläggare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'jv1x_tpK_32p', + name: 'Statistiker', + parentId: 'X82t_awd_Qyc', + }, + { + id: '4aPu_2nd_8X6', + name: 'Telefonister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'Bbkh_nrm_2J8', + name: 'Traders och fondförvaltare', + parentId: 'X82t_awd_Qyc', + }, + { + id: '6aak_8eh_iwT', + name: 'Åklagare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'Y6yY_SuR_hVh', + name: 'Övriga ekonomer', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'oEmP_NC1_sXE', + name: 'Övriga handläggare', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'br6a_VVS_V3y', + name: 'Övriga jurister', + parentId: 'X82t_awd_Qyc', + }, + { + id: 'eQ4M_CNm_ozj', + name: 'Övriga kontorsassistenter och sekreterare', + parentId: 'X82t_awd_Qyc', + }, + ], + }, + { + id: 'j7Cq_ZJe_GkT', + name: 'Bygg och anläggning', + items: [ + { + id: 'bZ4J_riZ_zK6', + name: 'Anläggningsarbetare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'DPPw_4wa_AsH', + name: 'Anläggningsdykare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: '3ZtN_hhA_SM7', + name: 'Anläggningsmaskinförare m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'w6ud_quG_dgh', + name: 'Arbetsledare inom bygg, anläggning och gruva', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'q2Ge_zrQ_zJb', + name: 'Betongarbetare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: '7zKm_4NW_eey', + name: 'Brunnsborrare m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'bXfo_4hb_SXx', + name: 'Byggnads- och ventilationsplåtslagare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'XeBP_nMe_pXx', + name: 'Civilingenjörsyrken inom bygg och anläggning', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'V79C_DD2_3Gj', + name: 'Golvläggare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'iHrC_aRv_fVm', + name: 'Grovarbetare inom bygg och anläggning', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'f71c_gjL_RDq', + name: 'Gruv- och stenbrottsarbetare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'thZP_oR7_WrY', + name: 'Ingenjörer och tekniker inom bygg och anläggning', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'cGxX_R9c_kW1', + name: 'Isoleringsmontörer', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'XYzP_5Tn_7Ep', + name: 'Kranförare m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: '3UzE_P8A_9sS', + name: 'Kyl- och värmepumpstekniker m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'NnB3_eWH_auo', + name: 'Murare m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'QKvX_v7r_PNL', + name: 'Målare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'Y4j1_P17_wVA', + name: 'Ställningsbyggare', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: '3g5x_Tm7_8QH', + name: 'Takmontörer', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: '9mJN_VwW_Xjg', + name: 'Träarbetare, snickare m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'fLKb_bJ3_69p', + name: 'VVS-montörer m.fl.', + parentId: 'j7Cq_ZJe_GkT', + }, + { + id: 'AD3U_cFH_rbe', + name: 'Övriga byggnads- och anläggningsarbetare', + parentId: 'j7Cq_ZJe_GkT', + }, + ], + }, + { + id: 'bh3H_Y3h_5eD', + name: 'Chefer och verksamhetsledare', + items: [ + { + id: '8SPu_K1k_5qR', + name: 'Chefer inom arkitekt- och ingenjörsverksamhet', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '9Mn4_PNA_7Yz', + name: 'Chefer inom bank, finans och försäkring', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'wby2_mwq_fWV', + name: 'Chefer inom friskvård, sport och fritid', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '1uau_t1u_rDL', + name: 'Chefer inom förskoleverksamhet', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'Fu4x_7KG_YgC', + name: 'Chefer inom handel', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'womV_SEj_CAH', + name: 'Chefer inom hälso- och sjukvård', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'NxXz_fBh_w7j', + name: 'Chefer inom socialt och kurativt arbete', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'coyZ_Cyv_Srw', + name: 'Chefer inom äldreomsorg', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'x9mo_1VH_Rps', + name: 'Chefer och ledare inom trossamfund', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'z8di_AqX_GBr', + name: 'Chefer, grund- o gymnasieskola o vuxenutbildning', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'ajwx_FvL_YuY', + name: 'Chefstjänstemän i intresseorganisationer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '7mn2_kA9_ftp', + name: 'Driftchefer inom bygg, anläggning och gruva', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'mZsb_A1K_Gec', + name: 'Ekonomi- och finanschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '4GAs_rKs_2Ne', + name: 'Fastighets- och förvaltningschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'QG4f_MCh_vND', + name: 'Forsknings- och utvecklingschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'Pz9M_srJ_Lc9', + name: 'Försäljnings- och marknadschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '9QMD_sZ3_ZjX', + name: 'Förvaltare inom skogsbruk och lantbruk m.fl.', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'X1Ac_Y9P_PJo', + name: 'Förvaltnings- och planeringschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'ddGt_fEH_432', + name: 'General-, landstings- och kommundirektörer m.fl.', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'eX3C_MtJ_nPA', + name: 'Hotell- och konferenschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'eWiB_mGP_MjE', + name: 'IT-chefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'mpuA_s56_Hsy', + name: 'Informations-, kommunikations- och PR-chefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'nNxJ_YWy_vR2', + name: 'Inköps-, logistik- och transportchefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'mNoS_AN5_drn', + name: 'Personal- och HR-chefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'qVHD_Hj5_PXh', + name: 'Politiker', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'pf1K_PTz_frm', + name: 'Produktionschefer inom tillverkning', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'hZLv_S5f_jo2', + name: 'Restaurang- och kökschefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: '3i4a_Ufc_qpp', + name: 'Verkställande direktörer m.fl.', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'uxst_tkg_zDh', + name: 'Övriga administrations- och servicechefer', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'sWzF_6pd_Y6L', + name: 'Övriga chefer inom samhällsservice', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'g6eC_Fwu_B3J', + name: 'Övriga chefer inom utbildning', + parentId: 'bh3H_Y3h_5eD', + }, + { + id: 'NQTS_fou_E6u', + name: 'Övriga chefer inom övrig servicenäring', + parentId: 'bh3H_Y3h_5eD', + }, + ], + }, + { + id: 'apaJ_2ja_LuF', + name: 'Data/IT', + items: [ + { + id: '13md_uyV_BNG', + name: 'Drifttekniker, IT', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'BAeH_eg8_T2d', + name: 'IT-säkerhetsspecialister', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'DJh5_yyF_hEM', + name: 'Mjukvaru- och systemutvecklare m.fl.', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'VCpu_5EN_bBt', + name: 'Nätverks- och systemtekniker m.fl.', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'hmaC_cfi_UKg', + name: 'Supporttekniker, IT', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'MYAz_x9m_2LJ', + name: 'Systemadministratörer', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'UXKZ_3zZ_ipB', + name: 'Systemanalytiker och IT-arkitekter m.fl.', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'cBBa_ngH_fCx', + name: 'Systemförvaltare m.fl.', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'D9SL_mtn_vGM', + name: 'Systemtestare och testledare', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'Q5DF_juj_8do', + name: 'Utvecklare inom spel och digitala media', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'Fv7d_YhP_YmS', + name: 'Webbmaster och webbadministratörer', + parentId: 'apaJ_2ja_LuF', + }, + { + id: 'UxT1_tPF_Kbg', + name: 'Övriga IT-specialister', + parentId: 'apaJ_2ja_LuF', + }, + ], + }, + { + id: 'RPTn_bxG_ExZ', + name: 'Försäljning, inköp, marknadsföring', + items: [ + { + id: '41Az_ioZ_rmH', + name: 'Apotekstekniker', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'FfMN_Bw1_qYR', + name: 'Banktjänstemän', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'JnTF_wXr_6Eh', + name: 'Bensinstationspersonal', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 's1Qk_o98_2o1', + name: 'Butikssäljare, dagligvaror', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'YKL2_FCB_1yr', + name: 'Butikssäljare, fackhandel', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: '48KE_fDE_ryL', + name: 'Evenemangs- och reseproducenter m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'NCeZ_rSk_B4D', + name: 'Eventsäljare och butiksdemonstratörer m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'Fghp_zje_WA8', + name: 'Fastighetsmäklare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'oXSW_fbY_XrY', + name: 'Företagssäljare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'A6X3_efC_VNy', + name: 'Guider och reseledare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: '85cq_6uK_4cK', + name: 'Inköpare och upphandlare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'iWcY_mko_rq2', + name: 'Inköps- och orderassistenter', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'WNVp_RYe_zLX', + name: 'Kassapersonal m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'pwRH_MT1_8nR', + name: 'Kundtjänstpersonal', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'p16X_44f_rwZ', + name: 'Marknads- och försäljningsassistenter', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'WX67_Pfb_WMN', + name: 'Marknadsanalytiker och marknadsförare m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: '83wV_GJa_vMd', + name: 'Marknadsundersökare och intervjuare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'AQrL_tTu_Wbg', + name: 'Optikerassistenter', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: '8A1f_sxQ_adT', + name: 'Ordersamordnare m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'fdLf_oPp_wVw', + name: 'Resesäljare och trafikassistenter m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'AuTi_FEo_j3R', + name: 'Speditörer och transportmäklare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'Fp7x_Yqt_bx9', + name: 'Säljande butikschefer o avdelningschefer i butik', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'PxXc_16t_oZo', + name: 'Telefonförsäljare m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'xyW2_toA_Skh', + name: 'Torg- och marknadsförsäljare m.fl.', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'M47D_MU2_dhS', + name: 'Uthyrare', + parentId: 'RPTn_bxG_ExZ', + }, + { + id: 'dUuh_wwa_FGj', + name: 'Övriga förmedlare', + parentId: 'RPTn_bxG_ExZ', + }, + ], + }, + { + id: 'PaxQ_o1G_wWH', + name: 'Hantverksyrken', + items: [ + { + id: '5qT8_z9d_8rw', + name: 'Bagare och konditorer', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: '1Nwn_GYH_wkH', + name: 'Fin-, inrednings- och möbelsnickare', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'e6nk_AGp_y28', + name: 'Finmekaniker', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'J17g_Q2a_2u1', + name: 'Glastekniker', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'nwSm_phw_sPo', + name: 'Guld- och silversmeder', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'vJQk_YvC_XB7', + name: 'Läderhantverkare och skomakare', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'v7W3_cLQ_q2S', + name: 'Manuella ytbehandlare, trä', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'aKdV_u7V_R5j', + name: 'Musikinstrumentmakare o övriga konsthantverkare', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'mwVN_oEH_g9k', + name: 'Skräddare och ateljésömmerskor m.fl.', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'q8Ho_3Xw_sHq', + name: 'Smeder', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'UZBj_yDX_Ctp', + name: 'Sömmare', + parentId: 'PaxQ_o1G_wWH', + }, + { + id: 'vhUJ_LyD_XWc', + name: 'Tapetserare', + parentId: 'PaxQ_o1G_wWH', + }, + ], + }, + { + id: 'ScKy_FHB_7wT', + name: 'Hotell, restaurang, storhushåll', + items: [ + { + id: 'XFXX_Jq9_Y2a', + name: 'Bartendrar', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'YHwG_fk2_MDL', + name: 'Croupierer och oddssättare m.fl.', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'bYde_Frc_xcB', + name: 'Hotellreceptionister m.fl.', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'UjoW_meY_Zwt', + name: 'Hovmästare och servitörer', + parentId: 'ScKy_FHB_7wT', + }, + { + id: '1wqU_Jhj_amb', + name: 'Kafé- och konditoribiträden', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'BStc_SJh_DKG', + name: 'Kockar och kallskänkor', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'XGyi_i4B_ME7', + name: 'Köksmästare och souschefer', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'a8gg_ktU_w8V', + name: 'Pizzabagare m.fl.', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'tPox_ie4_X9X', + name: 'Restaurang- och köksbiträden m.fl.', + parentId: 'ScKy_FHB_7wT', + }, + { + id: 'h324_DPT_7Tw', + name: 'Storhushållsföreståndare', + parentId: 'ScKy_FHB_7wT', + }, + ], + }, + { + id: 'NYW6_mP6_vwf', + name: 'Hälso- och sjukvård', + items: [ + { + id: 'ek9W_qqp_XpF', + name: 'AT-läkare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'PHJN_fva_yxs', + name: 'Ambulanssjuksköterskor m.fl.', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '3H17_ZZr_BEc', + name: 'Ambulanssjukvårdare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'nrVt_xUL_KdQ', + name: 'Anestesisjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'TMsM_oNw_j6z', + name: 'Apotekare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'TPH4_2AM_isT', + name: 'Arbetsterapeuter', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'pzch_NRY_9ZF', + name: 'Audionomer och logopeder', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '7XXd_4St_nit', + name: 'Barnmorskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'NFUg_y9y_1TY', + name: 'Barnsjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'kHgb_AHf_vrY', + name: 'Barnsköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'wNrt_Ysj_WuT', + name: 'Biomedicinska analytiker m.fl.', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'Pq5C_SPC_bRA', + name: 'Dietister', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'oj4c_P4b_cja', + name: 'Distriktssköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '8q1B_5AR_CEM', + name: 'Djursjukskötare m.fl.', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 's7vU_FhY_L5Z', + name: 'Fysioterapeuter och sjukgymnaster', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '6Fu3_qQA_9DK', + name: 'Företagssköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '6eAB_cbY_i9T', + name: 'Geriatriksjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'Z8ci_bBE_tmx', + name: 'Grundutbildade sjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'dyWo_sDb_MLQ', + name: 'Intensivvårdssjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'aWki_4uA_adn', + name: 'Kiropraktorer och naprapater m.fl.', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'cuaN_Rj5_YCc', + name: 'Operationssjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'PUhV_DVQ_MM6', + name: 'Optiker', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'bEDv_SL7_VrL', + name: 'Psykiatrisjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'VYeq_GDF_a2g', + name: 'Psykologer', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'UUQi_UJ5_MSb', + name: 'Psykoterapeuter', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'XjcN_5LT_bWx', + name: 'Receptarier', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '1tGC_fXC_mxX', + name: 'Röntgensjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'seu9_VoQ_VNo', + name: 'ST-läkare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'Bywn_Doc_3VF', + name: 'Skolsköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '7fNG_sve_JWU', + name: 'Skötare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'nu7c_QuB_KVQ', + name: 'Specialistläkare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '4F9o_Jzv_Pwz', + name: 'Tandhygienister', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'HPxT_fQJ_zwT', + name: 'Tandläkare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '5dxv_nVQ_N8o', + name: 'Tandsköterskor', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'F19Z_oB6_pg3', + name: 'Terapeuter inom alternativmedicin', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'jY19_knH_MJp', + name: 'Undersköterskor, hemtjänst, äldreboende m.fl.', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'LP4Z_ABV_gRm', + name: 'Undersköterskor, vård- o specialavd o mottagning', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'WL4E_r4b_ek4', + name: 'Veterinärer', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'tAJS_JNb_hDH', + name: 'Vårdbiträden', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'GiNX_ESA_AL1', + name: 'Övrig vård- och omsorgspersonal', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'gXqW_s5Q_ZjN', + name: 'Övriga läkare', + parentId: 'NYW6_mP6_vwf', + }, + { + id: 'vTgW_pnr_QMp', + name: 'Övriga specialister inom hälso- och sjukvård', + parentId: 'NYW6_mP6_vwf', + }, + { + id: '6zAR_EHM_Kwj', + name: 'Övriga specialistsjuksköterskor', + parentId: 'NYW6_mP6_vwf', + }, + ], + }, + { + id: 'wTEr_CBC_bqh', + name: 'Industriell tillverkning', + items: [ + { + id: 'dMVD_VYy_kgg', + name: 'Arbetsledare inom tillverkning', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'sX9n_CWa_KVC', + name: 'Bergsprängare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'mPzg_93F_QEv', + name: 'Bokbindare m.fl.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'shkw_ojo_UL2', + name: 'Fordonsmontörer', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'J9Vz_JxJ_Bji', + name: 'Gjutare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'DxiF_hTo_b3X', + name: 'Handpaketerare och andra fabriksarbetare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'dKUb_KBP_mw3', + name: 'Lackerare och industrimålare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'AUs8_M5f_dLt', + name: 'Maskinoperatörer inom ytbehandling, trä', + parentId: 'wTEr_CBC_bqh', + }, + { + id: '4DET_dLf_iB9', + name: 'Maskinoperatörer, blekning, färgning o tvättning', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'o31g_CX1_qhQ', + name: 'Maskinoperatörer, cement-, sten- och betongvaror', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'rxmK_wwM_1NA', + name: 'Maskinoperatörer, farmaceutiska produkter', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'ENV6_BNa_brP', + name: 'Maskinoperatörer, gummiindustri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'Vfum_e6B_7Bw', + name: 'Maskinoperatörer, kem.tekn. o fotografiska prod.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'kF59_fge_kts', + name: 'Maskinoperatörer, kvarn-, bageri- o konfektyrind', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'gJtZ_EBc_n2z', + name: 'Maskinoperatörer, kött- o fiskberedningsindustri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'yJk6_azD_ywF', + name: 'Maskinoperatörer, mejeri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'iZLB_KpD_LLo', + name: 'Maskinoperatörer, pappersvaruindustri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'yPQ4_EaN_Dtj', + name: 'Maskinoperatörer, plastindustri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'aU9p_ekE_Fqf', + name: 'Maskinoperatörer, påfyllning, packning o märkn.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'YiQw_N87_zLU', + name: 'Maskinoperatörer, ytbehandling', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'VKKg_e4t_t46', + name: 'Maskinsnickare och maskinoperatörer, träindustri', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'vaEp_iBS_c5h', + name: 'Maskinställare o maskinoperatörer, metallarbete', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'SgAJ_DW2_FN5', + name: 'Montörer, elektrisk och elektronisk utrustning', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'Kxm9_N3V_shF', + name: 'Montörer, metall-, gummi- och plastprodukter', + parentId: 'wTEr_CBC_bqh', + }, + { + id: '8ddv_P8e_iYz', + name: 'Montörer, träprodukter', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'UdrS_qzV_P7i', + name: 'Operatörer inom sågverk, hyvleri och plywood m.m', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'LeQV_umf_wUS', + name: 'Prepresstekniker', + parentId: 'wTEr_CBC_bqh', + }, + { + id: '1G6H_AuG_qyy', + name: 'Processoperatörer, papper', + parentId: 'wTEr_CBC_bqh', + }, + { + id: '4obu_LL6_RqJ', + name: 'Processoperatörer, pappersmassa', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'LEvM_7Hs_w8i', + name: 'Processoperatörer, stenkross- och malmförädling', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'dAu7_VyL_hsy', + name: 'Provsmakare och kvalitetsbedömare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'QqHf_XKZ_eyy', + name: 'Slaktare och styckare m.fl.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: '4bxV_58E_P9N', + name: 'Slipare m.fl.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'vCBT_Pnd_8UB', + name: 'Stenhuggare m.fl.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'TrwQ_RXT_W8a', + name: 'Stålkonstruktionsmontörer och grovplåtsslagare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'wQ1E_Bzk_ZyA', + name: 'Svetsare och gasskärare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'XeJB_bkn_mRn', + name: 'Tryckare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'L4hA_SJP_SFi', + name: 'Tunnplåtslagare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'm8TS_hdk_pSf', + name: 'Valsverksoperatörer', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'MSnK_3Z8_4qA', + name: 'Verktygsmakare', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'skLS_kpa_Ui1', + name: 'Övr maskinoperatörer, textil-, skinn- o läderind', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'UcNa_inr_snV', + name: 'Övr. maskin- o processoperatörer, stål- o metall', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'icae_Y69_H8E', + name: 'Övriga maskinoperatörer, livsmedelsindustri m.m.', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'HXzD_qvt_HV6', + name: 'Övriga montörer', + parentId: 'wTEr_CBC_bqh', + }, + { + id: 'hxm6_xkr_dHm', + name: 'Övriga process- och maskinoperatörer', + parentId: 'wTEr_CBC_bqh', + }, + ], + }, + { + id: 'yhCP_AqT_tns', + name: 'Installation, drift, underhåll', + items: [ + { + id: 'MW1P_GNJ_4F9', + name: 'Distributionselektriker', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'Cppd_9P7_HeR', + name: 'Drifttekniker vid värme- och vattenverk', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'fWrt_sLg_koW', + name: 'Elektronikrep. o kommunikationselektriker m.fl.', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'df9D_e6y_61z', + name: 'Fastighetsskötare', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'iGTu_bYL_2T7', + name: 'Flygmekaniker m.fl.', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'a75S_eLg_JWH', + name: 'Industrielektriker', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'yyF7_jsW_EeP', + name: 'Installations- och serviceelektriker', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'Lzpv_ofL_3H5', + name: 'Motorfordonsmekaniker och fordonsreparatörer', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'QEBd_qHu_vGr', + name: 'Processövervakare, kemisk industri', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'E87t_egE_pjA', + name: 'Processövervakare, metallproduktion', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'KttZ_Skc_bMR', + name: 'Underhållsmekaniker och maskinreparatörer', + parentId: 'yhCP_AqT_tns', + }, + { + id: '9DdK_AZY_ZNK', + name: 'Vaktmästare m.fl.', + parentId: 'yhCP_AqT_tns', + }, + { + id: '7Zqy_hSM_Fig', + name: 'Övriga drifttekniker och processövervakare', + parentId: 'yhCP_AqT_tns', + }, + { + id: 'ieVp_d5L_rS9', + name: 'Övriga servicearbetare', + parentId: 'yhCP_AqT_tns', + }, + ], + }, + { + id: 'Uuf1_GMh_Uvw', + name: 'Kropps- och skönhetsvård', + items: [ + { + id: 'HATH_AfN_RRz', + name: 'Fotterapeuter', + parentId: 'Uuf1_GMh_Uvw', + }, + { + id: 'LyBp_bY6_bZK', + name: 'Frisörer', + parentId: 'Uuf1_GMh_Uvw', + }, + { + id: 'xr7w_N6Q_QMA', + name: 'Hudterapeuter', + parentId: 'Uuf1_GMh_Uvw', + }, + { + id: 'uxHV_KXc_PKD', + name: 'Massörer och massageterapeuter', + parentId: 'Uuf1_GMh_Uvw', + }, + { + id: 'ezKk_kss_CiQ', + name: 'Övriga skönhets- och kroppsterapeuter', + parentId: 'Uuf1_GMh_Uvw', + }, + ], + }, + { + id: '9puE_nYg_crq', + name: 'Kultur, media, design', + items: [ + { + id: 'wVfo_Njx_1rB', + name: 'Bibliotekarier och arkivarier', + parentId: '9puE_nYg_crq', + }, + { + id: 'CkRH_4Qn_iX3', + name: 'Bild- och sändningstekniker', + parentId: '9puE_nYg_crq', + }, + { + id: '34Tn_BQQ_tfo', + name: 'Bildkonstnärer m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'Mbt6_3ko_DiD', + name: 'Designer inom spel och digitala medier', + parentId: '9puE_nYg_crq', + }, + { + id: '3J38_DNz_YKK', + name: 'Fotografer', + parentId: '9puE_nYg_crq', + }, + { + id: 'zfve_s6G_tpc', + name: 'Författare m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: '8Bmh_vtM_zts', + name: 'Grafisk formgivare m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'DqLe_pH6_jyj', + name: 'Industridesigner', + parentId: '9puE_nYg_crq', + }, + { + id: 'CSUf_ZVM_a7Z', + name: 'Inredare, dekoratörer och scenografer m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'PH2M_uV4_r72', + name: 'Inspicienter och scriptor m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'SgNH_hag_n9D', + name: 'Journalister m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'gmRr_7tt_eHj', + name: 'Koreografer och dansare', + parentId: '9puE_nYg_crq', + }, + { + id: '4BsK_q2C_sCL', + name: 'Ljus-, ljud- och scentekniker', + parentId: '9puE_nYg_crq', + }, + { + id: 'Qbvf_6nd_Esn', + name: 'Museiintendenter m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'AWJF_wqZ_va9', + name: 'Musiker, sångare och kompositörer', + parentId: '9puE_nYg_crq', + }, + { + id: 'rYSG_3WJ_LmC', + name: 'Regissörer och producenter av film, teater m.m.', + parentId: '9puE_nYg_crq', + }, + { + id: 'iBUL_s38_izZ', + name: 'Skådespelare', + parentId: '9puE_nYg_crq', + }, + { + id: 'PQDm_Z63_zst', + name: 'Översättare, tolkar och lingvister m.fl.', + parentId: '9puE_nYg_crq', + }, + { + id: 'PF4H_kQD_zpL', + name: 'Övriga designer och formgivare', + parentId: '9puE_nYg_crq', + }, + { + id: 'xuSE_mtB_Mir', + name: 'Övriga yrken inom kultur och underhållning', + parentId: '9puE_nYg_crq', + }, + ], + }, + { + id: 'bH5L_uXD_ZAX', + name: 'Militärt arbete', + items: [ + { + id: 'KiVA_anS_RJh', + name: 'Officerare', + parentId: 'bH5L_uXD_ZAX', + }, + { + id: 'jXUQ_rUV_iBv', + name: 'Soldater m.fl.', + parentId: 'bH5L_uXD_ZAX', + }, + { + id: 'dhgR_9jk_95r', + name: 'Specialistofficerare', + parentId: 'bH5L_uXD_ZAX', + }, + ], + }, + { + id: 'VuuL_7CH_adj', + name: 'Naturbruk', + items: [ + { + id: '1EBv_UzM_ozQ', + name: 'Bärplockare och plantörer m.fl.', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'Lm3Z_gek_GYc', + name: 'Fiskare', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'c8r8_e4L_gwj', + name: 'Fiskodlare', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'KwVo_sQu_G2e', + name: 'Förare av jordbruks- och skogsmaskiner', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'k3R3_UkC_nK2', + name: 'Odlare av jordbruksväxter, frukt och bär', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'qouP_wtb_93q', + name: 'Skogsarbetare', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'XurM_DVs_ggn', + name: 'Specialister och rådgivare inom lantbruk m.m.', + parentId: 'VuuL_7CH_adj', + }, + { + id: '3LdB_WEJ_8Ms', + name: 'Specialister och rådgivare inom skogsbruk', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'XBh3_Xrm_C4R', + name: 'Trädgårdsanläggare m.fl.', + parentId: 'VuuL_7CH_adj', + }, + { + id: '2xQ4_4kh_kTZ', + name: 'Trädgårdsodlare', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'KYmy_iqC_xiQ', + name: 'Uppfödare och skötare av lantbrukets husdjur', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'MSzH_F2n_Emb', + name: 'Uppfödare och skötare av sällskapsdjur', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'RYCQ_ogb_uUY', + name: 'Växtodlare och djuruppfödare, blandad drift', + parentId: 'VuuL_7CH_adj', + }, + { + id: 'Lrsj_wRZ_sFV', + name: 'Övriga djuruppfödare och djurskötare', + parentId: 'VuuL_7CH_adj', + }, + ], + }, + { + id: 'kJeN_wmw_9wX', + name: 'Naturvetenskapligt arbete', + items: [ + { + id: 'Z2MZ_eYc_Lfv', + name: 'Cell- och molekylärbiologer m.fl.', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'dsK3_hkt_zGy', + name: 'Farmakologer och biomedicinare', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'KM7d_Z6Y_LCJ', + name: 'Fysiker och astronomer', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'V7Yz_4WV_g4z', + name: 'Geologer och geofysiker m.fl.', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'eofS_oZs_RZi', + name: 'Kemister', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'ZA1N_Z2B_nFQ', + name: 'Matematiker och aktuarier', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'LP8B_auW_wMp', + name: 'Meteorologer', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'puim_6PY_DGj', + name: 'Miljö- och hälsoskyddsinspektörer', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'rE1E_m3d_cx1', + name: 'Specialister inom miljöskydd och miljöteknik', + parentId: 'kJeN_wmw_9wX', + }, + { + id: 'e9FK_VKh_ahW', + name: 'Växt- och djurbiologer', + parentId: 'kJeN_wmw_9wX', + }, + ], + }, + { + id: 'MVqp_eS8_kDZ', + name: 'Pedagogiskt arbete', + items: [ + { + id: 'NNK9_F1o_pK5', + name: 'Doktorander', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'XW9L_tA9_WaX', + name: 'Elevassistenter m.fl.', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'P7eS_nP8_3dy', + name: 'Forskarassistenter m.fl.', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'CFW8_eBa_NaV', + name: 'Fritidspedagoger', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: '5ek3_Cgq_WeZ', + name: 'Förskollärare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'oQUQ_D11_HPx', + name: 'Grundskollärare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: '4KhP_FxL_uZ5', + name: 'Gymnasielärare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'EA6o_N1N_QtT', + name: 'Idrottstränare och instruktörer m.fl.', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: '2x2V_UeL_6ke', + name: 'Lärare i yrkesämnen', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'AwXA_EM4_71n', + name: 'Professionella idrottsutövare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'Gm5j_S2Y_aTB', + name: 'Professorer', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: '3FP7_4Eg_x8P', + name: 'Speciallärare och specialpedagoger m.fl.', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'jJF3_qaQ_Zsh', + name: 'Studie- och yrkesvägledare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'yVZH_zHh_6fG', + name: 'Trafiklärare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'cYCo_PxY_zQd', + name: 'Universitets- och högskolelektorer', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'mcRJ_kq2_jFr', + name: 'Övr. pedagoger med teoretisk specialistkompetens', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: 'RPBE_x5M_cXX', + name: 'Övriga universitets- och högskollärare', + parentId: 'MVqp_eS8_kDZ', + }, + { + id: '1CX5_mZw_Vcq', + name: 'Övriga utbildare och instruktörer', + parentId: 'MVqp_eS8_kDZ', + }, + ], + }, + { + id: 'whao_Q6A_ScE', + name: 'Sanering och renhållning', + items: [ + { + id: 'FjdF_H2e_tAG', + name: 'Bilrekonditionerare, fönsterputsare m.fl.', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'X7HR_rZK_4wj', + name: 'Renhållnings- och återvinningsarbetare', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'idjo_2Wr_a3E', + name: 'Saneringsarbetare m.fl.', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'SUfj_4D9_FNx', + name: 'Skorstensfejare', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'Z6TY_xDf_Yup', + name: 'Städare', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'FtyZ_Joo_tB8', + name: 'Städledare och husfruar', + parentId: 'whao_Q6A_ScE', + }, + { + id: 'o1gn_FoS_fB7', + name: 'Övrig hemservicepersonal m.fl.', + parentId: 'whao_Q6A_ScE', + }, + ], + }, + { + id: 'GazW_2TU_kJw', + name: 'Socialt arbete', + items: [ + { + id: 'Hi9c_iTe_gHH', + name: 'Barnskötare', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'R8bW_rsJ_b2G', + name: 'Begravnings- och krematoriepersonal', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'BWwk_fYX_S5B', + name: 'Behandlingsassistenter och socialpedagoger m.fl.', + parentId: 'GazW_2TU_kJw', + }, + { + id: '5uP5_Ugw_aVE', + name: 'Biståndsbedömare m.fl.', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'wzeq_No2_LF1', + name: 'Diakoner', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'FpPP_jqK_xzT', + name: 'Friskvårdskonsulenter och hälsopedagoger m.fl.', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'aA2Z_9XX_R1v', + name: 'Fritidsledare m.fl.', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'dJXy_Rpq_a2u', + name: 'Kuratorer', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'x5rn_vga_gRK', + name: 'Pastorer m.fl.', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'sq3e_WVv_Fjd', + name: 'Personliga assistenter', + parentId: 'GazW_2TU_kJw', + }, + { + id: '2L2s_EU8_PzR', + name: 'Präster', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'pok1_ipJ_yzD', + name: 'Socialsekreterare', + parentId: 'GazW_2TU_kJw', + }, + { + id: '7pz9_eY9_D2s', + name: 'Vårdare, boendestödjare', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'DSGC_nw7_WnH', + name: 'Övrig servicepersonal', + parentId: 'GazW_2TU_kJw', + }, + { + id: 'n6iX_f2z_XfE', + name: 'Övriga yrken inom socialt arbete', + parentId: 'GazW_2TU_kJw', + }, + ], + }, + { + id: 'E7hm_BLq_fqZ', + name: 'Säkerhetsarbete', + items: [ + { + id: 'Uw64_cuc_U3H', + name: 'Arbetsmiljöingenjörer, yrkes- o miljöhygieniker', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'wCx8_rY3_XUT', + name: 'Brandingenjörer och byggnadsinspektörer m.fl.', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'ug5y_o6z_U3L', + name: 'Brandmän', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'hgAg_gLr_YGg', + name: 'Kriminalvårdare', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'rNcE_Zno_pD8', + name: 'Poliser', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'kZwz_D8K_bKs', + name: 'SOS-operatörer m.fl.', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'nuXg_Wjc_JPd', + name: 'Säkerhetsinspektörer m.fl.', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'FKCE_Anf_zGH', + name: 'Tull- och kustbevakningstjänstemän', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'iqZh_3yX_i8n', + name: 'Väktare och ordningsvakter', + parentId: 'E7hm_BLq_fqZ', + }, + { + id: 'ayQ4_G3W_A2w', + name: 'Övrig bevaknings- och säkerhetspersonal', + parentId: 'E7hm_BLq_fqZ', + }, + ], + }, + { + id: '6Hq3_tKo_V57', + name: 'Tekniskt arbete', + items: [ + { + id: '41KB_bfk_5jR', + name: 'Arkitekter m.fl.', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'SPYW_7Z1_ShT', + name: 'Civilingenjörsyrken inom elektroteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'rwpH_6RA_XTT', + name: 'Civilingenjörsyrken inom gruvteknik o metallurgi', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'qn2U_dB9_Cmh', + name: 'Civilingenjörsyrken inom kemi och kemiteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'PRQn_9yw_NJA', + name: 'Civilingenjörsyrken inom maskinteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'xm5G_vGn_iyk', + name: 'Civilingenjörsyrken, logistik och prod.planering', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'U8HK_Jdi_GuC', + name: 'Fastighetsförvaltare', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'eRkT_cTv_H9v', + name: 'Flygtekniker', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'ketV_G9W_GeR', + name: 'GIS- och kartingenjörer', + parentId: '6Hq3_tKo_V57', + }, + { + id: '3jEy_yuT_aVo', + name: 'Ingenjörer o tekniker i gruvteknik o metallurgi', + parentId: '6Hq3_tKo_V57', + }, + { + id: '33Nt_DSs_YYA', + name: 'Ingenjörer o tekniker, industri o prod.planering', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'nDaB_vdy_eAy', + name: 'Ingenjörer och tekniker inom elektroteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'v9nU_6Fw_4Qg', + name: 'Ingenjörer och tekniker inom kemi och kemiteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'K8yg_U4C_gkY', + name: 'Ingenjörer och tekniker inom maskinteknik', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'bExu_8gk_azk', + name: 'Laboratorieingenjörer', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'ETAR_ggZ_Wuw', + name: 'Landskapsarkitekter', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'GMDo_DVo_Yzh', + name: 'Lantmätare', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'Pd51_xnr_KCY', + name: 'Planeringsarkitekter m.fl.', + parentId: '6Hq3_tKo_V57', + }, + { + id: '39yB_xPQ_ozd', + name: 'Tandtekniker och ortopedingenjörer m.fl.', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'GC7L_Yw7_Mfo', + name: 'Tekniker, bilddiagnostik o medicintekn. utrustn.', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'mp2Y_vyC_RFV', + name: 'Övriga civilingenjörsyrken', + parentId: '6Hq3_tKo_V57', + }, + { + id: 'mis4_feV_uex', + name: 'Övriga ingenjörer och tekniker', + parentId: '6Hq3_tKo_V57', + }, + ], + }, + { + id: 'ASGV_zcE_bWf', + name: 'Transport', + items: [ + { + id: 'WhBn_FAp_ZNW', + name: 'Arbetsledare inom lager och terminal', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'nk6Z_5oD_QoM', + name: 'Bangårdspersonal', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'gaBh_1vR_tNE', + name: 'Brevbärare och postterminalarbetare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'FiDm_2S8_gx7', + name: 'Buss- och spårvagnsförare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'kDnq_Q98_sD3', + name: 'Fartygsbefäl m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'yct8_Pun_DWd', + name: 'Flygledare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'SZ7Q_2zF_nFy', + name: 'Hamnarbetare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: '1Tso_4TB_RkE', + name: 'Kabinpersonal m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'kLyY_rwr_aJr', + name: 'Lager- och terminalpersonal', + parentId: 'ASGV_zcE_bWf', + }, + { + id: '3MBw_pDA_P2F', + name: 'Lastbilsförare m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'UGgc_Vm9_Bog', + name: 'Lokförare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'Rsoy_sS6_6c4', + name: 'Maskinbefäl', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'CbQK_7th_Tyf', + name: 'Matroser och jungmän m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: '7n3y_FTE_qSe', + name: 'Piloter m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'bwnk_nv2_1cR', + name: 'Ramppersonal, flyttkarlar o varupåfyllare m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'qhbP_JEJ_HtK', + name: 'Reklamutdelare och tidningsdistributörer', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'ffz2_2n3_R7g', + name: 'Taxiförare m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: '957L_kZK_rHZ', + name: 'Transportledare och transportsamordnare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'MrcX_RDn_N53', + name: 'Truckförare', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 's78G_Zp2_dkq', + name: 'Tågvärdar och ombordansvariga m.fl.', + parentId: 'ASGV_zcE_bWf', + }, + { + id: 'P7Ay_ooF_pri', + name: 'Övriga bil-, motorcykel- och cykelförare', + parentId: 'ASGV_zcE_bWf', + }, + ], + }, +]; diff --git a/apps/mina-sidor-fa/src/app/shared/directives/anchor-link.directive.ts b/apps/mina-sidor-fa/src/app/shared/directives/anchor-link.directive.ts index a15239f..ae7d233 100644 --- a/apps/mina-sidor-fa/src/app/shared/directives/anchor-link.directive.ts +++ b/apps/mina-sidor-fa/src/app/shared/directives/anchor-link.directive.ts @@ -12,13 +12,17 @@ export class AnchorLinkDirective { const elementId = href?.trim().replace('#', ''); const element = document.getElementById(elementId); - if (element && element.focus) { - element.tabIndex = -1; - element.focus(); - } + if (element) { + const elementPosition: DOMRect = element.getBoundingClientRect(); + const absoluteElementPosition = elementPosition.top + window.scrollY; + const newPosition = absoluteElementPosition - window.innerHeight / 2; - if (element.tabIndex < 0) { - element.scrollIntoView(); + if (element.focus) { + element.tabIndex = -1; + element.focus(); + window.scrollTo(0, newPosition); + element.tabIndex = 0; + } } event.stopPropagation(); diff --git a/apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts b/apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts index e0e268c..ff90c25 100644 --- a/apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts +++ b/apps/mina-sidor-fa/src/app/shared/enums/feature.enum.ts @@ -16,5 +16,6 @@ export enum Feature { REPORTING_PERIODISK_REDOVISNING, REPORTING_INFORMATIV_RAPPORT, EXPORTS, + SLUTREDOVISNING, NEWS, } diff --git a/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts b/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts index de7c1ef..47b64d1 100644 --- a/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts +++ b/apps/mina-sidor-fa/src/app/shared/enums/report-type.enum.ts @@ -5,6 +5,7 @@ export enum ReportType { Avvikelse = 'Avvikelserapport (avvikelse)', Franvaro = 'Avvikelserapport (frånvaro)', PeriodiskRedovisning = 'Periodisk redovisning', + Slutredovisning = 'Slutredovisning', InformativRapport = 'Informativ rapport', InformativRedovisning = 'Informativ rapport', } diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.request.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.request.model.ts new file mode 100644 index 0000000..483c3a3 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.request.model.ts @@ -0,0 +1,68 @@ +import { + Anstallningsform, + EducationLength, + EducationLevel, + MainOccupation, + Omfattning, + StillUnemployedReason, +} from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningRequestMainOccupationWorkDetails { + yrkesomrade: string; + yrkesgrupp: string; + anstallningsform: Anstallningsform; + otherExplanation: string; + omfattning: Omfattning; + omfattningPercent: number; +} + +export interface SlutredovisningRequestMainOccupationWork { + type: MainOccupation.Work; + work: SlutredovisningRequestMainOccupationWorkDetails[]; +} + +export interface SlutredovisningRequestMainOccupationEducationDetails { + educationLevel: EducationLevel; + otherExplanation: string; + educationLength: EducationLength; + educationSpecification: string; +} + +export interface SlutredovisningRequestMainOccupationEducation { + type: MainOccupation.Education; + education: SlutredovisningRequestMainOccupationEducationDetails; +} + +export interface SlutredovisningRequestMainOccupationOtherDetails { + otherExplanation: string; +} + +export interface SlutredovisningRequestMainOccupationOther { + type: MainOccupation.Other; + other: SlutredovisningRequestMainOccupationOtherDetails; +} + +export interface SlutredovisningRequestMainOccupationStillUnemployedDetails { + reasonsGoalNotReached: StillUnemployedReason[]; + otherExplanation: string; +} + +export interface SlutredovisningRequestMainOccupationStillUnemployed { + type: MainOccupation.StillUnemployed; + stillUnemployed: SlutredovisningRequestMainOccupationStillUnemployedDetails; +} + +export type SlutredovisningRequestMainOccupationDetails = + | SlutredovisningRequestMainOccupationWork + | SlutredovisningRequestMainOccupationEducation + | SlutredovisningRequestMainOccupationOther + | SlutredovisningRequestMainOccupationStillUnemployed; + +export interface SlutredovisningRequest { + genomforandereferens: number; + mainOccupation: SlutredovisningRequestMainOccupationDetails; + activities: { id: string; whatHasBeenDone: string }[]; + progressDescription: string; + nextStepDescription: string; + otherInformation: string; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.response.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.response.model.ts new file mode 100644 index 0000000..56231c8 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/api/slutredovisning.response.model.ts @@ -0,0 +1,70 @@ +import { + Anstallningsform, + EducationLength, + EducationLevel, + MainOccupation, + Omfattning, + StillUnemployedReason, +} from '@msfa-models/slutredovisning.model'; + +export interface SlutredovisningResponseMainOccupationWorkDetails { + yrkesomrade: string; + yrkesgrupp: string; + yrkesomradeName: string; + yrkesgruppName: string; + anstallningsform: Anstallningsform; + otherExplanation: string; + omfattning: Omfattning; + omfattningPercent: number; +} + +export interface SlutredovisningResponseMainOccupationWork { + type: MainOccupation.Work; + work: SlutredovisningResponseMainOccupationWorkDetails[]; +} + +export interface SlutredovisningResponseMainOccupationEducationDetails { + educationLevel: EducationLevel; + otherExplanation: string; + educationLength: EducationLength; + educationSpecification: string; +} + +export interface SlutredovisningResponseMainOccupationEducation { + type: MainOccupation.Education; + education: SlutredovisningResponseMainOccupationEducationDetails; +} + +export interface SlutredovisningResponseMainOccupationOtherDetails { + otherExplanation: string; +} + +export interface SlutredovisningResponseMainOccupationOther { + type: MainOccupation.Other; + other: SlutredovisningResponseMainOccupationOtherDetails; +} + +export interface SlutredovisningResponseMainOccupationStillUnemployedDetails { + reasonsGoalNotReached: StillUnemployedReason[]; + otherExplanation: string; +} + +export interface SlutredovisningResponseMainOccupationStillUnemployed { + type: MainOccupation.StillUnemployed; + stillUnemployed: SlutredovisningResponseMainOccupationStillUnemployedDetails; +} + +export type SlutredovisningResponseMainOccupationDetails = + | SlutredovisningResponseMainOccupationWork + | SlutredovisningResponseMainOccupationEducation + | SlutredovisningResponseMainOccupationOther + | SlutredovisningResponseMainOccupationStillUnemployed; + +export interface SlutredovisningResponse { + genomforandereferens: number; + mainOccupation: SlutredovisningResponseMainOccupationDetails; + activities: { id: string; whatHasBeenDone: string; name: string }[]; + progressDescription: string; + nextStepDescription: string; + otherInformation: string; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/yrkesgrupp.response.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/yrkesgrupp.response.model.ts new file mode 100644 index 0000000..5e30520 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/api/yrkesgrupp.response.model.ts @@ -0,0 +1,5 @@ +export interface YrkesgruppResponse { + id: string; + name: string; + parentId: string; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/api/yrkesomrade.response.model.ts b/apps/mina-sidor-fa/src/app/shared/models/api/yrkesomrade.response.model.ts new file mode 100644 index 0000000..7ee1707 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/api/yrkesomrade.response.model.ts @@ -0,0 +1,7 @@ +import { YrkesgruppResponse } from './yrkesgrupp.response.model'; + +export interface YrkesomradeResponse { + id: string; + name: string; + items: YrkesgruppResponse[]; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/slutredovisning.model.ts b/apps/mina-sidor-fa/src/app/shared/models/slutredovisning.model.ts new file mode 100644 index 0000000..0cfa46b --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/slutredovisning.model.ts @@ -0,0 +1,108 @@ +import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; + +export enum MainOccupation { + Work = 'work', + Education = 'education', + StillUnemployed = 'stillUnemployed', + ByteTillNyLeverantorIRustaOchMatcha = 'byte till ny leverantör i rusta och matcha', + Other = 'other', +} + +export enum EducationLevel { + HogskolaEllerUniversitet = 'högskola eller universitet', + Yrkeshogskola = 'yrkeshögskola', + KomvuxGymnasiumFolkhogskola = 'komvux, gymnasium eller folkhögskola', + VetEj = 'vet ej', + Annat = 'annat', +} + +export function educationLevelToString(educationLevel: EducationLevel): string | null { + switch (educationLevel) { + case EducationLevel.HogskolaEllerUniversitet: + return 'Högskola eller universitet'; + case EducationLevel.Yrkeshogskola: + return 'Yrkeshögskola'; + case EducationLevel.KomvuxGymnasiumFolkhogskola: + return 'Komvux, gymnasium eller folkhögskola'; + case EducationLevel.VetEj: + return 'Vet ej'; + case EducationLevel.Annat: + return 'Annat'; + default: + return null; + } +} + +export enum StillUnemployedReason { + SaknarRelevantUtbildning = 'saknar relevant utbildning', + SaknarArbetslivserfarenhet = 'saknar arbetslivserfarenhet', + SaknarNatverkOchKontakter = 'saknar nätverk och kontakter', + BristandeSprakkunskaperISvenska = 'bristande språkkunskaper i svenska', + KonjukturLaget = 'konjunkturläget', + Annat = 'annat', +} + +export enum EducationLength { + UpToOneYear = 'upp till ett år', + OneToTwoYears = 'ett år till två år', + OverTwoYears = 'två år eller längre', +} + +export function educationLengthToString(educationLength: EducationLength): string | null { + switch (educationLength) { + case EducationLength.UpToOneYear: + return 'Upp till ett år'; + case EducationLength.OneToTwoYears: + return 'Ett år till två år'; + case EducationLength.OverTwoYears: + return 'Två år eller längre'; + default: + return null; + } +} + +export enum Anstallningsform { + Tillsvidare = 'tillsvidareanställning', + Prov = 'provanstallning', + Visstid = 'visstidsanställning', + VetEj = 'vet ej', + Annat = 'annat', +} + +export enum Omfattning { + Heltid = 'heltid', + Deltid = 'deltid', + VetEj = 'vet ej', +} + +export function omfattningToString(omfattning: Omfattning): string | null { + switch (omfattning) { + case Omfattning.Heltid: + return 'Heltid'; + case Omfattning.Deltid: + return 'Deltid'; + case Omfattning.VetEj: + return 'Vet ej'; + default: + return null; + } +} + +export type Slutredovisning = SlutredovisningResponse; + +export function mainOccupationToString(mainOccupation: MainOccupation): string | null { + switch (mainOccupation) { + case MainOccupation.Education: + return 'Utbildning'; + case MainOccupation.StillUnemployed: + return 'Fortsatt arbetssökande'; + case MainOccupation.ByteTillNyLeverantorIRustaOchMatcha: + return 'Byte till ny leverantör i Rusta och matcha'; + case MainOccupation.Other: + return 'Annat'; + case MainOccupation.Work: + return 'Arbete'; + default: + return null; + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/yrkesgrupp.model.ts b/apps/mina-sidor-fa/src/app/shared/models/yrkesgrupp.model.ts new file mode 100644 index 0000000..0454e03 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/yrkesgrupp.model.ts @@ -0,0 +1,13 @@ +import { YrkesgruppResponse } from './api/yrkesgrupp.response.model'; + +export interface Yrkesgrupp { + value: string; + name: string; + parentId: string; +} + +export function mapResponseToYrkesgrupp(data: YrkesgruppResponse): Yrkesgrupp { + const { id, name, parentId } = data; + + return { value: id, name, parentId }; +} diff --git a/apps/mina-sidor-fa/src/app/shared/models/yrkesomrade.model.ts b/apps/mina-sidor-fa/src/app/shared/models/yrkesomrade.model.ts new file mode 100644 index 0000000..75534e3 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/models/yrkesomrade.model.ts @@ -0,0 +1,26 @@ +import { YrkesomradeResponse } from './api/yrkesomrade.response.model'; +import { mapResponseToYrkesgrupp, Yrkesgrupp } from './yrkesgrupp.model'; + +export interface Yrkesomrade { + value: string; + name: string; + items: Yrkesgrupp[]; +} + +export function mapResponseToYrkesomrade(data: YrkesomradeResponse): Yrkesomrade { + const { id, name, items } = data; + + return { value: id, name, items: items.map(item => mapResponseToYrkesgrupp(item)) }; +} + +export function yrkeToTextMap(yrkesomraden: Yrkesomrade[]): { [key: string]: string } { + const translateMap: { [key: string]: string } = {}; + + yrkesomraden.forEach(yrkesomrade => { + translateMap[yrkesomrade.value] = yrkesomrade.name; + yrkesomrade.items.forEach(yrkesgrupp => { + translateMap[yrkesgrupp.value] = yrkesgrupp.name; + }); + }); + return translateMap; +} diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts index d477a82..7358caa 100644 --- a/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts +++ b/apps/mina-sidor-fa/src/app/shared/services/api/handlingar.api.service.ts @@ -6,6 +6,7 @@ import { FranvaroReportResponse } from '@msfa-models/api/franvaro-response.model import { GemensamPlaneringResponse } from '@msfa-models/api/gemensam-planering.response.model'; import { InformativRapportResponse } from '@msfa-models/api/informativ-rapport.response.model'; import { Observable } from 'rxjs'; +import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; @Injectable({ providedIn: 'root', @@ -34,4 +35,8 @@ export class HandlingarApiService { public fetchAvvikelseReport$(handlingId: string): Observable<{ data: AvvikelseReportResponse }> { return this.httpClient.get<{ data: AvvikelseReportResponse }>(`${this._apiBaseUrl}/avvikelse/${handlingId}`); } + + public fetchSlutredovisning$(handlingId: string) { + return this.httpClient.get<{ data: SlutredovisningResponse }>(`${this._apiBaseUrl}/slutredovisning/${handlingId}`); + } } diff --git a/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts b/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts new file mode 100644 index 0000000..87bfd82 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/services/api/slutredovisning.api.service.ts @@ -0,0 +1,43 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { YRKEN } from '@msfa-constants/yrken'; +import { ErrorType } from '@msfa-enums/error-type.enum'; +import { environment } from '@msfa-environment'; +import { SlutredovisningRequest } from '@msfa-models/api/slutredovisning.request.model'; +import { SlutredovisningResponse } from '@msfa-models/api/slutredovisning.response.model'; +import { YrkesomradeResponse } from '@msfa-models/api/yrkesomrade.response.model'; +import { CustomError } from '@msfa-models/error/custom-error'; +import { Observable, of } from 'rxjs'; +import { catchError } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root', +}) +export class SlutredovisningApiService { + private _apiBaseUrl = `${environment.api.url}/rapporter/slutredovisning`; + private _handlingarBaseUrl = `${environment.api.url}/handlingar`; + + constructor(private httpClient: HttpClient) {} + + public fetchYrken$(): Observable<{ data: YrkesomradeResponse[] }> { + return of({ data: YRKEN }); + } + + public fetchSlutredovisning$(handlingId: string): Observable<{ data: SlutredovisningResponse }> { + return this.httpClient.get<{ data: SlutredovisningResponse }>( + `${this._handlingarBaseUrl}/slutredovisning/${handlingId}` + ); + } + + public submitSlutredovisning$(requestData: SlutredovisningRequest): Observable { + return this.httpClient.post(`${this._apiBaseUrl}`, requestData).pipe( + catchError((error: Error) => { + throw new CustomError({ + error, + message: `Kunde inte spara Periodisk redovisning.\n\n${error.message}`, + type: ErrorType.API, + }); + }) + ); + } +} diff --git a/apps/mina-sidor-fa/src/app/shared/utils/capitalize-sentence.util.ts b/apps/mina-sidor-fa/src/app/shared/utils/capitalize-sentence.util.ts new file mode 100644 index 0000000..caa7b86 --- /dev/null +++ b/apps/mina-sidor-fa/src/app/shared/utils/capitalize-sentence.util.ts @@ -0,0 +1,3 @@ +export function capitalizeSentence(sentence: string): string { + return sentence.charAt(0).toUpperCase() + sentence.slice(1); +} diff --git a/apps/mina-sidor-fa/src/environments/active-features.ts b/apps/mina-sidor-fa/src/environments/active-features.ts index 914f8c1..b0f8cd2 100644 --- a/apps/mina-sidor-fa/src/environments/active-features.ts +++ b/apps/mina-sidor-fa/src/environments/active-features.ts @@ -28,6 +28,7 @@ export const ACTIVE_FEATURES_TEST: Feature[] = [ Feature.VERSION_INFO, Feature.REPORTING_PERIODISK_REDOVISNING, Feature.REPORTING_INFORMATIV_RAPPORT, + Feature.SLUTREDOVISNING, Feature.EXPORTS, Feature.NEWS, ]; diff --git a/libs/ui/src/error-list/error-link.model.ts b/libs/ui/src/error-list/error-link.model.ts new file mode 100644 index 0000000..8a628bf --- /dev/null +++ b/libs/ui/src/error-list/error-link.model.ts @@ -0,0 +1,4 @@ +export interface ErrorLink { + elementId: string; + text: string; +} diff --git a/libs/ui/src/error-list/error-list.component.html b/libs/ui/src/error-list/error-list.component.html new file mode 100644 index 0000000..6cf2c3e --- /dev/null +++ b/libs/ui/src/error-list/error-list.component.html @@ -0,0 +1,11 @@ + + + {{ validationErrorLink.text }} + + diff --git a/libs/ui/src/error-list/error-list.component.scss b/libs/ui/src/error-list/error-list.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/libs/ui/src/error-list/error-list.component.spec.ts b/libs/ui/src/error-list/error-list.component.spec.ts new file mode 100644 index 0000000..d3bf62d --- /dev/null +++ b/libs/ui/src/error-list/error-list.component.spec.ts @@ -0,0 +1,25 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ErrorListComponent } from './error-list.component'; + +describe('ErrorListComponent', () => { + let component: ErrorListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [ErrorListComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ErrorListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/error-list/error-list.component.ts b/libs/ui/src/error-list/error-list.component.ts new file mode 100644 index 0000000..38ca2e6 --- /dev/null +++ b/libs/ui/src/error-list/error-list.component.ts @@ -0,0 +1,33 @@ +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { ErrorLink } from './error-link.model'; + +@Component({ + selector: 'ui-error-list', + templateUrl: './error-list.component.html', + styleUrls: ['./error-list.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ErrorListComponent { + @Input() uiErrorLinks: ErrorLink[] = []; + @Input() uiHeadingText: string; + @Input() uiDescription: string; + + setFocusOnFormElement(element: HTMLElement): void { + const id = element.getAttribute('href').replace('#', ''); + const target = document.getElementById(id); + + if (target) { + const targetPosition: DOMRect = target.getBoundingClientRect(); + const absoluteElementPosition = targetPosition.top + window.scrollY; + const newPosition = absoluteElementPosition - window.innerHeight / 2; + + if (target.focus) { + console.log(target); + target.tabIndex = -1; + target.focus(); + window.scrollTo(0, newPosition); + target.tabIndex = 0; + } + } + } +} diff --git a/libs/ui/src/error-list/error-list.module.ts b/libs/ui/src/error-list/error-list.module.ts new file mode 100644 index 0000000..2abdd63 --- /dev/null +++ b/libs/ui/src/error-list/error-list.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { ErrorListComponent } from './error-list.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + declarations: [ErrorListComponent], + imports: [CommonModule], + exports: [ErrorListComponent], +}) +export class UiErrorListModule {} diff --git a/libs/ui/src/input/input-type.enum.ts b/libs/ui/src/input/input-type.enum.ts new file mode 100644 index 0000000..1dfc614 --- /dev/null +++ b/libs/ui/src/input/input-type.enum.ts @@ -0,0 +1,16 @@ +export enum UiInputType { + COLOR = 'color', + DATE = 'date', + DATETIME_LOCAL = 'datetime-local', + EMAIL = 'email', + HIDDEN = 'hidden', + MONTH = 'month', + NUMBER = 'number', + PASSWORD = 'password', + SEARCH = 'search', + TEL = 'tel', + TEXT = 'text', + TIME = 'time', + URL = 'url', + WEEK = 'week', +} diff --git a/libs/ui/src/input/input-variation.enum.ts b/libs/ui/src/input/input-variation.enum.ts new file mode 100644 index 0000000..d61bd7c --- /dev/null +++ b/libs/ui/src/input/input-variation.enum.ts @@ -0,0 +1,5 @@ +export enum UiInputVariation { + S = 's', + M = 'm', + L = 'l', +} diff --git a/libs/ui/src/input/input.component.html b/libs/ui/src/input/input.component.html new file mode 100644 index 0000000..f8c1105 --- /dev/null +++ b/libs/ui/src/input/input.component.html @@ -0,0 +1,23 @@ +
    + + +
    diff --git a/libs/ui/src/input/input.component.scss b/libs/ui/src/input/input.component.scss new file mode 100644 index 0000000..780deb5 --- /dev/null +++ b/libs/ui/src/input/input.component.scss @@ -0,0 +1,8 @@ +.ui-input { + display: flex; + flex-direction: column; + + &--invalid { + gap: var(--digi--layout--gutter--s); + } +} diff --git a/libs/ui/src/input/input.component.spec.ts b/libs/ui/src/input/input.component.spec.ts new file mode 100644 index 0000000..920614f --- /dev/null +++ b/libs/ui/src/input/input.component.spec.ts @@ -0,0 +1,23 @@ +/* tslint:disable:no-unused-variable */ +import { InputComponent } from './input.component'; + +export class MockInjector { + get = jest.fn(); +} + +// tslint:disable-next-line: max-classes-per-file +export class MockChangeDetectorRef { + markForCheck = jest.fn(); + detach = jest.fn(); + detectChanges = jest.fn(); + reattach = jest.fn(); + checkNoChanges = jest.fn(); +} + +describe('InputComponent', () => { + let component: InputComponent; + it('should create', () => { + component = new InputComponent(new MockInjector(), new MockChangeDetectorRef()); + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/input/input.component.stories.ts b/libs/ui/src/input/input.component.stories.ts new file mode 100644 index 0000000..c4c9318 --- /dev/null +++ b/libs/ui/src/input/input.component.stories.ts @@ -0,0 +1,16 @@ +import { ReactiveFormsModule } from '@angular/forms'; +import { InputComponent } from './input.component'; +import { UiInputModule } from './input.module'; + +export default { title: 'Input', component: InputComponent }; + +const componentModule = { + moduleMetadata: { + imports: [ReactiveFormsModule, UiInputModule], + }, +}; + +export const standard = () => ({ + ...componentModule, + template: '', +}); diff --git a/libs/ui/src/input/input.component.ts b/libs/ui/src/input/input.component.ts new file mode 100644 index 0000000..fa4f200 --- /dev/null +++ b/libs/ui/src/input/input.component.ts @@ -0,0 +1,100 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + Injector, + Input, + OnChanges, + Output, +} from '@angular/core'; +import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { uuid } from '@utils/uuid.util'; +import { UiInputType } from './input-type.enum'; +import { UiInputVariation } from './input-variation.enum'; + +/** + * A input input. Implemented with control value accessor + * + * ## Usage + * ``import {UiInputModule} from '@ui/input/input.module';`` + */ +@Component({ + selector: 'ui-input', + templateUrl: './input.component.html', + styleUrls: ['./input.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: InputComponent, + multi: true, + }, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class InputComponent implements AfterViewInit, ControlValueAccessor, OnChanges { + @Input() uiId: string = uuid(); + @Input() uiName: string; + @Input() uiLabel: string = ''; + @Input() uiDescription: string; + @Input() uiVariation: UiInputVariation = UiInputVariation.M; + @Input() uiRequired: boolean; + @Input() uiAnnounceIfOptional: boolean = false; + @Input() uiMin: number; + @Input() uiMax: number; + @Input() uiType: UiInputType = UiInputType.TEXT; + @Input() uiInvalid: boolean; + @Input() uiValidationMessage: string; + @Output() uiOnChange: EventEmitter = new EventEmitter(); + + name: string | number; + + onTouched: () => {}; + private onChange: (value: any) => {}; + private _value: any; + + constructor(private injector: Injector, private changeDetectorRef: ChangeDetectorRef) {} + + get currentValue(): string { + return this._value || ''; + } + + ngAfterViewInit(): void { + const ngControl: NgControl = this.injector.get(NgControl, null); + if (ngControl) { + this.name = this.uiName || ngControl.name; + } + } + + ngOnChanges(): void { + const ngControl: NgControl = this.injector.get(NgControl, null); + if (ngControl) { + this.name = this.uiName || ngControl.name; + } + } + + checkForChange(rawValue: string): void { + const value = this.uiType === UiInputType.NUMBER ? +rawValue : rawValue; + if (this._value !== value) { + if (this.onChange) { + this.onChange(value); + } + this._value = value; + this.uiOnChange.emit(value); + } + } + + writeValue(value: any): void { + this._value = value; + this.changeDetectorRef.detectChanges(); + } + + registerOnChange(fn: (value: string) => {}) { + this.onChange = fn; + } + + registerOnTouched(fn: () => {}) { + this.onTouched = fn; + } +} diff --git a/libs/ui/src/input/input.module.ts b/libs/ui/src/input/input.module.ts new file mode 100644 index 0000000..e46332b --- /dev/null +++ b/libs/ui/src/input/input.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { InputComponent } from './input.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + imports: [CommonModule], + declarations: [InputComponent], + exports: [InputComponent], +}) +export class UiInputModule {} diff --git a/libs/ui/src/radiobutton-group/radiobutton-group.component.html b/libs/ui/src/radiobutton-group/radiobutton-group.component.html index 65112d5..6511ae4 100644 --- a/libs/ui/src/radiobutton-group/radiobutton-group.component.html +++ b/libs/ui/src/radiobutton-group/radiobutton-group.component.html @@ -1,8 +1,9 @@
    (); @@ -85,19 +87,20 @@ export class RadiobuttonGroupComponent implements ControlValueAccessor, AfterVie ngAfterViewInit(): void { const ngControl: NgControl = this.injector.get(NgControl, null); if (ngControl) { - this.name = ngControl.name || this.uiName; + this.name = this.uiName || ngControl.name; } } ngOnChanges(): void { const ngControl: NgControl = this.injector.get(NgControl, null); if (ngControl) { - this.name = ngControl.name || this.uiName; + this.name = this.uiName || ngControl.name; } } checkForChange(rawValue: any): void { const value = this._transformValue(rawValue); + console.log(value); if (this._value !== value) { if (this.onChange) { this.onChange(value); diff --git a/libs/ui/src/select/select-option.model.ts b/libs/ui/src/select/select-option.model.ts new file mode 100644 index 0000000..d3480fd --- /dev/null +++ b/libs/ui/src/select/select-option.model.ts @@ -0,0 +1,4 @@ +export interface SelectOption { + value: any; + name: string; +} diff --git a/libs/ui/src/select/select.component.html b/libs/ui/src/select/select.component.html new file mode 100644 index 0000000..63f3711 --- /dev/null +++ b/libs/ui/src/select/select.component.html @@ -0,0 +1,45 @@ +
    +
    + +
    + + +
    +
    +
    + {{uiValidationMessage}} +
    +
    diff --git a/libs/ui/src/select/select.component.scss b/libs/ui/src/select/select.component.scss new file mode 100644 index 0000000..a63e058 --- /dev/null +++ b/libs/ui/src/select/select.component.scss @@ -0,0 +1,45 @@ +@import 'variables/gutters'; +@import 'functions/rem'; + +.ui-select { + display: flex; + flex-direction: column; + + &--invalid { + gap: var(--digi--layout--gutter--xs); + } + + &__select-wrapper { + position: relative; + display: flex; + align-items: center; + } + + &__select { + appearance: none; + width: 100%; + padding: var(--digi--ui--input--padding); + padding-right: var(--digi--layout--padding--30); + height: var(--digi--ui--input--height); + border-width: rem(1); + cursor: pointer; + font-size: var(--digi--typography--font-size--m); + color: var(--digi--typography--color--text); + background-color: var(--digi--ui--color--background); + border-color: var(--digi--ui--input--border--color); + + &--invalid { + border-color: var(--digi--ui--color--border--error); + background-color: var(--digi--ui--color--background--error); + } + } + + &__option { + font-size: var(--digi--typography--font-size--l); + } + + &__icon { + position: absolute; + right: rem(12); + } +} diff --git a/libs/ui/src/select/select.component.spec.ts b/libs/ui/src/select/select.component.spec.ts new file mode 100644 index 0000000..bd9c808 --- /dev/null +++ b/libs/ui/src/select/select.component.spec.ts @@ -0,0 +1,26 @@ +/* tslint:disable:no-unused-variable */ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { SelectComponent } from './select.component'; + +describe('SelectComponent', () => { + let component: SelectComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SelectComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(SelectComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/libs/ui/src/select/select.component.stories.ts b/libs/ui/src/select/select.component.stories.ts new file mode 100644 index 0000000..30fc5a4 --- /dev/null +++ b/libs/ui/src/select/select.component.stories.ts @@ -0,0 +1,16 @@ +import { ReactiveFormsModule } from '@angular/forms'; +import { SelectComponent } from './select.component'; +import { UiSelectModule } from './select.module'; + +export default { title: 'Select', component: SelectComponent }; + +const componentModule = { + moduleMetadata: { + imports: [ReactiveFormsModule, UiSelectModule], + }, +}; + +export const standard = () => ({ + ...componentModule, + template: '', +}); diff --git a/libs/ui/src/select/select.component.ts b/libs/ui/src/select/select.component.ts new file mode 100644 index 0000000..422717d --- /dev/null +++ b/libs/ui/src/select/select.component.ts @@ -0,0 +1,111 @@ +import { + AfterViewInit, + ChangeDetectionStrategy, + ChangeDetectorRef, + Component, + EventEmitter, + Injector, + Input, + OnChanges, + Output, +} from '@angular/core'; +import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms'; +import { uuid } from '@utils/uuid.util'; +import { SelectOption } from './select-option.model'; + +/** + * A select component. + * + * ## Usage + * ``import {UiSelectModule} from '@ui/select/select.module';`` + */ +@Component({ + selector: 'ui-select', + templateUrl: './select.component.html', + styleUrls: ['./select.component.scss'], + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: SelectComponent, + multi: true, + }, + ], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class SelectComponent implements ControlValueAccessor, AfterViewInit, OnChanges { + @Input() uiInvalid: boolean; + @Input() uiValidationMessage: string; + @Input() uiPlaceholder: string; + @Input() uiOptions: SelectOption[]; + @Input() uiRequired: boolean; + @Input() uiLabel: string; + @Input() uiDescription: string; + @Input() uiAnnounceIfOptional: boolean; + @Input() uiId: string = uuid(); + @Input() uiName: string; + @Output() uiOnChange = new EventEmitter(); + + name: string | number; + onTouched: () => {}; + private onChange: (value: any) => {}; + private _value: any; + + constructor(private injector: Injector, private changeDetectorRef: ChangeDetectorRef) {} + + get currentValue(): any { + return this._value; + } + + private get _requiredText() { + if (this.uiRequired && !this.uiAnnounceIfOptional) { + return ' (obligatoriskt)'; + } + + if (!this.uiRequired && this.uiAnnounceIfOptional) { + return ' (frivilligt)'; + } + + return ''; + } + + getLabelText(label: string): string { + return `${label}${this._requiredText}`; + } + + ngAfterViewInit(): void { + const ngControl: NgControl = this.injector.get(NgControl, null); + if (ngControl) { + this.name = this.uiName || ngControl.name; + } + } + + ngOnChanges(): void { + const ngControl: NgControl = this.injector.get(NgControl, null); + if (ngControl) { + this.name = this.uiName || ngControl.name; + } + } + + checkForChange(value: any): void { + if (this._value !== value) { + if (this.onChange) { + this.onChange(value); + } + this._value = value; + this.uiOnChange.emit(value); + } + } + + writeValue(value: any): void { + this._value = value; + this.changeDetectorRef.detectChanges(); + } + + registerOnChange(fn: (value: any) => {}) { + this.onChange = fn; + } + + registerOnTouched(fn: () => {}) { + this.onTouched = fn; + } +} diff --git a/libs/ui/src/select/select.module.ts b/libs/ui/src/select/select.module.ts new file mode 100644 index 0000000..593d220 --- /dev/null +++ b/libs/ui/src/select/select.module.ts @@ -0,0 +1,11 @@ +import { CommonModule } from '@angular/common'; +import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { SelectComponent } from './select.component'; + +@NgModule({ + schemas: [CUSTOM_ELEMENTS_SCHEMA], + imports: [CommonModule], + declarations: [SelectComponent], + exports: [SelectComponent], +}) +export class UiSelectModule {} diff --git a/mock-api/mina-sidor-fa/scripts/deltagare-handelser.js b/mock-api/mina-sidor-fa/scripts/deltagare-handelser.js index 77a734d..00a769f 100644 --- a/mock-api/mina-sidor-fa/scripts/deltagare-handelser.js +++ b/mock-api/mina-sidor-fa/scripts/deltagare-handelser.js @@ -1,4 +1,5 @@ import faker from 'faker'; + faker.locale = 'sv'; const HANDELSER = [