diff --git a/apps/console/src/App.tsx b/apps/console/src/App.tsx index f417b039d..d7d5911e0 100644 --- a/apps/console/src/App.tsx +++ b/apps/console/src/App.tsx @@ -46,6 +46,7 @@ const CreateOrganizationPage = lazy( ); const CreateFrameworkPage = lazy(() => import("./pages/CreateFrameworkPage")); const CreateControlPage = lazy(() => import("./pages/CreateControlPage")); +const UpdateFrameworkPage = lazy(() => import("./pages/UpdateFrameworkPage")); function App() { return ( @@ -230,6 +231,16 @@ function App() { } /> + + + + + + } + /> ( + graphql` + query ConsoleLayoutBreadcrumbUpdateFrameworkQuery($frameworkId: ID!) { + framework: node(id: $frameworkId) { + id + ... on Framework { + name + } + } + } + `, + { frameworkId: frameworkId! }, + { fetchPolicy: "store-or-network" } + ); + + return ( + <> + + + + + {data.framework?.name} + + + + + + Update + + + + ); +} + function BreadcrumbVendorList() { const { organizationId } = useParams(); return ( @@ -303,7 +345,6 @@ function BreadcrumbCreateControl() { graphql` query ConsoleLayoutBreadcrumbCreateControlQuery($frameworkId: ID!) { framework: node(id: $frameworkId) { - id ... on Framework { name } @@ -365,6 +406,10 @@ export default function ConsoleLayout() { element={} /> + } + /> } diff --git a/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbCreateControlQuery.graphql.ts b/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbCreateControlQuery.graphql.ts index 5eda85e95..57e664e1f 100644 --- a/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbCreateControlQuery.graphql.ts +++ b/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbCreateControlQuery.graphql.ts @@ -1,5 +1,5 @@ /** - * @generated SignedSource<<72acdb0b83faf29c9d1a4f403a40ac5e>> + * @generated SignedSource<<051137c0676ed5fd6b8807a44b9cb2a4>> * @lightSyntaxTransform * @nogrep */ @@ -14,7 +14,6 @@ export type ConsoleLayoutBreadcrumbCreateControlQuery$variables = { }; export type ConsoleLayoutBreadcrumbCreateControlQuery$data = { readonly framework: { - readonly id: string; readonly name?: string; }; }; @@ -39,13 +38,6 @@ v1 = [ } ], v2 = { - "alias": null, - "args": null, - "kind": "ScalarField", - "name": "id", - "storageKey": null -}, -v3 = { "kind": "InlineFragment", "selections": [ { @@ -74,8 +66,7 @@ return { "name": "node", "plural": false, "selections": [ - (v2/*: any*/), - (v3/*: any*/) + (v2/*: any*/) ], "storageKey": null } @@ -105,23 +96,29 @@ return { "storageKey": null }, (v2/*: any*/), - (v3/*: any*/) + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null + } ], "storageKey": null } ] }, "params": { - "cacheID": "96453f593f21e812afc5b888cc68da3e", + "cacheID": "a86ec305f24f6a83d549a31e1469a89c", "id": null, "metadata": {}, "name": "ConsoleLayoutBreadcrumbCreateControlQuery", "operationKind": "query", - "text": "query ConsoleLayoutBreadcrumbCreateControlQuery(\n $frameworkId: ID!\n) {\n framework: node(id: $frameworkId) {\n __typename\n id\n ... on Framework {\n name\n }\n }\n}\n" + "text": "query ConsoleLayoutBreadcrumbCreateControlQuery(\n $frameworkId: ID!\n) {\n framework: node(id: $frameworkId) {\n __typename\n ... on Framework {\n name\n }\n id\n }\n}\n" } }; })(); -(node as any).hash = "f249019075c60c4449f6f232229a6965"; +(node as any).hash = "5033069853aec310ad544974f7e64b5b"; export default node; diff --git a/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbUpdateFrameworkQuery.graphql.ts b/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbUpdateFrameworkQuery.graphql.ts new file mode 100644 index 000000000..1baa9a7b2 --- /dev/null +++ b/apps/console/src/layouts/__generated__/ConsoleLayoutBreadcrumbUpdateFrameworkQuery.graphql.ts @@ -0,0 +1,127 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ +/* eslint-disable */ +// @ts-nocheck + +import { ConcreteRequest } from 'relay-runtime'; +export type ConsoleLayoutBreadcrumbUpdateFrameworkQuery$variables = { + frameworkId: string; +}; +export type ConsoleLayoutBreadcrumbUpdateFrameworkQuery$data = { + readonly framework: { + readonly id: string; + readonly name?: string; + }; +}; +export type ConsoleLayoutBreadcrumbUpdateFrameworkQuery = { + response: ConsoleLayoutBreadcrumbUpdateFrameworkQuery$data; + variables: ConsoleLayoutBreadcrumbUpdateFrameworkQuery$variables; +}; + +const node: ConcreteRequest = (function(){ +var v0 = [ + { + "defaultValue": null, + "kind": "LocalArgument", + "name": "frameworkId" + } +], +v1 = [ + { + "kind": "Variable", + "name": "id", + "variableName": "frameworkId" + } +], +v2 = { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "id", + "storageKey": null +}, +v3 = { + "kind": "InlineFragment", + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "name", + "storageKey": null + } + ], + "type": "Framework", + "abstractKey": null +}; +return { + "fragment": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Fragment", + "metadata": null, + "name": "ConsoleLayoutBreadcrumbUpdateFrameworkQuery", + "selections": [ + { + "alias": "framework", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + (v2/*: any*/), + (v3/*: any*/) + ], + "storageKey": null + } + ], + "type": "Query", + "abstractKey": null + }, + "kind": "Request", + "operation": { + "argumentDefinitions": (v0/*: any*/), + "kind": "Operation", + "name": "ConsoleLayoutBreadcrumbUpdateFrameworkQuery", + "selections": [ + { + "alias": "framework", + "args": (v1/*: any*/), + "concreteType": null, + "kind": "LinkedField", + "name": "node", + "plural": false, + "selections": [ + { + "alias": null, + "args": null, + "kind": "ScalarField", + "name": "__typename", + "storageKey": null + }, + (v2/*: any*/), + (v3/*: any*/) + ], + "storageKey": null + } + ] + }, + "params": { + "cacheID": "194d6a240ee1e2f0ef799e08bc0e44f5", + "id": null, + "metadata": {}, + "name": "ConsoleLayoutBreadcrumbUpdateFrameworkQuery", + "operationKind": "query", + "text": "query ConsoleLayoutBreadcrumbUpdateFrameworkQuery(\n $frameworkId: ID!\n) {\n framework: node(id: $frameworkId) {\n __typename\n id\n ... on Framework {\n name\n }\n }\n}\n" + } +}; +})(); + +(node as any).hash = "c6381fa068566e0ec00356b3e6835700"; + +export default node; diff --git a/apps/console/src/pages/FrameworkOverviewPage.tsx b/apps/console/src/pages/FrameworkOverviewPage.tsx index 10c4660fd..9350bda3d 100644 --- a/apps/console/src/pages/FrameworkOverviewPage.tsx +++ b/apps/console/src/pages/FrameworkOverviewPage.tsx @@ -87,14 +87,23 @@ function FrameworkOverviewPageContent({

{framework.name}

{framework.description}

- +
+ + +
diff --git a/apps/console/src/pages/UpdateFrameworkPage.tsx b/apps/console/src/pages/UpdateFrameworkPage.tsx new file mode 100644 index 000000000..36c6a2459 --- /dev/null +++ b/apps/console/src/pages/UpdateFrameworkPage.tsx @@ -0,0 +1,268 @@ +import { Suspense, useState, useEffect } from "react"; +import { useNavigate, useParams } from "react-router"; +import { + graphql, + useMutation, + usePreloadedQuery, + PreloadedQuery, + useQueryLoader, +} from "react-relay"; +import { Helmet } from "react-helmet-async"; +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { useToast } from "@/hooks/use-toast"; +import { HelpCircle } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { UpdateFrameworkPageUpdateFrameworkMutation } from "./__generated__/UpdateFrameworkPageUpdateFrameworkMutation.graphql"; +import { UpdateFrameworkPageQuery as UpdateFrameworkPageQueryType } from "./__generated__/UpdateFrameworkPageQuery.graphql"; + +const updateFrameworkMutation = graphql` + mutation UpdateFrameworkPageUpdateFrameworkMutation( + $input: UpdateFrameworkInput! + ) { + updateFramework(input: $input) { + id + name + description + version + } + } +`; + +const updateFrameworkQuery = graphql` + query UpdateFrameworkPageQuery($frameworkId: ID!) { + node(id: $frameworkId) { + ... on Framework { + id + name + description + version + } + } + } +`; + +function EditableField({ + label, + value, + onChange, + type = "text", + helpText, + required, + multiline = false, +}: { + label: string; + value: string; + onChange: (value: string) => void; + type?: string; + helpText?: string; + required?: boolean; + multiline?: boolean; +}) { + return ( +
+
+ + {helpText && ( +
+ + {helpText} +
+ )} +
+ {multiline ? ( +