Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(j-s): Show send to prison admin file #17148

Merged
merged 15 commits into from
Dec 13, 2024
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,10 @@ export const strings = defineMessages({
description:
'Notaður sem texti á PDF takka til að sækja birtingarvottorð í ákærum.',
},
sentToPrisonAdmin: {
id: 'judicial.system.core:indictment_case_files_list.sent_to_prison_admin',
defaultMessage: 'Fullnusta',
description:
'Notaður sem titill á fullnusta hluta á dómskjalaskjá í ákærum.',
},
})
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FC, useContext } from 'react'
import { FC, useContext, useMemo } from 'react'
import { useIntl } from 'react-intl'
import { AnimatePresence } from 'framer-motion'

Expand All @@ -9,6 +9,7 @@ import {
isCompletedCase,
isDefenceUser,
isDistrictCourtUser,
isPrisonAdminUser,
isProsecutionUser,
isPublicProsecutor,
isPublicProsecutorUser,
Expand All @@ -25,6 +26,7 @@ import {
import {
CaseFile,
CaseFileCategory,
User,
} from '@island.is/judicial-system-web/src/graphql/schema'
import { TempCase as Case } from '@island.is/judicial-system-web/src/types'
import { useFileList } from '@island.is/judicial-system-web/src/utils/hooks'
Expand All @@ -45,6 +47,13 @@ interface RenderFilesProps {
onOpenFile: (fileId: string) => void
}

interface FileSection {
title: string
onOpenFile: (fileId: string) => void
files?: CaseFile[]
shouldRender?: boolean
}

export const RenderFiles: FC<RenderFilesProps> = ({
caseFiles,
onOpenFile,
Expand All @@ -65,6 +74,80 @@ export const RenderFiles: FC<RenderFilesProps> = ({
)
}

const FileSection: FC<FileSection> = (props: FileSection) => {
const { title, files, onOpenFile, shouldRender = true } = props

if (!files?.length || !shouldRender) {
return null
}

return (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{title}
</Text>
<RenderFiles caseFiles={files} onOpenFile={onOpenFile} />
</Box>
)
}

const useFilteredCaseFiles = (caseFiles?: CaseFile[] | null) => {
return useMemo(() => {
const filterByCategories = (
categories: CaseFileCategory | CaseFileCategory[],
) => {
const categoryArray = Array.isArray(categories)
? categories
: [categories]

return (
caseFiles?.filter(
(file) => file.category && categoryArray.includes(file.category),
) ?? []
)
}

return {
indictments: filterByCategories(CaseFileCategory.INDICTMENT),
criminalRecords: filterByCategories(CaseFileCategory.CRIMINAL_RECORD),
costBreakdowns: filterByCategories(CaseFileCategory.COST_BREAKDOWN),
others: filterByCategories(CaseFileCategory.CASE_FILE),
rulings: filterByCategories(CaseFileCategory.RULING),
courtRecords: filterByCategories(CaseFileCategory.COURT_RECORD),
criminalRecordUpdate: filterByCategories(
CaseFileCategory.CRIMINAL_RECORD_UPDATE,
),
uploadedCaseFiles: filterByCategories([
CaseFileCategory.PROSECUTOR_CASE_FILE,
CaseFileCategory.DEFENDANT_CASE_FILE,
]),
civilClaims: filterByCategories(CaseFileCategory.CIVIL_CLAIM),
sentToPrisonAdminFiles: filterByCategories(
CaseFileCategory.SENT_TO_PRISON_ADMIN_FILE,
),
}
}, [caseFiles])
}

const useFilePermissions = (workingCase: Case, user?: User) => {
return useMemo(
() => ({
canViewCriminalRecordUpdate:
isDistrictCourtUser(user) ||
isPublicProsecutor(user) ||
isPublicProsecutorUser(user),
canViewCivilClaims:
Boolean(workingCase.hasCivilClaims) &&
(isDistrictCourtUser(user) ||
isProsecutionUser(user) ||
isDefenceUser(user)),
canViewSentToPrisonAdminFiles:
isPrisonAdminUser(user) || isPublicProsecutorUser(user),
}),
[user, workingCase.hasCivilClaims],
)
}

const IndictmentCaseFilesList: FC<Props> = ({
workingCase,
displayGeneratedPDFs = true,
Expand All @@ -89,51 +172,19 @@ const IndictmentCaseFilesList: FC<Props> = ({
(defendant) => defendant.subpoenas && defendant.subpoenas.length > 0,
)

const cf = workingCase.caseFiles

const indictments = cf?.filter(
(file) => file.category === CaseFileCategory.INDICTMENT,
)
const criminalRecords = cf?.filter(
(file) => file.category === CaseFileCategory.CRIMINAL_RECORD,
)
const costBreakdowns = cf?.filter(
(file) => file.category === CaseFileCategory.COST_BREAKDOWN,
)
const others = cf?.filter(
(file) => file.category === CaseFileCategory.CASE_FILE,
)
const rulings = cf?.filter(
(file) => file.category === CaseFileCategory.RULING,
)
const courtRecords = cf?.filter(
(file) => file.category === CaseFileCategory.COURT_RECORD,
)
const criminalRecordUpdate = cf?.filter(
(file) => file.category === CaseFileCategory.CRIMINAL_RECORD_UPDATE,
)
const uploadedCaseFiles = cf?.filter(
(file) =>
file.category === CaseFileCategory.PROSECUTOR_CASE_FILE ||
file.category === CaseFileCategory.DEFENDANT_CASE_FILE,
)
const civilClaims = cf?.filter(
(file) => file.category === CaseFileCategory.CIVIL_CLAIM,
)
const filteredFiles = useFilteredCaseFiles(workingCase.caseFiles)
const permissions = useFilePermissions(workingCase, user)

return (
<>
{displayHeading && (
<SectionHeading title={formatMessage(strings.title)} />
)}
{indictments && indictments.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(caseFiles.indictmentSection)}
</Text>
<RenderFiles caseFiles={indictments} onOpenFile={onOpen} />
</Box>
)}
<FileSection
title={formatMessage(caseFiles.indictmentSection)}
files={filteredFiles.indictments}
onOpenFile={onOpen}
/>
{showTrafficViolationCaseFiles && displayGeneratedPDFs && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
Expand All @@ -150,42 +201,27 @@ const IndictmentCaseFilesList: FC<Props> = ({
</Box>
</Box>
)}
{criminalRecords && criminalRecords.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(caseFiles.criminalRecordSection)}
</Text>
<RenderFiles caseFiles={criminalRecords} onOpenFile={onOpen} />
</Box>
)}
{criminalRecordUpdate &&
criminalRecordUpdate.length > 0 &&
(isDistrictCourtUser(user) ||
isPublicProsecutor(user) ||
isPublicProsecutorUser(user)) && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(caseFiles.criminalRecordUpdateSection)}
</Text>
<RenderFiles caseFiles={criminalRecordUpdate} onOpenFile={onOpen} />
</Box>
)}
{costBreakdowns && costBreakdowns.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(caseFiles.costBreakdownSection)}
</Text>
<RenderFiles caseFiles={costBreakdowns} onOpenFile={onOpen} />
</Box>
)}
{others && others.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(caseFiles.otherDocumentsSection)}
</Text>
<RenderFiles caseFiles={others} onOpenFile={onOpen} />
</Box>
)}
<FileSection
title={formatMessage(caseFiles.criminalRecordSection)}
files={filteredFiles.criminalRecords}
onOpenFile={onOpen}
/>
<FileSection
title={formatMessage(caseFiles.criminalRecordUpdateSection)}
files={filteredFiles.criminalRecordUpdate}
onOpenFile={onOpen}
shouldRender={permissions.canViewCriminalRecordUpdate}
/>
<FileSection
title={formatMessage(caseFiles.costBreakdownSection)}
files={filteredFiles.costBreakdowns}
onOpenFile={onOpen}
/>
<FileSection
title={formatMessage(caseFiles.otherDocumentsSection)}
files={filteredFiles.others}
onOpenFile={onOpen}
/>
{displayGeneratedPDFs && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
Expand All @@ -207,34 +243,34 @@ const IndictmentCaseFilesList: FC<Props> = ({
))}
</Box>
)}
{courtRecords?.length || rulings?.length ? (
{filteredFiles.courtRecords?.length || filteredFiles.rulings?.length ? (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(strings.rulingAndCourtRecordsTitle)}
</Text>
{courtRecords && courtRecords.length > 0 && (
<RenderFiles caseFiles={courtRecords} onOpenFile={onOpen} />
)}
{filteredFiles.courtRecords &&
filteredFiles.courtRecords.length > 0 && (
<RenderFiles
caseFiles={filteredFiles.courtRecords}
onOpenFile={onOpen}
/>
)}
{(isDistrictCourtUser(user) || isCompletedCase(workingCase.state)) &&
oddsson marked this conversation as resolved.
Show resolved Hide resolved
rulings &&
rulings.length > 0 && (
<RenderFiles caseFiles={rulings} onOpenFile={onOpen} />
filteredFiles.rulings &&
filteredFiles.rulings.length > 0 && (
<RenderFiles
caseFiles={filteredFiles.rulings}
onOpenFile={onOpen}
/>
)}
</Box>
) : null}
{workingCase.hasCivilClaims &&
civilClaims &&
civilClaims.length > 0 &&
(isDistrictCourtUser(user) ||
isProsecutionUser(user) ||
isDefenceUser(user)) && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
{formatMessage(strings.civilClaimsTitle)}
</Text>
<RenderFiles caseFiles={civilClaims} onOpenFile={onOpen} />
</Box>
)}
<FileSection
title={formatMessage(strings.civilClaimsTitle)}
files={filteredFiles.civilClaims}
onOpenFile={onOpen}
shouldRender={permissions.canViewCivilClaims}
/>
{showSubpoenaPdf && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={1}>
Expand Down Expand Up @@ -273,14 +309,24 @@ const IndictmentCaseFilesList: FC<Props> = ({
)}
</Box>
)}
{uploadedCaseFiles && uploadedCaseFiles.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={3}>
{formatMessage(strings.uploadedCaseFiles)}
</Text>
<CaseFileTable caseFiles={uploadedCaseFiles} onOpenFile={onOpen} />
</Box>
)}
{filteredFiles.uploadedCaseFiles &&
filteredFiles.uploadedCaseFiles.length > 0 && (
<Box marginBottom={5}>
<Text variant="h4" as="h4" marginBottom={3}>
{formatMessage(strings.uploadedCaseFiles)}
</Text>
<CaseFileTable
caseFiles={filteredFiles.uploadedCaseFiles}
onOpenFile={onOpen}
/>
</Box>
)}
<FileSection
title={formatMessage(strings.sentToPrisonAdmin)}
files={filteredFiles.sentToPrisonAdminFiles}
onOpenFile={onOpen}
shouldRender={permissions.canViewSentToPrisonAdminFiles}
/>
<AnimatePresence>
{fileNotFound && <FileNotFoundModal dismiss={dismissFileNotFound} />}
</AnimatePresence>
Expand Down
16 changes: 8 additions & 8 deletions libs/judicial-system/types/src/lib/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ export const isPublicProsecutorUser = (user?: InstitutionUser): boolean => {
return Boolean(
user?.role &&
publicProsecutorRoles.includes(user.role) &&
user?.institution?.type === InstitutionType.PROSECUTORS_OFFICE &&
user?.institution?.id === '8f9e2f6d-6a00-4a5e-b39b-95fd110d762e', // TODO: Create a new institution type to avoid hardcoding
user.institution?.type === InstitutionType.PROSECUTORS_OFFICE &&
user.institution?.id === '8f9e2f6d-6a00-4a5e-b39b-95fd110d762e', // TODO: Create a new institution type to avoid hardcoding
)
}

