Fix processing activities & risks permissions pages handling

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2026-01-02 11:23:46 +01:00
committed by Bryan Frimin
parent de0e0b596d
commit e80766509a
15 changed files with 694 additions and 275 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<d8293252572dc69148a45b6ce2fabafa>> * @generated SignedSource<<7cb2759bd509c11cb25bb1af2a6105cd>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -17,6 +17,8 @@ export type ProcessingActivitiesPageFragment$data = {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly createdAt: string; readonly createdAt: string;
readonly dataSubjectCategory: string | null | undefined; readonly dataSubjectCategory: string | null | undefined;
readonly id: string; readonly id: string;
@@ -228,6 +230,32 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:delete\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -294,6 +322,6 @@ return {
}; };
})(); })();
(node as any).hash = "e60b3eb3cf3d172625c2873cb05039bd"; (node as any).hash = "df348ac63bc56da06da97e484fb2c0e5";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<0408262bc53f870212c3a87156f861f4>> * @generated SignedSource<<504b0d0e997eb43eb8d370a21cb3e0fb>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -263,6 +263,32 @@ return {
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:delete\")"
},
(v8/*: any*/) (v8/*: any*/)
], ],
"storageKey": null "storageKey": null
@@ -338,16 +364,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "bf2fb9a8eb709e64268710ca36f86a72", "cacheID": "71c255d719fe0ffafda13169e925b4b8",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivitiesPageRefetchQuery", "name": "ProcessingActivitiesPageRefetchQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivitiesPageRefetchQuery(\n $after: CursorKey\n $first: Int = 10\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ProcessingActivitiesPageFragment_35e0S5\n id\n }\n}\n\nfragment ProcessingActivitiesPageFragment_35e0S5 on Organization {\n id\n processingActivities(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" "text": "query ProcessingActivitiesPageRefetchQuery(\n $after: CursorKey\n $first: Int = 10\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...ProcessingActivitiesPageFragment_35e0S5\n id\n }\n}\n\nfragment ProcessingActivitiesPageFragment_35e0S5 on Organization {\n id\n processingActivities(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 canUpdate: permission(action: \"core:processing-activity:update\")\n canDelete: permission(action: \"core:processing-activity:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "e60b3eb3cf3d172625c2873cb05039bd"; (node as any).hash = "df348ac63bc56da06da97e484fb2c0e5";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<af15e0a3ab99f57152fbb4e9d23eca6b>> * @generated SignedSource<<238d486ca746aa2d13f6e87ddab1c8e3>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -46,6 +46,8 @@ export type ProcessingActivityGraphCreateMutation$data = {
readonly createProcessingActivity: { readonly createProcessingActivity: {
readonly processingActivityEdge: { readonly processingActivityEdge: {
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly consentEvidenceLink: string | null | undefined; readonly consentEvidenceLink: string | null | undefined;
readonly createdAt: string; readonly createdAt: string;
readonly dataProtectionImpactAssessmentNeeded: ProcessingActivityDataProtectionImpactAssessment; readonly dataProtectionImpactAssessmentNeeded: ProcessingActivityDataProtectionImpactAssessment;
@@ -330,6 +332,32 @@ v5 = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:delete\")"
} }
], ],
"storageKey": null "storageKey": null
@@ -403,16 +431,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "00d5d2374c8b6933fd01544e67518c14", "cacheID": "534bd7c442063267f6556101350e0d74",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityGraphCreateMutation", "name": "ProcessingActivityGraphCreateMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation ProcessingActivityGraphCreateMutation(\n $input: CreateProcessingActivityInput!\n) {\n createProcessingActivity(input: $input) {\n processingActivityEdge {\n node {\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 dataProtectionImpactAssessmentNeeded\n transferImpactAssessmentNeeded\n lastReviewDate\n nextReviewDate\n role\n dataProtectionOfficer {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n }\n }\n }\n}\n" "text": "mutation ProcessingActivityGraphCreateMutation(\n $input: CreateProcessingActivityInput!\n) {\n createProcessingActivity(input: $input) {\n processingActivityEdge {\n node {\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 dataProtectionImpactAssessmentNeeded\n transferImpactAssessmentNeeded\n lastReviewDate\n nextReviewDate\n role\n dataProtectionOfficer {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n }\n }\n }\n createdAt\n canUpdate: permission(action: \"core:processing-activity:update\")\n canDelete: permission(action: \"core:processing-activity:delete\")\n }\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "63271cfac482a18f5754df0af220e45d"; (node as any).hash = "69c155bfe5b8a028d1d72c3b57d8de98";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<4f7512912c29e784f2cd2a52fd5f81b4>> * @generated SignedSource<<14e03b23c216da916e36cecb49aefa6d>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -16,6 +16,7 @@ export type ProcessingActivityGraphListQuery$variables = {
}; };
export type ProcessingActivityGraphListQuery$data = { export type ProcessingActivityGraphListQuery$data = {
readonly node: { readonly node: {
readonly canCreateProcessingActivity?: boolean;
readonly " $fragmentSpreads": FragmentRefs<"ProcessingActivitiesPageDPIAFragment" | "ProcessingActivitiesPageFragment" | "ProcessingActivitiesPageTIAFragment">; readonly " $fragmentSpreads": FragmentRefs<"ProcessingActivitiesPageDPIAFragment" | "ProcessingActivitiesPageFragment" | "ProcessingActivitiesPageTIAFragment">;
}; };
}; };
@@ -44,30 +45,43 @@ v1 = [
"variableName": "organizationId" "variableName": "organizationId"
} }
], ],
v2 = [ v2 = {
"alias": "canCreateProcessingActivity",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:create\")"
},
v3 = [
{ {
"kind": "Variable", "kind": "Variable",
"name": "snapshotId", "name": "snapshotId",
"variableName": "snapshotId" "variableName": "snapshotId"
} }
], ],
v3 = { v4 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v4 = { v5 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "id", "name": "id",
"storageKey": null "storageKey": null
}, },
v5 = [ v6 = [
{ {
"fields": (v2/*: any*/), "fields": (v3/*: any*/),
"kind": "ObjectValue", "kind": "ObjectValue",
"name": "filter" "name": "filter"
}, },
@@ -77,42 +91,42 @@ v5 = [
"value": 10 "value": 10
} }
], ],
v6 = { v7 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "totalCount", "name": "totalCount",
"storageKey": null "storageKey": null
}, },
v7 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "name", "name": "name",
"storageKey": null "storageKey": null
}, },
v8 = { v9 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "createdAt",
"storageKey": null "storageKey": null
}, },
v9 = { v10 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "updatedAt", "name": "updatedAt",
"storageKey": null "storageKey": null
}, },
v10 = { v11 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "cursor", "name": "cursor",
"storageKey": null "storageKey": null
}, },
v11 = { v12 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "PageInfo", "concreteType": "PageInfo",
@@ -137,7 +151,7 @@ v11 = {
], ],
"storageKey": null "storageKey": null
}, },
v12 = { v13 = {
"kind": "ClientExtension", "kind": "ClientExtension",
"selections": [ "selections": [
{ {
@@ -149,10 +163,10 @@ v12 = {
} }
] ]
}, },
v13 = [ v14 = [
"filter" "filter"
], ],
v14 = { v15 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "ProcessingActivity", "concreteType": "ProcessingActivity",
@@ -160,8 +174,8 @@ v14 = {
"name": "processingActivity", "name": "processingActivity",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v5/*: any*/),
(v7/*: any*/) (v8/*: any*/)
], ],
"storageKey": null "storageKey": null
}; };
@@ -183,18 +197,19 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/),
{ {
"args": (v2/*: any*/), "args": (v3/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivitiesPageFragment" "name": "ProcessingActivitiesPageFragment"
}, },
{ {
"args": (v2/*: any*/), "args": (v3/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivitiesPageDPIAFragment" "name": "ProcessingActivitiesPageDPIAFragment"
}, },
{ {
"args": (v2/*: any*/), "args": (v3/*: any*/),
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "ProcessingActivitiesPageTIAFragment" "name": "ProcessingActivitiesPageTIAFragment"
} }
@@ -223,20 +238,21 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/),
(v4/*: any*/), (v4/*: any*/),
(v5/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/),
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"concreteType": "ProcessingActivityConnection", "concreteType": "ProcessingActivityConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "processingActivities", "name": "processingActivities",
"plural": false, "plural": false,
"selections": [ "selections": [
(v6/*: any*/), (v7/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -253,7 +269,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -268,7 +284,7 @@ return {
"name": "sourceId", "name": "sourceId",
"storageKey": null "storageKey": null
}, },
(v7/*: any*/), (v8/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -311,25 +327,51 @@ return {
"name": "internationalTransfers", "name": "internationalTransfers",
"storageKey": null "storageKey": null
}, },
(v8/*: any*/),
(v9/*: any*/), (v9/*: any*/),
(v3/*: any*/) (v10/*: any*/),
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:delete\")"
},
(v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/) (v11/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v11/*: any*/), (v12/*: any*/),
(v12/*: any*/) (v13/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"filters": (v13/*: any*/), "filters": (v14/*: any*/),
"handle": "connection", "handle": "connection",
"key": "ProcessingActivitiesPage_processingActivities", "key": "ProcessingActivitiesPage_processingActivities",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -337,13 +379,13 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"concreteType": "DataProtectionImpactAssessmentConnection", "concreteType": "DataProtectionImpactAssessmentConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "dataProtectionImpactAssessments", "name": "dataProtectionImpactAssessments",
"plural": false, "plural": false,
"selections": [ "selections": [
(v6/*: any*/), (v7/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -360,7 +402,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -382,26 +424,26 @@ return {
"name": "residualRisk", "name": "residualRisk",
"storageKey": null "storageKey": null
}, },
(v14/*: any*/), (v15/*: any*/),
(v8/*: any*/),
(v9/*: any*/), (v9/*: any*/),
(v3/*: any*/) (v10/*: any*/),
(v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/) (v11/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v11/*: any*/), (v12/*: any*/),
(v12/*: any*/) (v13/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"filters": (v13/*: any*/), "filters": (v14/*: any*/),
"handle": "connection", "handle": "connection",
"key": "ProcessingActivitiesPage_dataProtectionImpactAssessments", "key": "ProcessingActivitiesPage_dataProtectionImpactAssessments",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -409,13 +451,13 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"concreteType": "TransferImpactAssessmentConnection", "concreteType": "TransferImpactAssessmentConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "transferImpactAssessments", "name": "transferImpactAssessments",
"plural": false, "plural": false,
"selections": [ "selections": [
(v6/*: any*/), (v7/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -432,7 +474,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v4/*: any*/), (v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -454,26 +496,26 @@ return {
"name": "localLawRisk", "name": "localLawRisk",
"storageKey": null "storageKey": null
}, },
(v14/*: any*/), (v15/*: any*/),
(v8/*: any*/),
(v9/*: any*/), (v9/*: any*/),
(v3/*: any*/) (v10/*: any*/),
(v4/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/) (v11/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v11/*: any*/), (v12/*: any*/),
(v12/*: any*/) (v13/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v6/*: any*/),
"filters": (v13/*: any*/), "filters": (v14/*: any*/),
"handle": "connection", "handle": "connection",
"key": "ProcessingActivitiesPage_transferImpactAssessments", "key": "ProcessingActivitiesPage_transferImpactAssessments",
"kind": "LinkedHandle", "kind": "LinkedHandle",
@@ -489,16 +531,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "5901fa4af27b039bd50a1c97cdcb54d4", "cacheID": "1d48f2badad2cfdbc1d36a06756a9ec7",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityGraphListQuery", "name": "ProcessingActivityGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n ...ProcessingActivitiesPageFragment_3iomuz\n ...ProcessingActivitiesPageDPIAFragment_3iomuz\n ...ProcessingActivitiesPageTIAFragment_3iomuz\n }\n id\n }\n}\n\nfragment ProcessingActivitiesPageDPIAFragment_3iomuz on Organization {\n id\n dataProtectionImpactAssessments(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n description\n potentialRisk\n residualRisk\n processingActivity {\n id\n name\n }\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n\nfragment ProcessingActivitiesPageFragment_3iomuz on Organization {\n id\n processingActivities(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\nfragment ProcessingActivitiesPageTIAFragment_3iomuz on Organization {\n id\n transferImpactAssessments(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n dataSubjects\n transfer\n localLawRisk\n processingActivity {\n id\n name\n }\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n" "text": "query ProcessingActivityGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n node(id: $organizationId) {\n __typename\n ... on Organization {\n canCreateProcessingActivity: permission(action: \"core:processing-activity:create\")\n ...ProcessingActivitiesPageFragment_3iomuz\n ...ProcessingActivitiesPageDPIAFragment_3iomuz\n ...ProcessingActivitiesPageTIAFragment_3iomuz\n }\n id\n }\n}\n\nfragment ProcessingActivitiesPageDPIAFragment_3iomuz on Organization {\n id\n dataProtectionImpactAssessments(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n description\n potentialRisk\n residualRisk\n processingActivity {\n id\n name\n }\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n\nfragment ProcessingActivitiesPageFragment_3iomuz on Organization {\n id\n processingActivities(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 canUpdate: permission(action: \"core:processing-activity:update\")\n canDelete: permission(action: \"core:processing-activity:delete\")\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n\nfragment ProcessingActivitiesPageTIAFragment_3iomuz on Organization {\n id\n transferImpactAssessments(first: 10, filter: {snapshotId: $snapshotId}) {\n totalCount\n edges {\n node {\n id\n dataSubjects\n transfer\n localLawRisk\n processingActivity {\n id\n name\n }\n createdAt\n updatedAt\n __typename\n }\n cursor\n }\n pageInfo {\n hasNextPage\n endCursor\n }\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "b92a7dc2b38a5ae25c9a47a975fb718b"; (node as any).hash = "7a0d589abac7bbd3710a0caad37d6273";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<cf8cd15a7885212668ac995140192f12>> * @generated SignedSource<<ddc684800753eec2ae70df06e304dbde>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -22,9 +22,15 @@ export type ProcessingActivityGraphNodeQuery$variables = {
}; };
export type ProcessingActivityGraphNodeQuery$data = { export type ProcessingActivityGraphNodeQuery$data = {
readonly node: { readonly node: {
readonly canCreateDPIA?: boolean;
readonly canCreateTIA?: boolean;
readonly canDelete?: boolean;
readonly canUpdate?: boolean;
readonly consentEvidenceLink?: string | null | undefined; readonly consentEvidenceLink?: string | null | undefined;
readonly createdAt?: string; readonly createdAt?: string;
readonly dataProtectionImpactAssessment?: { readonly dataProtectionImpactAssessment?: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly createdAt: string; readonly createdAt: string;
readonly description: string | null | undefined; readonly description: string | null | undefined;
readonly id: string; readonly id: string;
@@ -60,6 +66,8 @@ export type ProcessingActivityGraphNodeQuery$data = {
readonly snapshotId?: string | null | undefined; readonly snapshotId?: string | null | undefined;
readonly specialOrCriminalData?: ProcessingActivitySpecialOrCriminalDatum; readonly specialOrCriminalData?: ProcessingActivitySpecialOrCriminalDatum;
readonly transferImpactAssessment?: { readonly transferImpactAssessment?: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly createdAt: string; readonly createdAt: string;
readonly dataSubjects: string | null | undefined; readonly dataSubjects: string | null | undefined;
readonly id: string; readonly id: string;
@@ -377,7 +385,33 @@ v26 = {
"storageKey": null "storageKey": null
}, },
(v24/*: any*/), (v24/*: any*/),
(v25/*: any*/) (v25/*: any*/),
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:data-protection-impact-assessment:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:data-protection-impact-assessment:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:data-protection-impact-assessment:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:data-protection-impact-assessment:delete\")"
}
], ],
"storageKey": null "storageKey": null
}, },
@@ -426,7 +460,33 @@ v27 = {
"storageKey": null "storageKey": null
}, },
(v24/*: any*/), (v24/*: any*/),
(v25/*: any*/) (v25/*: any*/),
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:transfer-impact-assessment:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:transfer-impact-assessment:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:transfer-impact-assessment:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:transfer-impact-assessment:delete\")"
}
], ],
"storageKey": null "storageKey": null
}, },
@@ -442,6 +502,58 @@ v28 = {
(v4/*: any*/) (v4/*: any*/)
], ],
"storageKey": null "storageKey": null
},
v29 = {
"alias": "canCreateDPIA",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:data-protection-impact-assessment:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:data-protection-impact-assessment:create\")"
},
v30 = {
"alias": "canCreateTIA",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:transfer-impact-assessment:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:transfer-impact-assessment:create\")"
},
v31 = {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:update\")"
},
v32 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:processing-activity:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:processing-activity:delete\")"
}; };
return { return {
"fragment": { "fragment": {
@@ -487,7 +599,11 @@ return {
(v27/*: any*/), (v27/*: any*/),
(v28/*: any*/), (v28/*: any*/),
(v24/*: any*/), (v24/*: any*/),
(v25/*: any*/) (v25/*: any*/),
(v29/*: any*/),
(v30/*: any*/),
(v31/*: any*/),
(v32/*: any*/)
], ],
"type": "ProcessingActivity", "type": "ProcessingActivity",
"abstractKey": null "abstractKey": null
@@ -549,7 +665,11 @@ return {
(v27/*: any*/), (v27/*: any*/),
(v28/*: any*/), (v28/*: any*/),
(v24/*: any*/), (v24/*: any*/),
(v25/*: any*/) (v25/*: any*/),
(v29/*: any*/),
(v30/*: any*/),
(v31/*: any*/),
(v32/*: any*/)
], ],
"type": "ProcessingActivity", "type": "ProcessingActivity",
"abstractKey": null "abstractKey": null
@@ -560,16 +680,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "8a92ed21a8b24d93c81ceba4b62a0911", "cacheID": "29bddd12b9399a78fb24420f11b6d56d",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "ProcessingActivityGraphNodeQuery", "name": "ProcessingActivityGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query ProcessingActivityGraphNodeQuery(\n $processingActivityId: ID!\n) {\n node(id: $processingActivityId) {\n __typename\n ... on ProcessingActivity {\n id\n snapshotId\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 dataProtectionImpactAssessmentNeeded\n transferImpactAssessmentNeeded\n lastReviewDate\n nextReviewDate\n role\n dataProtectionOfficer {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n dataProtectionImpactAssessment {\n id\n description\n necessityAndProportionality\n potentialRisk\n mitigations\n residualRisk\n createdAt\n updatedAt\n }\n transferImpactAssessment {\n id\n dataSubjects\n legalMechanism\n transfer\n localLawRisk\n supplementaryMeasures\n createdAt\n updatedAt\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query ProcessingActivityGraphNodeQuery(\n $processingActivityId: ID!\n) {\n node(id: $processingActivityId) {\n __typename\n ... on ProcessingActivity {\n id\n snapshotId\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 dataProtectionImpactAssessmentNeeded\n transferImpactAssessmentNeeded\n lastReviewDate\n nextReviewDate\n role\n dataProtectionOfficer {\n id\n fullName\n }\n vendors(first: 50) {\n edges {\n node {\n id\n name\n websiteUrl\n category\n }\n }\n }\n dataProtectionImpactAssessment {\n id\n description\n necessityAndProportionality\n potentialRisk\n mitigations\n residualRisk\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:data-protection-impact-assessment:update\")\n canDelete: permission(action: \"core:data-protection-impact-assessment:delete\")\n }\n transferImpactAssessment {\n id\n dataSubjects\n legalMechanism\n transfer\n localLawRisk\n supplementaryMeasures\n createdAt\n updatedAt\n canUpdate: permission(action: \"core:transfer-impact-assessment:update\")\n canDelete: permission(action: \"core:transfer-impact-assessment:delete\")\n }\n organization {\n id\n name\n }\n createdAt\n updatedAt\n canCreateDPIA: permission(action: \"core:data-protection-impact-assessment:create\")\n canCreateTIA: permission(action: \"core:transfer-impact-assessment:create\")\n canUpdate: permission(action: \"core:processing-activity:update\")\n canDelete: permission(action: \"core:processing-activity:delete\")\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "3fe20997f675ea566fe083e672bc82a3"; (node as any).hash = "d670e7ec4d612b19532332247c8c1f8f";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<c579c68998b3ded3e8833a7911f01a19>> * @generated SignedSource<<cac11a0f78a2e3980e953f77d040c52a>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,11 +12,14 @@ import { ReaderFragment } from 'relay-runtime';
export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED"; export type RiskTreatment = "ACCEPTED" | "AVOIDED" | "MITIGATED" | "TRANSFERRED";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type RiskGraphFragment$data = { export type RiskGraphFragment$data = {
readonly canCreateRisk: boolean;
readonly id: string; readonly id: string;
readonly risks: { readonly risks: {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly category: string; readonly category: string;
readonly id: string; readonly id: string;
readonly inherentImpact: number; readonly inherentImpact: number;
@@ -126,6 +129,19 @@ return {
}, },
"name": "RiskGraphFragment", "name": "RiskGraphFragment",
"selections": [ "selections": [
{
"alias": "canCreateRisk",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:create\")"
},
{ {
"alias": "risks", "alias": "risks",
"args": [ "args": [
@@ -252,6 +268,32 @@ return {
"name": "residualRiskScore", "name": "residualRiskScore",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:delete\")"
},
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
@@ -338,6 +380,6 @@ return {
}; };
})(); })();
(node as any).hash = "d8048ddb0ff8d4b08b7b9676d9b98f1a"; (node as any).hash = "41dc9e3adc5d7d9b2126a49afef685c7";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<af4a12179ab70cae3cc3f8c434151de0>> * @generated SignedSource<<4a3c1f52f5b371d6cbea3557e609252e>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -133,6 +133,19 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{
"alias": "canCreateRisk",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:create\")"
},
{ {
"alias": null, "alias": null,
"args": (v5/*: any*/), "args": (v5/*: any*/),
@@ -247,6 +260,32 @@ return {
"name": "residualRiskScore", "name": "residualRiskScore",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:delete\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -350,12 +389,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "225123bb702f2bce307ca69bea183e88", "cacheID": "feed1e410567a8707ca0e2e4b651bb7a",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RiskGraphListQuery", "name": "RiskGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query RiskGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...RiskGraphFragment_3iomuz\n }\n}\n\nfragment RiskGraphFragment_3iomuz on Organization {\n risks(first: 50, orderBy: {direction: DESC, field: CREATED_AT}, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n category\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n ...useRiskFormFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n" "text": "query RiskGraphListQuery(\n $organizationId: ID!\n $snapshotId: ID\n) {\n organization: node(id: $organizationId) {\n __typename\n id\n ...RiskGraphFragment_3iomuz\n }\n}\n\nfragment RiskGraphFragment_3iomuz on Organization {\n canCreateRisk: permission(action: \"core:risk:create\")\n risks(first: 50, orderBy: {direction: DESC, field: CREATED_AT}, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n category\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n canUpdate: permission(action: \"core:risk:update\")\n canDelete: permission(action: \"core:risk:delete\")\n ...useRiskFormFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<36175d4a9f9c3b377ec502f518a47015>> * @generated SignedSource<<a5c63cf999a2fe7127e12498399bb307>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -16,6 +16,8 @@ export type RiskGraphNodeQuery$variables = {
}; };
export type RiskGraphNodeQuery$data = { export type RiskGraphNodeQuery$data = {
readonly node: { readonly node: {
readonly canDelete?: boolean;
readonly canUpdate?: boolean;
readonly controlsInfo?: { readonly controlsInfo?: {
readonly totalCount: number; readonly totalCount: number;
}; };
@@ -196,41 +198,67 @@ v17 = {
"storageKey": "obligations(first:0)" "storageKey": "obligations(first:0)"
}, },
v18 = { v18 = {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:update\")"
},
v19 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:delete\")"
},
v20 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v19 = [ v21 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
"value": 100 "value": 100
} }
], ],
v20 = { v22 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "cursor", "name": "cursor",
"storageKey": null "storageKey": null
}, },
v21 = { v23 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "endCursor", "name": "endCursor",
"storageKey": null "storageKey": null
}, },
v22 = { v24 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "hasNextPage", "name": "hasNextPage",
"storageKey": null "storageKey": null
}, },
v23 = { v25 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "PageInfo", "concreteType": "PageInfo",
@@ -238,12 +266,12 @@ v23 = {
"name": "pageInfo", "name": "pageInfo",
"plural": false, "plural": false,
"selections": [ "selections": [
(v21/*: any*/), (v23/*: any*/),
(v22/*: any*/) (v24/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
v24 = { v26 = {
"kind": "ClientExtension", "kind": "ClientExtension",
"selections": [ "selections": [
{ {
@@ -255,14 +283,14 @@ v24 = {
} }
] ]
}, },
v25 = { v27 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "status", "name": "status",
"storageKey": null "storageKey": null
}, },
v26 = [ v28 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
@@ -300,6 +328,8 @@ return {
(v15/*: any*/), (v15/*: any*/),
(v16/*: any*/), (v16/*: any*/),
(v17/*: any*/), (v17/*: any*/),
(v18/*: any*/),
(v19/*: any*/),
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
@@ -355,7 +385,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v18/*: any*/), (v20/*: any*/),
(v2/*: any*/), (v2/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
@@ -372,6 +402,8 @@ return {
(v15/*: any*/), (v15/*: any*/),
(v16/*: any*/), (v16/*: any*/),
(v17/*: any*/), (v17/*: any*/),
(v18/*: any*/),
(v19/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -409,7 +441,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"concreteType": "MeasureConnection", "concreteType": "MeasureConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "measures", "name": "measures",
@@ -440,22 +472,22 @@ return {
"name": "state", "name": "state",
"storageKey": null "storageKey": null
}, },
(v18/*: any*/) (v20/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v20/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v23/*: any*/), (v25/*: any*/),
(v24/*: any*/) (v26/*: any*/)
], ],
"storageKey": "measures(first:100)" "storageKey": "measures(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "Risk__measures", "key": "Risk__measures",
@@ -464,7 +496,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"concreteType": "DocumentConnection", "concreteType": "DocumentConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "documents", "name": "documents",
@@ -539,7 +571,7 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v25/*: any*/) (v27/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -549,22 +581,22 @@ return {
], ],
"storageKey": "versions(first:1)" "storageKey": "versions(first:1)"
}, },
(v18/*: any*/) (v20/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v20/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v23/*: any*/), (v25/*: any*/),
(v24/*: any*/) (v26/*: any*/)
], ],
"storageKey": "documents(first:100)" "storageKey": "documents(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "Risk__documents", "key": "Risk__documents",
@@ -573,7 +605,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v26/*: any*/), "args": (v28/*: any*/),
"concreteType": "ControlConnection", "concreteType": "ControlConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "controls", "name": "controls",
@@ -617,11 +649,11 @@ return {
], ],
"storageKey": null "storageKey": null
}, },
(v18/*: any*/) (v20/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v20/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -633,8 +665,8 @@ return {
"name": "pageInfo", "name": "pageInfo",
"plural": false, "plural": false,
"selections": [ "selections": [
(v21/*: any*/), (v23/*: any*/),
(v22/*: any*/), (v24/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -657,7 +689,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v26/*: any*/), "args": (v28/*: any*/),
"filters": [ "filters": [
"orderBy", "orderBy",
"filter" "filter"
@@ -669,7 +701,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"concreteType": "ObligationConnection", "concreteType": "ObligationConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "obligations", "name": "obligations",
@@ -713,7 +745,7 @@ return {
"name": "source", "name": "source",
"storageKey": null "storageKey": null
}, },
(v25/*: any*/), (v27/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -727,22 +759,22 @@ return {
], ],
"storageKey": null "storageKey": null
}, },
(v18/*: any*/) (v20/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v20/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v23/*: any*/), (v25/*: any*/),
(v24/*: any*/) (v26/*: any*/)
], ],
"storageKey": "obligations(first:100)" "storageKey": "obligations(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v19/*: any*/), "args": (v21/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "Risk__obligations", "key": "Risk__obligations",
@@ -759,16 +791,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "a909af9427061d9e06e22798cbe1ba14", "cacheID": "0445299e60879ca00110fb07c5c1a3d9",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RiskGraphNodeQuery", "name": "RiskGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query RiskGraphNodeQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n ... on Risk {\n id\n snapshotId\n name\n description\n treatment\n owner {\n id\n fullName\n }\n note\n inherentRiskScore\n residualRiskScore\n measuresInfo: measures(first: 0) {\n totalCount\n }\n documentsInfo: documents(first: 0) {\n totalCount\n }\n controlsInfo: controls(first: 0) {\n totalCount\n }\n obligationsInfo: obligations(first: 0) {\n totalCount\n }\n ...useRiskFormFragment\n ...RiskOverviewTabFragment\n ...RiskMeasuresTabFragment\n ...RiskDocumentsTabFragment\n ...RiskControlsTabFragment\n ...RiskObligationsTabFragment\n }\n id\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment LinkedObligationsCardFragment on Obligation {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n}\n\nfragment RiskControlsTabFragment on Risk {\n id\n controls(first: 20) {\n edges {\n node {\n id\n sectionTitle\n name\n framework {\n id\n name\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment RiskDocumentsTabFragment on Risk {\n id\n documents(first: 100) {\n edges {\n node {\n id\n ...LinkedDocumentsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskMeasuresTabFragment on Risk {\n id\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskObligationsTabFragment on Risk {\n id\n obligations(first: 100) {\n edges {\n node {\n id\n ...LinkedObligationsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskOverviewTabFragment on Risk {\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n" "text": "query RiskGraphNodeQuery(\n $riskId: ID!\n) {\n node(id: $riskId) {\n __typename\n ... on Risk {\n id\n snapshotId\n name\n description\n treatment\n owner {\n id\n fullName\n }\n note\n inherentRiskScore\n residualRiskScore\n measuresInfo: measures(first: 0) {\n totalCount\n }\n documentsInfo: documents(first: 0) {\n totalCount\n }\n controlsInfo: controls(first: 0) {\n totalCount\n }\n obligationsInfo: obligations(first: 0) {\n totalCount\n }\n canUpdate: permission(action: \"core:risk:update\")\n canDelete: permission(action: \"core:risk:delete\")\n ...useRiskFormFragment\n ...RiskOverviewTabFragment\n ...RiskMeasuresTabFragment\n ...RiskDocumentsTabFragment\n ...RiskControlsTabFragment\n ...RiskObligationsTabFragment\n }\n id\n }\n}\n\nfragment LinkedDocumentsCardFragment on Document {\n id\n title\n createdAt\n documentType\n versions(first: 1) {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n\nfragment LinkedObligationsCardFragment on Obligation {\n id\n requirement\n area\n source\n status\n owner {\n fullName\n id\n }\n}\n\nfragment RiskControlsTabFragment on Risk {\n id\n controls(first: 20) {\n edges {\n node {\n id\n sectionTitle\n name\n framework {\n id\n name\n }\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n}\n\nfragment RiskDocumentsTabFragment on Risk {\n id\n documents(first: 100) {\n edges {\n node {\n id\n ...LinkedDocumentsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskMeasuresTabFragment on Risk {\n id\n measures(first: 100) {\n edges {\n node {\n id\n ...LinkedMeasuresCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskObligationsTabFragment on Risk {\n id\n obligations(first: 100) {\n edges {\n node {\n id\n ...LinkedObligationsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n}\n\nfragment RiskOverviewTabFragment on Risk {\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "f173ffcac7b82f1b62394cb74d1a78ee"; (node as any).hash = "3e80bcaa15ae8b722471a1c802767c29";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<8c69925ff6e0312b590896229c9bc688>> * @generated SignedSource<<173bd86c9660b900d34ccd42228adae5>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -211,6 +211,19 @@ return {
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
{
"alias": "canCreateRisk",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:create\")"
},
{ {
"alias": null, "alias": null,
"args": (v15/*: any*/), "args": (v15/*: any*/),
@@ -325,6 +338,32 @@ return {
"name": "residualRiskScore", "name": "residualRiskScore",
"storageKey": null "storageKey": null
}, },
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:risk:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:risk:delete\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -428,16 +467,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "34a33dde7e4e7868a885b6b6317f506b", "cacheID": "92be64a69721c7097dcc87a525d7d706",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "RisksListQuery", "name": "RisksListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query RisksListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: RiskOrder = {direction: DESC, field: CREATED_AT}\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...RiskGraphFragment_25MC8O\n id\n }\n}\n\nfragment RiskGraphFragment_25MC8O on Organization {\n risks(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n category\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n ...useRiskFormFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n" "text": "query RisksListQuery(\n $after: CursorKey = null\n $before: CursorKey = null\n $first: Int = 50\n $last: Int = null\n $order: RiskOrder = {direction: DESC, field: CREATED_AT}\n $snapshotId: ID = null\n $id: ID!\n) {\n node(id: $id) {\n __typename\n ...RiskGraphFragment_25MC8O\n id\n }\n}\n\nfragment RiskGraphFragment_25MC8O on Organization {\n canCreateRisk: permission(action: \"core:risk:create\")\n risks(first: $first, after: $after, last: $last, before: $before, orderBy: $order, filter: {snapshotId: $snapshotId}) {\n edges {\n node {\n id\n snapshotId\n name\n category\n treatment\n owner {\n id\n fullName\n }\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n canUpdate: permission(action: \"core:risk:update\")\n canDelete: permission(action: \"core:risk:delete\")\n ...useRiskFormFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n hasPreviousPage\n startCursor\n }\n }\n id\n}\n\nfragment useRiskFormFragment on Risk {\n id\n name\n category\n description\n treatment\n inherentLikelihood\n inherentImpact\n residualLikelihood\n residualImpact\n inherentRiskScore\n residualRiskScore\n note\n owner {\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "d8048ddb0ff8d4b08b7b9676d9b98f1a"; (node as any).hash = "41dc9e3adc5d7d9b2126a49afef685c7";
export default node; export default node;

View File

@@ -5,16 +5,25 @@ import { useTranslate } from "@probo/i18n";
import { promisifyMutation, sprintf } from "@probo/helpers"; import { promisifyMutation, sprintf } from "@probo/helpers";
import { useMutationWithToasts } from "../useMutationWithToasts"; import { useMutationWithToasts } from "../useMutationWithToasts";
export const ProcessingActivitiesConnectionKey = "ProcessingActivitiesPage_processingActivities"; export const ProcessingActivitiesConnectionKey =
"ProcessingActivitiesPage_processingActivities";
export type ProcessingActivityDPIAResidualRisk = "LOW" | "MEDIUM" | "HIGH"; export type ProcessingActivityDPIAResidualRisk = "LOW" | "MEDIUM" | "HIGH";
export const processingActivitiesQuery = graphql` export const processingActivitiesQuery = graphql`
query ProcessingActivityGraphListQuery($organizationId: ID!, $snapshotId: ID) { query ProcessingActivityGraphListQuery(
$organizationId: ID!
$snapshotId: ID
) {
node(id: $organizationId) { node(id: $organizationId) {
... on Organization { ... on Organization {
canCreateProcessingActivity: permission(
action: "core:processing-activity:create"
)
...ProcessingActivitiesPageFragment @arguments(snapshotId: $snapshotId) ...ProcessingActivitiesPageFragment @arguments(snapshotId: $snapshotId)
...ProcessingActivitiesPageDPIAFragment @arguments(snapshotId: $snapshotId) ...ProcessingActivitiesPageDPIAFragment
...ProcessingActivitiesPageTIAFragment @arguments(snapshotId: $snapshotId) @arguments(snapshotId: $snapshotId)
...ProcessingActivitiesPageTIAFragment
@arguments(snapshotId: $snapshotId)
} }
} }
} }
@@ -67,6 +76,12 @@ export const processingActivityNodeQuery = graphql`
residualRisk residualRisk
createdAt createdAt
updatedAt updatedAt
canUpdate: permission(
action: "core:data-protection-impact-assessment:update"
)
canDelete: permission(
action: "core:data-protection-impact-assessment:delete"
)
} }
transferImpactAssessment { transferImpactAssessment {
id id
@@ -77,6 +92,12 @@ export const processingActivityNodeQuery = graphql`
supplementaryMeasures supplementaryMeasures
createdAt createdAt
updatedAt updatedAt
canUpdate: permission(
action: "core:transfer-impact-assessment:update"
)
canDelete: permission(
action: "core:transfer-impact-assessment:delete"
)
} }
organization { organization {
id id
@@ -84,6 +105,14 @@ export const processingActivityNodeQuery = graphql`
} }
createdAt createdAt
updatedAt updatedAt
canCreateDPIA: permission(
action: "core:data-protection-impact-assessment:create"
)
canCreateTIA: permission(
action: "core:transfer-impact-assessment:create"
)
canUpdate: permission(action: "core:processing-activity:update")
canDelete: permission(action: "core:processing-activity:delete")
} }
} }
} }
@@ -130,6 +159,8 @@ export const createProcessingActivityMutation = graphql`
} }
} }
createdAt createdAt
canUpdate: permission(action: "core:processing-activity:update")
canDelete: permission(action: "core:processing-activity:delete")
} }
} }
} }
@@ -137,7 +168,9 @@ export const createProcessingActivityMutation = graphql`
`; `;
export const updateProcessingActivityMutation = graphql` export const updateProcessingActivityMutation = graphql`
mutation ProcessingActivityGraphUpdateMutation($input: UpdateProcessingActivityInput!) { mutation ProcessingActivityGraphUpdateMutation(
$input: UpdateProcessingActivityInput!
) {
updateProcessingActivity(input: $input) { updateProcessingActivity(input: $input) {
processingActivity { processingActivity {
id id
@@ -191,7 +224,7 @@ export const deleteProcessingActivityMutation = graphql`
export const useDeleteProcessingActivity = ( export const useDeleteProcessingActivity = (
processingActivity: { id: string; name: string }, processingActivity: { id: string; name: string },
connectionId: string connectionId: string,
) => { ) => {
const { __ } = useTranslate(); const { __ } = useTranslate();
const [mutate] = useMutationWithToasts(deleteProcessingActivityMutation, { const [mutate] = useMutationWithToasts(deleteProcessingActivityMutation, {
@@ -214,11 +247,11 @@ export const useDeleteProcessingActivity = (
{ {
message: sprintf( message: sprintf(
__( __(
"This will permanently delete the processing activity %s. This action cannot be undone." "This will permanently delete the processing activity %s. This action cannot be undone.",
), ),
processingActivity.name processingActivity.name,
), ),
} },
); );
}; };
}; };
@@ -251,10 +284,14 @@ export const useCreateProcessingActivity = (connectionId?: string) => {
vendorIds?: string[]; vendorIds?: string[];
}) => { }) => {
if (!input.organizationId) { if (!input.organizationId) {
return alert(__("Failed to create processing activity: organization is required")); return alert(
__("Failed to create processing activity: organization is required"),
);
} }
if (!input.name) { if (!input.name) {
return alert(__("Failed to create processing activity: name is required")); return alert(
__("Failed to create processing activity: name is required"),
);
} }
return promisifyMutation(mutate)({ return promisifyMutation(mutate)({
@@ -274,7 +311,8 @@ export const useCreateProcessingActivity = (connectionId?: string) => {
transferSafeguards: input.transferSafeguards, transferSafeguards: input.transferSafeguards,
retentionPeriod: input.retentionPeriod, retentionPeriod: input.retentionPeriod,
securityMeasures: input.securityMeasures, securityMeasures: input.securityMeasures,
dataProtectionImpactAssessmentNeeded: input.dataProtectionImpactAssessmentNeeded, dataProtectionImpactAssessmentNeeded:
input.dataProtectionImpactAssessmentNeeded,
transferImpactAssessmentNeeded: input.transferImpactAssessmentNeeded, transferImpactAssessmentNeeded: input.transferImpactAssessmentNeeded,
lastReviewDate: input.lastReviewDate, lastReviewDate: input.lastReviewDate,
nextReviewDate: input.nextReviewDate, nextReviewDate: input.nextReviewDate,
@@ -388,7 +426,9 @@ export const useCreateDataProtectionImpactAssessment = () => {
residualRisk?: ProcessingActivityDPIAResidualRisk; residualRisk?: ProcessingActivityDPIAResidualRisk;
}) => { }) => {
if (!input.processingActivityId) { if (!input.processingActivityId) {
return alert(__("Failed to create DPIA: Processing Activity ID is required")); return alert(
__("Failed to create DPIA: Processing Activity ID is required"),
);
} }
return promisifyMutation(mutate)({ return promisifyMutation(mutate)({
@@ -425,13 +465,16 @@ export const useUpdateDataProtectionImpactAssessment = () => {
export const useDeleteDataProtectionImpactAssessment = ( export const useDeleteDataProtectionImpactAssessment = (
dpia: { id: string }, dpia: { id: string },
options?: { onSuccess?: () => void } options?: { onSuccess?: () => void },
) => { ) => {
const { __ } = useTranslate(); const { __ } = useTranslate();
const [mutate] = useMutationWithToasts(deleteDataProtectionImpactAssessmentMutation, { const [mutate] = useMutationWithToasts(
successMessage: __("DPIA deleted successfully"), deleteDataProtectionImpactAssessmentMutation,
errorMessage: __("Failed to delete DPIA"), {
}); successMessage: __("DPIA deleted successfully"),
errorMessage: __("Failed to delete DPIA"),
},
);
const confirm = useConfirm(); const confirm = useConfirm();
return () => { return () => {
@@ -447,9 +490,9 @@ export const useDeleteDataProtectionImpactAssessment = (
}), }),
{ {
message: __( message: __(
"This will permanently delete this Data Protection Impact Assessment. This action cannot be undone." "This will permanently delete this Data Protection Impact Assessment. This action cannot be undone.",
), ),
} },
); );
}; };
}; };
@@ -515,7 +558,9 @@ export const useCreateTransferImpactAssessment = () => {
supplementaryMeasures?: string; supplementaryMeasures?: string;
}) => { }) => {
if (!input.processingActivityId) { if (!input.processingActivityId) {
return alert(__("Failed to create TIA: Processing Activity ID is required")); return alert(
__("Failed to create TIA: Processing Activity ID is required"),
);
} }
return promisifyMutation(mutate)({ return promisifyMutation(mutate)({
@@ -552,13 +597,16 @@ export const useUpdateTransferImpactAssessment = () => {
export const useDeleteTransferImpactAssessment = ( export const useDeleteTransferImpactAssessment = (
tia: { id: string }, tia: { id: string },
options?: { onSuccess?: () => void } options?: { onSuccess?: () => void },
) => { ) => {
const { __ } = useTranslate(); const { __ } = useTranslate();
const [mutate] = useMutationWithToasts(deleteTransferImpactAssessmentMutation, { const [mutate] = useMutationWithToasts(
successMessage: __("TIA deleted successfully"), deleteTransferImpactAssessmentMutation,
errorMessage: __("Failed to delete TIA"), {
}); successMessage: __("TIA deleted successfully"),
errorMessage: __("Failed to delete TIA"),
},
);
const confirm = useConfirm(); const confirm = useConfirm();
return () => { return () => {
@@ -574,9 +622,9 @@ export const useDeleteTransferImpactAssessment = (
}), }),
{ {
message: __( message: __(
"This will permanently delete this Transfer Impact Assessment. This action cannot be undone." "This will permanently delete this Transfer Impact Assessment. This action cannot be undone.",
), ),
} },
); );
}; };
}; };

View File

@@ -53,6 +53,7 @@ const risksFragment = graphql`
last: { type: "Int", defaultValue: null } last: { type: "Int", defaultValue: null }
snapshotId: { type: "ID", defaultValue: null } snapshotId: { type: "ID", defaultValue: null }
) { ) {
canCreateRisk: permission(action: "core:risk:create")
risks( risks(
first: $first first: $first
after: $after after: $after
@@ -79,6 +80,8 @@ const risksFragment = graphql`
residualImpact residualImpact
inherentRiskScore inherentRiskScore
residualRiskScore residualRiskScore
canUpdate: permission(action: "core:risk:update")
canDelete: permission(action: "core:risk:delete")
...useRiskFormFragment ...useRiskFormFragment
} }
} }
@@ -131,6 +134,8 @@ export const riskNodeQuery = graphql`
obligationsInfo: obligations(first: 0) { obligationsInfo: obligations(first: 0) {
totalCount totalCount
} }
canUpdate: permission(action: "core:risk:update")
canDelete: permission(action: "core:risk:delete")
...useRiskFormFragment ...useRiskFormFragment
...RiskOverviewTabFragment ...RiskOverviewTabFragment
...RiskMeasuresTabFragment ...RiskMeasuresTabFragment

View File

@@ -64,8 +64,7 @@ import type {
ProcessingActivitiesPageTIAFragment$key, ProcessingActivitiesPageTIAFragment$key,
ProcessingActivitiesPageTIAFragment$data, ProcessingActivitiesPageTIAFragment$data,
} from "/__generated__/core/ProcessingActivitiesPageTIAFragment.graphql"; } from "/__generated__/core/ProcessingActivitiesPageTIAFragment.graphql";
import { PermissionsContext } from "/providers/PermissionsContext"; import { useState } from "react";
import { use, useState } from "react";
import type { ProcessingActivityGraphListQuery } from "/__generated__/core/ProcessingActivityGraphListQuery.graphql"; import type { ProcessingActivityGraphListQuery } from "/__generated__/core/ProcessingActivityGraphListQuery.graphql";
interface ProcessingActivitiesPageProps { interface ProcessingActivitiesPageProps {
@@ -106,6 +105,8 @@ const processingActivitiesPageFragment = graphql`
internationalTransfers internationalTransfers
createdAt createdAt
updatedAt updatedAt
canUpdate: permission(action: "core:processing-activity:update")
canDelete: permission(action: "core:processing-activity:delete")
} }
} }
pageInfo { pageInfo {
@@ -237,7 +238,6 @@ export default function ProcessingActivitiesPage({
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>(); const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const { isAuthorized } = use(PermissionsContext);
const [activeTab, setActiveTab] = useState<"activities" | "dpia" | "tia">( const [activeTab, setActiveTab] = useState<"activities" | "dpia" | "tia">(
"activities", "activities",
); );
@@ -292,8 +292,7 @@ export default function ProcessingActivitiesPage({
const hasAnyAction = const hasAnyAction =
!isSnapshotMode && !isSnapshotMode &&
(isAuthorized("ProcessingActivity", "updateProcessingActivity") || activities.some(({ canUpdate, canDelete }) => canUpdate || canDelete);
isAuthorized("ProcessingActivity", "deleteProcessingActivity"));
const canExportPDF = isAuthorized( const canExportPDF = isAuthorized(
"ProcessingActivity", "ProcessingActivity",
@@ -467,7 +466,7 @@ export default function ProcessingActivitiesPage({
)} )}
{!isSnapshotMode && {!isSnapshotMode &&
activeTab === "activities" && activeTab === "activities" &&
isAuthorized("Organization", "createProcessingActivity") && ( organization.node.canCreateProcessingActivity && (
<CreateProcessingActivityDialog <CreateProcessingActivityDialog
organizationId={organizationId} organizationId={organizationId}
connectionId={connectionId} connectionId={connectionId}
@@ -677,7 +676,6 @@ function ActivityRow({
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const [deleteActivity] = useMutation(deleteProcessingActivityMutation); const [deleteActivity] = useMutation(deleteProcessingActivityMutation);
const confirm = useConfirm(); const confirm = useConfirm();
const { isAuthorized } = use(PermissionsContext);
const handleDelete = () => { const handleDelete = () => {
confirm( confirm(
@@ -729,7 +727,7 @@ function ActivityRow({
{hasAnyAction && ( {hasAnyAction && (
<Td noLink width={50} className="text-end"> <Td noLink width={50} className="text-end">
<ActionDropdown> <ActionDropdown>
{isAuthorized("ProcessingActivity", "deleteProcessingActivity") && ( {activity.canDelete && (
<DropdownItem <DropdownItem
icon={IconTrashCan} icon={IconTrashCan}
variant="danger" variant="danger"

View File

@@ -58,8 +58,7 @@ import {
} from "../../../components/form/ProcessingActivityEnumOptions"; } from "../../../components/form/ProcessingActivityEnumOptions";
import type { ProcessingActivityGraphNodeQuery } from "/__generated__/core/ProcessingActivityGraphNodeQuery.graphql"; import type { ProcessingActivityGraphNodeQuery } from "/__generated__/core/ProcessingActivityGraphNodeQuery.graphql";
import { use, useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
const updateProcessingActivitySchema = z.object({ const updateProcessingActivitySchema = z.object({
name: z.string().min(1, "Name is required"), name: z.string().min(1, "Name is required"),
@@ -99,17 +98,16 @@ type Props = {
}; };
export default function ProcessingActivityDetailsPage(props: Props) { export default function ProcessingActivityDetailsPage(props: Props) {
const data = usePreloadedQuery<ProcessingActivityGraphNodeQuery>( const { node: activity } =
processingActivityNodeQuery, usePreloadedQuery<ProcessingActivityGraphNodeQuery>(
props.queryRef, processingActivityNodeQuery,
); props.queryRef,
const activity = data.node; );
const { __ } = useTranslate(); const { __ } = useTranslate();
const { toast } = useToast(); const { toast } = useToast();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>(); const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const { isAuthorized } = use(PermissionsContext);
// Get initial tab from URL hash // Get initial tab from URL hash
const getInitialTab = (): "overview" | "dpia" | "tia" => { const getInitialTab = (): "overview" | "dpia" | "tia" => {
@@ -132,6 +130,13 @@ export default function ProcessingActivityDetailsPage(props: Props) {
const [dpiaDeleted, setDpiaDeleted] = useState(false); const [dpiaDeleted, setDpiaDeleted] = useState(false);
const [tiaDeleted, setTiaDeleted] = useState(false); const [tiaDeleted, setTiaDeleted] = useState(false);
const canCreateOrUpdateDPIA = activity.dataProtectionImpactAssessment
? activity.dataProtectionImpactAssessment.canUpdate
: activity.canCreateDPIA;
const canCreateOrUpdateTIA = activity.transferImpactAssessment
? activity.transferImpactAssessment.canUpdate
: activity.canCreateTIA;
useEffect(() => { useEffect(() => {
window.location.hash = activeTab === "overview" ? "" : activeTab; window.location.hash = activeTab === "overview" ? "" : activeTab;
}, [activeTab]); }, [activeTab]);
@@ -422,14 +427,13 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{ label: activity.name! }, { label: activity.name! },
]} ]}
/> />
{!isSnapshotMode && {!isSnapshotMode && activity.canDelete && (
isAuthorized("ProcessingActivity", "deleteProcessingActivity") && ( <ActionDropdown>
<ActionDropdown> <DropdownItem onClick={deleteActivity} variant="danger">
<DropdownItem onClick={deleteActivity} variant="danger"> {__("Delete")}
{__("Delete")} </DropdownItem>
</DropdownItem> </ActionDropdown>
</ActionDropdown> )}
)}
</div> </div>
<div className="mb-6"> <div className="mb-6">
@@ -468,7 +472,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{...register("name")} {...register("name")}
error={formState.errors.name?.message} error={formState.errors.name?.message}
required required
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<div> <div>
@@ -483,7 +487,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<RoleOptions /> <RoleOptions />
</Select> </Select>
@@ -502,7 +506,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{...register("purpose")} {...register("purpose")}
placeholder={__("Describe the purpose of processing")} placeholder={__("Describe the purpose of processing")}
rows={3} rows={3}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
</div> </div>
@@ -510,14 +514,14 @@ export default function ProcessingActivityDetailsPage(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} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<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} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<div> <div>
@@ -536,7 +540,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<SpecialOrCriminalDataOptions /> <SpecialOrCriminalDataOptions />
</Select> </Select>
@@ -553,7 +557,7 @@ export default function ProcessingActivityDetailsPage(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} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<div> <div>
@@ -568,7 +572,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<LawfulBasisOptions /> <LawfulBasisOptions />
</Select> </Select>
@@ -589,7 +593,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
id="lastReviewDate" id="lastReviewDate"
type="date" type="date"
{...register("lastReviewDate")} {...register("lastReviewDate")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
</div> </div>
@@ -601,7 +605,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
id="nextReviewDate" id="nextReviewDate"
type="date" type="date"
{...register("nextReviewDate")} {...register("nextReviewDate")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
</div> </div>
@@ -610,7 +614,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
control={control} control={control}
name="dataProtectionOfficerId" name="dataProtectionOfficerId"
label={__("Data Protection Officer")} label={__("Data Protection Officer")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
</div> </div>
@@ -619,14 +623,14 @@ export default function ProcessingActivityDetailsPage(props: Props) {
label={__("Recipients")} label={__("Recipients")}
{...register("recipients")} {...register("recipients")}
placeholder={__("Who receives the data")} placeholder={__("Who receives the data")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<Field <Field
label={__("Location")} label={__("Location")}
{...register("location")} {...register("location")}
placeholder={__("Where is the data processed")} placeholder={__("Where is the data processed")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<Controller <Controller
@@ -639,7 +643,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
<Checkbox <Checkbox
checked={field.value ?? false} checked={field.value ?? false}
onChange={field.onChange} onChange={field.onChange}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<span> <span>
{__("Data is transferred internationally")} {__("Data is transferred internationally")}
@@ -663,7 +667,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<TransferSafeguardsOptions /> <TransferSafeguardsOptions />
</Select> </Select>
@@ -680,7 +684,7 @@ export default function ProcessingActivityDetailsPage(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} disabled={isSnapshotMode || !activity.canUpdate}
/> />
<div> <div>
@@ -689,7 +693,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{...register("securityMeasures")} {...register("securityMeasures")}
placeholder={__("Technical and organizational measures")} placeholder={__("Technical and organizational measures")}
rows={3} rows={3}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
</div> </div>
@@ -707,7 +711,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<DataProtectionImpactAssessmentOptions /> <DataProtectionImpactAssessmentOptions />
</Select> </Select>
@@ -737,7 +741,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
> >
<TransferImpactAssessmentOptions /> <TransferImpactAssessmentOptions />
</Select> </Select>
@@ -761,15 +765,12 @@ export default function ProcessingActivityDetailsPage(props: Props) {
name="vendorIds" name="vendorIds"
selectedVendors={vendors} selectedVendors={vendors}
label={__("Vendors")} label={__("Vendors")}
disabled={isSnapshotMode} disabled={isSnapshotMode || !activity.canUpdate}
/> />
{!isSnapshotMode && ( {!isSnapshotMode && (
<div className="flex justify-end pt-4"> <div className="flex justify-end pt-4">
{isAuthorized( {activity.canUpdate && (
"ProcessingActivity",
"updateProcessingActivity",
) && (
<Button <Button
type="submit" type="submit"
variant="primary" variant="primary"
@@ -796,18 +797,14 @@ export default function ProcessingActivityDetailsPage(props: Props) {
<h2 className="text-xl font-semibold mb-6 text-center"> <h2 className="text-xl font-semibold mb-6 text-center">
{__("Data Protection Impact Assessment")} {__("Data Protection Impact Assessment")}
</h2> </h2>
{!isSnapshotMode && {!isSnapshotMode && activity.canCreateDPIA && (
isAuthorized( <Button
"ProcessingActivity", variant="primary"
"createDataProtectionImpactAssessment", onClick={() => setShowDpiaForm(true)}
) && ( >
<Button {__("Create DPIA")}
variant="primary" </Button>
onClick={() => setShowDpiaForm(true)} )}
>
{__("Create DPIA")}
</Button>
)}
</div> </div>
) : ( ) : (
<> <>
@@ -818,10 +815,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{!isSnapshotMode && {!isSnapshotMode &&
activity?.dataProtectionImpactAssessment?.id && activity?.dataProtectionImpactAssessment?.id &&
!dpiaDeleted && !dpiaDeleted &&
isAuthorized( activity.dataProtectionImpactAssessment.canDelete && (
"DataProtectionImpactAssessment",
"deleteDataProtectionImpactAssessment",
) && (
<Button variant="danger" onClick={deleteDPIA}> <Button variant="danger" onClick={deleteDPIA}>
{__("Delete DPIA")} {__("Delete DPIA")}
</Button> </Button>
@@ -840,7 +834,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe the processing activity and its purpose", "Describe the processing activity and its purpose",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateDPIA}
/> />
</div> </div>
@@ -855,7 +849,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Explain why the processing is necessary and proportionate", "Explain why the processing is necessary and proportionate",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateDPIA}
/> />
</div> </div>
@@ -870,7 +864,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe the potential risks to data subjects", "Describe the potential risks to data subjects",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateDPIA}
/> />
</div> </div>
@@ -885,7 +879,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe measures to mitigate the identified risks", "Describe measures to mitigate the identified risks",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateDPIA}
/> />
</div> </div>
@@ -903,7 +897,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
onValueChange={field.onChange} onValueChange={field.onChange}
value={field.value} value={field.value}
className="w-full" className="w-full"
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateDPIA}
> >
<Option value="LOW">{__("Low")}</Option> <Option value="LOW">{__("Low")}</Option>
<Option value="MEDIUM">{__("Medium")}</Option> <Option value="MEDIUM">{__("Medium")}</Option>
@@ -927,14 +921,8 @@ export default function ProcessingActivityDetailsPage(props: Props) {
)} )}
{(activity?.dataProtectionImpactAssessment?.id && {(activity?.dataProtectionImpactAssessment?.id &&
!dpiaDeleted !dpiaDeleted
? isAuthorized( ? activity.dataProtectionImpactAssessment.canUpdate
"DataProtectionImpactAssessment", : activity.canCreateDPIA) && (
"updateDataProtectionImpactAssessment",
)
: isAuthorized(
"ProcessingActivity",
"createDataProtectionImpactAssessment",
)) && (
<Button <Button
type="submit" type="submit"
variant="primary" variant="primary"
@@ -966,18 +954,14 @@ export default function ProcessingActivityDetailsPage(props: Props) {
<h2 className="text-xl font-semibold mb-6 text-center"> <h2 className="text-xl font-semibold mb-6 text-center">
{__("Transfer Impact Assessment")} {__("Transfer Impact Assessment")}
</h2> </h2>
{!isSnapshotMode && {!isSnapshotMode && activity.canCreateTIA && (
isAuthorized( <Button
"ProcessingActivity", variant="primary"
"createTransferImpactAssessment", onClick={() => setShowTiaForm(true)}
) && ( >
<Button {__("Create TIA")}
variant="primary" </Button>
onClick={() => setShowTiaForm(true)} )}
>
{__("Create TIA")}
</Button>
)}
</div> </div>
) : ( ) : (
<> <>
@@ -988,10 +972,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
{!isSnapshotMode && {!isSnapshotMode &&
activity?.transferImpactAssessment?.id && activity?.transferImpactAssessment?.id &&
!tiaDeleted && !tiaDeleted &&
isAuthorized( activity.transferImpactAssessment.canDelete && (
"TransferImpactAssessment",
"deleteTransferImpactAssessment",
) && (
<Button variant="danger" onClick={deleteTIA}> <Button variant="danger" onClick={deleteTIA}>
{__("Delete TIA")} {__("Delete TIA")}
</Button> </Button>
@@ -1010,7 +991,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe the data subjects involved in the transfer", "Describe the data subjects involved in the transfer",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateTIA}
/> />
</div> </div>
@@ -1025,7 +1006,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe the legal mechanism for the transfer (e.g., SCCs, BCRs, adequacy decision)", "Describe the legal mechanism for the transfer (e.g., SCCs, BCRs, adequacy decision)",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateTIA}
/> />
</div> </div>
@@ -1038,7 +1019,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe the nature and details of the data transfer", "Describe the nature and details of the data transfer",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateTIA}
/> />
</div> </div>
@@ -1053,7 +1034,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Assess the risks related to the local laws of the destination country", "Assess the risks related to the local laws of the destination country",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateTIA}
/> />
</div> </div>
@@ -1068,7 +1049,7 @@ export default function ProcessingActivityDetailsPage(props: Props) {
"Describe any supplementary measures taken to ensure adequate protection", "Describe any supplementary measures taken to ensure adequate protection",
)} )}
rows={4} rows={4}
disabled={isSnapshotMode} disabled={isSnapshotMode || !canCreateOrUpdateTIA}
/> />
</div> </div>
@@ -1085,14 +1066,8 @@ export default function ProcessingActivityDetailsPage(props: Props) {
</Button> </Button>
)} )}
{(activity?.transferImpactAssessment?.id && !tiaDeleted {(activity?.transferImpactAssessment?.id && !tiaDeleted
? isAuthorized( ? activity.transferImpactAssessment.canUpdate
"TransferImpactAssessment", : activity.canCreateTIA) && (
"updateTransferImpactAssessment",
)
: isAuthorized(
"ProcessingActivity",
"createTransferImpactAssessment",
)) && (
<Button <Button
type="submit" type="submit"
variant="primary" variant="primary"

View File

@@ -34,8 +34,6 @@ import {
} from "/hooks/graph/RiskGraph"; } from "/hooks/graph/RiskGraph";
import type { RiskGraphNodeQuery } from "/__generated__/core/RiskGraphNodeQuery.graphql"; import type { RiskGraphNodeQuery } from "/__generated__/core/RiskGraphNodeQuery.graphql";
import { SnapshotBanner } from "/components/SnapshotBanner"; import { SnapshotBanner } from "/components/SnapshotBanner";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
type Props = { type Props = {
queryRef: PreloadedQuery<RiskGraphNodeQuery>; queryRef: PreloadedQuery<RiskGraphNodeQuery>;
@@ -49,18 +47,16 @@ export default function RiskDetailPage(props: Props) {
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const navigate = useNavigate(); const navigate = useNavigate();
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const { isAuthorized } = use(PermissionsContext);
if (!riskId) { if (!riskId) {
throw new Error("Cannot load risk detail page without riskId parameter"); throw new Error("Cannot load risk detail page without riskId parameter");
} }
const { __ } = useTranslate(); const { __ } = useTranslate();
const data = usePreloadedQuery<RiskGraphNodeQuery>( const { node: risk } = usePreloadedQuery<RiskGraphNodeQuery>(
riskNodeQuery, riskNodeQuery,
props.queryRef, props.queryRef,
); );
const risk = data.node;
validateSnapshotConsistency(risk, snapshotId); validateSnapshotConsistency(risk, snapshotId);
const [deleteRisk] = useDeleteRiskMutation(); const [deleteRisk] = useDeleteRiskMutation();
@@ -136,7 +132,7 @@ export default function RiskDetailPage(props: Props) {
/> />
{!isSnapshotMode && ( {!isSnapshotMode && (
<div className="flex gap-2"> <div className="flex gap-2">
{isAuthorized("Risk", "updateRisk") && ( {risk.canUpdate && (
<FormRiskDialog <FormRiskDialog
trigger={ trigger={
<Button icon={IconPencil} variant="secondary"> <Button icon={IconPencil} variant="secondary">
@@ -146,7 +142,7 @@ export default function RiskDetailPage(props: Props) {
risk={{ id: riskId, ...risk }} risk={{ id: riskId, ...risk }}
/> />
)} )}
{isAuthorized("Risk", "deleteRisk") && ( {risk.canDelete && (
<ActionDropdown variant="secondary"> <ActionDropdown variant="secondary">
<DropdownItem <DropdownItem
variant="danger" variant="danger"

View File

@@ -29,8 +29,6 @@ import type { RiskGraphListQuery } from "/__generated__/core/RiskGraphListQuery.
import type { RiskGraphFragment$data } from "/__generated__/core/RiskGraphFragment.graphql"; import type { RiskGraphFragment$data } from "/__generated__/core/RiskGraphFragment.graphql";
import { useParams } from "react-router"; import { useParams } from "react-router";
import { SnapshotBanner } from "/components/SnapshotBanner"; import { SnapshotBanner } from "/components/SnapshotBanner";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
type Props = { type Props = {
queryRef: PreloadedQuery<RiskGraphListQuery>; queryRef: PreloadedQuery<RiskGraphListQuery>;
@@ -41,9 +39,13 @@ export default function RisksPage(props: Props) {
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const { snapshotId } = useParams<{ snapshotId?: string }>(); const { snapshotId } = useParams<{ snapshotId?: string }>();
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const { isAuthorized } = use(PermissionsContext);
const { connectionId, risks, ...pagination } = useRisksQuery(props.queryRef); const {
data: { canCreateRisk },
connectionId,
risks,
...pagination
} = useRisksQuery(props.queryRef);
const refetch = ({ const refetch = ({
order, order,
@@ -73,7 +75,7 @@ export default function RisksPage(props: Props) {
const hasAnyAction = const hasAnyAction =
!isSnapshotMode && !isSnapshotMode &&
(isAuthorized("Risk", "updateRisk") || isAuthorized("Risk", "deleteRisk")); risks.some(({ canDelete, canUpdate }) => canUpdate || canDelete);
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -84,7 +86,7 @@ export default function RisksPage(props: Props) {
"Risks are potential threats to your organization. Manage them by identifying, assessing, and implementing mitigation measures.", "Risks are potential threats to your organization. Manage them by identifying, assessing, and implementing mitigation measures.",
)} )}
> >
{!isSnapshotMode && isAuthorized("Organization", "createRisk") && ( {!isSnapshotMode && canCreateRisk && (
<FormRiskDialog <FormRiskDialog
connection={connectionId} connection={connectionId}
onSuccess={() => { onSuccess={() => {
@@ -153,7 +155,6 @@ function RiskRow(props: RowProps) {
const isSnapshotMode = Boolean(snapshotId); const isSnapshotMode = Boolean(snapshotId);
const [deleteRisk] = useDeleteRiskMutation(); const [deleteRisk] = useDeleteRiskMutation();
const confirm = useConfirm(); const confirm = useConfirm();
const { isAuthorized } = use(PermissionsContext);
const onDelete = () => { const onDelete = () => {
confirm( confirm(
() => () =>
@@ -206,7 +207,7 @@ function RiskRow(props: RowProps) {
{props.hasAnyAction && ( {props.hasAnyAction && (
<Td noLink className="text-end"> <Td noLink className="text-end">
<ActionDropdown> <ActionDropdown>
{isAuthorized("Risk", "updateRisk") && ( {risk.canUpdate && (
<DropdownItem <DropdownItem
icon={IconPencil} icon={IconPencil}
onClick={() => formDialogRef.current?.open()} onClick={() => formDialogRef.current?.open()}
@@ -215,7 +216,7 @@ function RiskRow(props: RowProps) {
</DropdownItem> </DropdownItem>
)} )}
{isAuthorized("Risk", "deleteRisk") && ( {risk.canDelete && (
<DropdownItem <DropdownItem
variant="danger" variant="danger"
icon={IconTrashCan} icon={IconTrashCan}