diff --git a/public/extension/chart-dark.png b/public/extension/chart-dark.png new file mode 100644 index 00000000..4dfe8a08 Binary files /dev/null and b/public/extension/chart-dark.png differ diff --git a/public/extension/chart-light.png b/public/extension/chart-light.png new file mode 100644 index 00000000..b9a368b7 Binary files /dev/null and b/public/extension/chart-light.png differ diff --git a/public/extension/definition-dark.png b/public/extension/definition-dark.png new file mode 100644 index 00000000..642e4468 Binary files /dev/null and b/public/extension/definition-dark.png differ diff --git a/public/extension/definition-light.png b/public/extension/definition-light.png new file mode 100644 index 00000000..65be8505 Binary files /dev/null and b/public/extension/definition-light.png differ diff --git a/public/extension/term-dark.png b/public/extension/term-dark.png new file mode 100644 index 00000000..3a1c3739 Binary files /dev/null and b/public/extension/term-dark.png differ diff --git a/public/extension/term-light.png b/public/extension/term-light.png new file mode 100644 index 00000000..72106aad Binary files /dev/null and b/public/extension/term-light.png differ diff --git a/src/components/sidebar-menu.tsx b/src/components/sidebar-menu.tsx index 80ba03b7..16e202f3 100644 --- a/src/components/sidebar-menu.tsx +++ b/src/components/sidebar-menu.tsx @@ -1,3 +1,4 @@ +import { cn } from "@/lib/utils"; import Link from "next/link"; interface SidebarMenuItemProps { @@ -17,6 +18,7 @@ export function SidebarMenuItem({ onClick, icon: IconComponent, href, + selected, }: SidebarMenuItemProps) { const className = "flex p-2 pl-4 text-xs hover:cursor-pointer hover:bg-secondary"; @@ -49,7 +51,10 @@ export function SidebarMenuItem({ } return ( - ); diff --git a/src/extensions/data-catalog/data-catalog-entry-modal.tsx b/src/extensions/data-catalog/data-catalog-entry-modal.tsx new file mode 100644 index 00000000..7e63027b --- /dev/null +++ b/src/extensions/data-catalog/data-catalog-entry-modal.tsx @@ -0,0 +1,172 @@ +import { ToolbarFiller } from "@/components/gui/toolbar"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { LucideLoader } from "lucide-react"; +import { useCallback, useEffect, useState } from "react"; +import DataCatalogDriver, { DataCatalogTermDefinition } from "./driver"; + +interface Props { + driver?: DataCatalogDriver; + open: boolean; + onSuccess: () => void; + onClose: (open: boolean) => void; + selectedTermDefinition?: DataCatalogTermDefinition; +} + +export function DataCatalogEntryModal({ + open, + onClose, + driver, + onSuccess, + selectedTermDefinition, +}: Props) { + const [deleting, setDeleting] = useState(false); + const [loading, setLoading] = useState(false); + const [formData, setFormData] = useState({ + id: "", + name: "", + otherName: "", + definition: "", + }); + + const clear = useCallback(() => { + setLoading(false); + setDeleting(false); + onClose(false); + setFormData({ + id: "", + name: "", + otherName: "", + definition: "", + }); + }, [onClose]); + + useEffect(() => { + if (selectedTermDefinition) { + setFormData(selectedTermDefinition); + } else { + clear(); + } + }, [selectedTermDefinition, clear]); + + const saveTermDefinition = useCallback(() => { + setLoading(true); + const data = { + ...formData, + id: selectedTermDefinition?.id || String(Date.now() * 1000), // Use existing ID if editing + }; + + driver + ?.updateTermDefinition(data) + .then(() => onSuccess()) + .finally(() => clear()); + }, [formData, driver, onSuccess, clear, selectedTermDefinition]); + + function onDelete() { + if (!selectedTermDefinition) return; + + setDeleting(true); + driver + ?.deleteTermDefinition(selectedTermDefinition.id) + .then(() => onSuccess()) + .finally(() => clear()); + } + + const onChangeValue = useCallback( + (value: string, key: keyof DataCatalogTermDefinition) => { + setFormData((prev) => ({ + ...prev, + [key]: value, + })); + }, + [] + ); + + return ( + + + + + {selectedTermDefinition ? "Edit Term" : "Add Term"} + + + {selectedTermDefinition + ? "Modify the existing term definition." + : "Add terms to your Data Dictionary to help your team and AI understand important business terminology."} + + +
+
+ + onChangeValue(e.currentTarget.value, "name")} + /> +
+
+ + + onChangeValue(e.currentTarget.value, "otherName") + } + /> +
+
+ +