diff --git a/apps/console/src/App.tsx b/apps/console/src/App.tsx index 8e129579a..01375dc31 100644 --- a/apps/console/src/App.tsx +++ b/apps/console/src/App.tsx @@ -27,12 +27,13 @@ const NotFoundPage = lazy(() => import("./pages/NotFoundPage")); const PeopleListPage = lazy(() => import("./pages/PeopleListPage")); const VendorListPage = lazy(() => import("./pages/VendorListPage")); const FrameworkListPage = lazy(() => import("./pages/FrameworkListPage")); -const FrameworkOverviewPage = lazy( - () => import("./pages/FrameworkOverviewPage"), -); const VendorOverviewPage = lazy(() => import("./pages/VendorOverviewPage")); const SettingsPage = lazy(() => import("./pages/SettingsPage")); const CreatePeoplePage = lazy(() => import("./pages/CreatePeoplePage")); +const FrameworkOverviewPage = lazy( + () => import("./pages/FrameworkOverviewPage"), +); +const ControlOverviewPage = lazy(() => import("./pages/ControlOverviewPage")); function App() { return ( @@ -121,6 +122,16 @@ function App() { } /> + + + + + + } + /> ; +}) { + const data = usePreloadedQuery( + controlOverviewPageQuery, + queryRef, + ); + const { setBreadcrumbSegment } = useBreadcrumb(); + const control = data.node; + const tasks = control.tasks?.edges.map((edge) => edge?.node) ?? []; + + useEffect(() => { + if (control?.name) { + setBreadcrumbSegment("frameworks/:frameworkId/:controlId", control.name); + } + }, [control?.name, setBreadcrumbSegment]); + + return ( +
+
+
+

{control.name}

+
+
+ 30 min +
+
+ Mandatory +
+
+ Assigned to you +
+
+
+

{control.description}

+
+ + + +
+
+
+
+ + {control.state === "IMPLEMENTED" ? "Validated" : "Not validated"} + +
+ + + +
+

Tasks

+
+ {tasks.map((task) => ( +
+
+ {task?.state === "DONE" && ( + + )} +
+
+
+
+

+ {task?.name} +

+

+ {task?.description} +

+
+
+
+ {task?.state.toLowerCase()} +
+
+
+
+
+ ))} +
+
+
+ ); +} + +function ControlOverviewPageFallback() { + return ( +
+
+
+
+
+
+ {[1, 2, 3].map((i) => ( + + +
+
+ + + ))} +
+
+ ); +} + +export default function ControlOverviewPage() { + const { controlId } = useParams(); + const [queryRef, loadQuery] = useQueryLoader( + controlOverviewPageQuery, + ); + + useEffect(() => { + loadQuery({ controlId: controlId! }); + }, [loadQuery, controlId]); + + return ( + <> + + Control Overview - Probo Console + + }> + {queryRef && } + + + ); +} diff --git a/apps/console/src/pages/FrameworkOverviewPage.tsx b/apps/console/src/pages/FrameworkOverviewPage.tsx index 52fa451e8..14393cef9 100644 --- a/apps/console/src/pages/FrameworkOverviewPage.tsx +++ b/apps/console/src/pages/FrameworkOverviewPage.tsx @@ -1,5 +1,5 @@ import { Suspense, useEffect, useState } from "react"; -import { useParams } from "react-router"; +import { useParams, useNavigate } from "react-router"; import { graphql, PreloadedQuery, @@ -55,6 +55,7 @@ function FrameworkOverviewPageContent({ width: number; } | null>(null); const [isTooltipHovered, setIsTooltipHovered] = useState(false); + const navigate = useNavigate(); useEffect(() => { if (framework?.name) { @@ -194,6 +195,13 @@ function FrameworkOverviewPageContent({ width: 400, }); }} + onClick={() => { + if (control?.id) { + navigate( + `/frameworks/${framework.id}/${control.id}`, + ); + } + }} onMouseLeave={() => { setTimeout(() => { if (!isTooltipHovered) { diff --git a/apps/console/src/pages/__generated__/ControlOverviewPageQuery.graphql.ts b/apps/console/src/pages/__generated__/ControlOverviewPageQuery.graphql.ts new file mode 100644 index 000000000..5ad303dc7 --- /dev/null +++ b/apps/console/src/pages/__generated__/ControlOverviewPageQuery.graphql.ts @@ -0,0 +1,203 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type ControlState = "IMPLEMENTED" | "IN_PROGRESS" | "NOT_APPLICABLE" | "NOT_STARTED"; +export type TaskState = "DONE" | "TODO"; +export type ControlOverviewPageQuery$variables = { + controlId: string; +}; +export type ControlOverviewPageQuery$data = { + readonly node: { + readonly category?: string; + readonly description?: string; + readonly id: string; + readonly name?: string; + readonly state?: ControlState; + readonly tasks?: { + readonly edges: ReadonlyArray<{ + readonly node: { + readonly description: string; + readonly id: string; + readonly name: string; + readonly state: TaskState; + }; + }>; + }; + }; +}; +export type ControlOverviewPageQuery = { + response: ControlOverviewPageQuery$data; + variables: ControlOverviewPageQuery$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": "description", + "storageKey": null +}, +v5 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "state", + "storageKey": null +}, +v6 = { + "kind": "InlineFragment", + "selections": [ + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/), + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "category", + "storageKey": null + }, + { + "alias": null, + "args": null, + "concreteType": "TaskConnection", + "kind": "LinkedField", + "name": "tasks", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "TaskEdge", + "kind": "LinkedField", + "name": "edges", + "plural": true, + "selections": [ + { + "alias": null, + "args": null, + "concreteType": "Task", + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + (v3/*: any*/), + (v4/*: any*/), + (v5/*: any*/) + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "storageKey": null + } + ], + "type": "Control", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "ControlOverviewPageQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + (v6/*: any*/) + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "ControlOverviewPageQuery", + "selections": [ + { + "alias": null, + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + (v2/*: any*/), + (v6/*: any*/) + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "adb3dd88c138a9168b25c35df888af86", + "id": null, + "metadata": {}, + "name": "ControlOverviewPageQuery", + "operationKind": "query", + "text": "query ControlOverviewPageQuery(\n $controlId: ID!\n) {\n node(id: $controlId) {\n __typename\n id\n ... on Control {\n name\n description\n state\n category\n tasks {\n edges {\n node {\n id\n name\n description\n state\n }\n }\n }\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "3db82e512ed61585e9825785e1685240"; + +export default node;