|
1 | | -import { Combobox, tComboboxItem } from "@/components/ui/combobox-legacy"; |
| 1 | +import { Badge } from "@/components/ui/badge"; |
| 2 | +import { |
| 3 | + Combobox, |
| 4 | + ComboboxContent, |
| 5 | + ComboboxEmpty, |
| 6 | + ComboboxItem, |
| 7 | + ComboboxList, |
| 8 | + ComboboxTrigger, |
| 9 | +} from "@/components/ui/combobox"; |
2 | 10 | import Label from "@/components/ui/label"; |
3 | 11 | import { PROFILE_KIND } from "@/config/constants"; |
| 12 | +import useQuery from "@/hooks/useQuery"; |
| 13 | +import { useSchema } from "@/hooks/useSchema"; |
| 14 | +import LoadingScreen from "@/screens/loading-screen/loading-screen"; |
| 15 | +import { getObjectPermissionsQuery } from "@/screens/permission/queries/getObjectPermissions"; |
| 16 | +import { PermissionData } from "@/screens/permission/types"; |
| 17 | +import { getPermission } from "@/screens/permission/utils"; |
4 | 18 | import { genericsState, profilesAtom, schemaState } from "@/state/atoms/schema.atom"; |
| 19 | +import { gql } from "@apollo/client"; |
5 | 20 | import { useAtomValue } from "jotai/index"; |
6 | | -import { useId } from "react"; |
| 21 | +import React, { useId, useState } from "react"; |
7 | 22 |
|
8 | 23 | type GenericSelectorProps = { |
9 | 24 | currentKind: string; |
10 | 25 | kindInheritingFromGeneric: string[]; |
11 | | - value?: string; |
12 | | - onChange: (item: string) => void; |
| 26 | + value?: string | null; |
| 27 | + onChange: (item: string | null) => void; |
13 | 28 | }; |
14 | 29 |
|
15 | 30 | export const GenericSelector = ({ |
16 | 31 | currentKind, |
17 | 32 | kindInheritingFromGeneric, |
18 | | - ...props |
| 33 | + value, |
| 34 | + onChange, |
19 | 35 | }: GenericSelectorProps) => { |
20 | 36 | const id = useId(); |
21 | 37 | const nodeSchemas = useAtomValue(schemaState); |
22 | 38 | const nodeGenerics = useAtomValue(genericsState); |
23 | 39 | const profileSchemas = useAtomValue(profilesAtom); |
| 40 | + const { schema } = useSchema(value); |
| 41 | + const [open, setOpen] = useState(false); |
| 42 | + const { data, loading } = useQuery(gql(getObjectPermissionsQuery(currentKind))); |
24 | 43 |
|
25 | | - const items: Array<tComboboxItem> = kindInheritingFromGeneric |
| 44 | + if (loading) return <LoadingScreen />; |
| 45 | + const permissionsData: Array<{ node: PermissionData }> = data?.[currentKind]?.permissions?.edges; |
| 46 | + |
| 47 | + const items = kindInheritingFromGeneric |
26 | 48 | .map((usedByKind) => { |
27 | 49 | const relatedSchema = [...nodeSchemas, ...profileSchemas].find( |
28 | 50 | (schema) => schema.kind === usedByKind |
@@ -62,7 +84,46 @@ export const GenericSelector = ({ |
62 | 84 | return ( |
63 | 85 | <div className="p-4 bg-gray-200"> |
64 | 86 | <Label htmlFor={id}>Select an object type</Label> |
65 | | - <Combobox id={id} items={items} {...props} /> |
| 87 | + <Combobox open={open} onOpenChange={setOpen}> |
| 88 | + <ComboboxTrigger id={id}> |
| 89 | + {schema && <SchemaItem label={schema.label as string} badge={schema.namespace} />} |
| 90 | + </ComboboxTrigger> |
| 91 | + |
| 92 | + <ComboboxContent> |
| 93 | + <ComboboxList> |
| 94 | + <ComboboxEmpty>No schema found.</ComboboxEmpty> |
| 95 | + {items.map((item) => { |
| 96 | + const itemValue = item?.value as string; |
| 97 | + const permissionToCreate = getPermission( |
| 98 | + permissionsData.filter(({ node }) => node.kind === itemValue) |
| 99 | + ).create; |
| 100 | + |
| 101 | + return ( |
| 102 | + <ComboboxItem |
| 103 | + key={itemValue} |
| 104 | + value={itemValue} |
| 105 | + selectedValue={value} |
| 106 | + onSelect={() => { |
| 107 | + onChange(value === itemValue ? null : itemValue); |
| 108 | + setOpen(false); |
| 109 | + }} |
| 110 | + disabled={!permissionToCreate.isAllowed} |
| 111 | + > |
| 112 | + <SchemaItem label={item.label} badge={item.badge} /> |
| 113 | + </ComboboxItem> |
| 114 | + ); |
| 115 | + })} |
| 116 | + </ComboboxList> |
| 117 | + </ComboboxContent> |
| 118 | + </Combobox> |
| 119 | + </div> |
| 120 | + ); |
| 121 | +}; |
| 122 | + |
| 123 | +const SchemaItem = ({ label, badge }: { label: string; badge: string }) => { |
| 124 | + return ( |
| 125 | + <div className="flex justify-between w-full"> |
| 126 | + <span>{label}</span> <Badge>{badge}</Badge> |
66 | 127 | </div> |
67 | 128 | ); |
68 | 129 | }; |
0 commit comments