Expand All @@ -85,7 +85,7 @@ export const isDistrictCourtUser = (user?: InstitutionUser): boolean => {
return Boolean(
user?.role &&
districtCourtRoles.includes(user.role) &&
user?.institution?.type === InstitutionType.DISTRICT_COURT,
user.institution?.type === InstitutionType.DISTRICT_COURT,
)
}

Expand All @@ -99,7 +99,7 @@ export const isCourtOfAppealsUser = (user?: InstitutionUser): boolean => {
return Boolean(
user?.role &&
courtOfAppealsRoles.includes(user.role) &&
user?.institution?.type === InstitutionType.COURT_OF_APPEALS,
user.institution?.type === InstitutionType.COURT_OF_APPEALS,
)
}

Expand All @@ -109,14 +109,14 @@ export const isPrisonSystemUser = (user?: InstitutionUser): boolean => {
return Boolean(
user?.role &&
prisonSystemRoles.includes(user.role) &&
(user?.institution?.type === InstitutionType.PRISON ||
user?.institution?.type === InstitutionType.PRISON_ADMIN),
(user.institution?.type === InstitutionType.PRISON ||
user.institution?.type === InstitutionType.PRISON_ADMIN),
)
}

export const isPrisonAdminUser = (user: InstitutionUser): boolean =>
export const isPrisonAdminUser = (user?: InstitutionUser): boolean =>
Boolean(
user.role &&
user?.role &&
oddsson marked this conversation as resolved.
Show resolved Hide resolved
prisonSystemRoles.includes(user.role) &&
user.institution?.type === InstitutionType.PRISON_ADMIN,
)
Expand Down
Loading