fix: scope and batch sensitive suggestions
This commit is contained in:
@@ -3,7 +3,7 @@ import { Menu } from "@base-ui/react/menu";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { AgGridReact } from "ag-grid-react";
|
||||
import type { ColDef, ICellRendererParams } from "ag-grid-community";
|
||||
import { ArrowLeft, ChevronDown, Columns3, Pencil, RefreshCw, Save, Trash2, X } from "lucide-react";
|
||||
import { ArrowLeft, ChevronDown, Columns3, Pencil, RefreshCw, Save, Sparkles, Trash2, X } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "../../components/ui/button";
|
||||
import { ApiError, apiErrorMessage } from "../../api/client";
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
type CatalogTable,
|
||||
type CatalogTableMetadataDeleteTarget,
|
||||
type DescriptionGenerationRun,
|
||||
type SensitiveDataSuggestionRequest,
|
||||
} from "../../api/catalog-databases";
|
||||
import type { DatabaseNavigationState } from "./model";
|
||||
import { DatabaseColumns } from "./DatabaseColumns";
|
||||
@@ -36,6 +37,7 @@ interface Props {
|
||||
onRunStarted: (run: CatalogSyncRun) => void;
|
||||
onOpenSync: () => void;
|
||||
onDescriptionGenerationRunStarted: (run: DescriptionGenerationRun) => void;
|
||||
onSuggestSensitive: (selection: SensitiveDataSuggestionRequest, scopeLabel: string) => Promise<void>;
|
||||
}
|
||||
|
||||
interface TableGridContext {
|
||||
@@ -70,6 +72,7 @@ export function DatabaseTables({
|
||||
onRunStarted,
|
||||
onOpenSync,
|
||||
onDescriptionGenerationRunStarted,
|
||||
onSuggestSensitive,
|
||||
}: Props) {
|
||||
const databaseId = database.id!;
|
||||
const queryClient = useQueryClient();
|
||||
@@ -86,7 +89,7 @@ export function DatabaseTables({
|
||||
const [editorVersion, setEditorVersion] = useState<number | null>(null);
|
||||
const [stale, setStale] = useState(false);
|
||||
const [staleBannerOpen, setStaleBannerOpen] = useState(true);
|
||||
const [busy, setBusy] = useState<"sync" | "save" | "delete" | "consolidate" | "generate" | null>(null);
|
||||
const [busy, setBusy] = useState<"sync" | "save" | "delete" | "consolidate" | "generate" | "suggest" | null>(null);
|
||||
const [pendingDelete, setPendingDelete] = useState<CatalogTableMetadataDeleteTarget | null>(null);
|
||||
const [columnNavigation, setColumnNavigation] = useState<DatabaseNavigationState>({ dirty: false, busy: false });
|
||||
const gridRef = useRef<AgGridReact<CatalogTable>>(null);
|
||||
@@ -240,6 +243,20 @@ export function DatabaseTables({
|
||||
toast.error(apiErrorMessage(error));
|
||||
} finally { setBusy(null); }
|
||||
};
|
||||
const suggestSensitive = async () => {
|
||||
if (selectedIds.length === 0) return;
|
||||
setBusy("suggest");
|
||||
try {
|
||||
await onSuggestSensitive(
|
||||
{ scope: "selected_tables", targetIds: selectedIds },
|
||||
`${selectedIds.length} selected table${selectedIds.length === 1 ? "" : "s"}`,
|
||||
);
|
||||
} catch {
|
||||
// The page-level request reports the safe, specific reason and preserves the selection.
|
||||
} finally {
|
||||
setBusy(null);
|
||||
}
|
||||
};
|
||||
|
||||
const columns = useMemo<ColDef<CatalogTable>[]>(() => [
|
||||
{ field: "name", headerName: "Name", minWidth: 250, flex: 1, cellClass: "font-mono text-xs" },
|
||||
@@ -303,6 +320,7 @@ export function DatabaseTables({
|
||||
onDescriptionGenerationRunStarted={onDescriptionGenerationRunStarted}
|
||||
onNavigationStateChange={setColumnNavigation}
|
||||
onSync={() => void synchronize("columns", [activeTable.id])}
|
||||
onSuggestSensitive={onSuggestSensitive}
|
||||
/>
|
||||
) : (
|
||||
<div className="min-h-0 overflow-y-auto px-4 py-5">
|
||||
@@ -420,6 +438,15 @@ export function DatabaseTables({
|
||||
</Menu.Positioner>
|
||||
</Menu.Portal>
|
||||
</Menu.Root>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={!canManage || descriptionGenerationActive || busy !== null}
|
||||
title={descriptionGenerationActive ? "Wait for the active description generation to finish" : undefined}
|
||||
onClick={() => void suggestSensitive()}
|
||||
>
|
||||
<Sparkles />{busy === "suggest" ? "Suggesting…" : "Suggest sensitive fields"}
|
||||
</Button>
|
||||
<Button type="button" variant="ghost" onClick={() => { gridRef.current?.api.deselectAll(); setSelectedIds([]); }}><X />Clear</Button>
|
||||
</>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user