56 lines
1.9 KiB
TypeScript
56 lines
1.9 KiB
TypeScript
import { Menu } from "@base-ui/react/menu";
|
|
import { ChevronDown, RefreshCw } from "lucide-react";
|
|
import { buttonVariants } from "../../components/ui/button";
|
|
import type { CatalogSyncScope } from "../../api/catalog-databases";
|
|
|
|
export type DatabaseSyncScope = Exclude<CatalogSyncScope, "columns">;
|
|
|
|
export const databaseSyncItemClass = [
|
|
"flex cursor-default select-none items-center rounded-md px-3 py-2 text-sm outline-none",
|
|
"data-[highlighted]:bg-muted data-[disabled]:opacity-45",
|
|
].join(" ");
|
|
|
|
export const databaseSyncScopes: ReadonlyArray<{ scope: DatabaseSyncScope; label: string }> = [
|
|
{ scope: "tables", label: "Synchronize tables" },
|
|
{ scope: "relationships", label: "Synchronize relationships" },
|
|
{ scope: "all", label: "Synchronize all" },
|
|
];
|
|
|
|
interface DatabaseSyncMenuProps {
|
|
disabled: boolean;
|
|
disabledReason?: string;
|
|
onSelect: (scope: DatabaseSyncScope) => void;
|
|
}
|
|
|
|
export function DatabaseSyncMenu({ disabled, disabledReason, onSelect }: DatabaseSyncMenuProps) {
|
|
return (
|
|
<Menu.Root>
|
|
<Menu.Trigger
|
|
type="button"
|
|
className={buttonVariants()}
|
|
disabled={disabled}
|
|
title={disabledReason}
|
|
aria-label="Synchronize database schema"
|
|
>
|
|
<RefreshCw />Synchronize<ChevronDown />
|
|
</Menu.Trigger>
|
|
<Menu.Portal>
|
|
<Menu.Positioner side="bottom" align="end" sideOffset={4}>
|
|
<Menu.Popup className="z-50 min-w-64 rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-none">
|
|
{databaseSyncScopes.map(({ scope, label }) => (
|
|
<Menu.Item
|
|
key={scope}
|
|
className={databaseSyncItemClass}
|
|
disabled={disabled}
|
|
onClick={() => onSelect(scope)}
|
|
>
|
|
{label}
|
|
</Menu.Item>
|
|
))}
|
|
</Menu.Popup>
|
|
</Menu.Positioner>
|
|
</Menu.Portal>
|
|
</Menu.Root>
|
|
);
|
|
}
|