From cfe3d0753aa82ea58c2f25a4e9475845a87a4075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dvar=20Oddsson?= Date: Mon, 16 Dec 2024 11:28:52 +0000 Subject: [PATCH 1/6] feat(j-s): Notifications sent when court officials are assigned (#17169) * Send notifications to court officials * Fix body * Send spesific judge notification * Send spesific registrar notifications * Send notifications in states received and submitted * Cleanup * Merge * Remove console.log * Refactor * Refactor * Rename variables * Remove redundant code --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../backend/src/app/messages/notifications.ts | 15 ++++++ .../src/app/modules/case/case.service.ts | 52 ++++++++++++++++++ .../modules/notification/guards/rolesRules.ts | 2 +- .../caseNotification.service.ts | 53 +++++++++++++++++++ .../types/src/lib/notification.ts | 2 + 5 files changed, 123 insertions(+), 1 deletion(-) diff --git a/apps/judicial-system/backend/src/app/messages/notifications.ts b/apps/judicial-system/backend/src/app/messages/notifications.ts index 43bda5af9fb3..ed00262e39d9 100644 --- a/apps/judicial-system/backend/src/app/messages/notifications.ts +++ b/apps/judicial-system/backend/src/app/messages/notifications.ts @@ -856,4 +856,19 @@ export const notifications = { description: 'Texti í pósti til aðila máls þegar ný gögn eru send', }, }), + courtOfficialAssignedEmail: defineMessages({ + subject: { + id: 'judicial.system.backend:notifications.court_official_assigned_email.subject', + defaultMessage: 'Úthlutun máls {courtCaseNumber}', + description: + 'Fyrirsögn í pósti til dómara og dómritara þegar máli er úthlutað á þau', + }, + body: { + id: 'judicial.system.backend:notifications.court_official_assigned_email.body', + defaultMessage: + 'Héraðsdómur hefur skráð þig sem {role, select, DISTRICT_COURT_JUDGE {dómara} DISTRICT_COURT_REGISTRAR {dómritara} other {óþekkt}} í máli {courtCaseNumber}. Hægt er að nálgast gögn málsins á {linkStart}yfirlitssíðu málsins í Réttarvörslugátt{linkEnd}', + description: + 'Texti í pósti til dómara og dómritara þegar máli er úthlutað á þau', + }, + }), } diff --git a/apps/judicial-system/backend/src/app/modules/case/case.service.ts b/apps/judicial-system/backend/src/app/modules/case/case.service.ts index b9980ed191fd..75fe945637d3 100644 --- a/apps/judicial-system/backend/src/app/modules/case/case.service.ts +++ b/apps/judicial-system/backend/src/app/modules/case/case.service.ts @@ -687,6 +687,34 @@ export class CaseService { ]) } + private addMessagesForDistrictCourtJudgeAssignedToQueue( + theCase: Case, + user: TUser, + ): Promise { + return this.messageService.sendMessagesToQueue([ + { + type: MessageType.NOTIFICATION, + user, + caseId: theCase.id, + body: { type: CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED }, + }, + ]) + } + + private addMessagesForDistrictCourtRegistrarAssignedToQueue( + theCase: Case, + user: TUser, + ): Promise { + return this.messageService.sendMessagesToQueue([ + { + type: MessageType.NOTIFICATION, + user, + caseId: theCase.id, + body: { type: CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED }, + }, + ]) + } + private addMessagesForReceivedCaseToQueue( theCase: Case, user: TUser, @@ -1403,6 +1431,30 @@ export class CaseService { } } + if ( + isIndictment && + [CaseState.SUBMITTED, CaseState.RECEIVED].includes(updatedCase.state) + ) { + const isJudgeChanged = + updatedCase.judge?.nationalId !== theCase.judge?.nationalId + const isRegistrarChanged = + updatedCase.registrar?.nationalId !== theCase.registrar?.nationalId + + if (isJudgeChanged) { + await this.addMessagesForDistrictCourtJudgeAssignedToQueue( + updatedCase, + user, + ) + } + + if (isRegistrarChanged) { + await this.addMessagesForDistrictCourtRegistrarAssignedToQueue( + updatedCase, + user, + ) + } + } + if ( isIndictment && ![ diff --git a/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts b/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts index 04cccc5de218..567e17620945 100644 --- a/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts +++ b/apps/judicial-system/backend/src/app/modules/notification/guards/rolesRules.ts @@ -28,7 +28,7 @@ export const defenderNotificationRule: RolesRule = { ], } as RolesRule -// Allows district court judges to send notifiications +// Allows district court judges to send notifications export const districtCourtJudgeNotificationRule: RolesRule = { role: UserRole.DISTRICT_COURT_JUDGE, type: RulesType.FIELD_VALUES, diff --git a/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts index 0c4cbba076cb..fe2aa576b272 100644 --- a/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts +++ b/apps/judicial-system/backend/src/app/modules/notification/services/caseNotification/caseNotification.service.ts @@ -21,6 +21,7 @@ import { INDICTMENTS_OVERVIEW_ROUTE, INVESTIGATION_CASE_POLICE_CONFIRMATION_ROUTE, RESTRICTION_CASE_OVERVIEW_ROUTE, + ROUTE_HANDLER_ROUTE, SIGNED_VERDICT_OVERVIEW_ROUTE, } from '@island.is/judicial-system/consts' import { @@ -46,6 +47,7 @@ import { RequestSharedWithDefender, SessionArrangements, type User, + UserRole, } from '@island.is/judicial-system/types' import { @@ -689,6 +691,28 @@ export class CaseNotificationService extends BaseNotificationService { }) } + private sendCourtOfficialAssignedEmailNotificationForIndictmentCase( + theCase: Case, + role: UserRole.DISTRICT_COURT_JUDGE | UserRole.DISTRICT_COURT_REGISTRAR, + ): Promise { + const official = + role === UserRole.DISTRICT_COURT_JUDGE ? theCase.judge : theCase.registrar + + return this.sendEmail( + this.formatMessage(notifications.courtOfficialAssignedEmail.subject, { + courtCaseNumber: theCase.courtCaseNumber, + }), + this.formatMessage(notifications.courtOfficialAssignedEmail.body, { + courtCaseNumber: theCase.courtCaseNumber, + role, + linkStart: ``, + linkEnd: '', + }), + official?.name, + official?.email, + ) + } + private sendCourtDateEmailNotificationForIndictmentCase( theCase: Case, user: User, @@ -810,6 +834,25 @@ export class CaseNotificationService extends BaseNotificationService { return result } + + private async sendDistrictCourtUserAssignedNotifications( + theCase: Case, + userRole: UserRole.DISTRICT_COURT_JUDGE | UserRole.DISTRICT_COURT_REGISTRAR, + ): Promise { + const recipient = + await this.sendCourtOfficialAssignedEmailNotificationForIndictmentCase( + theCase, + userRole, + ) + + return await this.recordNotification( + theCase.id, + userRole === UserRole.DISTRICT_COURT_JUDGE + ? CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED + : CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED, + [recipient], + ) + } //#endregion //#region RULING notifications @@ -2552,6 +2595,16 @@ export class CaseNotificationService extends BaseNotificationService { return this.sendReceivedByCourtNotifications(theCase) case CaseNotificationType.COURT_DATE: return this.sendCourtDateNotifications(theCase, user) + case CaseNotificationType.DISTRICT_COURT_JUDGE_ASSIGNED: + return this.sendDistrictCourtUserAssignedNotifications( + theCase, + UserRole.DISTRICT_COURT_JUDGE, + ) + case CaseNotificationType.DISTRICT_COURT_REGISTRAR_ASSIGNED: + return this.sendDistrictCourtUserAssignedNotifications( + theCase, + UserRole.DISTRICT_COURT_REGISTRAR, + ) case CaseNotificationType.RULING: return this.sendRulingNotifications(theCase) case CaseNotificationType.MODIFIED: diff --git a/libs/judicial-system/types/src/lib/notification.ts b/libs/judicial-system/types/src/lib/notification.ts index 347cef7b5852..ee863976b056 100644 --- a/libs/judicial-system/types/src/lib/notification.ts +++ b/libs/judicial-system/types/src/lib/notification.ts @@ -3,6 +3,8 @@ export enum CaseNotificationType { READY_FOR_COURT = 'READY_FOR_COURT', RECEIVED_BY_COURT = 'RECEIVED_BY_COURT', COURT_DATE = 'COURT_DATE', + DISTRICT_COURT_JUDGE_ASSIGNED = 'DISTRICT_COURT_JUDGE_ASSIGNED', + DISTRICT_COURT_REGISTRAR_ASSIGNED = 'DISTRICT_COURT_REGISTRAR_ASSIGNED', RULING = 'RULING', MODIFIED = 'MODIFIED', REVOKED = 'REVOKED', From 8aa0e52a9dfd19ad27258eb3d94c45a629e2d351 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sn=C3=A6r=20Seljan=20=C3=9E=C3=B3roddsson?= Date: Mon, 16 Dec 2024 12:40:15 +0000 Subject: [PATCH 2/6] fix(services-bff): Add missing exp check on the user endpoint (#17247) * fix(user): enhance token refresh logic with expiration check Add a utility function to check if the access token has expired before attempting to refresh it. This change improves the efficiency of the token refresh process by ensuring that refresh operations are only triggered when necessary. * test: enhance user token refresh logic in tests Add tests to verify token refresh behavior based on token expiration and refresh query parameter. Ensure that the refreshToken service is called only when the token exists, is expired, and refresh is set to true. This improves test coverage and ensures correct handling of token refresh scenarios. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../app/modules/user/user.controller.spec.ts | 112 ++++++++++++++++++ .../bff/src/app/modules/user/user.service.ts | 7 +- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/apps/services/bff/src/app/modules/user/user.controller.spec.ts b/apps/services/bff/src/app/modules/user/user.controller.spec.ts index dba1a6918e0a..a6dfc9d72ef6 100644 --- a/apps/services/bff/src/app/modules/user/user.controller.spec.ts +++ b/apps/services/bff/src/app/modules/user/user.controller.spec.ts @@ -230,5 +230,117 @@ describe('UserController', () => { profile: expiredTokenResponse.userProfile, }) }) + + it('should not refresh token when token exists but is not expired', async () => { + // Arrange - Set up login attempt in cache + mockCacheStore.set( + `attempt::${mockConfig.name}::${SID_VALUE}`, + createLoginAttempt(mockConfig), + ) + + // Initialize session + await server.get('/login') + await server + .get('/callbacks/login') + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + .query({ code: 'some_code', state: SID_VALUE }) + + // Set valid (not expired) token in cache + const validTokenResponse = { + ...mockCachedTokenResponse, + accessTokenExp: Date.now() + 1000, // Future expiration + } + mockCacheStore.set( + `current::${mockConfig.name}::${SID_VALUE}`, + validTokenResponse, + ) + + // Act + const res = await server + .get('/user') + .query({ refresh: 'true' }) + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + + // Assert + expect(mockTokenRefreshService.refreshToken).not.toHaveBeenCalled() + expect(res.status).toEqual(HttpStatus.OK) + expect(res.body).toEqual({ + scopes: validTokenResponse.scopes, + profile: validTokenResponse.userProfile, + }) + }) + + it('should refresh token only when all conditions are met (token exists, is expired, and refresh=true)', async () => { + // Arrange - Set up login attempt in cache + mockCacheStore.set( + `attempt::${mockConfig.name}::${SID_VALUE}`, + createLoginAttempt(mockConfig), + ) + + const testCases = [ + { + exists: true, + expired: true, + refresh: true, + shouldCallRefresh: true, + }, + { + exists: true, + expired: true, + refresh: false, + shouldCallRefresh: false, + }, + { + exists: true, + expired: false, + refresh: true, + shouldCallRefresh: false, + }, + { + exists: false, + expired: true, + refresh: true, + shouldCallRefresh: false, + }, + ] + + for (const testCase of testCases) { + // Reset mocks + jest.clearAllMocks() + mockCacheStore.clear() + + if (testCase.exists) { + const tokenResponse = { + ...mockCachedTokenResponse, + accessTokenExp: testCase.expired + ? Date.now() - 1000 // Expired + : Date.now() + 1000, // Not expired + } + mockCacheStore.set( + `current::${mockConfig.name}::${SID_VALUE}`, + tokenResponse, + ) + } + + // Act + const res = await server + .get('/user') + .query({ refresh: testCase.refresh.toString() }) + .set('Cookie', [`${SESSION_COOKIE_NAME}=${SID_VALUE}`]) + + // Assert + if (testCase.shouldCallRefresh) { + expect(mockTokenRefreshService.refreshToken).toHaveBeenCalled() + } else { + expect(mockTokenRefreshService.refreshToken).not.toHaveBeenCalled() + } + + if (testCase.exists) { + expect(res.status).toEqual(HttpStatus.OK) + } else { + expect(res.status).toEqual(HttpStatus.UNAUTHORIZED) + } + } + }) }) }) diff --git a/apps/services/bff/src/app/modules/user/user.service.ts b/apps/services/bff/src/app/modules/user/user.service.ts index 4babb4df7a4e..74f576a5d8aa 100644 --- a/apps/services/bff/src/app/modules/user/user.service.ts +++ b/apps/services/bff/src/app/modules/user/user.service.ts @@ -5,6 +5,7 @@ import { BffUser } from '@island.is/shared/types' import { SESSION_COOKIE_NAME } from '../../constants/cookies' import { ErrorService } from '../../services/error.service' +import { hasTimestampExpiredInMS } from '../../utils/has-timestamp-expired-in-ms' import { CachedTokenResponse } from '../auth/auth.types' import { TokenRefreshService } from '../auth/token-refresh.service' import { CacheService } from '../cache/cache.service' @@ -58,7 +59,11 @@ export class UserService { false, ) - if (cachedTokenResponse && refresh) { + if ( + cachedTokenResponse && + hasTimestampExpiredInMS(cachedTokenResponse.accessTokenExp) && + refresh + ) { cachedTokenResponse = await this.tokenRefreshService.refreshToken({ sid, encryptedRefreshToken: cachedTokenResponse.encryptedRefreshToken, From 3314c57c5bd40570899c1ee0fb5f7d22dab2b960 Mon Sep 17 00:00:00 2001 From: norda-gunni <161026627+norda-gunni@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:12:04 +0000 Subject: [PATCH 3/6] feat(application-system): Add phone and email fields to tablerepeater (#17219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial field and validation * feat(ExampleForm): Update table repeater field and validation schema - Renamed 'rentalHousingLandlordInfoTable' to 'tableRepeaterField' in ExampleForm. - Updated ExampleSchema to include validation for the new 'tableRepeaterField' structure. - Enhanced NationalIdWithName component to accept phone and email default values. - Refactored error handling in NationalIdWithName for better validation feedback. - Cleaned up unused code in TableRepeaterFormField for improved readability. * fix lint * cleanup * Error message cleanup * cleanup * Refine dataschema * PR comment * Fix field layout * Cleanup types * Revert example form changes * Update libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx Add suggestion from jonni Co-authored-by: Jónas G. Sigurðsson --------- Co-authored-by: Jónas G. Sigurðsson Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../reference-template/src/lib/dataSchema.ts | 14 ++ libs/application/types/src/lib/Fields.ts | 6 + .../NationalIdWithName/NationalIdWithName.tsx | 202 ++++++++++++------ 3 files changed, 153 insertions(+), 69 deletions(-) diff --git a/libs/application/templates/reference-template/src/lib/dataSchema.ts b/libs/application/templates/reference-template/src/lib/dataSchema.ts index faa3b728cff4..e4945ef27981 100644 --- a/libs/application/templates/reference-template/src/lib/dataSchema.ts +++ b/libs/application/templates/reference-template/src/lib/dataSchema.ts @@ -15,6 +15,20 @@ const careerHistoryCompaniesValidation = (data: any) => { } export const ExampleSchema = z.object({ approveExternalData: z.boolean().refine((v) => v), + tableRepeaterField: z.array( + z.object({ + nationalIdWithName: z.object({ + name: z.string().min(1).max(256), + nationalId: z.string().refine((n) => n && kennitala.isValid(n), { + params: m.dataSchemeNationalId, + }), + phone: z.string().refine(isValidNumber, { + params: m.dataSchemePhoneNumber, + }), + email: z.string().email(), + }), + }), + ), person: z.object({ name: z.string().min(1).max(256), age: z.string().refine((x) => { diff --git a/libs/application/types/src/lib/Fields.ts b/libs/application/types/src/lib/Fields.ts index fafd82964b7c..24a2c9ac8884 100644 --- a/libs/application/types/src/lib/Fields.ts +++ b/libs/application/types/src/lib/Fields.ts @@ -89,6 +89,8 @@ export type RepeaterItem = { */ displayInTable?: boolean label?: StaticText + phoneLabel?: StaticText + emailLabel?: StaticText placeholder?: StaticText options?: TableRepeaterOptions backgroundColor?: 'blue' | 'white' @@ -99,6 +101,10 @@ export type RepeaterItem = { activeField?: Record, ) => boolean dataTestId?: string + showPhoneField?: boolean + phoneRequired?: boolean + showEmailField?: boolean + emailRequired?: boolean readonly?: | boolean | (( diff --git a/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx b/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx index fb42f7b19422..e2786a44a3bd 100644 --- a/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx +++ b/libs/application/ui-components/src/components/NationalIdWithName/NationalIdWithName.tsx @@ -1,11 +1,7 @@ import { FC, useEffect, useState } from 'react' import { GridRow, GridColumn } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' -import { - coreErrorMessages, - getErrorViaPath, - getValueViaPath, -} from '@island.is/application/core' +import { coreErrorMessages, getValueViaPath } from '@island.is/application/core' import { Application, StaticText } from '@island.is/application/types' import { gql, useLazyQuery } from '@apollo/client' import { @@ -13,7 +9,10 @@ import { Query, RskCompanyInfoInput, } from '@island.is/api/schema' -import { InputController } from '@island.is/shared/form-fields' +import { + InputController, + PhoneInputController, +} from '@island.is/shared/form-fields' import { useFormContext } from 'react-hook-form' import * as kennitala from 'kennitala' import debounce from 'lodash/debounce' @@ -27,14 +26,23 @@ interface NationalIdWithNameProps { customId?: string customNationalIdLabel?: StaticText customNameLabel?: StaticText + phoneLabel?: StaticText + emailLabel?: StaticText + phoneRequired?: boolean + emailRequired?: boolean onNationalIdChange?: (s: string) => void onNameChange?: (s: string) => void nationalIdDefaultValue?: string nameDefaultValue?: string + phoneDefaultValue?: string + emailDefaultValue?: string errorMessage?: string minAgePerson?: number searchPersons?: boolean searchCompanies?: boolean + showPhoneField?: boolean + showEmailField?: boolean + error?: string } export const NationalIdWithName: FC< @@ -46,19 +54,30 @@ export const NationalIdWithName: FC< required, customId = '', customNationalIdLabel = '', + phoneLabel = '', + emailLabel = '', + phoneRequired = false, + emailRequired = false, customNameLabel = '', onNationalIdChange, onNameChange, nationalIdDefaultValue, nameDefaultValue, + phoneDefaultValue, + emailDefaultValue, errorMessage, minAgePerson, searchPersons = true, searchCompanies = false, + showPhoneField = false, + showEmailField = false, + error, }) => { const fieldId = customId.length > 0 ? customId : id const nameField = `${fieldId}.name` const nationalIdField = `${fieldId}.nationalId` + const emailField = `${fieldId}.email` + const phoneField = `${fieldId}.phone` const { formatMessage } = useLocale() const { @@ -69,12 +88,18 @@ export const NationalIdWithName: FC< const [personName, setPersonName] = useState('') const [companyName, setCompanyName] = useState('') - // get name validation errors - const nameFieldErrors = errorMessage - ? nameDefaultValue?.length === 0 - ? errorMessage - : undefined - : getErrorViaPath(errors, nameField) + const getFieldErrorString = ( + error: unknown, + id: string, + ): string | undefined => { + if (!error || typeof error !== 'object') return undefined + + const errorList = error as Record[] + if (!Array.isArray(errorList)) return undefined + + const fieldError = errorList[id as any] + return typeof fieldError === 'string' ? fieldError : undefined + } // get national id validation errors let nationalIdFieldErrors: string | undefined @@ -91,7 +116,7 @@ export const NationalIdWithName: FC< { minAge: minAgePerson }, ) } else if (!errorMessage) { - nationalIdFieldErrors = getErrorViaPath(errors, nationalIdField) + nationalIdFieldErrors = getFieldErrorString(error, 'nationalId') } // get default values @@ -101,6 +126,12 @@ export const NationalIdWithName: FC< const defaultName = nameDefaultValue ? nameDefaultValue : getValueViaPath(application.answers, nameField, '') + const defaultPhone = phoneDefaultValue + ? phoneDefaultValue + : getValueViaPath(application.answers, phoneField, '') + const defaultEmail = emailDefaultValue + ? emailDefaultValue + : getValueViaPath(application.answers, emailField, '') // query to get name by national id const [getIdentity, { data, loading: queryLoading, error: queryError }] = @@ -180,62 +211,95 @@ export const NationalIdWithName: FC< }, [personName, companyName, setValue, nameField, application.answers]) return ( - - - { - setNationalIdInput(v.target.value.replace(/\W/g, '')) - onNationalIdChange && - onNationalIdChange(v.target.value.replace(/\W/g, '')) - })} - loading={searchPersons ? queryLoading : companyQueryLoading} - error={nationalIdFieldErrors} - disabled={disabled} - /> - - - + + + { + setNationalIdInput(v.target.value.replace(/\W/g, '')) + onNationalIdChange && + onNationalIdChange(v.target.value.replace(/\W/g, '')) + })} + loading={searchPersons ? queryLoading : companyQueryLoading} + error={nationalIdFieldErrors} + disabled={disabled} + /> + + + - - + } + disabled + /> + + + {(showPhoneField || showEmailField) && ( + + {showPhoneField && ( + + + + )} + {showEmailField && ( + + + + )} + + )} + ) } From 271e5d2354358e14dfcf8a3610830f805b419145 Mon Sep 17 00:00:00 2001 From: helgifr Date: Mon, 16 Dec 2024 13:44:03 +0000 Subject: [PATCH 4/6] feat(new-primary-school): Add mock users for testing application hotfix (#17220) * feat(new-primary-school): Add mock users for testing application * remove console log * Removed mock user file --------- Co-authored-by: hfhelgason Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../new-primary-school.service.ts | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts b/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts index 80ce338d5cd2..15b415938eec 100644 --- a/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts +++ b/libs/application/template-api-modules/src/lib/modules/templates/new-primary-school/new-primary-school.service.ts @@ -13,6 +13,7 @@ import { TemplateApiModuleActionProps } from '../../../types' import { BaseTemplateApiService } from '../../base-template-api.service' import { transformApplicationToNewPrimarySchoolDTO } from './new-primary-school.utils' import { isRunningOnEnvironment } from '@island.is/shared/utils' +import { isRunningInProduction } from '../parental-leave/constants' @Injectable() export class NewPrimarySchoolService extends BaseTemplateApiService { @@ -38,6 +39,66 @@ export class NewPrimarySchoolService extends BaseTemplateApiService { } async getChildren({ auth }: TemplateApiModuleActionProps) { + if (!isRunningInProduction) { + if (auth.nationalId === '0101303019') { + return [ + { + nationalId: '1111111119', + fullName: 'Stubbur Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + if (auth.nationalId === '0101302989') { + return [ + { + nationalId: '2222222229', + fullName: 'Stúfur Maack ', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + otherParent: { + nationalId: '0101302399', + fullName: 'Gervimaður Færeyjar', + address: { + streetName: 'Hvassaleiti 5', + postalCode: '103', + city: 'Reykjavík', + municipalityCode: '0000', + }, + genderCode: '2', + }, + }, + { + nationalId: '5555555559', + fullName: 'Bína Maack ', + genderCode: '4', + livesWithApplicant: true, + livesWithBothParents: true, + }, + { + nationalId: '6666666669', + fullName: 'Snúður Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + if (auth.nationalId === '0101304929') { + return [ + { + nationalId: '6666666669', + fullName: 'Snúður Maack', + genderCode: '3', + livesWithApplicant: true, + livesWithBothParents: true, + }, + ] + } + } const children = await this.nationalRegistryService.getChildrenCustodyInformation(auth) From 0c7df8f3604c0a08e9329b881e1ba2a4618baf7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAnar=20Vestmann?= <43557895+RunarVestmann@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:23:51 +0000 Subject: [PATCH 5/6] feat(web): Pension Calculator - Display icon to left of title for 2025 preview (#17251) Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../PensionCalculator.css.ts | 4 ++ .../PensionCalculator.tsx | 33 ++++++-------- .../PensionCalculatorResults.tsx | 33 ++++++-------- .../PensionCalculatorTitle.tsx | 45 +++++++++++++++++++ .../translationStrings.ts | 7 +++ 5 files changed, 82 insertions(+), 40 deletions(-) create mode 100644 apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts index 66a268028923..8550d211f92b 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.css.ts @@ -46,3 +46,7 @@ export const yearSelectContainer = style({ md: { width: '204px' }, }), }) + +export const noWrap = style({ + flexWrap: 'nowrap', +}) diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx index 143a47f3b0de..2dfab0c78d4e 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculator.tsx @@ -50,6 +50,7 @@ import { GET_ORGANIZATION_PAGE_QUERY, GET_ORGANIZATION_QUERY, } from '../../queries' +import { PensionCalculatorTitle } from './PensionCalculatorTitle' import { PensionCalculatorWrapper } from './PensionCalculatorWrapper' import { translationStrings } from './translationStrings' import { @@ -554,16 +555,12 @@ const PensionCalculator: CustomScreen = ({ > - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage(translationStrings.isTurnedOff)}
@@ -584,16 +581,12 @@ const PensionCalculator: CustomScreen = ({ - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} +
= ({ > - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage(translationStrings.isTurnedOff)} @@ -391,16 +388,12 @@ const PensionCalculatorResults: CustomScreen = ({ - {isNewSystemActive && ( - - {title}
{titlePostfix}
-
- )} - {!isNewSystemActive && ( - - {title} {titlePostfix} - - )} + {formatMessage( diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx new file mode 100644 index 000000000000..4a61eb3b61fb --- /dev/null +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/PensionCalculatorTitle.tsx @@ -0,0 +1,45 @@ +import { useIntl } from 'react-intl' + +import { GridColumn, GridRow, Text } from '@island.is/island-ui/core' + +import { translationStrings } from './translationStrings' +import * as styles from './PensionCalculator.css' + +interface PensionCalculatorTitleProps { + isNewSystemActive: boolean + title: string + titlePostfix: string + titleVariant: 'h1' | 'h2' +} + +export const PensionCalculatorTitle = ({ + isNewSystemActive, + title, + titlePostfix, + titleVariant, +}: PensionCalculatorTitleProps) => { + const { formatMessage } = useIntl() + if (isNewSystemActive) + return ( + + + + + + + {title}
{titlePostfix}
+
+
+
+ ) + return ( + + {title} {titlePostfix} + + ) +} diff --git a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts index 8a273868f14b..89f5b13b9202 100644 --- a/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts +++ b/apps/web/screens/Organization/SocialInsuranceAdministration/translationStrings.ts @@ -625,6 +625,13 @@ export const translationStrings = defineMessages({ defaultMessage: 'Eftir 1. september 2025', description: 'Eftir 1. september 2025', }, + after1stSeptember2025IconUrl: { + id: 'web.pensionCalculator:after1stSeptember2025IconUrl', + defaultMessage: + 'https://images.ctfassets.net/8k0h54kbe6bj/5RIwKVet87Nm4ycltkzjnX/9c594855a9b2f90dde63766ee87a09ca/58dd40fbf365769d984be22a9b64bc29.png', + description: + 'Mynd vinstra megin við titil "Reiknivél örorku- og endurhæfingargreiðslna eftir 1. september 2025"', + }, after1stSeptember2025Calculate: { id: 'web.pensionCalculator:after1stSeptember2025Calculate', defaultMessage: 'Reikna', From 65767dcb54a01134fb1c6d12c40268fb28d81eed Mon Sep 17 00:00:00 2001 From: Ylfa <55542991+ylfahfa@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:35:22 +0000 Subject: [PATCH 6/6] feat(income-plan): Remove edit function after submission (#17246) * remove edit function after submission * format * remove unit test --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../income-plan/src/fields/Review/index.tsx | 15 --------------- .../src/lib/IncomePlanTemplate.spec.ts | 17 ----------------- .../income-plan/src/lib/IncomePlanTemplate.ts | 8 -------- .../income-plan/src/lib/messages.ts | 11 ++--------- 4 files changed, 2 insertions(+), 49 deletions(-) diff --git a/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx b/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx index 9a420ccf1e56..4dbb1ffe6f0c 100644 --- a/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx +++ b/libs/application/templates/social-insurance-administration/income-plan/src/fields/Review/index.tsx @@ -126,21 +126,6 @@ export const Review: FC = ({
- {state === `${States.TRYGGINGASTOFNUN_SUBMITTED}` && ( - - )}