Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/console/src/_locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -2461,7 +2461,7 @@
"columns": { "name": "Risk name", "category": "Category", "treatment": "Treatment", "initialRisk": "Initial Risk", "residualRisk": "Residual Risk", "owner": "Owner" }
},
"riskOverviewPage": {
"emptyScores": "Scores are set on a treatment plan in a risk analysis.",
"emptyNote": "This risk has no note.",
"fields": { "owner": "Owner", "treatment": "Treatment", "initialRiskScore": "Initial score", "residualRiskScore": "Residual score", "note": "Note" },
"treatments": { "mitigated": "Mitigate", "accepted": "Accept", "transferred": "Transfer", "avoided": "Avoid", "unknown": "Unknown" }
},
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/_locales/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -4664,7 +4664,7 @@
}
},
"riskOverviewPage": {
"emptyScores": "Les scores sont définis sur un plan de traitement dans une analyse de risques.",
"emptyNote": "Ce risque n'a pas de note.",
"fields": {
"owner": "Propriétaire",
"treatment": "Traitement",
Expand Down
2 changes: 1 addition & 1 deletion apps/console/src/_locales/nl-NL.json
Original file line number Diff line number Diff line change
Expand Up @@ -4654,7 +4654,7 @@
}
},
"riskOverviewPage": {
"emptyScores": "Scores worden ingesteld op een behandelplan in een risicoanalyse.",
"emptyNote": "Dit risico heeft geen opmerking.",
"fields": {
"owner": "Eigenaar",
"treatment": "Behandeling",
Expand Down
19 changes: 2 additions & 17 deletions apps/console/src/components/risks/LinkedRisksCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import {
Button,
IconTrashCan,
RiskBadge,
Table,
Tbody,
Td,
Expand All @@ -43,8 +42,6 @@ const linkedRiskFragment = graphql`
fragment LinkedRisksCardFragment on Risk {
id
name
inherentRiskScore
residualRiskScore
}
`;

Expand Down Expand Up @@ -109,16 +106,14 @@ export function LinkedRisksCard<Params>(props: Props<Params>) {
<Thead>
<Tr>
<Th>{t("linkedRisksCard.columns.name")}</Th>
<Th>{t("linkedRisksCard.columns.initialRisk")}</Th>
<Th>{t("linkedRisksCard.columns.residualRisk")}</Th>
{!props.readOnly && <Th></Th>}
</Tr>
</Thead>
<Tbody>
{props.risks.length === 0 && (
<Tr>
<Td
colSpan={props.readOnly ? 3 : 4}
colSpan={props.readOnly ? 1 : 2}
className="text-center text-txt-secondary"
>
{t("linkedRisksCard.empty")}
Expand All @@ -141,7 +136,7 @@ export function LinkedRisksCard<Params>(props: Props<Params>) {
onLink={onAttach}
onUnlink={onDetach}
>
<TrButton colspan={4}>
<TrButton colspan={props.readOnly ? 1 : 2}>
{t("linkedRisksCard.actions.link")}
</TrButton>
</LinkedRisksDialog>
Expand All @@ -164,16 +159,6 @@ function RiskRow(props: {
return (
<Tr to={`/organizations/${organizationId}/risk-management/risks/${risk.id}`}>
<Td>{risk.name}</Td>
<Td>
{risk.inherentRiskScore != null
? <RiskBadge level={risk.inherentRiskScore} />
: "—"}
</Td>
<Td>
{risk.residualRiskScore != null
? <RiskBadge level={risk.residualRiskScore} />
: "—"}
</Td>
{!props.readOnly && (
<Td noLink width={50} className="text-end">
<Button
Expand Down
23 changes: 1 addition & 22 deletions apps/console/src/hooks/forms/useRiskForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,27 +29,13 @@ export type RiskNode = Pick<
| "name"
| "category"
| "description"
| "treatment"
| "inherentLikelihood"
| "inherentImpact"
| "residualLikelihood"
| "residualImpact"
| "inherentRiskScore"
| "residualRiskScore"
| "note"
| "owner"
>;

export const riskSchema = z.object({
category: z.string().min(1, "Category is required"),
name: z.string().min(1, "Name is required"),
description: z.string().optional().nullable(),
ownerId: z.string().min(1, "Owner is required"),
treatment: z.enum(["AVOIDED", "MITIGATED", "TRANSFERRED", "ACCEPTED"]),
inherentLikelihood: z.coerce.number().min(1).max(5),
inherentImpact: z.coerce.number().min(1).max(5),
residualLikelihood: z.coerce.number().min(1).max(5),
residualImpact: z.coerce.number().min(1).max(5),
note: z.string().optional(),
});

Expand All @@ -59,15 +45,8 @@ export const useRiskForm = (risk?: RiskNode) => {
? {
...risk,
description: risk.description ?? undefined,
ownerId: risk.owner?.id,
treatment: risk.treatment ?? undefined,
}
: {
inherentLikelihood: 3,
inherentImpact: 3,
residualLikelihood: 3,
residualImpact: 3,
},
: undefined,
});
};

Expand Down
56 changes: 0 additions & 56 deletions apps/console/src/pages/organizations/risks/RisksPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import {
IconPlusLarge,
IconUpload,
PageHeader,
RisksChart,
Tbody,
Th,
Thead,
Expand Down Expand Up @@ -92,10 +91,6 @@ const risksFragment = graphql`
node {
id
name
inherentLikelihood
inherentImpact
residualLikelihood
residualImpact
canUpdate: permission(action: "risk-management:risk:update")
canDelete: permission(action: "risk-management:risk:delete")
...RiskRow_risk
Expand Down Expand Up @@ -128,33 +123,6 @@ export default function RisksPage(props: RisksPageProps) {
const risks = fragmentData.risks?.edges.map(edge => edge.node) ?? [];
const connectionId = fragmentData.risks.__id;

const chartRisks = risks.flatMap(({
id,
name,
inherentLikelihood,
inherentImpact,
residualLikelihood,
residualImpact,
}) => {
if (
inherentLikelihood == null
|| inherentImpact == null
|| residualLikelihood == null
|| residualImpact == null
) {
return [];
}

return [{
id,
name,
inherentLikelihood,
inherentImpact,
residualLikelihood,
residualImpact,
}];
});

const refetch = ({
order,
}: {
Expand All @@ -167,10 +135,6 @@ export default function RisksPage(props: RisksPageProps) {
field: order.field as
| "NAME"
| "CATEGORY"
| "TREATMENT"
| "INHERENT_RISK_SCORE"
| "RESIDUAL_RISK_SCORE"
| "OWNER_FULL_NAME"
| "CREATED_AT",
},
},
Expand Down Expand Up @@ -230,31 +194,11 @@ export default function RisksPage(props: RisksPageProps) {
</div>
</PageHeader>

<div className="grid grid-cols-2 gap-4">
<RisksChart
organizationId={organizationId}
type="inherent"
risks={chartRisks}
/>
<RisksChart
organizationId={organizationId}
type="residual"
risks={chartRisks}
/>
</div>
<SortableTable {...pagination} refetch={refetch}>
<Thead>
<Tr>
<SortableTh field="NAME">{t("risksPage.columns.name")}</SortableTh>
<SortableTh field="CATEGORY">{t("risksPage.columns.category")}</SortableTh>
<SortableTh field="TREATMENT">{t("risksPage.columns.treatment")}</SortableTh>
<SortableTh field="INHERENT_RISK_SCORE">
{t("risksPage.columns.initialRisk")}
</SortableTh>
<SortableTh field="RESIDUAL_RISK_SCORE">
{t("risksPage.columns.residualRisk")}
</SortableTh>
<SortableTh field="OWNER_FULL_NAME">{t("risksPage.columns.owner")}</SortableTh>
{hasAnyAction && <Th></Th>}
</Tr>
</Thead>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { useToggle } from "@probo/hooks";
import {
Breadcrumb,
Button,
Card,
Dialog,
DialogContent,
DialogFooter,
Expand All @@ -43,8 +42,7 @@ import { graphql } from "relay-runtime";
import type { FormRiskDialog_risk$key } from "#/__generated__/core/FormRiskDialog_risk.graphql";
import type { FormRiskDialogMutation } from "#/__generated__/core/FormRiskDialogMutation.graphql";
import type { FormRiskDialogUpdateRiskMutation } from "#/__generated__/core/FormRiskDialogUpdateRiskMutation.graphql";
import { ControlledField, ControlledSelect } from "#/components/form/ControlledField";
import { PeopleSelectField } from "#/components/form/PeopleSelectField";
import { ControlledSelect } from "#/components/form/ControlledField";
import {
type RiskData,
type RiskForm,
Expand Down Expand Up @@ -74,17 +72,7 @@ const formRiskFragment = graphql`
name
category
description
treatment
inherentLikelihood
inherentImpact
residualLikelihood
residualImpact
inherentRiskScore
residualRiskScore
note
owner {
id
}
}
`;

Expand Down Expand Up @@ -132,15 +120,7 @@ export function FormRiskDialog({
name: risk.name,
category: risk.category,
description: risk.description,
treatment: risk.treatment,
inherentLikelihood: risk.inherentLikelihood,
inherentImpact: risk.inherentImpact,
residualLikelihood: risk.residualLikelihood,
residualImpact: risk.residualImpact,
inherentRiskScore: risk.inherentRiskScore,
residualRiskScore: risk.residualRiskScore,
note: risk.note,
owner: risk.owner,
}
: undefined;
const { control, handleSubmit, setValue, register, watch, formState, reset }
Expand Down Expand Up @@ -231,56 +211,11 @@ export function FormRiskDialog({
placeholder={t("formRiskDialog.placeholders.description")}
type="textarea"
/>

<div className="grid grid-cols-2 gap-6">
<ImpactAndLikelihood
errors={errors}
control={control}
label={t("formRiskDialog.fields.initialRisk")}
prefix="inherent"
/>
<ImpactAndLikelihood
errors={errors}
control={control}
label={t("formRiskDialog.fields.residualRisk")}
prefix="residual"
/>
</div>
</div>

<div className="py-5 px-6 bg-subtle">
<Label>{t("formRiskDialog.properties")}</Label>

<PropertyRow
id="ownerId"
label={t("formRiskDialog.fields.owner")}
error={errors.ownerId?.message}
>
<PeopleSelectField
name="ownerId"
control={control}
organizationId={organizationId}
/>
</PropertyRow>

<PropertyRow
id="treatment"
label={t("formRiskDialog.fields.treatment")}
error={errors.treatment?.message}
>
<ControlledSelect
control={control}
name="treatment"
variant="editor"
placeholder={t("formRiskDialog.placeholders.treatment")}
>
<Option value="AVOIDED">{t("formRiskDialog.treatments.avoided")}</Option>
<Option value="MITIGATED">{t("formRiskDialog.treatments.mitigated")}</Option>
<Option value="TRANSFERRED">{t("formRiskDialog.treatments.transferred")}</Option>
<Option value="ACCEPTED">{t("formRiskDialog.treatments.accepted")}</Option>
</ControlledSelect>
</PropertyRow>

<PropertyRow
id="note"
label={t("formRiskDialog.fields.note")}
Expand Down Expand Up @@ -312,61 +247,6 @@ export function FormRiskDialog({
);
}

function ImpactAndLikelihood({
label,
prefix,
control,
errors,
}: {
label: string;
prefix: "inherent" | "residual";
control: RiskForm["control"];
errors: RiskForm["formState"]["errors"];
}) {
const { t } = useTranslation();
return (
<div>
<Label>{label}</Label>
<Card padded className="space-y-4 p-4">
<ControlledField
control={control}
name={`${prefix}Impact`}
type="select"
label={t("formRiskDialog.fields.impact")}
placeholder={t("formRiskDialog.placeholders.impact")}
error={errors?.[`${prefix}Impact`]?.message}
>
{[1, 2, 3, 4, 5].map(value => (
<Option key={value} value={value.toString()}>
{t("formRiskDialog.scoreOption", {
value,
label: t(`formRiskDialog.impacts.${value}`),
})}
</Option>
))}
</ControlledField>
<ControlledField
control={control}
name={`${prefix}Likelihood`}
type="select"
label={t("formRiskDialog.fields.likelihood")}
placeholder={t("formRiskDialog.placeholders.likelihood")}
error={errors?.[`${prefix}Likelihood`]?.message}
>
{[1, 2, 3, 4, 5].map(value => (
<Option key={value} value={value.toString()}>
{t("formRiskDialog.scoreOption", {
value,
label: t(`formRiskDialog.likelihoods.${value}`),
})}
</Option>
))}
</ControlledField>
</Card>
</div>
);
}

function TemplateSelector({
onChange,
control,
Expand Down
Loading
Loading