diff --git a/apps/dashboard/app/(app)/settings/root-keys/new/client.tsx b/apps/dashboard/app/(app)/settings/root-keys/new/client.tsx index 80ebc511bf..d045a59e26 100644 --- a/apps/dashboard/app/(app)/settings/root-keys/new/client.tsx +++ b/apps/dashboard/app/(app)/settings/root-keys/new/client.tsx @@ -8,6 +8,7 @@ import { Code } from "@/components/ui/code"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Checkbox } from "@/components/ui/checkbox"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { Dialog, DialogClose, @@ -22,6 +23,7 @@ import { toast } from "@/components/ui/toaster"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { trpc } from "@/lib/trpc/client"; import type { UnkeyPermission } from "@unkey/rbac"; +import { ChevronRight } from "lucide-react"; import { useRouter } from "next/navigation"; import { useState } from "react"; import { apiPermissions, workspacePermissions } from "../[keyId]/permissions/permissions"; @@ -38,7 +40,7 @@ export const Client: React.FC = ({ apis }) => { const [selectedPermissions, setSelectedPermissions] = useState([]); const key = trpc.rootKey.create.useMutation({ - onError(err) { + onError(err: { message: string }) { console.error(err); toast.error(err.message); }, @@ -65,6 +67,23 @@ export const Client: React.FC = ({ apis }) => { }); }; + type CardStates = { + [key: string]: boolean; + }; + + const initialCardStates: CardStates = {}; + apis.forEach((api) => { + initialCardStates[api.id] = false; + }); + const [cardStatesMap, setCardStatesMap] = useState(initialCardStates); + + const toggleCard = (apiId: string) => { + setCardStatesMap((prevStates) => ({ + ...prevStates, + [apiId]: !prevStates[apiId], + })); + }; + return (
@@ -132,56 +151,80 @@ export const Client: React.FC = ({ apis }) => { {apis.map((api) => ( - - - {api.name} - - Permissions scoped to this API. Enabling these roles only grants access to this - specific API. - - - -
- {Object.entries(apiPermissions(api.id)).map(([category, roles]) => { - const allPermissionNames = Object.values(roles).map(({ permission }) => permission); - const isAllSelected = allPermissionNames.every((permission) => - selectedPermissions.includes(permission), - ); + { + toggleCard(api.id); + }} + > + + + + {api.name} + + + + Permissions scoped to this API. Enabling these roles only grants access to this + specific API. + + + + + +
+ {Object.entries(apiPermissions(api.id)).map(([category, roles]) => { + const allPermissionNames = Object.values(roles).map( + ({ permission }) => permission, + ); + const isAllSelected = allPermissionNames.every((permission) => + selectedPermissions.includes(permission), + ); - return ( -
-
- {category}} - description={`Select all for ${category} permissions for this API`} - checked={isAllSelected} - setChecked={(isChecked) => { - allPermissionNames.forEach((permission) => { - handleSetChecked(permission, isChecked); - }); - }} - /> -
+ return ( +
+
+ {category}} + description={`Select all for ${category} permissions for this API`} + checked={isAllSelected} + setChecked={(isChecked) => { + allPermissionNames.forEach((permission) => { + handleSetChecked(permission, isChecked); + }); + }} + /> +
-
- {Object.entries(roles).map(([action, { description, permission }]) => ( - handleSetChecked(permission, isChecked)} - /> - ))} -
-
- ); - })} -
- - +
+ {Object.entries(roles).map(([action, { description, permission }]) => ( + handleSetChecked(permission, isChecked)} + /> + ))} +
+
+ ); + })} +
+
+ +
+ ))}