Skip to content

Commit c9843af

Browse files
committed
Add processing activity exports
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
1 parent 064fde8 commit c9843af

22 files changed

+3960
-209
lines changed

apps/console/src/pages/organizations/processingActivities/ProcessingActivitiesPage.tsx

Lines changed: 190 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import {
1616
useConfirm,
1717
Tabs,
1818
TabItem,
19+
IconArrowDown,
20+
Spinner,
1921
} from "@probo/ui";
2022
import { useTranslate } from "@probo/i18n";
2123
import { usePageTitle } from "@probo/hooks";
@@ -32,7 +34,8 @@ import { useOrganizationId } from "/hooks/useOrganizationId";
3234
import { useParams } from "react-router";
3335
import { CreateProcessingActivityDialog } from "./dialogs/CreateProcessingActivityDialog";
3436
import { deleteProcessingActivityMutation, ProcessingActivitiesConnectionKey, processingActivitiesQuery } from "../../../hooks/graph/ProcessingActivityGraph";
35-
import { sprintf, promisifyMutation } from "@probo/helpers";
37+
import { sprintf, promisifyMutation, downloadFile, toDateInput } from "@probo/helpers";
38+
import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
3639
import { SnapshotBanner } from "/components/SnapshotBanner";
3740
import type { NodeOf } from "/types";
3841
import type {
@@ -174,6 +177,36 @@ const tiaListPageFragment = graphql`
174177
}
175178
`;
176179

180+
const exportProcessingActivitiesPDFMutation = graphql`
181+
mutation ProcessingActivitiesPageExportPDFMutation(
182+
$input: ExportProcessingActivitiesPDFInput!
183+
) {
184+
exportProcessingActivitiesPDF(input: $input) {
185+
data
186+
}
187+
}
188+
`;
189+
190+
const exportDataProtectionImpactAssessmentsPDFMutation = graphql`
191+
mutation ProcessingActivitiesPageExportDPIAPDFMutation(
192+
$input: ExportDataProtectionImpactAssessmentsPDFInput!
193+
) {
194+
exportDataProtectionImpactAssessmentsPDF(input: $input) {
195+
data
196+
}
197+
}
198+
`;
199+
200+
const exportTransferImpactAssessmentsPDFMutation = graphql`
201+
mutation ProcessingActivitiesPageExportTIAPDFMutation(
202+
$input: ExportTransferImpactAssessmentsPDFInput!
203+
) {
204+
exportTransferImpactAssessmentsPDF(input: $input) {
205+
data
206+
}
207+
}
208+
`;
209+
177210
export default function ProcessingActivitiesPage({ queryRef }: ProcessingActivitiesPageProps) {
178211
const { __ } = useTranslate();
179212
const organizationId = useOrganizationId();
@@ -233,6 +266,126 @@ export default function ProcessingActivitiesPage({ queryRef }: ProcessingActivit
233266
isAuthorized("ProcessingActivity", "deleteProcessingActivity")
234267
);
235268

269+
const canExportPDF = !isSnapshotMode && isAuthorized("ProcessingActivity", "exportProcessingActivitiesPDF");
270+
const [exportPDF, isExportingPDF] = useMutationWithToasts<{
271+
response: {
272+
exportProcessingActivitiesPDF?: {
273+
data: string;
274+
};
275+
};
276+
variables: {
277+
input: {
278+
organizationId: string;
279+
filter: { snapshotId: string } | null;
280+
};
281+
};
282+
}>(
283+
exportProcessingActivitiesPDFMutation,
284+
{
285+
successMessage: __("PDF download started."),
286+
errorMessage: __("Failed to generate PDF"),
287+
}
288+
);
289+
290+
const handleExportPDF = () => {
291+
exportPDF({
292+
variables: {
293+
input: {
294+
organizationId: organizationId,
295+
filter: snapshotId ? { snapshotId } : null,
296+
},
297+
},
298+
onCompleted: (data) => {
299+
if (data.exportProcessingActivitiesPDF?.data) {
300+
downloadFile(
301+
data.exportProcessingActivitiesPDF.data,
302+
`processing-activities-${toDateInput(new Date().toISOString())}.pdf`
303+
);
304+
}
305+
},
306+
});
307+
};
308+
309+
const canExportDPIAPDF = !isSnapshotMode && isAuthorized("Organization", "exportDataProtectionImpactAssessmentsPDF");
310+
const [exportDPIAPDF, isExportingDPIAPDF] = useMutationWithToasts<{
311+
response: {
312+
exportDataProtectionImpactAssessmentsPDF?: {
313+
data: string;
314+
};
315+
};
316+
variables: {
317+
input: {
318+
organizationId: string;
319+
filter: { snapshotId: string } | null;
320+
};
321+
};
322+
}>(
323+
exportDataProtectionImpactAssessmentsPDFMutation,
324+
{
325+
successMessage: __("PDF download started."),
326+
errorMessage: __("Failed to generate PDF"),
327+
}
328+
);
329+
330+
const handleExportDPIAPDF = () => {
331+
exportDPIAPDF({
332+
variables: {
333+
input: {
334+
organizationId: organizationId,
335+
filter: snapshotId ? { snapshotId } : null,
336+
},
337+
},
338+
onCompleted: (data) => {
339+
if (data.exportDataProtectionImpactAssessmentsPDF?.data) {
340+
downloadFile(
341+
data.exportDataProtectionImpactAssessmentsPDF.data,
342+
`data-protection-impact-assessments-${toDateInput(new Date().toISOString())}.pdf`
343+
);
344+
}
345+
},
346+
});
347+
};
348+
349+
const canExportTIAPDF = !isSnapshotMode && isAuthorized("Organization", "exportTransferImpactAssessmentsPDF");
350+
const [exportTIAPDF, isExportingTIAPDF] = useMutationWithToasts<{
351+
response: {
352+
exportTransferImpactAssessmentsPDF?: {
353+
data: string;
354+
};
355+
};
356+
variables: {
357+
input: {
358+
organizationId: string;
359+
filter: { snapshotId: string } | null;
360+
};
361+
};
362+
}>(
363+
exportTransferImpactAssessmentsPDFMutation,
364+
{
365+
successMessage: __("PDF download started."),
366+
errorMessage: __("Failed to generate PDF"),
367+
}
368+
);
369+
370+
const handleExportTIAPDF = () => {
371+
exportTIAPDF({
372+
variables: {
373+
input: {
374+
organizationId: organizationId,
375+
filter: snapshotId ? { snapshotId } : null,
376+
},
377+
},
378+
onCompleted: (data) => {
379+
if (data.exportTransferImpactAssessmentsPDF?.data) {
380+
downloadFile(
381+
data.exportTransferImpactAssessmentsPDF.data,
382+
`transfer-impact-assessments-${toDateInput(new Date().toISOString())}.pdf`
383+
);
384+
}
385+
},
386+
});
387+
};
388+
236389
return (
237390
<div className="space-y-6">
238391
{isSnapshotMode && snapshotId && (
@@ -267,6 +420,18 @@ export default function ProcessingActivitiesPage({ queryRef }: ProcessingActivit
267420

268421
{activeTab === "activities" && (
269422
<>
423+
{canExportPDF && (
424+
<div className="flex justify-end mb-2 -mt-4">
425+
<Button
426+
variant="secondary"
427+
icon={isExportingPDF ? Spinner : IconArrowDown}
428+
disabled={isExportingPDF}
429+
onClick={handleExportPDF}
430+
>
431+
{__("Export PDF")}
432+
</Button>
433+
</div>
434+
)}
270435
{activities.length > 0 ? (
271436
<Card>
272437
<Table>
@@ -322,6 +487,18 @@ export default function ProcessingActivitiesPage({ queryRef }: ProcessingActivit
322487

323488
{activeTab === "dpia" && (
324489
<>
490+
{canExportDPIAPDF && (
491+
<div className="flex justify-end mb-2 -mt-4">
492+
<Button
493+
variant="secondary"
494+
icon={isExportingDPIAPDF ? Spinner : IconArrowDown}
495+
disabled={isExportingDPIAPDF}
496+
onClick={handleExportDPIAPDF}
497+
>
498+
{__("Export PDF")}
499+
</Button>
500+
</div>
501+
)}
325502
{dpias.length > 0 ? (
326503
<Card>
327504
<Table>
@@ -369,6 +546,18 @@ export default function ProcessingActivitiesPage({ queryRef }: ProcessingActivit
369546

370547
{activeTab === "tia" && (
371548
<>
549+
{canExportTIAPDF && (
550+
<div className="flex justify-end mb-2 -mt-4">
551+
<Button
552+
variant="secondary"
553+
icon={isExportingTIAPDF ? Spinner : IconArrowDown}
554+
disabled={isExportingTIAPDF}
555+
onClick={handleExportTIAPDF}
556+
>
557+
{__("Export PDF")}
558+
</Button>
559+
</div>
560+
)}
372561
{tias.length > 0 ? (
373562
<Card>
374563
<Table>

apps/console/src/pages/organizations/processingActivities/__generated__/ProcessingActivitiesPageExportDPIAPDFMutation.graphql.ts

Lines changed: 96 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)