Add processing activity registry snapshots

Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
Sacha Al Himdani
2025-08-29 16:59:54 +02:00
parent 433101fce9
commit 612149afc8
29 changed files with 831 additions and 192 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<849144f476ae613437242fe09259fc68>> * @generated SignedSource<<e5b5af0abe1d8af6f97da741084f1b16>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
export type SnapshotBannerQuery$variables = { export type SnapshotBannerQuery$variables = {
snapshotId: string; snapshotId: string;
}; };

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<4856a36194f867773166e9420b403d0b>> * @generated SignedSource<<449a3fe1cc57900bccd7085aa6c4eae8>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type LinkedSnapshotsCardFragment$data = { export type LinkedSnapshotsCardFragment$data = {
readonly createdAt: any; readonly createdAt: any;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<1348b159bfe8d53aa1b080efc63bd1b4>> * @generated SignedSource<<aaed837d3d9cdc303e3096ea7a467bd9>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type LinkedSnapshotsDialogFragment$data = { export type LinkedSnapshotsDialogFragment$data = {
readonly id: string; readonly id: string;

View File

@@ -8,10 +8,10 @@ import { useMutationWithToasts } from "../useMutationWithToasts";
export const ProcessingActivityRegistriesConnectionKey = "ProcessingActivityRegistriesPage_processingActivityRegistries"; export const ProcessingActivityRegistriesConnectionKey = "ProcessingActivityRegistriesPage_processingActivityRegistries";
export const processingActivityRegistriesQuery = graphql` export const processingActivityRegistriesQuery = graphql`
query ProcessingActivityRegistryGraphListQuery($organizationId: ID!) { query ProcessingActivityRegistryGraphListQuery($organizationId: ID!, $snapshotId: ID) {
node(id: $organizationId) { node(id: $organizationId) {
... on Organization { ... on Organization {
...ProcessingActivityRegistriesPageFragment ...ProcessingActivityRegistriesPageFragment @arguments(snapshotId: $snapshotId)
} }
} }
} }
@@ -22,6 +22,7 @@ export const processingActivityRegistryNodeQuery = graphql`
node(id: $processingActivityRegistryId) { node(id: $processingActivityRegistryId) {
... on ProcessingActivityRegistry { ... on ProcessingActivityRegistry {
id id
snapshotId
name name
purpose purpose
dataSubjectCategory dataSubjectCategory

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8f505e33f8bc537835367f0f54547998>> * @generated SignedSource<<c9fc3a1c4c1b2b41057496949cfea3bb>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type ProcessingActivityRegistryGraphListQuery$variables = { export type ProcessingActivityRegistryGraphListQuery$variables = {
organizationId: string; organizationId: string;
snapshotId?: string | null | undefined;
}; };
export type ProcessingActivityRegistryGraphListQuery$data = { export type ProcessingActivityRegistryGraphListQuery$data = {
readonly node: { readonly node: {
@@ -29,6 +30,11 @@ var v0 = [
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "organizationId" "name": "organizationId"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "snapshotId"
} }
], ],
v1 = [ v1 = [
@@ -38,21 +44,33 @@ v1 = [
"variableName": "organizationId" "variableName": "organizationId"
} }
], ],
v2 = { v2 = [
{
"kind": "Variable",
"name": "snapshotId",
"variableName": "snapshotId"
}
],
v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}, },
v4 = [ v5 = [
{
"fields": (v2/*: any*/),
"kind": "ObjectValue",
"name": "filter"
},
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
@@ -78,7 +96,7 @@ return {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{ {
"args": null, "args": (v2/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivityRegistriesPageFragment" "name": "ProcessingActivityRegistriesPageFragment"
} }
@@ -107,14 +125,14 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"concreteType": "ProcessingActivityRegistryConnection", "concreteType": "ProcessingActivityRegistryConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "processingActivityRegistries", "name": "processingActivityRegistries",
@@ -143,7 +161,21 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v4/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "snapshotId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "sourceId",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -207,7 +239,7 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
(v2/*: any*/) (v3/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -259,12 +291,14 @@ return {
] ]
} }
], ],
"storageKey": "processingActivityRegistries(first:10)" "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"filters": null, "filters": [
"filter"
],
"handle": "connection", "handle": "connection",
"key": "ProcessingActivityRegistriesPage_processingActivityRegistries", "key": "ProcessingActivityRegistriesPage_processingActivityRegistries",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -280,16 +314,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "720254aa19136fdf96cc29e26f980533", "cacheID": "47f8a2cccc6749482bf09e1a1a57271d",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityRegistryGraphListQuery", "name": "ProcessingActivityRegistryGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityRegistryGraphListQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...ProcessingActivityRegistriesPageFragment\n }\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment on Organization {\n id\n processingActivityRegistries(first: 10) {\n totalCount\n edges {\n node {\n id\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n" "text": "query ProcessingActivityRegistryGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...ProcessingActivityRegistriesPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment_3iomuz on Organization {\n id\n processingActivityRegistries(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n snapshotId\n sourceId\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "c4a1ee426fd64c8605134d80ee873b62"; (node as any).hash = "5b5316031782bbd4db8109a18b307430";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<e44cc513f256fbae2b03229efc8bd938>> * @generated SignedSource<<4453e7e28a9c546de765219f287f129a>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -37,6 +37,8 @@ export type ProcessingActivityRegistryGraphNodeQuery$data = {
readonly recipients?: string | null | undefined; readonly recipients?: string | null | undefined;
readonly retentionPeriod?: string | null | undefined; readonly retentionPeriod?: string | null | undefined;
readonly securityMeasures?: string | null | undefined; readonly securityMeasures?: string | null | undefined;
readonly snapshotId?: string | null | undefined;
readonly sourceId?: string | null | undefined;
readonly specialOrCriminalData?: ProcessingActivityRegistrySpecialOrCriminalData; readonly specialOrCriminalData?: ProcessingActivityRegistrySpecialOrCriminalData;
readonly transferImpactAssessment?: ProcessingActivityRegistryTransferImpactAssessment; readonly transferImpactAssessment?: ProcessingActivityRegistryTransferImpactAssessment;
readonly transferSafeguards?: ProcessingActivityRegistryTransferSafeguards | null | undefined; readonly transferSafeguards?: ProcessingActivityRegistryTransferSafeguards | null | undefined;
@@ -74,108 +76,122 @@ v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "name", "name": "snapshotId",
"storageKey": null "storageKey": null
}, },
v4 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "purpose", "name": "sourceId",
"storageKey": null "storageKey": null
}, },
v5 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dataSubjectCategory", "name": "name",
"storageKey": null "storageKey": null
}, },
v6 = { v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "personalDataCategory", "name": "purpose",
"storageKey": null "storageKey": null
}, },
v7 = { v7 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "specialOrCriminalData", "name": "dataSubjectCategory",
"storageKey": null "storageKey": null
}, },
v8 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "consentEvidenceLink", "name": "personalDataCategory",
"storageKey": null "storageKey": null
}, },
v9 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "lawfulBasis", "name": "specialOrCriminalData",
"storageKey": null "storageKey": null
}, },
v10 = { v10 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "recipients", "name": "consentEvidenceLink",
"storageKey": null "storageKey": null
}, },
v11 = { v11 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "location", "name": "lawfulBasis",
"storageKey": null "storageKey": null
}, },
v12 = { v12 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "internationalTransfers", "name": "recipients",
"storageKey": null "storageKey": null
}, },
v13 = { v13 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "transferSafeguards", "name": "location",
"storageKey": null "storageKey": null
}, },
v14 = { v14 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "retentionPeriod", "name": "internationalTransfers",
"storageKey": null "storageKey": null
}, },
v15 = { v15 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "securityMeasures", "name": "transferSafeguards",
"storageKey": null "storageKey": null
}, },
v16 = { v16 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "dataProtectionImpactAssessment", "name": "retentionPeriod",
"storageKey": null "storageKey": null
}, },
v17 = { v17 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "transferImpactAssessment", "name": "securityMeasures",
"storageKey": null "storageKey": null
}, },
v18 = { v18 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "dataProtectionImpactAssessment",
"storageKey": null
},
v19 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "transferImpactAssessment",
"storageKey": null
},
v20 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "Organization", "concreteType": "Organization",
@@ -184,18 +200,18 @@ v18 = {
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/) (v5/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
v19 = { v21 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v20 = { v22 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -238,7 +254,9 @@ return {
(v17/*: any*/), (v17/*: any*/),
(v18/*: any*/), (v18/*: any*/),
(v19/*: any*/), (v19/*: any*/),
(v20/*: any*/) (v20/*: any*/),
(v21/*: any*/),
(v22/*: any*/)
], ],
"type": "ProcessingActivityRegistry", "type": "ProcessingActivityRegistry",
"abstractKey": null "abstractKey": null
@@ -292,7 +310,9 @@ return {
(v17/*: any*/), (v17/*: any*/),
(v18/*: any*/), (v18/*: any*/),
(v19/*: any*/), (v19/*: any*/),
(v20/*: any*/) (v20/*: any*/),
(v21/*: any*/),
(v22/*: any*/)
], ],
"type": "ProcessingActivityRegistry", "type": "ProcessingActivityRegistry",
"abstractKey": null "abstractKey": null
@@ -303,16 +323,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "4a2a061717de77346b788a94d5c6b4ef", "cacheID": "b8a3edd61ea5d94cc3594f40f181d27f",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityRegistryGraphNodeQuery", "name": "ProcessingActivityRegistryGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityRegistryGraphNodeQuery(\n $processingActivityRegistryId: ID!\n) {\n node(id: $processingActivityRegistryId) {\n __typename\n ... on ProcessingActivityRegistry {\n id\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n specialOrCriminalData\n consentEvidenceLink\n lawfulBasis\n recipients\n location\n internationalTransfers\n transferSafeguards\n retentionPeriod\n securityMeasures\n dataProtectionImpactAssessment\n transferImpactAssessment\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query ProcessingActivityRegistryGraphNodeQuery(\n $processingActivityRegistryId: ID!\n) {\n node(id: $processingActivityRegistryId) {\n __typename\n ... on ProcessingActivityRegistry {\n id\n snapshotId\n sourceId\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n specialOrCriminalData\n consentEvidenceLink\n lawfulBasis\n recipients\n location\n internationalTransfers\n transferSafeguards\n retentionPeriod\n securityMeasures\n dataProtectionImpactAssessment\n transferImpactAssessment\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "80aa43b56a3258a77b0d1c6c0c9b950d"; (node as any).hash = "6714c1965f54321530f73a5b7ef86fa6";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<0b691997398fc5779891f6ce551192ae>> * @generated SignedSource<<8b949b0eacdf3d9aa1bbd71cbe6af5b0>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
export type CreateSnapshotInput = { export type CreateSnapshotInput = {
description?: string | null | undefined; description?: string | null | undefined;
name: string; name: string;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<202fa0acc16dc4343e193fb3f6784f3c>> * @generated SignedSource<<a8ffaeebdff333e49715088203906cdb>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
export type SnapshotGraphNodeQuery$variables = { export type SnapshotGraphNodeQuery$variables = {
snapshotId: string; snapshotId: string;
}; };

View File

@@ -27,9 +27,11 @@ import {
type PreloadedQuery, type PreloadedQuery,
} from "react-relay"; } from "react-relay";
import { useOrganizationId } from "/hooks/useOrganizationId"; import { useOrganizationId } from "/hooks/useOrganizationId";
import { useParams } from "react-router";
import { CreateProcessingActivityRegistryDialog } from "./dialogs/CreateProcessingActivityRegistryDialog"; import { CreateProcessingActivityRegistryDialog } from "./dialogs/CreateProcessingActivityRegistryDialog";
import { deleteProcessingActivityRegistryMutation, ProcessingActivityRegistriesConnectionKey } from "../../../hooks/graph/ProcessingActivityRegistryGraph"; import { deleteProcessingActivityRegistryMutation, ProcessingActivityRegistriesConnectionKey } from "../../../hooks/graph/ProcessingActivityRegistryGraph";
import { sprintf, promisifyMutation } from "@probo/helpers"; import { sprintf, promisifyMutation } from "@probo/helpers";
import { SnapshotBanner } from "/components/SnapshotBanner";
import type { NodeOf } from "/types"; import type { NodeOf } from "/types";
import type { ProcessingActivityRegistriesPageQuery } from "./__generated__/ProcessingActivityRegistriesPageQuery.graphql"; import type { ProcessingActivityRegistriesPageQuery } from "./__generated__/ProcessingActivityRegistriesPageQuery.graphql";
import type { import type {
@@ -47,15 +49,22 @@ const processingActivityRegistriesPageFragment = graphql`
@argumentDefinitions( @argumentDefinitions(
first: { type: "Int", defaultValue: 10 } first: { type: "Int", defaultValue: 10 }
after: { type: "CursorKey" } after: { type: "CursorKey" }
snapshotId: { type: "ID", defaultValue: null }
) { ) {
id id
processingActivityRegistries(first: $first, after: $after) processingActivityRegistries(
@connection(key: "ProcessingActivityRegistriesPage_processingActivityRegistries") { first: $first
after: $after
filter: { snapshotId: $snapshotId }
)
@connection(key: "ProcessingActivityRegistriesPage_processingActivityRegistries", filters: ["filter"]) {
__id __id
totalCount totalCount
edges { edges {
node { node {
id id
snapshotId
sourceId
name name
purpose purpose
dataSubjectCategory dataSubjectCategory
@@ -78,15 +87,18 @@ const processingActivityRegistriesPageFragment = graphql`
export default function ProcessingActivityRegistriesPage({ queryRef }: ProcessingActivityRegistriesPageProps) { export default function ProcessingActivityRegistriesPage({ queryRef }: ProcessingActivityRegistriesPageProps) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId);
usePageTitle(__("Processing Activity Registries")); usePageTitle(__("Processing Activity Registries"));
const organization = usePreloadedQuery( const organization = usePreloadedQuery(
graphql` graphql`
query ProcessingActivityRegistriesPageQuery($organizationId: ID!) { query ProcessingActivityRegistriesPageQuery($organizationId: ID!, $snapshotId: ID) {
node(id: $organizationId) { node(id: $organizationId) {
... on Organization { ... on Organization {
...ProcessingActivityRegistriesPageFragment ...ProcessingActivityRegistriesPageFragment @arguments(snapshotId: $snapshotId)
} }
} }
} }
@@ -109,13 +121,18 @@ export default function ProcessingActivityRegistriesPage({ queryRef }: Processin
const connectionId = ConnectionHandler.getConnectionID( const connectionId = ConnectionHandler.getConnectionID(
organizationId, organizationId,
ProcessingActivityRegistriesConnectionKey ProcessingActivityRegistriesConnectionKey,
{ filter: { snapshotId: snapshotId || null } }
); );
const registries = data?.processingActivityRegistries?.edges?.map((edge) => edge.node) ?? []; const registries = data?.processingActivityRegistries?.edges?.map((edge) => edge.node) ?? [];
return ( return (
<div className="space-y-6"> <div className="space-y-6">
{isSnapshotMode && snapshotId && (
<SnapshotBanner snapshotId={snapshotId} />
)}
<PageHeader title={__("Processing Activity Registries")} description={__("Manage your processing activity registry entries under GDPR")}> <PageHeader title={__("Processing Activity Registries")} description={__("Manage your processing activity registry entries under GDPR")}>
{!isSnapshotMode && (
<CreateProcessingActivityRegistryDialog <CreateProcessingActivityRegistryDialog
organizationId={organizationId} organizationId={organizationId}
connectionId={connectionId} connectionId={connectionId}
@@ -124,6 +141,7 @@ export default function ProcessingActivityRegistriesPage({ queryRef }: Processin
{__("Add processing activity registry")} {__("Add processing activity registry")}
</Button> </Button>
</CreateProcessingActivityRegistryDialog> </CreateProcessingActivityRegistryDialog>
)}
</PageHeader> </PageHeader>
{registries.length > 0 ? ( {registries.length > 0 ? (
@@ -137,7 +155,7 @@ export default function ProcessingActivityRegistriesPage({ queryRef }: Processin
<Th>{__("Lawful Basis")}</Th> <Th>{__("Lawful Basis")}</Th>
<Th>{__("Location")}</Th> <Th>{__("Location")}</Th>
<Th>{__("International Transfers")}</Th> <Th>{__("International Transfers")}</Th>
<Th>{__("Actions")}</Th> {!isSnapshotMode && <Th>{__("Actions")}</Th>}
</Tr> </Tr>
</Thead> </Thead>
<Tbody> <Tbody>
@@ -188,6 +206,8 @@ function RegistryRow({
}) { }) {
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { __ } = useTranslate(); const { __ } = useTranslate();
const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId);
const [deleteRegistry] = useMutation(deleteProcessingActivityRegistryMutation); const [deleteRegistry] = useMutation(deleteProcessingActivityRegistryMutation);
const confirm = useConfirm(); const confirm = useConfirm();
@@ -213,8 +233,12 @@ function RegistryRow({
); );
}; };
const registryUrl = isSnapshotMode && snapshotId
? `/organizations/${organizationId}/snapshots/${snapshotId}/processing-activity-registries/${registry.id}`
: `/organizations/${organizationId}/processing-activity-registries/${registry.id}`;
return ( return (
<Tr to={`/organizations/${organizationId}/processing-activity-registries/${registry.id}`}> <Tr to={registryUrl}>
<Td> <Td>
<span className="font-semibold">{registry.name}</span> <span className="font-semibold">{registry.name}</span>
</Td> </Td>
@@ -231,6 +255,7 @@ function RegistryRow({
{registry.internationalTransfers ? __("Yes") : __("No")} {registry.internationalTransfers ? __("Yes") : __("No")}
</Badge> </Badge>
</Td> </Td>
{!isSnapshotMode && (
<Td noLink width={50} className="text-end"> <Td noLink width={50} className="text-end">
<ActionDropdown> <ActionDropdown>
<DropdownItem <DropdownItem
@@ -242,6 +267,7 @@ function RegistryRow({
</DropdownItem> </DropdownItem>
</ActionDropdown> </ActionDropdown>
</Td> </Td>
)}
</Tr> </Tr>
); );
} }

View File

@@ -24,9 +24,12 @@ import {
} from "@probo/ui"; } from "@probo/ui";
import { useTranslate } from "@probo/i18n"; import { useTranslate } from "@probo/i18n";
import { useOrganizationId } from "/hooks/useOrganizationId"; import { useOrganizationId } from "/hooks/useOrganizationId";
import { useParams } from "react-router";
import { useFormWithSchema } from "/hooks/useFormWithSchema"; import { useFormWithSchema } from "/hooks/useFormWithSchema";
import { Controller } from "react-hook-form"; import { Controller } from "react-hook-form";
import z from "zod"; import z from "zod";
import { validateSnapshotConsistency } from "@probo/helpers";
import { SnapshotBanner } from "/components/SnapshotBanner";
import { import {
SpecialOrCriminalDataOptions, SpecialOrCriminalDataOptions,
LawfulBasisOptions, LawfulBasisOptions,
@@ -65,16 +68,21 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const { toast } = useToast(); const { toast } = useToast();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId);
if (!registry) { if (!registry) {
return <div>{__("Processing activity registry entry not found")}</div>; return <div>{__("Processing activity registry entry not found")}</div>;
} }
validateSnapshotConsistency(registry, snapshotId);
const updateRegistry = useUpdateProcessingActivityRegistry(); const updateRegistry = useUpdateProcessingActivityRegistry();
const connectionId = ConnectionHandler.getConnectionID( const connectionId = ConnectionHandler.getConnectionID(
organizationId, organizationId,
ProcessingActivityRegistriesConnectionKey ProcessingActivityRegistriesConnectionKey,
{ filter: { snapshotId: snapshotId || null } }
); );
const deleteRegistry = useDeleteProcessingActivityRegistry({ id: registry.id!, name: registry.name! }, connectionId); const deleteRegistry = useDeleteProcessingActivityRegistry({ id: registry.id!, name: registry.name! }, connectionId);
@@ -137,20 +145,29 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
} }
}); });
const breadcrumbRegistriesUrl = isSnapshotMode && snapshotId
? `/organizations/${organizationId}/snapshots/${snapshotId}/processing-activity-registries`
: `/organizations/${organizationId}/processing-activity-registries`;
return ( return (
<div className="space-y-6"> <div className="space-y-6">
{isSnapshotMode && snapshotId && (
<SnapshotBanner snapshotId={snapshotId} />
)}
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Breadcrumb <Breadcrumb
items={[ items={[
{ label: __("Processing Activity Registries"), to: "../processing-activity-registries" }, { label: __("Processing Activity Registries"), to: breadcrumbRegistriesUrl },
{ label: registry.name! }, { label: registry.name! },
]} ]}
/> />
{!isSnapshotMode && (
<ActionDropdown> <ActionDropdown>
<DropdownItem onClick={deleteRegistry} variant="danger"> <DropdownItem onClick={deleteRegistry} variant="danger">
{__("Delete")} {__("Delete")}
</DropdownItem> </DropdownItem>
</ActionDropdown> </ActionDropdown>
)}
</div> </div>
<Card> <Card>
@@ -169,6 +186,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
{...register("name")} {...register("name")}
error={formState.errors.name?.message} error={formState.errors.name?.message}
required required
disabled={isSnapshotMode}
/> />
<div> <div>
@@ -177,6 +195,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
{...register("purpose")} {...register("purpose")}
placeholder={__("Describe the purpose of processing")} placeholder={__("Describe the purpose of processing")}
rows={3} rows={3}
disabled={isSnapshotMode}
/> />
</div> </div>
@@ -184,12 +203,14 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
label={__("Data Subject Category")} label={__("Data Subject Category")}
{...register("dataSubjectCategory")} {...register("dataSubjectCategory")}
placeholder={__("e.g., employees, customers, prospects")} placeholder={__("e.g., employees, customers, prospects")}
disabled={isSnapshotMode}
/> />
<Field <Field
label={__("Personal Data Category")} label={__("Personal Data Category")}
{...register("personalDataCategory")} {...register("personalDataCategory")}
placeholder={__("e.g., contact details, financial data")} placeholder={__("e.g., contact details, financial data")}
disabled={isSnapshotMode}
/> />
<div> <div>
@@ -204,6 +225,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode}
> >
<SpecialOrCriminalDataOptions /> <SpecialOrCriminalDataOptions />
</Select> </Select>
@@ -218,6 +240,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
label={__("Consent Evidence Link")} label={__("Consent Evidence Link")}
{...register("consentEvidenceLink")} {...register("consentEvidenceLink")}
placeholder={__("Link to consent evidence if applicable")} placeholder={__("Link to consent evidence if applicable")}
disabled={isSnapshotMode}
/> />
<div> <div>
@@ -232,6 +255,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode}
> >
<LawfulBasisOptions /> <LawfulBasisOptions />
</Select> </Select>
@@ -248,12 +272,14 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
label={__("Recipients")} label={__("Recipients")}
{...register("recipients")} {...register("recipients")}
placeholder={__("Who receives the data")} placeholder={__("Who receives the data")}
disabled={isSnapshotMode}
/> />
<Field <Field
label={__("Location")} label={__("Location")}
{...register("location")} {...register("location")}
placeholder={__("Where is the data processed")} placeholder={__("Where is the data processed")}
disabled={isSnapshotMode}
/> />
<Controller <Controller
@@ -266,6 +292,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
<Checkbox <Checkbox
checked={field.value} checked={field.value}
onChange={field.onChange} onChange={field.onChange}
disabled={isSnapshotMode}
/> />
<span>{__("Data is transferred internationally")}</span> <span>{__("Data is transferred internationally")}</span>
</div> </div>
@@ -285,6 +312,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode}
> >
<TransferSafeguardsOptions /> <TransferSafeguardsOptions />
</Select> </Select>
@@ -299,6 +327,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
label={__("Retention Period")} label={__("Retention Period")}
{...register("retentionPeriod")} {...register("retentionPeriod")}
placeholder={__("How long is data retained")} placeholder={__("How long is data retained")}
disabled={isSnapshotMode}
/> />
<div> <div>
@@ -307,6 +336,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
{...register("securityMeasures")} {...register("securityMeasures")}
placeholder={__("Technical and organizational measures")} placeholder={__("Technical and organizational measures")}
rows={3} rows={3}
disabled={isSnapshotMode}
/> />
</div> </div>
@@ -322,6 +352,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode}
> >
<DataProtectionImpactAssessmentOptions /> <DataProtectionImpactAssessmentOptions />
</Select> </Select>
@@ -344,6 +375,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode}
> >
<TransferImpactAssessmentOptions /> <TransferImpactAssessmentOptions />
</Select> </Select>
@@ -356,6 +388,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
</div> </div>
</div> </div>
{!isSnapshotMode && (
<div className="flex justify-end pt-4"> <div className="flex justify-end pt-4">
<Button <Button
type="submit" type="submit"
@@ -365,6 +398,7 @@ export default function ProcessingActivityRegistryDetailsPage(props: Props) {
{formState.isSubmitting ? __("Saving...") : __("Save Changes")} {formState.isSubmitting ? __("Saving...") : __("Save Changes")}
</Button> </Button>
</div> </div>
)}
</form> </form>
</div> </div>
</Card> </Card>

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<f2595590d945925932f5093a2c76dd1b>> * @generated SignedSource<<138a897eea1aa78073db58d717fe2947>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -26,6 +26,8 @@ export type ProcessingActivityRegistriesPageFragment$data = {
readonly name: string; readonly name: string;
readonly personalDataCategory: string | null | undefined; readonly personalDataCategory: string | null | undefined;
readonly purpose: string | null | undefined; readonly purpose: string | null | undefined;
readonly snapshotId: string | null | undefined;
readonly sourceId: string | null | undefined;
readonly updatedAt: any; readonly updatedAt: any;
}; };
}>; }>;
@@ -66,6 +68,11 @@ return {
"defaultValue": 10, "defaultValue": 10,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "first" "name": "first"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "snapshotId"
} }
], ],
"kind": "Fragment", "kind": "Fragment",
@@ -102,7 +109,19 @@ return {
(v1/*: any*/), (v1/*: any*/),
{ {
"alias": "processingActivityRegistries", "alias": "processingActivityRegistries",
"args": null, "args": [
{
"fields": [
{
"kind": "Variable",
"name": "snapshotId",
"variableName": "snapshotId"
}
],
"kind": "ObjectValue",
"name": "filter"
}
],
"concreteType": "ProcessingActivityRegistryConnection", "concreteType": "ProcessingActivityRegistryConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "__ProcessingActivityRegistriesPage_processingActivityRegistries_connection", "name": "__ProcessingActivityRegistriesPage_processingActivityRegistries_connection",
@@ -132,6 +151,20 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v1/*: any*/), (v1/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "snapshotId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "sourceId",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -261,6 +294,6 @@ return {
}; };
})(); })();
(node as any).hash = "25222b5244115092f96c424d8a52a5db"; (node as any).hash = "a31cad7de09ddd436e7fa9068d53e05e";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<71dfd7c0d78070061957215363022475>> * @generated SignedSource<<e77ebb6a609b6122e9c6927f4e00acc4>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,7 @@ import { ConcreteRequest } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type ProcessingActivityRegistriesPageQuery$variables = { export type ProcessingActivityRegistriesPageQuery$variables = {
organizationId: string; organizationId: string;
snapshotId?: string | null | undefined;
}; };
export type ProcessingActivityRegistriesPageQuery$data = { export type ProcessingActivityRegistriesPageQuery$data = {
readonly node: { readonly node: {
@@ -29,6 +30,11 @@ var v0 = [
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "organizationId" "name": "organizationId"
},
{
"defaultValue": null,
"kind": "LocalArgument",
"name": "snapshotId"
} }
], ],
v1 = [ v1 = [
@@ -38,21 +44,33 @@ v1 = [
"variableName": "organizationId" "variableName": "organizationId"
} }
], ],
v2 = { v2 = [
{
"kind": "Variable",
"name": "snapshotId",
"variableName": "snapshotId"
}
],
v3 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}, },
v4 = [ v5 = [
{
"fields": (v2/*: any*/),
"kind": "ObjectValue",
"name": "filter"
},
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
@@ -78,7 +96,7 @@ return {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{ {
"args": null, "args": (v2/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivityRegistriesPageFragment" "name": "ProcessingActivityRegistriesPageFragment"
} }
@@ -107,14 +125,14 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v4/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"concreteType": "ProcessingActivityRegistryConnection", "concreteType": "ProcessingActivityRegistryConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "processingActivityRegistries", "name": "processingActivityRegistries",
@@ -143,7 +161,21 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v4/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "snapshotId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "sourceId",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -207,7 +239,7 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
(v2/*: any*/) (v3/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -259,12 +291,14 @@ return {
] ]
} }
], ],
"storageKey": "processingActivityRegistries(first:10)" "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": (v4/*: any*/), "args": (v5/*: any*/),
"filters": null, "filters": [
"filter"
],
"handle": "connection", "handle": "connection",
"key": "ProcessingActivityRegistriesPage_processingActivityRegistries", "key": "ProcessingActivityRegistriesPage_processingActivityRegistries",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -280,16 +314,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "331d1a749711d7a519fbdc5a721d2cec", "cacheID": "2b5cf834c7b4f34bb4a8e74705d1e530",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityRegistriesPageQuery", "name": "ProcessingActivityRegistriesPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityRegistriesPageQuery(\n $organizationId: ID!\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...ProcessingActivityRegistriesPageFragment\n }\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment on Organization {\n id\n processingActivityRegistries(first: 10) {\n totalCount\n edges {\n node {\n id\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n" "text": "query ProcessingActivityRegistriesPageQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...ProcessingActivityRegistriesPageFragment_3iomuz\n }\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment_3iomuz on Organization {\n id\n processingActivityRegistries(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n snapshotId\n sourceId\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "2d99b77d24e6583cb93580fdbf47ffb3"; (node as any).hash = "a4030e6ab7ce0351b431ce90d0440135";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<3ad73dde5a41f4370035f6156fc1f38b>> * @generated SignedSource<<fc4bc917b12579179eb09cc4919b1b57>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -14,6 +14,7 @@ export type ProcessingActivityRegistriesPageRefetchQuery$variables = {
after?: any | null | undefined; after?: any | null | undefined;
first?: number | null | undefined; first?: number | null | undefined;
id: string; id: string;
snapshotId?: string | null | undefined;
}; };
export type ProcessingActivityRegistriesPageRefetchQuery$data = { export type ProcessingActivityRegistriesPageRefetchQuery$data = {
readonly node: { readonly node: {
@@ -26,73 +27,99 @@ export type ProcessingActivityRegistriesPageRefetchQuery = {
}; };
const node: ConcreteRequest = (function(){ const node: ConcreteRequest = (function(){
var v0 = [ var v0 = {
{
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "after" "name": "after"
}, },
{ v1 = {
"defaultValue": 10, "defaultValue": 10,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "first" "name": "first"
}, },
{ v2 = {
"defaultValue": null, "defaultValue": null,
"kind": "LocalArgument", "kind": "LocalArgument",
"name": "id" "name": "id"
} },
], v3 = {
v1 = [ "defaultValue": null,
"kind": "LocalArgument",
"name": "snapshotId"
},
v4 = [
{ {
"kind": "Variable", "kind": "Variable",
"name": "id", "name": "id",
"variableName": "id" "variableName": "id"
} }
], ],
v2 = [ v5 = {
{
"kind": "Variable", "kind": "Variable",
"name": "after", "name": "after",
"variableName": "after" "variableName": "after"
}, },
{ v6 = {
"kind": "Variable", "kind": "Variable",
"name": "first", "name": "first",
"variableName": "first" "variableName": "first"
} },
], v7 = {
v3 = { "kind": "Variable",
"name": "snapshotId",
"variableName": "snapshotId"
},
v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v4 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}; },
v10 = [
(v5/*: any*/),
{
"fields": [
(v7/*: any*/)
],
"kind": "ObjectValue",
"name": "filter"
},
(v6/*: any*/)
];
return { return {
"fragment": { "fragment": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v2/*: any*/),
(v3/*: any*/)
],
"kind": "Fragment", "kind": "Fragment",
"metadata": null, "metadata": null,
"name": "ProcessingActivityRegistriesPageRefetchQuery", "name": "ProcessingActivityRegistriesPageRefetchQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v1/*: any*/), "args": (v4/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
{ {
"args": (v2/*: any*/), "args": [
(v5/*: any*/),
(v6/*: any*/),
(v7/*: any*/)
],
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivityRegistriesPageFragment" "name": "ProcessingActivityRegistriesPageFragment"
} }
@@ -105,26 +132,31 @@ return {
}, },
"kind": "Request", "kind": "Request",
"operation": { "operation": {
"argumentDefinitions": (v0/*: any*/), "argumentDefinitions": [
(v0/*: any*/),
(v1/*: any*/),
(v3/*: any*/),
(v2/*: any*/)
],
"kind": "Operation", "kind": "Operation",
"name": "ProcessingActivityRegistriesPageRefetchQuery", "name": "ProcessingActivityRegistriesPageRefetchQuery",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v1/*: any*/), "args": (v4/*: any*/),
"concreteType": null, "concreteType": null,
"kind": "LinkedField", "kind": "LinkedField",
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v8/*: any*/),
(v4/*: any*/), (v9/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{ {
"alias": null, "alias": null,
"args": (v2/*: any*/), "args": (v10/*: any*/),
"concreteType": "ProcessingActivityRegistryConnection", "concreteType": "ProcessingActivityRegistryConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "processingActivityRegistries", "name": "processingActivityRegistries",
@@ -153,7 +185,21 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v9/*: any*/),
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "snapshotId",
"storageKey": null
},
{
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "sourceId",
"storageKey": null
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -217,7 +263,7 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
(v3/*: any*/) (v8/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -273,8 +319,10 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v2/*: any*/), "args": (v10/*: any*/),
"filters": null, "filters": [
"filter"
],
"handle": "connection", "handle": "connection",
"key": "ProcessingActivityRegistriesPage_processingActivityRegistries", "key": "ProcessingActivityRegistriesPage_processingActivityRegistries",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -290,16 +338,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "1d359fcdec190d343db1cef8c01c7672", "cacheID": "f6f29dda67221647df6a500c124091a2",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityRegistriesPageRefetchQuery", "name": "ProcessingActivityRegistriesPageRefetchQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityRegistriesPageRefetchQuery(\n $after: CursorKey\n $first: Int = 10\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ProcessingActivityRegistriesPageFragment_2HEEH6\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment_2HEEH6 on Organization {\n id\n processingActivityRegistries(first: $first, after: $after) {\n totalCount\n edges {\n node {\n id\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n" "text": "query ProcessingActivityRegistriesPageRefetchQuery(\n $after: CursorKey\n $first: Int = 10\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ProcessingActivityRegistriesPageFragment_35e0S5\n id\n }\n}\n\nfragment ProcessingActivityRegistriesPageFragment_35e0S5 on Organization {\n id\n processingActivityRegistries(first: $first, after: $after, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n snapshotId\n sourceId\n name\n purpose\n dataSubjectCategory\n personalDataCategory\n lawfulBasis\n location\n internationalTransfers\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "25222b5244115092f96c424d8a52a5db"; (node as any).hash = "a31cad7de09ddd436e7fa9068d53e05e";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<e89d235e5971b278e9826d421b4a680c>> * @generated SignedSource<<dc710d55da977c21a12e3e21f29fbe94>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type SnapshotsPageFragment$data = { export type SnapshotsPageFragment$data = {
readonly snapshots: { readonly snapshots: {

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8e3f14794ab1cbd6c2e67ab4eb8ac373>> * @generated SignedSource<<50dda5d856ca750f1e85a8c1d2935c9c>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -9,7 +9,7 @@
// @ts-nocheck // @ts-nocheck
import { ConcreteRequest } from 'relay-runtime'; import { ConcreteRequest } from 'relay-runtime';
export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "RISKS" | "VENDORS"; export type SnapshotsType = "ASSETS" | "COMPLIANCE_REGISTRIES" | "CONTINUAL_IMPROVEMENT_REGISTRIES" | "DATA" | "NONCONFORMITY_REGISTRIES" | "PROCESSING_ACTIVITY_REGISTRIES" | "RISKS" | "VENDORS";
export type CreateSnapshotInput = { export type CreateSnapshotInput = {
description?: string | null | undefined; description?: string | null | undefined;
name: string; name: string;

View File

@@ -9,8 +9,23 @@ export const processingActivityRegistryRoutes = [
{ {
path: "processing-activity-registries", path: "processing-activity-registries",
fallback: PageSkeleton, fallback: PageSkeleton,
queryLoader: ({ organizationId }: { organizationId: string }) => queryLoader: (params: Record<string, string>) =>
loadQuery(relayEnvironment, processingActivityRegistriesQuery, { organizationId }), loadQuery(relayEnvironment, processingActivityRegistriesQuery, {
organizationId: params.organizationId,
snapshotId: null
}),
Component: lazy(
() => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistriesPage")
),
},
{
path: "snapshots/:snapshotId/processing-activity-registries",
fallback: PageSkeleton,
queryLoader: (params: Record<string, string>) =>
loadQuery(relayEnvironment, processingActivityRegistriesQuery, {
organizationId: params.organizationId,
snapshotId: params.snapshotId
}),
Component: lazy( Component: lazy(
() => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistriesPage") () => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistriesPage")
), ),
@@ -26,4 +41,15 @@ export const processingActivityRegistryRoutes = [
() => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistryDetailsPage") () => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistryDetailsPage")
), ),
}, },
{
path: "snapshots/:snapshotId/processing-activity-registries/:registryId",
fallback: PageSkeleton,
queryLoader: (params: Record<string, string>) =>
loadQuery(relayEnvironment, processingActivityRegistryNodeQuery, {
processingActivityRegistryId: params.registryId
}),
Component: lazy(
() => import("/pages/organizations/processingActivityRegistries/ProcessingActivityRegistryDetailsPage")
),
},
] satisfies AppRoute[]; ] satisfies AppRoute[];

View File

@@ -5,6 +5,7 @@ export const snapshotTypes = [
"NONCONFORMITY_REGISTRIES", "NONCONFORMITY_REGISTRIES",
"COMPLIANCE_REGISTRIES", "COMPLIANCE_REGISTRIES",
"CONTINUAL_IMPROVEMENT_REGISTRIES", "CONTINUAL_IMPROVEMENT_REGISTRIES",
"PROCESSING_ACTIVITY_REGISTRIES",
] as const; ] as const;
export function getSnapshotTypeLabel(__: Translator, type: string | null | undefined) { export function getSnapshotTypeLabel(__: Translator, type: string | null | undefined) {
@@ -27,6 +28,8 @@ export function getSnapshotTypeLabel(__: Translator, type: string | null | undef
return __("Compliance Registries"); return __("Compliance Registries");
case "CONTINUAL_IMPROVEMENT_REGISTRIES": case "CONTINUAL_IMPROVEMENT_REGISTRIES":
return __("Continual Improvement Registries"); return __("Continual Improvement Registries");
case "PROCESSING_ACTIVITY_REGISTRIES":
return __("Processing Activity Registries");
default: default:
return __("Unknown"); return __("Unknown");
} }
@@ -42,6 +45,8 @@ export function getSnapshotTypeUrlPath(type?: string): string {
return "/compliance-registries"; return "/compliance-registries";
case "CONTINUAL_IMPROVEMENT_REGISTRIES": case "CONTINUAL_IMPROVEMENT_REGISTRIES":
return "/continual-improvement-registries"; return "/continual-improvement-registries";
case "PROCESSING_ACTIVITY_REGISTRIES":
return "/processing-activity-registries";
default: default:
return ""; return "";
} }

View File

@@ -5,6 +5,7 @@ import { IconCheckmark1 } from "../Icons";
type Props = { type Props = {
checked: boolean; checked: boolean;
onChange: (checked: boolean) => void; onChange: (checked: boolean) => void;
disabled?: boolean;
}; };
const checkbox = tv({ const checkbox = tv({
@@ -16,19 +17,23 @@ const checkbox = tv({
checked: { checked: {
true: "bg-accent text-invert", true: "bg-accent text-invert",
}, },
disabled: {
true: "opacity-50 cursor-not-allowed",
},
}, },
}); });
export function Checkbox({ checked, onChange }: Props) { export function Checkbox({ checked, onChange, disabled = false }: Props) {
const [isFocused, setFocus] = useState(false); const [isFocused, setFocus] = useState(false);
return ( return (
<div className={checkbox({ isFocused, checked })}> <div className={checkbox({ isFocused, checked, disabled })}>
<input <input
className="absolute inset-0 opacity-0" className="absolute inset-0 opacity-0"
type="checkbox" type="checkbox"
checked={checked} checked={checked}
onChange={(e) => onChange(e.target.checked)} disabled={disabled}
onFocus={() => setFocus(true)} onChange={(e) => !disabled && onChange(e.target.checked)}
onFocus={() => !disabled && setFocus(true)}
onBlur={() => setFocus(false)} onBlur={() => setFocus(false)}
/> />
{checked && <IconCheckmark1 size={12} />} {checked && <IconCheckmark1 size={12} />}

View File

@@ -0,0 +1,13 @@
ALTER TYPE snapshots_type ADD VALUE 'PROCESSING_ACTIVITY_REGISTRIES';
ALTER TABLE processing_activity_registries ADD COLUMN snapshot_id TEXT;
ALTER TABLE processing_activity_registries ADD COLUMN source_id TEXT;
ALTER TABLE processing_activity_registries ADD CONSTRAINT processing_activity_registries_snapshot_id_fkey
FOREIGN KEY (snapshot_id)
REFERENCES snapshots(id)
ON UPDATE CASCADE
ON DELETE CASCADE;
ALTER TABLE processing_activity_registries ADD CONSTRAINT processing_activity_registries_source_id_snapshot_id_key
UNIQUE (source_id, snapshot_id);

View File

@@ -29,6 +29,8 @@ import (
type ( type (
ProcessingActivityRegistry struct { ProcessingActivityRegistry struct {
ID gid.GID `db:"id"` ID gid.GID `db:"id"`
SnapshotID *gid.GID `db:"snapshot_id"`
SourceID *gid.GID `db:"source_id"`
OrganizationID gid.GID `db:"organization_id"` OrganizationID gid.GID `db:"organization_id"`
Name string `db:"name"` Name string `db:"name"`
Purpose *string `db:"purpose"` Purpose *string `db:"purpose"`
@@ -72,6 +74,8 @@ func (p *ProcessingActivityRegistry) LoadByID(
q := ` q := `
SELECT SELECT
id, id,
snapshot_id,
source_id,
organization_id, organization_id,
name, name,
purpose, purpose,
@@ -123,6 +127,7 @@ func (p *ProcessingActivityRegistries) CountByOrganizationID(
conn pg.Conn, conn pg.Conn,
scope Scoper, scope Scoper,
organizationID gid.GID, organizationID gid.GID,
filter *ProcessingActivityRegistryFilter,
) (int, error) { ) (int, error) {
q := ` q := `
SELECT SELECT
@@ -132,12 +137,14 @@ FROM
WHERE WHERE
%s %s
AND organization_id = @organization_id AND organization_id = @organization_id
AND %s
` `
q = fmt.Sprintf(q, scope.SQLFragment()) q = fmt.Sprintf(q, scope.SQLFragment(), filter.SQLFragment())
args := pgx.StrictNamedArgs{"organization_id": organizationID} args := pgx.StrictNamedArgs{"organization_id": organizationID}
maps.Copy(args, scope.SQLArguments()) maps.Copy(args, scope.SQLArguments())
maps.Copy(args, filter.SQLArguments())
row := conn.QueryRow(ctx, q, args) row := conn.QueryRow(ctx, q, args)
@@ -156,10 +163,13 @@ func (p *ProcessingActivityRegistries) LoadByOrganizationID(
scope Scoper, scope Scoper,
organizationID gid.GID, organizationID gid.GID,
cursor *page.Cursor[ProcessingActivityRegistryOrderField], cursor *page.Cursor[ProcessingActivityRegistryOrderField],
filter *ProcessingActivityRegistryFilter,
) error { ) error {
q := ` q := `
SELECT SELECT
id, id,
snapshot_id,
source_id,
organization_id, organization_id,
name, name,
purpose, purpose,
@@ -184,12 +194,14 @@ WHERE
%s %s
AND organization_id = @organization_id AND organization_id = @organization_id
AND %s AND %s
AND %s
` `
q = fmt.Sprintf(q, scope.SQLFragment(), cursor.SQLFragment()) q = fmt.Sprintf(q, scope.SQLFragment(), filter.SQLFragment(), cursor.SQLFragment())
args := pgx.StrictNamedArgs{"organization_id": organizationID} args := pgx.StrictNamedArgs{"organization_id": organizationID}
maps.Copy(args, scope.SQLArguments()) maps.Copy(args, scope.SQLArguments())
maps.Copy(args, filter.SQLArguments())
maps.Copy(args, cursor.SQLArguments()) maps.Copy(args, cursor.SQLArguments())
rows, err := conn.Query(ctx, q, args) rows, err := conn.Query(ctx, q, args)
@@ -216,6 +228,8 @@ func (p *ProcessingActivityRegistry) Insert(
INSERT INTO processing_activity_registries ( INSERT INTO processing_activity_registries (
id, id,
tenant_id, tenant_id,
snapshot_id,
source_id,
organization_id, organization_id,
name, name,
purpose, purpose,
@@ -237,6 +251,8 @@ INSERT INTO processing_activity_registries (
) VALUES ( ) VALUES (
@id, @id,
@tenant_id, @tenant_id,
@snapshot_id,
@source_id,
@organization_id, @organization_id,
@name, @name,
@purpose, @purpose,
@@ -261,6 +277,8 @@ INSERT INTO processing_activity_registries (
args := pgx.StrictNamedArgs{ args := pgx.StrictNamedArgs{
"id": p.ID, "id": p.ID,
"tenant_id": scope.GetTenantID(), "tenant_id": scope.GetTenantID(),
"snapshot_id": p.SnapshotID,
"source_id": p.SourceID,
"organization_id": p.OrganizationID, "organization_id": p.OrganizationID,
"name": p.Name, "name": p.Name,
"purpose": p.Purpose, "purpose": p.Purpose,
@@ -316,6 +334,7 @@ SET
WHERE WHERE
%s %s
AND id = @id AND id = @id
AND snapshot_id IS NULL
` `
q = fmt.Sprintf(q, scope.SQLFragment()) q = fmt.Sprintf(q, scope.SQLFragment())
@@ -359,6 +378,7 @@ DELETE FROM processing_activity_registries
WHERE WHERE
%s %s
AND id = @id AND id = @id
AND snapshot_id IS NULL
` `
q = fmt.Sprintf(q, scope.SQLFragment()) q = fmt.Sprintf(q, scope.SQLFragment())
@@ -373,3 +393,74 @@ WHERE
return nil return nil
} }
func (pars ProcessingActivityRegistries) Snapshot(ctx context.Context, conn pg.Conn, scope Scoper, organizationID, snapshotID gid.GID) error {
query := `
INSERT INTO processing_activity_registries (
id,
tenant_id,
snapshot_id,
source_id,
organization_id,
name,
purpose,
data_subject_category,
personal_data_category,
special_or_criminal_data,
consent_evidence_link,
lawful_basis,
recipients,
location,
international_transfers,
transfer_safeguards,
retention_period,
security_measures,
data_protection_impact_assessment,
transfer_impact_assessment,
created_at,
updated_at
)
SELECT
generate_gid(decode_base64_unpadded(@tenant_id), @processing_activity_registry_entity_type),
@tenant_id,
@snapshot_id,
par.id,
par.organization_id,
par.name,
par.purpose,
par.data_subject_category,
par.personal_data_category,
par.special_or_criminal_data,
par.consent_evidence_link,
par.lawful_basis,
par.recipients,
par.location,
par.international_transfers,
par.transfer_safeguards,
par.retention_period,
par.security_measures,
par.data_protection_impact_assessment,
par.transfer_impact_assessment,
par.created_at,
par.updated_at
FROM processing_activity_registries par
WHERE %s AND par.organization_id = @organization_id AND par.snapshot_id IS NULL
`
query = fmt.Sprintf(query, scope.SQLFragment())
args := pgx.StrictNamedArgs{
"tenant_id": scope.GetTenantID(),
"snapshot_id": snapshotID,
"organization_id": organizationID,
"processing_activity_registry_entity_type": ProcessingActivityRegistryEntityType,
}
maps.Copy(args, scope.SQLArguments())
_, err := conn.Exec(ctx, query, args)
if err != nil {
return fmt.Errorf("cannot insert processing activity registry snapshots: %w", err)
}
return nil
}

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
package coredata
import (
"github.com/getprobo/probo/pkg/gid"
"github.com/jackc/pgx/v5"
)
type (
ProcessingActivityRegistryFilter struct {
snapshotID **gid.GID
}
)
func NewProcessingActivityRegistryFilter(snapshotID **gid.GID) *ProcessingActivityRegistryFilter {
return &ProcessingActivityRegistryFilter{
snapshotID: snapshotID,
}
}
func (f *ProcessingActivityRegistryFilter) SQLArguments() pgx.NamedArgs {
args := pgx.NamedArgs{}
if f.snapshotID != nil && *f.snapshotID != nil {
args["filter_snapshot_id"] = **f.snapshotID
}
return args
}
func (f *ProcessingActivityRegistryFilter) SQLFragment() string {
if f.snapshotID == nil {
return "TRUE"
}
if *f.snapshotID == nil {
return "snapshot_id IS NULL"
} else {
return "snapshot_id = @filter_snapshot_id"
}
}

View File

@@ -31,6 +31,7 @@ const (
SnapshotsTypeNonConformityRegistries SnapshotsType = "NONCONFORMITY_REGISTRIES" SnapshotsTypeNonConformityRegistries SnapshotsType = "NONCONFORMITY_REGISTRIES"
SnapshotsTypeComplianceRegistries SnapshotsType = "COMPLIANCE_REGISTRIES" SnapshotsTypeComplianceRegistries SnapshotsType = "COMPLIANCE_REGISTRIES"
SnapshotsTypeContinualImprovementRegistries SnapshotsType = "CONTINUAL_IMPROVEMENT_REGISTRIES" SnapshotsTypeContinualImprovementRegistries SnapshotsType = "CONTINUAL_IMPROVEMENT_REGISTRIES"
SnapshotsTypeProcessingActivityRegistries SnapshotsType = "PROCESSING_ACTIVITY_REGISTRIES"
) )
func (st SnapshotsType) String() string { func (st SnapshotsType) String() string {
@@ -63,6 +64,8 @@ func (st *SnapshotsType) Scan(value any) error {
*st = SnapshotsTypeComplianceRegistries *st = SnapshotsTypeComplianceRegistries
case SnapshotsTypeContinualImprovementRegistries.String(): case SnapshotsTypeContinualImprovementRegistries.String():
*st = SnapshotsTypeContinualImprovementRegistries *st = SnapshotsTypeContinualImprovementRegistries
case SnapshotsTypeProcessingActivityRegistries.String():
*st = SnapshotsTypeProcessingActivityRegistries
default: default:
return fmt.Errorf("invalid SnapshotsType value: %q", s) return fmt.Errorf("invalid SnapshotsType value: %q", s)
} }

View File

@@ -36,6 +36,8 @@ func GetSnapshottable(snapshotType SnapshotsType) (Snapshottable, error) {
return ComplianceRegistries{}, nil return ComplianceRegistries{}, nil
case SnapshotsTypeContinualImprovementRegistries: case SnapshotsTypeContinualImprovementRegistries:
return ContinualImprovementRegistries{}, nil return ContinualImprovementRegistries{}, nil
case SnapshotsTypeProcessingActivityRegistries:
return ProcessingActivityRegistries{}, nil
default: default:
return nil, fmt.Errorf("unsupported snapshot type: %s", snapshotType) return nil, fmt.Errorf("unsupported snapshot type: %s", snapshotType)
} }

View File

@@ -237,13 +237,14 @@ func (s ProcessingActivityRegistryService) ListForOrganizationID(
ctx context.Context, ctx context.Context,
organizationID gid.GID, organizationID gid.GID,
cursor *page.Cursor[coredata.ProcessingActivityRegistryOrderField], cursor *page.Cursor[coredata.ProcessingActivityRegistryOrderField],
filter *coredata.ProcessingActivityRegistryFilter,
) (*page.Page[*coredata.ProcessingActivityRegistry, coredata.ProcessingActivityRegistryOrderField], error) { ) (*page.Page[*coredata.ProcessingActivityRegistry, coredata.ProcessingActivityRegistryOrderField], error) {
var processingActivityRegistries coredata.ProcessingActivityRegistries var processingActivityRegistries coredata.ProcessingActivityRegistries
err := s.svc.pg.WithConn( err := s.svc.pg.WithConn(
ctx, ctx,
func(conn pg.Conn) error { func(conn pg.Conn) error {
err := processingActivityRegistries.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID, cursor) err := processingActivityRegistries.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID, cursor, filter)
if err != nil { if err != nil {
return fmt.Errorf("cannot load processing activity registries: %w", err) return fmt.Errorf("cannot load processing activity registries: %w", err)
} }
@@ -262,6 +263,7 @@ func (s ProcessingActivityRegistryService) ListForOrganizationID(
func (s ProcessingActivityRegistryService) CountForOrganizationID( func (s ProcessingActivityRegistryService) CountForOrganizationID(
ctx context.Context, ctx context.Context,
organizationID gid.GID, organizationID gid.GID,
filter *coredata.ProcessingActivityRegistryFilter,
) (int, error) { ) (int, error) {
var count int var count int
@@ -269,7 +271,7 @@ func (s ProcessingActivityRegistryService) CountForOrganizationID(
ctx, ctx,
func(conn pg.Conn) (err error) { func(conn pg.Conn) (err error) {
processingActivityRegistries := coredata.ProcessingActivityRegistries{} processingActivityRegistries := coredata.ProcessingActivityRegistries{}
count, err = processingActivityRegistries.CountByOrganizationID(ctx, conn, s.svc.scope, organizationID) count, err = processingActivityRegistries.CountByOrganizationID(ctx, conn, s.svc.scope, organizationID, filter)
if err != nil { if err != nil {
return fmt.Errorf("cannot count processing activity registries: %w", err) return fmt.Errorf("cannot count processing activity registries: %w", err)
} }

View File

@@ -880,6 +880,10 @@ enum SnapshotsType
@goEnum( @goEnum(
value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeContinualImprovementRegistries" value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeContinualImprovementRegistries"
) )
PROCESSING_ACTIVITY_REGISTRIES
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeProcessingActivityRegistries"
)
} }
enum SnapshotOrderField enum SnapshotOrderField
@@ -1122,6 +1126,10 @@ input ContinualImprovementRegistryFilter {
snapshotId: ID snapshotId: ID
} }
input ProcessingActivityRegistryFilter {
snapshotId: ID
}
# Core Types # Core Types
type TrustCenter implements Node { type TrustCenter implements Node {
id: ID! id: ID!
@@ -1288,6 +1296,7 @@ type Organization implements Node {
last: Int last: Int
before: CursorKey before: CursorKey
orderBy: ProcessingActivityRegistryOrder orderBy: ProcessingActivityRegistryOrder
filter: ProcessingActivityRegistryFilter
): ProcessingActivityRegistryConnection! @goField(forceResolver: true) ): ProcessingActivityRegistryConnection! @goField(forceResolver: true)
snapshots( snapshots(
@@ -1770,6 +1779,8 @@ type ContinualImprovementRegistry implements Node {
type ProcessingActivityRegistry implements Node { type ProcessingActivityRegistry implements Node {
id: ID! id: ID!
snapshotId: ID
sourceId: ID
organization: Organization! @goField(forceResolver: true) organization: Organization! @goField(forceResolver: true)
name: String! name: String!
purpose: String purpose: String

View File

@@ -889,7 +889,7 @@ type ComplexityRoot struct {
Name func(childComplexity int) int Name func(childComplexity int) int
NonconformityRegistries func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityRegistryOrderBy, filter *types.NonconformityRegistryFilter) int NonconformityRegistries func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityRegistryOrderBy, filter *types.NonconformityRegistryFilter) int
Peoples func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PeopleOrderBy, filter *types.PeopleFilter) int Peoples func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.PeopleOrderBy, filter *types.PeopleFilter) int
ProcessingActivityRegistries func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy) int ProcessingActivityRegistries func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy, filter *types.ProcessingActivityRegistryFilter) int
Risks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) int Risks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.RiskOrderBy, filter *types.RiskFilter) int
Snapshots func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) int Snapshots func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) int
Tasks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) int Tasks func(childComplexity int, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.TaskOrderBy) int
@@ -956,6 +956,8 @@ type ComplexityRoot struct {
Recipients func(childComplexity int) int Recipients func(childComplexity int) int
RetentionPeriod func(childComplexity int) int RetentionPeriod func(childComplexity int) int
SecurityMeasures func(childComplexity int) int SecurityMeasures func(childComplexity int) int
SnapshotID func(childComplexity int) int
SourceID func(childComplexity int) int
SpecialOrCriminalData func(childComplexity int) int SpecialOrCriminalData func(childComplexity int) int
TransferImpactAssessment func(childComplexity int) int TransferImpactAssessment func(childComplexity int) int
TransferSafeguards func(childComplexity int) int TransferSafeguards func(childComplexity int) int
@@ -1675,7 +1677,7 @@ type OrganizationResolver interface {
NonconformityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityRegistryOrderBy, filter *types.NonconformityRegistryFilter) (*types.NonconformityRegistryConnection, error) NonconformityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.NonconformityRegistryOrderBy, filter *types.NonconformityRegistryFilter) (*types.NonconformityRegistryConnection, error)
ComplianceRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ComplianceRegistryOrderBy, filter *types.ComplianceRegistryFilter) (*types.ComplianceRegistryConnection, error) ComplianceRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ComplianceRegistryOrderBy, filter *types.ComplianceRegistryFilter) (*types.ComplianceRegistryConnection, error)
ContinualImprovementRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ContinualImprovementRegistriesOrderBy, filter *types.ContinualImprovementRegistryFilter) (*types.ContinualImprovementRegistryConnection, error) ContinualImprovementRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ContinualImprovementRegistriesOrderBy, filter *types.ContinualImprovementRegistryFilter) (*types.ContinualImprovementRegistryConnection, error)
ProcessingActivityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy) (*types.ProcessingActivityRegistryConnection, error) ProcessingActivityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy, filter *types.ProcessingActivityRegistryFilter) (*types.ProcessingActivityRegistryConnection, error)
Snapshots(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error) Snapshots(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.SnapshotOrderBy) (*types.SnapshotConnection, error)
TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error) TrustCenter(ctx context.Context, obj *types.Organization) (*types.TrustCenter, error)
} }
@@ -5550,7 +5552,7 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return 0, false return 0, false
} }
return e.complexity.Organization.ProcessingActivityRegistries(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.ProcessingActivityRegistryOrderBy)), true return e.complexity.Organization.ProcessingActivityRegistries(childComplexity, args["first"].(*int), args["after"].(*page.CursorKey), args["last"].(*int), args["before"].(*page.CursorKey), args["orderBy"].(*types.ProcessingActivityRegistryOrderBy), args["filter"].(*types.ProcessingActivityRegistryFilter)), true
case "Organization.risks": case "Organization.risks":
if e.complexity.Organization.Risks == nil { if e.complexity.Organization.Risks == nil {
@@ -5892,6 +5894,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
return e.complexity.ProcessingActivityRegistry.SecurityMeasures(childComplexity), true return e.complexity.ProcessingActivityRegistry.SecurityMeasures(childComplexity), true
case "ProcessingActivityRegistry.snapshotId":
if e.complexity.ProcessingActivityRegistry.SnapshotID == nil {
break
}
return e.complexity.ProcessingActivityRegistry.SnapshotID(childComplexity), true
case "ProcessingActivityRegistry.sourceId":
if e.complexity.ProcessingActivityRegistry.SourceID == nil {
break
}
return e.complexity.ProcessingActivityRegistry.SourceID(childComplexity), true
case "ProcessingActivityRegistry.specialOrCriminalData": case "ProcessingActivityRegistry.specialOrCriminalData":
if e.complexity.ProcessingActivityRegistry.SpecialOrCriminalData == nil { if e.complexity.ProcessingActivityRegistry.SpecialOrCriminalData == nil {
break break
@@ -7780,6 +7796,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
ec.unmarshalInputOrganizationOrder, ec.unmarshalInputOrganizationOrder,
ec.unmarshalInputPeopleFilter, ec.unmarshalInputPeopleFilter,
ec.unmarshalInputPeopleOrder, ec.unmarshalInputPeopleOrder,
ec.unmarshalInputProcessingActivityRegistryFilter,
ec.unmarshalInputProcessingActivityRegistryOrder, ec.unmarshalInputProcessingActivityRegistryOrder,
ec.unmarshalInputPublishDocumentVersionInput, ec.unmarshalInputPublishDocumentVersionInput,
ec.unmarshalInputRemoveUserInput, ec.unmarshalInputRemoveUserInput,
@@ -8806,6 +8823,10 @@ enum SnapshotsType
@goEnum( @goEnum(
value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeContinualImprovementRegistries" value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeContinualImprovementRegistries"
) )
PROCESSING_ACTIVITY_REGISTRIES
@goEnum(
value: "github.com/getprobo/probo/pkg/coredata.SnapshotsTypeProcessingActivityRegistries"
)
} }
enum SnapshotOrderField enum SnapshotOrderField
@@ -9048,6 +9069,10 @@ input ContinualImprovementRegistryFilter {
snapshotId: ID snapshotId: ID
} }
input ProcessingActivityRegistryFilter {
snapshotId: ID
}
# Core Types # Core Types
type TrustCenter implements Node { type TrustCenter implements Node {
id: ID! id: ID!
@@ -9214,6 +9239,7 @@ type Organization implements Node {
last: Int last: Int
before: CursorKey before: CursorKey
orderBy: ProcessingActivityRegistryOrder orderBy: ProcessingActivityRegistryOrder
filter: ProcessingActivityRegistryFilter
): ProcessingActivityRegistryConnection! @goField(forceResolver: true) ): ProcessingActivityRegistryConnection! @goField(forceResolver: true)
snapshots( snapshots(
@@ -9696,6 +9722,8 @@ type ContinualImprovementRegistry implements Node {
type ProcessingActivityRegistry implements Node { type ProcessingActivityRegistry implements Node {
id: ID! id: ID!
snapshotId: ID
sourceId: ID
organization: Organization! @goField(forceResolver: true) organization: Organization! @goField(forceResolver: true)
name: String! name: String!
purpose: String purpose: String
@@ -17139,6 +17167,11 @@ func (ec *executionContext) field_Organization_processingActivityRegistries_args
return nil, err return nil, err
} }
args["orderBy"] = arg4 args["orderBy"] = arg4
arg5, err := ec.field_Organization_processingActivityRegistries_argsFilter(ctx, rawArgs)
if err != nil {
return nil, err
}
args["filter"] = arg5
return args, nil return args, nil
} }
func (ec *executionContext) field_Organization_processingActivityRegistries_argsFirst( func (ec *executionContext) field_Organization_processingActivityRegistries_argsFirst(
@@ -17206,6 +17239,19 @@ func (ec *executionContext) field_Organization_processingActivityRegistries_args
return zeroVal, nil return zeroVal, nil
} }
func (ec *executionContext) field_Organization_processingActivityRegistries_argsFilter(
ctx context.Context,
rawArgs map[string]any,
) (*types.ProcessingActivityRegistryFilter, error) {
ctx = graphql.WithPathContext(ctx, graphql.NewPathWithField("filter"))
if tmp, ok := rawArgs["filter"]; ok {
return ec.unmarshalOProcessingActivityRegistryFilter2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐProcessingActivityRegistryFilter(ctx, tmp)
}
var zeroVal *types.ProcessingActivityRegistryFilter
return zeroVal, nil
}
func (ec *executionContext) field_Organization_risks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { func (ec *executionContext) field_Organization_risks_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) {
var err error var err error
args := map[string]any{} args := map[string]any{}
@@ -42331,7 +42377,7 @@ func (ec *executionContext) _Organization_processingActivityRegistries(ctx conte
}() }()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) { resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children ctx = rctx // use context from middleware stack in children
return ec.resolvers.Organization().ProcessingActivityRegistries(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.ProcessingActivityRegistryOrderBy)) return ec.resolvers.Organization().ProcessingActivityRegistries(rctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*page.CursorKey), fc.Args["last"].(*int), fc.Args["before"].(*page.CursorKey), fc.Args["orderBy"].(*types.ProcessingActivityRegistryOrderBy), fc.Args["filter"].(*types.ProcessingActivityRegistryFilter))
}) })
if err != nil { if err != nil {
ec.Error(ctx, err) ec.Error(ctx, err)
@@ -43733,6 +43779,88 @@ func (ec *executionContext) fieldContext_ProcessingActivityRegistry_id(_ context
return fc, nil return fc, nil
} }
func (ec *executionContext) _ProcessingActivityRegistry_snapshotId(ctx context.Context, field graphql.CollectedField, obj *types.ProcessingActivityRegistry) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ProcessingActivityRegistry_snapshotId(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SnapshotID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gid.GID)
fc.Result = res
return ec.marshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_ProcessingActivityRegistry_snapshotId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ProcessingActivityRegistry",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type ID does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _ProcessingActivityRegistry_sourceId(ctx context.Context, field graphql.CollectedField, obj *types.ProcessingActivityRegistry) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ProcessingActivityRegistry_sourceId(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.SourceID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*gid.GID)
fc.Result = res
return ec.marshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_ProcessingActivityRegistry_sourceId(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ProcessingActivityRegistry",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type ID does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _ProcessingActivityRegistry_organization(ctx context.Context, field graphql.CollectedField, obj *types.ProcessingActivityRegistry) (ret graphql.Marshaler) { func (ec *executionContext) _ProcessingActivityRegistry_organization(ctx context.Context, field graphql.CollectedField, obj *types.ProcessingActivityRegistry) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field) fc, err := ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field)
if err != nil { if err != nil {
@@ -44781,6 +44909,10 @@ func (ec *executionContext) fieldContext_ProcessingActivityRegistryEdge_node(_ c
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_ProcessingActivityRegistry_id(ctx, field) return ec.fieldContext_ProcessingActivityRegistry_id(ctx, field)
case "snapshotId":
return ec.fieldContext_ProcessingActivityRegistry_snapshotId(ctx, field)
case "sourceId":
return ec.fieldContext_ProcessingActivityRegistry_sourceId(ctx, field)
case "organization": case "organization":
return ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field) return ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field)
case "name": case "name":
@@ -50682,6 +50814,10 @@ func (ec *executionContext) fieldContext_UpdateProcessingActivityRegistryPayload
switch field.Name { switch field.Name {
case "id": case "id":
return ec.fieldContext_ProcessingActivityRegistry_id(ctx, field) return ec.fieldContext_ProcessingActivityRegistry_id(ctx, field)
case "snapshotId":
return ec.fieldContext_ProcessingActivityRegistry_snapshotId(ctx, field)
case "sourceId":
return ec.fieldContext_ProcessingActivityRegistry_sourceId(ctx, field)
case "organization": case "organization":
return ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field) return ec.fieldContext_ProcessingActivityRegistry_organization(ctx, field)
case "name": case "name":
@@ -63407,6 +63543,33 @@ func (ec *executionContext) unmarshalInputPeopleOrder(ctx context.Context, obj a
return it, nil return it, nil
} }
func (ec *executionContext) unmarshalInputProcessingActivityRegistryFilter(ctx context.Context, obj any) (types.ProcessingActivityRegistryFilter, error) {
var it types.ProcessingActivityRegistryFilter
asMap := map[string]any{}
for k, v := range obj.(map[string]any) {
asMap[k] = v
}
fieldsInOrder := [...]string{"snapshotId"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
continue
}
switch k {
case "snapshotId":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("snapshotId"))
data, err := ec.unmarshalOID2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋgidᚐGID(ctx, v)
if err != nil {
return it, err
}
it.SnapshotID = data
}
}
return it, nil
}
func (ec *executionContext) unmarshalInputProcessingActivityRegistryOrder(ctx context.Context, obj any) (types.ProcessingActivityRegistryOrderBy, error) { func (ec *executionContext) unmarshalInputProcessingActivityRegistryOrder(ctx context.Context, obj any) (types.ProcessingActivityRegistryOrderBy, error) {
var it types.ProcessingActivityRegistryOrderBy var it types.ProcessingActivityRegistryOrderBy
asMap := map[string]any{} asMap := map[string]any{}
@@ -75118,6 +75281,10 @@ func (ec *executionContext) _ProcessingActivityRegistry(ctx context.Context, sel
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
atomic.AddUint32(&out.Invalids, 1) atomic.AddUint32(&out.Invalids, 1)
} }
case "snapshotId":
out.Values[i] = ec._ProcessingActivityRegistry_snapshotId(ctx, field, obj)
case "sourceId":
out.Values[i] = ec._ProcessingActivityRegistry_sourceId(ctx, field, obj)
case "organization": case "organization":
field := field field := field
@@ -84978,6 +85145,7 @@ var (
"NONCONFORMITY_REGISTRIES": coredata.SnapshotsTypeNonConformityRegistries, "NONCONFORMITY_REGISTRIES": coredata.SnapshotsTypeNonConformityRegistries,
"COMPLIANCE_REGISTRIES": coredata.SnapshotsTypeComplianceRegistries, "COMPLIANCE_REGISTRIES": coredata.SnapshotsTypeComplianceRegistries,
"CONTINUAL_IMPROVEMENT_REGISTRIES": coredata.SnapshotsTypeContinualImprovementRegistries, "CONTINUAL_IMPROVEMENT_REGISTRIES": coredata.SnapshotsTypeContinualImprovementRegistries,
"PROCESSING_ACTIVITY_REGISTRIES": coredata.SnapshotsTypeProcessingActivityRegistries,
} }
marshalNSnapshotsType2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐSnapshotsType = map[coredata.SnapshotsType]string{ marshalNSnapshotsType2githubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐSnapshotsType = map[coredata.SnapshotsType]string{
coredata.SnapshotsTypeRisks: "RISKS", coredata.SnapshotsTypeRisks: "RISKS",
@@ -84987,6 +85155,7 @@ var (
coredata.SnapshotsTypeNonConformityRegistries: "NONCONFORMITY_REGISTRIES", coredata.SnapshotsTypeNonConformityRegistries: "NONCONFORMITY_REGISTRIES",
coredata.SnapshotsTypeComplianceRegistries: "COMPLIANCE_REGISTRIES", coredata.SnapshotsTypeComplianceRegistries: "COMPLIANCE_REGISTRIES",
coredata.SnapshotsTypeContinualImprovementRegistries: "CONTINUAL_IMPROVEMENT_REGISTRIES", coredata.SnapshotsTypeContinualImprovementRegistries: "CONTINUAL_IMPROVEMENT_REGISTRIES",
coredata.SnapshotsTypeProcessingActivityRegistries: "PROCESSING_ACTIVITY_REGISTRIES",
} }
) )
@@ -87738,6 +87907,14 @@ var (
} }
) )
func (ec *executionContext) unmarshalOProcessingActivityRegistryFilter2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋserverᚋapiᚋconsoleᚋv1ᚋtypesᚐProcessingActivityRegistryFilter(ctx context.Context, v any) (*types.ProcessingActivityRegistryFilter, error) {
if v == nil {
return nil, nil
}
res, err := ec.unmarshalInputProcessingActivityRegistryFilter(ctx, v)
return &res, graphql.ErrorOnPath(ctx, err)
}
func (ec *executionContext) unmarshalOProcessingActivityRegistryLawfulBasis2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐProcessingActivityRegistryLawfulBasis(ctx context.Context, v any) (*coredata.ProcessingActivityRegistryLawfulBasis, error) { func (ec *executionContext) unmarshalOProcessingActivityRegistryLawfulBasis2ᚖgithubᚗcomᚋgetproboᚋproboᚋpkgᚋcoredataᚐProcessingActivityRegistryLawfulBasis(ctx context.Context, v any) (*coredata.ProcessingActivityRegistryLawfulBasis, error) {
if v == nil { if v == nil {
return nil, nil return nil, nil

View File

@@ -30,6 +30,7 @@ type (
Resolver any Resolver any
ParentID gid.GID ParentID gid.GID
Filter *ProcessingActivityRegistryFilter
} }
) )
@@ -37,6 +38,7 @@ func NewProcessingActivityRegistryConnection(
p *page.Page[*coredata.ProcessingActivityRegistry, coredata.ProcessingActivityRegistryOrderField], p *page.Page[*coredata.ProcessingActivityRegistry, coredata.ProcessingActivityRegistryOrderField],
parentType any, parentType any,
parentID gid.GID, parentID gid.GID,
filter *ProcessingActivityRegistryFilter,
) *ProcessingActivityRegistryConnection { ) *ProcessingActivityRegistryConnection {
edges := make([]*ProcessingActivityRegistryEdge, len(p.Data)) edges := make([]*ProcessingActivityRegistryEdge, len(p.Data))
for i, registry := range p.Data { for i, registry := range p.Data {
@@ -49,12 +51,14 @@ func NewProcessingActivityRegistryConnection(
Resolver: parentType, Resolver: parentType,
ParentID: parentID, ParentID: parentID,
Filter: filter,
} }
} }
func NewProcessingActivityRegistry(par *coredata.ProcessingActivityRegistry) *ProcessingActivityRegistry { func NewProcessingActivityRegistry(par *coredata.ProcessingActivityRegistry) *ProcessingActivityRegistry {
return &ProcessingActivityRegistry{ return &ProcessingActivityRegistry{
ID: par.ID, ID: par.ID,
SnapshotID: par.SnapshotID,
Name: par.Name, Name: par.Name,
Purpose: par.Purpose, Purpose: par.Purpose,
DataSubjectCategory: par.DataSubjectCategory, DataSubjectCategory: par.DataSubjectCategory,

View File

@@ -1239,6 +1239,8 @@ type PeopleFilter struct {
type ProcessingActivityRegistry struct { type ProcessingActivityRegistry struct {
ID gid.GID `json:"id"` ID gid.GID `json:"id"`
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
SourceID *gid.GID `json:"sourceId,omitempty"`
Organization *Organization `json:"organization"` Organization *Organization `json:"organization"`
Name string `json:"name"` Name string `json:"name"`
Purpose *string `json:"purpose,omitempty"` Purpose *string `json:"purpose,omitempty"`
@@ -1267,6 +1269,10 @@ type ProcessingActivityRegistryEdge struct {
Node *ProcessingActivityRegistry `json:"node"` Node *ProcessingActivityRegistry `json:"node"`
} }
type ProcessingActivityRegistryFilter struct {
SnapshotID *gid.GID `json:"snapshotId,omitempty"`
}
type PublishDocumentVersionInput struct { type PublishDocumentVersionInput struct {
DocumentID gid.GID `json:"documentId"` DocumentID gid.GID `json:"documentId"`
Changelog *string `json:"changelog,omitempty"` Changelog *string `json:"changelog,omitempty"`

View File

@@ -3797,7 +3797,7 @@ func (r *organizationResolver) ContinualImprovementRegistries(ctx context.Contex
} }
// ProcessingActivityRegistries is the resolver for the processingActivityRegistries field. // ProcessingActivityRegistries is the resolver for the processingActivityRegistries field.
func (r *organizationResolver) ProcessingActivityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy) (*types.ProcessingActivityRegistryConnection, error) { func (r *organizationResolver) ProcessingActivityRegistries(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.ProcessingActivityRegistryOrderBy, filter *types.ProcessingActivityRegistryFilter) (*types.ProcessingActivityRegistryConnection, error) {
prb := r.ProboService(ctx, obj.ID.TenantID()) prb := r.ProboService(ctx, obj.ID.TenantID())
pageOrderBy := page.OrderBy[coredata.ProcessingActivityRegistryOrderField]{ pageOrderBy := page.OrderBy[coredata.ProcessingActivityRegistryOrderField]{
@@ -3814,12 +3814,17 @@ func (r *organizationResolver) ProcessingActivityRegistries(ctx context.Context,
cursor := types.NewCursor(first, after, last, before, pageOrderBy) cursor := types.NewCursor(first, after, last, before, pageOrderBy)
page, err := prb.ProcessingActivityRegistries.ListForOrganizationID(ctx, obj.ID, cursor) processingActivityRegistryFilter := coredata.NewProcessingActivityRegistryFilter(nil)
if filter != nil {
processingActivityRegistryFilter = coredata.NewProcessingActivityRegistryFilter(&filter.SnapshotID)
}
page, err := prb.ProcessingActivityRegistries.ListForOrganizationID(ctx, obj.ID, cursor, processingActivityRegistryFilter)
if err != nil { if err != nil {
panic(fmt.Errorf("cannot list organization processing activity registries: %w", err)) panic(fmt.Errorf("cannot list organization processing activity registries: %w", err))
} }
return types.NewProcessingActivityRegistryConnection(page, r, obj.ID), nil return types.NewProcessingActivityRegistryConnection(page, r, obj.ID, filter), nil
} }
// Snapshots is the resolver for the snapshots field. // Snapshots is the resolver for the snapshots field.
@@ -3898,7 +3903,12 @@ func (r *processingActivityRegistryConnectionResolver) TotalCount(ctx context.Co
switch obj.Resolver.(type) { switch obj.Resolver.(type) {
case *organizationResolver: case *organizationResolver:
count, err := prb.ProcessingActivityRegistries.CountForOrganizationID(ctx, obj.ParentID) processingActivityRegistryFilter := coredata.NewProcessingActivityRegistryFilter(nil)
if obj.Filter != nil {
processingActivityRegistryFilter = coredata.NewProcessingActivityRegistryFilter(&obj.Filter.SnapshotID)
}
count, err := prb.ProcessingActivityRegistries.CountForOrganizationID(ctx, obj.ParentID, processingActivityRegistryFilter)
if err != nil { if err != nil {
panic(fmt.Errorf("cannot count organization processing activity registries: %w", err)) panic(fmt.Errorf("cannot count organization processing activity registries: %w", err))
} }