diff --git a/apps/application-system/api/infra/application-system-api.ts b/apps/application-system/api/infra/application-system-api.ts index 0c3b5c273739..9cb0aa3406ea 100644 --- a/apps/application-system/api/infra/application-system-api.ts +++ b/apps/application-system/api/infra/application-system-api.ts @@ -49,80 +49,83 @@ export const GRAPHQL_API_URL_ENV_VAR_NAME = 'GRAPHQL_API_URL' // This property i const namespace = 'application-system' const serviceAccount = 'application-system-api' -export const workerSetup = - (): ServiceBuilder<'application-system-api-worker'> => - service('application-system-api-worker') - .namespace(namespace) - .image('application-system-api') - .db() - .serviceAccount('application-system-api-worker') - .redis() - .codeOwner(CodeOwners.NordaApplications) - .env({ - IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/application-system', - IDENTITY_SERVER_ISSUER_URL: { - dev: 'https://identity-server.dev01.devland.is', - staging: 'https://identity-server.staging01.devland.is', - prod: 'https://innskra.island.is', - }, - XROAD_CHARGE_FJS_V2_PATH: { - dev: 'IS-DEV/GOV/10021/FJS-Public/chargeFJS_v2', - staging: 'IS-TEST/GOV/10021/FJS-Public/chargeFJS_v2', - prod: 'IS/GOV/5402697509/FJS-Public/chargeFJS_v2', - }, - APPLICATION_ATTACHMENT_BUCKET: { - dev: 'island-is-dev-storage-application-system', - staging: 'island-is-staging-storage-application-system', - prod: 'island-is-prod-storage-application-system', - }, - FILE_SERVICE_PRESIGN_BUCKET: { - dev: 'island-is-dev-fs-presign-bucket', - staging: 'island-is-staging-fs-presign-bucket', - prod: 'island-is-prod-fs-presign-bucket', - }, - FILE_STORAGE_UPLOAD_BUCKET: { - dev: 'island-is-dev-upload-api', - staging: 'island-is-staging-upload-api', - prod: 'island-is-prod-upload-api', - }, - CLIENT_LOCATION_ORIGIN: { - dev: 'https://beta.dev01.devland.is/umsoknir', - staging: 'https://beta.staging01.devland.is/umsoknir', - prod: 'https://island.is/umsoknir', - local: 'http://localhost:4200/umsoknir', - }, - }) - .xroad(Base, Client, Payment, Inna, EHIC, WorkMachines) - .secrets({ - IDENTITY_SERVER_CLIENT_SECRET: - '/k8s/application-system/api/IDENTITY_SERVER_CLIENT_SECRET', - SYSLUMENN_HOST: '/k8s/application-system-api/SYSLUMENN_HOST', - SYSLUMENN_USERNAME: '/k8s/application-system/api/SYSLUMENN_USERNAME', - SYSLUMENN_PASSWORD: '/k8s/application-system/api/SYSLUMENN_PASSWORD', - DRIVING_LICENSE_BOOK_XROAD_PATH: - '/k8s/application-system-api/DRIVING_LICENSE_BOOK_XROAD_PATH', - DRIVING_LICENSE_BOOK_USERNAME: - '/k8s/application-system-api/DRIVING_LICENSE_BOOK_USERNAME', - DRIVING_LICENSE_BOOK_PASSWORD: - '/k8s/application-system-api/DRIVING_LICENSE_BOOK_PASSWORD', - DOKOBIT_ACCESS_TOKEN: - '/k8s/application-system/api/DOKOBIT_ACCESS_TOKEN', - DOKOBIT_URL: '/k8s/application-system-api/DOKOBIT_URL', - ARK_BASE_URL: '/k8s/application-system-api/ARK_BASE_URL', - DOMSYSLA_PASSWORD: '/k8s/application-system-api/DOMSYSLA_PASSWORD', - DOMSYSLA_USERNAME: '/k8s/application-system-api/DOMSYSLA_USERNAME', - }) - .args('main.js', '--job', 'worker') - .command('node') - .extraAttributes({ - dev: { schedule: '*/30 * * * *' }, - staging: { schedule: '*/30 * * * *' }, - prod: { schedule: '*/30 * * * *' }, - }) - .resources({ - limits: { cpu: '400m', memory: '768Mi' }, - requests: { cpu: '150m', memory: '384Mi' }, - }) +export const workerSetup = (services: { + userNotificationService: ServiceBuilder<'services-user-notification'> +}): ServiceBuilder<'application-system-api-worker'> => + service('application-system-api-worker') + .namespace(namespace) + .image('application-system-api') + .db() + .serviceAccount('application-system-api-worker') + .redis() + .codeOwner(CodeOwners.NordaApplications) + .env({ + IDENTITY_SERVER_CLIENT_ID: '@island.is/clients/application-system', + IDENTITY_SERVER_ISSUER_URL: { + dev: 'https://identity-server.dev01.devland.is', + staging: 'https://identity-server.staging01.devland.is', + prod: 'https://innskra.island.is', + }, + XROAD_CHARGE_FJS_V2_PATH: { + dev: 'IS-DEV/GOV/10021/FJS-Public/chargeFJS_v2', + staging: 'IS-TEST/GOV/10021/FJS-Public/chargeFJS_v2', + prod: 'IS/GOV/5402697509/FJS-Public/chargeFJS_v2', + }, + APPLICATION_ATTACHMENT_BUCKET: { + dev: 'island-is-dev-storage-application-system', + staging: 'island-is-staging-storage-application-system', + prod: 'island-is-prod-storage-application-system', + }, + FILE_SERVICE_PRESIGN_BUCKET: { + dev: 'island-is-dev-fs-presign-bucket', + staging: 'island-is-staging-fs-presign-bucket', + prod: 'island-is-prod-fs-presign-bucket', + }, + FILE_STORAGE_UPLOAD_BUCKET: { + dev: 'island-is-dev-upload-api', + staging: 'island-is-staging-upload-api', + prod: 'island-is-prod-upload-api', + }, + CLIENT_LOCATION_ORIGIN: { + dev: 'https://beta.dev01.devland.is/umsoknir', + staging: 'https://beta.staging01.devland.is/umsoknir', + prod: 'https://island.is/umsoknir', + local: 'http://localhost:4200/umsoknir', + }, + USER_NOTIFICATION_API_URL: ref( + (h) => `http://${h.svc(services.userNotificationService)}`, + ), + }) + .xroad(Base, Client, Payment, Inna, EHIC, WorkMachines) + .secrets({ + IDENTITY_SERVER_CLIENT_SECRET: + '/k8s/application-system/api/IDENTITY_SERVER_CLIENT_SECRET', + SYSLUMENN_HOST: '/k8s/application-system-api/SYSLUMENN_HOST', + SYSLUMENN_USERNAME: '/k8s/application-system/api/SYSLUMENN_USERNAME', + SYSLUMENN_PASSWORD: '/k8s/application-system/api/SYSLUMENN_PASSWORD', + DRIVING_LICENSE_BOOK_XROAD_PATH: + '/k8s/application-system-api/DRIVING_LICENSE_BOOK_XROAD_PATH', + DRIVING_LICENSE_BOOK_USERNAME: + '/k8s/application-system-api/DRIVING_LICENSE_BOOK_USERNAME', + DRIVING_LICENSE_BOOK_PASSWORD: + '/k8s/application-system-api/DRIVING_LICENSE_BOOK_PASSWORD', + DOKOBIT_ACCESS_TOKEN: '/k8s/application-system/api/DOKOBIT_ACCESS_TOKEN', + DOKOBIT_URL: '/k8s/application-system-api/DOKOBIT_URL', + ARK_BASE_URL: '/k8s/application-system-api/ARK_BASE_URL', + DOMSYSLA_PASSWORD: '/k8s/application-system-api/DOMSYSLA_PASSWORD', + DOMSYSLA_USERNAME: '/k8s/application-system-api/DOMSYSLA_USERNAME', + }) + .args('main.js', '--job', 'worker') + .command('node') + .extraAttributes({ + dev: { schedule: '*/30 * * * *' }, + staging: { schedule: '*/30 * * * *' }, + prod: { schedule: '*/30 * * * *' }, + }) + .resources({ + limits: { cpu: '400m', memory: '768Mi' }, + requests: { cpu: '150m', memory: '384Mi' }, + }) export const serviceSetup = (services: { documentsService: ServiceBuilder<'services-documents'> diff --git a/apps/web/components/connected/WHODAS/Calculator.css.ts b/apps/web/components/connected/WHODAS/Calculator.css.ts index c98463701223..81dca8be11dc 100644 --- a/apps/web/components/connected/WHODAS/Calculator.css.ts +++ b/apps/web/components/connected/WHODAS/Calculator.css.ts @@ -2,8 +2,20 @@ import { style } from '@vanilla-extract/css' import { theme } from '@island.is/island-ui/theme' +const leftWidth = 180 + export const breakdownRowContainer = style({ display: 'grid', - gridTemplateColumns: '180px 1fr', + gridTemplateColumns: `${leftWidth}px 1fr`, gap: theme.spacing[5], }) + +export const totalScoreRowContainer = style({ + display: 'grid', + gridTemplateColumns: `${leftWidth + 24}px 1fr`, + gap: theme.spacing[5], +}) + +export const stayOnSinglePageWhenPrinting = style({ + pageBreakInside: 'avoid', +}) diff --git a/apps/web/components/connected/WHODAS/Calculator.strings.ts b/apps/web/components/connected/WHODAS/Calculator.strings.ts index 5794e1786e71..8d81c1bb4750 100644 --- a/apps/web/components/connected/WHODAS/Calculator.strings.ts +++ b/apps/web/components/connected/WHODAS/Calculator.strings.ts @@ -62,6 +62,18 @@ export const m = { 'Takk fyrir að svara spurningalistanum, Mat á færni þinni. Mat þitt á færni er stuðningur við að meta þörf þína fyrir heimaþjónustu. Ef þú hefur ekki svarað öllum spurningum getur það haft áhrif á niðurstöðuna.', description: 'Texti fyrir ofan niðurstöðuskjá', }, + totalScore: { + id: 'web.whodas.calculator:results.totalScore', + defaultMessage: 'Stig samtals', + description: 'Stig samtals', + }, + resultDisclaimer: { + id: 'web.whodas.calculator:results.resultDisclaimer', + defaultMessage: + 'Gott er að prenta út eða senda sér svarið. Það getur gangast við umsókn um heimaþjónustu.', + description: + 'Gott er að prenta út eða senda sér svarið. Það getur gangast við umsókn um heimaþjónustu.', + }, mainHeading: { id: 'web.whodas.calculator:form.mainHeading', defaultMessage: 'Niðurstaða mats á færni', @@ -77,16 +89,6 @@ export const m = { defaultMessage: 'Heildarstig', description: 'Heildarstig', }, - firstBracketScoreText: { - id: 'web.whodas.calculator:form.firstBracketScoreText', - defaultMessage: '0 til 16,9 stig', - description: 'Lítil skerðing á færni - "Score" texti', - }, - secondBracketScoreText: { - id: 'web.whodas.calculator:form.secondBracketScoreText', - defaultMessage: '17 til 100 stig', - description: 'Talsverð skerðing á færni - "Score" texti', - }, firstBracketInterpretationText: { id: 'web.whodas.calculator:form.firstBracketInterpretationText', defaultMessage: 'Lítil skerðing á færni', diff --git a/apps/web/components/connected/WHODAS/Calculator.tsx b/apps/web/components/connected/WHODAS/Calculator.tsx index 99ff866974b7..109eb573ccfa 100644 --- a/apps/web/components/connected/WHODAS/Calculator.tsx +++ b/apps/web/components/connected/WHODAS/Calculator.tsx @@ -6,6 +6,7 @@ import { useState, } from 'react' import { useIntl } from 'react-intl' +import round from 'lodash/round' import { Box, @@ -25,6 +26,10 @@ import { MarkdownText } from '../../Organization' import { m } from './Calculator.strings' import * as styles from './Calculator.css' +const formatScore = (score: number) => { + return String(round(score, 1)).replace('.', ',') +} + interface Question { question: string answerOptions: { @@ -41,6 +46,7 @@ interface Step { interface CheckboxState { steps: { title: string + maxScorePossible: number questions: { selectedAnswerIndex: number answerScore: number @@ -119,74 +125,73 @@ interface WHODASResultsProps { steps: (Pick & { scoreForStep: number })[] } bracket: 1 | 2 + totalScore: number } -const WHODASResults = ({ results, bracket }: WHODASResultsProps) => { +const WHODASResults = ({ + results, + bracket, + totalScore, +}: WHODASResultsProps) => { const { format } = useDateUtils() const date = format(new Date(), 'do MMMM yyyy') const { formatMessage } = useIntl() return ( - - - - {formatMessage(m.results.mainHeading)} - - - - {date} - - - {formatMessage(m.results.scoreHeading)} - - + + + + + {formatMessage(m.results.mainHeading)} + + + + {date} + + + {formatMessage(m.results.scoreHeading)} + + + {formatScore(totalScore)} + + + + + {formatMessage(m.results.interpretationHeading)} + {formatMessage( bracket === 1 - ? m.results.firstBracketScoreText - : m.results.secondBracketScoreText, + ? m.results.firstBracketInterpretationText + : m.results.secondBracketInterpretationText, )} - - - - - {formatMessage(m.results.interpretationHeading)} - - - {formatMessage( - bracket === 1 - ? m.results.firstBracketInterpretationText - : m.results.secondBracketInterpretationText, - )} - - - - - - {formatMessage(m.results.adviceHeading)} - - - {formatMessage( - bracket === 1 - ? m.results.firstBracketAdviceText - : m.results.secondBracketAdviceText, - )} - - + - {bracket !== 1 && ( + + {formatMessage(m.results.adviceHeading)} + + + {formatMessage( + bracket === 1 + ? m.results.firstBracketAdviceText + : m.results.secondBracketAdviceText, + )} + + + + {formatMessage(m.results.breakdownHeading)} @@ -195,13 +200,27 @@ const WHODASResults = ({ results, bracket }: WHODASResultsProps) => { {step.title} - {step.scoreForStep} + {formatScore(step.scoreForStep)} ))} + + + {formatMessage(m.results.totalScore)} + + {formatScore(totalScore)} + - )} + + + {formatMessage(m.results.resultDisclaimer)} + ) } @@ -225,6 +244,13 @@ export const WHODASCalculator = ({ slice }: WHODASCalculatorProps) => { steps: steps.map(({ title, description, questions }) => ({ title, description, + maxScorePossible: questions.reduce( + (prev, acc) => + prev + acc.answerOptions.length > 0 + ? acc.answerOptions[acc.answerOptions.length - 1].score + : 0, + 0, + ), questions: questions.map(() => ({ selectedAnswerIndex: 0, answerScore: 0, @@ -245,30 +271,41 @@ export const WHODASCalculator = ({ slice }: WHODASCalculatorProps) => { if (showResults) { let totalScore = 0 + let totalMaxScorePossible = 0 const results: WHODASResultsProps['results'] = { steps: [], } for (const stateStep of state.steps) { + totalMaxScorePossible += stateStep.maxScorePossible let score = 0 for (const question of stateStep.questions) { score += question.answerScore } - results.steps.push({ ...stateStep, scoreForStep: score }) totalScore += score + if (stateStep.maxScorePossible > 0) { + score = (score * 100) / stateStep.maxScorePossible + } + results.steps.push({ ...stateStep, scoreForStep: score }) + } + if (totalMaxScorePossible > 0) { + totalScore = (totalScore * 100) / totalMaxScorePossible } return ( {formatMessage(m.results.topDescription)} - + + + ) } diff --git a/charts/islandis/values.dev.yaml b/charts/islandis/values.dev.yaml index 0a6d35e252cf..0dd1634ad8ad 100644 --- a/charts/islandis/values.dev.yaml +++ b/charts/islandis/values.dev.yaml @@ -852,6 +852,7 @@ application-system-api-worker: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: '' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.dev01.devland.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.dev01.devland.is/r1/IS-DEV' XROAD_CHARGE_FJS_V2_PATH: 'IS-DEV/GOV/10021/FJS-Public/chargeFJS_v2' diff --git a/charts/islandis/values.prod.yaml b/charts/islandis/values.prod.yaml index cbc83be17d50..04619e6f6b0a 100644 --- a/charts/islandis/values.prod.yaml +++ b/charts/islandis/values.prod.yaml @@ -840,6 +840,7 @@ application-system-api-worker: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.whakos.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.island.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.island.is/r1/IS' XROAD_CHARGE_FJS_V2_PATH: 'IS/GOV/5402697509/FJS-Public/chargeFJS_v2' diff --git a/charts/islandis/values.staging.yaml b/charts/islandis/values.staging.yaml index 36116c21bc12..a2192f932e41 100644 --- a/charts/islandis/values.staging.yaml +++ b/charts/islandis/values.staging.yaml @@ -849,6 +849,7 @@ application-system-api-worker: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.ab9ckb.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: '' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.staging01.devland.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.staging01.devland.is/r1/IS-TEST' XROAD_CHARGE_FJS_V2_PATH: 'IS-TEST/GOV/10021/FJS-Public/chargeFJS_v2' diff --git a/charts/services/application-system-api-worker/values.dev.yaml b/charts/services/application-system-api-worker/values.dev.yaml index 5f8102c047e2..91699959fa25 100644 --- a/charts/services/application-system-api-worker/values.dev.yaml +++ b/charts/services/application-system-api-worker/values.dev.yaml @@ -41,6 +41,7 @@ env: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.5fzau3.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: '' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.dev01.devland.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.dev01.devland.is/r1/IS-DEV' XROAD_CHARGE_FJS_V2_PATH: 'IS-DEV/GOV/10021/FJS-Public/chargeFJS_v2' diff --git a/charts/services/application-system-api-worker/values.prod.yaml b/charts/services/application-system-api-worker/values.prod.yaml index e8c6b233d0c0..e484a5d20bb8 100644 --- a/charts/services/application-system-api-worker/values.prod.yaml +++ b/charts/services/application-system-api-worker/values.prod.yaml @@ -41,6 +41,7 @@ env: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.whakos.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: 'driving-license-use-v1-endpoint-for-v2-comms' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.island.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.island.is/r1/IS' XROAD_CHARGE_FJS_V2_PATH: 'IS/GOV/5402697509/FJS-Public/chargeFJS_v2' diff --git a/charts/services/application-system-api-worker/values.staging.yaml b/charts/services/application-system-api-worker/values.staging.yaml index 1b3b2c57186f..a654300a66ef 100644 --- a/charts/services/application-system-api-worker/values.staging.yaml +++ b/charts/services/application-system-api-worker/values.staging.yaml @@ -41,6 +41,7 @@ env: NODE_OPTIONS: '--max-old-space-size=691 -r dd-trace/init' REDIS_URL_NODE_01: '["clustercfg.general-redis-cluster-group.ab9ckb.euw1.cache.amazonaws.com:6379"]' SERVERSIDE_FEATURES_ON: '' + USER_NOTIFICATION_API_URL: 'http://web-user-notification.user-notification.svc.cluster.local' XROAD_BASE_PATH: 'http://securityserver.staging01.devland.is' XROAD_BASE_PATH_WITH_ENV: 'http://securityserver.staging01.devland.is/r1/IS-TEST' XROAD_CHARGE_FJS_V2_PATH: 'IS-TEST/GOV/10021/FJS-Public/chargeFJS_v2' diff --git a/infra/src/uber-charts/islandis.ts b/infra/src/uber-charts/islandis.ts index 705e3c1113f0..569b921bc2bf 100644 --- a/infra/src/uber-charts/islandis.ts +++ b/infra/src/uber-charts/islandis.ts @@ -85,7 +85,9 @@ const appSystemApi = appSystemApiSetup({ servicePortalApi, userNotificationService, }) -const appSystemApiWorker = appSystemApiWorkerSetup() +const appSystemApiWorker = appSystemApiWorkerSetup({ + userNotificationService, +}) const nameRegistryBackend = serviceNameRegistryBackendSetup()