diff --git a/apps/console/src/components/skeletons/ControlSkeleton.tsx b/apps/console/src/components/skeletons/ControlSkeleton.tsx
new file mode 100644
index 000000000..9da502f31
--- /dev/null
+++ b/apps/console/src/components/skeletons/ControlSkeleton.tsx
@@ -0,0 +1,26 @@
+import { ActionDropdown, Skeleton } from "@probo/ui";
+import { Button, IconPencil } from "@probo/ui";
+import { useTranslate } from "@probo/i18n";
+
+/**
+ * Skeleton state for the framework control panel
+ */
+export function ControlSkeleton() {
+ const { __ } = useTranslate();
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/apps/console/src/components/skeletons/LinkCardSkeleton.tsx b/apps/console/src/components/skeletons/LinkCardSkeleton.tsx
new file mode 100644
index 000000000..534d56963
--- /dev/null
+++ b/apps/console/src/components/skeletons/LinkCardSkeleton.tsx
@@ -0,0 +1,5 @@
+import { Skeleton } from "@probo/ui";
+
+export function LinkCardSkeleton() {
+ return ;
+}
diff --git a/apps/console/src/hooks/graph/FrameworkGraph.ts b/apps/console/src/hooks/graph/FrameworkGraph.ts
index e525b30bf..9db2e0b7a 100644
--- a/apps/console/src/hooks/graph/FrameworkGraph.ts
+++ b/apps/console/src/hooks/graph/FrameworkGraph.ts
@@ -88,3 +88,37 @@ export const frameworkNodeQuery = graphql`
}
}
`;
+
+export const frameworkControlNodeQuery = graphql`
+ query FrameworkGraphControlNodeQuery($controlId: ID!) {
+ node(id: $controlId) {
+ ... on Control {
+ id
+ name
+ sectionTitle
+ description
+ ...FrameworkControlDialogFragment
+ measures(first: 100)
+ @connection(key: "FrameworkGraphControl_measures") {
+ __id
+ edges {
+ node {
+ id
+ ...LinkedMeasuresCardFragment
+ }
+ }
+ }
+ documents(first: 100)
+ @connection(key: "FrameworkGraphControl_documents") {
+ __id
+ edges {
+ node {
+ id
+ ...LinkedDocumentsCardFragment
+ }
+ }
+ }
+ }
+ }
+ }
+`;
diff --git a/apps/console/src/hooks/graph/__generated__/FrameworkGraphControlNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/FrameworkGraphControlNodeQuery.graphql.ts
new file mode 100644
index 000000000..6f61473a9
--- /dev/null
+++ b/apps/console/src/hooks/graph/__generated__/FrameworkGraphControlNodeQuery.graphql.ts
@@ -0,0 +1,508 @@
+/**
+ * @generated SignedSource<<9972eafa19f49d7beea0458c5b9c06d9>>
+ * @lightSyntaxTransform
+ * @nogrep
+ */
+
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest } from 'relay-runtime';
+import { FragmentRefs } from "relay-runtime";
+export type FrameworkGraphControlNodeQuery$variables = {
+ controlId: string;
+};
+export type FrameworkGraphControlNodeQuery$data = {
+ readonly node: {
+ readonly description?: string;
+ readonly documents?: {
+ readonly __id: string;
+ readonly edges: ReadonlyArray<{
+ readonly node: {
+ readonly id: string;
+ readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsCardFragment">;
+ };
+ }>;
+ };
+ readonly id?: string;
+ readonly measures?: {
+ readonly __id: string;
+ readonly edges: ReadonlyArray<{
+ readonly node: {
+ readonly id: string;
+ readonly " $fragmentSpreads": FragmentRefs<"LinkedMeasuresCardFragment">;
+ };
+ }>;
+ };
+ readonly name?: string;
+ readonly sectionTitle?: string;
+ readonly " $fragmentSpreads": FragmentRefs<"FrameworkControlDialogFragment">;
+ };
+};
+export type FrameworkGraphControlNodeQuery = {
+ response: FrameworkGraphControlNodeQuery$data;
+ variables: FrameworkGraphControlNodeQuery$variables;
+};
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "defaultValue": null,
+ "kind": "LocalArgument",
+ "name": "controlId"
+ }
+],
+v1 = [
+ {
+ "kind": "Variable",
+ "name": "id",
+ "variableName": "controlId"
+ }
+],
+v2 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+},
+v3 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "name",
+ "storageKey": null
+},
+v4 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "sectionTitle",
+ "storageKey": null
+},
+v5 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "description",
+ "storageKey": null
+},
+v6 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__typename",
+ "storageKey": null
+},
+v7 = {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "cursor",
+ "storageKey": null
+},
+v8 = {
+ "alias": null,
+ "args": null,
+ "concreteType": "PageInfo",
+ "kind": "LinkedField",
+ "name": "pageInfo",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "endCursor",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "hasNextPage",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+},
+v9 = {
+ "kind": "ClientExtension",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__id",
+ "storageKey": null
+ }
+ ]
+},
+v10 = [
+ {
+ "kind": "Literal",
+ "name": "first",
+ "value": 100
+ }
+];
+return {
+ "fragment": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "FrameworkGraphControlNodeQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": null,
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ {
+ "kind": "InlineFragment",
+ "selections": [
+ (v2/*: any*/),
+ (v3/*: any*/),
+ (v4/*: any*/),
+ (v5/*: any*/),
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "FrameworkControlDialogFragment"
+ },
+ {
+ "alias": "measures",
+ "args": null,
+ "concreteType": "MeasureConnection",
+ "kind": "LinkedField",
+ "name": "__FrameworkGraphControl_measures_connection",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "MeasureEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "Measure",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "LinkedMeasuresCardFragment"
+ },
+ (v6/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v7/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v8/*: any*/),
+ (v9/*: any*/)
+ ],
+ "storageKey": null
+ },
+ {
+ "alias": "documents",
+ "args": null,
+ "concreteType": "DocumentConnection",
+ "kind": "LinkedField",
+ "name": "__FrameworkGraphControl_documents_connection",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DocumentEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "Document",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "args": null,
+ "kind": "FragmentSpread",
+ "name": "LinkedDocumentsCardFragment"
+ },
+ (v6/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v7/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v8/*: any*/),
+ (v9/*: any*/)
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Control",
+ "abstractKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": (v0/*: any*/),
+ "kind": "Operation",
+ "name": "FrameworkGraphControlNodeQuery",
+ "selections": [
+ {
+ "alias": null,
+ "args": (v1/*: any*/),
+ "concreteType": null,
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v6/*: any*/),
+ (v2/*: any*/),
+ {
+ "kind": "InlineFragment",
+ "selections": [
+ (v3/*: any*/),
+ (v4/*: any*/),
+ (v5/*: any*/),
+ {
+ "alias": null,
+ "args": (v10/*: any*/),
+ "concreteType": "MeasureConnection",
+ "kind": "LinkedField",
+ "name": "measures",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "MeasureEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "Measure",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ (v3/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "state",
+ "storageKey": null
+ },
+ (v6/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v7/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v8/*: any*/),
+ (v9/*: any*/)
+ ],
+ "storageKey": "measures(first:100)"
+ },
+ {
+ "alias": null,
+ "args": (v10/*: any*/),
+ "filters": null,
+ "handle": "connection",
+ "key": "FrameworkGraphControl_measures",
+ "kind": "LinkedHandle",
+ "name": "measures"
+ },
+ {
+ "alias": null,
+ "args": (v10/*: any*/),
+ "concreteType": "DocumentConnection",
+ "kind": "LinkedField",
+ "name": "documents",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DocumentEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "Document",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "title",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "documentType",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "first",
+ "value": 1
+ }
+ ],
+ "concreteType": "DocumentVersionConnection",
+ "kind": "LinkedField",
+ "name": "versions",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DocumentVersionEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "DocumentVersion",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ (v2/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "status",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": "versions(first:1)"
+ },
+ (v6/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v7/*: any*/)
+ ],
+ "storageKey": null
+ },
+ (v8/*: any*/),
+ (v9/*: any*/)
+ ],
+ "storageKey": "documents(first:100)"
+ },
+ {
+ "alias": null,
+ "args": (v10/*: any*/),
+ "filters": null,
+ "handle": "connection",
+ "key": "FrameworkGraphControl_documents",
+ "kind": "LinkedHandle",
+ "name": "documents"
+ }
+ ],
+ "type": "Control",
+ "abstractKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ]
+ },
+ "params": {
+ "cacheID": "165ee5f4a3579e54fb7acafd6fd7ab12",
+ "id": null,
+ "metadata": {
+ "connection": [
+ {
+ "count": null,
+ "cursor": null,
+ "direction": "forward",
+ "path": [
+ "node",
+ "measures"
+ ]
+ },
+ {
+ "count": null,
+ "cursor": null,
+ "direction": "forward",
+ "path": [
+ "node",
+ "documents"
+ ]
+ }
+ ]
+ },
+ "name": "FrameworkGraphControlNodeQuery",
+ "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 ...FrameworkControlDialogFragment\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 }\n id\n }\n}\n\nfragment FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\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"
+ }
+};
+})();
+
+(node as any).hash = "a2b0b5449af380ea2843aab6ce187b75";
+
+export default node;
diff --git a/apps/console/src/hooks/graph/__generated__/FrameworkGraphNodeQuery.graphql.ts b/apps/console/src/hooks/graph/__generated__/FrameworkGraphNodeQuery.graphql.ts
index 270b85819..fe82746f4 100644
--- a/apps/console/src/hooks/graph/__generated__/FrameworkGraphNodeQuery.graphql.ts
+++ b/apps/console/src/hooks/graph/__generated__/FrameworkGraphNodeQuery.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<5cb97bc6e333575149d6cc4418370d45>>
+ * @generated SignedSource<<5627e402cef1ec879c133d54980b26ab>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -53,71 +53,6 @@ v3 = {
"kind": "ScalarField",
"name": "name",
"storageKey": null
-},
-v4 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "__typename",
- "storageKey": null
-},
-v5 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "description",
- "storageKey": null
-},
-v6 = [
- {
- "kind": "Literal",
- "name": "first",
- "value": 100
- }
-],
-v7 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "cursor",
- "storageKey": null
-},
-v8 = {
- "alias": null,
- "args": null,
- "concreteType": "PageInfo",
- "kind": "LinkedField",
- "name": "pageInfo",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "endCursor",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "hasNextPage",
- "storageKey": null
- }
- ],
- "storageKey": null
-},
-v9 = {
- "kind": "ClientExtension",
- "selections": [
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "__id",
- "storageKey": null
- }
- ]
};
return {
"fragment": {
@@ -169,16 +104,34 @@ return {
"name": "node",
"plural": false,
"selections": [
- (v4/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__typename",
+ "storageKey": null
+ },
(v2/*: any*/),
{
"kind": "InlineFragment",
"selections": [
(v3/*: any*/),
- (v5/*: any*/),
{
"alias": null,
- "args": (v6/*: any*/),
+ "args": null,
+ "kind": "ScalarField",
+ "name": "description",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": [
+ {
+ "kind": "Literal",
+ "name": "first",
+ "value": 100
+ }
+ ],
"concreteType": "ControlConnection",
"kind": "LinkedField",
"name": "controls",
@@ -208,185 +161,25 @@ return {
"name": "sectionTitle",
"storageKey": null
},
- (v3/*: any*/),
- (v5/*: any*/),
- {
- "alias": null,
- "args": (v6/*: any*/),
- "concreteType": "MeasureConnection",
- "kind": "LinkedField",
- "name": "measures",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "MeasureEdge",
- "kind": "LinkedField",
- "name": "edges",
- "plural": true,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "Measure",
- "kind": "LinkedField",
- "name": "node",
- "plural": false,
- "selections": [
- (v2/*: any*/),
- (v3/*: any*/),
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "state",
- "storageKey": null
- },
- (v4/*: any*/)
- ],
- "storageKey": null
- },
- (v7/*: any*/)
- ],
- "storageKey": null
- },
- (v8/*: any*/),
- (v9/*: any*/)
- ],
- "storageKey": "measures(first:100)"
- },
- {
- "alias": null,
- "args": (v6/*: any*/),
- "filters": null,
- "handle": "connection",
- "key": "FrameworkDetailPage_measures",
- "kind": "LinkedHandle",
- "name": "measures"
- },
- {
- "alias": null,
- "args": (v6/*: any*/),
- "concreteType": "DocumentConnection",
- "kind": "LinkedField",
- "name": "documents",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "DocumentEdge",
- "kind": "LinkedField",
- "name": "edges",
- "plural": true,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "Document",
- "kind": "LinkedField",
- "name": "node",
- "plural": false,
- "selections": [
- (v2/*: any*/),
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "title",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "createdAt",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "documentType",
- "storageKey": null
- },
- {
- "alias": null,
- "args": [
- {
- "kind": "Literal",
- "name": "first",
- "value": 1
- }
- ],
- "concreteType": "DocumentVersionConnection",
- "kind": "LinkedField",
- "name": "versions",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "DocumentVersionEdge",
- "kind": "LinkedField",
- "name": "edges",
- "plural": true,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "DocumentVersion",
- "kind": "LinkedField",
- "name": "node",
- "plural": false,
- "selections": [
- (v2/*: any*/),
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "status",
- "storageKey": null
- }
- ],
- "storageKey": null
- }
- ],
- "storageKey": null
- }
- ],
- "storageKey": "versions(first:1)"
- },
- (v4/*: any*/)
- ],
- "storageKey": null
- },
- (v7/*: any*/)
- ],
- "storageKey": null
- },
- (v8/*: any*/),
- (v9/*: any*/)
- ],
- "storageKey": "documents(first:100)"
- },
- {
- "alias": null,
- "args": (v6/*: any*/),
- "filters": null,
- "handle": "connection",
- "key": "FrameworkDetailPage_documents",
- "kind": "LinkedHandle",
- "name": "documents"
- }
+ (v3/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
},
- (v9/*: any*/)
+ {
+ "kind": "ClientExtension",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__id",
+ "storageKey": null
+ }
+ ]
+ }
],
"storageKey": "controls(first:100)"
}
@@ -400,12 +193,12 @@ return {
]
},
"params": {
- "cacheID": "4b21f0ec7a74eed125d96e4cfc7f94fd",
+ "cacheID": "28ea34e7b455cffd5283428ef567963a",
"id": null,
"metadata": {},
"name": "FrameworkGraphNodeQuery",
"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 FrameworkControlDialogFragment on Control {\n id\n name\n description\n sectionTitle\n}\n\nfragment FrameworkDetailPageFragment on Framework {\n id\n name\n description\n controls(first: 100) {\n edges {\n node {\n id\n sectionTitle\n name\n description\n ...FrameworkControlDialogFragment\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 }\n }\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"
+ "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 controls(first: 100) {\n edges {\n node {\n id\n sectionTitle\n name\n }\n }\n }\n}\n"
}
};
})();
diff --git a/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx b/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx
new file mode 100644
index 000000000..87fe169f8
--- /dev/null
+++ b/apps/console/src/pages/organizations/frameworks/FrameworkControlPage.tsx
@@ -0,0 +1,195 @@
+import {
+ useMutation,
+ usePreloadedQuery,
+ type PreloadedQuery,
+} from "react-relay";
+import { graphql } from "relay-runtime";
+import {
+ ActionDropdown,
+ Button,
+ DropdownItem,
+ IconPencil,
+ IconTrashCan,
+ useConfirm,
+} from "@probo/ui";
+import { useTranslate } from "@probo/i18n";
+import { LinkedMeasuresCard } from "/components/measures/LinkedMeasuresCard";
+import { useNavigate, useOutletContext } from "react-router";
+import { useOrganizationId } from "/hooks/useOrganizationId";
+import { LinkedDocumentsCard } from "/components/documents/LinkedDocumentsCard";
+import { FrameworkControlDialog } from "./dialogs/FrameworkControlDialog";
+import { promisifyMutation } from "@probo/helpers";
+import type { FrameworkGraphControlNodeQuery } from "/hooks/graph/__generated__/FrameworkGraphControlNodeQuery.graphql";
+import { frameworkControlNodeQuery } from "/hooks/graph/FrameworkGraph";
+import type { FrameworkDetailPageFragment$data } from "./__generated__/FrameworkDetailPageFragment.graphql";
+
+const attachMeasureMutation = graphql`
+ mutation FrameworkControlPageAttachMutation(
+ $input: CreateControlMeasureMappingInput!
+ $connections: [ID!]!
+ ) {
+ createControlMeasureMapping(input: $input) {
+ measureEdge @prependEdge(connections: $connections) {
+ node {
+ id
+ ...LinkedMeasuresCardFragment
+ }
+ }
+ }
+ }
+`;
+
+const detachMeasureMutation = graphql`
+ mutation FrameworkControlPageDetachMutation(
+ $input: DeleteControlMeasureMappingInput!
+ $connections: [ID!]!
+ ) {
+ deleteControlMeasureMapping(input: $input) {
+ deletedMeasureId @deleteEdge(connections: $connections)
+ }
+ }
+`;
+
+const attachDocumentMutation = graphql`
+ mutation FrameworkControlPageAttachDocumentMutation(
+ $input: CreateControlDocumentMappingInput!
+ $connections: [ID!]!
+ ) {
+ createControlDocumentMapping(input: $input) {
+ documentEdge @prependEdge(connections: $connections) {
+ node {
+ id
+ ...LinkedDocumentsCardFragment
+ }
+ }
+ }
+ }
+`;
+
+const detachDocumentMutation = graphql`
+ mutation FrameworkControlPageDetachDocumentMutation(
+ $input: DeleteControlDocumentMappingInput!
+ $connections: [ID!]!
+ ) {
+ deleteControlDocumentMapping(input: $input) {
+ deletedDocumentId @deleteEdge(connections: $connections)
+ }
+ }
+`;
+
+const deleteControlMutation = graphql`
+ mutation FrameworkControlPageDeleteControlMutation(
+ $input: DeleteControlInput!
+ $connections: [ID!]!
+ ) {
+ deleteControl(input: $input) {
+ deletedControlId @deleteEdge(connections: $connections)
+ }
+ }
+`;
+
+type Props = {
+ queryRef: PreloadedQuery;
+};
+
+/**
+ * Display the control detail on the right panel
+ */
+export default function FrameworkControlPage({ queryRef }: Props) {
+ const { __ } = useTranslate();
+ const { framework } = useOutletContext<{
+ framework: FrameworkDetailPageFragment$data;
+ }>();
+ const connectionId = framework.controls.__id;
+ const control = usePreloadedQuery(frameworkControlNodeQuery, queryRef).node;
+ const organizationId = useOrganizationId();
+ const confirm = useConfirm();
+ const navigate = useNavigate();
+ // Mutations
+ const [detachMeasure, isDetachingMeasure] = useMutation(
+ detachMeasureMutation
+ );
+ const [attachMeasure, isAttachingMeasure] = useMutation(
+ attachMeasureMutation
+ );
+ const [detachDocument, isDetachingDocument] = useMutation(
+ detachDocumentMutation
+ );
+ const [attachDocument, isAttachingDocument] = useMutation(
+ attachDocumentMutation
+ );
+ const [deleteControl] = useMutation(deleteControlMutation);
+
+ const onDelete = () => {
+ confirm(
+ () => {
+ return promisifyMutation(deleteControl)({
+ variables: {
+ input: {
+ controlId: control.id,
+ },
+ connections: [connectionId],
+ },
+ onCompleted: () => {
+ navigate(
+ `/organizations/${organizationId}/frameworks/${framework.id}`
+ );
+ },
+ });
+ },
+ {
+ message: __("Are you sure you want to delete this control?"),
+ }
+ );
+ };
+
+ return (
+
+
+
+ {control.sectionTitle}
+
+
+
+
+
+
+
+ {__("Delete")}
+
+
+
+
+
+
{control.name}
+
edge.node) ?? []}
+ params={{ controlId: control.id }}
+ connectionId={control.measures?.__id!}
+ onAttach={attachMeasure}
+ onDetach={detachMeasure}
+ disabled={isAttachingMeasure || isDetachingMeasure}
+ />
+ edge.node) ?? []}
+ params={{ controlId: control.id }}
+ connectionId={control.documents?.__id!}
+ onAttach={attachDocument}
+ onDetach={detachDocument}
+ disabled={isAttachingDocument || isDetachingDocument}
+ />
+
+ );
+}
diff --git a/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx b/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx
index 67a4511bf..582bb17ed 100644
--- a/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx
+++ b/apps/console/src/pages/organizations/frameworks/FrameworkDetailPage.tsx
@@ -1,6 +1,5 @@
import {
useFragment,
- useMutation,
usePreloadedQuery,
type PreloadedQuery,
} from "react-relay";
@@ -15,7 +14,6 @@ import {
IconPlusLarge,
IconTrashCan,
PageHeader,
- useConfirm,
} from "@probo/ui";
import { FrameworkLogo } from "/components/FrameworkLogo";
import {
@@ -24,20 +22,12 @@ import {
useDeleteFrameworkMutation,
} from "/hooks/graph/FrameworkGraph";
import { useTranslate } from "@probo/i18n";
-import { LinkedMeasuresCard } from "/components/measures/LinkedMeasuresCard";
-import { useNavigate, useParams } from "react-router";
+import { Navigate, Outlet, useNavigate, useParams } from "react-router";
import { useOrganizationId } from "/hooks/useOrganizationId";
import type { FrameworkGraphNodeQuery } from "/hooks/graph/__generated__/FrameworkGraphNodeQuery.graphql";
-import type {
- FrameworkDetailPageFragment$data,
- FrameworkDetailPageFragment$key,
-} from "./__generated__/FrameworkDetailPageFragment.graphql";
-import { LinkedDocumentsCard } from "/components/documents/LinkedDocumentsCard";
+import type { FrameworkDetailPageFragment$key } from "./__generated__/FrameworkDetailPageFragment.graphql";
import { FrameworkFormDialog } from "./dialogs/FrameworkFormDialog";
import { FrameworkControlDialog } from "./dialogs/FrameworkControlDialog";
-import type { FrameworkControlDialogFragment$key } from "./dialogs/__generated__/FrameworkControlDialogFragment.graphql";
-import type { NodeOf } from "/types";
-import { promisifyMutation } from "@probo/helpers";
const frameworkDetailFragment = graphql`
fragment FrameworkDetailPageFragment on Framework {
@@ -51,88 +41,12 @@ const frameworkDetailFragment = graphql`
id
sectionTitle
name
- description
- ...FrameworkControlDialogFragment
- measures(first: 100)
- @connection(key: "FrameworkDetailPage_measures") {
- __id
- edges {
- node {
- id
- ...LinkedMeasuresCardFragment
- }
- }
- }
- documents(first: 100)
- @connection(key: "FrameworkDetailPage_documents") {
- __id
- edges {
- node {
- id
- ...LinkedDocumentsCardFragment
- }
- }
- }
}
}
}
}
`;
-const attachMeasureMutation = graphql`
- mutation FrameworkDetailPageAttachMutation(
- $input: CreateControlMeasureMappingInput!
- $connections: [ID!]!
- ) {
- createControlMeasureMapping(input: $input) {
- measureEdge @prependEdge(connections: $connections) {
- node {
- id
- ...LinkedMeasuresCardFragment
- }
- }
- }
- }
-`;
-
-const detachMeasureMutation = graphql`
- mutation FrameworkDetailPageDetachMutation(
- $input: DeleteControlMeasureMappingInput!
- $connections: [ID!]!
- ) {
- deleteControlMeasureMapping(input: $input) {
- deletedMeasureId @deleteEdge(connections: $connections)
- }
- }
-`;
-
-const attachDocumentMutation = graphql`
- mutation FrameworkDetailPageAttachDocumentMutation(
- $input: CreateControlDocumentMappingInput!
- $connections: [ID!]!
- ) {
- createControlDocumentMapping(input: $input) {
- documentEdge @prependEdge(connections: $connections) {
- node {
- id
- ...LinkedDocumentsCardFragment
- }
- }
- }
- }
-`;
-
-const detachDocumentMutation = graphql`
- mutation FrameworkDetailPageDetachDocumentMutation(
- $input: DeleteControlDocumentMappingInput!
- $connections: [ID!]!
- ) {
- deleteControlDocumentMapping(input: $input) {
- deletedDocumentId @deleteEdge(connections: $connections)
- }
- }
-`;
-
type Props = {
queryRef: PreloadedQuery;
};
@@ -166,6 +80,14 @@ export default function FrameworkDetailPage(props: Props) {
});
};
+ if (!controlId) {
+ return (
+
+ );
+ }
+
return (
@@ -217,137 +139,8 @@ export default function FrameworkDetailPage(props: Props) {
- {selectedControl ? (
-
- ) : (
-
-
- {__("No control selected")}
-
-
- )}
+
);
}
-
-const deleteControlMutation = graphql`
- mutation FrameworkDetailPageDeleteControlMutation(
- $input: DeleteControlInput!
- $connections: [ID!]!
- ) {
- deleteControl(input: $input) {
- deletedControlId @deleteEdge(connections: $connections)
- }
- }
-`;
-
-/**
- * Right side pannel (showing the content of the selected control)
- */
-function ControlContent({
- control,
- frameworkId,
- connectionId,
-}: {
- control: NodeOf &
- FrameworkControlDialogFragment$key;
- frameworkId: string;
- connectionId: string;
-}) {
- const { __ } = useTranslate();
- const organizationId = useOrganizationId();
- const confirm = useConfirm();
- const navigate = useNavigate();
- // Mutations
- const [detachMeasure, isDetachingMeasure] = useMutation(
- detachMeasureMutation
- );
- const [attachMeasure, isAttachingMeasure] = useMutation(
- attachMeasureMutation
- );
- const [detachDocument, isDetachingDocument] = useMutation(
- detachDocumentMutation
- );
- const [attachDocument, isAttachingDocument] = useMutation(
- attachDocumentMutation
- );
- const [deleteControl] = useMutation(deleteControlMutation);
-
- const onDelete = () => {
- confirm(
- () => {
- return promisifyMutation(deleteControl)({
- variables: {
- input: {
- controlId: control.id,
- },
- connections: [connectionId],
- },
- onCompleted: () => {
- navigate(
- `/organizations/${organizationId}/frameworks/${frameworkId}`
- );
- },
- });
- },
- {
- message: __("Are you sure you want to delete this control?"),
- }
- );
- };
-
- return (
-
-
-
- {control.sectionTitle}
-
-
-
-
-
-
-
- {__("Delete")}
-
-
-
-
-
-
{control.name}
-
edge.node) ?? []}
- params={{ controlId: control.id }}
- connectionId={control.measures.__id!}
- onAttach={attachMeasure}
- onDetach={detachMeasure}
- disabled={isAttachingMeasure || isDetachingMeasure}
- />
- edge.node) ?? []}
- params={{ controlId: control.id }}
- connectionId={control.documents.__id!}
- onAttach={attachDocument}
- onDetach={detachDocument}
- disabled={isAttachingDocument || isDetachingDocument}
- />
-
- );
-}
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachDocumentMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachDocumentMutation.graphql.ts
similarity index 85%
rename from apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachDocumentMutation.graphql.ts
rename to apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachDocumentMutation.graphql.ts
index 6f99a2bd2..8fad6cfbe 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachDocumentMutation.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachDocumentMutation.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<7d4a807c299030c97164951cbe8ef067>>
+ * @generated SignedSource<<47d493f6b225797004c11ba908c1e7d2>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,11 +14,11 @@ export type CreateControlDocumentMappingInput = {
controlId: string;
documentId: string;
};
-export type FrameworkDetailPageAttachDocumentMutation$variables = {
+export type FrameworkControlPageAttachDocumentMutation$variables = {
connections: ReadonlyArray;
input: CreateControlDocumentMappingInput;
};
-export type FrameworkDetailPageAttachDocumentMutation$data = {
+export type FrameworkControlPageAttachDocumentMutation$data = {
readonly createControlDocumentMapping: {
readonly documentEdge: {
readonly node: {
@@ -28,9 +28,9 @@ export type FrameworkDetailPageAttachDocumentMutation$data = {
};
};
};
-export type FrameworkDetailPageAttachDocumentMutation = {
- response: FrameworkDetailPageAttachDocumentMutation$data;
- variables: FrameworkDetailPageAttachDocumentMutation$variables;
+export type FrameworkControlPageAttachDocumentMutation = {
+ response: FrameworkControlPageAttachDocumentMutation$data;
+ variables: FrameworkControlPageAttachDocumentMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -66,7 +66,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
- "name": "FrameworkDetailPageAttachDocumentMutation",
+ "name": "FrameworkControlPageAttachDocumentMutation",
"selections": [
{
"alias": null,
@@ -118,7 +118,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
- "name": "FrameworkDetailPageAttachDocumentMutation",
+ "name": "FrameworkControlPageAttachDocumentMutation",
"selections": [
{
"alias": null,
@@ -241,16 +241,16 @@ return {
]
},
"params": {
- "cacheID": "968bd0beeabab861ca610804640e5e11",
+ "cacheID": "857c472a56bba83b8249bb6f3b97eea2",
"id": null,
"metadata": {},
- "name": "FrameworkDetailPageAttachDocumentMutation",
+ "name": "FrameworkControlPageAttachDocumentMutation",
"operationKind": "mutation",
- "text": "mutation FrameworkDetailPageAttachDocumentMutation(\n $input: CreateControlDocumentMappingInput!\n) {\n createControlDocumentMapping(input: $input) {\n documentEdge {\n node {\n id\n ...LinkedDocumentsCardFragment\n }\n }\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"
+ "text": "mutation FrameworkControlPageAttachDocumentMutation(\n $input: CreateControlDocumentMappingInput!\n) {\n createControlDocumentMapping(input: $input) {\n documentEdge {\n node {\n id\n ...LinkedDocumentsCardFragment\n }\n }\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"
}
};
})();
-(node as any).hash = "26c53db439feba2b2d65c3e3a9a973c7";
+(node as any).hash = "6f019fa6bdfccc4cddd80f0de770440f";
export default node;
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachMutation.graphql.ts
similarity index 82%
rename from apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachMutation.graphql.ts
rename to apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachMutation.graphql.ts
index eedb63fd4..c11a2064a 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageAttachMutation.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageAttachMutation.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<81d008fc4116a78a92e2d925f8d6daa7>>
+ * @generated SignedSource<<1d23c8e1a8e16a9811d75d208ade0889>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -14,11 +14,11 @@ export type CreateControlMeasureMappingInput = {
controlId: string;
measureId: string;
};
-export type FrameworkDetailPageAttachMutation$variables = {
+export type FrameworkControlPageAttachMutation$variables = {
connections: ReadonlyArray;
input: CreateControlMeasureMappingInput;
};
-export type FrameworkDetailPageAttachMutation$data = {
+export type FrameworkControlPageAttachMutation$data = {
readonly createControlMeasureMapping: {
readonly measureEdge: {
readonly node: {
@@ -28,9 +28,9 @@ export type FrameworkDetailPageAttachMutation$data = {
};
};
};
-export type FrameworkDetailPageAttachMutation = {
- response: FrameworkDetailPageAttachMutation$data;
- variables: FrameworkDetailPageAttachMutation$variables;
+export type FrameworkControlPageAttachMutation = {
+ response: FrameworkControlPageAttachMutation$data;
+ variables: FrameworkControlPageAttachMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -66,7 +66,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
- "name": "FrameworkDetailPageAttachMutation",
+ "name": "FrameworkControlPageAttachMutation",
"selections": [
{
"alias": null,
@@ -118,7 +118,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
- "name": "FrameworkDetailPageAttachMutation",
+ "name": "FrameworkControlPageAttachMutation",
"selections": [
{
"alias": null,
@@ -187,16 +187,16 @@ return {
]
},
"params": {
- "cacheID": "9fcb599cd78f3108d6d71aa571d7005d",
+ "cacheID": "85f870b18745fcd28bac3a52c404e98f",
"id": null,
"metadata": {},
- "name": "FrameworkDetailPageAttachMutation",
+ "name": "FrameworkControlPageAttachMutation",
"operationKind": "mutation",
- "text": "mutation FrameworkDetailPageAttachMutation(\n $input: CreateControlMeasureMappingInput!\n) {\n createControlMeasureMapping(input: $input) {\n measureEdge {\n node {\n id\n ...LinkedMeasuresCardFragment\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n"
+ "text": "mutation FrameworkControlPageAttachMutation(\n $input: CreateControlMeasureMappingInput!\n) {\n createControlMeasureMapping(input: $input) {\n measureEdge {\n node {\n id\n ...LinkedMeasuresCardFragment\n }\n }\n }\n}\n\nfragment LinkedMeasuresCardFragment on Measure {\n id\n name\n state\n}\n"
}
};
})();
-(node as any).hash = "d3834b8c2656d347e13189469894be61";
+(node as any).hash = "e52f26e6906aa014ad020bd6f23a75d6";
export default node;
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDeleteControlMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDeleteControlMutation.graphql.ts
similarity index 73%
rename from apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDeleteControlMutation.graphql.ts
rename to apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDeleteControlMutation.graphql.ts
index 5166e9377..c549c68c1 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDeleteControlMutation.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDeleteControlMutation.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<>
+ * @generated SignedSource<<87a74ac3a3c2523bd65512703dc2246e>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -12,18 +12,18 @@ import { ConcreteRequest } from 'relay-runtime';
export type DeleteControlInput = {
controlId: string;
};
-export type FrameworkDetailPageDeleteControlMutation$variables = {
+export type FrameworkControlPageDeleteControlMutation$variables = {
connections: ReadonlyArray;
input: DeleteControlInput;
};
-export type FrameworkDetailPageDeleteControlMutation$data = {
+export type FrameworkControlPageDeleteControlMutation$data = {
readonly deleteControl: {
readonly deletedControlId: string;
};
};
-export type FrameworkDetailPageDeleteControlMutation = {
- response: FrameworkDetailPageDeleteControlMutation$data;
- variables: FrameworkDetailPageDeleteControlMutation$variables;
+export type FrameworkControlPageDeleteControlMutation = {
+ response: FrameworkControlPageDeleteControlMutation$data;
+ variables: FrameworkControlPageDeleteControlMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -59,7 +59,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
- "name": "FrameworkDetailPageDeleteControlMutation",
+ "name": "FrameworkControlPageDeleteControlMutation",
"selections": [
{
"alias": null,
@@ -84,7 +84,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
- "name": "FrameworkDetailPageDeleteControlMutation",
+ "name": "FrameworkControlPageDeleteControlMutation",
"selections": [
{
"alias": null,
@@ -117,16 +117,16 @@ return {
]
},
"params": {
- "cacheID": "d86c7a2bd535a98d1cb7308a96c13401",
+ "cacheID": "f5559c3bf33da22ba6cb83fc408426e0",
"id": null,
"metadata": {},
- "name": "FrameworkDetailPageDeleteControlMutation",
+ "name": "FrameworkControlPageDeleteControlMutation",
"operationKind": "mutation",
- "text": "mutation FrameworkDetailPageDeleteControlMutation(\n $input: DeleteControlInput!\n) {\n deleteControl(input: $input) {\n deletedControlId\n }\n}\n"
+ "text": "mutation FrameworkControlPageDeleteControlMutation(\n $input: DeleteControlInput!\n) {\n deleteControl(input: $input) {\n deletedControlId\n }\n}\n"
}
};
})();
-(node as any).hash = "a067e712c3c51b73abac50e6c3779141";
+(node as any).hash = "c92c75d0666d2a60d3a2fcfb2959b2e9";
export default node;
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachDocumentMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachDocumentMutation.graphql.ts
similarity index 73%
rename from apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachDocumentMutation.graphql.ts
rename to apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachDocumentMutation.graphql.ts
index 8381ead9f..14d1fe584 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachDocumentMutation.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachDocumentMutation.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<6f2850042c0413963bd82f90236fe220>>
+ * @generated SignedSource<<61b6714faa71bf0afe54a1984b719a55>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,18 +13,18 @@ export type DeleteControlDocumentMappingInput = {
controlId: string;
documentId: string;
};
-export type FrameworkDetailPageDetachDocumentMutation$variables = {
+export type FrameworkControlPageDetachDocumentMutation$variables = {
connections: ReadonlyArray;
input: DeleteControlDocumentMappingInput;
};
-export type FrameworkDetailPageDetachDocumentMutation$data = {
+export type FrameworkControlPageDetachDocumentMutation$data = {
readonly deleteControlDocumentMapping: {
readonly deletedDocumentId: string;
};
};
-export type FrameworkDetailPageDetachDocumentMutation = {
- response: FrameworkDetailPageDetachDocumentMutation$data;
- variables: FrameworkDetailPageDetachDocumentMutation$variables;
+export type FrameworkControlPageDetachDocumentMutation = {
+ response: FrameworkControlPageDetachDocumentMutation$data;
+ variables: FrameworkControlPageDetachDocumentMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -60,7 +60,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
- "name": "FrameworkDetailPageDetachDocumentMutation",
+ "name": "FrameworkControlPageDetachDocumentMutation",
"selections": [
{
"alias": null,
@@ -85,7 +85,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
- "name": "FrameworkDetailPageDetachDocumentMutation",
+ "name": "FrameworkControlPageDetachDocumentMutation",
"selections": [
{
"alias": null,
@@ -118,16 +118,16 @@ return {
]
},
"params": {
- "cacheID": "53618baa1678e3a1b496a08597bdd364",
+ "cacheID": "f442693991b055c11609fb7bc326f1da",
"id": null,
"metadata": {},
- "name": "FrameworkDetailPageDetachDocumentMutation",
+ "name": "FrameworkControlPageDetachDocumentMutation",
"operationKind": "mutation",
- "text": "mutation FrameworkDetailPageDetachDocumentMutation(\n $input: DeleteControlDocumentMappingInput!\n) {\n deleteControlDocumentMapping(input: $input) {\n deletedDocumentId\n }\n}\n"
+ "text": "mutation FrameworkControlPageDetachDocumentMutation(\n $input: DeleteControlDocumentMappingInput!\n) {\n deleteControlDocumentMapping(input: $input) {\n deletedDocumentId\n }\n}\n"
}
};
})();
-(node as any).hash = "233b182104744a67a21d21d60b6df67a";
+(node as any).hash = "8c20b51090f69e932bc4801d88a6eaa6";
export default node;
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachMutation.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachMutation.graphql.ts
similarity index 75%
rename from apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachMutation.graphql.ts
rename to apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachMutation.graphql.ts
index 953e08a4e..632e7040b 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageDetachMutation.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkControlPageDetachMutation.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<>
+ * @generated SignedSource<<40a72ad7f2eb9fc26bf12c7f4ce731d7>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -13,18 +13,18 @@ export type DeleteControlMeasureMappingInput = {
controlId: string;
measureId: string;
};
-export type FrameworkDetailPageDetachMutation$variables = {
+export type FrameworkControlPageDetachMutation$variables = {
connections: ReadonlyArray;
input: DeleteControlMeasureMappingInput;
};
-export type FrameworkDetailPageDetachMutation$data = {
+export type FrameworkControlPageDetachMutation$data = {
readonly deleteControlMeasureMapping: {
readonly deletedMeasureId: string;
};
};
-export type FrameworkDetailPageDetachMutation = {
- response: FrameworkDetailPageDetachMutation$data;
- variables: FrameworkDetailPageDetachMutation$variables;
+export type FrameworkControlPageDetachMutation = {
+ response: FrameworkControlPageDetachMutation$data;
+ variables: FrameworkControlPageDetachMutation$variables;
};
const node: ConcreteRequest = (function(){
@@ -60,7 +60,7 @@ return {
],
"kind": "Fragment",
"metadata": null,
- "name": "FrameworkDetailPageDetachMutation",
+ "name": "FrameworkControlPageDetachMutation",
"selections": [
{
"alias": null,
@@ -85,7 +85,7 @@ return {
(v0/*: any*/)
],
"kind": "Operation",
- "name": "FrameworkDetailPageDetachMutation",
+ "name": "FrameworkControlPageDetachMutation",
"selections": [
{
"alias": null,
@@ -118,16 +118,16 @@ return {
]
},
"params": {
- "cacheID": "0bede5dc29caa4e2aba9b0dd96e58014",
+ "cacheID": "ce39a8bbb51cd7437dbc08612b60a214",
"id": null,
"metadata": {},
- "name": "FrameworkDetailPageDetachMutation",
+ "name": "FrameworkControlPageDetachMutation",
"operationKind": "mutation",
- "text": "mutation FrameworkDetailPageDetachMutation(\n $input: DeleteControlMeasureMappingInput!\n) {\n deleteControlMeasureMapping(input: $input) {\n deletedMeasureId\n }\n}\n"
+ "text": "mutation FrameworkControlPageDetachMutation(\n $input: DeleteControlMeasureMappingInput!\n) {\n deleteControlMeasureMapping(input: $input) {\n deletedMeasureId\n }\n}\n"
}
};
})();
-(node as any).hash = "96945bf8e909e7425af2297f7ee6ea0a";
+(node as any).hash = "c62748aaf06f0050732be91ae341ae73";
export default node;
diff --git a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageFragment.graphql.ts b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageFragment.graphql.ts
index e91bd5fec..86d97ace4 100644
--- a/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageFragment.graphql.ts
+++ b/apps/console/src/pages/organizations/frameworks/__generated__/FrameworkDetailPageFragment.graphql.ts
@@ -1,5 +1,5 @@
/**
- * @generated SignedSource<<775e1361b15523efe196b9edbd406f5a>>
+ * @generated SignedSource<<6b38711542a158ba9424c744d217bed5>>
* @lightSyntaxTransform
* @nogrep
*/
@@ -15,29 +15,9 @@ export type FrameworkDetailPageFragment$data = {
readonly __id: string;
readonly edges: ReadonlyArray<{
readonly node: {
- readonly description: string;
- readonly documents: {
- readonly __id: string;
- readonly edges: ReadonlyArray<{
- readonly node: {
- readonly id: string;
- readonly " $fragmentSpreads": FragmentRefs<"LinkedDocumentsCardFragment">;
- };
- }>;
- };
readonly id: string;
- readonly measures: {
- readonly __id: string;
- readonly edges: ReadonlyArray<{
- readonly node: {
- readonly id: string;
- readonly " $fragmentSpreads": FragmentRefs<"LinkedMeasuresCardFragment">;
- };
- }>;
- };
readonly name: string;
readonly sectionTitle: string;
- readonly " $fragmentSpreads": FragmentRefs<"FrameworkControlDialogFragment">;
};
}>;
};
@@ -53,97 +33,34 @@ export type FrameworkDetailPageFragment$key = {
const node: ReaderFragment = (function(){
var v0 = {
- "count": null,
- "cursor": null,
- "direction": "forward",
- "path": null
-},
-v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "id",
"storageKey": null
},
-v2 = {
+v1 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "name",
"storageKey": null
-},
-v3 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "description",
- "storageKey": null
-},
-v4 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "__typename",
- "storageKey": null
-},
-v5 = {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "cursor",
- "storageKey": null
-},
-v6 = {
- "alias": null,
- "args": null,
- "concreteType": "PageInfo",
- "kind": "LinkedField",
- "name": "pageInfo",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "endCursor",
- "storageKey": null
- },
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "hasNextPage",
- "storageKey": null
- }
- ],
- "storageKey": null
-},
-v7 = {
- "kind": "ClientExtension",
- "selections": [
- {
- "alias": null,
- "args": null,
- "kind": "ScalarField",
- "name": "__id",
- "storageKey": null
- }
- ]
};
return {
"argumentDefinitions": [],
"kind": "Fragment",
- "metadata": {
- "connection": [
- (v0/*: any*/),
- (v0/*: any*/)
- ]
- },
+ "metadata": null,
"name": "FrameworkDetailPageFragment",
"selections": [
+ (v0/*: any*/),
(v1/*: any*/),
- (v2/*: any*/),
- (v3/*: any*/),
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "description",
+ "storageKey": null
+ },
{
"alias": null,
"args": [
@@ -174,7 +91,7 @@ return {
"name": "node",
"plural": false,
"selections": [
- (v1/*: any*/),
+ (v0/*: any*/),
{
"alias": null,
"args": null,
@@ -182,106 +99,25 @@ return {
"name": "sectionTitle",
"storageKey": null
},
- (v2/*: any*/),
- (v3/*: any*/),
- {
- "args": null,
- "kind": "FragmentSpread",
- "name": "FrameworkControlDialogFragment"
- },
- {
- "alias": "measures",
- "args": null,
- "concreteType": "MeasureConnection",
- "kind": "LinkedField",
- "name": "__FrameworkDetailPage_measures_connection",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "MeasureEdge",
- "kind": "LinkedField",
- "name": "edges",
- "plural": true,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "Measure",
- "kind": "LinkedField",
- "name": "node",
- "plural": false,
- "selections": [
- (v1/*: any*/),
- {
- "args": null,
- "kind": "FragmentSpread",
- "name": "LinkedMeasuresCardFragment"
- },
- (v4/*: any*/)
- ],
- "storageKey": null
- },
- (v5/*: any*/)
- ],
- "storageKey": null
- },
- (v6/*: any*/),
- (v7/*: any*/)
- ],
- "storageKey": null
- },
- {
- "alias": "documents",
- "args": null,
- "concreteType": "DocumentConnection",
- "kind": "LinkedField",
- "name": "__FrameworkDetailPage_documents_connection",
- "plural": false,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "DocumentEdge",
- "kind": "LinkedField",
- "name": "edges",
- "plural": true,
- "selections": [
- {
- "alias": null,
- "args": null,
- "concreteType": "Document",
- "kind": "LinkedField",
- "name": "node",
- "plural": false,
- "selections": [
- (v1/*: any*/),
- {
- "args": null,
- "kind": "FragmentSpread",
- "name": "LinkedDocumentsCardFragment"
- },
- (v4/*: any*/)
- ],
- "storageKey": null
- },
- (v5/*: any*/)
- ],
- "storageKey": null
- },
- (v6/*: any*/),
- (v7/*: any*/)
- ],
- "storageKey": null
- }
+ (v1/*: any*/)
],
"storageKey": null
}
],
"storageKey": null
},
- (v7/*: any*/)
+ {
+ "kind": "ClientExtension",
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "__id",
+ "storageKey": null
+ }
+ ]
+ }
],
"storageKey": "controls(first:100)"
}
@@ -291,6 +127,6 @@ return {
};
})();
-(node as any).hash = "b70c5b2090c5db158c44f0b9fcc0f9bc";
+(node as any).hash = "e95f82575c72a8b95c87ecd3ffc676ed";
export default node;
diff --git a/apps/console/src/routes.tsx b/apps/console/src/routes.tsx
index 28f4d0a09..16e594fef 100644
--- a/apps/console/src/routes.tsx
+++ b/apps/console/src/routes.tsx
@@ -165,7 +165,11 @@ function routeTransformer({
useCleanup(dispose, 1000);
- return ;
+ return (
+ : null}>
+
+
+ );
},
};
}
diff --git a/apps/console/src/routes/documentsRoutes.ts b/apps/console/src/routes/documentsRoutes.ts
index 0fcfa98fe..1c404398d 100644
--- a/apps/console/src/routes/documentsRoutes.ts
+++ b/apps/console/src/routes/documentsRoutes.ts
@@ -7,6 +7,7 @@ import { documentNodeQuery } from "/hooks/graph/DocumentGraph";
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
import { redirect } from "react-router";
import { lazy } from "@probo/react-lazy";
+import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton";
export const documentsRoutes = [
{
@@ -38,6 +39,7 @@ export const documentsRoutes = [
},
{
path: "description",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import(
@@ -47,6 +49,7 @@ export const documentsRoutes = [
},
{
path: "controls",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import("../pages/organizations/documents/tabs/DocumentControlsTab")
diff --git a/apps/console/src/routes/frameworkRoutes.ts b/apps/console/src/routes/frameworkRoutes.ts
index da0d765ca..87a37a2b6 100644
--- a/apps/console/src/routes/frameworkRoutes.ts
+++ b/apps/console/src/routes/frameworkRoutes.ts
@@ -4,10 +4,12 @@ import { relayEnvironment } from "/providers/RelayProviders";
import {
frameworksQuery,
frameworkNodeQuery,
+ frameworkControlNodeQuery,
} from "/hooks/graph/FrameworkGraph";
import type { AppRoute } from "/routes";
import { Fragment } from "react";
import { lazy } from "@probo/react-lazy";
+import { ControlSkeleton } from "../components/skeletons/ControlSkeleton";
export const frameworkRoutes = [
{
@@ -34,7 +36,12 @@ export const frameworkRoutes = [
},
{
path: "controls/:controlId",
- Component: Fragment,
+ fallback: ControlSkeleton,
+ queryLoader: ({ controlId }) =>
+ loadQuery(relayEnvironment, frameworkControlNodeQuery, { controlId }),
+ Component: lazy(
+ () => import("/pages/organizations/frameworks/FrameworkControlPage")
+ ),
},
],
},
diff --git a/apps/console/src/routes/measureRoutes.ts b/apps/console/src/routes/measureRoutes.ts
index f817cbed1..f5559949b 100644
--- a/apps/console/src/routes/measureRoutes.ts
+++ b/apps/console/src/routes/measureRoutes.ts
@@ -6,6 +6,7 @@ import { measureNodeQuery, measuresQuery } from "/hooks/graph/MeasureGraph";
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
import { redirect } from "react-router";
import { lazy } from "@probo/react-lazy";
+import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton";
export const measureRoutes = [
{
@@ -39,18 +40,21 @@ export const measureRoutes = [
},
{
path: "risks",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/measures/tabs/MeasureRisksTab.tsx")
),
},
{
path: "tasks",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/measures/tabs/MeasureTasksTab.tsx")
),
},
{
path: "controls",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import("/pages/organizations/measures/tabs/MeasureControlsTab.tsx")
@@ -58,6 +62,7 @@ export const measureRoutes = [
},
{
path: "evidences",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import("/pages/organizations/measures/tabs/MeasureEvidencesTab.tsx")
diff --git a/apps/console/src/routes/peopleRoutes.ts b/apps/console/src/routes/peopleRoutes.ts
index 08a7b1025..8ff3ac174 100644
--- a/apps/console/src/routes/peopleRoutes.ts
+++ b/apps/console/src/routes/peopleRoutes.ts
@@ -7,6 +7,7 @@ import {
paginatedPeopleQuery,
peopleNodeQuery,
} from "/hooks/graph/PeopleGraph";
+import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton";
export const peopleRoutes = [
{
@@ -27,18 +28,21 @@ export const peopleRoutes = [
children: [
{
path: "tasks",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/people/tabs/PeopleTasksTab")
),
},
{
path: "role",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/people/tabs/PeopleRoleTab")
),
},
{
path: "profile",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/people/tabs/PeopleProfileTab")
),
diff --git a/apps/console/src/routes/riskRoutes.ts b/apps/console/src/routes/riskRoutes.ts
index 4598e7723..8b93ef30a 100644
--- a/apps/console/src/routes/riskRoutes.ts
+++ b/apps/console/src/routes/riskRoutes.ts
@@ -7,6 +7,7 @@ import { riskNodeQuery, risksQuery } from "/hooks/graph/RiskGraph";
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
import { redirect } from "react-router";
import { lazy } from "@probo/react-lazy";
+import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton";
export const riskRoutes = [
{
@@ -32,24 +33,28 @@ export const riskRoutes = [
},
{
path: "overview",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/risks/tabs/RiskOverviewTab.tsx")
),
},
{
path: "measures",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/risks/tabs/RiskMeasuresTab.tsx")
),
},
{
path: "documents",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/risks/tabs/RiskDocumentsTab.tsx")
),
},
{
path: "controls",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("/pages/organizations/risks/tabs/RiskControlsTab.tsx")
),
diff --git a/apps/console/src/routes/vendorRoutes.ts b/apps/console/src/routes/vendorRoutes.ts
index 797db13da..25e5aab38 100644
--- a/apps/console/src/routes/vendorRoutes.ts
+++ b/apps/console/src/routes/vendorRoutes.ts
@@ -4,6 +4,7 @@ import type { AppRoute } from "/routes.tsx";
import { relayEnvironment } from "/providers/RelayProviders";
import { PageSkeleton } from "/components/skeletons/PageSkeleton";
import { vendorNodeQuery, vendorsQuery } from "/hooks/graph/VendorGraph";
+import { LinkCardSkeleton } from "/components/skeletons/LinkCardSkeleton";
export const vendorRoutes = [
{
@@ -27,12 +28,14 @@ export const vendorRoutes = [
children: [
{
path: "overview",
+ fallback: LinkCardSkeleton,
Component: lazy(
() => import("../pages/organizations/vendors/tabs/VendorOverviewTab")
),
},
{
path: "certifications",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import(
@@ -42,6 +45,7 @@ export const vendorRoutes = [
},
{
path: "compliance",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import("../pages/organizations/vendors/tabs/VendorComplianceTab")
@@ -49,6 +53,7 @@ export const vendorRoutes = [
},
{
path: "risks",
+ fallback: LinkCardSkeleton,
Component: lazy(
() =>
import(