v0.7.6: PostgreSQL object management, keychain toggle, tabbed Objects workspace (#12)
* [P1-T1] Change::Ddl Rust variant + execute_change arm * [P1-T2] Frontend ddl change type + objectCrud capability * [P1-T3] use_keychain data model + migration v8 * [P2-T1] object_crud skeleton + validators + build_ddl dispatch * [P2-T2] Sequence builders * [P2-T3] Enum builders (no value removal) * [P2-T4] View / matview / extension builders * [P2-T5] Index + constraint builders * [P2-T6] Function / procedure + trigger builders * [P2-T7] build_object_ddl + get_available_extensions commands + wrappers * [P3-T1] conditional keychain + session passwords * [P3-T2] keychain-off password prompt on connect * [P3-T3] default-ON keychain opt-out + tooltip + modal conditional * [P3-T4] ddl queue card + after-commit refetch * [P4-T1] ObjectCrudDialog shell * [P4-T2] SequenceForm * [P4-T3] EnumForm with no-removal note * [P4-T4] ExtensionForm with available-extensions picker * [P4-T5] ViewForm (view + materialized view) * [P5-T1] IndexForm with column picker * [P5-T2] ConstraintForm (check/unique/pk/fk) + ColumnPicker * [P5-T3] FunctionForm (function + procedure) * [P5-T4] TriggerForm with trigger-function picker * [P5-T5] ObjectContextMenu + Explorer/TableOverflowMenu CRUD wiring * [P6-T1] object tab type + openObjectTab dedup * [P6-T2] extract ObjectDetail for object tabs * [P6-T3] Objects view two-pane sidebar + workspace * [P6-T4] object-tab content + per-type tab icons * [P7-T1] Version bump 0.7.5 -> 0.7.6 * [P7-T2] docs sync README/ROADMAP/AGENTS for v0.7.6 * [P7-T3] chore: Cargo.lock version sync 0.7.5 -> 0.7.6 * fix(ui): object tab icon stacks above name (preflight svg block) * fix(ui): optically center object tab icon with name * fix(ui): object tab icon matches query/table icon handling * [UI-POLISH-1] objectForm tab type + openFormTab store action * [UI-POLISH-2] ObjectFormTab + KindForm with Visual/SQL toggle * [UI-POLISH-3] route create/edit through form tabs; remove modal * docs: create/edit now open as form tabs (AGENTS sync) * [FB-1] follow app styling patterns + schema dropdown in forms * [FB-2] Monaco editor for function body + view definition * [FB-3] form tabs styled like viewers + in-cell editing * [FB-5] focus outline scoped to input area (label excluded) * [FB-6] no amber focus outline on Monaco body/definition rows * [FB-7] header dedupe + schema default + full edit prefill * [FB-8] SQL view in read-only Monaco editor * docs: roadmap — table create/edit + relationships (next) * docs: roadmap — Admin follow-up is 0.7.7 (next after 0.7.6)
This commit is contained in:
@@ -15,11 +15,14 @@ const DestructiveQueryDialog = lazy(() =>
|
||||
);
|
||||
import { TableTree } from "./TableTree";
|
||||
import { ObjectExplorerPage } from "./ObjectExplorerPage";
|
||||
import { ObjectDetail, type AnyObject } from "./objects/ObjectDetail";
|
||||
import { ObjectFormTab } from "./objects/ObjectFormTab";
|
||||
import { TabBar } from "./TabBar";
|
||||
import { VirtualDataGrid } from "../grid/VirtualDataGrid";
|
||||
import { RowDetailDrawer } from "../grid/RowDetailDrawer";
|
||||
import { TableControls } from "./TableControls";
|
||||
import { EditConnectionModal } from "./EditConnectionModal";
|
||||
import { PasswordPromptDialog } from "./PasswordPromptDialog";
|
||||
import { useDbConnection } from "../../hooks/useDbConnection";
|
||||
import { useDbViewerStore } from "../../stores/dbViewerStore";
|
||||
import { useConnectionStore } from "../../stores/connectionStore";
|
||||
@@ -162,7 +165,8 @@ export function DbViewerScreen({
|
||||
onHome,
|
||||
onSettings,
|
||||
}: DbViewerScreenProps) {
|
||||
const { connectionError, connect } = useDbConnection(connectionId);
|
||||
const { connectionError, connect, passwordPromptOpen, submitPassword, cancelPassword } =
|
||||
useDbConnection(connectionId);
|
||||
const [dismissedError, setDismissedError] = useState<string | null>(null);
|
||||
const [currentView, setCurrentView] = useState<string>("db-viewer");
|
||||
const [tablePanelWidth, setTablePanelWidth] = useState(280);
|
||||
@@ -984,15 +988,30 @@ const onQueriesPanelResizeStart = useCallback(
|
||||
<div className="flex-1 flex flex-col items-center justify-center gap-2 text-text-muted">
|
||||
{currentView === "queries" ? (
|
||||
<Terminal size={32} />
|
||||
) : currentView === "objects" ? (
|
||||
<Database size={32} />
|
||||
) : (
|
||||
<Table2 size={32} />
|
||||
)}
|
||||
<span>
|
||||
{currentView === "queries"
|
||||
? "Open a new query tab or run a query from the history"
|
||||
: "Select a table from the tree to browse its data, or open a new query tab"}
|
||||
: currentView === "objects"
|
||||
? "Open an object from the list, or open a new query tab"
|
||||
: "Select a table from the tree to browse its data, or open a new query tab"}
|
||||
</span>
|
||||
</div>
|
||||
) : activeTab?.tabType === "objectForm" ? (
|
||||
<ObjectFormTab
|
||||
connectionId={connectionId}
|
||||
tab={activeTab}
|
||||
/>
|
||||
) : activeTab?.tabType === "object" ? (
|
||||
<ObjectDetail
|
||||
connectionId={connectionId}
|
||||
type={activeTab.objectType!}
|
||||
item={activeTab.objectItem as AnyObject}
|
||||
/>
|
||||
) : activeTab?.tabType === "query" ? (
|
||||
<Suspense
|
||||
fallback={
|
||||
@@ -1439,7 +1458,20 @@ const onQueriesPanelResizeStart = useCallback(
|
||||
{renderQueryWorkspace()}
|
||||
</div>
|
||||
) : currentView === "objects" ? (
|
||||
<ObjectExplorerPage connectionId={connectionId} />
|
||||
<div className="flex flex-1 min-h-0 overflow-hidden">
|
||||
<div
|
||||
className="border-r border-border flex flex-col shrink-0"
|
||||
style={{ width: tablePanelWidth }}
|
||||
>
|
||||
<ObjectExplorerPage connectionId={connectionId} sidebarMode />
|
||||
</div>
|
||||
<div
|
||||
className="w-1 cursor-col-resize bg-border/20 hover:bg-accent/30 active:bg-accent/50 shrink-0 border-r border-border"
|
||||
onMouseDown={onPanelResizeStart}
|
||||
onDoubleClick={() => setTablePanelWidth(280)}
|
||||
/>
|
||||
{renderQueryWorkspace()}
|
||||
</div>
|
||||
) : currentView === "tools" ? (
|
||||
<ToolsPage connectionId={connectionId} />
|
||||
) : currentView === "queries" ? (
|
||||
@@ -1473,6 +1505,12 @@ const onQueriesPanelResizeStart = useCallback(
|
||||
onSaved={() => {}}
|
||||
/>
|
||||
)}
|
||||
<PasswordPromptDialog
|
||||
open={passwordPromptOpen}
|
||||
connectionName={currentConnection?.name ?? ""}
|
||||
onConnect={submitPassword}
|
||||
onCancel={cancelPassword}
|
||||
/>
|
||||
{capabilities.objects && (
|
||||
<ObjectSearchPalette connectionId={connectionId} />
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user