feat(usable): integrate current dbtool implementation snapshot
Some checks failed
release-smoke / macos-13 / x86_64-apple-darwin (push) Has been cancelled
release-smoke / ubuntu-latest / x86_64-unknown-linux-gnu (push) Has been cancelled
release-smoke / windows-latest / x86_64-pc-windows-msvc (push) Has been cancelled

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Paperclip CTO
2026-04-02 08:26:18 +00:00
parent a28dab4cd9
commit d5f69462b0
73 changed files with 5895 additions and 322 deletions

94
gui/prototype/app.js vendored
View File

@@ -495,6 +495,8 @@ limit 25;`,
const connectionCards = document.querySelectorAll(".connection-card");
const bottomTabs = document.querySelectorAll(".bottom-tab");
const tabContents = document.querySelectorAll(".tab-content");
const workflowStepButtons = document.querySelectorAll("[data-workflow-step]");
const reviewPanels = document.querySelectorAll("[data-review-panel]");
const activeConnection = document.getElementById("active-connection");
const driverPill = document.getElementById("driver-pill");
@@ -556,6 +558,7 @@ const commandCloseButton = document.getElementById("command-close");
const commandStateButtons = document.querySelectorAll("[data-command-state]");
const commandConnectionButtons = document.querySelectorAll("[data-command-connection]");
const commandActionButtons = document.querySelectorAll("[data-command-action]");
const workflowCopy = document.getElementById("workflow-copy");
const appState = {
connection: "pg-prod-readonly",
@@ -563,9 +566,17 @@ const appState = {
selection: "public.orders",
activeState: "success",
activeTab: "results",
workflowStep: "connect",
runTimer: null,
};
const workflowStepCopy = {
connect: "当前聚焦 Connect先确认活动目标、环境标签和连接摘要清晰可见。",
inspect: "当前聚焦 Inspect核对 schema browser、当前对象和 inspector 元数据保持同步。",
query: "当前聚焦 Query确认 SQL 草稿、执行反馈和结果区在同一工作台上下文里。",
export: "当前聚焦 Export复核默认导出路径、空结果说明和错误态禁用约束。",
};
function getActiveConnectionCard() {
return document.querySelector(`.connection-card[data-connection="${appState.connection}"]`);
}
@@ -618,6 +629,20 @@ function setActiveTab(tabName) {
});
}
function renderWorkflowStep() {
workflowStepButtons.forEach((button) => {
const isActive = button.dataset.workflowStep === appState.workflowStep;
button.classList.toggle("is-active", isActive);
button.setAttribute("aria-pressed", String(isActive));
});
reviewPanels.forEach((panel) => {
panel.classList.toggle("is-review-focus", panel.dataset.reviewPanel === appState.workflowStep);
});
workflowCopy.textContent = workflowStepCopy[appState.workflowStep];
}
function renderToolbarTabs() {
const fixture = getWorkspaceFixture();
@@ -1095,6 +1120,7 @@ function renderAll() {
renderConnection();
renderSelection();
renderThemeLabel();
renderWorkflowStep();
renderQuery();
setActiveTab(appState.activeTab);
}
@@ -1124,6 +1150,26 @@ function syncSelection(selection) {
renderSelection();
}
function setWorkflowStep(step, { syncTab = false, status = null } = {}) {
appState.workflowStep = step;
if (syncTab) {
if (step === "query") {
setActiveTab("results");
}
if (step === "export") {
setActiveTab("export");
}
}
renderWorkflowStep();
if (status) {
statusMessage.textContent = status;
}
}
function setQuery(queryKey, syncState = true) {
const preset = getQueryPreset(queryKey);
appState.query = queryKey;
@@ -1136,6 +1182,7 @@ function setQuery(queryKey, syncState = true) {
function startRunPreview() {
clearRunTimer();
setWorkflowStep("query", { syncTab: true });
appState.activeState = "running";
setActiveTab("results");
renderState();
@@ -1158,7 +1205,9 @@ connectionCards.forEach((card) => {
schemaSearch.value = "";
setActiveTab("results");
renderAll();
statusMessage.textContent = `${card.dataset.connection} loaded. Catalog, draft labels, and inspector now reflect the active target.`;
setWorkflowStep("connect", {
status: `${card.dataset.connection} loaded. Catalog, draft labels, and inspector now reflect the active target.`,
});
});
});
@@ -1170,7 +1219,9 @@ schemaTree.addEventListener("click", (event) => {
}
syncSelection(item.dataset.selection);
statusMessage.textContent = `Selection changed to ${item.dataset.selection}. Inspector and workspace stay aligned.`;
setWorkflowStep("inspect", {
status: `Selection changed to ${item.dataset.selection}. Inspector and workspace stay aligned.`,
});
});
toolbarTabsContainer.addEventListener("click", (event) => {
@@ -1181,6 +1232,7 @@ toolbarTabsContainer.addEventListener("click", (event) => {
}
clearRunTimer();
setWorkflowStep("query", { syncTab: true });
setActiveTab("results");
setQuery(tab.dataset.query, true);
});
@@ -1191,6 +1243,21 @@ bottomTabs.forEach((tab) => {
});
});
workflowStepButtons.forEach((button) => {
button.addEventListener("click", () => {
const step = button.dataset.workflowStep;
const syncTab = step === "query" || step === "export";
const statusMap = {
connect: "Connect review active. Confirm target health, environment label, and workspace summary.",
inspect: "Inspect review active. Check schema tree, selection, and inspector metadata alignment.",
query: "Query review active. Validate SQL draft, execution banner, and results context together.",
export: "Export review active. Check default path, blocked states, and empty-result guidance.",
};
setWorkflowStep(step, { syncTab, status: statusMap[step] });
});
});
runQueryButton.addEventListener("click", () => {
startRunPreview();
});
@@ -1205,6 +1272,7 @@ cycleStateButton.addEventListener("click", () => {
function activateExport(format) {
clearRunTimer();
setWorkflowStep("export", { syncTab: true });
if (appState.activeState === "running") {
renderState();
@@ -1321,10 +1389,32 @@ document.addEventListener("keydown", (event) => {
return;
}
if (!commandPalette.hidden) {
return;
}
if (event.target === schemaSearch) {
return;
}
const workflowHotkeyMap = {
c: "connect",
i: "inspect",
q: "query",
e: "export",
};
const workflowStep = workflowHotkeyMap[event.key.toLowerCase()];
if (workflowStep && !event.metaKey && !event.ctrlKey) {
event.preventDefault();
setWorkflowStep(workflowStep, {
syncTab: workflowStep === "query" || workflowStep === "export",
status: `${workflowStep[0].toUpperCase()}${workflowStep.slice(1)} review active.`,
});
return;
}
if (event.key === "/") {
event.preventDefault();
schemaSearch.focus();