feat(usable): integrate current dbtool implementation snapshot
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
94
gui/prototype/app.js
vendored
94
gui/prototype/app.js
vendored
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user