diff --git a/apps/contentful-apps/pages/fields/admin-only-boolean-field.tsx b/apps/contentful-apps/pages/fields/admin-only-boolean-field.tsx new file mode 100644 index 000000000000..3bf79f5d25a3 --- /dev/null +++ b/apps/contentful-apps/pages/fields/admin-only-boolean-field.tsx @@ -0,0 +1,16 @@ +import { FieldExtensionSDK } from '@contentful/app-sdk' +import { Paragraph } from '@contentful/f36-components' +import { BooleanEditor } from '@contentful/field-editor-boolean' +import { useSDK } from '@contentful/react-apps-toolkit' + +const AdminOnlyBooleanField = () => { + const sdk = useSDK() + + if (!sdk.user.spaceMembership.admin) { + return (Only admins can edit this field) + } + + return +} + +export default AdminOnlyBooleanField diff --git a/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts b/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts index 589709247bd9..437900ffb488 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/models/defendant.model.ts @@ -110,6 +110,9 @@ export class Defendant { @Field(() => String, { nullable: true }) readonly sentToPrisonAdminDate?: string + @Field(() => String, { nullable: true }) + readonly openedByPrisonAdminDate?: string + @Field(() => PunishmentType, { nullable: true }) readonly punishmentType?: PunishmentType } 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 75fe945637d3..3adf5cac8f0d 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 @@ -417,6 +417,16 @@ export const caseListInclude: Includeable[] = [ as: 'defendants', required: false, order: [['created', 'ASC']], + include: [ + { + model: DefendantEventLog, + as: 'eventLogs', + required: false, + where: { eventType: defendantEventTypes }, + order: [['created', 'DESC']], + separate: true, + }, + ], separate: true, }, { diff --git a/apps/judicial-system/backend/src/app/modules/case/interceptors/case.interceptor.ts b/apps/judicial-system/backend/src/app/modules/case/interceptors/case.interceptor.ts index 85e302ad6754..adfb51abe7f2 100644 --- a/apps/judicial-system/backend/src/app/modules/case/interceptors/case.interceptor.ts +++ b/apps/judicial-system/backend/src/app/modules/case/interceptors/case.interceptor.ts @@ -7,6 +7,8 @@ import { NestInterceptor, } from '@nestjs/common' +import { DefendantEventType } from '@island.is/judicial-system/types' + import { Defendant, DefendantEventLog } from '../../defendant' import { Case } from '../models/case.model' import { CaseString } from '../models/caseString.model' @@ -15,8 +17,15 @@ export const transformDefendants = (defendants?: Defendant[]) => { return defendants?.map((defendant) => ({ ...defendant.toJSON(), sentToPrisonAdminDate: defendant.isSentToPrisonAdmin - ? DefendantEventLog.sentToPrisonAdminDate(defendant.eventLogs)?.created + ? DefendantEventLog.getDefendantEventLogTypeDate({ + defendantEventLogs: defendant.eventLogs, + eventType: DefendantEventType.SENT_TO_PRISON_ADMIN, + }) : undefined, + openedByPrisonAdminDate: DefendantEventLog.getDefendantEventLogTypeDate({ + defendantEventLogs: defendant.eventLogs, + eventType: DefendantEventType.OPENED_BY_PRISON_ADMIN, + }), })) } diff --git a/apps/judicial-system/backend/src/app/modules/case/interceptors/defendantIndictmentAccessed.interceptor.ts b/apps/judicial-system/backend/src/app/modules/case/interceptors/defendantIndictmentAccessed.interceptor.ts new file mode 100644 index 000000000000..64d122d8db7c --- /dev/null +++ b/apps/judicial-system/backend/src/app/modules/case/interceptors/defendantIndictmentAccessed.interceptor.ts @@ -0,0 +1,63 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + NestInterceptor, +} from '@nestjs/common' + +import { + DefendantEventType, + isIndictmentCase, + isPrisonAdminUser, + User, +} from '@island.is/judicial-system/types' + +import { DefendantEventLog, DefendantService } from '../../defendant' +import { Case } from '../models/case.model' + +const hasValidOpenByPrisonAdminEvent = ( + defendantEventLogs: DefendantEventLog[], +) => { + const sentToPrisonAdminDate = DefendantEventLog.getDefendantEventLogTypeDate({ + defendantEventLogs, + eventType: DefendantEventType.SENT_TO_PRISON_ADMIN, + }) + const openedByPrisonAdminDate = + DefendantEventLog.getDefendantEventLogTypeDate({ + defendantEventLogs, + eventType: DefendantEventType.OPENED_BY_PRISON_ADMIN, + }) + return ( + sentToPrisonAdminDate && + openedByPrisonAdminDate && + sentToPrisonAdminDate <= openedByPrisonAdminDate + ) +} + +@Injectable() +export class DefendantIndictmentAccessedInterceptor implements NestInterceptor { + constructor(private readonly defendantService: DefendantService) {} + + intercept(context: ExecutionContext, next: CallHandler) { + const request = context.switchToHttp().getRequest() + const user: User = request.user + const theCase: Case = request.case + + if (isIndictmentCase(theCase.type) && isPrisonAdminUser(user)) { + const defendantsIndictmentNotOpened = theCase.defendants?.filter( + ({ isSentToPrisonAdmin, eventLogs = [] }) => + isSentToPrisonAdmin && !hasValidOpenByPrisonAdminEvent(eventLogs), + ) + + // create new events for all defendants that prison admin has not accessed according to defendant event logs + defendantsIndictmentNotOpened?.forEach((defendant) => + this.defendantService.createDefendantEvent({ + caseId: theCase.id, + defendantId: defendant.id, + eventType: DefendantEventType.OPENED_BY_PRISON_ADMIN, + }), + ) + } + return next.handle() + } +} diff --git a/apps/judicial-system/backend/src/app/modules/case/limitedAccessCase.controller.ts b/apps/judicial-system/backend/src/app/modules/case/limitedAccessCase.controller.ts index c263e83f455d..be63d588328f 100644 --- a/apps/judicial-system/backend/src/app/modules/case/limitedAccessCase.controller.ts +++ b/apps/judicial-system/backend/src/app/modules/case/limitedAccessCase.controller.ts @@ -30,13 +30,16 @@ import type { User as TUser } from '@island.is/judicial-system/types' import { CaseState, CaseType, + DefendantEventType, indictmentCases, investigationCases, restrictionCases, + UserRole, } from '@island.is/judicial-system/types' import { nowFactory } from '../../factories' import { defenderRule, prisonSystemStaffRule } from '../../guards' +import { DefendantService } from '../defendant' import { EventService } from '../event' import { User } from '../user' import { TransitionCaseDto } from './dto/transitionCase.dto' @@ -57,6 +60,7 @@ import { } from './guards/rolesRules' import { CaseInterceptor } from './interceptors/case.interceptor' import { CompletedAppealAccessedInterceptor } from './interceptors/completedAppealAccessed.interceptor' +import { DefendantIndictmentAccessedInterceptor } from './interceptors/defendantIndictmentAccessed.interceptor' import { LimitedAccessCaseFileInterceptor } from './interceptors/limitedAccessCaseFile.interceptor' import { Case } from './models/case.model' import { transitionCase } from './state/case.state' @@ -73,6 +77,7 @@ export class LimitedAccessCaseController { private readonly limitedAccessCaseService: LimitedAccessCaseService, private readonly eventService: EventService, private readonly pdfService: PdfService, + private readonly defendantService: DefendantService, @Inject(LOGGER_PROVIDER) private readonly logger: Logger, ) {} @@ -84,6 +89,7 @@ export class LimitedAccessCaseController { ) @RolesRules(prisonSystemStaffRule, defenderRule) @UseInterceptors( + DefendantIndictmentAccessedInterceptor, CompletedAppealAccessedInterceptor, LimitedAccessCaseFileInterceptor, CaseInterceptor, @@ -100,7 +106,7 @@ export class LimitedAccessCaseController { ): Promise { this.logger.debug(`Getting limitedAccess case ${caseId} by id`) - if (!theCase.openedByDefender) { + if (user.role === UserRole.DEFENDER && !theCase.openedByDefender) { const updated = await this.limitedAccessCaseService.update( theCase, { openedByDefender: nowFactory() }, diff --git a/apps/judicial-system/backend/src/app/modules/case/test/limitedAccessCaseController/getById.spec.ts b/apps/judicial-system/backend/src/app/modules/case/test/limitedAccessCaseController/getById.spec.ts index 034bded816f0..4036446f36ed 100644 --- a/apps/judicial-system/backend/src/app/modules/case/test/limitedAccessCaseController/getById.spec.ts +++ b/apps/judicial-system/backend/src/app/modules/case/test/limitedAccessCaseController/getById.spec.ts @@ -1,6 +1,6 @@ import { uuid } from 'uuidv4' -import type { User } from '@island.is/judicial-system/types' +import { type User, UserRole } from '@island.is/judicial-system/types' import { createTestingCaseModule } from '../createTestingCaseModule' @@ -14,14 +14,18 @@ interface Then { error: Error } -type GivenWhenThen = (caseId: string, theCase: Case) => Promise +type GivenWhenThen = ( + caseId: string, + theCase: Case, + user?: User, +) => Promise describe('LimitedAccessCaseController - Get by id', () => { let givenWhenThen: GivenWhenThen const openedBeforeDate = randomDate() const openedNowDate = randomDate() const caseId = uuid() - const user = { id: uuid() } as User + const defaultUser = { id: uuid() } as User let mockCaseModel: typeof Case @@ -42,7 +46,11 @@ describe('LimitedAccessCaseController - Get by id', () => { const mockFindOne = mockCaseModel.findOne as jest.Mock mockFindOne.mockResolvedValue(updatedCase) - givenWhenThen = async (caseId: string, theCase: Case) => { + givenWhenThen = async ( + caseId: string, + theCase: Case, + user = defaultUser, + ) => { const then = {} as Then try { @@ -79,11 +87,11 @@ describe('LimitedAccessCaseController - Get by id', () => { describe('case exists and has not been opened by defender before', () => { const theCase = { id: caseId } as Case - + const user = { ...defaultUser, role: UserRole.DEFENDER } as User let then: Then beforeEach(async () => { - then = await givenWhenThen(caseId, theCase) + then = await givenWhenThen(caseId, theCase, user) }) it('should update openedByDefender and return case', () => { diff --git a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts index 6276f0634115..d1f24d828393 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/defendant.service.ts @@ -271,6 +271,22 @@ export class DefendantService { return updatedDefendant } + async createDefendantEvent({ + caseId, + defendantId, + eventType, + }: { + caseId: string + defendantId: string + eventType: DefendantEventType + }): Promise { + await this.defendantEventLogModel.create({ + caseId, + defendantId, + eventType, + }) + } + async updateIndictmentCaseDefendant( theCase: Case, defendant: Defendant, @@ -284,7 +300,7 @@ export class DefendantService { ) if (update.isSentToPrisonAdmin) { - this.defendantEventLogModel.create({ + this.createDefendantEvent({ caseId: theCase.id, defendantId: defendant.id, eventType: DefendantEventType.SENT_TO_PRISON_ADMIN, diff --git a/apps/judicial-system/backend/src/app/modules/defendant/models/defendantEventLog.model.ts b/apps/judicial-system/backend/src/app/modules/defendant/models/defendantEventLog.model.ts index ca0a332704ee..df19027fd0f9 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/models/defendantEventLog.model.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/models/defendantEventLog.model.ts @@ -20,11 +20,17 @@ import { Defendant } from './defendant.model' timestamps: true, }) export class DefendantEventLog extends Model { - static sentToPrisonAdminDate(defendantEventLogs?: DefendantEventLog[]) { + // gets the latest log date of a given type, since the defendant event logs are sorted + static getDefendantEventLogTypeDate({ + defendantEventLogs, + eventType, + }: { + defendantEventLogs?: DefendantEventLog[] + eventType: DefendantEventType + }) { return defendantEventLogs?.find( - (defendantEventLog) => - defendantEventLog.eventType === DefendantEventType.SENT_TO_PRISON_ADMIN, - ) + (defendantEventLog) => defendantEventLog.eventType === eventType, + )?.created } @Column({ diff --git a/apps/judicial-system/web/src/components/FormProvider/case.graphql b/apps/judicial-system/web/src/components/FormProvider/case.graphql index 4aec6d983d4b..069e36645c3f 100644 --- a/apps/judicial-system/web/src/components/FormProvider/case.graphql +++ b/apps/judicial-system/web/src/components/FormProvider/case.graphql @@ -35,6 +35,7 @@ query Case($input: CaseQueryInput!) { subpoenaType isSentToPrisonAdmin sentToPrisonAdminDate + openedByPrisonAdminDate punishmentType subpoenas { id diff --git a/apps/judicial-system/web/src/components/FormProvider/limitedAccessCase.graphql b/apps/judicial-system/web/src/components/FormProvider/limitedAccessCase.graphql index dea05680c538..8d31030894bc 100644 --- a/apps/judicial-system/web/src/components/FormProvider/limitedAccessCase.graphql +++ b/apps/judicial-system/web/src/components/FormProvider/limitedAccessCase.graphql @@ -47,6 +47,7 @@ query LimitedAccessCase($input: CaseQueryInput!) { subpoenaType isSentToPrisonAdmin sentToPrisonAdminDate + openedByPrisonAdminDate punishmentType subpoenas { id diff --git a/apps/judicial-system/web/src/components/Tags/utils.ts b/apps/judicial-system/web/src/components/Tags/utils.ts index 2a3725d64579..51cc830a199e 100644 --- a/apps/judicial-system/web/src/components/Tags/utils.ts +++ b/apps/judicial-system/web/src/components/Tags/utils.ts @@ -151,3 +151,19 @@ export const getPunishmentTypeTag = ( text: getPunishmentTypeLabel(punishmentType), } } + +export const getPrisonCaseStateTag = ( + prisonCaseState: CaseState, +): { + color: TagVariant + text: { id: string; defaultMessage: string; description: string } +} => { + switch (prisonCaseState) { + case CaseState.NEW: + return { color: 'purple', text: strings.new } + case CaseState.RECEIVED: + return { color: 'blue', text: strings.received } + default: + return { color: 'darkerBlue', text: strings.complete } + } +} diff --git a/apps/judicial-system/web/src/routes/Defender/Cases/components/DefenderCasesTable.tsx b/apps/judicial-system/web/src/routes/Defender/Cases/components/DefenderCasesTable.tsx index 169584028e9b..7a52c93d46ff 100644 --- a/apps/judicial-system/web/src/routes/Defender/Cases/components/DefenderCasesTable.tsx +++ b/apps/judicial-system/web/src/routes/Defender/Cases/components/DefenderCasesTable.tsx @@ -57,6 +57,9 @@ export const DefenderCasesTable: FC = ({ ) { return entry.defendants[0].name ?? '' } + if (column === 'courtDate') { + return entry.courtDate + } return entry.created } const { sortedData, requestSort, getClassNamesFor, isActiveColumn } = useSort( @@ -129,9 +132,13 @@ export const DefenderCasesTable: FC = ({ ) : ( - - {formatMessage(tables.hearingArrangementDate)} - + requestSort('courtDate')} + sortAsc={getClassNamesFor('courtDate') === 'ascending'} + sortDes={getClassNamesFor('courtDate') === 'descending'} + isActive={isActiveColumn('courtDate')} + /> )} diff --git a/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.strings.ts b/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.strings.ts index d574238883e5..bc87e97beef8 100644 --- a/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.strings.ts +++ b/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.strings.ts @@ -14,7 +14,12 @@ export const strings = defineMessages({ indictmentCompletedTitle: { id: 'judicial.system.core:indictment_overview.indictment_completed_title', defaultMessage: 'Dómsuppkvaðning {date}', - description: 'Titill á yfirliti ákæru fyrir fangelsi', + description: 'Undirtitill á yfirliti ákæru fyrir fangelsi', + }, + indictmentReceivedTitle: { + id: 'judicial.system.core:indictment_overview.indictment_received_title', + defaultMessage: 'Móttekið {date}', + description: 'Undirtitill á yfirliti ákæru fyrir fangelsi', }, infoCardDefendantsTitle: { id: 'judicial.system.core:indictment_overview.info_card_defendants_title', diff --git a/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.tsx b/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.tsx index beab42f136a8..82065184df56 100644 --- a/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.tsx +++ b/apps/judicial-system/web/src/routes/Prison/IndictmentOverview/IndictmentOverview.tsx @@ -81,6 +81,13 @@ const IndictmentOverview = () => { })} )} + {defendant?.openedByPrisonAdminDate && ( + + {formatMessage(strings.indictmentReceivedTitle, { + date: formatDate(defendant.openedByPrisonAdminDate, 'PPP'), + })} + + )} diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx b/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx index a71487d59d6c..6520c30fa09e 100644 --- a/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx +++ b/apps/judicial-system/web/src/routes/Shared/Cases/PrisonCases.tsx @@ -32,7 +32,7 @@ import { getDurationDate, } from '@island.is/judicial-system-web/src/components/Table' import Table from '@island.is/judicial-system-web/src/components/Table/Table' -import { getPunishmentTypeTag } from '@island.is/judicial-system-web/src/components/Tags/utils' +import { getPrisonCaseStateTag,getPunishmentTypeTag } from '@island.is/judicial-system-web/src/components/Tags/utils' import { CaseListEntry, CaseState, @@ -238,11 +238,23 @@ export const PrisonCases: FC = () => { ), }, { - cell: () => ( - - {'Nýtt'} - - ), + cell: (row) => { + const prisonCaseState = + row.defendants && + row.defendants?.length > 0 && + row.defendants[0].openedByPrisonAdminDate + ? CaseState.RECEIVED + : CaseState.NEW + const prisonCaseStateTag = + getPrisonCaseStateTag(prisonCaseState) + + return ( + + ) + }, }, ]} generateContextMenuItems={(row) => [openCaseInNewTabMenuItem(row.id)]} diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/cases.graphql b/apps/judicial-system/web/src/routes/Shared/Cases/cases.graphql index 7520e5252387..b188cbfac1aa 100644 --- a/apps/judicial-system/web/src/routes/Shared/Cases/cases.graphql +++ b/apps/judicial-system/web/src/routes/Shared/Cases/cases.graphql @@ -29,6 +29,7 @@ query Cases { verdictViewDate isSentToPrisonAdmin punishmentType + openedByPrisonAdminDate } defendantsPunishmentType courtDate diff --git a/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql b/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql index 7c23b41a1977..98b6483bff99 100644 --- a/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql +++ b/apps/judicial-system/web/src/routes/Shared/Cases/prisonCases.graphql @@ -27,6 +27,7 @@ query PrisonCases { noNationalId defenderChoice punishmentType + openedByPrisonAdminDate } courtDate isValidToDateInThePast diff --git a/apps/web/components/Organization/Slice/OverviewLinks/OverviewLinks.tsx b/apps/web/components/Organization/Slice/OverviewLinks/OverviewLinks.tsx index 8b1a4604f4e3..1decf6b1bf48 100644 --- a/apps/web/components/Organization/Slice/OverviewLinks/OverviewLinks.tsx +++ b/apps/web/components/Organization/Slice/OverviewLinks/OverviewLinks.tsx @@ -55,23 +55,18 @@ export const OverviewLinksSlice: React.FC< key={index} direction={leftImage ? 'row' : 'rowReverse'} > - - - {/** - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error make web strict */} - - - + {image?.url && ( + + + + + + )} + > + {!indexableBySearchEngine && ( + + )} + { const formattedStartDate = format( new Date(item.startDate), - 'dd. MMMM yyyy', + 'd. MMMM yyyy', { locale: localeMap[locale], }, diff --git a/apps/web/screens/queries/Organization.tsx b/apps/web/screens/queries/Organization.tsx index 8a1c92b5a600..5a04733342db 100644 --- a/apps/web/screens/queries/Organization.tsx +++ b/apps/web/screens/queries/Organization.tsx @@ -127,6 +127,7 @@ export const GET_ORGANIZATION_PAGE_QUERY = gql` slug title description + canBeFoundInSearchResults topLevelNavigation { links { label diff --git a/libs/api/domains/health-directorate/src/lib/health-directorate.service.ts b/libs/api/domains/health-directorate/src/lib/health-directorate.service.ts index 9c4bdfc139ed..61395b471319 100644 --- a/libs/api/domains/health-directorate/src/lib/health-directorate.service.ts +++ b/libs/api/domains/health-directorate/src/lib/health-directorate.service.ts @@ -28,14 +28,20 @@ export class HealthDirectorateService { if (data === null) { return null } + const hasExceptionComment: boolean = + data.exceptionComment !== undefined && data.exceptionComment.length > 0 + const hasExceptions: boolean = + data.exceptions !== undefined && data.exceptions.length > 0 const donorStatus: Donor = { - isDonor: data?.isDonor ?? true, + isDonor: data.isDonor, limitations: { hasLimitations: - ((data?.exceptions?.length ?? 0) > 0 && data?.isDonor) ?? false, - limitedOrgansList: data?.exceptions, - comment: data?.exceptionComment, + ((hasExceptionComment || hasExceptions) && data.isDonor) ?? false, + limitedOrgansList: data.exceptions, + comment: data.exceptionComment, }, + isMinor: data.isMinor ?? false, + isTemporaryResident: data.isTemporaryResident ?? false, } return donorStatus } @@ -62,11 +68,15 @@ export class HealthDirectorateService { input: DonorInput, locale: Locale, ): Promise { + const filteredList = + input.organLimitations?.filter((item) => item !== 'other') ?? [] + return await this.organDonationApi.updateOrganDonation( auth, { isDonor: input.isDonor, - exceptions: input.organLimitations ?? [], + exceptions: filteredList, + exceptionComment: input.comment, }, locale === 'is' ? organLocale.Is : organLocale.En, ) diff --git a/libs/api/domains/health-directorate/src/lib/models/organ-donation.model.ts b/libs/api/domains/health-directorate/src/lib/models/organ-donation.model.ts index 8893f2149324..824124479661 100644 --- a/libs/api/domains/health-directorate/src/lib/models/organ-donation.model.ts +++ b/libs/api/domains/health-directorate/src/lib/models/organ-donation.model.ts @@ -33,6 +33,12 @@ export class Donor { @Field(() => Limitations, { nullable: true }) limitations?: Limitations + + @Field(() => Boolean, { defaultValue: false }) + isMinor!: boolean + + @Field(() => Boolean, { defaultValue: false }) + isTemporaryResident!: boolean } @ObjectType('HealthDirectorateOrganDonation') @@ -54,4 +60,7 @@ export class DonorInput { @Field(() => [String], { nullable: true }) organLimitations?: string[] + + @Field({ nullable: true }) + comment?: string } diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts index 868f78ae3130..0e17f4f59ecd 100644 --- a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts +++ b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.input.ts @@ -1,5 +1,5 @@ import { AdvertSignatureTypeEnum } from '@island.is/clients/official-journal-of-iceland' -import { InputType, Field, registerEnumType } from '@nestjs/graphql' +import { InputType, Field, registerEnumType, Int } from '@nestjs/graphql' registerEnumType(AdvertSignatureTypeEnum, { name: 'OfficialJournalOfIcelandAdvertSignatureType', @@ -10,10 +10,10 @@ export class AdvertsInput { @Field(() => String, { nullable: true }) search?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) page?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) pageSize?: number @Field(() => [String], { nullable: true }) @@ -43,10 +43,10 @@ export class TypeQueryParams { @Field(() => String, { nullable: true }) department?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) page?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) pageSize?: number } @@ -61,10 +61,10 @@ export class QueryParams { @Field(() => String, { nullable: true }) search?: string - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) page?: number - @Field(() => Number, { nullable: true }) + @Field(() => Int, { nullable: true }) pageSize?: number } @@ -134,3 +134,15 @@ export class SubmitApplicationInput { @Field(() => AdvertSignature) signature!: AdvertSignature } + +@InputType('OfficialJournalOfIcelandMainTypesInput') +export class MainTypesQueryParams { + @Field(() => String, { nullable: true }) + department?: string + + @Field(() => Int, { nullable: true }) + page?: number + + @Field(() => Int, { nullable: true }) + pageSize?: number +} diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts index 30d22c9840f5..70a9135f7d45 100644 --- a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts +++ b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.model.ts @@ -136,3 +136,21 @@ export class Advert { @Field(() => AdvertDocument) document!: AdvertDocument } + +@ObjectType('OfficialJournalOfIcelandAdvertsMainType') +export class AdvertMainType { + @Field() + id!: string + + @Field() + title!: string + + @Field() + slug!: string + + @Field(() => AdvertEntity) + department!: AdvertEntity + + @Field(() => [AdvertType]) + types!: AdvertType[] +} diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.response.ts b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.response.ts index 633157789400..baa06f7a4f6f 100644 --- a/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.response.ts +++ b/libs/api/domains/official-journal-of-iceland/src/lib/models/advert.response.ts @@ -5,6 +5,7 @@ import { AdvertEntity, AdvertMainCategory, AdvertType, + AdvertMainType, } from './advert.model' import { AdvertPaging } from './advert-paging.model' @@ -79,3 +80,12 @@ export class AdvertResponse { @Field(() => Advert) advert?: Advert } + +@ObjectType('OfficialJournalOfIcelandMainTypesResponse') +export class MainTypesResponse { + @Field(() => [AdvertMainType]) + mainTypes!: AdvertMainType[] + + @Field(() => AdvertPaging) + paging!: AdvertPaging +} diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts index cde591d90f87..1fddbf0d108a 100644 --- a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts +++ b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.resolver.ts @@ -8,6 +8,7 @@ import { AdvertsInput, QueryParams, TypeQueryParams, + MainTypesQueryParams, } from './models/advert.input' import { AdvertCategoryResponse, @@ -19,6 +20,7 @@ import { AdvertsResponse, AdvertTypeResponse, AdvertTypesResponse, + MainTypesResponse, } from './models/advert.response' import { Features } from '@island.is/feature-flags' import { FeatureFlag } from '@island.is/nest/feature-flags' @@ -72,6 +74,13 @@ export class OfficialJournalOfIcelandResolver { return this.ojoiService.getAdvertTypes(params) } + @Query(() => MainTypesResponse, { + name: 'officialJournalOfIcelandMainTypes', + }) + getAdvertMainTypes(@Args('params') params: MainTypesQueryParams) { + return this.ojoiService.getMainTypes(params) + } + @Query(() => AdvertMainCategoriesResponse, { name: 'officialJournalOfIcelandMainCategories', }) diff --git a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts index 954a7ab1d8ad..39d9c4c2507d 100644 --- a/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts +++ b/libs/api/domains/official-journal-of-iceland/src/lib/officialJournalOfIceland.service.ts @@ -8,6 +8,7 @@ import { AdvertSingleParams, QueryParams, TypeQueryParams, + MainTypesQueryParams, } from './models/advert.input' import { AdvertCategoryResponse, @@ -17,6 +18,7 @@ import { AdvertResponse, AdvertsResponse, AdvertTypesResponse, + MainTypesResponse, } from './models/advert.response' import { CasesInProgressResponse } from './models/cases.response' @@ -54,6 +56,10 @@ export class OfficialJournalOfIcelandService { return await this.ojoiService.getAdvertTypes(params) } + async getMainTypes(params: MainTypesQueryParams): Promise { + return await this.ojoiService.getAdvertMainTypes(params) + } + async getInstitutions( params: QueryParams, ): Promise { diff --git a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/index.tsx b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/index.tsx index 48e0043813d3..7ee02130ecca 100644 --- a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/index.tsx @@ -1,10 +1,29 @@ -import { Box, Button, Tag, Text } from '@island.is/island-ui/core' +import { Box, Button, Tag, TagVariant, Text } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' -import React, { FC } from 'react' import * as styles from './ReviewSection.css' -import { ReviewSectionProps } from './types' +import { MessageDescriptor } from 'react-intl' -export const StatusStep: FC> = ({ +export type ActionProps = { + title: string + description: string + fileNames?: string + actionButtonTitle: string + hasActionButtonIcon?: boolean + showAlways?: boolean + cta?: () => void +} + +type Props = { + title: string + description: string + hasActionMessage: boolean + action?: ActionProps + visible?: boolean + tagText: MessageDescriptor | string + tagVariant: TagVariant +} + +export const StatusStep = ({ title, description, tagVariant = 'blue', @@ -12,7 +31,7 @@ export const StatusStep: FC> = ({ hasActionMessage, action, visible = true, -}) => { +}: Props) => { const { formatMessage } = useLocale() const handleOnCTAButtonClick = () => { action?.cta && action.cta() diff --git a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/types.ts b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/types.ts index 195eba30c7ee..96926fa90211 100644 --- a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/types.ts +++ b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/StatusStep/types.ts @@ -1,16 +1,3 @@ -import { TagVariant } from '@island.is/island-ui/core' -import { MessageDescriptor } from '@formatjs/intl' - -export interface ActionProps { - title: string - description: string - fileNames?: string - actionButtonTitle: string - hasActionButtonIcon?: boolean - showAlways?: boolean - cta?: () => void -} - export enum AccidentNotificationStatusEnum { ACCEPTED = 'ACCEPTED', REFUSED = 'REFUSED', @@ -18,26 +5,6 @@ export enum AccidentNotificationStatusEnum { INPROGRESSWAITINGFORDOCUMENT = 'INPROGRESSWAITINGFORDOCUMENT', } -export interface ReviewSectionProps { - title: string - description: string - hasActionMessage: boolean - action?: ActionProps - visible?: boolean - tagText: MessageDescriptor | string - tagVariant: TagVariant -} - -export interface Steps { - title: string - description: string - hasActionMessage: boolean - action?: ActionProps - visible?: boolean - tagText: MessageDescriptor | string - tagVariant: TagVariant -} - export interface SubmittedApplicationData { data?: { documentId: string diff --git a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/applicationStatusUtils.ts b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/applicationStatusUtils.ts index a74efdac944b..da17ae9b693d 100644 --- a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/applicationStatusUtils.ts +++ b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/applicationStatusUtils.ts @@ -1,16 +1,33 @@ -import { FormatMessage, FormValue } from '@island.is/application/types' +import { + FormatMessage, + FormValue, + TagVariant, +} from '@island.is/application/types' import { inReview } from '../../lib/messages' -import { AccidentNotificationStatusEnum, Steps } from './StatusStep/types' +import { AccidentNotificationStatusEnum } from './StatusStep/types' import { getValueViaPath } from '@island.is/application/core' import { ReviewApprovalEnum } from '../../types' import { AccidentNotificationStatus } from '@island.is/api/schema' import { - hasReceivedAllDocuments, + hasReceivedConfirmation, isInjuredAndRepresentativeOfCompanyOrInstitute, shouldRequestReview, -} from '../../utils' -import { hasReceivedConfirmation } from '../../utils/hasReceivedConfirmation' +} from '../../utils/miscUtils' + import { AccidentNotificationAnswers } from '../..' +import { MessageDescriptor } from 'react-intl' +import { ActionProps } from './StatusStep' +import { hasReceivedAllDocuments } from '../../utils/documentUtils' + +type Steps = { + title: string + description: string + hasActionMessage: boolean + action?: ActionProps + visible?: boolean + tagText: MessageDescriptor | string + tagVariant: TagVariant +} export const tagMapperApplicationStatus = { [AccidentNotificationStatusEnum.ACCEPTED]: { diff --git a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/index.tsx b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/index.tsx index 0055324cd571..36aec0ba358a 100644 --- a/libs/application/templates/accident-notification/src/fields/ApplicationStatus/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/ApplicationStatus/index.tsx @@ -15,13 +15,11 @@ import { useFormContext } from 'react-hook-form' import { getAccidentStatusQuery } from '../../hooks/useLazyStatusOfNotification' import { inReview } from '../../lib/messages' import { ReviewApprovalEnum, SubmittedApplicationData } from '../../types' -import { - getErrorMessageForMissingDocuments, - isUniqueAssignee, -} from '../../utils' +import { isUniqueAssignee } from '../../utils/miscUtils' import { StatusStep } from './StatusStep' import { ApplicationStatusProps } from './StatusStep/types' import { getStatusAndApproval, getSteps } from './applicationStatusUtils' +import { getErrorMessageForMissingDocuments } from '../../utils/documentUtils' export const ApplicationStatus = ({ goToScreen, diff --git a/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx b/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx index 27627c0f8f2b..e51b848862e3 100644 --- a/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/DateOfAccident/index.tsx @@ -1,16 +1,15 @@ import { IsHealthInsuredInput } from '@island.is/api/schema' -import { FieldBaseProps } from '@island.is/application/types' +import { FieldBaseProps, NO, YES } from '@island.is/application/types' import { Box, Input } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' import { DatePickerController } from '@island.is/shared/form-fields' -import React, { FC, useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect, useState } from 'react' import { Controller, useFormContext } from 'react-hook-form' -import { NO, YES } from '../../utils/constants' import { useLazyIsHealthInsured } from '../../hooks/useLazyIsHealthInsured' import { AccidentNotification } from '../../lib/dataSchema' import { accidentDetails } from '../../lib/messages' -export const DateOfAccident: FC> = ({ +export const DateOfAccident = ({ application, field, error, diff --git a/libs/application/templates/accident-notification/src/fields/FormOverview/ValueLine.tsx b/libs/application/templates/accident-notification/src/fields/FormOverview/ValueLine.tsx index 6e2101294be2..5c2fd31ef800 100644 --- a/libs/application/templates/accident-notification/src/fields/FormOverview/ValueLine.tsx +++ b/libs/application/templates/accident-notification/src/fields/FormOverview/ValueLine.tsx @@ -1,22 +1,17 @@ import { Box, Bullet, BulletList, Text } from '@island.is/island-ui/core' import { Colors } from '@island.is/island-ui/theme' import { useLocale } from '@island.is/localization' -import React, { FC } from 'react' import { MessageDescriptor } from 'react-intl' import * as styles from './FormOverview.css' import cn from 'classnames' -interface ValueLineProps { +type ValueLineProps = { label: string | MessageDescriptor value: string | MessageDescriptor color?: Colors } -export const ValueLine: FC> = ({ - label, - value, - color, -}) => { +export const ValueLine = ({ label, value, color }: ValueLineProps) => { const { formatMessage } = useLocale() return ( @@ -32,10 +27,7 @@ interface FileValueLineProps { files: MessageDescriptor[] | undefined } -export const FileValueLine: FC> = ({ - label, - files, -}) => { +export const FileValueLine = ({ label, files }: FileValueLineProps) => { const { formatMessage } = useLocale() return ( diff --git a/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx b/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx index 3eb21101ca94..07eb4ffa93b4 100644 --- a/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/FormOverview/index.tsx @@ -1,5 +1,5 @@ import { formatText } from '@island.is/application/core' -import { FieldBaseProps, FormValue } from '@island.is/application/types' +import { FieldBaseProps, FormValue, YES } from '@island.is/application/types' import { formatPhoneNumber, ReviewGroup, @@ -17,8 +17,7 @@ import format from 'date-fns/format' import is from 'date-fns/locale/is' import parseISO from 'date-fns/parseISO' import kennitala from 'kennitala' -import React, { FC } from 'react' -import { States, YES } from '../../utils/constants' +import { States } from '../../utils/constants' import { AccidentNotification } from '../../lib/dataSchema' import { accidentDetails, @@ -38,24 +37,30 @@ import { sportsClubInfo, workMachine, } from '../../lib/messages' +import * as styles from './FormOverview.css' +import { FileValueLine, ValueLine } from './ValueLine' import { getAttachmentTitles, + returnMissingDocumentsList, +} from '../../utils/documentUtils' +import { getWorkplaceData, - hideLocationAndPurpose, isAgricultureAccident, isFishermanAccident, isGeneralWorkplaceAccident, - isHomeActivitiesAccident, isMachineRelatedAccident, isProfessionalAthleteAccident, +} from '../../utils/occupationUtils' +import { isReportingOnBehalfOfChild, isReportingOnBehalfOfEmployee, isReportingOnBehalfOfInjured, +} from '../../utils/reportingUtils' +import { hideLocationAndPurpose } from '../../utils/miscUtils' +import { + isHomeActivitiesAccident, isWorkAccident, - returnMissingDocumentsList, -} from '../../utils' -import * as styles from './FormOverview.css' -import { FileValueLine, ValueLine } from './ValueLine' +} from '../../utils/accidentUtils' interface SubmittedApplicationData { data?: { @@ -63,7 +68,7 @@ interface SubmittedApplicationData { } } -interface FormOverviewProps { +type Props = { field: { props: { isAssignee: boolean @@ -71,9 +76,11 @@ interface FormOverviewProps { } } -export const FormOverview: FC< - React.PropsWithChildren -> = ({ application, goToScreen, field }) => { +export const FormOverview = ({ + application, + goToScreen, + field, +}: FieldBaseProps & Props) => { const isAssignee = field?.props?.isAssignee || false const answers = application.answers as AccidentNotification const { formatMessage } = useLocale() diff --git a/libs/application/templates/accident-notification/src/fields/FormOverviewInReview/ConfirmationModal.tsx b/libs/application/templates/accident-notification/src/fields/FormOverviewInReview/ConfirmationModal.tsx index 237d074014ff..46c2ccca0fcb 100644 --- a/libs/application/templates/accident-notification/src/fields/FormOverviewInReview/ConfirmationModal.tsx +++ b/libs/application/templates/accident-notification/src/fields/FormOverviewInReview/ConfirmationModal.tsx @@ -3,11 +3,10 @@ import { Application, DefaultEvents } from '@island.is/application/types' import { SUBMIT_APPLICATION } from '@island.is/application/graphql' import { Box, Button, Icon, ModalBase, Text } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' -import React, { FC } from 'react' import { inReview } from '../../lib/messages' import * as styles from './ConfirmationModal.css' -type ConfirmationModalProps = { +type Props = { visibility: boolean setVisibility: (visibility: boolean) => void title: string @@ -20,9 +19,7 @@ type ConfirmationModalProps = { refetch?: () => void } -export const ConfirmationModal: FC< - React.PropsWithChildren -> = ({ +export const ConfirmationModal = ({ visibility, setVisibility, title, @@ -33,7 +30,7 @@ export const ConfirmationModal: FC< application, comment = '', refetch, -}) => { +}: Props) => { const { formatMessage } = useLocale() const [submitApplication, { loading: loadingSubmit }] = useMutation( SUBMIT_APPLICATION, @@ -68,6 +65,7 @@ export const ConfirmationModal: FC< const closeModal = () => { setVisibility(false) } + return ( -> = ({ application, field, refetch, goToScreen }) => { +export const FormOverviewInReview = ({ + application, + field, + refetch, + goToScreen, +}: Props & FieldBaseProps) => { const isAssignee = field?.props?.isAssignee || false const { formatMessage } = useLocale() const reviewApproval = getValueViaPath( diff --git a/libs/application/templates/accident-notification/src/fields/HiddenInformation/index.tsx b/libs/application/templates/accident-notification/src/fields/HiddenInformation/index.tsx index 337319b0c86e..a8e458076fd0 100644 --- a/libs/application/templates/accident-notification/src/fields/HiddenInformation/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/HiddenInformation/index.tsx @@ -1,10 +1,9 @@ import { FieldBaseProps } from '@island.is/application/types' -import React, { FC } from 'react' import { useFormContext } from 'react-hook-form' import { AccidentNotification } from '../../lib/dataSchema' -import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../utils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../utils/miscUtils' -interface HiddenInformationProps { +type Props = { field: { props: { id: string @@ -12,9 +11,10 @@ interface HiddenInformationProps { } } -export const HiddenInformation: FC< - React.PropsWithChildren -> = ({ application, field }) => { +export const HiddenInformation = ({ + application, + field, +}: Props & FieldBaseProps) => { const { register, setValue } = useFormContext() const { id } = field.props diff --git a/libs/application/templates/accident-notification/src/fields/ProxyDocument/index.tsx b/libs/application/templates/accident-notification/src/fields/ProxyDocument/index.tsx index 76d7906957b0..51895095fb08 100644 --- a/libs/application/templates/accident-notification/src/fields/ProxyDocument/index.tsx +++ b/libs/application/templates/accident-notification/src/fields/ProxyDocument/index.tsx @@ -1,12 +1,8 @@ -import { FieldBaseProps } from '@island.is/application/types' import { Box, Button, Inline, Text } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' -import React, { FC } from 'react' import { powerOfAttorney } from '../../lib/messages' -export const ProxyDocument: FC< - React.PropsWithChildren -> = () => { +export const ProxyDocument = () => { const { formatMessage } = useLocale() return ( diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentDetailSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentDetailSubSection.ts index bb8693200540..ce37b82a5b37 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentDetailSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentDetailSubSection.ts @@ -8,8 +8,9 @@ import { buildTextField, } from '@island.is/application/core' import { accidentDetails } from '../../../lib/messages' -import { isDateOlderThanAYear, isHomeActivitiesAccident } from '../../../utils' -import { isHealthInsured } from '../../../utils/isHealthInsured' +import { isDateOlderThanAYear } from '../../../utils/dateUtils' +import { isHealthInsured } from '../../../utils/miscUtils' +import { isHomeActivitiesAccident } from '../../../utils/accidentUtils' // Details of the accident export const accidentDetailsSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentTypeSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentTypeSubSection.ts index 387eb21ad6c9..8a81fb15fdf7 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentTypeSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/accidentTypeSubSection.ts @@ -1,6 +1,6 @@ import { buildRadioField, buildSubSection } from '@island.is/application/core' import { accidentType } from '../../../lib/messages' -import { getAccidentTypeOptions } from '../../../utils' +import { getAccidentTypeOptions } from '../../../utils/getOptions' export const accidentTypeSubSection = buildSubSection({ id: 'accidentType.section', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts index e8c71b90e331..9b239dc5d8b0 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/attachmentsSubSection.ts @@ -15,18 +15,12 @@ import { fatalAccidentAttachment, injuredPersonInformation, } from '../../../lib/messages' -import { - isFatalAccident, - isReportingOnBehalfOfInjured, - isRepresentativeOfCompanyOrInstitute, -} from '../../../utils' +import { isRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' import { AttachmentsEnum } from '../../../types' -import { - FILE_SIZE_LIMIT, - NO, - UPLOAD_ACCEPT, - YES, -} from '../../../utils/constants' +import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../../utils/constants' +import { isReportingOnBehalfOfInjured } from '../../../utils/reportingUtils' +import { NO, YES } from '@island.is/application/types' +import { isFatalAccident } from '../../../utils/accidentUtils' // Injury certificate and fatal accident section export const attachmentsSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/companyInfoSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/companyInfoSubSection.ts index 05cc9f837316..e9d181e3a167 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/companyInfoSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/companyInfoSubSection.ts @@ -9,11 +9,11 @@ import { companyInfo, representativeInfo } from '../../../lib/messages' import { isAgricultureAccident, isGeneralWorkplaceAccident, - isHomeActivitiesAccident, - isInjuredAndRepresentativeOfCompanyOrInstitute, isInternshipStudiesAccident, - isReportingOnBehalfOfEmployee, -} from '../../../utils' +} from '../../../utils/occupationUtils' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' +import { isHomeActivitiesAccident } from '../../../utils/accidentUtils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' // Company information if work accident without the injured being a fisherman or in agriculture export const companyInfoSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/fishingCompanyInfoSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/fishingCompanyInfoSubSection.ts index 03efd89ffdaf..d009af8a3b5c 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/fishingCompanyInfoSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/fishingCompanyInfoSubSection.ts @@ -5,12 +5,10 @@ import { buildSubSection, buildTextField, } from '@island.is/application/core' -import { - isFishermanAccident, - isInjuredAndRepresentativeOfCompanyOrInstitute, - isReportingOnBehalfOfEmployee, -} from '../../../utils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' import { fishingCompanyInfo, representativeInfo } from '../../../lib/messages' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' +import { isFishermanAccident } from '../../../utils/occupationUtils' // fishery information if fisherman export const fishingCompanyInfoSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts index be855a49a6f0..1afcdb3d604c 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/locationSubSection.ts @@ -11,19 +11,6 @@ import { locationAndPurpose, sportsClubInfo, } from '../../../lib/messages' -import { - hideLocationAndPurpose, - isAgricultureAccident, - isFishermanAccident, - isGeneralWorkplaceAccident, - isHomeActivitiesAccident, - isInternshipStudiesAccident, - isProfessionalAthleteAccident, - isRescueWorkAccident, - isStudiesAccident, -} from '../../../utils' -import { NO, YES } from '../../../utils/constants' -import { isSportAccidentAndEmployee } from '../../../utils/isSportAccidentAndEmployee' import { AgricultureAccidentLocationEnum, FishermanWorkplaceAccidentLocationEnum, @@ -33,6 +20,21 @@ import { RescueWorkAccidentLocationEnum, StudiesAccidentLocationEnum, } from '../../../types' +import { + isAgricultureAccident, + isFishermanAccident, + isGeneralWorkplaceAccident, + isInternshipStudiesAccident, + isProfessionalAthleteAccident, + isSportAccidentAndEmployee, +} from '../../../utils/occupationUtils' +import { NO, YES } from '@island.is/application/types' +import { + isHomeActivitiesAccident, + isRescueWorkAccident, + isStudiesAccident, +} from '../../../utils/accidentUtils' +import { hideLocationAndPurpose } from '../../../utils/miscUtils' // Location Subsection export const locationSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/rescueSquadInfoSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/rescueSquadInfoSubSection.ts index 640aa635f36b..55960413bba6 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/rescueSquadInfoSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/rescueSquadInfoSubSection.ts @@ -6,11 +6,9 @@ import { buildTextField, } from '@island.is/application/core' import { representativeInfo, rescueSquadInfo } from '../../../lib/messages' -import { - isInjuredAndRepresentativeOfCompanyOrInstitute, - isReportingOnBehalfOfEmployee, - isRescueWorkAccident, -} from '../../../utils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' +import { isRescueWorkAccident } from '../../../utils/accidentUtils' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' // Rescue squad information when accident is related to rescue squad export const rescueSquadInfoSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/schoolInfoSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/schoolInfoSubSection.ts index 148f9ec35872..8f26c1c56fef 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/schoolInfoSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/schoolInfoSubSection.ts @@ -6,12 +6,10 @@ import { buildTextField, } from '@island.is/application/core' import { representativeInfo, schoolInfo } from '../../../lib/messages' -import { - isInjuredAndRepresentativeOfCompanyOrInstitute, - isInternshipStudiesAccident, - isReportingOnBehalfOfEmployee, - isStudiesAccident, -} from '../../../utils' +import { isStudiesAccident } from '../../../utils/accidentUtils' +import { isInternshipStudiesAccident } from '../../../utils/occupationUtils' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' // School information if school accident export const schoolInfoSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/sportsClubInfoSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/sportsClubInfoSubSection.ts index 7914ecbe0158..8410b242d596 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/sportsClubInfoSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/sportsClubInfoSubSection.ts @@ -5,12 +5,10 @@ import { buildSubSection, buildTextField, } from '@island.is/application/core' -import { - isInjuredAndRepresentativeOfCompanyOrInstitute, - isProfessionalAthleteAccident, - isReportingOnBehalfOfEmployee, -} from '../../../utils' +import { isInjuredAndRepresentativeOfCompanyOrInstitute } from '../../../utils/miscUtils' import { representativeInfo, sportsClubInfo } from '../../../lib/messages' +import { isProfessionalAthleteAccident } from '../../../utils/occupationUtils' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' // Sports club information when the injured has a sports related accident export const sportsClubInfoSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/studiesAccidentSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/studiesAccidentSubSection.ts index 87bead5e5d5c..19346e794c61 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/studiesAccidentSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/studiesAccidentSubSection.ts @@ -4,8 +4,8 @@ import { buildSubSection, } from '@island.is/application/core' import { accidentType } from '../../../lib/messages' -import { isStudiesAccident } from '../../../utils' import { StudiesAccidentTypeEnum } from '../../../types' +import { isStudiesAccident } from '../../../utils/accidentUtils' export const studiesAccidentSubSection = buildSubSection({ id: 'studiesAccident.subSection', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workAccidentSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workAccidentSubSection.ts index db49a860e014..1bb5b00d63ac 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workAccidentSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workAccidentSubSection.ts @@ -11,12 +11,10 @@ import { attachments, injuredPersonInformation, } from '../../../lib/messages' -import { - isAgricultureAccident, - isReportingOnBehalfSelf, - isWorkAccident, -} from '../../../utils' import { WorkAccidentTypeEnum } from '../../../types' +import { isWorkAccident } from '../../../utils/accidentUtils' +import { isAgricultureAccident } from '../../../utils/occupationUtils' +import { isReportingOnBehalfSelf } from '../../../utils/reportingUtils' export const workAccidentSubSection = buildSubSection({ id: 'workAccident.subSection', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts index bdfa59c43e79..0f5a41785262 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/aboutTheAccidentSection/workMachineSubSection.ts @@ -8,9 +8,9 @@ import { application, workMachine } from '../../../lib/messages' import { isAgricultureAccident, isGeneralWorkplaceAccident, -} from '../../../utils' -import { isSportAccidentAndEmployee } from '../../../utils/isSportAccidentAndEmployee' -import { NO, YES } from '../../../utils/constants' + isSportAccidentAndEmployee, +} from '../../../utils/occupationUtils' +import { NO, YES } from '@island.is/application/types' // Workmachine information only applicable to generic workplace accidents export const workMachineSubSection = buildSubSection({ diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts index f91bcfaaee43..0c948df0a9f0 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/applicantInformationSection.ts @@ -1,6 +1,7 @@ import { buildSection } from '@island.is/application/core' import { applicantInformation } from '../../lib/messages' import { applicantInformationMultiField } from '@island.is/application/ui-forms' + export const applicantInformationSection = buildSection({ id: 'informationAboutApplicantSection', title: applicantInformation.general.title, diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/childInCustodySubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/childInCustodySubSection.ts index 9587578fe81c..a826034c5773 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/childInCustodySubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/childInCustodySubSection.ts @@ -4,7 +4,7 @@ import { buildTextField, } from '@island.is/application/core' import { childInCustody } from '../../../lib/messages' -import { isReportingOnBehalfOfChild } from '../../../utils' +import { isReportingOnBehalfOfChild } from '../../../utils/reportingUtils' export const childInCustodySubSection = buildSubSection({ id: 'childInCustody.section', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/injuredPersonInformationSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/injuredPersonInformationSubSection.ts index 643cc77ad62d..0b5acc8a391a 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/injuredPersonInformationSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/injuredPersonInformationSubSection.ts @@ -8,7 +8,7 @@ import { injuredPersonInformation } from '../../../lib/messages' import { isReportingOnBehalfOfEmployee, isReportingOnBehalfOfInjured, -} from '../../../utils' +} from '../../../utils/reportingUtils' export const injuredPersonInformationSubSection = buildSubSection({ id: 'injuredPersonInformation.section', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts index 5d747453c1d0..ea81a695800d 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/juridicialPersonCompanySubSection.ts @@ -5,8 +5,8 @@ import { buildTextField, } from '@island.is/application/core' import { juridicalPerson } from '../../../lib/messages' -import { isReportingOnBehalfOfEmployee } from '../../../utils' -import { YES } from '../../../utils/constants' +import { isReportingOnBehalfOfEmployee } from '../../../utils/reportingUtils' +import { YES } from '@island.is/application/types' export const juridicalPersonCompanySubSection = buildSubSection({ id: 'juridicalPerson.company', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneySubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneySubSection.ts index eb16cefeec0f..7556f6c32cbc 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneySubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneySubSection.ts @@ -7,7 +7,7 @@ import { } from '@island.is/application/core' import { powerOfAttorney } from '../../../lib/messages' import { PowerOfAttorneyUploadEnum } from '../../../types' -import { isPowerOfAttorney } from '../../../utils' +import { isPowerOfAttorney } from '../../../utils/miscUtils' export const powerOfAttorneySubSection = buildSubSection({ id: 'powerOfAttorney.type.section', diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts index 00ec8aff756d..437a4072b541 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/powerOfAttorneyUploadSubSection.ts @@ -6,11 +6,12 @@ import { } from '@island.is/application/core' import { error, powerOfAttorney } from '../../../lib/messages' import { FILE_SIZE_LIMIT, UPLOAD_ACCEPT } from '../../../utils/constants' -import { isUploadNow } from '../../../utils/isUploadNow' +import { isUploadNow } from '../../../utils/documentUtils' export const powerOfAttorneyUploadSubSection = buildSubSection({ id: 'powerOfAttorney.upload.section', title: powerOfAttorney.upload.sectionTitle, + condition: (formValue) => isUploadNow(formValue), children: [ buildMultiField({ id: 'powerOfAttorney', @@ -37,5 +38,4 @@ export const powerOfAttorneyUploadSubSection = buildSubSection({ ], }), ], - condition: (formValue) => isUploadNow(formValue), }) diff --git a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts index d59f1f345a83..96665ccc5d98 100644 --- a/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts +++ b/libs/application/templates/accident-notification/src/forms/AccidentNotificationForm/whoIsTheNotificationForSection/whoIsTheNotificationForMultiField.ts @@ -3,7 +3,7 @@ import { whoIsTheNotificationFor } from '../../../lib/messages' import { whoIsTheNotificationForOptions, whoIsTheNotificationForProcureOptions, -} from '../../../utils/getWhoIstheNotificationForOptions' +} from '../../../utils/getOptions' export const whoIsTheNotificationForMultiField = buildMultiField({ id: 'whoIsTheNotificationFor', diff --git a/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts b/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts index f0c88a39c67a..a53e2afcabfc 100644 --- a/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts +++ b/libs/application/templates/accident-notification/src/forms/InReviewForm/addAttachmentsSection.ts @@ -13,11 +13,10 @@ import { hasReceivedInjuryCertificate, hasReceivedPoliceReport, hasReceivedProxyDocument, - isFatalAccident, - isPowerOfAttorney, - isReportingOnBehalfOfInjured, - isUniqueAssignee, -} from '../../utils' +} from '../../utils/documentUtils' +import { isPowerOfAttorney, isUniqueAssignee } from '../../utils/miscUtils' +import { isReportingOnBehalfOfInjured } from '../../utils/reportingUtils' +import { isFatalAccident } from '../../utils/accidentUtils' export const addAttachmentsSection = (isAssignee?: boolean) => buildSection({ diff --git a/libs/application/templates/accident-notification/src/index.ts b/libs/application/templates/accident-notification/src/index.ts index 512077174291..2d4f5c15801b 100644 --- a/libs/application/templates/accident-notification/src/index.ts +++ b/libs/application/templates/accident-notification/src/index.ts @@ -2,7 +2,7 @@ import AccidentNotificationTemplate from './lib/AccidentNotificationTemplate' import { AccidentNotification } from './lib/dataSchema' import * as appMessages from './lib/messages' import { OnBehalf } from './types' -import * as appUtils from './utils' +import * as appUtils from './utils/miscUtils' export const getFields = () => import('./fields') diff --git a/libs/application/templates/accident-notification/src/lib/dataSchema.ts b/libs/application/templates/accident-notification/src/lib/dataSchema.ts index afb53946fe3b..3ba93cdc8e15 100644 --- a/libs/application/templates/accident-notification/src/lib/dataSchema.ts +++ b/libs/application/templates/accident-notification/src/lib/dataSchema.ts @@ -1,7 +1,6 @@ import { applicantInformationSchema } from '@island.is/application/ui-forms' import * as kennitala from 'kennitala' import { z } from 'zod' -import { YES } from '../utils/constants' import { AccidentTypeEnum, AgricultureAccidentLocationEnum, @@ -19,10 +18,11 @@ import { ReviewApprovalEnum, OnBehalf, Status, - ChoiceEnum, + YesOrNo, } from '../types' -import { isValid24HFormatTime } from '../utils' import { error } from './messages/error' +import { isValid24HFormatTime } from '../utils/dateUtils' +import { YES } from '@island.is/application/types' const FileSchema = z.object({ name: z.string(), @@ -99,7 +99,7 @@ const accidentDetails = z.object({ dateOfAccident: z.string().refine((x) => x.trim().length > 0, { params: error.invalidValue, }), - isHealthInsured: z.nativeEnum(ChoiceEnum).optional(), + isHealthInsured: z.nativeEnum(YesOrNo).optional(), timeOfAccident: z .string() .refine((x) => (x ? isValid24HFormatTime(x) : false), { @@ -193,8 +193,8 @@ export const AccidentNotificationSchema = z.object({ info: z.object({ onBehalf: z.nativeEnum(OnBehalf), }), - timePassedHindrance: z.nativeEnum(ChoiceEnum), - carAccidentHindrance: z.nativeEnum(ChoiceEnum), + timePassedHindrance: z.nativeEnum(YesOrNo), + carAccidentHindrance: z.nativeEnum(YesOrNo), applicant: applicantInformationSchema(), whoIsTheNotificationFor: z.object({ answer: z.nativeEnum(WhoIsTheNotificationForEnum), @@ -213,13 +213,13 @@ export const AccidentNotificationSchema = z.object({ ]), }), attachments, - wasTheAccidentFatal: z.nativeEnum(ChoiceEnum), - fatalAccidentUploadDeathCertificateNow: z.nativeEnum(ChoiceEnum), + wasTheAccidentFatal: z.nativeEnum(YesOrNo), + fatalAccidentUploadDeathCertificateNow: z.nativeEnum(YesOrNo), accidentDetails, isRepresentativeOfCompanyOrInstitue: z.array(z.string()).optional(), fishingShipInfo, onPayRoll: z.object({ - answer: z.nativeEnum(ChoiceEnum), + answer: z.nativeEnum(YesOrNo), }), locationAndPurpose: z.object({ location: z.string().refine((x) => x.trim().length > 0, { @@ -240,7 +240,7 @@ export const AccidentNotificationSchema = z.object({ shipLocation: z.object({ answer: z.nativeEnum(FishermanWorkplaceAccidentShipLocationEnum), }), - workMachineRadio: z.nativeEnum(ChoiceEnum), + workMachineRadio: z.nativeEnum(YesOrNo), workMachine: z.object({ descriptionOfMachine: z.string().refine((x) => x.trim().length > 0, { params: error.invalidValue, diff --git a/libs/application/templates/accident-notification/src/lib/messages/externalData.ts b/libs/application/templates/accident-notification/src/lib/messages/externalData.ts index 869618dbdc54..4f1342fc8544 100644 --- a/libs/application/templates/accident-notification/src/lib/messages/externalData.ts +++ b/libs/application/templates/accident-notification/src/lib/messages/externalData.ts @@ -12,6 +12,24 @@ export const externalData = { defaultMessage: 'Meðferð á gögnum', description: 'Data handling list item title', }, + bulletOne: { + id: 'an.application:section.agreementDescription.BulletOne', + defaultMessage: + 'Þegar tilkynning um slys er send Sjúkratryggingum Íslands mun stofnunin miðla upplýsingum um afstöðu til bótaskyldu með þeim atvinnurekanda eða íþróttafélagi sem á í hlut. Ástæða þess er að umræddir aðilar kunna að eiga rétt á endurgreiðslu útlagðs kostnaðar og/eða dagpeningum ef greidd hafa verið laun í veikindaforföllum vegna slyssins. Þessir aðilar fá aldrei afhentar heilsufars- eða sjúkraskrárupplýsingar.', + description: 'List item 1 on data gathering information', + }, + bulletTwo: { + id: 'an.application:section.agreementDescription.BulletTwo', + defaultMessage: + 'Vinnueftirlit ríkisins kann einnig að fá afrit af tilkynningunni undir ákveðnum kringumstæðum á grundvelli 4. mgr. 79. gr. laga nr. 46/1980 sem og Rannsóknarnefnd samgönguslysa á grundvelli 12. og 16. gr. laga nr. 18/2013.', + description: 'List item 2 on data gathering information', + }, + bulletThree: { + id: 'an.application:section.agreementDescription.BulletThree', + defaultMessage: + 'Eitthvað óvænt verður að hafa gerst sem veldur tjóni á líkama hins tryggða og áhorfandi getur áttað sig á að hafi gerst.', + description: 'List item 3 on data gathering information', + }, bulletFour: { id: 'an.application:section.agreementDescription.BulletFour', defaultMessage: diff --git a/libs/application/templates/accident-notification/src/types/index.ts b/libs/application/templates/accident-notification/src/types/index.ts index da316a4fd5f7..58dac3b071d9 100644 --- a/libs/application/templates/accident-notification/src/types/index.ts +++ b/libs/application/templates/accident-notification/src/types/index.ts @@ -1,4 +1,4 @@ -import { NO, YES } from '../utils/constants' +import { companyInfo, representativeInfo } from '../lib/messages' export type CompanyInfo = { nationalRegistrationId: string @@ -53,11 +53,6 @@ export enum OnBehalf { OTHERS = 'others', } -export enum ChoiceEnum { - YES = 'yes', - NO = 'no', -} - export enum WhoIsTheNotificationForEnum { JURIDICALPERSON = 'juridicalPerson', ME = 'me', @@ -73,7 +68,10 @@ export enum AccidentTypeEnum { SPORTS = 'sports', } -export type YesOrNo = typeof NO | typeof YES +export enum YesOrNo { + YES = 'yes', + NO = 'no', +} export enum AttachmentsEnum { INJURYCERTIFICATE = 'injuryCertificate', @@ -229,3 +227,13 @@ export type RepresentativeInfoV2 = { nationalId?: string | null phoneNumber?: string | null } + +export type WorkplaceData = { + companyInfo: CompanyInfo + representitive: RepresentativeInfo + companyInfoMsg: typeof companyInfo + representitiveMsg: typeof representativeInfo + type: WorkAccidentTypeEnum | AccidentTypeEnum + onPayRoll?: YesOrNo + screenId: string +} diff --git a/libs/application/templates/accident-notification/src/utils/accidentNotificationUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/accidentNotificationUtils.spec.ts deleted file mode 100644 index 1e1d888a4745..000000000000 --- a/libs/application/templates/accident-notification/src/utils/accidentNotificationUtils.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { isValid24HFormatTime } from './index' -describe('Health insurance utils', () => { - const validString = '2359' - const tooLongString = '23599' - const threeLetterString = '123' - const twoLetterString = '12' - const oneLetterString = '1' - const emptyString = '' - const illlegalHourString = '2459' - const illlegalMinuteString = '2364' - - describe('Check time format validation logic', () => { - it('should return true for 2359', () => { - expect(isValid24HFormatTime(validString)).toEqual(true) - }) - it('should return false for 23599', () => { - expect(isValid24HFormatTime(tooLongString)).toEqual(false) - }) - it('should return false for 123', () => { - expect(isValid24HFormatTime(threeLetterString)).toEqual(false) - }) - it('should return false for 12', () => { - expect(isValid24HFormatTime(twoLetterString)).toEqual(false) - }) - it('should return false for 1', () => { - expect(isValid24HFormatTime(oneLetterString)).toEqual(false) - }) - it('should return false for empty string', () => { - expect(isValid24HFormatTime(emptyString)).toEqual(false) - }) - it('should return false for 2459', () => { - expect(isValid24HFormatTime(illlegalHourString)).toEqual(false) - }) - it('should return false for 2364', () => { - expect(isValid24HFormatTime(illlegalMinuteString)).toEqual(false) - }) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/accidentUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/accidentUtils.spec.ts new file mode 100644 index 000000000000..8fbbccbf2274 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/accidentUtils.spec.ts @@ -0,0 +1,157 @@ +import { FormValue, NO, YES } from '@island.is/application/types' +import { AccidentTypeEnum } from '../types' +import { + getInjuredPersonInformation, + isFatalAccident, + isHomeActivitiesAccident, + isRescueWorkAccident, + isStudiesAccident, + isWorkAccident, +} from './accidentUtils' + +describe('isHomeActivitiesAccident', () => { + const homeActivitiesAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, + } + + const someOtherAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, + } + + const emptyObject = {} + + it('should return true for home activity accidents', () => { + expect(isHomeActivitiesAccident(homeActivitiesAccident)).toEqual(true) + }) + it('should return false for accidents other than home activity accidents', () => { + expect(isHomeActivitiesAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isHomeActivitiesAccident(emptyObject)).toEqual(false) + }) +}) +describe('isWorkAccident', () => { + const workAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, + } + + const emptyObject = {} + + it('should return true for work accidents', () => { + expect(isWorkAccident(workAccident)).toEqual(true) + }) + it('should return false for accidents other than work', () => { + expect(isWorkAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isWorkAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isRescueWorkAccident', () => { + const rescueWorkAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, + } + + const someOtherAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, + } + + const emptyObject = {} + + it('should return true for rescue work accidents', () => { + expect(isRescueWorkAccident(rescueWorkAccident)).toEqual(true) + }) + it('should return false for accidents other than rescue work', () => { + expect(isRescueWorkAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isRescueWorkAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isStudiesAccident', () => { + const studiesAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.STUDIES }, + } + + const someOtherAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, + } + + const emptyObject = {} + + it('should return true for studies accidents', () => { + expect(isStudiesAccident(studiesAccident)).toEqual(true) + }) + it('should return false for accidents other than studies', () => { + expect(isStudiesAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isStudiesAccident(emptyObject)).toEqual(false) + }) +}) + +describe('getInjuredPersonInformation', () => { + const injuredPersonInformation: FormValue = { + injuredPersonInformation: { + email: 'kalli@palli.is', + name: 'Kalli', + }, + } + + const emptyInjuredPersonInformation: FormValue = { + injuredPersonInformation: { + email: '', + name: '', + }, + } + + it('Should return the email of the injured person', () => { + expect( + getInjuredPersonInformation(injuredPersonInformation)?.email, + ).toEqual('kalli@palli.is') + }) + + it('Should return the name of the injured person', () => { + expect(getInjuredPersonInformation(injuredPersonInformation)?.name).toEqual( + 'Kalli', + ) + }) + + it('Should return empty string for email if not provided', () => { + expect( + getInjuredPersonInformation(emptyInjuredPersonInformation)?.email, + ).toEqual('') + }) + + it('Should return empty string for name if not provided', () => { + expect( + getInjuredPersonInformation(emptyInjuredPersonInformation)?.name, + ).toEqual('') + }) +}) + +describe('isFatalAccident', () => { + const fatal: FormValue = { + wasTheAccidentFatal: YES, + } + + const notFatal: FormValue = { + wasTheAccidentFatal: NO, + } + + it('should return true for a fatal accident', () => { + expect(isFatalAccident(fatal)).toEqual(true) + }) + it('should return false for a non fatal accident', () => { + expect(isFatalAccident(notFatal)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isFatalAccident({})).toEqual(false) + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/accidentUtils.ts b/libs/application/templates/accident-notification/src/utils/accidentUtils.ts new file mode 100644 index 000000000000..94f8954d5954 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/accidentUtils.ts @@ -0,0 +1,60 @@ +import { getValueViaPath } from '@island.is/application/core' +import { FormValue, YES } from '@island.is/application/types' +import { AccidentTypeEnum, YesOrNo } from '../types' + +export const isWorkAccident = (formValue: FormValue) => { + const accidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) + return accidentType === AccidentTypeEnum.WORK +} + +export const isHomeActivitiesAccident = (formValue: FormValue) => { + const workAccidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) + return workAccidentType === AccidentTypeEnum.HOMEACTIVITIES +} + +export const isRescueWorkAccident = (formValue: FormValue) => { + const accidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) + return accidentType === AccidentTypeEnum.RESCUEWORK +} + +export const isStudiesAccident = (formValue: FormValue) => { + const accidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) + return accidentType === AccidentTypeEnum.STUDIES +} + +export const getInjuredPersonInformation = (answers: FormValue) => { + const injuredPersonsEmail = getValueViaPath( + answers, + 'injuredPersonInformation.email', + ) + + const injuredPersonsName = getValueViaPath( + answers, + 'injuredPersonInformation.name', + ) + + return { + email: injuredPersonsEmail, + name: injuredPersonsName, + } +} + +export const isFatalAccident = (formValue: FormValue) => { + const wasTheAccidentFatal = getValueViaPath( + formValue, + 'wasTheAccidentFatal', + ) + return wasTheAccidentFatal === YES +} diff --git a/libs/application/templates/accident-notification/src/utils/constants/index.ts b/libs/application/templates/accident-notification/src/utils/constants/index.ts index c13413335ab9..b57a23b4f76a 100644 --- a/libs/application/templates/accident-notification/src/utils/constants/index.ts +++ b/libs/application/templates/accident-notification/src/utils/constants/index.ts @@ -1,6 +1,3 @@ -export const YES = 'yes' -export const NO = 'no' - export const UPLOAD_ACCEPT = '.pdf, .doc, .docx, .rtf, .jpg, .jpeg, .png, .heic' export const FILE_SIZE_LIMIT = 10000000 // 10MB diff --git a/libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.spec.ts b/libs/application/templates/accident-notification/src/utils/dateUtils.spec.ts similarity index 61% rename from libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.spec.ts rename to libs/application/templates/accident-notification/src/utils/dateUtils.spec.ts index 60fae84cec61..1045a0918ffe 100644 --- a/libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/dateUtils.spec.ts @@ -1,5 +1,6 @@ import { FormValue } from '@island.is/application/types' -import { isDateOlderThanAYear } from './isDateOlderThanAYear' +import { isDateOlderThanAYear, isValid24HFormatTime } from './dateUtils' + describe('isDateOlderThanAYear', () => { const yesterday = new Date() yesterday.setDate(yesterday.getDate() - 1) @@ -27,3 +28,29 @@ describe('isDateOlderThanAYear', () => { expect(isDateOlderThanAYear(emptyObject)).toEqual(false) }) }) + +describe('isValid24HFormatTime', () => { + it.each(['0000', '2359', '1234'])( + 'should return true for valid time', + (time) => { + const result = isValid24HFormatTime(time) + expect(result).toBeTruthy() + }, + ) + + it.each([ + '2534', + '1265', + '2360', + '2400', + '12:34', + '', + '1', + '12', + '123', + '12345', + ])('should return false for invalid time', (time) => { + const result = isValid24HFormatTime(time) + expect(result).toBeFalsy() + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.ts b/libs/application/templates/accident-notification/src/utils/dateUtils.ts similarity index 60% rename from libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.ts rename to libs/application/templates/accident-notification/src/utils/dateUtils.ts index e554a1df59f4..1e7f2d43b42f 100644 --- a/libs/application/templates/accident-notification/src/utils/isDateOlderThanAYear.ts +++ b/libs/application/templates/accident-notification/src/utils/dateUtils.ts @@ -10,9 +10,18 @@ const getDateAYearBack = () => { export const isDateOlderThanAYear = (answers: FormValue) => { const aYearAgo = getDateAYearBack() - const date = getValueViaPath( + const date = getValueViaPath( answers, 'accidentDetails.dateOfAccident', - ) as string + ) return !!date && new Date(date).getTime() < aYearAgo.getTime() } + +export const isValid24HFormatTime = (value: string) => { + if (value.length !== 4) return false + const hours = parseInt(value.slice(0, 2)) + const minutes = parseInt(value.slice(2, 4)) + if (hours > 23) return false + if (minutes > 59) return false + return true +} diff --git a/libs/application/templates/accident-notification/src/utils/documentUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/documentUtils.spec.ts new file mode 100644 index 000000000000..4ab59d4aa1d7 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/documentUtils.spec.ts @@ -0,0 +1,316 @@ +import { FormatMessage } from '@island.is/localization' + +import { AccidentNotification } from '../lib/dataSchema' +import { + AttachmentsEnum, + PowerOfAttorneyUploadEnum, + WhoIsTheNotificationForEnum, + YesOrNo, +} from '../types' +import { + getAttachmentTitles, + isUploadNow, + returnMissingDocumentsList, +} from './documentUtils' +import { + getErrorMessageForMissingDocuments, + hasMissingDocuments, + hasReceivedAllDocuments, +} from './documentUtils' +import { FormValue } from '@island.is/application/types' + +describe('hasMissingDocuments', () => { + it('should return true when missing documents', () => { + expect(hasMissingDocuments(getMissingDocuments())).toEqual(true) + }) + + it('should return false when no missing documents', () => { + expect(hasMissingDocuments(getNoMissingDocuments())).toEqual(false) + }) +}) + +describe('getErrorMessageForMissingDocuments', () => { + const formatMessage: FormatMessage = jest.fn().mockReturnValue('test.pdf') + + beforeEach(() => { + jest.clearAllMocks() + }) + + it('should return error message for missing documents', () => { + const result = getErrorMessageForMissingDocuments( + getMissingDocuments(), + formatMessage, + false, + ) + expect(result).toEqual('test.pdf, test.pdf, test.pdf') + expect(formatMessage).toHaveBeenCalledTimes(3) + }) + + it('should return empty string when no documents are missing', () => { + const docs = getNoMissingDocuments() + const result = getErrorMessageForMissingDocuments(docs, formatMessage, true) + expect(result).toBe('') + expect(formatMessage).not.toHaveBeenCalled() + }) +}) + +describe('hasReceivedAllDocuments', () => { + const testCases = [ + { who: WhoIsTheNotificationForEnum.ME, fatal: YesOrNo.NO }, + { who: WhoIsTheNotificationForEnum.JURIDICALPERSON, fatal: YesOrNo.NO }, + { who: WhoIsTheNotificationForEnum.POWEROFATTORNEY, fatal: YesOrNo.YES }, + { who: WhoIsTheNotificationForEnum.POWEROFATTORNEY, fatal: YesOrNo.NO }, + ] + it.each(testCases)( + 'should return true when all documents are received', + (data) => { + const answers = getNoMissingDocuments() as AccidentNotification + answers.whoIsTheNotificationFor.answer = data.who + answers.wasTheAccidentFatal = data.fatal + expect(hasReceivedAllDocuments(answers)).toEqual(true) + }, + ) + + it.each(testCases)('should return false when missing documents', (data) => { + const answers = getMissingDocuments() as AccidentNotification + answers.whoIsTheNotificationFor.answer = data.who + answers.wasTheAccidentFatal = data.fatal + expect(hasReceivedAllDocuments(answers)).toEqual(false) + }) +}) + +const EMPTY_FILE: never[] = [] + +const SAMPLE_FILE = { + name: 'test.pdf', + url: 'https://test.pdf', +} as const +const createAttachment = () => ({ file: [SAMPLE_FILE] }) + +const getMissingDocuments = (): FormValue => ({ + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + wasTheAccidentFatal: YesOrNo.YES, + injuryCertificate: { + answer: AttachmentsEnum.SENDCERTIFICATELATER, + }, + accidentStatus: { + receivedAttachments: { + InjuryCertificate: false, + PoliceReport: false, + DeathCertificate: false, + ProxyDocument: false, + }, + }, + attachments: { + injuryCertificateFile: { file: EMPTY_FILE }, + deathCertificateFile: { file: EMPTY_FILE }, + powerOfAttorneyFile: { file: EMPTY_FILE }, + }, +}) + +const getNoMissingDocuments = (): FormValue => ({ + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + wasTheAccidentFatal: YesOrNo.YES, + injuryCertificate: { + answer: AttachmentsEnum.SENDCERTIFICATELATER, + }, + accidentStatus: { + receivedAttachments: { + InjuryCertificate: true, + PoliceReport: true, + DeathCertificate: true, + ProxyDocument: true, + }, + }, + attachments: { + injuryCertificateFile: { + file: [createAttachment()], + }, + deathCertificateFile: { + file: [createAttachment()], + }, + powerOfAttorneyFile: { + file: [createAttachment()], + }, + }, +}) + +describe('getAttachmentTitles', () => { + it.each([ + AttachmentsEnum.SENDCERTIFICATELATER, + AttachmentsEnum.HOSPITALSENDSCERTIFICATE, + ])('should return attachment titles', (injuryCertificate) => { + const answers = { + injuryCertificate: { + answer: injuryCertificate, + }, + attachments: { + deathCertificateFile: { + file: [ + { + name: 'test.pdf', + url: 'https://test.pdf', + }, + ], + }, + injuryCertificateFile: { + file: [ + { + name: 'test.pdf', + url: 'https://test.pdf', + }, + ], + }, + powerOfAttorneyFile: { + file: [ + { + name: 'test.pdf', + url: 'https://test.pdf', + }, + ], + }, + additionalFiles: { + file: [ + { + name: 'test.pdf', + url: 'https://test.pdf', + }, + ], + }, + additionalFilesFromReviewer: { + file: [ + { + name: 'test.pdf', + url: 'https://test.pdf', + }, + ], + }, + }, + } + + // Semi annoying push stuff here because order matters for strict equals + const isHospitalSendsCertificate = + injuryCertificate === AttachmentsEnum.HOSPITALSENDSCERTIFICATE + const expectedResults = [] + expectedResults.push({ + id: 'an.application:attachments.documentNames.deathCertificate', + defaultMessage: 'Lögregluskýrsla', + description: 'Name of police report for in review', + }) + if (!isHospitalSendsCertificate) { + expectedResults.push({ + id: 'an.application:attachments.documentNames.injuryCertificate', + defaultMessage: 'Áverkavottorð', + description: 'Name of injury certificate for in review', + }) + } + expectedResults.push({ + id: 'an.application:attachments.documentNames.powerOfAttorney', + defaultMessage: 'Umboð', + description: 'Name of power of attorney document for in review', + }) + if (isHospitalSendsCertificate) { + expectedResults.push({ + id: 'an.application:overview.labels.hospitalSendsCertificate', + defaultMessage: + 'Bráðamóttökuskrá - Ég mun óska eftir því að Landspítalinn sendi bráðamóttökuskrá til Sjúkratrygginga Íslands', + description: 'Label for hospital sends certificate in document list', + }) + } + expectedResults.push({ + id: 'an.application:attachments.documentNames.additionalDocumentsFromApplicant', + defaultMessage: 'Auka fylgiskjöl frá umsækjanda', + description: + 'Name of additional attachments for in review from applicant', + }) + expectedResults.push({ + id: 'an.application:attachments.documentNames.additionalDocumentsFromReviewer', + defaultMessage: 'Auka fylgiskjöl frá forsvarsmanni', + description: 'Name of additional attachments for in review from reviewer', + }) + + const result = getAttachmentTitles( + answers as unknown as AccidentNotification, + ) + expect(result).toStrictEqual(expectedResults) + }) +}) + +describe('returnMissingDocumentsList', () => { + it('should return missing documents list', () => { + const formatMessage: FormatMessage = jest.fn().mockReturnValue('test.pdf') + const missingDocuments = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + wasTheAccidentFatal: YesOrNo.YES, + injuryCertificate: { + answer: AttachmentsEnum.SENDCERTIFICATELATER, + }, + attachments: { + injuryCertificateFile: { + file: [], + }, + deathCertificateFile: { + file: [], + }, + powerOfAttorneyFile: { + file: [], + }, + }, + } + const result = returnMissingDocumentsList( + missingDocuments as unknown as AccidentNotification, + formatMessage, + ) + expect(result).toEqual('test.pdf, test.pdf, test.pdf') + }) +}) + +describe('isUploadNow', () => { + const powerOfAttorneyReporterWithUploadNow: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + powerOfAttorney: { + type: PowerOfAttorneyUploadEnum.UPLOADNOW, + }, + } + + const powerOfAttorneyReporterWithUploadLater: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + powerOfAttorney: { + type: PowerOfAttorneyUploadEnum.UPLOADLATER, + }, + } + + const reportingForSelf: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.ME, + }, + } + + const emptyObject = {} + + it('should return true for power of attorney reporter with upload now', () => { + expect(isUploadNow(powerOfAttorneyReporterWithUploadNow)).toEqual(true) + }) + + it('should return false for power of attorney reporter with upload later', () => { + expect(isUploadNow(powerOfAttorneyReporterWithUploadLater)).toEqual(false) + }) + + it('should return false for reporting for yourself', () => { + expect(isUploadNow(reportingForSelf)).toEqual(false) + }) + + it('should return false for empty object', () => { + expect(isUploadNow(emptyObject)).toEqual(false) + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/documentUtils.ts b/libs/application/templates/accident-notification/src/utils/documentUtils.ts new file mode 100644 index 000000000000..e352dfe2997e --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/documentUtils.ts @@ -0,0 +1,295 @@ +import { getValueViaPath, YES } from '@island.is/application/core' +import { AccidentNotification } from '../lib/dataSchema' +import { + AttachmentsEnum, + FileType, + PowerOfAttorneyUploadEnum, + WhoIsTheNotificationForEnum, +} from '../types' +import { attachments, overview } from '../lib/messages' +import { FormatMessage } from '@island.is/localization' +import { FormValue } from '@island.is/application/types' +import { + AccidentNotificationAttachmentStatus, + AccidentNotifTypes, + YesOrNo, +} from '../types' +import { + isReportingOnBehalfOfEmployee, + isReportingOnBehalfSelf, +} from './reportingUtils' +import { isFatalAccident } from './accidentUtils' + +export const hasAttachment = (attachment: Array | undefined) => + attachment && attachment.length > 0 + +const includesAttachment = ( + answers: FormValue, + attachmentType: AccidentNotifTypes, +): boolean => { + const accidentNotifications = + getValueViaPath( + answers, + 'accidentStatus.receivedAttachments', + ) + return accidentNotifications?.[attachmentType] || false +} + +export const hasReceivedInjuryCertificate = (answers: FormValue) => { + return includesAttachment(answers, 'InjuryCertificate') +} + +export const hasReceivedProxyDocument = (answers: FormValue) => { + return includesAttachment(answers, 'ProxyDocument') +} + +export const hasReceivedPoliceReport = (answers: FormValue) => { + return includesAttachment(answers, 'PoliceReport') +} + +export const hasReceivedInjuryCertificateOrAddedToAnswers = ( + answers: FormValue, +) => { + const injuryCertificateFile = getValueViaPath>( + answers, + 'attachments.injuryCertificateFile.file', + [{ key: '', name: '' }], + ) + + return ( + hasReceivedInjuryCertificate(answers) || + hasAttachment(injuryCertificateFile) + ) +} + +export const hasReceivedProxyDocumentOrAddedToAnswers = ( + answers: FormValue, +) => { + const powerOfAttorneyFile = getValueViaPath>( + answers, + 'attachments.powerOfAttorneyFile.file', + [{ key: '', name: '' }], + ) + + return hasReceivedProxyDocument(answers) || hasAttachment(powerOfAttorneyFile) +} + +export const hasReceivedPoliceReportOrAddedToAnswers = (answers: FormValue) => { + const deathCertificateFile = getValueViaPath>( + answers, + 'attachments.deathCertificateFile.file', + [{ key: '', name: '' }], + ) + + return hasReceivedPoliceReport(answers) || hasAttachment(deathCertificateFile) +} + +export const hasReceivedAllDocuments = (answers: FormValue) => { + // Reporting for self or as juridicial person only injury certificate relevent + if ( + isReportingOnBehalfSelf(answers) || + isReportingOnBehalfOfEmployee(answers) + ) { + return hasReceivedInjuryCertificate(answers) + } else { + // If fatal and not report for self or as juridicial all documents are relevant + if (isFatalAccident(answers)) { + return ( + hasReceivedPoliceReport(answers) && + hasReceivedProxyDocument(answers) && + hasReceivedInjuryCertificate(answers) + ) + } else { + return ( + hasReceivedProxyDocument(answers) && + hasReceivedInjuryCertificate(answers) + ) + } + } +} + +export const getErrorMessageForMissingDocuments = ( + answers: FormValue, + formatMessage: FormatMessage, + isAssigneeAndUnique: boolean, +) => { + const whoIsTheNotificationFor = getValueViaPath( + answers, + 'whoIsTheNotificationFor.answer', + ) + const wasTheAccidentFatal = getValueViaPath( + answers, + 'wasTheAccidentFatal', + ) + const missingDocuments = [] + + if (!hasReceivedInjuryCertificateOrAddedToAnswers(answers)) { + missingDocuments.push( + formatMessage(attachments.documentNames.injuryCertificate), + ) + } + + // Only show this to applicant or assignee that is also the applicant + if ( + whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && + !hasReceivedProxyDocumentOrAddedToAnswers(answers) && + !isAssigneeAndUnique + ) { + missingDocuments.push( + formatMessage(attachments.documentNames.powerOfAttorneyDocument), + ) + } + + if ( + wasTheAccidentFatal === YES && + !hasReceivedPoliceReportOrAddedToAnswers(answers) + ) { + missingDocuments.push( + formatMessage(attachments.documentNames.deathCertificate), + ) + } + + return missingDocuments.join(', ') +} + +export const hasMissingInjuryCertificate = (answers: FormValue) => { + const injuryCertificate = getValueViaPath( + answers, + 'injuryCertificate.answer', + ) + return injuryCertificate === AttachmentsEnum.SENDCERTIFICATELATER +} + +export const hasMissingDeathCertificate = (answers: FormValue) => { + const wasTheAccidentFatal = getValueViaPath( + answers, + 'wasTheAccidentFatal', + ) + return wasTheAccidentFatal === YES +} + +export const hasMissingPowerOfAttorneyFile = (answers: FormValue): boolean => { + const whoIsTheNotificationFor = getValueViaPath( + answers, + 'whoIsTheNotificationFor.answer', + ) + return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY +} + +export const hasMissingDocuments = (answers: FormValue) => { + const injuryCertificateFile = getValueViaPath>( + answers, + 'attachments.injuryCertificateFile.file', + ) + + const deathCertificateFile = getValueViaPath>( + answers, + 'attachments.deathCertificateFile.file', + ) + + const powerOfAttorneyFile = getValueViaPath>( + answers, + 'attachments.powerOfAttorneyFile.file', + ) + + return ( + (hasMissingInjuryCertificate(answers) && + !hasAttachment(injuryCertificateFile)) || + (hasMissingDeathCertificate(answers) && + !hasAttachment(deathCertificateFile)) || + (hasMissingPowerOfAttorneyFile(answers) && + !hasAttachment(powerOfAttorneyFile)) + ) +} + +export const getAttachmentTitles = (answers: AccidentNotification) => { + const deathCertificateFile = + answers.attachments?.deathCertificateFile?.file || undefined + const injuryCertificateFile = + answers.attachments?.injuryCertificateFile?.file || undefined + const powerOfAttorneyFile = + answers.attachments?.powerOfAttorneyFile?.file || undefined + const additionalFiles = + answers.attachments?.additionalFiles?.file || undefined + const additionalFilesFromReviewer = + answers.attachments?.additionalFilesFromReviewer?.file || undefined + + const files = [] + + if (hasAttachment(deathCertificateFile)) + files.push(attachments.documentNames.deathCertificate) + if ( + hasAttachment(injuryCertificateFile) && + getValueViaPath(answers, 'injuryCertificate.answer') !== + AttachmentsEnum.HOSPITALSENDSCERTIFICATE + ) + files.push(attachments.documentNames.injuryCertificate) + if (hasAttachment(powerOfAttorneyFile)) + files.push(attachments.documentNames.powerOfAttorneyDocument) + if ( + answers.injuryCertificate?.answer === + AttachmentsEnum.HOSPITALSENDSCERTIFICATE + ) + files.push(overview.labels.hospitalSendsCertificate) + if (hasAttachment(additionalFiles)) + files.push(attachments.documentNames.additionalDocumentsFromApplicant) + if (hasAttachment(additionalFilesFromReviewer)) + files.push(attachments.documentNames.additionalDocumentsFromReviewer) + + return files +} + +export const returnMissingDocumentsList = ( + answers: AccidentNotification, + formatMessage: FormatMessage, +) => { + const injuryCertificate = answers.injuryCertificate + const whoIsTheNotificationFor = answers.whoIsTheNotificationFor.answer + const wasTheAccidentFatal = answers.wasTheAccidentFatal + const missingDocuments = [] + + if ( + injuryCertificate?.answer === AttachmentsEnum.SENDCERTIFICATELATER && + !hasAttachment(answers.attachments?.injuryCertificateFile?.file) + ) { + missingDocuments.push( + formatMessage(attachments.documentNames.injuryCertificate), + ) + } + + // Only show this to applicant or assignee that is also the applicant + if ( + whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && + !hasAttachment(answers.attachments?.powerOfAttorneyFile?.file) + ) { + missingDocuments.push( + formatMessage(attachments.documentNames.powerOfAttorneyDocument), + ) + } + + if ( + wasTheAccidentFatal === YES && + !hasAttachment(answers.attachments?.deathCertificateFile?.file) + ) { + missingDocuments.push( + formatMessage(attachments.documentNames.deathCertificate), + ) + } + + return missingDocuments.join(', ') +} + +export const isUploadNow = (formValue: FormValue) => { + const whoIsTheNotificationFor = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + const powerOfAttorneyType = getValueViaPath( + formValue, + 'powerOfAttorney.type', + ) + return ( + whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && + powerOfAttorneyType === PowerOfAttorneyUploadEnum.UPLOADNOW + ) +} diff --git a/libs/application/templates/accident-notification/src/utils/fishermanUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/fishermanUtils.spec.ts deleted file mode 100644 index 03141eb17bdd..000000000000 --- a/libs/application/templates/accident-notification/src/utils/fishermanUtils.spec.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { - AccidentTypeEnum, - FishermanWorkplaceAccidentLocationEnum, - WorkAccidentTypeEnum, -} from '../types' -import { isAboardShip, isFishermanAccident } from './fishermanUtils' -describe('isFishermanAccident', () => { - const fishermanAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, - } - - const emptyObject = {} - - it('should return true for fisherman accidents', () => { - expect(isFishermanAccident(fishermanAccident)).toEqual(true) - }) - it('should return false for workplace accidents other than fisherman', () => { - expect(isFishermanAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isFishermanAccident(emptyObject)).toEqual(false) - }) -}) - -describe('isAboardShip', () => { - const onTheShipLocation: FormValue = { - accidentLocation: { - answer: FishermanWorkplaceAccidentLocationEnum.ONTHESHIP, - }, - workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherLocation: FormValue = { - accidentLocation: { answer: FishermanWorkplaceAccidentLocationEnum.OTHER }, - workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const emptyObject = {} - - it('should return true for fisherman work accident that happens on a ship', () => { - expect(isAboardShip(onTheShipLocation)).toEqual(true) - }) - it('should return false for fisherman work accident that happens else where', () => { - expect(isAboardShip(someOtherLocation)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isAboardShip(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/fishermanUtils.ts b/libs/application/templates/accident-notification/src/utils/fishermanUtils.ts deleted file mode 100644 index 280165f94136..000000000000 --- a/libs/application/templates/accident-notification/src/utils/fishermanUtils.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { - FishermanWorkplaceAccidentLocationEnum, - WorkAccidentTypeEnum, -} from '../types' -import { isWorkAccident } from './isWorkAccident' - -// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the workaccident type. -// Therefore we need to check also whether this is a work accident -export const isFishermanAccident = (formValue: FormValue) => { - const workAccidentType = getValueViaPath( - formValue, - 'workAccident.type', - ) as WorkAccidentTypeEnum - return ( - workAccidentType === WorkAccidentTypeEnum.FISHERMAN && - isWorkAccident(formValue) - ) -} - -// As this is a third question the user is asked there is a case where he could go back -// and select home activities and keep the workaccident type or go back and change where the -// accident happened. -// Therefore we need to check ifFishermanAccident function again -export const isAboardShip = (formValue: FormValue) => { - const fishermanWorkplaceAccidentLocationAnswer = getValueViaPath( - formValue, - 'accidentLocation.answer', - ) as FishermanWorkplaceAccidentLocationEnum - return ( - isFishermanAccident(formValue) && - fishermanWorkplaceAccidentLocationAnswer === - FishermanWorkplaceAccidentLocationEnum.ONTHESHIP - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.ts b/libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.ts deleted file mode 100644 index ce91825ff6c9..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { accidentType } from '../lib/messages' -import { AccidentTypeEnum } from '../types' -import { isReportingOnBehalfOfChild } from './isReportingOnBehalfOfChild' -import { isReportingOnBehalfOfEmployee } from './isReportingOnBehalfOfEmployee' - -export const getAccidentTypeOptions = (answers: FormValue) => { - const options = [ - { - value: AccidentTypeEnum.WORK, - label: accidentType.labels.work, - }, - { - value: AccidentTypeEnum.RESCUEWORK, - label: accidentType.labels.rescueWork, - }, - { - value: AccidentTypeEnum.STUDIES, - label: accidentType.labels.studies, - }, - { - value: AccidentTypeEnum.SPORTS, - label: accidentType.labels.sports, - }, - ] - - if ( - !isReportingOnBehalfOfEmployee(answers) && - !isReportingOnBehalfOfChild(answers) - ) { - options.unshift({ - value: AccidentTypeEnum.HOMEACTIVITIES, - label: accidentType.labels.homeActivities, - }) - } - - return options -} diff --git a/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.spec.ts b/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.spec.ts deleted file mode 100644 index d5cdb40fada9..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { getInjuredPersonInformation } from './getInjuredPersonInformation' - -describe('getInjuredPersonInformation', () => { - const injuredPersonInformation: FormValue = { - injuredPersonInformation: { - email: 'kalli@palli.is', - name: 'Kalli', - }, - } - - const emptyInjuredPersonInformation: FormValue = { - injuredPersonInformation: { - email: '', - name: '', - }, - } - - it('should return an array of length 4 when submitting on behalf of employee', () => { - expect( - getInjuredPersonInformation(injuredPersonInformation)?.email, - ).toEqual('kalli@palli.is') - }) - - it('should return an array of length 5 when not submitting on behalf of employee', () => { - expect(getInjuredPersonInformation(injuredPersonInformation)?.name).toEqual( - 'Kalli', - ) - }) - - it('should return an array of length 5 for empty object', () => { - expect( - getInjuredPersonInformation(emptyInjuredPersonInformation)?.email, - ).toEqual('') - }) - - it('should have work as first option when submitting on behalf of employee', () => { - expect( - getInjuredPersonInformation(emptyInjuredPersonInformation)?.name, - ).toEqual('') - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.ts b/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.ts deleted file mode 100644 index 4a2560a62074..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getInjuredPersonInformation.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' - -export const getInjuredPersonInformation = (answers: FormValue) => { - const injuredPersonsEmail = getValueViaPath( - answers, - 'injuredPersonInformation.email', - ) as string - - const injuredPersonsName = getValueViaPath( - answers, - 'injuredPersonInformation.name', - ) as string - const injuredPersonsInformation = { - email: injuredPersonsEmail, - name: injuredPersonsName, - } - return injuredPersonsInformation -} diff --git a/libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.spec.ts b/libs/application/templates/accident-notification/src/utils/getOptions.spec.ts similarity index 96% rename from libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.spec.ts rename to libs/application/templates/accident-notification/src/utils/getOptions.spec.ts index 0d252b1e768b..b884f68e3347 100644 --- a/libs/application/templates/accident-notification/src/utils/getAccidentTypeOptions.spec.ts +++ b/libs/application/templates/accident-notification/src/utils/getOptions.spec.ts @@ -1,6 +1,6 @@ import { FormValue } from '@island.is/application/types' import { AccidentTypeEnum, WhoIsTheNotificationForEnum } from '../types' -import { getAccidentTypeOptions } from './getAccidentTypeOptions' +import { getAccidentTypeOptions } from './getOptions' describe('getAccidentTypeOptions', () => { const onBehalfOfEmployee: FormValue = { diff --git a/libs/application/templates/accident-notification/src/utils/getOptions.ts b/libs/application/templates/accident-notification/src/utils/getOptions.ts new file mode 100644 index 000000000000..e2945ae17ad4 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/getOptions.ts @@ -0,0 +1,72 @@ +import { WhoIsTheNotificationForEnum } from '../types' +import { whoIsTheNotificationFor } from '../lib/messages' +import { FormValue } from '@island.is/application/types' +import { accidentType } from '../lib/messages' +import { AccidentTypeEnum } from '../types' +import { + isReportingOnBehalfOfChild, + isReportingOnBehalfOfEmployee, +} from './reportingUtils' + +export const getAccidentTypeOptions = (answers: FormValue) => { + const options = [ + { + value: AccidentTypeEnum.WORK, + label: accidentType.labels.work, + }, + { + value: AccidentTypeEnum.RESCUEWORK, + label: accidentType.labels.rescueWork, + }, + { + value: AccidentTypeEnum.STUDIES, + label: accidentType.labels.studies, + }, + { + value: AccidentTypeEnum.SPORTS, + label: accidentType.labels.sports, + }, + ] + + if ( + !isReportingOnBehalfOfEmployee(answers) && + !isReportingOnBehalfOfChild(answers) + ) { + options.unshift({ + value: AccidentTypeEnum.HOMEACTIVITIES, + label: accidentType.labels.homeActivities, + }) + } + + return options +} + +export const whoIsTheNotificationForOptions = [ + { + value: WhoIsTheNotificationForEnum.ME, + label: whoIsTheNotificationFor.labels.me, + }, + { + value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + label: whoIsTheNotificationFor.labels.powerOfAttorney, + }, + { + value: WhoIsTheNotificationForEnum.JURIDICALPERSON, + label: whoIsTheNotificationFor.labels.juridicalPerson, + }, + { + value: WhoIsTheNotificationForEnum.CHILDINCUSTODY, + label: whoIsTheNotificationFor.labels.childInCustody, + }, +] + +export const whoIsTheNotificationForProcureOptions = [ + { + value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + label: whoIsTheNotificationFor.labels.powerOfAttorneyProcure, + }, + { + value: WhoIsTheNotificationForEnum.JURIDICALPERSON, + label: whoIsTheNotificationFor.labels.juridicalPerson, + }, +] diff --git a/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts b/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts deleted file mode 100644 index 28910229cf83..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getWhoIstheNotificationForOptions.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { WhoIsTheNotificationForEnum } from '../types' -import { whoIsTheNotificationFor } from '../lib/messages' - -export const whoIsTheNotificationForOptions = [ - { - value: WhoIsTheNotificationForEnum.ME, - label: whoIsTheNotificationFor.labels.me, - }, - { - value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - label: whoIsTheNotificationFor.labels.powerOfAttorney, - }, - { - value: WhoIsTheNotificationForEnum.JURIDICALPERSON, - label: whoIsTheNotificationFor.labels.juridicalPerson, - }, - { - value: WhoIsTheNotificationForEnum.CHILDINCUSTODY, - label: whoIsTheNotificationFor.labels.childInCustody, - }, -] - -export const whoIsTheNotificationForProcureOptions = [ - { - value: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - label: whoIsTheNotificationFor.labels.powerOfAttorneyProcure, - }, - { - value: WhoIsTheNotificationForEnum.JURIDICALPERSON, - label: whoIsTheNotificationFor.labels.juridicalPerson, - }, -] diff --git a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts b/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts deleted file mode 100644 index 45a3cb6d6a11..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.spec.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { YES } from './constants' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { getWorkplaceData } from './getWorkplaceData' - -describe('getWorkplaceData', () => { - const generalWorkplaceAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.GENERAL }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - companyInfo: {}, - } - - const professionalAthleteAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.SPORTS }, - companyInfo: { onPayRoll: { answer: YES } }, - } - - const rescueWorkAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, - } - - const studiesAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.STUDIES }, - } - - const fishermanAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const emptyObject = {} - - it('should return general work type data for general work accidents', () => { - expect(getWorkplaceData(generalWorkplaceAccident)?.type).toEqual( - AccidentTypeEnum.WORK, - ) - }) - - it('should return sports type data for professional athlete accidents', () => { - expect(getWorkplaceData(professionalAthleteAccident)?.type).toEqual( - AccidentTypeEnum.SPORTS, - ) - }) - - it('should return employee information for professional athlete accidents', () => { - expect( - getWorkplaceData(professionalAthleteAccident)?.companyInfo.onPayRoll - ?.answer, - ).toBe(YES) - }) - - it('should not return employee information for general workplace accident', () => { - expect( - getWorkplaceData(generalWorkplaceAccident)?.companyInfo.onPayRoll, - ).toBe(undefined) - }) - - it('should return rescue work type data for rescue work accidents', () => { - expect(getWorkplaceData(rescueWorkAccident)?.type).toEqual( - AccidentTypeEnum.RESCUEWORK, - ) - }) - - it('should return studies type data for student accidents', () => { - expect(getWorkplaceData(studiesAccident)?.type).toEqual( - AccidentTypeEnum.STUDIES, - ) - }) - - it('should return fisherman type data for fisherman accidents', () => { - expect(getWorkplaceData(fishermanAccident)?.type).toEqual( - WorkAccidentTypeEnum.FISHERMAN, - ) - }) - - it('should return undefined for empty object', () => { - expect(getWorkplaceData(emptyObject)?.type).toEqual(undefined) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.ts b/libs/application/templates/accident-notification/src/utils/getWorkplaceData.ts deleted file mode 100644 index ccabbb5fe7aa..000000000000 --- a/libs/application/templates/accident-notification/src/utils/getWorkplaceData.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { - isGeneralWorkplaceAccident, - isStudiesAccident, - isFishermanAccident, - isProfessionalAthleteAccident, - isRescueWorkAccident, -} from './' -import { - companyInfo, - fishingCompanyInfo, - rescueSquadInfo, - schoolInfo, - sportsClubInfo, - representativeInfo, -} from '../lib/messages' -import { - AccidentTypeEnum, - CompanyInfo, - RepresentativeInfo, - WorkAccidentTypeEnum, - YesOrNo, -} from '../types' -import { isHomeActivitiesAccident } from './isHomeActivitiesAccident' - -interface WorkplaceData { - companyInfo: CompanyInfo - representitive: RepresentativeInfo - companyInfoMsg: typeof companyInfo - representitiveMsg: typeof representativeInfo - type: WorkAccidentTypeEnum | AccidentTypeEnum - onPayRoll?: YesOrNo - screenId: string -} - -export const getWorkplaceData = ( - answers: FormValue, -): WorkplaceData | undefined => { - if (isHomeActivitiesAccident(answers)) { - return - } - - const workplaceData = { - companyInfo: getValueViaPath(answers, 'companyInfo') as CompanyInfo, - representitive: getValueViaPath( - answers, - 'representative', - ) as RepresentativeInfo, - representitiveMsg: representativeInfo, - } as WorkplaceData - - if (isGeneralWorkplaceAccident(answers)) - return { - ...workplaceData, - companyInfoMsg: companyInfo, - type: AccidentTypeEnum.WORK, - screenId: 'companyInfo', - } - - if (isStudiesAccident(answers)) - return { - ...workplaceData, - companyInfoMsg: schoolInfo, - type: AccidentTypeEnum.STUDIES, - screenId: 'schoolInfo', - } - - if (isFishermanAccident(answers)) - return { - ...workplaceData, - companyInfoMsg: fishingCompanyInfo, - type: WorkAccidentTypeEnum.FISHERMAN, - screenId: 'fishingCompanyInfo', - } - - if (isProfessionalAthleteAccident(answers)) - return { - ...workplaceData, - onPayRoll: getValueViaPath(answers, 'onPayRoll.answer') as YesOrNo, - companyInfoMsg: sportsClubInfo, - type: AccidentTypeEnum.SPORTS, - screenId: 'sportsClubInfo', - } - - if (isRescueWorkAccident(answers)) - return { - ...workplaceData, - companyInfoMsg: rescueSquadInfo, - type: AccidentTypeEnum.RESCUEWORK, - screenId: 'rescueSquad', - } -} diff --git a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts deleted file mode 100644 index 945c4858ce4f..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.spec.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { - getErrorMessageForMissingDocuments, - hasMissingDocuments, - hasReceivedAllDocuments, -} from './hasMissingDocuments' -import { WhoIsTheNotificationForEnum, AttachmentsEnum } from '../types' -import { NO, YES } from './constants' -import { FormatMessage } from '@island.is/localization' -import { FormValue } from '@island.is/application/types' -import { AccidentNotification } from '../lib/dataSchema' - -describe('hasMissingDocuments', () => { - it('should return true when missing documents', () => { - expect(hasMissingDocuments(getMissingDocuments())).toEqual(true) - }) - - it('should return false when no missing documents', () => { - expect(hasMissingDocuments(getNoMissingDocuments())).toEqual(false) - }) -}) - -describe('getErrorMessageForMissingDocuments', () => { - const formatMessage: FormatMessage = jest.fn().mockReturnValue('test.pdf') - - beforeEach(() => { - jest.clearAllMocks() - }) - - it('should return error message for missing documents', () => { - const result = getErrorMessageForMissingDocuments( - getMissingDocuments(), - formatMessage, - false, - ) - expect(result).toEqual('test.pdf, test.pdf, test.pdf') - expect(formatMessage).toHaveBeenCalledTimes(3) - }) - - it('should return empty string when no documents are missing', () => { - const docs = getNoMissingDocuments() - const result = getErrorMessageForMissingDocuments(docs, formatMessage, true) - expect(result).toBe('') - expect(formatMessage).not.toHaveBeenCalled() - }) -}) - -describe('hasReceivedAllDocuments', () => { - const testCases = [ - { who: WhoIsTheNotificationForEnum.ME, fatal: NO }, - { who: WhoIsTheNotificationForEnum.JURIDICALPERSON, fatal: NO }, - { who: WhoIsTheNotificationForEnum.POWEROFATTORNEY, fatal: YES }, - { who: WhoIsTheNotificationForEnum.POWEROFATTORNEY, fatal: NO }, - ] - it.each(testCases)( - 'should return true when all documents are received', - (data) => { - const answers = getNoMissingDocuments() as AccidentNotification - answers.whoIsTheNotificationFor.answer = data.who - answers.wasTheAccidentFatal = data.fatal as unknown as 'no' | 'yes' - expect(hasReceivedAllDocuments(answers)).toEqual(true) - }, - ) - - it.each(testCases)('should return false when missing documents', (data) => { - const answers = getMissingDocuments() as AccidentNotification - answers.whoIsTheNotificationFor.answer = data.who - answers.wasTheAccidentFatal = data.fatal as unknown as 'no' | 'yes' - expect(hasReceivedAllDocuments(answers)).toEqual(false) - }) -}) - -const EMPTY_FILE: never[] = [] - -const SAMPLE_FILE = { - name: 'test.pdf', - url: 'https://test.pdf', -} as const -const createAttachment = () => ({ file: [SAMPLE_FILE] }) - -const getMissingDocuments = (): FormValue => ({ - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - wasTheAccidentFatal: YES, - injuryCertificate: { - answer: AttachmentsEnum.SENDCERTIFICATELATER, - }, - accidentStatus: { - receivedAttachments: { - InjuryCertificate: false, - PoliceReport: false, - DeathCertificate: false, - ProxyDocument: false, - }, - }, - attachments: { - injuryCertificateFile: { file: EMPTY_FILE }, - deathCertificateFile: { file: EMPTY_FILE }, - powerOfAttorneyFile: { file: EMPTY_FILE }, - }, -}) - -const getNoMissingDocuments = (): FormValue => ({ - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - wasTheAccidentFatal: YES, - injuryCertificate: { - answer: AttachmentsEnum.SENDCERTIFICATELATER, - }, - accidentStatus: { - receivedAttachments: { - InjuryCertificate: true, - PoliceReport: true, - DeathCertificate: true, - ProxyDocument: true, - }, - }, - attachments: { - injuryCertificateFile: { - file: [createAttachment()], - }, - deathCertificateFile: { - file: [createAttachment()], - }, - powerOfAttorneyFile: { - file: [createAttachment()], - }, - }, -}) diff --git a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts b/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts deleted file mode 100644 index d262c07b6226..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hasMissingDocuments.ts +++ /dev/null @@ -1,195 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { FormatMessage } from '@island.is/localization' -import { AttachmentsEnum, FileType, WhoIsTheNotificationForEnum } from '..' -import { YES } from './constants' -import { attachments } from '../lib/messages' -import { - AccidentNotificationAttachmentStatus, - AccidentNotifTypes, - YesOrNo, -} from '../types' -import { isFatalAccident } from './isFatalAccident' -import { isReportingOnBehalfSelf } from './isReportingBehalfOfSelf' -import { isReportingOnBehalfOfEmployee } from './isReportingOnBehalfOfEmployee' - -const hasAttachment = (attachment: FileType[] | undefined) => - attachment && attachment.length > 0 - -const includesAttachment = ( - answers: FormValue, - attachmentType: AccidentNotifTypes, -): boolean => { - const accidentNotifications = getValueViaPath( - answers, - 'accidentStatus.receivedAttachments', - ) as AccidentNotificationAttachmentStatus - return accidentNotifications?.[attachmentType] || false -} - -export const hasReceivedInjuryCertificate = (answers: FormValue) => { - return includesAttachment(answers, 'InjuryCertificate') -} - -export const hasReceivedProxyDocument = (answers: FormValue) => { - return includesAttachment(answers, 'ProxyDocument') -} - -export const hasReceivedPoliceReport = (answers: FormValue) => { - return includesAttachment(answers, 'PoliceReport') -} - -export const hasReceivedInjuryCertificateOrAddedToAnswers = ( - answers: FormValue, -) => { - const injuryCertificateFile = getValueViaPath( - answers, - 'attachments.injuryCertificateFile.file', - {}, - ) as FileType[] - - return ( - hasReceivedInjuryCertificate(answers) || - hasAttachment(injuryCertificateFile) - ) -} - -export const hasReceivedProxyDocumentOrAddedToAnswers = ( - answers: FormValue, -) => { - const powerOfAttorneyFile = getValueViaPath( - answers, - 'attachments.powerOfAttorneyFile.file', - {}, - ) as FileType[] - - return hasReceivedProxyDocument(answers) || hasAttachment(powerOfAttorneyFile) -} - -export const hasReceivedPoliceReportOrAddedToAnswers = (answers: FormValue) => { - const deathCertificateFile = getValueViaPath( - answers, - 'attachments.deathCertificateFile.file', - {}, - ) as FileType[] - - return hasReceivedPoliceReport(answers) || hasAttachment(deathCertificateFile) -} - -export const hasReceivedAllDocuments = (answers: FormValue) => { - // Reporting for self or as juridicial person only injury certificate relevent - if ( - isReportingOnBehalfSelf(answers) || - isReportingOnBehalfOfEmployee(answers) - ) { - return hasReceivedInjuryCertificate(answers) - } else { - // If fatal and not report for self or as juridicial all documents are relevant - if (isFatalAccident(answers)) { - return ( - hasReceivedPoliceReport(answers) && - hasReceivedProxyDocument(answers) && - hasReceivedInjuryCertificate(answers) - ) - } else { - return ( - hasReceivedProxyDocument(answers) && - hasReceivedInjuryCertificate(answers) - ) - } - } -} - -export const getErrorMessageForMissingDocuments = ( - answers: FormValue, - formatMessage: FormatMessage, - isAssigneeAndUnique: boolean, -) => { - const whoIsTheNotificationFor = getValueViaPath( - answers, - 'whoIsTheNotificationFor.answer', - ) - const wasTheAccidentFatal = getValueViaPath( - answers, - 'wasTheAccidentFatal', - ) as YesOrNo - const missingDocuments = [] - - if (!hasReceivedInjuryCertificateOrAddedToAnswers(answers)) { - missingDocuments.push( - formatMessage(attachments.documentNames.injuryCertificate), - ) - } - - // Only show this to applicant or assignee that is also the applicant - if ( - whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && - !hasReceivedProxyDocumentOrAddedToAnswers(answers) && - !isAssigneeAndUnique - ) { - missingDocuments.push( - formatMessage(attachments.documentNames.powerOfAttorneyDocument), - ) - } - - if ( - wasTheAccidentFatal === YES && - !hasReceivedPoliceReportOrAddedToAnswers(answers) - ) { - missingDocuments.push( - formatMessage(attachments.documentNames.deathCertificate), - ) - } - - return missingDocuments.join(', ') -} - -export const hasMissingInjuryCertificate = (answers: FormValue) => { - const injuryCertificate = getValueViaPath( - answers, - 'injuryCertificate.answer', - ) as AttachmentsEnum - return injuryCertificate === AttachmentsEnum.SENDCERTIFICATELATER -} - -export const hasMissingDeathCertificate = (answers: FormValue) => { - const wasTheAccidentFatal = getValueViaPath( - answers, - 'wasTheAccidentFatal', - ) as YesOrNo - return wasTheAccidentFatal === YES -} - -export const hasMissingPowerOfAttorneyFile = (answers: FormValue): boolean => { - const whoIsTheNotificationFor = getValueViaPath( - answers, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY -} - -export const hasMissingDocuments = (answers: FormValue) => { - const injuryCertificateFile = getValueViaPath( - answers, - 'attachments.injuryCertificateFile.file', - ) as FileType[] - - const deathCertificateFile = getValueViaPath( - answers, - 'attachments.deathCertificateFile.file', - ) as FileType[] - - const powerOfAttorneyFile = getValueViaPath( - answers, - 'attachments.powerOfAttorneyFile.file', - ) as FileType[] - - return ( - (hasMissingInjuryCertificate(answers) && - !hasAttachment(injuryCertificateFile)) || - (hasMissingDeathCertificate(answers) && - !hasAttachment(deathCertificateFile)) || - (hasMissingPowerOfAttorneyFile(answers) && - !hasAttachment(powerOfAttorneyFile)) - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.spec.ts b/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.spec.ts deleted file mode 100644 index a778beed75ab..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { hasReceivedConfirmation } from './hasReceivedConfirmation' -import { WhoIsTheNotificationForEnum } from '../types' -describe('hasReceivedConfirmation', () => { - const confirmedJuridicial: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, - }, - accidentStatus: { - receivedConfirmations: { - InjuredOrRepresentativeParty: true, - }, - }, - } - - const confirmedMe: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.ME, - }, - accidentStatus: { - receivedConfirmations: { - CompanyParty: true, - }, - }, - } - - const notConfirmed: FormValue = { - accidentStatus: { - receivedConfirmations: false, - }, - } - - it.each([ - { for: 'juridical person', input: confirmedJuridicial, expected: true }, - { for: 'company', input: confirmedMe, expected: true }, - { for: 'not confirmed', input: notConfirmed, expected: false }, - ])( - 'should return $expected when confirmation is $for', - ({ input, expected }) => { - expect(hasReceivedConfirmation(input)).toEqual(expected) - }, - ) -}) diff --git a/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.ts b/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.ts deleted file mode 100644 index d3796bbe8ede..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hasReceivedConfirmation.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { AccidentNotificationConfirmation } from '@island.is/api/schema' -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { isReportingOnBehalfOfEmployee } from './isReportingOnBehalfOfEmployee' - -export const hasReceivedConfirmation = (answers: FormValue) => { - const accidentConfirmations = getValueViaPath( - answers, - 'accidentStatus.receivedConfirmations', - ) as AccidentNotificationConfirmation - - // if juridical person then the injured or the power of attorney holder has to confirm - if (isReportingOnBehalfOfEmployee(answers)) { - return !!accidentConfirmations.InjuredOrRepresentativeParty - } - - // as there isn't an juridical person reporting, this must be someone reporting for the injured - // or the injured himself and that requires the companies confirmation - return !!accidentConfirmations.CompanyParty -} diff --git a/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.spec.ts b/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.spec.ts deleted file mode 100644 index e6c00793695b..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { - GeneralWorkplaceAccidentLocationEnum, - StudiesAccidentLocationEnum, -} from '../types' -import { hideLocationAndPurpose } from './hideLocationAndPurpose' -describe('hideLocationAndPurpose', () => { - const accidentLocationAtWorkplace: FormValue = { - accidentLocation: { - answer: GeneralWorkplaceAccidentLocationEnum.ATTHEWORKPLACE, - }, - } - - const accidentLocationAtSchoole: FormValue = { - accidentLocation: { answer: StudiesAccidentLocationEnum.ATTHESCHOOL }, - } - - const someOtherLocation: FormValue = { - accidentLocation: { answer: GeneralWorkplaceAccidentLocationEnum.OTHER }, - } - - const emptyObject = {} - - it('should return true for accident location at workplace', () => { - expect(hideLocationAndPurpose(accidentLocationAtWorkplace)).toEqual(true) - }) - it('should return true for accident location at school', () => { - expect(hideLocationAndPurpose(accidentLocationAtSchoole)).toEqual(true) - }) - it('should return false for accident location elsewhere', () => { - expect(hideLocationAndPurpose(someOtherLocation)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(hideLocationAndPurpose(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.ts b/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.ts deleted file mode 100644 index c0d1d5496027..000000000000 --- a/libs/application/templates/accident-notification/src/utils/hideLocationAndPurpose.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { - GeneralWorkplaceAccidentLocationEnum, - ProfessionalAthleteAccidentLocationEnum, - StudiesAccidentLocationEnum, -} from '../types' -import { isHomeActivitiesAccident } from './isHomeActivitiesAccident' - -// Location and purpose of accident only relevant in work and studies and never in home -// activities -export const hideLocationAndPurpose = (formValue: FormValue) => { - const answer = getValueViaPath(formValue, 'accidentLocation.answer') as - | GeneralWorkplaceAccidentLocationEnum - | StudiesAccidentLocationEnum - | ProfessionalAthleteAccidentLocationEnum - - if (isHomeActivitiesAccident(formValue)) { - return true - } - return ( - answer === GeneralWorkplaceAccidentLocationEnum.ATTHEWORKPLACE || - answer === StudiesAccidentLocationEnum.ATTHESCHOOL || - answer === ProfessionalAthleteAccidentLocationEnum.SPORTCLUBSFACILITES - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/index.spec.ts b/libs/application/templates/accident-notification/src/utils/index.spec.ts deleted file mode 100644 index 9bde4080715f..000000000000 --- a/libs/application/templates/accident-notification/src/utils/index.spec.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { FormatMessage } from '@island.is/localization' -import { YES } from './constants' -import { AccidentNotification } from '../lib/dataSchema' -import { AttachmentsEnum, WhoIsTheNotificationForEnum } from '../types' -import { - isValid24HFormatTime, - formatPhonenumber, - getAttachmentTitles, - returnMissingDocumentsList, -} from './index' - -describe('isValid24HFormatTime', () => { - it.each(['0000', '2359', '1234'])( - 'should return true for valid time', - (time) => { - const result = isValid24HFormatTime(time) - expect(result).toBeTruthy() - }, - ) - - it.each([ - '2534', - '1265', - '2360', - '2400', - '12:34', - '', - '1', - '12', - '123', - '12345', - ])('should return false for invalid time', (time) => { - const result = isValid24HFormatTime(time) - expect(result).toBeFalsy() - }) -}) - -describe('formatPhonenumber', () => { - it.each([ - { input: '1234567', expected: '123-4567' }, - { input: '1234567891011', expected: '123-4567891011' }, - { input: 'ABCDEF@!()', expected: 'ABC-DEF@!()' }, - { input: '123', expected: '123' }, - ])('should format phone number', ({ input, expected }) => { - const result = formatPhonenumber(input) - expect(result).toBe(expected) - }) -}) - -describe('getAttachmentTitles', () => { - it.each([ - AttachmentsEnum.SENDCERTIFICATELATER, - AttachmentsEnum.HOSPITALSENDSCERTIFICATE, - ])('should return attachment titles', (injuryCertificate) => { - const answers = { - injuryCertificate: { - answer: injuryCertificate, - }, - attachments: { - deathCertificateFile: { - file: [ - { - name: 'test.pdf', - url: 'https://test.pdf', - }, - ], - }, - injuryCertificateFile: { - file: [ - { - name: 'test.pdf', - url: 'https://test.pdf', - }, - ], - }, - powerOfAttorneyFile: { - file: [ - { - name: 'test.pdf', - url: 'https://test.pdf', - }, - ], - }, - additionalFiles: { - file: [ - { - name: 'test.pdf', - url: 'https://test.pdf', - }, - ], - }, - additionalFilesFromReviewer: { - file: [ - { - name: 'test.pdf', - url: 'https://test.pdf', - }, - ], - }, - }, - } - - // Semi annoying push stuff here because order matters for strict equals - const isHospitalSendsCertificate = - injuryCertificate === AttachmentsEnum.HOSPITALSENDSCERTIFICATE - const expectedResults = [] - expectedResults.push({ - id: 'an.application:attachments.documentNames.deathCertificate', - defaultMessage: 'Lögregluskýrsla', - description: 'Name of police report for in review', - }) - if (!isHospitalSendsCertificate) { - expectedResults.push({ - id: 'an.application:attachments.documentNames.injuryCertificate', - defaultMessage: 'Áverkavottorð', - description: 'Name of injury certificate for in review', - }) - } - expectedResults.push({ - id: 'an.application:attachments.documentNames.powerOfAttorney', - defaultMessage: 'Umboð', - description: 'Name of power of attorney document for in review', - }) - if (isHospitalSendsCertificate) { - expectedResults.push({ - id: 'an.application:overview.labels.hospitalSendsCertificate', - defaultMessage: - 'Bráðamóttökuskrá - Ég mun óska eftir því að Landspítalinn sendi bráðamóttökuskrá til Sjúkratrygginga Íslands', - description: 'Label for hospital sends certificate in document list', - }) - } - expectedResults.push({ - id: 'an.application:attachments.documentNames.additionalDocumentsFromApplicant', - defaultMessage: 'Auka fylgiskjöl frá umsækjanda', - description: - 'Name of additional attachments for in review from applicant', - }) - expectedResults.push({ - id: 'an.application:attachments.documentNames.additionalDocumentsFromReviewer', - defaultMessage: 'Auka fylgiskjöl frá forsvarsmanni', - description: 'Name of additional attachments for in review from reviewer', - }) - - const result = getAttachmentTitles( - answers as unknown as AccidentNotification, - ) - expect(result).toStrictEqual(expectedResults) - }) -}) - -describe('returnMissingDocumentsList', () => { - it('should return missing documents list', () => { - const formatMessage: FormatMessage = jest.fn().mockReturnValue('test.pdf') - const missingDocuments = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - wasTheAccidentFatal: YES, - injuryCertificate: { - answer: AttachmentsEnum.SENDCERTIFICATELATER, - }, - attachments: { - injuryCertificateFile: { - file: [], - }, - deathCertificateFile: { - file: [], - }, - powerOfAttorneyFile: { - file: [], - }, - }, - } - const result = returnMissingDocumentsList( - missingDocuments as unknown as AccidentNotification, - formatMessage, - ) - expect(result).toEqual('test.pdf, test.pdf, test.pdf') - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/index.ts b/libs/application/templates/accident-notification/src/utils/index.ts deleted file mode 100644 index 2c1059df92f6..000000000000 --- a/libs/application/templates/accident-notification/src/utils/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { AttachmentsEnum, FileType, WhoIsTheNotificationForEnum } from '..' -import { getValueViaPath } from '@island.is/application/core' -import { YES } from './constants' -import { AccidentNotification } from '../lib/dataSchema' -import { attachments, overview } from '../lib/messages' -import { FormatMessage } from '@island.is/localization' - -export const isValid24HFormatTime = (value: string) => { - if (value.length !== 4) return false - const hours = parseInt(value.slice(0, 2)) - const minutes = parseInt(value.slice(2, 4)) - if (hours > 23) return false - if (minutes > 59) return false - return true -} - -export const formatPhonenumber = (value: string) => { - const splitAt = (index: number) => (x: string) => - [x.slice(0, index), x.slice(index)] - if (value.length > 3) return splitAt(3)(value).join('-') - return value -} - -const hasAttachment = (attachment: FileType[] | undefined) => - attachment && attachment.length > 0 - -export const getAttachmentTitles = (answers: AccidentNotification) => { - const deathCertificateFile = - answers.attachments?.deathCertificateFile?.file || undefined - const injuryCertificateFile = - answers.attachments?.injuryCertificateFile?.file || undefined - const powerOfAttorneyFile = - answers.attachments?.powerOfAttorneyFile?.file || undefined - const additionalFiles = - answers.attachments?.additionalFiles?.file || undefined - const additionalFilesFromReviewer = - answers.attachments?.additionalFilesFromReviewer?.file || undefined - - const files = [] - - if (hasAttachment(deathCertificateFile)) - files.push(attachments.documentNames.deathCertificate) - if ( - hasAttachment(injuryCertificateFile) && - getValueViaPath(answers, 'injuryCertificate.answer') !== - AttachmentsEnum.HOSPITALSENDSCERTIFICATE - ) - files.push(attachments.documentNames.injuryCertificate) - if (hasAttachment(powerOfAttorneyFile)) - files.push(attachments.documentNames.powerOfAttorneyDocument) - if ( - answers.injuryCertificate?.answer === - AttachmentsEnum.HOSPITALSENDSCERTIFICATE - ) - files.push(overview.labels.hospitalSendsCertificate) - if (hasAttachment(additionalFiles)) - files.push(attachments.documentNames.additionalDocumentsFromApplicant) - if (hasAttachment(additionalFilesFromReviewer)) - files.push(attachments.documentNames.additionalDocumentsFromReviewer) - - return files -} - -export const returnMissingDocumentsList = ( - answers: AccidentNotification, - formatMessage: FormatMessage, -) => { - const injuryCertificate = answers.injuryCertificate - const whoIsTheNotificationFor = answers.whoIsTheNotificationFor.answer - const wasTheAccidentFatal = answers.wasTheAccidentFatal - const missingDocuments = [] - - if ( - injuryCertificate?.answer === AttachmentsEnum.SENDCERTIFICATELATER && - !hasAttachment(answers.attachments?.injuryCertificateFile?.file) - ) { - missingDocuments.push( - formatMessage(attachments.documentNames.injuryCertificate), - ) - } - - // Only show this to applicant or assignee that is also the applicant - if ( - whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && - !hasAttachment(answers.attachments?.powerOfAttorneyFile?.file) - ) { - missingDocuments.push( - formatMessage(attachments.documentNames.powerOfAttorneyDocument), - ) - } - - if ( - wasTheAccidentFatal === YES && - !hasAttachment(answers.attachments?.deathCertificateFile?.file) - ) { - missingDocuments.push( - formatMessage(attachments.documentNames.deathCertificate), - ) - } - - return missingDocuments.join(', ') -} - -export * from './fishermanUtils' -export * from './getAccidentTypeOptions' -export * from './getInjuredPersonInformation' -export * from './getWorkplaceData' -export * from './hasMissingDocuments' -export * from './hideLocationAndPurpose' -export * from './isAgricultureAccident' -export * from './isDateOlderThanAYear' -export * from './isGeneralWorkplaceAccident' -export * from './isHomeActivitiesAccident' -export * from './isInternshipStudiesAccident' -export * from './isMachineRelatedAccident' -export * from './isProfessionalAthleteAccident' -export * from './isReportingOnBehalfOfChild' -export * from './isReportingOnBehalfOfEmployee' -export * from './isReportingOnBehalfOfInjured' -export * from './isRepresentativeOfCompanyOrInstitute' -export * from './isRescueWorkAccident' -export * from './isStudiesAccident' -export * from './isWorkAccident' -export * from './isPowerOfAttorney' -export * from './isRepresentativeOfCompanyOrInstitute' -export * from './isFatalAccident' -export * from './isReportingBehalfOfSelf' -export * from './isOfWorkTypeAccident' -export * from './shouldRequestReview' -export * from './isUniqueAssignee' diff --git a/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.spec.ts deleted file mode 100644 index 8cbb0f338cfc..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { isAgricultureAccident } from './isAgricultureAccident' -describe('isAgricultureAccident', () => { - const agricultureAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.AGRICULTURE }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, - } - - const emptyObject = {} - - it('should return true for agriculture accidents', () => { - expect(isAgricultureAccident(agricultureAccident)).toEqual(true) - }) - it('should return false for workplace accidents other than agriculture', () => { - expect(isAgricultureAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isAgricultureAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.ts b/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.ts deleted file mode 100644 index e13dea0a0da9..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isAgricultureAccident.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WorkAccidentTypeEnum } from '../types' -import { isWorkAccident } from './isWorkAccident' - -// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the agriculture type. -// Therefore we need to check also whether this is a work accident -export const isAgricultureAccident = (formValue: FormValue) => { - const workAccidentType = getValueViaPath( - formValue, - 'workAccident.type', - ) as WorkAccidentTypeEnum - return ( - workAccidentType === WorkAccidentTypeEnum.AGRICULTURE && - isWorkAccident(formValue) - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts deleted file mode 100644 index 67b9f7bb25ec..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isFatalAccident.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { isFatalAccident } from './isFatalAccident' -import { NO, YES } from './constants' - -describe('isFatalAccident', () => { - const fatal: FormValue = { - wasTheAccidentFatal: YES, - } - - const notFatal: FormValue = { - wasTheAccidentFatal: NO, - } - - it('should return true for a fatal accident', () => { - expect(isFatalAccident(fatal)).toEqual(true) - }) - it('should return false for a non fatal accident', () => { - expect(isFatalAccident(notFatal)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isFatalAccident({})).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts b/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts deleted file mode 100644 index 4094c3efbc99..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isFatalAccident.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { YES } from './constants' -import { YesOrNo } from '../types' - -export const isFatalAccident = (formValue: FormValue) => { - const wasTheAccidentFatal = getValueViaPath( - formValue, - 'wasTheAccidentFatal', - ) as YesOrNo - return wasTheAccidentFatal === YES -} diff --git a/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.spec.ts deleted file mode 100644 index 1949e40394b6..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { isGeneralWorkplaceAccident } from './isGeneralWorkplaceAccident' -describe('isGeneralWorkplaceAccident', () => { - const generalWorkplaceAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.GENERAL }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, - } - - const emptyObject = {} - - it('should return true for general workplace accidents', () => { - expect(isGeneralWorkplaceAccident(generalWorkplaceAccident)).toEqual(true) - }) - it('should return false for workplace accidents other than general', () => { - expect(isGeneralWorkplaceAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isGeneralWorkplaceAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.ts b/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.ts deleted file mode 100644 index 7be7ff2e3c8e..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isGeneralWorkplaceAccident.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WorkAccidentTypeEnum } from '../types' -import { isWorkAccident } from './isWorkAccident' - -// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the workaccident type. -// Therefore we need to check also whether this is a work accident -export const isGeneralWorkplaceAccident = (formValue: FormValue) => { - const workAccidentType = getValueViaPath( - formValue, - 'workAccident.type', - ) as string - return ( - workAccidentType === WorkAccidentTypeEnum.GENERAL && - isWorkAccident(formValue) - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/isHealthInsured.spec.ts b/libs/application/templates/accident-notification/src/utils/isHealthInsured.spec.ts deleted file mode 100644 index a5e8d11ce750..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isHealthInsured.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { isHealthInsured } from './isHealthInsured' - -describe('isHealthInsured', () => { - const healthInsured = { - accidentDetails: { - isHealthInsured: 'yes', - }, - } - - const notHealthInsured = { - accidentDetails: { - isHealthInsured: 'no', - }, - } - - it('should return true when health insured is yes', () => { - expect(isHealthInsured(healthInsured)).toEqual(true) - }) - - it('should return false when health insured is no', () => { - expect(isHealthInsured(notHealthInsured)).toEqual(false) - }) - - it('should return true when health insured is undefined', () => { - expect(isHealthInsured({})).toEqual(true) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isHealthInsured.ts b/libs/application/templates/accident-notification/src/utils/isHealthInsured.ts deleted file mode 100644 index e0e6765d67e1..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isHealthInsured.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' - -export const isHealthInsured = (formValue: FormValue) => { - const isHealthInsured = getValueViaPath( - formValue, - 'accidentDetails.isHealthInsured', - ) as string - if (isHealthInsured === undefined) return true - return isHealthInsured === 'yes' -} diff --git a/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.spec.ts deleted file mode 100644 index c418a2b87656..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' -import { isHomeActivitiesAccident } from './isHomeActivitiesAccident' -describe('isHomeActivitiesAccident', () => { - const homeActivitiesAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, - } - - const someOtherAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, - } - - const emptyObject = {} - - it('should return true for home activity accidents', () => { - expect(isHomeActivitiesAccident(homeActivitiesAccident)).toEqual(true) - }) - it('should return false for accidents other than home activity accidents', () => { - expect(isHomeActivitiesAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isHomeActivitiesAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.ts b/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.ts deleted file mode 100644 index 4aa71f8c1902..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isHomeActivitiesAccident.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' - -export const isHomeActivitiesAccident = (formValue: FormValue) => { - const workAccidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - return workAccidentType === AccidentTypeEnum.HOMEACTIVITIES -} diff --git a/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.spec.ts deleted file mode 100644 index ac468eb6b2bb..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { StudiesAccidentTypeEnum } from '../types' -import { isInternshipStudiesAccident } from './isInternshipStudiesAccident' -describe('isInternshipStudiesAccident', () => { - const studiesAccidentType: FormValue = { - studiesAccident: { type: StudiesAccidentTypeEnum.INTERNSHIP }, - } - - const someOtherAccidentType: FormValue = { - studiesAccident: { type: StudiesAccidentTypeEnum.APPRENTICESHIP }, - } - - const emptyObject = {} - - it('should return true for studies accidents', () => { - expect(isInternshipStudiesAccident(studiesAccidentType)).toEqual(true) - }) - it('should return false for accidents other than studies', () => { - expect(isInternshipStudiesAccident(someOtherAccidentType)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isInternshipStudiesAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.ts b/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.ts deleted file mode 100644 index 07b7a859e87f..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isInternshipStudiesAccident.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { StudiesAccidentTypeEnum } from '../types' - -export const isInternshipStudiesAccident = (formValue: FormValue) => { - const studiesAccidentType = getValueViaPath( - formValue, - 'studiesAccident.type', - ) as StudiesAccidentTypeEnum - return studiesAccidentType === StudiesAccidentTypeEnum.INTERNSHIP -} diff --git a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts deleted file mode 100644 index 017a1e679a26..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { NO, YES } from './constants' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { isMachineRelatedAccident } from './isMachineRelatedAccident' -describe('isMachineRelatedAccident', () => { - const machineRelatedAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.GENERAL }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - workMachineRadio: YES, - } - - const nonMachineRelatedAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.GENERAL }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - workMachineRadio: NO, - } - - const someOtherAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, - } - - const emptyObject = {} - - it('should return true for machine related general work accidents', () => { - expect(isMachineRelatedAccident(machineRelatedAccident)).toEqual(true) - }) - it('should return false for non machine related general work accidents', () => { - expect(isMachineRelatedAccident(nonMachineRelatedAccident)).toEqual(false) - }) - it('should return false for workplace accidents other than general', () => { - expect(isMachineRelatedAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isMachineRelatedAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts b/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts deleted file mode 100644 index fd3cabc5347b..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isMachineRelatedAccident.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { YES } from './constants' -import { YesOrNo } from '../types' -import { isGeneralWorkplaceAccident } from './isGeneralWorkplaceAccident' - -export const isMachineRelatedAccident = (formValue: FormValue) => { - const workMachineAnswer = getValueViaPath( - formValue, - 'workMachineRadio', - ) as YesOrNo - return isGeneralWorkplaceAccident(formValue) && workMachineAnswer === YES -} diff --git a/libs/application/templates/accident-notification/src/utils/isOfWorkTypeAccident.ts b/libs/application/templates/accident-notification/src/utils/isOfWorkTypeAccident.ts deleted file mode 100644 index 7ecb4c31b781..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isOfWorkTypeAccident.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { AccidentNotificationAnswers } from '..' -import { WorkAccidentTypeEnum } from '../types' - -export const isOfWorkAccidentType = ( - answers: Partial, - type: WorkAccidentTypeEnum, -) => { - const workAccidentType = getValueViaPath( - answers, - 'workAccident.type', - ) as WorkAccidentTypeEnum - return workAccidentType === type -} diff --git a/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.spec.ts b/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.spec.ts deleted file mode 100644 index 1c5ade01d399..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' -import { isPowerOfAttorney } from './isPowerOfAttorney' - -describe('isPowerOfAttorney', () => { - const powerOfAttorneyReporter: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - } - - const juridicialPersonReporter: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, - }, - } - - const reportingForSelf: FormValue = { - whoIsTheNotificationFor: { answer: WhoIsTheNotificationForEnum.ME }, - } - - const emptyObject = {} - - it('should return true for power of attorney reporter', () => { - expect(isPowerOfAttorney(powerOfAttorneyReporter)).toEqual(true) - }) - - it('should return false for power of juridical person reporter', () => { - expect(isPowerOfAttorney(juridicialPersonReporter)).toEqual(false) - }) - - it('should return false for reporting for yourself', () => { - expect(isPowerOfAttorney(reportingForSelf)).toEqual(false) - }) - - it('should return false for empty object', () => { - expect(isPowerOfAttorney(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.ts b/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.ts deleted file mode 100644 index 46b4d177bc5e..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isPowerOfAttorney.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isPowerOfAttorney = (formValue: FormValue) => { - const reportingOnBehalfType = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return reportingOnBehalfType === WhoIsTheNotificationForEnum.POWEROFATTORNEY -} diff --git a/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.spec.ts deleted file mode 100644 index 22c0f49af199..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { isProfessionalAthleteAccident } from './isProfessionalAthleteAccident' - -describe('isProfessionalAthleteAccident', () => { - const professionalAthleteAccidentRadio: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.SPORTS }, - } - - const professionalAthleteAccidentSecondaryWorkQuestion: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherAccident: FormValue = { - workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, - } - - const emptyObject = {} - - it('should return true for professional athlete accidents', () => { - expect( - isProfessionalAthleteAccident(professionalAthleteAccidentRadio), - ).toEqual(true) - }) - - it('should return true for professional athlete accident when user picked work related and then sports related', () => { - expect( - isProfessionalAthleteAccident( - professionalAthleteAccidentSecondaryWorkQuestion, - ), - ).toEqual(true) - }) - - it('should return false for workplace accidents other than professional athlete', () => { - expect(isProfessionalAthleteAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isProfessionalAthleteAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.ts b/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.ts deleted file mode 100644 index e1b61896a622..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isProfessionalAthleteAccident.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { isWorkAccident } from './isWorkAccident' - -// Specific case check here since the accident can be a sports accident if he picks sports in the first question where -// he is asked what the circumstances of the accident were. But that user could also select work and then a sport related -// accident since the question can be missunderstood by the user so we are funneling both cases into the same flow -export const isProfessionalAthleteAccident = (formValue: FormValue) => { - const workAccidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - const workAccidentSecondaryType = getValueViaPath( - formValue, - 'workAccident.type', - ) as WorkAccidentTypeEnum - return ( - workAccidentType === AccidentTypeEnum.SPORTS || - (workAccidentSecondaryType === WorkAccidentTypeEnum.PROFESSIONALATHLETE && - isWorkAccident(formValue)) - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.spec.ts b/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.spec.ts deleted file mode 100644 index 98b80807ac4a..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { isReportingOnBehalfSelf } from './isReportingBehalfOfSelf' -import { WhoIsTheNotificationForEnum } from '../types' - -describe('isRepresentativeOfCompanyOrInstitute', () => { - const self: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.ME, - }, - } - - const notSelf: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - } - - it('should return true when someone is reporting on behalf of themselves', () => { - expect(isReportingOnBehalfSelf(self)).toEqual(true) - }) - it('should return false when someone is not reporting on behalf of themselves', () => { - expect(isReportingOnBehalfSelf(notSelf)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isReportingOnBehalfSelf({})).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.ts b/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.ts deleted file mode 100644 index 90b3784bc058..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingBehalfOfSelf.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isReportingOnBehalfSelf = (formValue: FormValue) => { - const whoIsTheNotificationFor = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.ME -} diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.spec.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.spec.ts deleted file mode 100644 index f778067b61c1..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.spec.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' -import { isReportingOnBehalfOfChild } from './isReportingOnBehalfOfChild' -describe('isReportingOnBehalfOfChild', () => { - const onBehalfOfChild: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.CHILDINCUSTODY, - }, - } - - const onBehalfOfSomeOtherPerson: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - } - - const emptyObject = {} - - it('should return true if reporting on behalf of child', () => { - expect(isReportingOnBehalfOfChild(onBehalfOfChild)).toEqual(true) - }) - it('should return false if reporting on behalf of some other person', () => { - expect(isReportingOnBehalfOfChild(onBehalfOfSomeOtherPerson)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isReportingOnBehalfOfChild(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.ts deleted file mode 100644 index d3193b011c11..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfChild.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isReportingOnBehalfOfChild = (formValue: FormValue) => { - const whoIsTheNotificationFor = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.CHILDINCUSTODY -} diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.spec.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.spec.ts deleted file mode 100644 index 50c105735b0d..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' -import { isReportingOnBehalfOfEmployee } from './isReportingOnBehalfOfEmployee' -describe('isReportingOnBehalfOfEmployee', () => { - const onBehalfOfEmployee: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, - }, - } - - const onBehalfOfSomeOtherPerson: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - } - - const emptyObject = {} - - it('should return true if reporting on behalf of employee', () => { - expect(isReportingOnBehalfOfEmployee(onBehalfOfEmployee)).toEqual(true) - }) - it('should return false if reporting on behalf of some other person', () => { - expect(isReportingOnBehalfOfEmployee(onBehalfOfSomeOtherPerson)).toEqual( - false, - ) - }) - it('should return false for empty object', () => { - expect(isReportingOnBehalfOfEmployee(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.ts deleted file mode 100644 index d00c7ed47f7f..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfEmployee.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isReportingOnBehalfOfEmployee = (formValue: FormValue) => { - const whoIsTheNotificationFor = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.JURIDICALPERSON -} diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.spec.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.spec.ts deleted file mode 100644 index efce07880e51..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.spec.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' -import { isReportingOnBehalfOfInjured } from './isReportingOnBehalfOfInjured' - -describe('isReportingOnBehalfOfInjured', () => { - const powerOfAttorneyReporter: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - } - - const juridicialPersonReporter: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, - }, - } - - const reportingForSelf: FormValue = { - whoIsTheNotificationFor: { answer: WhoIsTheNotificationForEnum.ME }, - } - - const emptyObject = {} - - it('should return true for power of attorney reporter', () => { - expect(isReportingOnBehalfOfInjured(powerOfAttorneyReporter)).toEqual(true) - }) - - it('should return true for power of juridical person reporter', () => { - expect(isReportingOnBehalfOfInjured(juridicialPersonReporter)).toEqual(true) - }) - - it('should return false for reporting for yourself', () => { - expect(isReportingOnBehalfOfInjured(reportingForSelf)).toEqual(false) - }) - - it('should return false for empty object', () => { - expect(isReportingOnBehalfOfInjured(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.ts b/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.ts deleted file mode 100644 index d0ac674762ae..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isReportingOnBehalfOfInjured.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isReportingOnBehalfOfInjured = (formValue: FormValue) => { - const whoIsTheNotificationFor = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - return ( - whoIsTheNotificationFor === WhoIsTheNotificationForEnum.JURIDICALPERSON || - whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts deleted file mode 100644 index aeff9475efef..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.spec.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { WhoIsTheNotificationForEnum } from '../types' - -import { - isInjuredAndRepresentativeOfCompanyOrInstitute, - isRepresentativeOfCompanyOrInstitute, -} from './isRepresentativeOfCompanyOrInstitute' -import { NO, YES } from './constants' - -const emptyObject = {} - -describe('isRepresentativeOfCompanyOrInstitute', () => { - const representative: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, - }, - } - - const notRepresentative: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.ME, - }, - } - - const emptyRepresentative: FormValue = { - whoIsTheNotificationFor: {}, - } - - it('should return true for someone that is a representative of the company or institue', () => { - expect(isRepresentativeOfCompanyOrInstitute(representative)).toEqual(true) - }) - it('should return false for someone that isnt a representative of the company or institue', () => { - expect(isRepresentativeOfCompanyOrInstitute(notRepresentative)).toEqual( - false, - ) - }) - it('should return false for empty object', () => { - expect(isRepresentativeOfCompanyOrInstitute(emptyObject)).toEqual(false) - }) - it('should return false for empty whoIsTheNotificationFor', () => { - expect(isRepresentativeOfCompanyOrInstitute(emptyRepresentative)).toEqual( - false, - ) - }) -}) - -describe('isInjuredAndRepresentativeOfCompanyOrInstitute', () => { - const representative: FormValue = { - isRepresentativeOfCompanyOrInstitute: YES, - } - - const notRepresentative: FormValue = { - isRepresentativeOfCompanyOrInstitute: NO, - } - - it('should return true for someone that is a representative of the company or institute', () => { - expect( - isInjuredAndRepresentativeOfCompanyOrInstitute(representative), - ).toEqual(true) - }) - - it('should return false for someone that isnt a representative of the company or institute', () => { - expect( - isInjuredAndRepresentativeOfCompanyOrInstitute(notRepresentative), - ).toEqual(false) - }) - - it('should return false for empty object', () => { - expect(isInjuredAndRepresentativeOfCompanyOrInstitute(emptyObject)).toEqual( - false, - ) - }) - - it('should return false for garbage string', () => { - expect( - isInjuredAndRepresentativeOfCompanyOrInstitute({ - isRepresentativeOfCompanyOrInstitute: 'garbage', - }), - ).toEqual(false) - }) - - it('should return false for object with non string value', () => { - expect( - isInjuredAndRepresentativeOfCompanyOrInstitute({ - isRepresentativeOfCompanyOrInstitute: true, - }), - ).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts b/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts deleted file mode 100644 index f8c98b7b61f5..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isRepresentativeOfCompanyOrInstitute.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { YES } from './constants' -import { WhoIsTheNotificationForEnum } from '../types' - -export const isRepresentativeOfCompanyOrInstitute = (formValue: FormValue) => { - return ( - getValueViaPath(formValue, 'whoIsTheNotificationFor.answer') === - WhoIsTheNotificationForEnum.JURIDICALPERSON - ) -} - -export const isInjuredAndRepresentativeOfCompanyOrInstitute = ( - formValue: FormValue, -) => { - return formValue.isRepresentativeOfCompanyOrInstitute?.toString() === YES -} diff --git a/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.spec.ts deleted file mode 100644 index 1cdf033a88e6..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' -import { isRescueWorkAccident } from './isRescueWorkAccident' -describe('isRescueWorkAccident', () => { - const rescueWorkAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, - } - - const someOtherAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, - } - - const emptyObject = {} - - it('should return true for rescue work accidents', () => { - expect(isRescueWorkAccident(rescueWorkAccident)).toEqual(true) - }) - it('should return false for accidents other than rescue work', () => { - expect(isRescueWorkAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isRescueWorkAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.ts b/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.ts deleted file mode 100644 index 2fd410280af8..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isRescueWorkAccident.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' - -export const isRescueWorkAccident = (formValue: FormValue) => { - const accidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - return accidentType === AccidentTypeEnum.RESCUEWORK -} diff --git a/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.spec.ts b/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.spec.ts deleted file mode 100644 index a095aa9370ef..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import exp from 'constants' -import { isSportAccidentAndEmployee } from './isSportAccidentAndEmployee' -import { accidentType } from '../lib/messages' - -describe('isSportAccidentAndEmployee', () => { - const sportAccidentRadio: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.SPORTS }, - onPayRoll: { answer: 'yes' }, - } - - const someOtherAccident: FormValue = { - workAccident: { type: AccidentTypeEnum.HOMEACTIVITIES }, - onPayRoll: { answer: 'yes' }, - } - - const notOnPayroll: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.SPORTS }, - onPayRoll: { answer: 'no' }, - } - - it('should return true for sport accidents where the person is also an employee of the sports club', () => { - expect(isSportAccidentAndEmployee(sportAccidentRadio)).toEqual(true) - }) - - it('should return false for other accidents', () => { - expect(isSportAccidentAndEmployee(someOtherAccident)).toEqual(false) - }) - - it('should return false if the person is not on payroll', () => { - expect(isSportAccidentAndEmployee(notOnPayroll)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.ts b/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.ts deleted file mode 100644 index e214ce3c414f..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isSportAccidentAndEmployee.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Answer, FormValue } from '@island.is/application/types' -import { AccidentTypeEnum, YesOrNo } from '../types' -import { getValueViaPath } from '@island.is/application/core' - -// When a person is hurt in a sports accident and is an employee of the sport, the accident -// is considered a work accident. This function checks if both conditions are met. -export const isSportAccidentAndEmployee = (formValue: FormValue): boolean => { - const workAccidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - const onPayRoll = getValueViaPath(formValue, 'onPayRoll.answer') as YesOrNo - - if (workAccidentType === AccidentTypeEnum.SPORTS && onPayRoll === 'yes') { - return true - } - - return false -} diff --git a/libs/application/templates/accident-notification/src/utils/isStudiesAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isStudiesAccident.spec.ts deleted file mode 100644 index b4e40c6e8e4e..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isStudiesAccident.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' -import { isStudiesAccident } from './isStudiesAccident' -describe('isStudiesAccident', () => { - const studiesAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.STUDIES }, - } - - const someOtherAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, - } - - const emptyObject = {} - - it('should return true for studies accidents', () => { - expect(isStudiesAccident(studiesAccident)).toEqual(true) - }) - it('should return false for accidents other than studies', () => { - expect(isStudiesAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isStudiesAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isStudiesAccident.ts b/libs/application/templates/accident-notification/src/utils/isStudiesAccident.ts deleted file mode 100644 index 9de0fa5042f3..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isStudiesAccident.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' - -export const isStudiesAccident = (formValue: FormValue) => { - const accidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - return accidentType === AccidentTypeEnum.STUDIES -} diff --git a/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.spec.ts b/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.spec.ts deleted file mode 100644 index 707eeca6673b..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.spec.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { isUniqueAssignee } from './isUniqueAssignee' -describe('isUniqueAssignee', () => { - // Gervimenn nationalIds: - const applicant = '0101051450' - const assigneeSameAsApplicant = '0101051450' - const uniqueAssignee = '0102491479' - const isAssignee = true - - const applicationSameAsApplicant: FormValue = { - applicant: { - nationalId: applicant, - }, - representative: { - nationalId: assigneeSameAsApplicant, - }, - } - - const applicationUniqueAssignee: FormValue = { - applicant: { - nationalId: applicant, - }, - representative: { - nationalId: uniqueAssignee, - }, - } - - it('should return false for assignee that is the same as applicant', () => { - expect(isUniqueAssignee(applicationSameAsApplicant, isAssignee)).toEqual( - false, - ) - }) - it('should return true for assignee that is unique', () => { - expect(isUniqueAssignee(applicationUniqueAssignee, isAssignee)).toEqual( - true, - ) - }) - it('should return false for not being assignee', () => { - expect(isUniqueAssignee(applicationUniqueAssignee, !isAssignee)).toEqual( - false, - ) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.ts b/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.ts deleted file mode 100644 index b1ba7fe86444..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isUniqueAssignee.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' - -export const isUniqueAssignee = ( - formValue: FormValue, - isAssignee: boolean, -): boolean => { - const applicant = getValueViaPath(formValue, 'applicant.nationalId') - const assignee = getValueViaPath(formValue, 'representative.nationalId') - const isSamePerson = applicant === assignee - - return !isSamePerson && isAssignee -} diff --git a/libs/application/templates/accident-notification/src/utils/isUploadNow.spec.ts b/libs/application/templates/accident-notification/src/utils/isUploadNow.spec.ts deleted file mode 100644 index f080cf0092e5..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isUploadNow.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { - PowerOfAttorneyUploadEnum, - WhoIsTheNotificationForEnum, -} from '../types' -import { isUploadNow } from './isUploadNow' - -describe('isUploadNow', () => { - const powerOfAttorneyReporterWithUploadNow: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - powerOfAttorney: { - type: PowerOfAttorneyUploadEnum.UPLOADNOW, - }, - } - - const powerOfAttorneyReporterWithUploadLater: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, - }, - powerOfAttorney: { - type: PowerOfAttorneyUploadEnum.UPLOADLATER, - }, - } - - const reportingForSelf: FormValue = { - whoIsTheNotificationFor: { - answer: WhoIsTheNotificationForEnum.ME, - }, - } - - const emptyObject = {} - - it('should return true for power of attorney reporter with upload now', () => { - expect(isUploadNow(powerOfAttorneyReporterWithUploadNow)).toEqual(true) - }) - - it('should return false for power of attorney reporter with upload later', () => { - expect(isUploadNow(powerOfAttorneyReporterWithUploadLater)).toEqual(false) - }) - - it('should return false for reporting for yourself', () => { - expect(isUploadNow(reportingForSelf)).toEqual(false) - }) - - it('should return false for empty object', () => { - expect(isUploadNow(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isUploadNow.ts b/libs/application/templates/accident-notification/src/utils/isUploadNow.ts deleted file mode 100644 index 94d87d93940a..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isUploadNow.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { - PowerOfAttorneyUploadEnum, - WhoIsTheNotificationForEnum, -} from '../types' - -export const isUploadNow = (formValue: FormValue) => { - const whoIsTheNotificationFor = getValueViaPath( - formValue, - 'whoIsTheNotificationFor.answer', - ) as WhoIsTheNotificationForEnum - const powerOfAttorneyType = getValueViaPath( - formValue, - 'powerOfAttorney.type', - ) as PowerOfAttorneyUploadEnum - return ( - whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY && - powerOfAttorneyType === PowerOfAttorneyUploadEnum.UPLOADNOW - ) -} diff --git a/libs/application/templates/accident-notification/src/utils/isWorkAccident.spec.ts b/libs/application/templates/accident-notification/src/utils/isWorkAccident.spec.ts deleted file mode 100644 index a3aaae308e53..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isWorkAccident.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' -import { isWorkAccident } from './isWorkAccident' -describe('isWorkAccident', () => { - const workAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.WORK }, - } - - const someOtherAccident: FormValue = { - accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, - } - - const emptyObject = {} - - it('should return true for work accidents', () => { - expect(isWorkAccident(workAccident)).toEqual(true) - }) - it('should return false for accidents other than work', () => { - expect(isWorkAccident(someOtherAccident)).toEqual(false) - }) - it('should return false for empty object', () => { - expect(isWorkAccident(emptyObject)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/isWorkAccident.ts b/libs/application/templates/accident-notification/src/utils/isWorkAccident.ts deleted file mode 100644 index d88e055641be..000000000000 --- a/libs/application/templates/accident-notification/src/utils/isWorkAccident.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { getValueViaPath } from '@island.is/application/core' -import { FormValue } from '@island.is/application/types' -import { AccidentTypeEnum } from '../types' - -export const isWorkAccident = (formValue: FormValue) => { - const accidentType = getValueViaPath( - formValue, - 'accidentType.radioButton', - ) as AccidentTypeEnum - return accidentType === AccidentTypeEnum.WORK -} diff --git a/libs/application/templates/accident-notification/src/utils/miscUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/miscUtils.spec.ts new file mode 100644 index 000000000000..a415c9b0cc91 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/miscUtils.spec.ts @@ -0,0 +1,313 @@ +import { + formatPhonenumber, + hasReceivedConfirmation, + hideLocationAndPurpose, + isHealthInsured, + isInjuredAndRepresentativeOfCompanyOrInstitute, + isPowerOfAttorney, + isRepresentativeOfCompanyOrInstitute, + isUniqueAssignee, + shouldRequestReview, +} from './miscUtils' +import { FormValue, NO, YES } from '@island.is/application/types' +import { + AccidentTypeEnum, + GeneralWorkplaceAccidentLocationEnum, + StudiesAccidentLocationEnum, + WhoIsTheNotificationForEnum, + WorkAccidentTypeEnum, +} from '../types' +import { AccidentNotificationAnswers } from '..' + +describe('formatPhonenumber', () => { + it.each([ + { input: '1234567', expected: '123-4567' }, + { input: '1234567891011', expected: '123-4567891011' }, + { input: 'ABCDEF@!()', expected: 'ABC-DEF@!()' }, + { input: '123', expected: '123' }, + ])('should format phone number', ({ input, expected }) => { + const result = formatPhonenumber(input) + expect(result).toBe(expected) + }) +}) + +describe('hasReceivedConfirmation', () => { + const confirmedJuridicial: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, + }, + accidentStatus: { + receivedConfirmations: { + InjuredOrRepresentativeParty: true, + }, + }, + } + + const confirmedMe: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.ME, + }, + accidentStatus: { + receivedConfirmations: { + CompanyParty: true, + }, + }, + } + + const notConfirmed: FormValue = { + accidentStatus: { + receivedConfirmations: false, + }, + } + + it.each([ + { for: 'juridical person', input: confirmedJuridicial, expected: true }, + { for: 'company', input: confirmedMe, expected: true }, + { for: 'not confirmed', input: notConfirmed, expected: false }, + ])( + 'should return $expected when confirmation is $for', + ({ input, expected }) => { + expect(hasReceivedConfirmation(input)).toEqual(expected) + }, + ) +}) + +describe('hideLocationAndPurpose', () => { + const accidentLocationAtWorkplace: FormValue = { + accidentLocation: { + answer: GeneralWorkplaceAccidentLocationEnum.ATTHEWORKPLACE, + }, + } + + const accidentLocationAtSchoole: FormValue = { + accidentLocation: { answer: StudiesAccidentLocationEnum.ATTHESCHOOL }, + } + + const someOtherLocation: FormValue = { + accidentLocation: { answer: GeneralWorkplaceAccidentLocationEnum.OTHER }, + } + + const emptyObject = {} + + it('should return true for accident location at workplace', () => { + expect(hideLocationAndPurpose(accidentLocationAtWorkplace)).toEqual(true) + }) + it('should return true for accident location at school', () => { + expect(hideLocationAndPurpose(accidentLocationAtSchoole)).toEqual(true) + }) + it('should return false for accident location elsewhere', () => { + expect(hideLocationAndPurpose(someOtherLocation)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(hideLocationAndPurpose(emptyObject)).toEqual(false) + }) +}) + +describe('isHealthInsured', () => { + const healthInsured = { + accidentDetails: { + isHealthInsured: 'yes', + }, + } + + const notHealthInsured = { + accidentDetails: { + isHealthInsured: 'no', + }, + } + + it('should return true when health insured is yes', () => { + expect(isHealthInsured(healthInsured)).toEqual(true) + }) + + it('should return false when health insured is no', () => { + expect(isHealthInsured(notHealthInsured)).toEqual(false) + }) + + it('should return true when health insured is undefined', () => { + expect(isHealthInsured({})).toEqual(true) + }) +}) + +describe('isPowerOfAttorney', () => { + const powerOfAttorneyReporter: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + } + + const juridicialPersonReporter: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, + }, + } + + const reportingForSelf: FormValue = { + whoIsTheNotificationFor: { answer: WhoIsTheNotificationForEnum.ME }, + } + + const emptyObject = {} + + it('should return true for power of attorney reporter', () => { + expect(isPowerOfAttorney(powerOfAttorneyReporter)).toEqual(true) + }) + + it('should return false for power of juridical person reporter', () => { + expect(isPowerOfAttorney(juridicialPersonReporter)).toEqual(false) + }) + + it('should return false for reporting for yourself', () => { + expect(isPowerOfAttorney(reportingForSelf)).toEqual(false) + }) + + it('should return false for empty object', () => { + expect(isPowerOfAttorney(emptyObject)).toEqual(false) + }) +}) + +describe('isRepresentativeOfCompanyOrInstitute', () => { + const representative: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, + }, + } + + const notRepresentative: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.ME, + }, + } + + const emptyRepresentative: FormValue = { + whoIsTheNotificationFor: {}, + } + + it('should return true for someone that is a representative of the company or institue', () => { + expect(isRepresentativeOfCompanyOrInstitute(representative)).toEqual(true) + }) + it('should return false for someone that isnt a representative of the company or institue', () => { + expect(isRepresentativeOfCompanyOrInstitute(notRepresentative)).toEqual( + false, + ) + }) + it('should return false for empty object', () => { + expect(isRepresentativeOfCompanyOrInstitute(emptyObject)).toEqual(false) + }) + it('should return false for empty whoIsTheNotificationFor', () => { + expect(isRepresentativeOfCompanyOrInstitute(emptyRepresentative)).toEqual( + false, + ) + }) +}) + +const emptyObject = {} + +describe('isInjuredAndRepresentativeOfCompanyOrInstitute', () => { + const representative: FormValue = { + isRepresentativeOfCompanyOrInstitute: YES, + } + + const notRepresentative: FormValue = { + isRepresentativeOfCompanyOrInstitute: NO, + } + + it('should return true for someone that is a representative of the company or institute', () => { + expect( + isInjuredAndRepresentativeOfCompanyOrInstitute(representative), + ).toEqual(true) + }) + + it('should return false for someone that isnt a representative of the company or institute', () => { + expect( + isInjuredAndRepresentativeOfCompanyOrInstitute(notRepresentative), + ).toEqual(false) + }) + + it('should return false for empty object', () => { + expect(isInjuredAndRepresentativeOfCompanyOrInstitute(emptyObject)).toEqual( + false, + ) + }) + + it('should return false for garbage string', () => { + expect( + isInjuredAndRepresentativeOfCompanyOrInstitute({ + isRepresentativeOfCompanyOrInstitute: 'garbage', + }), + ).toEqual(false) + }) + + it('should return false for object with non string value', () => { + expect( + isInjuredAndRepresentativeOfCompanyOrInstitute({ + isRepresentativeOfCompanyOrInstitute: true, + }), + ).toEqual(false) + }) +}) + +describe('isUniqueAssignee', () => { + // Gervimenn nationalIds: + const applicant = '0101051450' + const assigneeSameAsApplicant = '0101051450' + const uniqueAssignee = '0102491479' + const isAssignee = true + + const applicationSameAsApplicant: FormValue = { + applicant: { + nationalId: applicant, + }, + representative: { + nationalId: assigneeSameAsApplicant, + }, + } + + const applicationUniqueAssignee: FormValue = { + applicant: { + nationalId: applicant, + }, + representative: { + nationalId: uniqueAssignee, + }, + } + + it('should return false for assignee that is the same as applicant', () => { + expect(isUniqueAssignee(applicationSameAsApplicant, isAssignee)).toEqual( + false, + ) + }) + it('should return true for assignee that is unique', () => { + expect(isUniqueAssignee(applicationUniqueAssignee, isAssignee)).toEqual( + true, + ) + }) + it('should return false for not being assignee', () => { + expect(isUniqueAssignee(applicationUniqueAssignee, !isAssignee)).toEqual( + false, + ) + }) +}) + +describe('shouldRequestReview', () => { + const agricultureAccident: Partial = { + workAccident: { type: WorkAccidentTypeEnum.AGRICULTURE }, + } + + const accidentAtHome: Partial = { + accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, + } + + const normalWorkAccident: Partial = { + workAccident: { type: WorkAccidentTypeEnum.GENERAL }, + } + + it('should return false for work accidents', () => { + expect(shouldRequestReview(agricultureAccident)).toEqual(false) + }) + it('should return true for general work accident', () => { + expect(shouldRequestReview(normalWorkAccident)).toEqual(true) + }) + it('should return false for home accident', () => { + expect(shouldRequestReview(accidentAtHome)).toEqual(false) + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/miscUtils.ts b/libs/application/templates/accident-notification/src/utils/miscUtils.ts new file mode 100644 index 000000000000..5ae53a9533cc --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/miscUtils.ts @@ -0,0 +1,137 @@ +import { getValueViaPath } from '@island.is/application/core' +import { FormValue, YES } from '@island.is/application/types' +import { isReportingOnBehalfOfEmployee as isReportingOnBehalfOfEmployeeOrginal } from './reportingUtils' +import { + GeneralWorkplaceAccidentLocationEnum, + ProfessionalAthleteAccidentLocationEnum, + StudiesAccidentLocationEnum, + WhoIsTheNotificationForEnum, + WorkAccidentTypeEnum, + YesOrNo, +} from '../types' +import { + getInjuredPersonInformation as getInjuredPersonInformationOrginal, + isHomeActivitiesAccident, +} from './accidentUtils' +import { AccidentNotificationAnswers } from '..' +import { + getWorkplaceData as getWorkplaceDataOrginal, + isOfWorkAccidentType, +} from './occupationUtils' + +export const formatPhonenumber = (value: string) => { + const splitAt = (index: number) => (x: string) => + [x.slice(0, index), x.slice(index)] + if (value.length > 3) return splitAt(3)(value).join('-') + return value +} + +export const hasReceivedConfirmation = (answers: FormValue) => { + // The fetched value is actually typed as AccidentNotificationConfirmation, but importing that type breaks when codegen is run after cleanup + const accidentConfirmations = getValueViaPath( + answers, + 'accidentStatus.receivedConfirmations', + ) as { + InjuredOrRepresentativeParty: boolean | undefined + CompanyParty: boolean | undefined + } + + // if juridical person then the injured or the power of attorney holder has to confirm + if (isReportingOnBehalfOfEmployee(answers)) { + return !!accidentConfirmations.InjuredOrRepresentativeParty + } + + // as there isn't an juridical person reporting, this must be someone reporting for the injured + // or the injured himself and that requires the companies confirmation + return !!accidentConfirmations.CompanyParty +} + +// Location and purpose of accident only relevant in work and studies and never in home +// activities +export const hideLocationAndPurpose = (formValue: FormValue) => { + const answer = getValueViaPath(formValue, 'accidentLocation.answer') as + | GeneralWorkplaceAccidentLocationEnum + | StudiesAccidentLocationEnum + | ProfessionalAthleteAccidentLocationEnum + + if (isHomeActivitiesAccident(formValue)) { + return true + } + return ( + answer === GeneralWorkplaceAccidentLocationEnum.ATTHEWORKPLACE || + answer === StudiesAccidentLocationEnum.ATTHESCHOOL || + answer === ProfessionalAthleteAccidentLocationEnum.SPORTCLUBSFACILITES + ) +} + +export const isHealthInsured = (formValue: FormValue) => { + const isHealthInsured = getValueViaPath( + formValue, + 'accidentDetails.isHealthInsured', + ) + if (isHealthInsured === undefined) return true + return isHealthInsured === 'yes' +} + +export const isPowerOfAttorney = (formValue: FormValue) => { + const reportingOnBehalfType = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + return reportingOnBehalfType === WhoIsTheNotificationForEnum.POWEROFATTORNEY +} + +export const isRepresentativeOfCompanyOrInstitute = (formValue: FormValue) => { + return ( + getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) === WhoIsTheNotificationForEnum.JURIDICALPERSON + ) +} + +export const isInjuredAndRepresentativeOfCompanyOrInstitute = ( + formValue: FormValue, +) => { + return formValue.isRepresentativeOfCompanyOrInstitute?.toString() === YES +} + +export const isUniqueAssignee = ( + formValue: FormValue, + isAssignee: boolean, +): boolean => { + const applicant = getValueViaPath(formValue, 'applicant.nationalId') + const assignee = getValueViaPath( + formValue, + 'representative.nationalId', + ) + const isSamePerson = applicant === assignee + + return !isSamePerson && isAssignee +} + +export const shouldRequestReview = ( + answers: Partial, +): boolean => { + const ishome = isHomeActivitiesAccident(answers) + const isAgriculture = isOfWorkAccidentType( + answers, + WorkAccidentTypeEnum.AGRICULTURE, + ) + + const isEitherHomeOrAgriculture = ishome || isAgriculture + + return !isEitherHomeOrAgriculture +} + +export const isReportingOnBehalfOfEmployee = (answers: FormValue) => { + return isReportingOnBehalfOfEmployeeOrginal(answers) +} + +export const getWorkplaceData = (answers: FormValue) => { + return getWorkplaceDataOrginal(answers) +} + +export const getInjuredPersonInformation = (answers: FormValue) => { + return getInjuredPersonInformationOrginal(answers) +} diff --git a/libs/application/templates/accident-notification/src/utils/occupationUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/occupationUtils.spec.ts new file mode 100644 index 000000000000..4a76aafb7521 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/occupationUtils.spec.ts @@ -0,0 +1,312 @@ +import { FormValue, NO, YES } from '@island.is/application/types' +import { + AccidentTypeEnum, + FishermanWorkplaceAccidentLocationEnum, + StudiesAccidentTypeEnum, + WorkAccidentTypeEnum, +} from '../types' +import { + getWorkplaceData, + isAboardShip, + isAgricultureAccident, + isFishermanAccident, + isGeneralWorkplaceAccident, + isInternshipStudiesAccident, + isMachineRelatedAccident, + isProfessionalAthleteAccident, + isSportAccidentAndEmployee, +} from './occupationUtils' + +describe('isAboardShip', () => { + const onTheShipLocation: FormValue = { + accidentLocation: { + answer: FishermanWorkplaceAccidentLocationEnum.ONTHESHIP, + }, + workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherLocation: FormValue = { + accidentLocation: { answer: FishermanWorkplaceAccidentLocationEnum.OTHER }, + workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const emptyObject = {} + + it('should return true for fisherman work accident that happens on a ship', () => { + expect(isAboardShip(onTheShipLocation)).toEqual(true) + }) + it('should return false for fisherman work accident that happens else where', () => { + expect(isAboardShip(someOtherLocation)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isAboardShip(emptyObject)).toEqual(false) + }) +}) + +describe('getWorkplaceData', () => { + const generalWorkplaceAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.GENERAL }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + companyInfo: {}, + } + + const professionalAthleteAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.SPORTS }, + companyInfo: { onPayRoll: { answer: YES } }, + } + + const rescueWorkAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.RESCUEWORK }, + } + + const studiesAccident: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.STUDIES }, + } + + const fishermanAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const emptyObject = {} + + it('should return general work type data for general work accidents', () => { + expect(getWorkplaceData(generalWorkplaceAccident)?.type).toEqual( + AccidentTypeEnum.WORK, + ) + }) + + it('should return sports type data for professional athlete accidents', () => { + expect(getWorkplaceData(professionalAthleteAccident)?.type).toEqual( + AccidentTypeEnum.SPORTS, + ) + }) + + it('should return employee information for professional athlete accidents', () => { + expect( + getWorkplaceData(professionalAthleteAccident)?.companyInfo.onPayRoll + ?.answer, + ).toBe(YES) + }) + + it('should not return employee information for general workplace accident', () => { + expect( + getWorkplaceData(generalWorkplaceAccident)?.companyInfo.onPayRoll, + ).toBe(undefined) + }) + + it('should return rescue work type data for rescue work accidents', () => { + expect(getWorkplaceData(rescueWorkAccident)?.type).toEqual( + AccidentTypeEnum.RESCUEWORK, + ) + }) + + it('should return studies type data for student accidents', () => { + expect(getWorkplaceData(studiesAccident)?.type).toEqual( + AccidentTypeEnum.STUDIES, + ) + }) + + it('should return fisherman type data for fisherman accidents', () => { + expect(getWorkplaceData(fishermanAccident)?.type).toEqual( + WorkAccidentTypeEnum.FISHERMAN, + ) + }) + + it('should return undefined for empty object', () => { + expect(getWorkplaceData(emptyObject)?.type).toEqual(undefined) + }) +}) + +describe('isInternshipStudiesAccident', () => { + const studiesAccidentType: FormValue = { + studiesAccident: { type: StudiesAccidentTypeEnum.INTERNSHIP }, + } + + const someOtherAccidentType: FormValue = { + studiesAccident: { type: StudiesAccidentTypeEnum.APPRENTICESHIP }, + } + + const emptyObject = {} + + it('should return true for studies accidents', () => { + expect(isInternshipStudiesAccident(studiesAccidentType)).toEqual(true) + }) + it('should return false for accidents other than studies', () => { + expect(isInternshipStudiesAccident(someOtherAccidentType)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isInternshipStudiesAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isMachineRelatedAccident', () => { + const machineRelatedAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.GENERAL }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + workMachineRadio: YES, + } + + const nonMachineRelatedAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.GENERAL }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + workMachineRadio: NO, + } + + const someOtherAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, + } + + const emptyObject = {} + + it('should return true for machine related general work accidents', () => { + expect(isMachineRelatedAccident(machineRelatedAccident)).toEqual(true) + }) + it('should return false for non machine related general work accidents', () => { + expect(isMachineRelatedAccident(nonMachineRelatedAccident)).toEqual(false) + }) + it('should return false for workplace accidents other than general', () => { + expect(isMachineRelatedAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isMachineRelatedAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isSportAccidentAndEmployee', () => { + const sportAccidentRadio: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.SPORTS }, + onPayRoll: { answer: 'yes' }, + } + + const someOtherAccident: FormValue = { + workAccident: { type: AccidentTypeEnum.HOMEACTIVITIES }, + onPayRoll: { answer: 'yes' }, + } + + const notOnPayroll: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.SPORTS }, + onPayRoll: { answer: 'no' }, + } + + it('should return true for sport accidents where the person is also an employee of the sports club', () => { + expect(isSportAccidentAndEmployee(sportAccidentRadio)).toEqual(true) + }) + + it('should return false for other accidents', () => { + expect(isSportAccidentAndEmployee(someOtherAccident)).toEqual(false) + }) + + it('should return false if the person is not on payroll', () => { + expect(isSportAccidentAndEmployee(notOnPayroll)).toEqual(false) + }) +}) + +describe('isFishermanAccident', () => { + const fishermanAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, + } + + const emptyObject = {} + + it('should return true for fisherman accidents', () => { + expect(isFishermanAccident(fishermanAccident)).toEqual(true) + }) + it('should return false for workplace accidents other than fisherman', () => { + expect(isFishermanAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isFishermanAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isAgricultureAccident', () => { + const agricultureAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.AGRICULTURE }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, + } + + const emptyObject = {} + + it('should return true for agriculture accidents', () => { + expect(isAgricultureAccident(agricultureAccident)).toEqual(true) + }) + it('should return false for workplace accidents other than agriculture', () => { + expect(isAgricultureAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isAgricultureAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isProfessionalAthleteAccident', () => { + const professionalAthleteAccidentRadio: FormValue = { + accidentType: { radioButton: AccidentTypeEnum.SPORTS }, + } + + const professionalAthleteAccidentSecondaryWorkQuestion: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.FISHERMAN }, + } + + const emptyObject = {} + + it('should return true for professional athlete accidents', () => { + expect( + isProfessionalAthleteAccident(professionalAthleteAccidentRadio), + ).toEqual(true) + }) + + it('should return true for professional athlete accident when user picked work related and then sports related', () => { + expect( + isProfessionalAthleteAccident( + professionalAthleteAccidentSecondaryWorkQuestion, + ), + ).toEqual(true) + }) + + it('should return false for workplace accidents other than professional athlete', () => { + expect(isProfessionalAthleteAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isProfessionalAthleteAccident(emptyObject)).toEqual(false) + }) +}) + +describe('isGeneralWorkplaceAccident', () => { + const generalWorkplaceAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.GENERAL }, + accidentType: { radioButton: AccidentTypeEnum.WORK }, + } + + const someOtherAccident: FormValue = { + workAccident: { type: WorkAccidentTypeEnum.PROFESSIONALATHLETE }, + } + + const emptyObject = {} + + it('should return true for general workplace accidents', () => { + expect(isGeneralWorkplaceAccident(generalWorkplaceAccident)).toEqual(true) + }) + it('should return false for workplace accidents other than general', () => { + expect(isGeneralWorkplaceAccident(someOtherAccident)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isGeneralWorkplaceAccident(emptyObject)).toEqual(false) + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/occupationUtils.ts b/libs/application/templates/accident-notification/src/utils/occupationUtils.ts new file mode 100644 index 000000000000..79351222b877 --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/occupationUtils.ts @@ -0,0 +1,203 @@ +import { getValueViaPath, YES } from '@island.is/application/core' +import { FormValue } from '@island.is/application/types' +import { + AccidentTypeEnum, + CompanyInfo, + FishermanWorkplaceAccidentLocationEnum, + RepresentativeInfo, + StudiesAccidentTypeEnum, + WorkAccidentTypeEnum, + WorkplaceData, + YesOrNo, +} from '../types' +import { + isHomeActivitiesAccident, + isRescueWorkAccident, + isStudiesAccident, + isWorkAccident, +} from './accidentUtils' +import { + companyInfo, + fishingCompanyInfo, + representativeInfo, + rescueSquadInfo, + schoolInfo, + sportsClubInfo, +} from '../lib/messages' +import { AccidentNotificationAnswers } from '..' + +// As this is a third question the user is asked there is a case where he could go back +// and select home activities and keep the workaccident type or go back and change where the +// accident happened. +// Therefore we need to check ifFishermanAccident function again +export const isAboardShip = (formValue: FormValue) => { + const fishermanWorkplaceAccidentLocationAnswer = + getValueViaPath( + formValue, + 'accidentLocation.answer', + ) + return ( + isFishermanAccident(formValue) && + fishermanWorkplaceAccidentLocationAnswer === + FishermanWorkplaceAccidentLocationEnum.ONTHESHIP + ) +} + +export const getWorkplaceData = ( + answers: FormValue, +): WorkplaceData | undefined => { + if (isHomeActivitiesAccident(answers)) { + return + } + + const workplaceData = { + companyInfo: getValueViaPath(answers, 'companyInfo'), + representitive: getValueViaPath( + answers, + 'representative', + ), + representitiveMsg: representativeInfo, + } as WorkplaceData + + if (isGeneralWorkplaceAccident(answers)) + return { + ...workplaceData, + companyInfoMsg: companyInfo, + type: AccidentTypeEnum.WORK, + screenId: 'companyInfo', + } + + if (isStudiesAccident(answers)) + return { + ...workplaceData, + companyInfoMsg: schoolInfo, + type: AccidentTypeEnum.STUDIES, + screenId: 'schoolInfo', + } + + if (isFishermanAccident(answers)) + return { + ...workplaceData, + companyInfoMsg: fishingCompanyInfo, + type: WorkAccidentTypeEnum.FISHERMAN, + screenId: 'fishingCompanyInfo', + } + + if (isProfessionalAthleteAccident(answers)) + return { + ...workplaceData, + onPayRoll: getValueViaPath(answers, 'onPayRoll.answer'), + companyInfoMsg: sportsClubInfo, + type: AccidentTypeEnum.SPORTS, + screenId: 'sportsClubInfo', + } + + if (isRescueWorkAccident(answers)) + return { + ...workplaceData, + companyInfoMsg: rescueSquadInfo, + type: AccidentTypeEnum.RESCUEWORK, + screenId: 'rescueSquad', + } +} + +export const isInternshipStudiesAccident = (formValue: FormValue) => { + const studiesAccidentType = getValueViaPath( + formValue, + 'studiesAccident.type', + ) + return studiesAccidentType === StudiesAccidentTypeEnum.INTERNSHIP +} + +export const isMachineRelatedAccident = (formValue: FormValue) => { + const workMachineAnswer = getValueViaPath( + formValue, + 'workMachineRadio', + ) + return isGeneralWorkplaceAccident(formValue) && workMachineAnswer === YES +} + +// When a person is hurt in a sports accident and is an employee of the sport, the accident +// is considered a work accident. This function checks if both conditions are met. +export const isSportAccidentAndEmployee = (formValue: FormValue): boolean => { + const workAccidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) as AccidentTypeEnum + const onPayRoll = getValueViaPath(formValue, 'onPayRoll.answer') as YesOrNo + + if (workAccidentType === AccidentTypeEnum.SPORTS && onPayRoll === 'yes') { + return true + } + + return false +} + +// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the workaccident type. +// Therefore we need to check also whether this is a work accident +export const isFishermanAccident = (formValue: FormValue) => { + const workAccidentType = getValueViaPath( + formValue, + 'workAccident.type', + ) + return ( + workAccidentType === WorkAccidentTypeEnum.FISHERMAN && + isWorkAccident(formValue) + ) +} + +// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the agriculture type. +// Therefore we need to check also whether this is a work accident +export const isAgricultureAccident = (formValue: FormValue) => { + const workAccidentType = getValueViaPath( + formValue, + 'workAccident.type', + ) + return ( + workAccidentType === WorkAccidentTypeEnum.AGRICULTURE && + isWorkAccident(formValue) + ) +} + +// Specific case check here since the accident can be a sports accident if he picks sports in the first question where +// he is asked what the circumstances of the accident were. But that user could also select work and then a sport related +// accident since the question can be missunderstood by the user so we are funneling both cases into the same flow +export const isProfessionalAthleteAccident = (formValue: FormValue) => { + const workAccidentType = getValueViaPath( + formValue, + 'accidentType.radioButton', + ) + const workAccidentSecondaryType = getValueViaPath( + formValue, + 'workAccident.type', + ) + return ( + workAccidentType === AccidentTypeEnum.SPORTS || + (workAccidentSecondaryType === WorkAccidentTypeEnum.PROFESSIONALATHLETE && + isWorkAccident(formValue)) + ) +} + +// As this is a second question the user is asked there is a case where he could go back and select home activities and keep the workaccident type. +// Therefore we need to check also whether this is a work accident +export const isGeneralWorkplaceAccident = (formValue: FormValue) => { + const workAccidentType = getValueViaPath( + formValue, + 'workAccident.type', + ) + return ( + workAccidentType === WorkAccidentTypeEnum.GENERAL && + isWorkAccident(formValue) + ) +} + +export const isOfWorkAccidentType = ( + answers: Partial, + type: WorkAccidentTypeEnum, +) => { + const workAccidentType = getValueViaPath( + answers, + 'workAccident.type', + ) + return workAccidentType === type +} diff --git a/libs/application/templates/accident-notification/src/utils/reportingUtils.spec.ts b/libs/application/templates/accident-notification/src/utils/reportingUtils.spec.ts new file mode 100644 index 000000000000..1cad36fc260c --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/reportingUtils.spec.ts @@ -0,0 +1,122 @@ +import { FormValue } from '@island.is/application/types' +import { WhoIsTheNotificationForEnum } from '../types' +import { + isReportingOnBehalfOfChild, + isReportingOnBehalfOfEmployee, + isReportingOnBehalfOfInjured, + isReportingOnBehalfSelf, +} from './reportingUtils' + +describe('isReportingOnBehalfOfInjured', () => { + const powerOfAttorneyReporter: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + } + + const juridicialPersonReporter: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, + }, + } + + const reportingForSelf: FormValue = { + whoIsTheNotificationFor: { answer: WhoIsTheNotificationForEnum.ME }, + } + + const emptyObject = {} + + it('should return true for power of attorney reporter', () => { + expect(isReportingOnBehalfOfInjured(powerOfAttorneyReporter)).toEqual(true) + }) + + it('should return true for power of juridical person reporter', () => { + expect(isReportingOnBehalfOfInjured(juridicialPersonReporter)).toEqual(true) + }) + + it('should return false for reporting for yourself', () => { + expect(isReportingOnBehalfOfInjured(reportingForSelf)).toEqual(false) + }) + + it('should return false for empty object', () => { + expect(isReportingOnBehalfOfInjured(emptyObject)).toEqual(false) + }) +}) + +describe('isReportingOnBehalfOfEmployee', () => { + const onBehalfOfEmployee: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.JURIDICALPERSON, + }, + } + + const onBehalfOfSomeOtherPerson: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + } + + const emptyObject = {} + + it('should return true if reporting on behalf of employee', () => { + expect(isReportingOnBehalfOfEmployee(onBehalfOfEmployee)).toEqual(true) + }) + it('should return false if reporting on behalf of some other person', () => { + expect(isReportingOnBehalfOfEmployee(onBehalfOfSomeOtherPerson)).toEqual( + false, + ) + }) + it('should return false for empty object', () => { + expect(isReportingOnBehalfOfEmployee(emptyObject)).toEqual(false) + }) +}) + +describe('isReportingOnBehalfOfChild', () => { + const onBehalfOfChild: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.CHILDINCUSTODY, + }, + } + + const onBehalfOfSomeOtherPerson: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + } + + const emptyObject = {} + + it('should return true if reporting on behalf of child', () => { + expect(isReportingOnBehalfOfChild(onBehalfOfChild)).toEqual(true) + }) + it('should return false if reporting on behalf of some other person', () => { + expect(isReportingOnBehalfOfChild(onBehalfOfSomeOtherPerson)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isReportingOnBehalfOfChild(emptyObject)).toEqual(false) + }) +}) + +describe('isRepresentativeOfCompanyOrInstitute', () => { + const self: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.ME, + }, + } + + const notSelf: FormValue = { + whoIsTheNotificationFor: { + answer: WhoIsTheNotificationForEnum.POWEROFATTORNEY, + }, + } + + it('should return true when someone is reporting on behalf of themselves', () => { + expect(isReportingOnBehalfSelf(self)).toEqual(true) + }) + it('should return false when someone is not reporting on behalf of themselves', () => { + expect(isReportingOnBehalfSelf(notSelf)).toEqual(false) + }) + it('should return false for empty object', () => { + expect(isReportingOnBehalfSelf({})).toEqual(false) + }) +}) diff --git a/libs/application/templates/accident-notification/src/utils/reportingUtils.ts b/libs/application/templates/accident-notification/src/utils/reportingUtils.ts new file mode 100644 index 000000000000..ecba491760ad --- /dev/null +++ b/libs/application/templates/accident-notification/src/utils/reportingUtils.ts @@ -0,0 +1,38 @@ +import { getValueViaPath } from '@island.is/application/core' +import { FormValue } from '@island.is/application/types' +import { WhoIsTheNotificationForEnum } from '../types' + +export const isReportingOnBehalfOfInjured = (formValue: FormValue) => { + const whoIsTheNotificationFor = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + return ( + whoIsTheNotificationFor === WhoIsTheNotificationForEnum.JURIDICALPERSON || + whoIsTheNotificationFor === WhoIsTheNotificationForEnum.POWEROFATTORNEY + ) +} + +export const isReportingOnBehalfOfEmployee = (formValue: FormValue) => { + const whoIsTheNotificationFor = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.JURIDICALPERSON +} + +export const isReportingOnBehalfOfChild = (formValue: FormValue) => { + const whoIsTheNotificationFor = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.CHILDINCUSTODY +} + +export const isReportingOnBehalfSelf = (formValue: FormValue) => { + const whoIsTheNotificationFor = getValueViaPath( + formValue, + 'whoIsTheNotificationFor.answer', + ) + return whoIsTheNotificationFor === WhoIsTheNotificationForEnum.ME +} diff --git a/libs/application/templates/accident-notification/src/utils/shouldRequestReview.spec.ts b/libs/application/templates/accident-notification/src/utils/shouldRequestReview.spec.ts deleted file mode 100644 index cef1aa791e08..000000000000 --- a/libs/application/templates/accident-notification/src/utils/shouldRequestReview.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { AccidentNotificationAnswers } from '..' -import { AccidentTypeEnum, WorkAccidentTypeEnum } from '../types' -import { shouldRequestReview } from './shouldRequestReview' -describe('shouldRequestReview', () => { - const agricultureAccident: Partial = { - workAccident: { type: WorkAccidentTypeEnum.AGRICULTURE }, - } - - const accidentAtHome: Partial = { - accidentType: { radioButton: AccidentTypeEnum.HOMEACTIVITIES }, - } - - const normalWorkAccident: Partial = { - workAccident: { type: WorkAccidentTypeEnum.GENERAL }, - } - - it('should return false for work accidents', () => { - expect(shouldRequestReview(agricultureAccident)).toEqual(false) - }) - it('should return true for general work accident', () => { - expect(shouldRequestReview(normalWorkAccident)).toEqual(true) - }) - it('should return false for home accident', () => { - expect(shouldRequestReview(accidentAtHome)).toEqual(false) - }) -}) diff --git a/libs/application/templates/accident-notification/src/utils/shouldRequestReview.ts b/libs/application/templates/accident-notification/src/utils/shouldRequestReview.ts deleted file mode 100644 index f4773098dc74..000000000000 --- a/libs/application/templates/accident-notification/src/utils/shouldRequestReview.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { AccidentNotificationAnswers, utils, WorkAccidentTypeEnum } from '..' - -export const shouldRequestReview = ( - answers: Partial, -): boolean => { - const ishome = utils.isHomeActivitiesAccident(answers) - const isAgriculture = utils.isOfWorkAccidentType( - answers, - WorkAccidentTypeEnum.AGRICULTURE, - ) - - const isEitherHomeOrAgriculture = ishome || isAgriculture - - return !isEitherHomeOrAgriculture -} diff --git a/libs/application/templates/aosh/register-new-machine/src/fields/LocationInputField/index.tsx b/libs/application/templates/aosh/register-new-machine/src/fields/LocationInputField/index.tsx new file mode 100644 index 000000000000..37a39cf795b5 --- /dev/null +++ b/libs/application/templates/aosh/register-new-machine/src/fields/LocationInputField/index.tsx @@ -0,0 +1,50 @@ +import { FieldBaseProps } from '@island.is/application/types' +import { FC, useState } from 'react' +import { useFormContext } from 'react-hook-form' +import { coreErrorMessages } from '@island.is/application/core' +import { AboutMachine } from '../../lib/dataSchema' +import { Box } from '@island.is/island-ui/core' +import { InputController } from '@island.is/shared/form-fields' +import { useLocale } from '@island.is/localization' +import { machine } from '../../lib/messages' + +export const LocationInputField: FC> = ( + props, +) => { + const { field, setBeforeSubmitCallback } = props + const { formatMessage } = useLocale() + const { watch } = useFormContext() + const [displayError, setDisplayError] = useState(false) + const watchMachine = watch('machine.aboutMachine') as AboutMachine + const location = watch(field.id) as string + const categoryValue = 'Fólkslyftur og vörulyftur' + + setBeforeSubmitCallback?.(async () => { + if ( + watchMachine.category?.nameIs === categoryValue && + location.length === 0 + ) { + setDisplayError(true) + return [false, ''] + } + return [true, null] + }) + + return ( + + setDisplayError(false)} + error={ + displayError && location.length === 0 + ? formatMessage(coreErrorMessages.defaultError) + : undefined + } + /> + + ) +} diff --git a/libs/application/templates/aosh/register-new-machine/src/fields/index.ts b/libs/application/templates/aosh/register-new-machine/src/fields/index.ts index cf08b813c38b..b33672f5ec00 100644 --- a/libs/application/templates/aosh/register-new-machine/src/fields/index.ts +++ b/libs/application/templates/aosh/register-new-machine/src/fields/index.ts @@ -3,3 +3,4 @@ export { Overview } from './Overview' export { AboutMachine } from './AboutMachine' export { TechnicalInfo } from './TechnicalInfo' export { ChangeAnswers } from './ChangeAnswers' +export { LocationInputField } from './LocationInputField' diff --git a/libs/application/templates/aosh/register-new-machine/src/forms/RegisterMachineForm/MachineSection/MachineBasicInformation.ts b/libs/application/templates/aosh/register-new-machine/src/forms/RegisterMachineForm/MachineSection/MachineBasicInformation.ts index 22afa79349c9..716b3af34f9e 100644 --- a/libs/application/templates/aosh/register-new-machine/src/forms/RegisterMachineForm/MachineSection/MachineBasicInformation.ts +++ b/libs/application/templates/aosh/register-new-machine/src/forms/RegisterMachineForm/MachineSection/MachineBasicInformation.ts @@ -122,11 +122,11 @@ export const MachineBasicInformation = buildSubSection({ titleVariant: 'h5', marginTop: 3, }), - buildTextField({ + buildCustomField({ id: 'machine.basicInformation.location', - title: machine.labels.basicMachineInformation.location, + title: '', width: 'half', - maxLength: 255, + component: 'LocationInputField', }), buildTextField({ id: 'machine.basicInformation.cargoFileNumber', diff --git a/libs/application/templates/aosh/register-new-machine/tsconfig.lib.json b/libs/application/templates/aosh/register-new-machine/tsconfig.lib.json index 8d36d2eaf5af..cfc356e7214b 100644 --- a/libs/application/templates/aosh/register-new-machine/tsconfig.lib.json +++ b/libs/application/templates/aosh/register-new-machine/tsconfig.lib.json @@ -2,23 +2,22 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "../../../../../dist/out-tsc", - "types": [ - "node", - - "@nx/react/typings/cssmodule.d.ts", - "@nx/react/typings/image.d.ts" - ] + "types": ["node"] }, + "files": [ + "../../../../../node_modules/@nx/react/typings/cssmodule.d.ts", + "../../../../../node_modules/@nx/react/typings/image.d.ts" + ], "exclude": [ - "jest.config.ts", - "src/**/*.spec.ts", - "src/**/*.test.ts", - "src/**/*.spec.tsx", - "src/**/*.test.tsx", - "src/**/*.spec.js", - "src/**/*.test.js", - "src/**/*.spec.jsx", - "src/**/*.test.jsx" + "**/*.spec.ts", + "**/*.test.ts", + "**/*.spec.tsx", + "**/*.test.tsx", + "**/*.spec.js", + "**/*.test.js", + "**/*.spec.jsx", + "**/*.test.jsx", + "jest.config.ts" ], - "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] } diff --git a/libs/application/templates/official-journal-of-iceland/src/components/htmlEditor/HTMLEditor.tsx b/libs/application/templates/official-journal-of-iceland/src/components/htmlEditor/HTMLEditor.tsx index f8cb1367ec92..0b91a291d5e7 100644 --- a/libs/application/templates/official-journal-of-iceland/src/components/htmlEditor/HTMLEditor.tsx +++ b/libs/application/templates/official-journal-of-iceland/src/components/htmlEditor/HTMLEditor.tsx @@ -3,7 +3,7 @@ import { Editor, EditorFileUploader } from '@island.is/regulations-tools/Editor' import { useEffect, useRef, useState } from 'react' import { Controller } from 'react-hook-form' import { classes, editorWrapper, errorStyle } from './HTMLEditor.css' -import { Box, Text } from '@island.is/island-ui/core' +import { Box, Stack, Text } from '@island.is/island-ui/core' type Props = { title?: string name: string @@ -50,12 +50,8 @@ export const HTMLEditor = ({ defaultValue={initialValue} render={({ field: { onChange: updateFormValue, value } }) => { return ( - <> - {title && ( - - {title} - - )} + + {title && {title}} {error &&
{error}
} - +
) }} /> diff --git a/libs/application/templates/official-journal-of-iceland/src/components/input/OJOISelectController.tsx b/libs/application/templates/official-journal-of-iceland/src/components/input/OJOISelectController.tsx index 00eac25ff080..799ed40704d8 100644 --- a/libs/application/templates/official-journal-of-iceland/src/components/input/OJOISelectController.tsx +++ b/libs/application/templates/official-journal-of-iceland/src/components/input/OJOISelectController.tsx @@ -4,7 +4,12 @@ import { useApplication } from '../../hooks/useUpdateApplication' import { OJOIApplication } from '../../lib/types' import { useFormContext } from 'react-hook-form' import set from 'lodash/set' -import { Select, SkeletonLoader } from '@island.is/island-ui/core' +import { + Box, + Select, + SkeletonLoader, + useBreakpoint, +} from '@island.is/island-ui/core' import { OJOI_INPUT_HEIGHT } from '../../lib/constants' import { isBaseEntity } from '../../lib/utils' import { getValueViaPath } from '@island.is/application/core' @@ -23,6 +28,7 @@ type Props = { loading?: boolean applicationId: string disabled?: boolean + width?: 'full' | 'half' onBeforeChange?: (answers: OJOIApplication['answers'], value: T) => void onChange?: (value: T) => void } @@ -36,6 +42,7 @@ export const OJOISelectController = ({ loading, applicationId, disabled, + width = 'full', onBeforeChange, onChange, }: Props) => { @@ -46,6 +53,9 @@ export const OJOISelectController = ({ const { setValue } = useFormContext() + const { xs, sm, md } = useBreakpoint() + const isSmOrSmaller = xs || (sm && !md) + const placeholderText = typeof placeholder === 'string' ? placeholder : f(placeholder) @@ -68,35 +78,33 @@ export const OJOISelectController = ({ return opt.value.id === defaultVal.id } - return false + return undefined }) - if (loading) { - return ( - - ) - } - return ( - { + if (!opt?.value) return + return handleChange(opt.value) + }} + /> + )} +
) } diff --git a/libs/application/templates/official-journal-of-iceland/src/fields/Advert.tsx b/libs/application/templates/official-journal-of-iceland/src/fields/Advert.tsx index 0e81b3062f40..fcaa5cfdb6fc 100644 --- a/libs/application/templates/official-journal-of-iceland/src/fields/Advert.tsx +++ b/libs/application/templates/official-journal-of-iceland/src/fields/Advert.tsx @@ -1,8 +1,7 @@ import { InputFields, OJOIFieldBaseProps } from '../lib/types' -import { Box } from '@island.is/island-ui/core' +import { Stack } from '@island.is/island-ui/core' import { FormGroup } from '../components/form/FormGroup' import { advert } from '../lib/messages' -import * as styles from './Advert.css' import { useDepartments } from '../hooks/useDepartments' import { OJOISelectController } from '../components/input/OJOISelectController' import { useTypes } from '../hooks/useTypes' @@ -12,25 +11,23 @@ import { useFormContext } from 'react-hook-form' import { useApplication } from '../hooks/useUpdateApplication' import set from 'lodash/set' import { HTMLEditor } from '../components/htmlEditor/HTMLEditor' -import { getAdvertMarkup } from '../lib/utils' +import { cleanTypename, getAdvertMarkup } from '../lib/utils' +import { DEPARTMENT_A } from '../lib/constants' export const Advert = ({ application }: OJOIFieldBaseProps) => { const { setValue } = useFormContext() const { application: currentApplication } = useApplication({ applicationId: application.id, }) + const { departments, loading: loadingDepartments } = useDepartments() - const { - getLazyTypes, - types, - loading: loadingTypes, - } = useTypes({ - initalDepartmentId: application.answers?.advert?.department?.id, - }) - const titlePreview = getAdvertMarkup({ - type: currentApplication.answers.advert?.type?.title, - title: currentApplication.answers.advert?.title, + const defaultDepartment = + application.answers?.advert?.department?.id || DEPARTMENT_A + + const { getLazyMainTypes, mainTypes, mainTypeLoading } = useTypes({ + initalDepartmentId: defaultDepartment, + pageSize: 300, }) const departmentOptions = departments?.map((d) => ({ @@ -42,20 +39,28 @@ export const Advert = ({ application }: OJOIFieldBaseProps) => { }, })) - const typeOptions = types?.map((d) => ({ + const mainTypeOptions = mainTypes?.map((d) => ({ label: d.title, - value: { - id: d.id, - title: d.title, - slug: d.slug, - }, + value: d, })) + const currentTypes = + currentApplication?.answers?.advert?.mainType?.types?.map((d) => ({ + label: d.title, + value: d, + })) ?? [] + + const titlePreview = getAdvertMarkup({ + type: currentApplication.answers.advert?.type?.title, + title: currentApplication.answers.advert?.title, + }) + return ( - <> + - + { set(answers, InputFields.advert.type, null) }} onChange={(value) => - getLazyTypes({ + getLazyMainTypes({ variables: { params: { department: value.id, @@ -78,19 +83,36 @@ export const Advert = ({ application }: OJOIFieldBaseProps) => { }) } /> - - + { + if (value.types.length === 1) { + const cleaned = cleanTypename(value.types[0]) + set(answers, InputFields.advert.type, cleaned) + } else { + set(answers, InputFields.advert.type, null) + } + }} /> - - + + {currentTypes.length > 1 && ( + + )} + { textarea={true} maxLength={600} /> - - + - + - + { applicationId={application.id} disabled={true} /> - - + { // because this is not a controlled component onChange={(value) => setValue(InputFields.advert.html, value)} /> - + - + ) } diff --git a/libs/application/templates/official-journal-of-iceland/src/fields/AdvertModal.tsx b/libs/application/templates/official-journal-of-iceland/src/fields/AdvertModal.tsx index 8327cefa5e93..5020d1b8fbe7 100644 --- a/libs/application/templates/official-journal-of-iceland/src/fields/AdvertModal.tsx +++ b/libs/application/templates/official-journal-of-iceland/src/fields/AdvertModal.tsx @@ -26,6 +26,7 @@ import debounce from 'lodash/debounce' import { InputFields } from '../lib/types' import { useFormContext } from 'react-hook-form' import { OfficialJournalOfIcelandAdvert } from '@island.is/api/schema' +import { cleanTypename } from '../lib/utils' type Props = { applicationId: string visible: boolean @@ -75,20 +76,12 @@ export const AdvertModal = ({ return } - const clean = (obj: { - __typename?: string - id: string - title: string - slug: string - }) => { - const { __typename: _, ...rest } = obj - return rest - } - - const department = clean(advert.department) - const type = clean(advert.type) + const department = cleanTypename(advert.department) + const type = cleanTypename(advert.type) - const categories = advert.categories.map((category) => clean(category)) + const categories = advert.categories.map((category) => + cleanTypename(category), + ) setValue(InputFields.advert.department, department) setValue(InputFields.advert.type, type) diff --git a/libs/application/templates/official-journal-of-iceland/src/graphql/queries.ts b/libs/application/templates/official-journal-of-iceland/src/graphql/queries.ts index ebe437b894ad..cfe4f70ab68b 100644 --- a/libs/application/templates/official-journal-of-iceland/src/graphql/queries.ts +++ b/libs/application/templates/official-journal-of-iceland/src/graphql/queries.ts @@ -117,6 +117,38 @@ export const ADVERT_QUERY = gql` } ` +export const MAIN_TYPES_QUERY = gql` + query AdvertMainTypes($params: OfficialJournalOfIcelandMainTypesInput!) { + officialJournalOfIcelandMainTypes(params: $params) { + mainTypes { + id + title + slug + department { + id + title + slug + } + types { + id + title + slug + } + } + paging { + page + pageSize + totalPages + totalItems + hasNextPage + hasPreviousPage + nextPage + previousPage + } + } + } +` + export const TYPES_QUERY = gql` query AdvertTypes($params: OfficialJournalOfIcelandTypesInput!) { officialJournalOfIcelandTypes(params: $params) { diff --git a/libs/application/templates/official-journal-of-iceland/src/hooks/useTypes.ts b/libs/application/templates/official-journal-of-iceland/src/hooks/useTypes.ts index 8cd4ff5678ed..7ff98ea1949f 100644 --- a/libs/application/templates/official-journal-of-iceland/src/hooks/useTypes.ts +++ b/libs/application/templates/official-journal-of-iceland/src/hooks/useTypes.ts @@ -1,7 +1,10 @@ import { useLazyQuery, useQuery } from '@apollo/client' -import { OfficialJournalOfIcelandAdvertsTypesResponse } from '@island.is/api/schema' +import { + OfficialJournalOfIcelandAdvertsTypesResponse, + OfficialJournalOfIcelandMainTypesResponse, +} from '@island.is/api/schema' -import { TYPES_QUERY } from '../graphql/queries' +import { MAIN_TYPES_QUERY, TYPES_QUERY } from '../graphql/queries' type UseTypesParams = { initalDepartmentId?: string @@ -14,6 +17,10 @@ type TypesResponse = { officialJournalOfIcelandTypes: OfficialJournalOfIcelandAdvertsTypesResponse } +type MainTypesResponse = { + officialJournalOfIcelandMainTypes: OfficialJournalOfIcelandMainTypesResponse +} + type TypesVariables = { params: { department?: string @@ -50,6 +57,16 @@ export const useTypes = ({ }, ) + const { + data: mainTypesData, + loading: mainTypeLoading, + error: mainTypeError, + } = useQuery(MAIN_TYPES_QUERY, { + variables: { + params: params, + }, + }) + const [ getLazyTypes, { data: lazyTypes, loading: lazyTypesLoading, error: lazyTypesError }, @@ -57,11 +74,33 @@ export const useTypes = ({ fetchPolicy: 'network-only', }) + const [ + getLazyMainTypes, + { + data: lazyMainTypes, + loading: lazyMainTypesLoading, + error: lazyMainTypesError, + }, + ] = useLazyQuery(MAIN_TYPES_QUERY, { + fetchPolicy: 'network-only', + }) + const currentTypes = lazyTypes ? lazyTypes.officialJournalOfIcelandTypes.types : data?.officialJournalOfIcelandTypes.types + const currentMainTypes = lazyMainTypes + ? lazyMainTypes.officialJournalOfIcelandMainTypes.mainTypes + : mainTypesData?.officialJournalOfIcelandMainTypes.mainTypes + return { + mainTypes: currentMainTypes, + mainTypeLoading, + mainTypeError, + lazyMainTypesLoading, + lazyMainTypesError, + getLazyMainTypes, + lazyMainTypes: lazyMainTypes?.officialJournalOfIcelandMainTypes.mainTypes, lazyTypes: lazyTypes?.officialJournalOfIcelandTypes.types, lazyTypesLoading, lazyTypesError, diff --git a/libs/application/templates/official-journal-of-iceland/src/lib/constants.ts b/libs/application/templates/official-journal-of-iceland/src/lib/constants.ts index e05b15dcaf66..ed4ea3efc463 100644 --- a/libs/application/templates/official-journal-of-iceland/src/lib/constants.ts +++ b/libs/application/templates/official-journal-of-iceland/src/lib/constants.ts @@ -14,6 +14,10 @@ export enum AnswerOption { NO = 'no', } +export const DEPARTMENT_A = 'a-deild' +export const DEPARTMENT_B = 'b-deild' +export const DEPARTMENT_C = 'c-deild' + export enum ApplicationAttachmentType { ORIGINAL = 'frumrit', ADDITIONS = 'fylgiskjol', diff --git a/libs/application/templates/official-journal-of-iceland/src/lib/dataSchema.ts b/libs/application/templates/official-journal-of-iceland/src/lib/dataSchema.ts index 046cbeed2664..8dcfe02c7bbd 100644 --- a/libs/application/templates/official-journal-of-iceland/src/lib/dataSchema.ts +++ b/libs/application/templates/official-journal-of-iceland/src/lib/dataSchema.ts @@ -69,6 +69,9 @@ const advertSchema = z .object({ department: baseEntitySchema.optional(), type: baseEntitySchema.optional().nullable(), + mainType: baseEntitySchema + .extend({ types: z.array(baseEntitySchema).optional() }) + .optional(), title: z.string().optional(), html: z.string().optional(), requestedDate: z.string().optional(), diff --git a/libs/application/templates/official-journal-of-iceland/src/lib/messages/advert.ts b/libs/application/templates/official-journal-of-iceland/src/lib/messages/advert.ts index 681773cf8393..0bde1ec2be09 100644 --- a/libs/application/templates/official-journal-of-iceland/src/lib/messages/advert.ts +++ b/libs/application/templates/official-journal-of-iceland/src/lib/messages/advert.ts @@ -63,15 +63,27 @@ export const advert = { description: 'Placeholder for the department input', }, }), + mainType: defineMessages({ + label: { + id: 'ojoi.application:advert.inputs.mainType.label', + defaultMessage: 'Tegund birtingar', + description: 'Label for the main type input', + }, + placeholder: { + id: 'ojoi.application:advert.inputs.mainType.placeholder', + defaultMessage: 'Veldu tegund birtingar', + description: 'Placeholder for the main type input', + }, + }), type: defineMessages({ label: { id: 'ojoi.application:advert.inputs.type.label', - defaultMessage: 'Tegund birtingar', + defaultMessage: 'Undirtegund birtingar', description: 'Label for the type input', }, placeholder: { id: 'ojoi.application:advert.inputs.type.placeholder', - defaultMessage: 'Veldu tegund birtingar', + defaultMessage: 'Veldu undirtegund birtingar', description: 'Placeholder for the type input', }, }), diff --git a/libs/application/templates/official-journal-of-iceland/src/lib/types.ts b/libs/application/templates/official-journal-of-iceland/src/lib/types.ts index 1529e2d56442..032d13c63692 100644 --- a/libs/application/templates/official-journal-of-iceland/src/lib/types.ts +++ b/libs/application/templates/official-journal-of-iceland/src/lib/types.ts @@ -12,6 +12,7 @@ export const InputFields = { }, [Routes.ADVERT]: { department: 'advert.department', + mainType: 'advert.mainType', type: 'advert.type', title: 'advert.title', html: 'advert.html', diff --git a/libs/application/templates/official-journal-of-iceland/src/lib/utils.ts b/libs/application/templates/official-journal-of-iceland/src/lib/utils.ts index 15699f900241..fdfaad3ab0d9 100644 --- a/libs/application/templates/official-journal-of-iceland/src/lib/utils.ts +++ b/libs/application/templates/official-journal-of-iceland/src/lib/utils.ts @@ -388,3 +388,13 @@ export const convertNumberToRoman = (num: number) => { const roman = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'] return roman[num - 1] } + +export const cleanTypename = (obj: { + __typename?: string + id: string + title: string + slug: string +}) => { + const { __typename: _, ...rest } = obj + return rest +} diff --git a/libs/application/templates/official-journal-of-iceland/src/screens/InvolvedPartyScreen.tsx b/libs/application/templates/official-journal-of-iceland/src/screens/InvolvedPartyScreen.tsx index 7ed23a605848..b35efca32233 100644 --- a/libs/application/templates/official-journal-of-iceland/src/screens/InvolvedPartyScreen.tsx +++ b/libs/application/templates/official-journal-of-iceland/src/screens/InvolvedPartyScreen.tsx @@ -90,21 +90,20 @@ export const InvolvedPartyScreen = ({ /> )} - - { - setSubmitButtonDisabled && setSubmitButtonDisabled(false) - }} - /> - + { + setSubmitButtonDisabled && setSubmitButtonDisabled(false) + }} + />
) diff --git a/libs/clients/health-directorate/src/lib/clients/organ-donation/clientConfig.json b/libs/clients/health-directorate/src/lib/clients/organ-donation/clientConfig.json index b83056a0484c..8612145527f7 100644 --- a/libs/clients/health-directorate/src/lib/clients/organ-donation/clientConfig.json +++ b/libs/clients/health-directorate/src/lib/clients/organ-donation/clientConfig.json @@ -1,18 +1,11 @@ { "openapi": "3.0.0", "paths": { - "/v1/me/organ-donor-status": { + "/v1/donation-exceptions": { "get": { - "operationId": "MeDonorStatusController_getOrganDonorStatus", - "description": "Get user's donation-exception donor status", + "operationId": "DonationExceptionController_getOrgans", + "description": "Gets a list of organs that can be omitted from an donation-exception donation", "parameters": [ - { - "name": "ip", - "required": false, - "in": "query", - "description": "The IP address of the user", - "schema": { "type": "string" } - }, { "name": "locale", "required": false, @@ -26,7 +19,10 @@ "description": "", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/OrganDonorDto" } + "schema": { + "type": "array", + "items": { "$ref": "#/components/schemas/OrganDto" } + } } } }, @@ -63,37 +59,38 @@ } } }, - "tags": ["me/organ-donor-status"] - }, - "post": { - "operationId": "MeDonorStatusController_updateOrganDonorStatus", - "description": "Update user's donation-exception donor status", + "tags": ["donation-exceptions"] + } + }, + "/v1/me/organ-donor-status": { + "get": { + "operationId": "MeDonorStatusController_getOrganDonorStatus", + "description": "Get user's donation-exception donor status", "parameters": [ { - "name": "ip", + "name": "locale", "required": false, "in": "query", - "description": "The IP address of the user", - "schema": { "type": "string" } + "description": "The locale to use for the response", + "schema": { "$ref": "#/components/schemas/Locale" } }, { - "name": "locale", + "name": "ip", "required": false, "in": "query", - "description": "The locale to use for the response", - "schema": { "$ref": "#/components/schemas/Locale" } + "description": "The IP address of the user", + "schema": { "type": "string" } } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { "$ref": "#/components/schemas/UpdateOrganDonorDto" } - } - } - }, "responses": { - "200": { "description": "" }, + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/OrganDonorDto" } + } + } + }, "400": { "description": "", "content": { @@ -128,12 +125,10 @@ } }, "tags": ["me/organ-donor-status"] - } - }, - "/v1/donation-exceptions": { - "get": { - "operationId": "DonationExceptionController_getOrgans", - "description": "Gets a list of organs that can be omitted from an donation-exception donation", + }, + "post": { + "operationId": "MeDonorStatusController_updateOrganDonorStatus", + "description": "Update user's donation-exception donor status", "parameters": [ { "name": "locale", @@ -141,20 +136,25 @@ "in": "query", "description": "The locale to use for the response", "schema": { "$ref": "#/components/schemas/Locale" } + }, + { + "name": "ip", + "required": false, + "in": "query", + "description": "The IP address of the user", + "schema": { "type": "string" } } ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "array", - "items": { "$ref": "#/components/schemas/OrganDto" } - } - } + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/UpdateOrganDonorDto" } } - }, + } + }, + "responses": { + "200": { "description": "" }, "400": { "description": "", "content": { @@ -188,7 +188,7 @@ } } }, - "tags": ["donation-exceptions"] + "tags": ["me/organ-donor-status"] } } }, @@ -226,24 +226,11 @@ }, "required": ["id", "name"] }, - "OrganDonorDto": { - "type": "object", - "properties": { - "isDonor": { "type": "boolean" }, - "exceptions": { - "type": "array", - "items": { "$ref": "#/components/schemas/OrganDto" } - }, - "exceptionComment": { "type": "string" }, - "registrationDate": { "format": "date-time", "type": "string" } - }, - "required": ["isDonor", "exceptions"] - }, "HttpProblemResponse": { "type": "object", "properties": { "type": { - "type": "object", + "type": "string", "description": "A URI reference that identifies the problem type" }, "title": { @@ -262,12 +249,27 @@ }, "required": ["type", "title"] }, + "OrganDonorDto": { + "type": "object", + "properties": { + "isDonor": { "type": "boolean" }, + "exceptions": { + "type": "array", + "items": { "$ref": "#/components/schemas/OrganDto" } + }, + "exceptionComment": { "type": "string" }, + "registrationDate": { "format": "date-time", "type": "string" }, + "isMinor": { "type": "boolean" }, + "isTemporaryResident": { "type": "boolean" } + }, + "required": ["isDonor", "exceptions"] + }, "UpdateOrganDonorDto": { "type": "object", "properties": { "isDonor": { "type": "boolean" }, "exceptions": { "type": "array", "items": { "type": "string" } }, - "exceptionComment": { "type": "object" } + "exceptionComment": { "type": "string" } }, "required": ["isDonor", "exceptions"] } diff --git a/libs/clients/official-journal-of-iceland/public/src/clientConfig.json b/libs/clients/official-journal-of-iceland/public/src/clientConfig.json index 092ccd7520e1..6206b173263a 100644 --- a/libs/clients/official-journal-of-iceland/public/src/clientConfig.json +++ b/libs/clients/official-journal-of-iceland/public/src/clientConfig.json @@ -169,15 +169,40 @@ } } }, - "/api/v1/types/{id}": { + "/api/v1/maincategories": { "get": { - "operationId": "getAdvertTypeById", + "operationId": "getMainCategories", "parameters": [ { - "name": "id", - "required": true, - "in": "path", + "name": "search", + "description": "String to search for", + "required": false, + "in": "query", "schema": { "type": "string" } + }, + { + "name": "ids", + "required": false, + "in": "query", + "schema": { + "default": [], + "type": "array", + "items": { "type": "string" } + } + }, + { + "name": "page", + "description": "Page number to return.", + "required": false, + "in": "query", + "schema": { "type": "number" } + }, + { + "name": "pageSize", + "description": "Page size number to return.", + "required": false, + "in": "query", + "schema": { "type": "number" } } ], "responses": { @@ -186,7 +211,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAdvertTypeResponse" + "$ref": "#/components/schemas/GetMainCategoriesResponse" } } } @@ -194,23 +219,26 @@ } } }, - "/api/v1/types": { + "/api/v1/categories": { "get": { - "operationId": "getAdvertTypes", + "operationId": "getCategories", "parameters": [ { - "name": "department", - "description": "Department slug to get categories for.", + "name": "search", + "description": "String to search for", "required": false, "in": "query", "schema": { "type": "string" } }, { - "name": "search", - "description": "String to search for in types.", + "name": "ids", "required": false, "in": "query", - "schema": { "type": "string" } + "schema": { + "default": [], + "type": "array", + "items": { "type": "string" } + } }, { "name": "page", @@ -221,7 +249,7 @@ }, { "name": "pageSize", - "description": "Number of items per page.", + "description": "Page size number to return.", "required": false, "in": "query", "schema": { "type": "number" } @@ -233,7 +261,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetAdvertTypesResponse" + "$ref": "#/components/schemas/GetCategoriesResponse" } } } @@ -241,9 +269,9 @@ } } }, - "/api/v1/maincategories": { + "/api/v1/institutions": { "get": { - "operationId": "getMainCategories", + "operationId": "getInstitutions", "parameters": [ { "name": "search", @@ -283,7 +311,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetMainCategoriesResponse" + "$ref": "#/components/schemas/GetInstitutionsResponse" } } } @@ -291,37 +319,36 @@ } } }, - "/api/v1/categories": { + "/api/v1/signatures": { "get": { - "operationId": "getCategories", + "operationId": "getSignatures", "parameters": [ { - "name": "search", - "description": "String to search for", + "description": "Search for a specific signature by id", "required": false, + "name": "id", "in": "query", "schema": { "type": "string" } }, { - "name": "ids", + "description": "Search for a specific signature by type", + "example": "Regular", "required": false, + "name": "type", "in": "query", - "schema": { - "default": [], - "type": "array", - "items": { "type": "string" } - } + "schema": { "type": "string" } }, { - "name": "page", - "description": "Page number to return.", + "description": "Search for a specific signature", + "example": "Dagur B. Eggertsson", "required": false, + "name": "search", "in": "query", - "schema": { "type": "number" } + "schema": { "type": "string" } }, { - "name": "pageSize", - "description": "Page size number to return.", + "name": "page", + "description": "Page number to return.", "required": false, "in": "query", "schema": { "type": "number" } @@ -333,7 +360,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetCategoriesResponse" + "$ref": "#/components/schemas/GetAdvertSignatureResponse" } } } @@ -341,9 +368,9 @@ } } }, - "/api/v1/institutions": { + "/api/v1/cases": { "get": { - "operationId": "getInstitutions", + "operationId": "getCasesInProgress", "parameters": [ { "name": "search", @@ -383,7 +410,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/GetInstitutionsResponse" + "$ref": "#/components/schemas/GetCasesInProgressReponse" } } } @@ -391,115 +418,384 @@ } } }, - "/api/v1/signatures": { + "/api/v1/error": { "get": { - "operationId": "getSignatures", + "operationId": "error", + "parameters": [], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ValidationResponse" } + } + } + } + } + } + }, + "/api/v1/advert-types/types": { + "get": { + "operationId": "getTypes", + "summary": "", "parameters": [ { - "description": "Search for a specific signature by id", "required": false, + "description": "Search by id", "name": "id", "in": "query", "schema": { "type": "string" } }, { - "description": "Search for a specific signature by type", - "example": "Regular", "required": false, - "name": "type", + "description": "Filter by unassigned", + "name": "unassigned", + "in": "query", + "schema": { "type": "boolean" } + }, + { + "required": false, + "description": "Search by main type id", + "name": "mainType", "in": "query", "schema": { "type": "string" } }, { - "description": "Search for a specific signature", - "example": "Dagur B. Eggertsson", "required": false, + "description": "Search by title", "name": "search", "in": "query", "schema": { "type": "string" } }, { + "required": false, + "description": "Search by slug", + "name": "slug", + "in": "query", + "schema": { "type": "string" } + }, + { + "required": false, + "description": "Search by department slug, title or id", + "name": "department", + "in": "query", + "schema": { "type": "string" } + }, + { + "required": false, + "description": "The page number", "name": "page", - "description": "Page number to return.", + "in": "query", + "schema": { "type": "number" } + }, + { "required": false, + "description": "The page size", + "name": "pageSize", "in": "query", "schema": { "type": "number" } } ], "responses": { - "default": { + "200": { "description": "", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/GetAdvertSignatureResponse" - } + "schema": { "$ref": "#/components/schemas/GetAdvertTypes" } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } } } } } } }, - "/api/v1/cases": { + "/api/v1/advert-types/main-types": { "get": { - "operationId": "getCasesInProgress", + "operationId": "getMainTypes", + "summary": "", "parameters": [ { + "required": false, + "description": "Search by id", + "name": "id", + "in": "query", + "schema": { "type": "string" } + }, + { + "required": false, + "description": "Filter by unassigned", + "name": "unassigned", + "in": "query", + "schema": { "type": "boolean" } + }, + { + "required": false, + "description": "Search by main type id", + "name": "mainType", + "in": "query", + "schema": { "type": "string" } + }, + { + "required": false, + "description": "Search by title", "name": "search", - "description": "String to search for", + "in": "query", + "schema": { "type": "string" } + }, + { "required": false, + "description": "Search by slug", + "name": "slug", "in": "query", "schema": { "type": "string" } }, { - "name": "ids", "required": false, + "description": "Search by department slug, title or id", + "name": "department", "in": "query", - "schema": { - "default": [], - "type": "array", - "items": { "type": "string" } - } + "schema": { "type": "string" } }, { - "name": "page", - "description": "Page number to return.", "required": false, + "description": "The page number", + "name": "page", "in": "query", "schema": { "type": "number" } }, { - "name": "pageSize", - "description": "Page size number to return.", "required": false, + "description": "The page size", + "name": "pageSize", "in": "query", "schema": { "type": "number" } } ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAdvertMainTypes" } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + } + } + } + }, + "/api/v1/advert-types/types/{id}": { + "get": { + "operationId": "getTypeById", + "summary": "", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAdvertType" } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "404": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + } + } + } + }, + "/api/v1/advert-types/main-types/{id}": { + "get": { + "operationId": "getMainTypeById", + "summary": "", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAdvertMainType" } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "404": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/AdvertTypeError" } + } + } + } + } + } + }, + "/api/v1/pdf/case/{id}": { + "get": { + "operationId": "getPdfByCaseId", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], "responses": { "default": { "description": "", "content": { "application/json": { - "schema": { - "$ref": "#/components/schemas/GetCasesInProgressReponse" - } + "schema": { "$ref": "#/components/schemas/GetPdfRespone" } } } } } } }, - "/api/v1/error": { + "/api/v1/pdf/application/{id}": { "get": { - "operationId": "error", - "parameters": [], + "operationId": "getPdfByApplicationId", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], "responses": { "default": { "description": "", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ValidationResponse" } + "schema": { "$ref": "#/components/schemas/GetPdfRespone" } + } + } + } + } + } + }, + "/api/v1/pdf/case/{id}/url": { + "get": { + "operationId": "getPdfUrlByCaseId", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetPdfUrlResponse" } + } + } + } + } + } + }, + "/api/v1/pdf/application/{id}/url": { + "get": { + "operationId": "getPdfUrlByApplicationId", + "parameters": [ + { + "name": "id", + "required": true, + "in": "path", + "schema": { "type": "string" } + } + ], + "responses": { + "default": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetPdfUrlResponse" } } } } @@ -551,23 +847,18 @@ "properties": { "id": { "type": "string", - "description": "Unique ID for the advert type, GUID format.", - "example": "00000000-0000-0000-0000-000000000000", - "nullable": false + "description": "The id of the main advert type" }, "title": { "type": "string", - "description": "Title of the advert type, always uppercased.", - "example": "AUGLÝSING" + "description": "The title of the main advert type" }, "slug": { "type": "string", - "description": "Slug of the advert type, used in URLs and API requests.", - "example": "auglysing" + "description": "The slug of the main advert type" }, "department": { - "description": "Department the advert type belongs to.", - "nullable": true, + "description": "The department of the main advert type", "allOf": [{ "$ref": "#/components/schemas/Department" }] } }, @@ -977,31 +1268,6 @@ }, "required": ["departments", "paging"] }, - "GetAdvertTypeResponse": { - "type": "object", - "properties": { - "type": { - "description": "Advert type", - "allOf": [{ "$ref": "#/components/schemas/AdvertType" }] - } - }, - "required": ["type"] - }, - "GetAdvertTypesResponse": { - "type": "object", - "properties": { - "types": { - "description": "List of advert types", - "type": "array", - "items": { "$ref": "#/components/schemas/AdvertType" } - }, - "paging": { - "description": "Paging info", - "allOf": [{ "$ref": "#/components/schemas/Paging" }] - } - }, - "required": ["types", "paging"] - }, "MainCategory": { "type": "object", "properties": { @@ -1190,6 +1456,108 @@ } }, "required": ["message", "statusCode"] + }, + "GetAdvertTypes": { + "type": "object", + "properties": { + "types": { + "description": "List of advert types", + "type": "array", + "items": { "$ref": "#/components/schemas/AdvertType" } + }, + "paging": { + "description": "Paging information", + "allOf": [{ "$ref": "#/components/schemas/Paging" }] + } + }, + "required": ["types", "paging"] + }, + "AdvertTypeError": { + "type": "object", + "properties": { + "errorType": { + "type": "string", + "enum": ["DuplicateError", "ValidationError", "NotFoundError"] + }, + "name": { "type": "string" }, + "message": { "type": "string" }, + "severity": { "type": "string", "enum": ["info", "warning", "error"] } + }, + "required": ["errorType", "name", "message", "severity"] + }, + "AdvertMainType": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The id of the main advert type" + }, + "title": { + "type": "string", + "description": "The title of the main advert type" + }, + "slug": { + "type": "string", + "description": "The slug of the main advert type" + }, + "department": { + "description": "The department this main type belongs to", + "allOf": [{ "$ref": "#/components/schemas/Department" }] + }, + "types": { + "description": "All types under this main type", + "type": "array", + "items": { "$ref": "#/components/schemas/AdvertType" } + } + }, + "required": ["id", "title", "slug", "department", "types"] + }, + "GetAdvertMainTypes": { + "type": "object", + "properties": { + "mainTypes": { + "description": "List of all main advert types", + "type": "array", + "items": { "$ref": "#/components/schemas/AdvertMainType" } + }, + "paging": { + "description": "Paging information", + "allOf": [{ "$ref": "#/components/schemas/Paging" }] + } + }, + "required": ["mainTypes", "paging"] + }, + "GetAdvertType": { + "type": "object", + "properties": { + "type": { + "description": "The advert type", + "allOf": [{ "$ref": "#/components/schemas/AdvertType" }] + } + }, + "required": ["type"] + }, + "GetAdvertMainType": { + "type": "object", + "properties": { + "mainType": { + "description": "The main advert type", + "allOf": [{ "$ref": "#/components/schemas/AdvertMainType" }] + } + }, + "required": ["mainType"] + }, + "GetPdfRespone": { + "type": "object", + "properties": { + "content": { "type": "string", "description": "Base64 encoded PDF" } + }, + "required": ["content"] + }, + "GetPdfUrlResponse": { + "type": "object", + "properties": { "url": { "type": "string" } }, + "required": ["url"] } } } diff --git a/libs/clients/official-journal-of-iceland/public/src/lib/officialJournalOfIcelandClient.service.ts b/libs/clients/official-journal-of-iceland/public/src/lib/officialJournalOfIcelandClient.service.ts index 1ab4b33951c9..a600c48cb36e 100644 --- a/libs/clients/official-journal-of-iceland/public/src/lib/officialJournalOfIcelandClient.service.ts +++ b/libs/clients/official-journal-of-iceland/public/src/lib/officialJournalOfIcelandClient.service.ts @@ -7,11 +7,13 @@ import { GetDepartmentsRequest, GetInstitutionsRequest, GetMainCategoriesRequest, - GetAdvertTypesRequest, GetDepartmentByIdRequest, - GetAdvertTypeByIdRequest, GetCasesInProgressRequest, + GetTypeByIdRequest, + GetTypesRequest, + GetMainTypesRequest, } from '../../gen/fetch/apis' +import { GetAdvertMainTypes } from '../../gen/fetch' @Injectable() export class OfficialJournalOfIcelandClientService { @@ -33,12 +35,18 @@ export class OfficialJournalOfIcelandClientService { return this.api.getDepartments(params ?? {}) } - public async getAdvertTypeById(params: GetAdvertTypeByIdRequest) { - return this.api.getAdvertTypeById(params) + public async getAdvertTypeById(params: GetTypeByIdRequest) { + return this.api.getTypeById(params) } - public async getAdvertTypes(params: GetAdvertTypesRequest) { - return this.api.getAdvertTypes(params) + public async getAdvertMainTypes( + params: GetMainTypesRequest, + ): Promise { + return this.api.getMainTypes(params) + } + + public async getAdvertTypes(params: GetTypesRequest) { + return this.api.getTypes(params) } public async getMainCategories(params: GetMainCategoriesRequest) { diff --git a/libs/cms/src/lib/generated/contentfulTypes.d.ts b/libs/cms/src/lib/generated/contentfulTypes.d.ts index 24d4c5a81f65..2f49a4508978 100644 --- a/libs/cms/src/lib/generated/contentfulTypes.d.ts +++ b/libs/cms/src/lib/generated/contentfulTypes.d.ts @@ -3249,6 +3249,9 @@ export interface IOrganizationPageFields { /** Sitemap */ sitemap?: ISitemap | undefined + + /** Can be found in search results */ + canBeFoundInSearchResults?: boolean | undefined } export interface IOrganizationPage extends Entry { diff --git a/libs/cms/src/lib/models/organizationPage.model.ts b/libs/cms/src/lib/models/organizationPage.model.ts index 4ca0e4b3eb98..233b62efafff 100644 --- a/libs/cms/src/lib/models/organizationPage.model.ts +++ b/libs/cms/src/lib/models/organizationPage.model.ts @@ -86,6 +86,9 @@ export class OrganizationPage { @CacheField(() => OrganizationPageTopLevelNavigation, { nullable: true }) topLevelNavigation?: OrganizationPageTopLevelNavigation | null + + @Field(() => Boolean, { nullable: true }) + canBeFoundInSearchResults?: boolean } export const mapOrganizationPage = ({ @@ -144,5 +147,6 @@ export const mapOrganizationPage = ({ ? mapImage(fields.defaultHeaderImage) : undefined, topLevelNavigation, + canBeFoundInSearchResults: fields.canBeFoundInSearchResults ?? true, } } diff --git a/libs/cms/src/lib/search/importers/organizationPage.service.ts b/libs/cms/src/lib/search/importers/organizationPage.service.ts index 9a60a31bf272..984d64527323 100644 --- a/libs/cms/src/lib/search/importers/organizationPage.service.ts +++ b/libs/cms/src/lib/search/importers/organizationPage.service.ts @@ -15,7 +15,8 @@ export class OrganizationPageSyncService return entries.filter( (entry: Entry): entry is IOrganizationPage => entry.sys.contentType.sys.id === 'organizationPage' && - !!entry.fields.title, + !!entry.fields.title && + (entry.fields.canBeFoundInSearchResults ?? true), ) } diff --git a/libs/cms/src/lib/search/importers/organizationSubpage.service.ts b/libs/cms/src/lib/search/importers/organizationSubpage.service.ts index 7edf40d5a224..5113a03ff260 100644 --- a/libs/cms/src/lib/search/importers/organizationSubpage.service.ts +++ b/libs/cms/src/lib/search/importers/organizationSubpage.service.ts @@ -24,7 +24,10 @@ export class OrganizationSubpageSyncService !!entry.fields.slug && !!entry.fields.organizationPage?.fields?.slug && // Standalone organization pages have their own search, we don't want subpages there to be found in the global search - entry.fields.organizationPage.fields.theme !== 'standalone', + entry.fields.organizationPage.fields.theme !== 'standalone' && + // Subpage should not be searchable if the organization frontpage isn't searchable + (entry.fields.organizationPage.fields.canBeFoundInSearchResults ?? + true), ) } diff --git a/libs/feature-flags/src/lib/features.ts b/libs/feature-flags/src/lib/features.ts index 5cc65a03a541..858df10f9027 100644 --- a/libs/feature-flags/src/lib/features.ts +++ b/libs/feature-flags/src/lib/features.ts @@ -63,6 +63,9 @@ export enum Features { //Is social administration payment plan 2025 enabled? isServicePortalPaymentPlan2025Enabled = 'isServicePortalPaymentPlan2025Enabled', + //Is vehicle bulk mileage graph enabled? + isServicePortalVehicleBulkMileageSubdataPageEnabled = 'isServicePortalVehicleBulkMileageSubdataPageEnabled', + //Possible universities isUniversityOfAkureyriEnabled = 'isUniversityOfAkureyriEnabled', isAgriculturalUniversityOfIcelandEnabled = 'isAgriculturalUniversityOfIcelandEnabled', diff --git a/libs/judicial-system/types/src/lib/eventLog.ts b/libs/judicial-system/types/src/lib/eventLog.ts index fca7b91f81ea..5aa84c863960 100644 --- a/libs/judicial-system/types/src/lib/eventLog.ts +++ b/libs/judicial-system/types/src/lib/eventLog.ts @@ -15,6 +15,7 @@ export const eventTypes = Object.values(EventType) export enum DefendantEventType { SENT_TO_PRISON_ADMIN = 'SENT_TO_PRISON_ADMIN', + OPENED_BY_PRISON_ADMIN = 'OPENED_BY_PRISON_ADMIN', } export const defendantEventTypes = Object.values(DefendantEventType) diff --git a/libs/portals/my-pages/assets/src/lib/messages.ts b/libs/portals/my-pages/assets/src/lib/messages.ts index 3e6a455f3bac..e8ec6fdca6c3 100644 --- a/libs/portals/my-pages/assets/src/lib/messages.ts +++ b/libs/portals/my-pages/assets/src/lib/messages.ts @@ -292,10 +292,34 @@ export const vehicleMessage = defineMessages({ id: 'sp.vehicles:permno', defaultMessage: 'Fastanúmer', }, + viewChart: { + id: 'sp.vehicles:view-chart', + defaultMessage: 'Sjá línurit', + }, + viewTable: { + id: 'sp.vehicles:view-table', + defaultMessage: 'Sjá töflu', + }, + registrationHistory: { + id: 'sp.vehicles:registration-history', + defaultMessage: 'Skráningarsaga', + }, + viewRegistrationHistory: { + id: 'sp.vehicles:view-registration-history', + defaultMessage: 'Sjá alla skráningarsögu', + }, lastRegistration: { id: 'sp.vehicles:last-registration', defaultMessage: 'Síðasta skráning', }, + lastStatus: { + id: 'sp.vehicles:last-status', + defaultMessage: 'Síðasta staða', + }, + lastRegistered: { + id: 'sp.vehicles:last-registered', + defaultMessage: 'Síðast skráð', + }, verno: { id: 'sp.vehicles:verno', defaultMessage: 'Verksmiðjunúmer', @@ -518,6 +542,10 @@ export const vehicleMessage = defineMessages({ id: 'sp.vehicles:total-weight', defaultMessage: 'Heildarþyngd', }, + total: { + id: 'sp.vehicles:total', + defaultMessage: 'Samtals:', + }, width: { id: 'sp.vehicles:width', defaultMessage: 'Breidd', diff --git a/libs/portals/my-pages/assets/src/lib/navigation.ts b/libs/portals/my-pages/assets/src/lib/navigation.ts index 150c8dd15d07..ca8c691d26f2 100644 --- a/libs/portals/my-pages/assets/src/lib/navigation.ts +++ b/libs/portals/my-pages/assets/src/lib/navigation.ts @@ -45,11 +45,7 @@ export const assetsNavigation: PortalNavigationItem = { ], }, { - name: m.vehiclesLookup, - path: AssetsPaths.AssetsVehiclesLookup, - }, - { - name: m.vehiclesBulkMileage, + name: m.vehiclesRegisterMileage, path: AssetsPaths.AssetsVehiclesBulkMileage, children: [ { @@ -71,6 +67,11 @@ export const assetsNavigation: PortalNavigationItem = { }, ], }, + { + name: m.vehiclesLookup, + path: AssetsPaths.AssetsVehiclesLookup, + }, + { name: m.vehiclesHistory, path: AssetsPaths.AssetsVehiclesHistory, diff --git a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.tsx b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.tsx index c2964c3ee81a..7e58161e7feb 100644 --- a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.tsx +++ b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileage.tsx @@ -3,7 +3,6 @@ import { Box, Filter, FilterInput, - Inline, Checkbox, Pagination, Text, @@ -16,7 +15,6 @@ import { SAMGONGUSTOFA_SLUG, LinkButton, IntroWrapper, - formatDate, } from '@island.is/portals/my-pages/core' import { vehicleMessage as messages, vehicleMessage } from '../../lib/messages' import * as styles from './VehicleBulkMileage.css' @@ -41,6 +39,7 @@ const VehicleBulkMileage = () => { const [totalPages, setTotalPages] = useState(1) const [search, setSearch] = useState() const [filterValue, setFilterValue] = useState(false) + const [displayFilters, setDisplayFilters] = useState(false) const [vehicleListQuery, { data, loading, error, called }] = useVehiclesListLazyQuery() @@ -118,6 +117,12 @@ const VehicleBulkMileage = () => { const methods = useForm() + useEffect(() => { + if (!displayFilters) { + setDisplayFilters((data?.vehiclesListV3?.totalRecords ?? 0) > 10) + } + }, [data, displayFilters]) + return ( @@ -143,62 +148,68 @@ const VehicleBulkMileage = () => { } serviceProviderSlug={SAMGONGUSTOFA_SLUG} serviceProviderTooltip={formatMessage(m.vehiclesTooltip)} - buttonGroup={[ - , - , - ]} + buttonGroup={ + displayFilters + ? [ + , + , + ] + : undefined + } > - - { - console.log('clear') - }} - align="left" - reverse - filterInput={ - { - setSearch(search) - }} - name={formatMessage(m.searchLabel)} - placeholder={formatMessage(vehicleMessage.searchForPlate)} - /> - } - > - - - {formatMessage(m.filterBy)} - - setFilterValue(!filterValue)} - /> - - - + {displayFilters && ( + + { + setFilterValue(false) + }} + align="left" + reverse + filterInput={ + { + setSearch(search) + }} + name={formatMessage(m.searchLabel)} + placeholder={formatMessage(vehicleMessage.searchForPlate)} + /> + } + > + + + {formatMessage(m.filterBy)} + + setFilterValue(!filterValue)} + /> + + + + )} {error && !loading && } {!error && ( diff --git a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx index b4661d31d6a4..206acc4fbc76 100644 --- a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx +++ b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageRow.tsx @@ -10,18 +10,22 @@ import { import { useEffect, useState, useCallback, useMemo } from 'react' import { + EmptyTable, ExpandRow, NestedFullTable, formatDate, m, } from '@island.is/portals/my-pages/core' -import { AlertMessage, Box } from '@island.is/island-ui/core' import { vehicleMessage } from '../../lib/messages' import { VehicleBulkMileageSaveButton } from './VehicleBulkMileageSaveButton' import { InputController } from '@island.is/shared/form-fields' import * as styles from './VehicleBulkMileage.css' import { displayWithUnit } from '../../utils/displayWithUnit' import { isReadDateToday } from '../../utils/readDate' +import { AlertMessage, Box, Text } from '@island.is/island-ui/core' +import format from 'date-fns/format' +import { VehicleBulkMileageSubData } from './VehicleBulkMileageSubData' +import { Features, useFeatureFlagClient } from '@island.is/react/feature-flags' const ORIGIN_CODE = 'ISLAND.IS' @@ -41,6 +45,22 @@ export const VehicleBulkMileageRow = ({ vehicle }: Props) => { const [postError, setPostError] = useState(null) const [postStatus, setPostStatus] = useState('initial') + const [showSubdata, setShowSubdata] = useState(false) + const featureFlagClient = useFeatureFlagClient() + useEffect(() => { + const isFlagEnabled = async () => { + const ffEnabled = await featureFlagClient.getValue( + Features.isServicePortalVehicleBulkMileageSubdataPageEnabled, + false, + ) + if (ffEnabled) { + setShowSubdata(ffEnabled as boolean) + } + } + isFlagEnabled() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + const [ executeRegistrationsQuery, { data, loading, error, refetch: registrationsRefetch }, @@ -236,10 +256,17 @@ export const VehicleBulkMileageRow = ({ vehicle }: Props) => { onExpandCallback={executeRegistrationsQuery} data={[ { - value: vehicle.vehicleType, + value: ( + + {vehicle.vehicleType} + {vehicle.vehicleId} + + ), }, { - value: vehicle.vehicleId, + value: vehicle.lastMileageRegistration?.date + ? format(vehicle.lastMileageRegistration?.date, 'dd.MM.yyyy') + : '-', }, { value: vehicle.lastMileageRegistration?.mileage @@ -257,6 +284,8 @@ export const VehicleBulkMileageRow = ({ vehicle }: Props) => { control={control} id={vehicle.vehicleId} name={vehicle.vehicleId} + backgroundColor="blue" + placeholder="km" type="number" suffix=" km" thousandSeparator @@ -375,6 +404,20 @@ export const VehicleBulkMileageRow = ({ vehicle }: Props) => { type="error" message={formatMessage(vehicleMessage.mileageHistoryFetchFailed)} /> + ) : showSubdata ? ( + data?.vehiclesMileageRegistrationHistory ? ( + + ) : ( + + ) ) : ( > => { + const filteredData = data.mileageRegistrationHistory?.reduce< + Record + >((acc, current) => { + if (!current.mileage || !current.date || !current.originCode) { + return acc + } + + const currentDate = new Date(current.date).toISOString() + //01.01.1993-ISLAND.IS + const mashedKey = currentDate + '-' + current.originCode + //If the "mashed" key isn't in the key array, add it. + if (!Object.keys(acc).includes(mashedKey)) { + acc[mashedKey] = { date: currentDate, mileage: current.mileage } + } + return acc + }, {}) + + if (!filteredData) { + return [] + } + + return Object.values(filteredData) + .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) + .map((item) => ({ + date: format(new Date(item.date), 'dd.MM.yyyy'), + mileage: item.mileage, + })) +} + +export const VehicleBulkMileageSubData = ({ + vehicleId, + loading, + data, +}: Props) => { + const { formatMessage } = useLocale() + + const [displayMode, setDisplayMode] = useState<'chart' | 'table'>('table') + + const nestedTable = useMemo(() => { + if (!data) { + return [[]] + } + const tableData: Array> = [[]] + for (const mileageRegistration of data.mileageRegistrationHistory?.slice( + 0, + 5, + ) ?? []) { + if (mileageRegistration) { + tableData.push([ + formatDate(mileageRegistration.date), + mileageRegistration.originCode, + displayWithUnit(mileageRegistration.mileage, 'km', true), + ]) + } + } + + return tableData + }, [data]) + + return ( + + + + {formatMessage(vehicleMessage.registrationHistory)} + + + + {displayMode === 'table' ? ( + + ) : data.mileageRegistrationHistory ? ( + `${numberFormat(arg)} km`, + }} + /> + ) : undefined} + + + + + + + ) +} diff --git a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx index 0cc14273bbe8..e4bec2aafdf9 100644 --- a/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx +++ b/libs/portals/my-pages/assets/src/screens/VehicleBulkMileage/VehicleBulkMileageTable.tsx @@ -1,10 +1,12 @@ -import { Table as T, Box } from '@island.is/island-ui/core' +import { Table as T, Box, Text } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' import { EmptyTable, ExpandHeader } from '@island.is/portals/my-pages/core' import { vehicleMessage } from '../../lib/messages' import { useMemo } from 'react' import { VehicleType } from './types' import { VehicleBulkMileageRow } from './VehicleBulkMileageRow' +import { displayWithUnit } from '../../utils/displayWithUnit' +import { useFormContext } from 'react-hook-form' interface Props { vehicles: Array @@ -23,6 +25,35 @@ const VehicleBulkMileageTable = ({ vehicles, loading }: Props) => { )) }, [formatMessage, vehicles]) + const { getValues, watch } = useFormContext() + + const totalLastMileage = useMemo(() => { + if (!vehicles.length) { + return 0 + } + + return vehicles.reduce( + (totalMileage, vehicle) => + totalMileage + (vehicle.lastMileageRegistration?.mileage ?? 0), + 0, + ) + }, [vehicles]) + + const formValues = watch() + + const totalRegisteredMileage = useMemo(() => { + const values = getValues() + + return Object.values(values).reduce((total, mileage) => { + const number = Number.parseInt(mileage) + if (!number || Number.isNaN(number)) { + return total + } + return total + number + }, 0) + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [formValues]) + return (
@@ -32,13 +63,46 @@ const VehicleBulkMileageTable = ({ vehicles, loading }: Props) => { data={[ { value: '', printHidden: true }, { value: formatMessage(vehicleMessage.type) }, - { value: formatMessage(vehicleMessage.permno) }, - { value: formatMessage(vehicleMessage.lastRegistration) }, + { value: formatMessage(vehicleMessage.lastRegistered) }, + { value: formatMessage(vehicleMessage.lastStatus) }, { value: formatMessage(vehicleMessage.odometer) }, { value: '', printHidden: true }, ]} /> - {rows} + + {rows} + {rows.length > 0 && ( + + + + + {formatMessage(vehicleMessage.total)} + + + + + + + + + {displayWithUnit(totalLastMileage, 'km', true)} + + + + + + + {displayWithUnit(totalRegisteredMileage, 'km', true)} + + + + + )} + )} {(!rows.length || loading) && ( diff --git a/libs/portals/my-pages/assets/src/screens/VehicleMileage/VehicleMileage.tsx b/libs/portals/my-pages/assets/src/screens/VehicleMileage/VehicleMileage.tsx index 6b7aee95f6c7..9fd231e906cf 100644 --- a/libs/portals/my-pages/assets/src/screens/VehicleMileage/VehicleMileage.tsx +++ b/libs/portals/my-pages/assets/src/screens/VehicleMileage/VehicleMileage.tsx @@ -1,5 +1,5 @@ import { useParams } from 'react-router-dom' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { InputController } from '@island.is/shared/form-fields' import { useForm } from 'react-hook-form' import { @@ -21,6 +21,7 @@ import { SAMGONGUSTOFA_SLUG, IntroHeader, icelandLocalTime, + SimpleBarChart, } from '@island.is/portals/my-pages/core' import { isReadDateToday } from '../../utils/readDate' @@ -33,6 +34,9 @@ import { import { displayWithUnit } from '../../utils/displayWithUnit' import * as styles from './VehicleMileage.css' import { Problem } from '@island.is/react-spa/shared' +import { VehicleMileageDetail } from '@island.is/api/schema' +import format from 'date-fns/format' +import { Features, useFeatureFlagClient } from '@island.is/react/feature-flags' const ORIGIN_CODE = 'ISLAND.IS' @@ -44,6 +48,11 @@ interface FormData { odometerStatus: number } +interface ChartProps { + date: string + mileage: number +} + const VehicleMileage = () => { useNamespaces('sp.vehicles') const { formatMessage } = useLocale() @@ -56,6 +65,22 @@ const VehicleMileage = () => { reset, } = useForm() + const [showChart, setShowChart] = useState(false) + const featureFlagClient = useFeatureFlagClient() + useEffect(() => { + const isFlagEnabled = async () => { + const ffEnabled = await featureFlagClient.getValue( + Features.isServicePortalVehicleBulkMileageSubdataPageEnabled, + false, + ) + if (ffEnabled) { + setShowChart(ffEnabled as boolean) + } + } + isFlagEnabled() + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []) + const clearAll = () => { // Clear form, state and errors on success. setFormValue('') @@ -133,6 +158,43 @@ const VehicleMileage = () => { return } + const parseChartData = ( + data: Array, + ): Array> => { + const filteredData = data?.reduce>( + (acc, current) => { + if ( + !current.mileageNumber || + !current.readDate || + !current.originCode + ) { + return acc + } + + const currentDate = new Date(current.readDate).toISOString() + //01.01.1993-ISLAND.IS + const mashedKey = currentDate + '-' + current.originCode + //If the "mashed" key isn't in the key array, add it. + if (!Object.keys(acc).includes(mashedKey)) { + acc[mashedKey] = { date: currentDate, mileage: current.mileageNumber } + } + return acc + }, + {}, + ) + + if (!filteredData) { + return [] + } + + return Object.values(filteredData) + .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()) + .map((item) => ({ + date: format(new Date(item.date), 'dd.MM.yyyy'), + mileage: item.mileage, + })) + } + return ( <> @@ -312,49 +374,78 @@ const VehicleMileage = () => { )} {!loading && !error && hasData && ( - - - - - {formatMessage(m.overview)} - - - - - - - - - {formatMessage(m.date)} - - {formatMessage(messages.vehicleMileageRegistration)} - - - {formatMessage(messages.odometer)} - - - - - {details?.map((item, i) => ( - - - {item.readDate - ? icelandLocalTime(item.readDate) - : ''} - - - {item.originCode} - - - {displayWithUnit(item.mileageNumber, 'km', true)} - + <> + + + + + {formatMessage(m.overview)} + + + + + + + + + + {formatMessage(m.date)} + + + {formatMessage(messages.vehicleMileageRegistration)} + + + {formatMessage(messages.odometer)} + - ))} - - - - - + + + {details?.map((item, i) => ( + + + {item.readDate + ? icelandLocalTime(item.readDate) + : ''} + + + {item.originCode} + + + {displayWithUnit(item.mileageNumber, 'km', true)} + + + ))} + + + + + + {showChart && ( + + + + )} + )} diff --git a/libs/portals/my-pages/assets/src/utils/displayWithUnit.ts b/libs/portals/my-pages/assets/src/utils/displayWithUnit.ts index aa310d4e7d77..e313dd5cc7b5 100644 --- a/libs/portals/my-pages/assets/src/utils/displayWithUnit.ts +++ b/libs/portals/my-pages/assets/src/utils/displayWithUnit.ts @@ -5,8 +5,16 @@ export const displayWithUnit = ( unit: 'kg' | 'cc' | 'hö' | 'mm' | 'g/km' | 'km', formatNumber?: boolean, ) => { - if (value) { - return `${formatNumber ? numberFormat(+value) : value} ${unit}` + //Explict checking because 0 is falsy. + if (value === null || value === undefined) { + return '' } - return '' + + const number = +value + + if (Number.isNaN(number)) { + return '' + } + + return `${formatNumber ? numberFormat(number) : value} ${unit}` } diff --git a/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/SimpleBarChart.tsx b/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/SimpleBarChart.tsx new file mode 100644 index 000000000000..ba7bd5427c41 --- /dev/null +++ b/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/SimpleBarChart.tsx @@ -0,0 +1,135 @@ +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + Tooltip, + Legend, + ResponsiveContainer, +} from 'recharts' +import { + CustomizedAxisTick, + RenderLegend, + CustomTooltip, + YAxisLabel, +} from '../sharedChartComponents' +import { Box } from '@island.is/island-ui/core' +import * as styles from './styles.css' +import { theme } from '@island.is/island-ui/theme' + +interface Axis { + label?: string + datakey: string + valueFormat?: (arg: number) => string +} + +interface BarType { + datakey: string +} + +interface TooltipType { + labels: Record + valueFormat?: (arg: number) => string +} + +interface GraphDataProps { + title?: string + data: Array> + datakeys: Array + bars: Array + xAxis: Axis + yAxis: Axis + tooltip?: TooltipType +} + +export const SimpleBarChart = ({ + title, + data, + datakeys, + bars, + xAxis, + yAxis, + tooltip, +}: GraphDataProps) => { + return ( + + + + + + + + + } + padding={{ left: 30 }} + tickLine={false} + /> + } /> + + } + /> + + } + /> + {bars.map((item: BarType, index: number) => ( + + ))} + + + + + + + ) +} + +export default SimpleBarChart diff --git a/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/styles.css.ts b/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/styles.css.ts new file mode 100644 index 000000000000..a5c91da05a86 --- /dev/null +++ b/libs/portals/my-pages/core/src/components/Charts/SimpleBarChart/styles.css.ts @@ -0,0 +1,43 @@ +import { style } from '@vanilla-extract/css' + +export const frameWrapper = style({ + //height: '646px', + width: '100%', + minHeight: 124, + boxSizing: 'border-box', + position: 'relative', + background: 'transparent', + overflowX: 'scroll', +}) + +export const outerWrapper = style({ + width: '100%', + height: '100%', + borderTopLeftRadius: '8px', + borderTopRightRadius: '8px', + alignItems: 'center', +}) + +export const innerWrapper = style({ + minHeight: '80px', + borderTopLeftRadius: '8px', + borderTopRightRadius: '8px', +}) + +export const graphWrapper = style({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + width: '100%', + height: '100%', +}) + +export const graphParent = style({ + width: '100%', + height: '420px', +}) + +export const pie = style({ + width: '100%', + height: 'fit-content', +}) diff --git a/libs/portals/my-pages/core/src/components/Charts/charts.css.ts b/libs/portals/my-pages/core/src/components/Charts/charts.css.ts new file mode 100644 index 000000000000..e894605b5e69 --- /dev/null +++ b/libs/portals/my-pages/core/src/components/Charts/charts.css.ts @@ -0,0 +1,54 @@ +import { style } from '@vanilla-extract/css' + +export const list = style({ + color: '#00003C', + display: 'inline-flex', + alignItems: 'center', + fontFamily: 'IBM Plex Sans', + fontStyle: 'normal', + fontWeight: 'normal', + fontSize: '14px', + lineHeight: '24px', + flexWrap: 'nowrap', +}) + +export const dot = style({ + width: '12px', + height: '12px', + borderWidth: '3px', + borderStyle: 'solid', + borderRadius: '12px', + marginRight: '2px', + marginLeft: '8px', +}) + +export const listWrapper = style({ + display: 'flex', + flexDirection: 'row', + justifyContent: 'flex-start', + flexWrap: 'wrap', +}) + +export const wrapper = style({ + paddingTop: '37px', +}) + +export const title = style({ + fontFamily: 'IBM Plex Sans', + fontStyle: 'normal', + fontWeight: 600, + fontSize: '14px', + lineHeight: '16px', + color: '#00003C', + paddingBottom: '12px', +}) + +export const tooltip = style({ + display: 'inline-block', + backgroundColor: '#F2F7FF', + borderRadius: '8px', + padding: '20px', + maxWidth: '240px', + fontSize: '15px', + lineHeight: '20px', +}) diff --git a/libs/portals/my-pages/core/src/components/Charts/index.ts b/libs/portals/my-pages/core/src/components/Charts/index.ts new file mode 100644 index 000000000000..ac68afc50713 --- /dev/null +++ b/libs/portals/my-pages/core/src/components/Charts/index.ts @@ -0,0 +1 @@ +export * from './SimpleBarChart/SimpleBarChart' diff --git a/libs/portals/my-pages/core/src/components/Charts/sharedChartComponents.tsx b/libs/portals/my-pages/core/src/components/Charts/sharedChartComponents.tsx new file mode 100644 index 000000000000..9c76da7bc149 --- /dev/null +++ b/libs/portals/my-pages/core/src/components/Charts/sharedChartComponents.tsx @@ -0,0 +1,211 @@ +import React from 'react' +import * as styles from './charts.css' +import cn from 'classnames' +import { LegendProps, TooltipProps } from 'recharts' +import { Box, Text } from '@island.is/island-ui/core' +import { isDefined } from '@island.is/shared/utils' + +interface AxisTickProps { + x?: number + y?: number + className?: string + payload?: { value: string } + valueFormat?: (arg: number) => string +} + +interface CustomTooltipProps extends TooltipProps { + valueLabels?: Record + valueFormat?: (arg: number) => string +} + +export const CustomTooltip = ({ + payload, + active, + label, + valueLabels, + valueFormat, +}: CustomTooltipProps) => { + if (active && payload && payload.length) { + return ( + + {label} + {payload + .map((item, index) => { + if (!item.value) return null + + return ( + +
+ + {valueLabels && item.dataKey + ? valueLabels[item.dataKey] + : item.name} + : {valueFormat ? valueFormat(item.value) : item.value} + + + ) + }) + .filter(isDefined)} + + ) + } + + return null +} + +export const CustomizedAxisTick = ({ + x, + y, + className, + payload, +}: AxisTickProps) => { + const xAxis = className?.includes('xAxis') + return ( + + + {payload?.value} {xAxis} + + + ) +} + +export const CustomizedRightAxisTick = ({ x, y, payload }: AxisTickProps) => { + return ( + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore make web strict + + + { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore make web strict + payload.value + } + + + ) +} +interface CustomLegendProps extends LegendProps { + title?: string + labels?: Record +} +export const RenderLegend = ({ payload, title, labels }: CustomLegendProps) => { + if (!payload || !payload.values) { + return null + } + + return ( + + {[...payload.values()].map((item) => ( + + + {labels?.[item.value] ?? item.value} + + ))} + + ) +} + +// Define the type for the destructured props +type CustomLabelProps = { + cx: number + cy: number + midAngle: number + outerRadius: number + innerRadius: number + percent: number +} + +const RADIAN = Math.PI / 180 +export const renderCustomizedLabel = ({ + cx, + cy, + midAngle, + outerRadius, + innerRadius, + percent, +}: CustomLabelProps) => { + const radius = innerRadius + (outerRadius - innerRadius) * 1.2 + const x = cx + radius * Math.cos(-midAngle * RADIAN) + const y = cy + radius * Math.sin(-midAngle * RADIAN) + + return ( + outerRadius ? 'middle' : 'end'} + dominantBaseline="central" + fontSize="12px" + > + {`${(percent * 100).toFixed(0)}%`} + + ) +} + +interface yAxisLabelProps { + label?: string + labelRight?: string + rightPadding?: number +} +export const YAxisLabel = ({ + label, + labelRight, + rightPadding = 0, +}: yAxisLabelProps) => { + return ( + + {label && {label}} + {labelRight && {labelRight}} + + ) +} + +export const COLORS = [ + '#FFF066', + '#FF99B9', + '#C3ABD9', + '#D799C7', + '#99F4EA', + '#B5B6EC', + '#FF0050', + '#00B39E', + '#0061FF', + '#E6CF00', + '#6A2EA0', + '#00E4CA', + '#FFFCE0', + '#9A0074', + '#99C0FF', +] + +export default RenderLegend diff --git a/libs/portals/my-pages/core/src/components/EmptyTable/EmptyTable.tsx b/libs/portals/my-pages/core/src/components/EmptyTable/EmptyTable.tsx index 3ed19c1b5a44..1b12a3a6efe7 100644 --- a/libs/portals/my-pages/core/src/components/EmptyTable/EmptyTable.tsx +++ b/libs/portals/my-pages/core/src/components/EmptyTable/EmptyTable.tsx @@ -1,4 +1,4 @@ -import { Box, LoadingDots, Text } from '@island.is/island-ui/core' +import { Box, BoxProps, LoadingDots, Text } from '@island.is/island-ui/core' import { useLocale } from '@island.is/localization' import { MessageDescriptor } from 'react-intl' import * as styles from './EmptyTable.css' @@ -6,9 +6,14 @@ import * as styles from './EmptyTable.css' type Props = { message?: string | MessageDescriptor loading?: boolean + background?: BoxProps['background'] } -export const EmptyTable: React.FC = ({ message, loading }) => { +export const EmptyTable: React.FC = ({ + message, + loading, + background, +}) => { const { formatMessage } = useLocale() const msg = message @@ -18,7 +23,7 @@ export const EmptyTable: React.FC = ({ message, loading }) => { : null return ( - + {loading && } {!loading && message && ( diff --git a/libs/portals/my-pages/core/src/index.ts b/libs/portals/my-pages/core/src/index.ts index f87e890391dc..ddb3535f0f7d 100644 --- a/libs/portals/my-pages/core/src/index.ts +++ b/libs/portals/my-pages/core/src/index.ts @@ -9,6 +9,7 @@ export * from './components/EmptyState/EmptyState' export * from './components/EmptyState/EmptyImage' export * from './components/EmptyState/EmptyImgSmall' export * from './components/Menu/Menu' +export * from './components/Charts' export * from './components/Modal/Modal' export * from './components/ConfirmationModal/ConfirmationModal' export * from './components/UserInfoLine/UserInfoLine' diff --git a/libs/portals/my-pages/core/src/lib/messages.ts b/libs/portals/my-pages/core/src/lib/messages.ts index eb534bda0c73..3f30f63dd7dd 100644 --- a/libs/portals/my-pages/core/src/lib/messages.ts +++ b/libs/portals/my-pages/core/src/lib/messages.ts @@ -313,6 +313,10 @@ export const m = defineMessages({ id: 'service.portal:vehicles-bulk-mileage', defaultMessage: 'Magnskráning kílómetrastöðu', }, + vehiclesRegisterMileage: { + id: 'service.portal:vehicles-register-mileage', + defaultMessage: 'Skrá kílómetrastöðu', + }, vehiclesBulkMileageUpload: { id: 'service.portal:vehicles-bulk-mileage-upload', defaultMessage: 'Magnskrá með skjali', diff --git a/libs/portals/my-pages/health/src/lib/messages.ts b/libs/portals/my-pages/health/src/lib/messages.ts index d22f5798bed3..67c32b9383c0 100644 --- a/libs/portals/my-pages/health/src/lib/messages.ts +++ b/libs/portals/my-pages/health/src/lib/messages.ts @@ -1024,10 +1024,22 @@ export const messages = defineMessages({ defaultMessage: 'Textareitur má ekki vera tómur sé þessi valkostur valinn. ', }, + organMinor: { + id: 'sp.health:organ-minor', + defaultMessage: 'Til að geta gerst líffæragjafi þarftu að vera 18 ára.', + }, + organTemporaryNationalId: { + id: 'sp.health:organ-temporary-national-id', + defaultMessage: 'Líffæragjöf er ekki heimiluð á kerfiskennitölur.', + }, other: { id: 'sp.health:other-lower-case', defaultMessage: 'annað', }, + otherPascalCase: { + id: 'sp.health:other', + defaultMessage: 'Annað', + }, registrationComplete: { id: 'sp.health:registration-complete', defaultMessage: 'Skráning tókst', diff --git a/libs/portals/my-pages/health/src/module.tsx b/libs/portals/my-pages/health/src/module.tsx index 5d9cc4fdfccd..2f6f92805030 100644 --- a/libs/portals/my-pages/health/src/module.tsx +++ b/libs/portals/my-pages/health/src/module.tsx @@ -59,7 +59,7 @@ const OrganDonation = lazy(() => ) const OrganDonationRegistration = lazy(() => - import('./screens/OrganDonationRegistration/RegistrationForm'), + import('./screens/OrganDonation/components/RegistrationForm'), ) const Vaccinations = lazy(() => diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.css.ts b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.css.ts new file mode 100644 index 000000000000..4dfc4127851b --- /dev/null +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.css.ts @@ -0,0 +1,32 @@ +import { style, keyframes } from '@vanilla-extract/css' +import { theme } from '@island.is/island-ui/theme' + +export const buttonContainer = style({ + gap: theme.spacing[2], +}) + +const fadeIn = keyframes({ + from: { + opacity: 0, + }, + to: { + opacity: 1, + }, +}) + +const fadeOut = keyframes({ + from: { + opacity: 1, + }, + to: { + opacity: 0, + }, +}) + +export const commentVisible = style({ + animation: `${fadeIn} 0.5s forwards`, +}) + +export const commentHidden = style({ + animation: `${fadeOut} 0.5s forwards`, +}) diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.graphql b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.graphql index d120a592b167..6790da16ee2b 100644 --- a/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.graphql +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.graphql @@ -10,21 +10,8 @@ query getDonorStatus($locale: String) { } comment } - } - } -} - -query getOrgansList($locale: String) { - healthDirectorateOrganDonation(locale: $locale) { - donor { - isDonor - limitations { - hasLimitations - limitedOrgansList { - id - name - } - } + isMinor + isTemporaryResident } organList { id diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.tsx b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.tsx index 7efcd493e3b5..7ef00c370fb5 100644 --- a/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.tsx +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/OrganDonation.tsx @@ -1,15 +1,17 @@ +import { Box, Button, Text } from '@island.is/island-ui/core' import { useLocale, useNamespaces } from '@island.is/localization' import { ActionCard, CardLoader, - IntroHeader, + IntroWrapper, LinkResolver, } from '@island.is/portals/my-pages/core' +import { Problem } from '@island.is/react-spa/shared' import { messages as m } from '../../lib/messages' -import { Button, Box, Text } from '@island.is/island-ui/core' import { HealthPaths } from '../../lib/paths' -import { Problem } from '@island.is/react-spa/shared' import { useGetDonorStatusQuery } from './OrganDonation.generated' +import { NoAccess } from './components/NoAccess' +import { getOrganText } from './helpers/textMapper' const OrganDonation = () => { useNamespaces('sp.health') @@ -22,30 +24,39 @@ const OrganDonation = () => { }, }) const donorStatus = data?.healthDirectorateOrganDonation.donor - const cardText: string = donorStatus?.isDonor - ? donorStatus?.limitations?.hasLimitations - ? [ - formatMessage(m.iAmOrganDonorWithExceptionsText), - donorStatus?.limitations.limitedOrgansList - ?.map((organ) => organ.name) - .join(', '), - ].join(' ') + '.' - : formatMessage(m.iAmOrganDonorText) - : formatMessage(m.iAmNotOrganDonorText) + const isMinor = donorStatus?.isMinor + const isTemporaryResident = donorStatus?.isTemporaryResident + + const comment = donorStatus?.limitations?.comment + + const allLimitations: Array = + donorStatus?.limitations?.limitedOrgansList?.map((item) => item.name) ?? [] - const heading = donorStatus?.isDonor - ? donorStatus.limitations?.hasLimitations - ? formatMessage(m.iAmOrganDonorWithExceptions) - : formatMessage(m.iAmOrganDonor) - : formatMessage(m.iAmNotOrganDonor) + if (comment !== undefined && comment !== null && comment.length > 0) { + allLimitations.push(comment) + } + + const texts = getOrganText( + donorStatus?.isDonor ?? true, + donorStatus?.limitations?.hasLimitations ?? false, + { + iAmOrganDonorWithExceptionsText: formatMessage( + m.iAmOrganDonorWithExceptionsText, + ), + iAmNotOrganDonorText: formatMessage(m.iAmOrganDonorText), + iAmOrganDonorText: formatMessage(m.iAmNotOrganDonorText), + iAmOrganDonorWithExceptions: formatMessage(m.iAmOrganDonorWithExceptions), + iAmOrganDonor: formatMessage(m.iAmOrganDonor), + iAmNotOrganDonor: formatMessage(m.iAmNotOrganDonor), + }, + allLimitations, + ) return ( - - - + { - - + , + ]} + > {loading && ( )} - {!error && !loading && donorStatus !== null && ( - - - {formatMessage(m.takeOnOrganDonation)} - - - + {!error && + !loading && + !isMinor && + !isTemporaryResident && + donorStatus !== null && ( + + + {formatMessage(m.takeOnOrganDonation)} + + + + )} + {!error && !loading && (isMinor || isTemporaryResident) && ( + )} {error && !loading && } {!error && !loading && data === null && ( )} - + ) } diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/components/Limitations.tsx b/libs/portals/my-pages/health/src/screens/OrganDonation/components/Limitations.tsx new file mode 100644 index 000000000000..ab0e895e30a3 --- /dev/null +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/components/Limitations.tsx @@ -0,0 +1,113 @@ +import { HealthDirectorateOrganDonationOrgan } from '@island.is/api/schema' +import { + Box, + Checkbox, + Divider, + GridColumn, + GridContainer, + GridRow, + Input, + Stack, +} from '@island.is/island-ui/core' +import { useLocale, useNamespaces } from '@island.is/localization' +import { useState } from 'react' +import { messages } from '../../../lib/messages' +import * as styles from '../OrganDonation.css' + +interface LimitationsProps { + data: HealthDirectorateOrganDonationOrgan[] + selected?: string[] | null + exceptionComment?: string +} + +const Limitations = ({ + data, + selected, + exceptionComment, +}: LimitationsProps) => { + useNamespaces('sp.health') + const { formatMessage } = useLocale() + const [checked, setChecked] = useState>(selected ?? []) + const [comment, setComment] = useState(exceptionComment ?? '') + + const handleCheckboxChange = (id: string, isChecked: boolean) => { + setChecked((prevState) => + isChecked ? [...prevState, id] : prevState.filter((item) => item !== id), + ) + } + + return ( + + + + + {data?.map((y, yi) => ( + + + handleCheckboxChange(y.id ?? '', e.target.checked) + } + checked={checked.includes(y.id ?? '')} + /> + + ))} + + { + setComment(e.target.value) + handleCheckboxChange('other', e.target.checked) + }} + checked={checked.includes('other')} + /> + + + + {checked.includes('other') && ( + + + + + setComment(e.target.value)} + value={comment} + /> + + + + + )} + + ) +} + +export default Limitations diff --git a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Loader.tsx b/libs/portals/my-pages/health/src/screens/OrganDonation/components/Loader.tsx similarity index 100% rename from libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Loader.tsx rename to libs/portals/my-pages/health/src/screens/OrganDonation/components/Loader.tsx index b907c382c105..59bf49245f20 100644 --- a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Loader.tsx +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/components/Loader.tsx @@ -1,6 +1,6 @@ -import React from 'react' import { Box, SkeletonLoader, Stack } from '@island.is/island-ui/core' import { useIsMobile } from '@island.is/portals/my-pages/core' +import React from 'react' interface Props { amount?: number diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/components/NoAccess.tsx b/libs/portals/my-pages/health/src/screens/OrganDonation/components/NoAccess.tsx new file mode 100644 index 000000000000..369589995cd1 --- /dev/null +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/components/NoAccess.tsx @@ -0,0 +1,13 @@ +import { AlertMessage, GridColumn, GridRow } from '@island.is/island-ui/core' + +export const NoAccess = ({ text }: { text: string }) => { + return ( + + + + + + ) +} + +export default NoAccess diff --git a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/RegistrationForm.tsx b/libs/portals/my-pages/health/src/screens/OrganDonation/components/RegistrationForm.tsx similarity index 77% rename from libs/portals/my-pages/health/src/screens/OrganDonationRegistration/RegistrationForm.tsx rename to libs/portals/my-pages/health/src/screens/OrganDonation/components/RegistrationForm.tsx index 6ef3db623dcf..4b4db5a87fcf 100644 --- a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/RegistrationForm.tsx +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/components/RegistrationForm.tsx @@ -1,58 +1,68 @@ import { Box, + Button, RadioButton, Stack, Text, - Button, toast, - LoadingDots, } from '@island.is/island-ui/core' import { useLocale, useNamespaces } from '@island.is/localization' import { - IntroHeader, + IntroWrapper, LinkResolver, m as coreMessages, } from '@island.is/portals/my-pages/core' -import { messages } from '../..' -import { useEffect, useState } from 'react' -import React from 'react' -import { HealthPaths } from '../../lib/paths' -import * as styles from './OrganDonationRegistration.css' -import Limitations from './Limitations' +import React, { useEffect, useState } from 'react' import { useNavigate } from 'react-router-dom' +import { messages } from '../../..' +import { HealthPaths } from '../../../lib/paths' +import * as styles from '../OrganDonation.css' import { - useGetOrgansListQuery, + useGetDonorStatusQuery, useUpdateOrganDonationInfoMutation, -} from '../OrganDonation/OrganDonation.generated' +} from '../OrganDonation.generated' +import Limitations from './Limitations' import { Loader } from './Loader' +import { NoAccess } from './NoAccess' const OPT_IN = 'opt-in' const OPT_IN_EXCEPTIONS = 'opt-in-exceptions' const OPT_OUT = 'opt-out' -export const Form2 = () => { +export const OrganRegistrationForm = () => { useNamespaces('sp.health') const { formatMessage, lang } = useLocale() const navigate = useNavigate() - const { data, loading } = useGetOrgansListQuery({ + const { data, loading } = useGetDonorStatusQuery({ variables: { locale: lang }, fetchPolicy: 'no-cache', }) const isDonor = data?.healthDirectorateOrganDonation.donor?.isDonor + const isMinor = data?.healthDirectorateOrganDonation.donor?.isMinor + const isTemporaryResident = + data?.healthDirectorateOrganDonation.donor?.isTemporaryResident const hasLimitations = data?.healthDirectorateOrganDonation.donor?.limitations?.hasLimitations const allLimitations = data?.healthDirectorateOrganDonation.organList + const exceptionComment = + data?.healthDirectorateOrganDonation.donor?.limitations?.comment + const selectedLimitations = data?.healthDirectorateOrganDonation.donor?.limitations?.limitedOrgansList?.map( (item) => item.id, ) + + const updatedLimitations = selectedLimitations + ? [...selectedLimitations, ...(exceptionComment?.length ? ['other'] : [])] + : [] const donorStatus = isDonor ? hasLimitations ? OPT_IN_EXCEPTIONS : OPT_IN : OPT_OUT + const [radioValue, setRadioValue] = useState(donorStatus) const [updateDonorStatus, { loading: submitLoading }] = @@ -76,8 +86,8 @@ export const Form2 = () => { e.preventDefault() const formData = new FormData(e.currentTarget) const data = Object.fromEntries(formData.entries()) - const idKey = 'selected-limitations-' + const otherLimitations = data['otherLimitatons'].toString() const limitations = Object.keys(data) .filter((key) => key.includes(idKey)) .map((key) => key.replace(idKey, '').toLowerCase()) @@ -87,6 +97,7 @@ export const Form2 = () => { input: { isDonor: radioValue === OPT_IN || radioValue === OPT_IN_EXCEPTIONS, organLimitations: radioValue === OPT_IN_EXCEPTIONS ? limitations : [], + comment: otherLimitations, }, locale: lang, }, @@ -94,16 +105,24 @@ export const Form2 = () => { } return ( - - + {formatMessage(messages.changeTake)} {loading && } - {!loading && ( + {!loading && (isMinor || isTemporaryResident) && ( + + )} + {!loading && !isMinor && !isTemporaryResident && ( { radioValue === OPT_IN_EXCEPTIONS && ( )} @@ -187,8 +207,8 @@ export const Form2 = () => { )} - + ) } -export default Form2 +export default OrganRegistrationForm diff --git a/libs/portals/my-pages/health/src/screens/OrganDonation/helpers/textMapper.ts b/libs/portals/my-pages/health/src/screens/OrganDonation/helpers/textMapper.ts new file mode 100644 index 000000000000..7793edbf10bf --- /dev/null +++ b/libs/portals/my-pages/health/src/screens/OrganDonation/helpers/textMapper.ts @@ -0,0 +1,27 @@ +export const getOrganText = ( + isDonor: boolean, + hasLimitations: boolean, + texts: { + iAmOrganDonorWithExceptionsText: string + iAmOrganDonorText: string + iAmNotOrganDonorText: string + iAmOrganDonorWithExceptions: string + iAmOrganDonor: string + iAmNotOrganDonor: string + }, + limitations: string[], +) => { + const limitationText = hasLimitations + ? texts.iAmOrganDonorWithExceptionsText + ' ' + limitations.join(', ') + : texts.iAmOrganDonorText + + const cardText: string = isDonor ? limitationText : texts.iAmNotOrganDonorText + + const heading = isDonor + ? hasLimitations + ? texts.iAmOrganDonorWithExceptions + : texts.iAmOrganDonor + : texts.iAmNotOrganDonor + + return { cardText, heading } +} diff --git a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Limitations.tsx b/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Limitations.tsx deleted file mode 100644 index e625cdf7a3a4..000000000000 --- a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/Limitations.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { Box, Checkbox, Divider, Stack } from '@island.is/island-ui/core' -import React, { useState } from 'react' -import { useNamespaces } from '@island.is/localization' -import { HealthDirectorateOrganDonationOrgan } from '@island.is/api/schema' - -interface LimitationsProps { - data: HealthDirectorateOrganDonationOrgan[] - selected?: string[] | null -} - -const Limitations = ({ data, selected }: LimitationsProps) => { - useNamespaces('sp.health') - const [checked, setChecked] = useState>(selected ?? []) - const handleCheckboxChange = (id: string, isChecked: boolean) => { - setChecked((prevState) => - isChecked ? [...prevState, id] : prevState.filter((item) => item !== id), - ) - } - - //const input = data.find((x) => x.type === 'input') - - return ( - - - - - {data?.map( - (y, yi) => ( - // y.type === 'checkbox' && ( - - - - handleCheckboxChange(y.id ?? '', e.target.checked) - } - checked={checked.includes(y.id ?? '')} - /> - - ), - // ), - )} - - - {/* This is commented out because of feature that was removed. May be included later on */} - {/* {input && checked.includes(input.name.toLowerCase()) && ( - - - - - - - - - - )} */} - - ) -} - -export default Limitations diff --git a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/OrganDonationRegistration.css.ts b/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/OrganDonationRegistration.css.ts deleted file mode 100644 index e985fe3863ac..000000000000 --- a/libs/portals/my-pages/health/src/screens/OrganDonationRegistration/OrganDonationRegistration.css.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { style } from '@vanilla-extract/css' -import { theme } from '@island.is/island-ui/theme' - -export const buttonContainer = style({ - gap: theme.spacing[2], -})