Fix framework pages permissions handling

Signed-off-by: Émile Ré <nemile.re@gmail.com>
This commit is contained in:
Émile Ré
2025-12-31 17:49:56 +01:00
committed by Bryan Frimin
parent 269f963b48
commit 095254a73d
11 changed files with 663 additions and 188 deletions

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<1c21fa202a0315a19517c79eb93932f3>> * @generated SignedSource<<7f57391fcdf09c326854f1cc2e0008c2>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -12,6 +12,10 @@ import { ReaderFragment } from 'relay-runtime';
export type ControlStatus = "EXCLUDED" | "INCLUDED"; export type ControlStatus = "EXCLUDED" | "INCLUDED";
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type FrameworkDetailPageFragment$data = { export type FrameworkDetailPageFragment$data = {
readonly canCreateControl: boolean;
readonly canDelete: boolean;
readonly canExport: boolean;
readonly canUpdate: boolean;
readonly controls: { readonly controls: {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
@@ -84,6 +88,58 @@ return {
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
}, },
{
"alias": "canExport",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:franework:export"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:franework:export\")"
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
},
{
"alias": "canCreateControl",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -191,6 +247,6 @@ return {
}; };
})(); })();
(node as any).hash = "e7be231a4f5cbad12945d2ca627cc442"; (node as any).hash = "c88994d5f1872bfe21cfe65e1911b76a";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<af136d6db1a014d6241ad2c9c6dd5f55>> * @generated SignedSource<<3e99dde71cf9c37ef1ec401a9e76bb6c>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -173,6 +173,32 @@ return {
"kind": "ScalarField", "kind": "ScalarField",
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
} }
], ],
"storageKey": null "storageKey": null
@@ -202,12 +228,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "c66177d87b59d87fdf7cbc9268af431a", "cacheID": "a26c4f5b9c310055da331176905fc712",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "FrameworkFormDialogMutation", "name": "FrameworkFormDialogMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation FrameworkFormDialogMutation(\n $input: CreateFrameworkInput!\n) {\n createFramework(input: $input) {\n frameworkEdge {\n node {\n id\n ...FrameworksPageCardFragment\n }\n }\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n}\n" "text": "mutation FrameworkFormDialogMutation(\n $input: CreateFrameworkInput!\n) {\n createFramework(input: $input) {\n frameworkEdge {\n node {\n id\n ...FrameworksPageCardFragment\n }\n }\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<ec1b843d1afb3a82c747b8580b528fda>> * @generated SignedSource<<194328b415c68a01a447d4646639b3c0>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -25,6 +25,20 @@ export type FrameworkGraphControlNodeQuery$data = {
}; };
}>; }>;
}; };
readonly canCreateAuditMapping?: boolean;
readonly canCreateDocumentMapping?: boolean;
readonly canCreateMeasureMapping?: boolean;
readonly canCreateObligationMapping?: boolean;
readonly canCreateSnapshotMapping?: boolean;
readonly canCreateStateOfApplicabilityMapping?: boolean;
readonly canDelete?: boolean;
readonly canDeleteAuditMapping?: boolean;
readonly canDeleteDocumentMapping?: boolean;
readonly canDeleteMeasureMapping?: boolean;
readonly canDeleteObligationMapping?: boolean;
readonly canDeleteSnapshotMapping?: boolean;
readonly canDeleteStateOfApplicabilityMapping?: boolean;
readonly canUpdate?: boolean;
readonly description?: string | null | undefined; readonly description?: string | null | undefined;
readonly documents?: { readonly documents?: {
readonly __id: string; readonly __id: string;
@@ -142,20 +156,202 @@ v7 = {
"storageKey": null "storageKey": null
}, },
v8 = { v8 = {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:update\")"
},
v9 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:delete\")"
},
v10 = {
"alias": "canCreateMeasureMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create-measure-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create-measure-mapping\")"
},
v11 = {
"alias": "canDeleteMeasureMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:delete-measure-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:delete-measure-mapping\")"
},
v12 = {
"alias": "canCreateDocumentMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create-document-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create-document-mapping\")"
},
v13 = {
"alias": "canDeleteDocumentMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:delete-document-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:delete-document-mapping\")"
},
v14 = {
"alias": "canCreateAuditMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create-audit-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create-audit-mapping\")"
},
v15 = {
"alias": "canDeleteAuditMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:delete-audit-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:delete-audit-mapping\")"
},
v16 = {
"alias": "canCreateSnapshotMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create-snapshot-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create-snapshot-mapping\")"
},
v17 = {
"alias": "canDeleteSnapshotMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:delete-snapshot-mapping"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:delete-snapshot-mapping\")"
},
v18 = {
"alias": "canCreateStateOfApplicabilityMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:state-of-applicability-control-mapping:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:state-of-applicability-control-mapping:create\")"
},
v19 = {
"alias": "canDeleteStateOfApplicabilityMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:state-of-applicability-control-mapping:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:state-of-applicability-control-mapping:delete\")"
},
v20 = {
"alias": "canCreateObligationMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:obligation-control-mapping:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:obligation-control-mapping:create\")"
},
v21 = {
"alias": "canDeleteObligationMapping",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:obligation-control-mapping:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:obligation-control-mapping:delete\")"
},
v22 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v9 = { v23 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "cursor", "name": "cursor",
"storageKey": null "storageKey": null
}, },
v10 = { v24 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "PageInfo", "concreteType": "PageInfo",
@@ -180,7 +376,7 @@ v10 = {
], ],
"storageKey": null "storageKey": null
}, },
v11 = { v25 = {
"kind": "ClientExtension", "kind": "ClientExtension",
"selections": [ "selections": [
{ {
@@ -192,25 +388,25 @@ v11 = {
} }
] ]
}, },
v12 = [ v26 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
"value": 100 "value": 100
} }
], ],
v13 = [ v27 = [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/) (v3/*: any*/)
], ],
v14 = { v28 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "state", "name": "state",
"storageKey": null "storageKey": null
}, },
v15 = { v29 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -241,6 +437,20 @@ return {
(v5/*: any*/), (v5/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
(v11/*: any*/),
(v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/),
(v15/*: any*/),
(v16/*: any*/),
(v17/*: any*/),
(v18/*: any*/),
(v19/*: any*/),
(v20/*: any*/),
(v21/*: any*/),
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
@@ -276,16 +486,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedStatesOfApplicabilityCardFragment" "name": "LinkedStatesOfApplicabilityCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -319,16 +529,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedMeasuresCardFragment" "name": "LinkedMeasuresCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -362,16 +572,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedDocumentsCardFragment" "name": "LinkedDocumentsCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -405,16 +615,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedAuditsCardFragment" "name": "LinkedAuditsCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -448,16 +658,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedObligationsCardFragment" "name": "LinkedObligationsCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
@@ -491,16 +701,16 @@ return {
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "LinkedSnapshotsCardFragment" "name": "LinkedSnapshotsCardFragment"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -529,7 +739,7 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v8/*: any*/), (v22/*: any*/),
(v2/*: any*/), (v2/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
@@ -539,6 +749,20 @@ return {
(v5/*: any*/), (v5/*: any*/),
(v6/*: any*/), (v6/*: any*/),
(v7/*: any*/), (v7/*: any*/),
(v8/*: any*/),
(v9/*: any*/),
(v10/*: any*/),
(v11/*: any*/),
(v12/*: any*/),
(v13/*: any*/),
(v14/*: any*/),
(v15/*: any*/),
(v16/*: any*/),
(v17/*: any*/),
(v18/*: any*/),
(v19/*: any*/),
(v20/*: any*/),
(v21/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -548,7 +772,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "StateOfApplicabilityControlConnection", "concreteType": "StateOfApplicabilityControlConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "stateOfApplicabilityControls", "name": "stateOfApplicabilityControls",
@@ -592,7 +816,7 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "stateOfApplicability", "name": "stateOfApplicability",
"plural": false, "plural": false,
"selections": (v13/*: any*/), "selections": (v27/*: any*/),
"storageKey": null "storageKey": null
}, },
{ {
@@ -609,22 +833,22 @@ return {
"name": "justification", "name": "justification",
"storageKey": null "storageKey": null
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "stateOfApplicabilityControls(first:100)" "storageKey": "stateOfApplicabilityControls(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_stateOfApplicabilityControls", "key": "FrameworkGraphControl_stateOfApplicabilityControls",
@@ -633,7 +857,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "MeasureConnection", "concreteType": "MeasureConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "measures", "name": "measures",
@@ -657,23 +881,23 @@ return {
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v14/*: any*/), (v28/*: any*/),
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "measures(first:100)" "storageKey": "measures(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_measures", "key": "FrameworkGraphControl_measures",
@@ -682,7 +906,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "DocumentConnection", "concreteType": "DocumentConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "documents", "name": "documents",
@@ -712,7 +936,7 @@ return {
"name": "title", "name": "title",
"storageKey": null "storageKey": null
}, },
(v15/*: any*/), (v29/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -761,22 +985,22 @@ return {
], ],
"storageKey": "versions(first:1)" "storageKey": "versions(first:1)"
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "documents(first:100)" "storageKey": "documents(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_documents", "key": "FrameworkGraphControl_documents",
@@ -785,7 +1009,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "AuditConnection", "concreteType": "AuditConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "audits", "name": "audits",
@@ -809,8 +1033,8 @@ return {
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/), (v3/*: any*/),
(v15/*: any*/), (v29/*: any*/),
(v14/*: any*/), (v28/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -832,25 +1056,25 @@ return {
"kind": "LinkedField", "kind": "LinkedField",
"name": "framework", "name": "framework",
"plural": false, "plural": false,
"selections": (v13/*: any*/), "selections": (v27/*: any*/),
"storageKey": null "storageKey": null
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "audits(first:100)" "storageKey": "audits(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_audits", "key": "FrameworkGraphControl_audits",
@@ -859,7 +1083,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "ObligationConnection", "concreteType": "ObligationConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "obligations", "name": "obligations",
@@ -923,22 +1147,22 @@ return {
], ],
"storageKey": null "storageKey": null
}, },
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "obligations(first:100)" "storageKey": "obligations(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_obligations", "key": "FrameworkGraphControl_obligations",
@@ -947,7 +1171,7 @@ return {
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"concreteType": "SnapshotConnection", "concreteType": "SnapshotConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "snapshots", "name": "snapshots",
@@ -979,23 +1203,23 @@ return {
"name": "type", "name": "type",
"storageKey": null "storageKey": null
}, },
(v15/*: any*/), (v29/*: any*/),
(v8/*: any*/) (v22/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v9/*: any*/) (v23/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v10/*: any*/), (v24/*: any*/),
(v11/*: any*/) (v25/*: any*/)
], ],
"storageKey": "snapshots(first:100)" "storageKey": "snapshots(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v12/*: any*/), "args": (v26/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworkGraphControl_snapshots", "key": "FrameworkGraphControl_snapshots",
@@ -1012,7 +1236,7 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "f7773b474bf5f22e9a7075c685839001", "cacheID": "83f936f5dced0f50c645aa6ef30efedc",
"id": null, "id": null,
"metadata": { "metadata": {
"connection": [ "connection": [
@@ -1074,11 +1298,11 @@ return {
}, },
"name": "FrameworkGraphControlNodeQuery", "name": "FrameworkGraphControlNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query FrameworkGraphControlNodeQuery(\n $controlId: ID!\n) {\n node(id: $controlId) {\n __typename\n ... on Control {\n id\n name\n sectionTitle\n description\n status\n exclusionJustification\n ...FrameworkControlDialogFragment\n stateOfApplicabilityControls(first: 100) {\n edges {\n node {\n id\n ...LinkedStatesOfApplicabilityCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\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 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 audits(first: 100) {\n edges {\n node {\n id\n ...LinkedAuditsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\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 snapshots(first: 100) {\n edges {\n node {\n id\n ...LinkedSnapshotsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n status\n exclusionJustification\n bestPractice\n}\n\nfragment LinkedAuditsCardFragment on Audit {\n id\n name\n createdAt\n state\n validFrom\n validUntil\n framework {\n id\n name\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 LinkedSnapshotsCardFragment on Snapshot {\n id\n name\n description\n type\n createdAt\n}\n\nfragment LinkedStatesOfApplicabilityCardFragment on StateOfApplicabilityControl {\n id\n stateOfApplicabilityId\n controlId\n stateOfApplicability {\n id\n name\n }\n applicability\n justification\n}\n" "text": "query FrameworkGraphControlNodeQuery(\n $controlId: ID!\n) {\n node(id: $controlId) {\n __typename\n ... on Control {\n id\n name\n sectionTitle\n description\n status\n exclusionJustification\n canUpdate: permission(action: \"core:control:update\")\n canDelete: permission(action: \"core:control:delete\")\n canCreateMeasureMapping: permission(action: \"core:control:create-measure-mapping\")\n canDeleteMeasureMapping: permission(action: \"core:control:delete-measure-mapping\")\n canCreateDocumentMapping: permission(action: \"core:control:create-document-mapping\")\n canDeleteDocumentMapping: permission(action: \"core:control:delete-document-mapping\")\n canCreateAuditMapping: permission(action: \"core:control:create-audit-mapping\")\n canDeleteAuditMapping: permission(action: \"core:control:delete-audit-mapping\")\n canCreateSnapshotMapping: permission(action: \"core:control:create-snapshot-mapping\")\n canDeleteSnapshotMapping: permission(action: \"core:control:delete-snapshot-mapping\")\n canCreateStateOfApplicabilityMapping: permission(action: \"core:control:state-of-applicability-control-mapping:create\")\n canDeleteStateOfApplicabilityMapping: permission(action: \"core:control:state-of-applicability-control-mapping:delete\")\n canCreateObligationMapping: permission(action: \"core:control:obligation-control-mapping:create\")\n canDeleteObligationMapping: permission(action: \"core:control:obligation-control-mapping:delete\")\n ...FrameworkControlDialogFragment\n stateOfApplicabilityControls(first: 100) {\n edges {\n node {\n id\n ...LinkedStatesOfApplicabilityCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\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 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 audits(first: 100) {\n edges {\n node {\n id\n ...LinkedAuditsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\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 snapshots(first: 100) {\n edges {\n node {\n id\n ...LinkedSnapshotsCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n status\n exclusionJustification\n bestPractice\n}\n\nfragment LinkedAuditsCardFragment on Audit {\n id\n name\n createdAt\n state\n validFrom\n validUntil\n framework {\n id\n name\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 LinkedSnapshotsCardFragment on Snapshot {\n id\n name\n description\n type\n createdAt\n}\n\nfragment LinkedStatesOfApplicabilityCardFragment on StateOfApplicabilityControl {\n id\n stateOfApplicabilityId\n controlId\n stateOfApplicability {\n id\n name\n }\n applicability\n justification\n}\n"
} }
}; };
})(); })();
(node as any).hash = "b28838e3c3c4cdd68906247d129799c8"; (node as any).hash = "755f62f220b1a05bf44dd770974691a9";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<7aaf0b32e40fe8c723a28ab9590b62b5>> * @generated SignedSource<<063d92802621a02aff6b40a9cb2266c2>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -15,10 +15,13 @@ export type FrameworkGraphListQuery$variables = {
}; };
export type FrameworkGraphListQuery$data = { export type FrameworkGraphListQuery$data = {
readonly organization: { readonly organization: {
readonly canCreateFramework?: boolean;
readonly frameworks?: { readonly frameworks?: {
readonly __id: string; readonly __id: string;
readonly edges: ReadonlyArray<{ readonly edges: ReadonlyArray<{
readonly node: { readonly node: {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly id: string; readonly id: string;
readonly " $fragmentSpreads": FragmentRefs<"FrameworksPageCardFragment">; readonly " $fragmentSpreads": FragmentRefs<"FrameworksPageCardFragment">;
}; };
@@ -55,20 +58,59 @@ v2 = {
"storageKey": null "storageKey": null
}, },
v3 = { v3 = {
"alias": "canCreateFramework",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:create\")"
},
v4 = {
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
v5 = {
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
},
v6 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "__typename", "name": "__typename",
"storageKey": null "storageKey": null
}, },
v4 = { v7 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "cursor", "name": "cursor",
"storageKey": null "storageKey": null
}, },
v5 = { v8 = {
"alias": null, "alias": null,
"args": null, "args": null,
"concreteType": "PageInfo", "concreteType": "PageInfo",
@@ -93,7 +135,7 @@ v5 = {
], ],
"storageKey": null "storageKey": null
}, },
v6 = { v9 = {
"kind": "ClientExtension", "kind": "ClientExtension",
"selections": [ "selections": [
{ {
@@ -105,7 +147,7 @@ v6 = {
} }
] ]
}, },
v7 = [ v10 = [
{ {
"kind": "Literal", "kind": "Literal",
"name": "first", "name": "first",
@@ -131,6 +173,7 @@ return {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v3/*: any*/),
{ {
"alias": "frameworks", "alias": "frameworks",
"args": null, "args": null,
@@ -156,21 +199,23 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v4/*: any*/),
(v5/*: any*/),
{ {
"args": null, "args": null,
"kind": "FragmentSpread", "kind": "FragmentSpread",
"name": "FrameworksPageCardFragment" "name": "FrameworksPageCardFragment"
}, },
(v3/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v4/*: any*/) (v7/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v5/*: any*/), (v8/*: any*/),
(v6/*: any*/) (v9/*: any*/)
], ],
"storageKey": null "storageKey": null
} }
@@ -199,14 +244,15 @@ return {
"name": "node", "name": "node",
"plural": false, "plural": false,
"selections": [ "selections": [
(v3/*: any*/), (v6/*: any*/),
(v2/*: any*/), (v2/*: any*/),
{ {
"kind": "InlineFragment", "kind": "InlineFragment",
"selections": [ "selections": [
(v3/*: any*/),
{ {
"alias": null, "alias": null,
"args": (v7/*: any*/), "args": (v10/*: any*/),
"concreteType": "FrameworkConnection", "concreteType": "FrameworkConnection",
"kind": "LinkedField", "kind": "LinkedField",
"name": "frameworks", "name": "frameworks",
@@ -229,6 +275,8 @@ return {
"plural": false, "plural": false,
"selections": [ "selections": [
(v2/*: any*/), (v2/*: any*/),
(v4/*: any*/),
(v5/*: any*/),
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -257,22 +305,22 @@ return {
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
}, },
(v3/*: any*/) (v6/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v4/*: any*/) (v7/*: any*/)
], ],
"storageKey": null "storageKey": null
}, },
(v5/*: any*/), (v8/*: any*/),
(v6/*: any*/) (v9/*: any*/)
], ],
"storageKey": "frameworks(first:100)" "storageKey": "frameworks(first:100)"
}, },
{ {
"alias": null, "alias": null,
"args": (v7/*: any*/), "args": (v10/*: any*/),
"filters": null, "filters": null,
"handle": "connection", "handle": "connection",
"key": "FrameworksListQuery_frameworks", "key": "FrameworksListQuery_frameworks",
@@ -289,7 +337,7 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "90e970007a500be89809ac0f2a77bccd", "cacheID": "2d16147e68885223a69b3597e96d694b",
"id": null, "id": null,
"metadata": { "metadata": {
"connection": [ "connection": [
@@ -306,11 +354,11 @@ return {
}, },
"name": "FrameworkGraphListQuery", "name": "FrameworkGraphListQuery",
"operationKind": "query", "operationKind": "query",
"text": "query FrameworkGraphListQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n frameworks(first: 100) {\n edges {\n node {\n id\n ...FrameworksPageCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n}\n" "text": "query FrameworkGraphListQuery(\n $organizationId: ID!\n) {\n organization: node(id: $organizationId) {\n __typename\n ... on Organization {\n id\n canCreateFramework: permission(action: \"core:framework:create\")\n frameworks(first: 100) {\n edges {\n node {\n id\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n ...FrameworksPageCardFragment\n __typename\n }\n cursor\n }\n pageInfo {\n endCursor\n hasNextPage\n }\n }\n }\n id\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n}\n"
} }
}; };
})(); })();
(node as any).hash = "4aaead183328e669aba942992db6f89c"; (node as any).hash = "f8d3a38faddf4285b8f495f54f3d988e";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<43528dc19e67fdeca407f5081e6252b9>> * @generated SignedSource<<bbc7e1cc0c5c3f72d0297ff14a1dff77>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -137,6 +137,58 @@ return {
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
}, },
{
"alias": "canExport",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:franework:export"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:franework:export\")"
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
},
{
"alias": "canCreateControl",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:control:create"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:control:create\")"
},
{ {
"alias": null, "alias": null,
"args": null, "args": null,
@@ -249,12 +301,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "5af3d5c9f8d466c5d6a78d7bd5da70d1", "cacheID": "2a82ae6447b93b0fa6b570571694052b",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "FrameworkGraphNodeQuery", "name": "FrameworkGraphNodeQuery",
"operationKind": "query", "operationKind": "query",
"text": "query FrameworkGraphNodeQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n ...FrameworkDetailPageFragment\n }\n id\n }\n}\n\nfragment FrameworkDetailPageFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n organization {\n name\n id\n }\n controls(first: 250, orderBy: {field: SECTION_TITLE, direction: ASC}) {\n edges {\n node {\n id\n sectionTitle\n name\n status\n exclusionJustification\n bestPractice\n }\n }\n }\n}\n" "text": "query FrameworkGraphNodeQuery(\n $frameworkId: ID!\n) {\n node(id: $frameworkId) {\n __typename\n ... on Framework {\n id\n name\n ...FrameworkDetailPageFragment\n }\n id\n }\n}\n\nfragment FrameworkDetailPageFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canExport: permission(action: \"core:franework:export\")\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n canCreateControl: permission(action: \"core:control:create\")\n organization {\n name\n id\n }\n controls(first: 250, orderBy: {field: SECTION_TITLE, direction: ASC}) {\n edges {\n node {\n id\n sectionTitle\n name\n status\n exclusionJustification\n bestPractice\n }\n }\n }\n}\n"
} }
}; };
})(); })();

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<412cc494e90709fca575c68f6deef112>> * @generated SignedSource<<d797330ab78ac421e3c64cebdb2ec975>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -11,6 +11,8 @@
import { ReaderFragment } from 'relay-runtime'; import { ReaderFragment } from 'relay-runtime';
import { FragmentRefs } from "relay-runtime"; import { FragmentRefs } from "relay-runtime";
export type FrameworksPageCardFragment$data = { export type FrameworksPageCardFragment$data = {
readonly canDelete: boolean;
readonly canUpdate: boolean;
readonly darkLogoURL: string | null | undefined; readonly darkLogoURL: string | null | undefined;
readonly description: string | null | undefined; readonly description: string | null | undefined;
readonly id: string; readonly id: string;
@@ -63,12 +65,38 @@ const node: ReaderFragment = {
"kind": "ScalarField", "kind": "ScalarField",
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
} }
], ],
"type": "Framework", "type": "Framework",
"abstractKey": null "abstractKey": null
}; };
(node as any).hash = "fe86a14971741a77f587ae015ebf0a22"; (node as any).hash = "dfb64192cedec377c8df8a6d8251e815";
export default node; export default node;

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<2256362d89b6b5c2f5c707acb44d283e>> * @generated SignedSource<<b24323b7c04c927d73fb16ffe3c86532>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -172,6 +172,32 @@ return {
"kind": "ScalarField", "kind": "ScalarField",
"name": "darkLogoURL", "name": "darkLogoURL",
"storageKey": null "storageKey": null
},
{
"alias": "canUpdate",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:update"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:update\")"
},
{
"alias": "canDelete",
"args": [
{
"kind": "Literal",
"name": "action",
"value": "core:framework:delete"
}
],
"kind": "ScalarField",
"name": "permission",
"storageKey": "permission(action:\"core:framework:delete\")"
} }
], ],
"storageKey": null "storageKey": null
@@ -201,12 +227,12 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "5584472f1e68fac3d766662c6d5dab90", "cacheID": "6521d91ba0bd6d9d59567cd2a05d0f35",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "FrameworksPageImportMutation", "name": "FrameworksPageImportMutation",
"operationKind": "mutation", "operationKind": "mutation",
"text": "mutation FrameworksPageImportMutation(\n $input: ImportFrameworkInput!\n) {\n importFramework(input: $input) {\n frameworkEdge {\n node {\n id\n ...FrameworksPageCardFragment\n }\n }\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n}\n" "text": "mutation FrameworksPageImportMutation(\n $input: ImportFrameworkInput!\n) {\n importFramework(input: $input) {\n frameworkEdge {\n node {\n id\n ...FrameworksPageCardFragment\n }\n }\n }\n}\n\nfragment FrameworksPageCardFragment on Framework {\n id\n name\n description\n lightLogoURL\n darkLogoURL\n canUpdate: permission(action: \"core:framework:update\")\n canDelete: permission(action: \"core:framework:delete\")\n}\n"
} }
}; };
})(); })();

