From ab54d13b877b3e9c7ddf524c9647632fbfad43b1 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Tue, 17 Jun 2025 17:07:32 +0200 Subject: [PATCH] Add evidence preview url Signed-off-by: Bryan Frimin --- .../MeasureGraphNodeQuery.graphql.ts | 34 ++++---- .../measures/dialog/EvidencePreviewDialog.tsx | 77 +++++++++++++++++++ .../measures/tabs/MeasureEvidencesTab.tsx | 77 +++++++++++++------ .../MeasureEvidencesTabFragment.graphql.ts | 28 ++++++- .../MeasureEvidencesTabQuery.graphql.ts | 36 ++++----- apps/console/src/routes/measureRoutes.ts | 2 +- package.json | 5 +- packages/ui/src/Molecules/Dialog/Dialog.tsx | 12 ++- 8 files changed, 207 insertions(+), 64 deletions(-) create mode 100644 apps/console/src/pages/organizations/measures/dialog/EvidencePreviewDialog.tsx diff --git a/apps/console/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts index 5c83aca2a..94e113d22 100644 --- a/apps/console/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts +++ b/apps/console/src/hooks/graph/__generated__/MeasureGraphNodeQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<7e91345490d4b70ef6668bb6504be1e3>> + * @generated SignedSource<<286a7d808d7a9c793cd9e9b6830cb40b>> * @lightSyntaxTransform * @nogrep */ @@ -598,6 +598,20 @@ return { "name": "filename", "storageKey": null }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "fileUrl", + "storageKey": null + }, + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "mimeType", + "storageKey": null + }, { "alias": null, "args": null, @@ -619,20 +633,6 @@ return { "name": "createdAt", "storageKey": null }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "fileUrl", - "storageKey": null - }, - { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "mimeType", - "storageKey": null - }, (v13/*: any*/) ], "storageKey": null @@ -667,12 +667,12 @@ return { ] }, "params": { - "cacheID": "4a923b265801da22c605af53e744d543", + "cacheID": "c36bf27c7f4d6b3ef4a3e063e4bfccea", "id": null, "metadata": {}, "name": "MeasureGraphNodeQuery", "operationKind": "query", - "text": "query MeasureGraphNodeQuery(\n $measureId: ID!\n) {\n node(id: $measureId) {\n __typename\n ... on Measure {\n id\n name\n description\n state\n category\n evidencesInfos: evidences(first: 0) {\n totalCount\n }\n risksInfos: risks(first: 0) {\n totalCount\n }\n tasksInfos: tasks(first: 0) {\n totalCount\n }\n controlsInfos: controls(first: 0) {\n totalCount\n }\n ...MeasureRisksTabFragment\n ...MeasureTasksTabFragment\n ...MeasureControlsTabFragment\n ...MeasureFormDialogMeasureFragment\n ...MeasureEvidencesTabFragment\n }\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n\nfragment LinkedRisksCardFragment on Risk {\n id\n name\n inherentRiskScore\n residualRiskScore\n}\n\nfragment MeasureControlsTabFragment on Measure {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment on Measure {\n id\n evidences(first: 50) {\n edges {\n node {\n id\n ...MeasureEvidencesTabFragment_evidence\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment_evidence on Evidence {\n id\n filename\n size\n type\n createdAt\n fileUrl\n mimeType\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n\nfragment MeasureRisksTabFragment on Measure {\n id\n risks(first: 100) {\n edges {\n node {\n id\n ...LinkedRisksCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment MeasureTasksTabFragment on Measure {\n tasks(first: 100) {\n edges {\n node {\n id\n name\n state\n description\n ...TaskFormDialogFragment\n assignedTo {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment TaskFormDialogFragment on Task {\n id\n description\n name\n state\n timeEstimate\n deadline\n assignedTo {\n id\n }\n measure {\n id\n }\n}\n" + "text": "query MeasureGraphNodeQuery(\n $measureId: ID!\n) {\n node(id: $measureId) {\n __typename\n ... on Measure {\n id\n name\n description\n state\n category\n evidencesInfos: evidences(first: 0) {\n totalCount\n }\n risksInfos: risks(first: 0) {\n totalCount\n }\n tasksInfos: tasks(first: 0) {\n totalCount\n }\n controlsInfos: controls(first: 0) {\n totalCount\n }\n ...MeasureRisksTabFragment\n ...MeasureTasksTabFragment\n ...MeasureControlsTabFragment\n ...MeasureFormDialogMeasureFragment\n ...MeasureEvidencesTabFragment\n }\n id\n }\n}\n\nfragment LinkedControlsCardFragment on Control {\n id\n name\n sectionTitle\n framework {\n id\n name\n }\n}\n\nfragment LinkedRisksCardFragment on Risk {\n id\n name\n inherentRiskScore\n residualRiskScore\n}\n\nfragment MeasureControlsTabFragment on Measure {\n id\n controls(first: 20) {\n edges {\n node {\n id\n ...LinkedControlsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment on Measure {\n id\n evidences(first: 50) {\n edges {\n node {\n id\n filename\n fileUrl\n mimeType\n ...MeasureEvidencesTabFragment_evidence\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment MeasureEvidencesTabFragment_evidence on Evidence {\n id\n filename\n size\n type\n createdAt\n fileUrl\n mimeType\n}\n\nfragment MeasureFormDialogMeasureFragment on Measure {\n id\n description\n name\n category\n state\n}\n\nfragment MeasureRisksTabFragment on Measure {\n id\n risks(first: 100) {\n edges {\n node {\n id\n ...LinkedRisksCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment MeasureTasksTabFragment on Measure {\n tasks(first: 100) {\n edges {\n node {\n id\n name\n state\n description\n ...TaskFormDialogFragment\n assignedTo {\n id\n fullName\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment TaskFormDialogFragment on Task {\n id\n description\n name\n state\n timeEstimate\n deadline\n assignedTo {\n id\n }\n measure {\n id\n }\n}\n" } }; })(); diff --git a/apps/console/src/pages/organizations/measures/dialog/EvidencePreviewDialog.tsx b/apps/console/src/pages/organizations/measures/dialog/EvidencePreviewDialog.tsx new file mode 100644 index 000000000..2590d2138 --- /dev/null +++ b/apps/console/src/pages/organizations/measures/dialog/EvidencePreviewDialog.tsx @@ -0,0 +1,77 @@ +import { + Button, + Dialog, + DialogContent, + IconArrowInbox, + IconFilter, +} from "@probo/ui"; +import { useTranslate } from "@probo/i18n"; + +type Props = { + evidence: { + filename: string; + fileUrl?: string | null; + mimeType: string; + }; + onClose: () => void; +}; + +export function EvidencePreviewDialog({ evidence, onClose }: Props) { + const { __ } = useTranslate(); + return ( + + +

+ {__( + "Preview of the evidence file. You can view or download the file from here." + )} +

+ +
+
+ ); +} + +function EvidencePreviewContent({ evidence }: Pick) { + const { __ } = useTranslate(); + + if (!evidence.fileUrl) { + return null; + } + + if (evidence.mimeType.startsWith("image/")) { + return ( + {evidence.filename} + ); + } + + if (evidence.mimeType.includes("pdf")) { + return ( +