From a5ac1dc2cc4efec5f5b8152f36449fe4bb481161 Mon Sep 17 00:00:00 2001 From: unakb Date: Fri, 18 Oct 2024 15:32:52 +0000 Subject: [PATCH 01/17] feat(j-s): Allow judge to confirm defender and civil claimant choices --- .../dto/updateCivilClaimant.input.ts | 5 + .../defendant/dto/updateDefendant.input.ts | 5 + .../defendant/models/civilClaimant.model.ts | 3 + .../defendant/models/defendant.model.ts | 3 + .../20241015110312-update-defendant.js | 46 ++++++++ .../20241018105400-update-civil-claimant.js | 26 +++++ .../modules/defendant/defendant.service.ts | 10 ++ .../defendant/dto/createDefendant.dto.ts | 5 + .../defendant/dto/updateCivilClaimant.dto.ts | 5 + .../defendant/dto/updateDefendant.dto.ts | 5 + .../defendant/models/civilClaimant.model.ts | 7 ++ .../defendant/models/defendant.model.ts | 4 + .../subpoena/dto/updateSubpoena.dto.ts | 7 +- .../app/modules/subpoena/subpoena.service.ts | 11 ++ .../src/app/modules/cases/case.service.ts | 4 + .../src/components/FormProvider/case.graphql | 2 + .../Advocates/Advocates.strings.ts | 97 ++++++++++++++++ .../Advocates/SelectCivilClaimantAdvocate.tsx | 107 ++++++++++++++---- .../Indictments/Advocates/SelectDefender.tsx | 87 +++++++++++++- .../judicial-system/web/src/utils/validate.ts | 2 + .../xrd-api/src/app/app.service.ts | 23 +++- 21 files changed, 432 insertions(+), 32 deletions(-) create mode 100644 apps/judicial-system/backend/migrations/20241015110312-update-defendant.js create mode 100644 apps/judicial-system/backend/migrations/20241018105400-update-civil-claimant.js diff --git a/apps/judicial-system/api/src/app/modules/defendant/dto/updateCivilClaimant.input.ts b/apps/judicial-system/api/src/app/modules/defendant/dto/updateCivilClaimant.input.ts index 5c00a5bfe44c..7e13fa8ebccd 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/dto/updateCivilClaimant.input.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/dto/updateCivilClaimant.input.ts @@ -61,4 +61,9 @@ export class UpdateCivilClaimantInput { @IsOptional() @Field(() => Boolean, { nullable: true }) readonly caseFilesSharedWithSpokesperson?: boolean + + @Allow() + @IsOptional() + @Field(() => Boolean, { nullable: true }) + readonly isSpokespersonConfirmed?: boolean } diff --git a/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts b/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts index 09637837e462..50857a9b32ee 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts @@ -94,4 +94,9 @@ export class UpdateDefendantInput { @IsOptional() @Field(() => SubpoenaType, { nullable: true }) readonly subpoenaType?: SubpoenaType + + @Allow() + @IsOptional() + @Field(() => Boolean, { nullable: true }) + readonly isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/api/src/app/modules/defendant/models/civilClaimant.model.ts b/apps/judicial-system/api/src/app/modules/defendant/models/civilClaimant.model.ts index da90d7d1834f..a2298adf5abd 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/models/civilClaimant.model.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/models/civilClaimant.model.ts @@ -43,4 +43,7 @@ export class CivilClaimant { @Field(() => Boolean, { nullable: true }) readonly caseFilesSharedWithSpokesperson?: boolean + + @Field(() => Boolean, { nullable: true }) + readonly isSpokespersonConfirmed?: boolean } 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 f1e16bf6a8aa..7388a15a11f1 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 @@ -89,4 +89,7 @@ export class Defendant { @Field(() => [Subpoena], { nullable: true }) readonly subpoenas?: Subpoena[] + + @Field(() => Boolean, { nullable: true }) + readonly isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/backend/migrations/20241015110312-update-defendant.js b/apps/judicial-system/backend/migrations/20241015110312-update-defendant.js new file mode 100644 index 000000000000..684e85916d13 --- /dev/null +++ b/apps/judicial-system/backend/migrations/20241015110312-update-defendant.js @@ -0,0 +1,46 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.sequelize.transaction((t) => + Promise.all([ + queryInterface.addColumn( + 'defendant', + 'is_defender_choice_confirmed', + { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + { transaction: t }, + ), + queryInterface.addColumn( + 'defendant', + 'case_files_shared_with_defender', + { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + { transaction: t }, + ), + ]), + ) + }, + down: (queryInterface) => { + return queryInterface.sequelize.transaction((t) => + Promise.all([ + queryInterface.removeColumn( + 'defendant', + 'is_defender_choice_confirmed', + { + transaction: t, + }, + ), + queryInterface.removeColumn( + 'defendant', + 'case_files_shared_with_defender', + { + transaction: t, + }, + ), + ]), + ) + }, +} diff --git a/apps/judicial-system/backend/migrations/20241018105400-update-civil-claimant.js b/apps/judicial-system/backend/migrations/20241018105400-update-civil-claimant.js new file mode 100644 index 000000000000..e8cc6f8f09a4 --- /dev/null +++ b/apps/judicial-system/backend/migrations/20241018105400-update-civil-claimant.js @@ -0,0 +1,26 @@ +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.sequelize.transaction((t) => + queryInterface.addColumn( + 'civil_claimant', + 'is_spokesperson_confirmed', + { + type: Sequelize.BOOLEAN, + allowNull: true, + }, + { transaction: t }, + ), + ) + }, + down: (queryInterface) => { + return queryInterface.sequelize.transaction((t) => + queryInterface.removeColumn( + 'civil_claimant', + 'is_spokesperson_confirmed', + { + transaction: t, + }, + ), + ) + }, +} 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 f323632f2476..77e2ee238e25 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 @@ -21,6 +21,7 @@ import type { User } from '@island.is/judicial-system/types' import { CaseState, CaseType, + isDistrictCourtUser, NotificationType, } from '@island.is/judicial-system/types' @@ -200,7 +201,16 @@ export class DefendantService { caseId: string, defendantNationalId: string, update: UpdateDefendantDto, + user?: User, ): Promise { + const isDefenderChoiceConfirmed = Boolean( + user && + isDistrictCourtUser(user) && + update.isDefenderChoiceConfirmed === true, + ) + + update = { ...update, isDefenderChoiceConfirmed: isDefenderChoiceConfirmed } + const [numberOfAffectedRows, defendants] = await this.defendantModel.update( update, { diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts index eee5ea58da99..4ea4d1380836 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts @@ -59,4 +59,9 @@ export class CreateDefendantDto { @IsEnum(DefenderChoice) @ApiPropertyOptional({ enum: DefenderChoice }) readonly defenderChoice?: DefenderChoice + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateCivilClaimant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateCivilClaimant.dto.ts index 4ad6cb1ce29c..3f85ec624a7f 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateCivilClaimant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateCivilClaimant.dto.ts @@ -52,4 +52,9 @@ export class UpdateCivilClaimantDto { @IsBoolean() @ApiPropertyOptional({ type: Boolean }) readonly caseFilesSharedWithSpokesperson?: boolean + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly isSpokespersonConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts index 5c51ae0d2813..65724815320c 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts @@ -108,4 +108,9 @@ export class UpdateDefendantDto { @IsString() @ApiPropertyOptional({ type: String }) readonly requestedDefenderName?: string + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/models/civilClaimant.model.ts b/apps/judicial-system/backend/src/app/modules/defendant/models/civilClaimant.model.ts index 308ba8820ce8..08aadc3034ee 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/models/civilClaimant.model.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/models/civilClaimant.model.ts @@ -110,4 +110,11 @@ export class CivilClaimant extends Model { }) @ApiPropertyOptional({ type: Boolean }) caseFilesSharedWithSpokesperson?: boolean + + @Column({ + type: DataType.BOOLEAN, + allowNull: true, + }) + @ApiPropertyOptional({ type: Boolean }) + isSpokespersonConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts index b8c66a3bc14b..03a417c3ed6c 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts @@ -153,4 +153,8 @@ export class Defendant extends Model { @Column({ type: DataType.STRING, allowNull: true }) @ApiPropertyOptional({ type: String }) requestedDefenderName?: string + + @Column({ type: DataType.BOOLEAN, allowNull: true }) + @ApiPropertyOptional({ type: Boolean }) + isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts index 5132ae3fb5d2..80603c97865d 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts @@ -1,4 +1,4 @@ -import { IsEnum, IsOptional, IsString } from 'class-validator' +import { IsBoolean, IsEnum, IsOptional, IsString } from 'class-validator' import { ApiPropertyOptional } from '@nestjs/swagger' @@ -64,4 +64,9 @@ export class UpdateSubpoenaDto { @IsString() @ApiPropertyOptional({ type: String }) readonly requestedDefenderName?: string + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly isDefenderChoiceConfirmed?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts index c476d085e835..dd593c0ca0f3 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/subpoena.service.ts @@ -16,6 +16,7 @@ import { LOGGER_PROVIDER } from '@island.is/logging' import { CaseFileCategory, + isDistrictCourtUser, isTrafficViolationCase, type User, } from '@island.is/judicial-system/types' @@ -85,6 +86,7 @@ export class SubpoenaService { subpoena: Subpoena, update: UpdateSubpoenaDto, transaction?: Transaction, + user?: User, ): Promise { const { defenderChoice, @@ -95,6 +97,7 @@ export class SubpoenaService { requestedDefenderChoice, requestedDefenderNationalId, requestedDefenderName, + isDefenderChoiceConfirmed, } = update const [numberOfAffectedRows] = await this.subpoenaModel.update(update, { @@ -104,6 +107,13 @@ export class SubpoenaService { }) let defenderAffectedRows = 0 + // This is added because the defender choice can only be confirmed by + // a district court user. If someone else updates it then we want to + // reset the existing confirmation (unless a court user is updating it) + const confirmDefenderChoice = Boolean( + user && isDistrictCourtUser(user) && isDefenderChoiceConfirmed === true, + ) + if ( defenderChoice || defenderNationalId || @@ -119,6 +129,7 @@ export class SubpoenaService { requestedDefenderChoice, requestedDefenderNationalId, requestedDefenderName, + isDefenderChoiceConfirmed: confirmDefenderChoice, } const [defenderUpdateAffectedRows] = await this.defendantModel.update( diff --git a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts index 03ea716e60d8..885705224044 100644 --- a/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts +++ b/apps/judicial-system/digital-mailbox-api/src/app/modules/cases/case.service.ts @@ -137,6 +137,10 @@ export class CaseService { } const defenderChoice = { + ...defenderAssignment, + defenderName: chosenLawyer?.Name, + defenderEmail: chosenLawyer?.Email, + defenderPhoneNumber: chosenLawyer?.Phone, requestedDefenderChoice: defenderAssignment.defenderChoice, requestedDefenderNationalId: defenderAssignment.defenderNationalId, requestedDefenderName: chosenLawyer?.Name, diff --git a/apps/judicial-system/web/src/components/FormProvider/case.graphql b/apps/judicial-system/web/src/components/FormProvider/case.graphql index a8afe466ec62..da1dd3d6de76 100644 --- a/apps/judicial-system/web/src/components/FormProvider/case.graphql +++ b/apps/judicial-system/web/src/components/FormProvider/case.graphql @@ -25,6 +25,7 @@ query Case($input: CaseQueryInput!) { requestedDefenderChoice requestedDefenderNationalId requestedDefenderName + isDefenderChoiceConfirmed serviceRequirement verdictViewDate verdictAppealDeadline @@ -340,6 +341,7 @@ query Case($input: CaseQueryInput!) { spokespersonEmail spokespersonPhoneNumber caseFilesSharedWithSpokesperson + isSpokespersonConfirmed } civilDemands hasCivilClaims diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index ac7bfc63dc14..c685e6b3f41b 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -25,6 +25,32 @@ export const strings = defineMessages({ description: 'Notaður sem texti fyrir takka þegar ákærðu óska ekki eftir verjanda í dómaraflæði í ákærum. ', }, + confirmDefenderChoice: { + id: 'judicial.system.core:court_indictments.advocates.confirm_defender_choice', + defaultMessage: 'Staðfesta val á verjanda', + description: + 'Notaður sem texti fyrir takka til að staðfesta val á verjanda í dómaraflæði í ákærum.', + }, + changeDefenderChoice: { + id: 'judicial.system.core:court_indictments.advocates.change_defender_choice', + defaultMessage: 'Breyta vali á verjanda', + description: + 'Notaður sem texti fyrir takka til að breyta vali á verjanda í dómaraflæði í ákærum.', + }, + confirmSpokespersonChoice: { + id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_choice', + defaultMessage: + 'Staðfesta {spokespersonIsLawyer, select, true {lögmann} other {réttargæslumann}}', + description: + 'Notaður sem texti fyrir takka til að staðfesta val á talsmanni í dómaraflæði í ákærum.', + }, + changeSpokespersonChoice: { + id: 'judicial.system.core:court_indictments.advocates.change_spokesperson_choice', + defaultMessage: + 'Breyta {spokespersonIsLawyer, select, true {lögmanni} other {réttargæslumanni}}', + description: + 'Notaður sem texti fyrir takka til að breyta vali á talsmanni í dómaraflæði í ákærum.', + }, civilClaimants: { id: 'judicial.system.core:court_indictments.advocates.civil_claimants', defaultMessage: 'Kröfuhafar', @@ -87,4 +113,75 @@ export const strings = defineMessages({ description: 'Notaður sem texti þegar ákærði hefur valið verjanda í dómaraflæði í ákærum.', }, + confirmDefenderChoiceModalTitle: { + id: 'judicial.system.core:court_indictments.advocates.modal_title', + defaultMessage: + '{isDefenderChoiceConfirmed, select, true {Breyta} other {Staðfesta}}', + description: + 'Notaður sem titill á staðfesta eða breyta val á verjanda modal í dómaraflæði í ákærum.', + }, + confirmDefenderChoiceModalText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_defender_choice_modal_text', + defaultMessage: + 'Valinn verjandi, {defenderName}, mun fá aðgang að máli í Réttarvörslugátt. ', + description: + 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', + }, + confirmDefenderWaivedModalText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_defender_waived_modal_text', + defaultMessage: 'Ákærða verður ekki skipaður verjandi.', + description: + 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', + }, + confirmDefenderDelayModalText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_defender_delay_modal_text', + defaultMessage: + 'Ákærði fær frest fram að þingfestingu til þess að tilnefna verjanda.', + description: + 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', + }, + changeDefenderChoiceModalText: { + id: 'judicial.system.core:court_indictments.advocates.change_modal_text', + defaultMessage: 'Ertu viss um að þú viljir breyta vali á verjanda?', + description: + 'Notaður sem texti í breyta vali á verjanda modal í dómaraflæði í ákærum.', + }, + confirmDefenderChoiceModalPrimaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.modal_primary_button_text', + defaultMessage: 'Staðfesta', + description: + 'Notaður sem texti á takka til að staðfesta val á verjanda í dómaraflæði í ákærum.', + }, + confirmDefenderChoiceModalSecondaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.modal_secondary_button_text', + defaultMessage: 'Hætta við', + description: + 'Notaður sem texti á takka til að hætta við val á verjanda í dómaraflæði í ákærum.', + }, + confirmSpokespersonModalTitle: { + id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_title', + defaultMessage: + '{isSpokespersonConfirmed, select, true {Breyta} other {Staðfesta}} val á {spokespersonIsLawyer, select, true {lögmanni} other {réttargæslumanni}}', + description: + 'Notaður sem titill á staðfesta val á lögmanni eða réttargæslumanni modal í dómaraflæði í ákærum.', + }, + confirmSpokespersonModalText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_text', + defaultMessage: + 'Ertu viss um að þú viljir {isSpokespersonConfirmed, select, true {breyta vali} other {staðfesta val}} á {spokespersonIsLawyer, select, true {lögmanni} other {réttargæslumanni}}?', + description: + 'Notaður sem texti í staðfesta val á lögmanni eða réttargæslumanni modal í dómaraflæði í ákærum.', + }, + confirmSpokespersonModalPrimaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_primary_button_text', + defaultMessage: 'Staðfesta', + description: + 'Notaður sem texti á takka til að staðfesta val á lögmanni eða réttargæslumanni í dómaraflæði í ákærum.', + }, + confirmSpokespersonModalSecondaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_secondary_button_text', + defaultMessage: 'Hætta við', + description: + 'Notaður sem texti á takka til að hætta við val á lögmanni eða réttargæslumanni í dómaraflæði í ákærum.', + }, }) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx index 7047b7724dfd..b55a8967376b 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx @@ -1,4 +1,4 @@ -import { FC, useContext } from 'react' +import { FC, useContext, useState } from 'react' import { useIntl } from 'react-intl' import { @@ -14,6 +14,7 @@ import { BlueBox, FormContext, InputAdvocate, + Modal, } from '@island.is/judicial-system-web/src/components' import { CivilClaimant, @@ -28,10 +29,11 @@ interface Props { } const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { - const { setAndSendCivilClaimantToServer } = useCivilClaimants() const { workingCase, setWorkingCase } = useContext(FormContext) - const { formatMessage } = useIntl() + const { setAndSendCivilClaimantToServer } = useCivilClaimants() + + const [displayModal, setDisplayModal] = useState(false) const updateCivilClaimant = (update: UpdateCivilClaimantInput) => { setAndSendCivilClaimantToServer( @@ -65,6 +67,7 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { spokespersonIsLawyer: true, } as UpdateCivilClaimantInput) } + disabled={Boolean(civilClaimant.isSpokespersonConfirmed)} /> @@ -80,6 +83,7 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { spokespersonIsLawyer: false, } as UpdateCivilClaimantInput) } + disabled={Boolean(civilClaimant.isSpokespersonConfirmed)} /> @@ -93,7 +97,8 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { } disabled={ civilClaimant.spokespersonIsLawyer === null || - civilClaimant.spokespersonIsLawyer === undefined + civilClaimant.spokespersonIsLawyer === undefined || + civilClaimant.isSpokespersonConfirmed } isCivilClaim={true} /> @@ -132,30 +137,82 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { /> )} - + + )} + + + + + + {displayModal && ( + { updateCivilClaimant({ - hasSpokesperson: !civilClaimant.hasSpokesperson, - spokespersonEmail: null, - spokespersonPhoneNumber: null, - spokespersonName: null, - spokespersonIsLawyer: null, - spokespersonNationalId: null, - caseFilesSharedWithSpokesperson: null, + isSpokespersonConfirmed: !civilClaimant.isSpokespersonConfirmed, } as UpdateCivilClaimantInput) + setDisplayModal(false) }} - > - {civilClaimant.hasSpokesperson - ? formatMessage(strings.removeCivilClaimantAdvocate, { - defenderIsLawyer: civilClaimant.spokespersonIsLawyer, - }) - : formatMessage(strings.addCivilClaimantAdvocate)} - - + secondaryButtonText={formatMessage( + strings.confirmSpokespersonModalSecondaryButtonText, + )} + onSecondaryButtonClick={() => setDisplayModal(false)} + /> + )} ) } diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx index 15b455791e48..5ec05bec1222 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx @@ -1,7 +1,7 @@ import { ChangeEvent, FC, useCallback, useContext, useState } from 'react' import { useIntl } from 'react-intl' -import { Box, Checkbox, Text } from '@island.is/island-ui/core' +import { Box, Button, Checkbox, Text } from '@island.is/island-ui/core' import { capitalize } from '@island.is/judicial-system/formatters' import { core } from '@island.is/judicial-system-web/messages' import { @@ -9,6 +9,7 @@ import { DefenderNotFound, FormContext, InputAdvocate, + Modal, } from '@island.is/judicial-system-web/src/components' import { Defendant, @@ -27,6 +28,8 @@ const SelectDefender: FC = ({ defendant }) => { const { formatMessage } = useIntl() const { setAndSendDefendantToServer } = useDefendants() + const [displayModal, setDisplayModal] = useState(false) + const [defenderNotFound, setDefenderNotFound] = useState(false) const gender = defendant.gender || 'NONE' @@ -54,14 +57,51 @@ const SelectDefender: FC = ({ defendant }) => { defenderChoice: defendantWaivesRightToCounsel === true ? DefenderChoice.WAIVE - : undefined, + : DefenderChoice.DELAY, + } + + setAndSendDefendantToServer(updateDefendantInput, setWorkingCase) + }, + [setWorkingCase, setAndSendDefendantToServer], + ) + + const toggleDefenderChoiceConfirmed = useCallback( + ( + caseId: string, + defendant: Defendant, + isDefenderChoiceConfirmed: boolean, + ) => { + const shouldChangeDefenderChoice = + isDefenderChoiceConfirmed && + defendant.defenderChoice !== DefenderChoice.WAIVE && + defendant.defenderChoice !== DefenderChoice.DELEGATE + + const updateDefendantInput = { + caseId, + defendantId: defendant.id, + isDefenderChoiceConfirmed, + defenderChoice: shouldChangeDefenderChoice + ? DefenderChoice.CHOOSE + : defendant.defenderChoice, } setAndSendDefendantToServer(updateDefendantInput, setWorkingCase) + setDisplayModal(false) }, [setWorkingCase, setAndSendDefendantToServer], ) + const confirmDefenderChoiceModalText = formatMessage( + defendant.isDefenderChoiceConfirmed + ? strings.changeDefenderChoiceModalText + : defendant.defenderChoice === DefenderChoice.WAIVE + ? strings.confirmDefenderWaivedModalText + : !defendant.defenderName + ? strings.confirmDefenderDelayModalText + : strings.confirmDefenderChoiceModalText, + { defenderName: defendant?.defenderName }, + ) + return ( {defenderNotFound && !workingCase.defendantWaivesRightToCounsel && ( @@ -94,14 +134,55 @@ const SelectDefender: FC = ({ defendant }) => { }} filled large + disabled={defendant.isDefenderChoiceConfirmed === true} /> + + + + {displayModal && ( + + toggleDefenderChoiceConfirmed( + workingCase.id, + defendant, + !defendant.isDefenderChoiceConfirmed, + ) + } + secondaryButtonText={formatMessage( + strings.confirmDefenderChoiceModalSecondaryButtonText, + )} + onSecondaryButtonClick={() => setDisplayModal(false)} + /> + )} ) } diff --git a/apps/judicial-system/web/src/utils/validate.ts b/apps/judicial-system/web/src/utils/validate.ts index b2162dc1c6da..e510a2739436 100644 --- a/apps/judicial-system/web/src/utils/validate.ts +++ b/apps/judicial-system/web/src/utils/validate.ts @@ -469,6 +469,8 @@ export const isDefenderStepValid = (workingCase: Case): boolean => { workingCase.defendants?.every((defendant) => { return ( defendant.defenderChoice === DefenderChoice.WAIVE || + defendant.defenderChoice === DefenderChoice.DELAY || + !defendant.defenderChoice || validate([ [defendant.defenderName, ['empty']], [defendant.defenderEmail, ['email-format']], diff --git a/apps/judicial-system/xrd-api/src/app/app.service.ts b/apps/judicial-system/xrd-api/src/app/app.service.ts index cafa8a8287c6..57648e9254f7 100644 --- a/apps/judicial-system/xrd-api/src/app/app.service.ts +++ b/apps/judicial-system/xrd-api/src/app/app.service.ts @@ -96,7 +96,15 @@ export class AppService { subpoenaId: string, updateSubpoena: UpdateSubpoenaDto, ): Promise { - let defenderName = undefined + let defenderInfo: { + defenderName: string | undefined + defenderEmail: string | undefined + defenderPhoneNumber: string | undefined + } = { + defenderName: undefined, + defenderEmail: undefined, + defenderPhoneNumber: undefined, + } if ( updateSubpoena.defenderChoice === DefenderChoice.CHOOSE && @@ -113,7 +121,11 @@ export class AppService { updateSubpoena.defenderNationalId, ) - defenderName = chosenLawyer.Name + defenderInfo = { + defenderName: chosenLawyer.Name, + defenderEmail: chosenLawyer.Email, + defenderPhoneNumber: chosenLawyer.Phone, + } } catch (reason) { // TODO: Reconsider throwing - what happens if registry is down? this.logger.error( @@ -141,9 +153,14 @@ export class AppService { comment: updateSubpoena.comment, servedBy: updateSubpoena.servedBy, serviceDate: updateSubpoena.servedAt, + defenderChoice: updateSubpoena.defenderChoice, + defenderNationalId: updateSubpoena.defenderNationalId, + defenderName: defenderInfo.defenderName, + defenderEmail: defenderInfo.defenderEmail, + defenderPhoneNumber: defenderInfo.defenderPhoneNumber, requestedDefenderChoice: updateSubpoena.defenderChoice, requestedDefenderNationalId: updateSubpoena.defenderNationalId, - requestedDefenderName: defenderName, + requestedDefenderName: defenderInfo.defenderName, } try { From 886096780ad14aea367141c88bce0964567adaac Mon Sep 17 00:00:00 2001 From: unakb Date: Fri, 18 Oct 2024 17:10:55 +0000 Subject: [PATCH 02/17] Update SelectDefender.tsx --- .../Indictments/Advocates/SelectDefender.tsx | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx index 5ec05bec1222..518e7e97b4b3 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx @@ -71,18 +71,26 @@ const SelectDefender: FC = ({ defendant }) => { defendant: Defendant, isDefenderChoiceConfirmed: boolean, ) => { - const shouldChangeDefenderChoice = - isDefenderChoiceConfirmed && - defendant.defenderChoice !== DefenderChoice.WAIVE && - defendant.defenderChoice !== DefenderChoice.DELEGATE + const { defenderChoice, defenderName } = defendant + + const isDelaying = + !defenderName && + (!defenderChoice || defenderChoice === DefenderChoice.CHOOSE) + const isChoosing = + defenderName && + (!defenderChoice || defenderChoice === DefenderChoice.DELAY) + + const defenderChoiceUpdate = isDelaying + ? DefenderChoice.DELAY + : isChoosing + ? DefenderChoice.CHOOSE + : defenderChoice const updateDefendantInput = { caseId, defendantId: defendant.id, isDefenderChoiceConfirmed, - defenderChoice: shouldChangeDefenderChoice - ? DefenderChoice.CHOOSE - : defendant.defenderChoice, + defenderChoice: defenderChoiceUpdate, } setAndSendDefendantToServer(updateDefendantInput, setWorkingCase) From c087faf2cc7fafc7d637084942fd09edc010a959 Mon Sep 17 00:00:00 2001 From: unakb Date: Fri, 18 Oct 2024 17:17:49 +0000 Subject: [PATCH 03/17] cleanup --- .../Advocates/Advocates.strings.ts | 28 ++++++------------- .../Advocates/SelectCivilClaimantAdvocate.tsx | 4 +-- .../Indictments/Advocates/SelectDefender.tsx | 4 +-- 3 files changed, 13 insertions(+), 23 deletions(-) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index c685e6b3f41b..c4834bcf2fa5 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -113,8 +113,9 @@ export const strings = defineMessages({ description: 'Notaður sem texti þegar ákærði hefur valið verjanda í dómaraflæði í ákærum.', }, + confirmDefenderChoiceModalTitle: { - id: 'judicial.system.core:court_indictments.advocates.modal_title', + id: 'judicial.system.core:court_indictments.advocates.confirm_defender_choice_modal_title', defaultMessage: '{isDefenderChoiceConfirmed, select, true {Breyta} other {Staðfesta}}', description: @@ -136,28 +137,17 @@ export const strings = defineMessages({ confirmDefenderDelayModalText: { id: 'judicial.system.core:court_indictments.advocates.confirm_defender_delay_modal_text', defaultMessage: - 'Ákærði fær frest fram að þingfestingu til þess að tilnefna verjanda.', + 'Ákærð fær frest fram að þingfestingu til þess að tilnefna verjanda.', description: 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', }, changeDefenderChoiceModalText: { - id: 'judicial.system.core:court_indictments.advocates.change_modal_text', + id: 'judicial.system.core:court_indictments.advocates.change_defender_choice_modal_text', defaultMessage: 'Ertu viss um að þú viljir breyta vali á verjanda?', description: 'Notaður sem texti í breyta vali á verjanda modal í dómaraflæði í ákærum.', }, - confirmDefenderChoiceModalPrimaryButtonText: { - id: 'judicial.system.core:court_indictments.advocates.modal_primary_button_text', - defaultMessage: 'Staðfesta', - description: - 'Notaður sem texti á takka til að staðfesta val á verjanda í dómaraflæði í ákærum.', - }, - confirmDefenderChoiceModalSecondaryButtonText: { - id: 'judicial.system.core:court_indictments.advocates.modal_secondary_button_text', - defaultMessage: 'Hætta við', - description: - 'Notaður sem texti á takka til að hætta við val á verjanda í dómaraflæði í ákærum.', - }, + confirmSpokespersonModalTitle: { id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_title', defaultMessage: @@ -172,14 +162,14 @@ export const strings = defineMessages({ description: 'Notaður sem texti í staðfesta val á lögmanni eða réttargæslumanni modal í dómaraflæði í ákærum.', }, - confirmSpokespersonModalPrimaryButtonText: { - id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_primary_button_text', + confirmModalPrimaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.modal_primary_button_text', defaultMessage: 'Staðfesta', description: 'Notaður sem texti á takka til að staðfesta val á lögmanni eða réttargæslumanni í dómaraflæði í ákærum.', }, - confirmSpokespersonModalSecondaryButtonText: { - id: 'judicial.system.core:court_indictments.advocates.confirm_spokesperson_modal_secondary_button_text', + confirmModalSecondaryButtonText: { + id: 'judicial.system.core:court_indictments.advocates.modal_secondary_button_text', defaultMessage: 'Hætta við', description: 'Notaður sem texti á takka til að hætta við val á lögmanni eða réttargæslumanni í dómaraflæði í ákærum.', diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx index b55a8967376b..29263aa60383 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectCivilClaimantAdvocate.tsx @@ -199,7 +199,7 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { spokespersonIsLawyer: civilClaimant.spokespersonIsLawyer, })} primaryButtonText={formatMessage( - strings.confirmSpokespersonModalPrimaryButtonText, + strings.confirmModalPrimaryButtonText, )} onPrimaryButtonClick={() => { updateCivilClaimant({ @@ -208,7 +208,7 @@ const SelectCivilClaimantAdvocate: FC = ({ civilClaimant }) => { setDisplayModal(false) }} secondaryButtonText={formatMessage( - strings.confirmSpokespersonModalSecondaryButtonText, + strings.confirmModalSecondaryButtonText, )} onSecondaryButtonClick={() => setDisplayModal(false)} /> diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx index 518e7e97b4b3..5cd229577551 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx @@ -176,7 +176,7 @@ const SelectDefender: FC = ({ defendant }) => { })} text={confirmDefenderChoiceModalText} primaryButtonText={formatMessage( - strings.confirmDefenderChoiceModalPrimaryButtonText, + strings.confirmModalPrimaryButtonText, )} onPrimaryButtonClick={() => toggleDefenderChoiceConfirmed( @@ -186,7 +186,7 @@ const SelectDefender: FC = ({ defendant }) => { ) } secondaryButtonText={formatMessage( - strings.confirmDefenderChoiceModalSecondaryButtonText, + strings.confirmModalSecondaryButtonText, )} onSecondaryButtonClick={() => setDisplayModal(false)} /> From dddef74fe1f1ba346a00ec51eb0433ea76aa2384 Mon Sep 17 00:00:00 2001 From: unakb Date: Fri, 18 Oct 2024 17:22:28 +0000 Subject: [PATCH 04/17] fix(j-s): Cleanup --- .../Advocates/Advocates.strings.ts | 2 +- .../Indictments/Advocates/SelectDefender.tsx | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index c4834bcf2fa5..80e8cc24f8ef 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -137,7 +137,7 @@ export const strings = defineMessages({ confirmDefenderDelayModalText: { id: 'judicial.system.core:court_indictments.advocates.confirm_defender_delay_modal_text', defaultMessage: - 'Ákærð fær frest fram að þingfestingu til þess að tilnefna verjanda.', + 'Ákærð fær frest fram að þingfestingu til þess að tilnefna verjanda.', description: 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', }, diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx index 5cd229577551..1df8cb1a1748 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx @@ -99,17 +99,6 @@ const SelectDefender: FC = ({ defendant }) => { [setWorkingCase, setAndSendDefendantToServer], ) - const confirmDefenderChoiceModalText = formatMessage( - defendant.isDefenderChoiceConfirmed - ? strings.changeDefenderChoiceModalText - : defendant.defenderChoice === DefenderChoice.WAIVE - ? strings.confirmDefenderWaivedModalText - : !defendant.defenderName - ? strings.confirmDefenderDelayModalText - : strings.confirmDefenderChoiceModalText, - { defenderName: defendant?.defenderName }, - ) - return ( {defenderNotFound && !workingCase.defendantWaivesRightToCounsel && ( @@ -174,7 +163,16 @@ const SelectDefender: FC = ({ defendant }) => { title={formatMessage(strings.confirmDefenderChoiceModalTitle, { isDefenderChoiceConfirmed: defendant.isDefenderChoiceConfirmed, })} - text={confirmDefenderChoiceModalText} + text={formatMessage( + defendant.isDefenderChoiceConfirmed + ? strings.changeDefenderChoiceModalText + : defendant.defenderChoice === DefenderChoice.WAIVE + ? strings.confirmDefenderWaivedModalText + : !defendant.defenderName + ? strings.confirmDefenderDelayModalText + : strings.confirmDefenderChoiceModalText, + { defenderName: defendant?.defenderName }, + )} primaryButtonText={formatMessage( strings.confirmModalPrimaryButtonText, )} From 451e98d8d8454acfb6856e68b9915761e7d65f23 Mon Sep 17 00:00:00 2001 From: andes-it Date: Fri, 18 Oct 2024 17:34:58 +0000 Subject: [PATCH 05/17] chore: nx format:write update dirty files --- .../src/routes/Court/Indictments/Advocates/Advocates.strings.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index 80e8cc24f8ef..c4834bcf2fa5 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -137,7 +137,7 @@ export const strings = defineMessages({ confirmDefenderDelayModalText: { id: 'judicial.system.core:court_indictments.advocates.confirm_defender_delay_modal_text', defaultMessage: - 'Ákærð fær frest fram að þingfestingu til þess að tilnefna verjanda.', + 'Ákærð fær frest fram að þingfestingu til þess að tilnefna verjanda.', description: 'Notaður sem texti í staðfesta val á verjanda modal í dómaraflæði í ákærum.', }, From f490663ac87d9f19b108d0ce3df77fe984300dee Mon Sep 17 00:00:00 2001 From: unakb Date: Mon, 21 Oct 2024 12:21:03 +0000 Subject: [PATCH 06/17] feat(j-s): Add case files shared with defender front end handling --- .../defendant/dto/updateDefendant.input.ts | 5 +++ .../defendant/models/defendant.model.ts | 3 ++ .../defendant/dto/createDefendant.dto.ts | 5 +++ .../defendant/dto/updateDefendant.dto.ts | 5 +++ .../defendant/models/defendant.model.ts | 4 ++ .../subpoena/dto/updateSubpoena.dto.ts | 5 +++ .../src/components/FormProvider/case.graphql | 1 + .../Advocates/Advocates.strings.ts | 12 ++++++ .../Indictments/Advocates/SelectDefender.tsx | 39 +++++++++++++++++++ 9 files changed, 79 insertions(+) diff --git a/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts b/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts index 50857a9b32ee..ca43a4658f72 100644 --- a/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts +++ b/apps/judicial-system/api/src/app/modules/defendant/dto/updateDefendant.input.ts @@ -99,4 +99,9 @@ export class UpdateDefendantInput { @IsOptional() @Field(() => Boolean, { nullable: true }) readonly isDefenderChoiceConfirmed?: boolean + + @Allow() + @IsOptional() + @Field(() => Boolean, { nullable: true }) + readonly caseFilesSharedWithDefender?: boolean } 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 7388a15a11f1..5b509b4dba2b 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 @@ -92,4 +92,7 @@ export class Defendant { @Field(() => Boolean, { nullable: true }) readonly isDefenderChoiceConfirmed?: boolean + + @Field(() => Boolean, { nullable: true }) + readonly caseFilesSharedWithDefender?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts index 4ea4d1380836..c56e7e282f57 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/createDefendant.dto.ts @@ -64,4 +64,9 @@ export class CreateDefendantDto { @IsBoolean() @ApiPropertyOptional({ type: Boolean }) readonly isDefenderChoiceConfirmed?: boolean + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly caseFilesSharedWithDefender?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts index 65724815320c..47848c5c084f 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/dto/updateDefendant.dto.ts @@ -113,4 +113,9 @@ export class UpdateDefendantDto { @IsBoolean() @ApiPropertyOptional({ type: Boolean }) readonly isDefenderChoiceConfirmed?: boolean + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly caseFilesSharedWithDefender?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts index 9415aead6c4f..de79f0bbf705 100644 --- a/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts +++ b/apps/judicial-system/backend/src/app/modules/defendant/models/defendant.model.ts @@ -171,4 +171,8 @@ export class Defendant extends Model { @Column({ type: DataType.BOOLEAN, allowNull: true }) @ApiPropertyOptional({ type: Boolean }) isDefenderChoiceConfirmed?: boolean + + @Column({ type: DataType.BOOLEAN, allowNull: true }) + @ApiPropertyOptional({ type: Boolean }) + caseFilesSharedWithDefender?: boolean } diff --git a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts index 80603c97865d..363e2379cf7c 100644 --- a/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts +++ b/apps/judicial-system/backend/src/app/modules/subpoena/dto/updateSubpoena.dto.ts @@ -69,4 +69,9 @@ export class UpdateSubpoenaDto { @IsBoolean() @ApiPropertyOptional({ type: Boolean }) readonly isDefenderChoiceConfirmed?: boolean + + @IsOptional() + @IsBoolean() + @ApiPropertyOptional({ type: Boolean }) + readonly caseFilesSharedWithDefender?: boolean } diff --git a/apps/judicial-system/web/src/components/FormProvider/case.graphql b/apps/judicial-system/web/src/components/FormProvider/case.graphql index da1dd3d6de76..5f2d3f3ec668 100644 --- a/apps/judicial-system/web/src/components/FormProvider/case.graphql +++ b/apps/judicial-system/web/src/components/FormProvider/case.graphql @@ -26,6 +26,7 @@ query Case($input: CaseQueryInput!) { requestedDefenderNationalId requestedDefenderName isDefenderChoiceConfirmed + caseFilesSharedWithDefender serviceRequirement verdictViewDate verdictAppealDeadline diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts index c4834bcf2fa5..0ee84e48c080 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/Advocates.strings.ts @@ -174,4 +174,16 @@ export const strings = defineMessages({ description: 'Notaður sem texti á takka til að hætta við val á lögmanni eða réttargæslumanni í dómaraflæði í ákærum.', }, + shareFilesWithDefender: { + id: 'judicial.system.core:court_indictments.advocates.share_files_with_defender', + defaultMessage: 'Deila gögnum með verjanda', + description: 'Notaður sem texti á deila kröfum með verjanda takka.', + }, + shareFilesWithDefenderTooltip: { + id: 'judicial.system.core:court_indictments.advocates.share_files_with_defender_tooltip', + defaultMessage: + 'Ef hakað er í þennan reit fær lögmaður aðgang að gögnum málsins', + description: + 'Notaður sem texti í tooltip á deila kröfum með verjanda takka.', + }, }) diff --git a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx index 1df8cb1a1748..d4e75dc8856c 100644 --- a/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx +++ b/apps/judicial-system/web/src/routes/Court/Indictments/Advocates/SelectDefender.tsx @@ -99,6 +99,26 @@ const SelectDefender: FC = ({ defendant }) => { [setWorkingCase, setAndSendDefendantToServer], ) + const toggleCaseFilesSharedWithDefender = useCallback( + ( + caseId: string, + defendant: Defendant, + caseFilesSharedWithDefender: boolean, + ) => { + if (defendant) { + defendant.caseFilesSharedWithDefender = caseFilesSharedWithDefender + + const updateDefendantInput = { + caseId: caseId, + defendantId: defendant.id, + caseFilesSharedWithDefender, + } + setAndSendDefendantToServer(updateDefendantInput, setWorkingCase) + } + }, + [setWorkingCase, setAndSendDefendantToServer], + ) + return ( {defenderNotFound && !workingCase.defendantWaivesRightToCounsel && ( @@ -142,6 +162,25 @@ const SelectDefender: FC = ({ defendant }) => { onAdvocateNotFound={setDefenderNotFound} clientId={defendant.id} /> + + { + toggleCaseFilesSharedWithDefender( + workingCase.id, + defendant, + !defendant.caseFilesSharedWithDefender, + ) + }} + tooltip={formatMessage(strings.shareFilesWithDefenderTooltip)} + backgroundColor="white" + large + filled + /> +