View File

@@ -12,12 +12,15 @@ export const frameworksQuery = graphql`
organization: node(id: $organizationId) { organization: node(id: $organizationId) {
... on Organization { ... on Organization {
id id
canCreateFramework: permission(action: "core:framework:create")
frameworks(first: 100) frameworks(first: 100)
@connection(key: "FrameworksListQuery_frameworks") { @connection(key: "FrameworksListQuery_frameworks") {
__id __id
edges { edges {
node { node {
id id
canUpdate: permission(action: "core:framework:update")
canDelete: permission(action: "core:framework:delete")
...FrameworksPageCardFragment ...FrameworksPageCardFragment
} }
} }
@@ -40,7 +43,7 @@ const deleteFrameworkMutation = graphql`
export const useDeleteFrameworkMutation = ( export const useDeleteFrameworkMutation = (
framework: { id: string; name: string }, framework: { id: string; name: string },
connectionId: string connectionId: string,
) => { ) => {
const [commitDelete] = useMutationWithToasts(deleteFrameworkMutation, { const [commitDelete] = useMutationWithToasts(deleteFrameworkMutation, {
errorMessage: "Failed to delete framework", errorMessage: "Failed to delete framework",
@@ -66,14 +69,14 @@ export const useDeleteFrameworkMutation = (
{ {
message: sprintf( message: sprintf(
__( __(
'This will permanently delete framework "%s". This action cannot be undone.' 'This will permanently delete framework "%s". This action cannot be undone.',
), ),
framework.name framework.name,
), ),
} },
); );
}, },
[framework, connectionId, commitDelete, confirm, __] [framework, connectionId, commitDelete, confirm, __],
); );
}; };
@@ -99,6 +102,44 @@ export const frameworkControlNodeQuery = graphql`
description description
status status
exclusionJustification exclusionJustification
canUpdate: permission(action: "core:control:update")
canDelete: permission(action: "core:control:delete")
canCreateMeasureMapping: permission(
action: "core:control:create-measure-mapping"
)
canDeleteMeasureMapping: permission(
action: "core:control:delete-measure-mapping"
)
canCreateDocumentMapping: permission(
action: "core:control:create-document-mapping"
)
canDeleteDocumentMapping: permission(
action: "core:control:delete-document-mapping"
)
canCreateAuditMapping: permission(
action: "core:control:create-audit-mapping"
)
canDeleteAuditMapping: permission(
action: "core:control:delete-audit-mapping"
)
canCreateSnapshotMapping: permission(
action: "core:control:create-snapshot-mapping"
)
canDeleteSnapshotMapping: permission(
action: "core:control:delete-snapshot-mapping"
)
canCreateStateOfApplicabilityMapping: permission(
action: "core:control:state-of-applicability-control-mapping:create"
)
canDeleteStateOfApplicabilityMapping: permission(
action: "core:control:state-of-applicability-control-mapping:delete"
)
canCreateObligationMapping: permission(
action: "core:control:obligation-control-mapping:create"
)
canDeleteObligationMapping: permission(
action: "core:control:obligation-control-mapping:delete"
)
...FrameworkControlDialogFragment ...FrameworkControlDialogFragment
stateOfApplicabilityControls(first: 100) stateOfApplicabilityControls(first: 100)
@connection(key: "FrameworkGraphControl_stateOfApplicabilityControls") { @connection(key: "FrameworkGraphControl_stateOfApplicabilityControls") {
@@ -130,8 +171,7 @@ export const frameworkControlNodeQuery = graphql`
} }
} }
} }
audits(first: 100) audits(first: 100) @connection(key: "FrameworkGraphControl_audits") {
@connection(key: "FrameworkGraphControl_audits") {
__id __id
edges { edges {
node { node {

View File

@@ -29,8 +29,6 @@ import { promisifyMutation } from "@probo/helpers";
import type { FrameworkGraphControlNodeQuery } from "/__generated__/core/FrameworkGraphControlNodeQuery.graphql"; import type { FrameworkGraphControlNodeQuery } from "/__generated__/core/FrameworkGraphControlNodeQuery.graphql";
import { frameworkControlNodeQuery } from "/hooks/graph/FrameworkGraph"; import { frameworkControlNodeQuery } from "/hooks/graph/FrameworkGraph";
import type { FrameworkDetailPageFragment$data } from "/__generated__/core/FrameworkDetailPageFragment.graphql"; import type { FrameworkDetailPageFragment$data } from "/__generated__/core/FrameworkDetailPageFragment.graphql";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
const attachStateOfApplicabilityMutation = graphql` const attachStateOfApplicabilityMutation = graphql`
mutation FrameworkControlPageAttachStateOfApplicabilityMutation( mutation FrameworkControlPageAttachStateOfApplicabilityMutation(
@@ -227,11 +225,6 @@ export default function FrameworkControlPage({ queryRef }: Props) {
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const confirm = useConfirm(); const confirm = useConfirm();
const navigate = useNavigate(); const navigate = useNavigate();
const { isAuthorized } = use(PermissionsContext);
const [detachStateOfApplicability, isDetachingStateOfApplicability] =
useMutation(detachStateOfApplicabilityMutation);
const [attachStateOfApplicability, isAttachingStateOfApplicability] =
useMutation(attachStateOfApplicabilityMutation);
const [detachMeasure, isDetachingMeasure] = useMutation( const [detachMeasure, isDetachingMeasure] = useMutation(
detachMeasureMutation, detachMeasureMutation,
); );
@@ -253,6 +246,11 @@ export default function FrameworkControlPage({ queryRef }: Props) {
attachSnapshotMutation, attachSnapshotMutation,
); );
const [deleteControl] = useMutation(deleteControlMutation); const [deleteControl] = useMutation(deleteControlMutation);
const [attachStateOfApplicability, isAttachingStateOfApplicability] =
useMutation(attachStateOfApplicabilityMutation);
const [detachStateOfApplicability, isDetachingStateOfApplicability] =
useMutation(detachStateOfApplicabilityMutation);
const [attachObligation, isAttachingObligation] = useMutation( const [attachObligation, isAttachingObligation] = useMutation(
attachObligationMutation, attachObligationMutation,
); );
@@ -260,61 +258,33 @@ export default function FrameworkControlPage({ queryRef }: Props) {
detachObligationMutation, detachObligationMutation,
); );
const canLinkStateOfApplicability = isAuthorized( const canLinkStateOfApplicability =
"Control", control.canCreateStateOfApplicabilityMapping;
"createStateOfApplicabilityControlMapping", const canUnlinkStateOfApplicability =
); control.canDeleteStateOfApplicabilityMapping;
const canUnlinkStateOfApplicability = isAuthorized(
"Control",
"deleteStateOfApplicabilityControlMapping",
);
const statesOfApplicabilityReadOnly = const statesOfApplicabilityReadOnly =
!canLinkStateOfApplicability && !canUnlinkStateOfApplicability; !canLinkStateOfApplicability && !canUnlinkStateOfApplicability;
const canLinkMeasure = isAuthorized( const canLinkMeasure = control.canCreateMeasureMapping;
"Control", const canUnlinkMeasure = control.canDeleteMeasureMapping;
"createControlMeasureMapping",
);
const canUnlinkMeasure = isAuthorized(
"Control",
"deleteControlMeasureMapping",
);
const measuresReadOnly = !canLinkMeasure && !canUnlinkMeasure; const measuresReadOnly = !canLinkMeasure && !canUnlinkMeasure;
const canLinkDocument = isAuthorized( const canLinkDocument = control.canCreateDocumentMapping;
"Control", const canUnlinkDocument = control.canDeleteDocumentMapping;
"createControlDocumentMapping",
);
const canUnlinkDocument = isAuthorized(
"Control",
"deleteControlDocumentMapping",
);
const documentsReadOnly = !canLinkDocument && !canUnlinkDocument; const documentsReadOnly = !canLinkDocument && !canUnlinkDocument;
const canLinkAudit = isAuthorized("Control", "createControlAuditMapping"); const canLinkAudit = control.canCreateAuditMapping;
const canUnlinkAudit = isAuthorized("Control", "deleteControlAuditMapping"); const canUnlinkAudit = control.canDeleteAuditMapping;
const auditsReadOnly = !canLinkAudit && !canUnlinkAudit; const auditsReadOnly = !canLinkAudit && !canUnlinkAudit;
const canLinkObligation = isAuthorized( const canLinkSnapshot = control.canCreateSnapshotMapping;
"Control", const canUnlinkSnapshot = control.canDeleteSnapshotMapping;
"createControlObligationMapping",
);
const canUnlinkObligation = isAuthorized(
"Control",
"deleteControlObligationMapping",
);
const obligationsReadOnly = !canLinkObligation && !canUnlinkObligation;
const canLinkSnapshot = isAuthorized(
"Control",
"createControlSnapshotMapping",
);
const canUnlinkSnapshot = isAuthorized(
"Control",
"deleteControlSnapshotMapping",
);
const snapshotsReadOnly = !canLinkSnapshot && !canUnlinkSnapshot; const snapshotsReadOnly = !canLinkSnapshot && !canUnlinkSnapshot;
const canLinkObligation = control.canCreateObligationMapping;
const canUnlinkObligation = control.canDeleteObligationMapping;
const obligationsReadOnly = !canLinkObligation && !canUnlinkObligation;
const withErrorHandling = const withErrorHandling =
<T extends MutationParameters>( <T extends MutationParameters>(
mutationFn: (config: UseMutationConfig<T>) => void, mutationFn: (config: UseMutationConfig<T>) => void,
@@ -382,7 +352,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
</div> </div>
</div> </div>
<div className="flex gap-2"> <div className="flex gap-2">
{isAuthorized("Control", "updateControl") && ( {control.canUpdate && (
<FrameworkControlDialog <FrameworkControlDialog
frameworkId={framework.id} frameworkId={framework.id}
connectionId={connectionId} connectionId={connectionId}
@@ -393,7 +363,7 @@ export default function FrameworkControlPage({ queryRef }: Props) {
</Button> </Button>
</FrameworkControlDialog> </FrameworkControlDialog>
)} )}
{isAuthorized("Control", "deleteControl") && ( {control.canDelete && (
<ActionDropdown variant="secondary"> <ActionDropdown variant="secondary">
<DropdownItem <DropdownItem
icon={IconTrashCan} icon={IconTrashCan}

View File

@@ -31,8 +31,6 @@ import type { FrameworkDetailPageExportFrameworkMutation } from "/__generated__/
import { FrameworkFormDialog } from "./dialogs/FrameworkFormDialog"; import { FrameworkFormDialog } from "./dialogs/FrameworkFormDialog";
import { FrameworkControlDialog } from "./dialogs/FrameworkControlDialog"; import { FrameworkControlDialog } from "./dialogs/FrameworkControlDialog";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
import { use } from "react";
import { PermissionsContext } from "/providers/PermissionsContext";
const frameworkDetailFragment = graphql` const frameworkDetailFragment = graphql`
fragment FrameworkDetailPageFragment on Framework { fragment FrameworkDetailPageFragment on Framework {
@@ -41,6 +39,10 @@ const frameworkDetailFragment = graphql`
description description
lightLogoURL lightLogoURL
darkLogoURL darkLogoURL
canExport: permission(action: "core:franework:export")
canUpdate: permission(action: "core:framework:update")
canDelete: permission(action: "core:framework:delete")
canCreateControl: permission(action: "core:control:create")
organization { organization {
name name
} }
@@ -88,10 +90,15 @@ type Props = {
}; };
export default function FrameworkDetailPage(props: Props) { export default function FrameworkDetailPage(props: Props) {
const { queryRef } = props;
const { __ } = useTranslate(); const { __ } = useTranslate();
const { controlId } = useParams<{ controlId?: string }>(); const { controlId } = useParams<{ controlId?: string }>();
const organizationId = useOrganizationId(); const organizationId = useOrganizationId();
const data = usePreloadedQuery(frameworkNodeQuery, props.queryRef); const data = usePreloadedQuery<FrameworkGraphNodeQuery>(
frameworkNodeQuery,
queryRef,
);
const framework = useFragment<FrameworkDetailPageFragment$key>( const framework = useFragment<FrameworkDetailPageFragment$key>(
frameworkDetailFragment, frameworkDetailFragment,
data.node, data.node,
@@ -106,7 +113,6 @@ export default function FrameworkDetailPage(props: Props) {
framework, framework,
ConnectionHandler.getConnectionID(organizationId, connectionListKey)!, ConnectionHandler.getConnectionID(organizationId, connectionListKey)!,
); );
const { isAuthorized } = use(PermissionsContext);
const [generateFrameworkStateOfApplicability] = const [generateFrameworkStateOfApplicability] =
useMutationWithToasts<FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation>( useMutationWithToasts<FrameworkDetailPageGenerateFrameworkStateOfApplicabilityMutation>(
generateFrameworkStateOfApplicabilityMutation, generateFrameworkStateOfApplicabilityMutation,
@@ -155,7 +161,7 @@ export default function FrameworkDetailPage(props: Props) {
</> </>
} }
> >
{isAuthorized("Framework", "updateFramework") && ( {framework.canUpdate && (
<FrameworkFormDialog <FrameworkFormDialog
organizationId={organizationId} organizationId={organizationId}
framework={framework} framework={framework}
@@ -202,7 +208,7 @@ export default function FrameworkDetailPage(props: Props) {
> >
{__("Export Framework")} {__("Export Framework")}
</DropdownItem> </DropdownItem>
{isAuthorized("Framework", "deleteFramework") && ( {framework.canDelete && (
<DropdownItem <DropdownItem
icon={IconTrashCan} icon={IconTrashCan}
variant="danger" variant="danger"
@@ -231,7 +237,7 @@ export default function FrameworkDetailPage(props: Props) {
active={selectedControl?.id === control.id} active={selectedControl?.id === control.id}
/> />
))} ))}
{isAuthorized("Organization", "createControl") && ( {framework.canCreateControl && (
<FrameworkControlDialog <FrameworkControlDialog
frameworkId={framework.id} frameworkId={framework.id}
connectionId={connectionId} connectionId={connectionId}

View File

@@ -27,9 +27,8 @@ import {
import { Link } from "react-router"; import { Link } from "react-router";
import type { FrameworksPageCardFragment$key } from "/__generated__/core/FrameworksPageCardFragment.graphql"; import type { FrameworksPageCardFragment$key } from "/__generated__/core/FrameworksPageCardFragment.graphql";
import { useMutationWithToasts } from "/hooks/useMutationWithToasts"; import { useMutationWithToasts } from "/hooks/useMutationWithToasts";
import { useState, type ChangeEventHandler, use } from "react"; import { useState, type ChangeEventHandler } from "react";
import { FrameworkFormDialog } from "./dialogs/FrameworkFormDialog"; import { FrameworkFormDialog } from "./dialogs/FrameworkFormDialog";
import { PermissionsContext } from "/providers/PermissionsContext";
type Props = { type Props = {
queryRef: PreloadedQuery<FrameworkGraphListQuery>; queryRef: PreloadedQuery<FrameworkGraphListQuery>;
@@ -53,7 +52,6 @@ const importFrameworkMutation = graphql`
export default function FrameworksPage(props: Props) { export default function FrameworksPage(props: Props) {
const { __ } = useTranslate(); const { __ } = useTranslate();
const { isAuthorized } = use(PermissionsContext);
usePageTitle(__("Frameworks")); usePageTitle(__("Frameworks"));
const data = usePreloadedQuery(frameworksQuery, props.queryRef); const data = usePreloadedQuery(frameworksQuery, props.queryRef);
const connectionId = data.organization.frameworks!.__id; const connectionId = data.organization.frameworks!.__id;
@@ -120,9 +118,9 @@ export default function FrameworksPage(props: Props) {
const isLoading = isUploading || isImporting; const isLoading = isUploading || isImporting;
const hasAnyAction = const hasAnyAction = frameworks.some(
isAuthorized("Framework", "updateFramework") || ({ canUpdate, canDelete }) => canUpdate || canDelete,
isAuthorized("Framework", "deleteFramework"); );
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -135,7 +133,7 @@ export default function FrameworksPage(props: Props) {
title={__("Frameworks")} title={__("Frameworks")}
description={__("Manage your compliance frameworks")} description={__("Manage your compliance frameworks")}
> >
{isAuthorized("Organization", "createFramework") && ( {data.organization.canCreateFramework && (
<> <>
<FileButton <FileButton
variant="secondary" variant="secondary"
@@ -175,6 +173,8 @@ const frameworkCardFragment = graphql`
description description
lightLogoURL lightLogoURL
darkLogoURL darkLogoURL
canUpdate: permission(action: "core:framework:update")
canDelete: permission(action: "core:framework:delete")
} }
`; `;
@@ -187,7 +187,6 @@ type FrameworkCardProps = {
function FrameworkCard(props: FrameworkCardProps) { function FrameworkCard(props: FrameworkCardProps) {
const framework = useFragment(frameworkCardFragment, props.framework); const framework = useFragment(frameworkCardFragment, props.framework);
const { isAuthorized } = use(PermissionsContext);
const deleteFramework = useDeleteFrameworkMutation( const deleteFramework = useDeleteFrameworkMutation(
framework, framework,
props.connectionId, props.connectionId,
@@ -210,7 +209,7 @@ function FrameworkCard(props: FrameworkCardProps) {
/> />
{props.hasAnyAction && ( {props.hasAnyAction && (
<ActionDropdown className="z-10 relative"> <ActionDropdown className="z-10 relative">
{isAuthorized("Framework", "updateFramework") && ( {framework.canUpdate && (
<DropdownItem <DropdownItem
icon={IconPencil} icon={IconPencil}
onClick={() => { onClick={() => {
@@ -220,7 +219,7 @@ function FrameworkCard(props: FrameworkCardProps) {
{__("Edit")} {__("Edit")}
</DropdownItem> </DropdownItem>
)} )}
{isAuthorized("Framework", "deleteFramework") && ( {framework.canDelete && (
<DropdownItem <DropdownItem
icon={IconTrashCan} icon={IconTrashCan}
onClick={() => deleteFramework()} onClick={() => deleteFramework()}