fix(llm): add fetch-models endpoint, fix SQL Lab INSERT (client_id truncation, sync mode, target_column, timestamp normalization)
- Add POST /api/llm/providers/fetch-models route with LLMClient.fetch_models() - Add target_column to TranslationJob model/schema/service/orchestrator - Fix SQL Lab execute: truncate client_id to 11 chars (varchar(11)) - Switch SQL Lab to sync mode (runAsync: false) — no Celery workers - Fix polling: unwrap nested result from Superset query API - Fix ClickHouse timestamp: normalize float timestamps to YYYY-MM-DD
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
<!-- @BRIEF Component component: components/RepositoryDashboardGrid.svelte -->
|
||||
<!-- @LAYER UI -->
|
||||
<!--
|
||||
@COMPLEXITY: 3
|
||||
@SEMANTICS: dashboard, grid, selection, pagination
|
||||
@PURPOSE: Displays a grid of dashboards with selection and pagination.
|
||||
@LAYER: Component
|
||||
@@ -98,7 +97,7 @@
|
||||
);
|
||||
// [/SECTION]
|
||||
|
||||
// [DEF:handleSort:Function]
|
||||
// #region handleSort:Function [TYPE Function]
|
||||
// @PURPOSE: Toggles sort direction or changes sort column.
|
||||
// @PRE: column name is provided.
|
||||
// @POST: sortColumn and sortDirection state updated.
|
||||
@@ -110,9 +109,9 @@
|
||||
sortDirection = "asc";
|
||||
}
|
||||
}
|
||||
// [/DEF:handleSort:Function]
|
||||
// #endregion handleSort:Function
|
||||
|
||||
// [DEF:handleSelectionChange:Function]
|
||||
// #region handleSelectionChange:Function [TYPE Function]
|
||||
// @PURPOSE: Handles individual checkbox changes.
|
||||
// @PRE: dashboard ID and checked status provided.
|
||||
// @POST: selectedIds array updated.
|
||||
@@ -125,9 +124,9 @@
|
||||
}
|
||||
selectedIds = newSelected;
|
||||
}
|
||||
// [/DEF:handleSelectionChange:Function]
|
||||
// #endregion handleSelectionChange:Function
|
||||
|
||||
// [DEF:handleSelectAll:Function]
|
||||
// #region handleSelectAll:Function [TYPE Function]
|
||||
// @PURPOSE: Handles select all checkbox.
|
||||
// @PRE: checked status provided.
|
||||
// @POST: selectedIds array updated for all paginated items.
|
||||
@@ -144,9 +143,9 @@
|
||||
}
|
||||
selectedIds = newSelected;
|
||||
}
|
||||
// [/DEF:handleSelectAll:Function]
|
||||
// #endregion handleSelectAll:Function
|
||||
|
||||
// [DEF:goToPage:Function]
|
||||
// #region goToPage:Function [TYPE Function]
|
||||
// @PURPOSE: Changes current page.
|
||||
// @PRE: page index is provided.
|
||||
// @POST: currentPage state updated if within valid range.
|
||||
@@ -155,9 +154,9 @@
|
||||
currentPage = page;
|
||||
}
|
||||
}
|
||||
// [/DEF:goToPage:Function]
|
||||
// #endregion goToPage:Function
|
||||
|
||||
// [DEF:getRepositoryStatusToken:Function]
|
||||
// #region getRepositoryStatusToken:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Returns normalized repository status token for a dashboard.
|
||||
* @pre Dashboard exists.
|
||||
@@ -166,17 +165,17 @@
|
||||
function getRepositoryStatusToken(dashboardId: number): string {
|
||||
return repositoryStatusByDashboardId[dashboardId] || "loading";
|
||||
}
|
||||
// [/DEF:getRepositoryStatusToken:Function]
|
||||
// #endregion getRepositoryStatusToken:Function
|
||||
|
||||
// [DEF:isRepositoryReady:Function]
|
||||
// #region isRepositoryReady:Function [TYPE Function]
|
||||
// @PURPOSE: Determines whether git actions can run for a dashboard.
|
||||
function isRepositoryReady(dashboardId: number): boolean {
|
||||
const token = getRepositoryStatusToken(dashboardId);
|
||||
return token !== "loading" && token !== "no_repo" && token !== "error";
|
||||
}
|
||||
// [/DEF:isRepositoryReady:Function]
|
||||
// #endregion isRepositoryReady:Function
|
||||
|
||||
// [DEF:invalidateRepositoryStatuses:Function]
|
||||
// #region invalidateRepositoryStatuses:Function [TYPE Function]
|
||||
// @PURPOSE: Marks dashboard statuses as loading so they are refetched.
|
||||
function invalidateRepositoryStatuses(dashboardIds: number[]): void {
|
||||
if (dashboardIds.length === 0) return;
|
||||
@@ -186,9 +185,9 @@
|
||||
});
|
||||
repositoryStatusByDashboardId = nextStatuses;
|
||||
}
|
||||
// [/DEF:invalidateRepositoryStatuses:Function]
|
||||
// #endregion invalidateRepositoryStatuses:Function
|
||||
|
||||
// [DEF:resolveRepositoryStatusToken:Function]
|
||||
// #region resolveRepositoryStatusToken:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Converts git status payload into a stable UI status token.
|
||||
*/
|
||||
@@ -220,9 +219,9 @@
|
||||
|
||||
return hasChanges ? "changes" : "synced";
|
||||
}
|
||||
// [/DEF:resolveRepositoryStatusToken:Function]
|
||||
// #endregion resolveRepositoryStatusToken:Function
|
||||
|
||||
// [DEF:loadRepositoryStatuses:Function]
|
||||
// #region loadRepositoryStatuses:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Hydrates repository status map for dashboards in repository mode.
|
||||
*/
|
||||
@@ -279,9 +278,9 @@
|
||||
...Object.fromEntries(entries),
|
||||
};
|
||||
}
|
||||
// [/DEF:loadRepositoryStatuses:Function]
|
||||
// #endregion loadRepositoryStatuses:Function
|
||||
|
||||
// [DEF:runBulkGitAction:Function]
|
||||
// #region runBulkGitAction:Function [TYPE Function]
|
||||
// @PURPOSE: Executes git action for selected dashboards with limited parallelism.
|
||||
async function runBulkGitAction(
|
||||
actionToken: string,
|
||||
@@ -333,15 +332,15 @@
|
||||
bulkActionRunning = false;
|
||||
}
|
||||
}
|
||||
// [/DEF:runBulkGitAction:Function]
|
||||
// #endregion runBulkGitAction:Function
|
||||
|
||||
// [DEF:handleBulkSync:Function]
|
||||
// #region handleBulkSync:Function [TYPE Function]
|
||||
async function handleBulkSync(): Promise<void> {
|
||||
await runBulkGitAction("sync", (dashboardId) => gitService.sync(dashboardId, null, envId));
|
||||
}
|
||||
// [/DEF:handleBulkSync:Function]
|
||||
// #endregion handleBulkSync:Function
|
||||
|
||||
// [DEF:handleBulkCommit:Function]
|
||||
// #region handleBulkCommit:Function [TYPE Function]
|
||||
async function handleBulkCommit(): Promise<void> {
|
||||
const message = prompt($t.git?.commit_message);
|
||||
if (!message?.trim()) return;
|
||||
@@ -349,21 +348,21 @@
|
||||
gitService.commit(dashboardId, message.trim(), [], envId),
|
||||
);
|
||||
}
|
||||
// [/DEF:handleBulkCommit:Function]
|
||||
// #endregion handleBulkCommit:Function
|
||||
|
||||
// [DEF:handleBulkPull:Function]
|
||||
// #region handleBulkPull:Function [TYPE Function]
|
||||
async function handleBulkPull(): Promise<void> {
|
||||
await runBulkGitAction("pull", (dashboardId) => gitService.pull(dashboardId, envId));
|
||||
}
|
||||
// [/DEF:handleBulkPull:Function]
|
||||
// #endregion handleBulkPull:Function
|
||||
|
||||
// [DEF:handleBulkPush:Function]
|
||||
// #region handleBulkPush:Function [TYPE Function]
|
||||
async function handleBulkPush(): Promise<void> {
|
||||
await runBulkGitAction("push", (dashboardId) => gitService.push(dashboardId, envId));
|
||||
}
|
||||
// [/DEF:handleBulkPush:Function]
|
||||
// #endregion handleBulkPush:Function
|
||||
|
||||
// [DEF:handleBulkDelete:Function]
|
||||
// #region handleBulkDelete:Function [TYPE Function]
|
||||
// @PURPOSE: Removes selected repositories from storage and binding table.
|
||||
async function handleBulkDelete(): Promise<void> {
|
||||
if (!confirm($t.git?.confirm_delete_repo || "Удалить выбранные репозитории?")) return;
|
||||
@@ -374,9 +373,9 @@
|
||||
dashboards = dashboards.filter((dashboard) => !idsToDelete.includes(dashboard.id));
|
||||
selectedIds = [];
|
||||
}
|
||||
// [/DEF:handleBulkDelete:Function]
|
||||
// #endregion handleBulkDelete:Function
|
||||
|
||||
// [DEF:handleManageSelected:Function]
|
||||
// #region handleManageSelected:Function [TYPE Function]
|
||||
// @PURPOSE: Opens Git manager for exactly one selected dashboard.
|
||||
async function handleManageSelected(): Promise<void> {
|
||||
if (selectedIds.length !== 1) {
|
||||
@@ -390,9 +389,9 @@
|
||||
);
|
||||
openGitManagerForDashboard(selectedDashboard || null);
|
||||
}
|
||||
// [/DEF:handleManageSelected:Function]
|
||||
// #endregion handleManageSelected:Function
|
||||
|
||||
// [DEF:resolveDashboardRef:Function]
|
||||
// #region resolveDashboardRef:Function [TYPE Function]
|
||||
// @PURPOSE: Resolves dashboard slug from payload fields.
|
||||
// @PRE: Dashboard metadata is provided.
|
||||
// @POST: Returns slug string or null if unavailable.
|
||||
@@ -411,9 +410,9 @@
|
||||
if (!slugMatch?.[1]) return null;
|
||||
return decodeURIComponent(slugMatch[1]);
|
||||
}
|
||||
// [/DEF:resolveDashboardRef:Function]
|
||||
// #endregion resolveDashboardRef:Function
|
||||
|
||||
// [DEF:openGitManagerForDashboard:Function]
|
||||
// #region openGitManagerForDashboard:Function [TYPE Function]
|
||||
// @PURPOSE: Opens Git manager for provided dashboard metadata.
|
||||
function openGitManagerForDashboard(dashboard: DashboardMetadata | null): void {
|
||||
if (!dashboard) return;
|
||||
@@ -426,9 +425,9 @@
|
||||
gitDashboardTitle = dashboard.title || "";
|
||||
showGitManager = true;
|
||||
}
|
||||
// [/DEF:openGitManagerForDashboard:Function]
|
||||
// #endregion openGitManagerForDashboard:Function
|
||||
|
||||
// [DEF:handleInitializeRepositories:Function]
|
||||
// #region handleInitializeRepositories:Function [TYPE Function]
|
||||
// @PURPOSE: Opens Git manager from bulk actions to initialize selected repository.
|
||||
async function handleInitializeRepositories(): Promise<void> {
|
||||
if (selectedIds.length !== 1) {
|
||||
@@ -439,9 +438,9 @@
|
||||
const selectedDashboard = dashboards.find((dashboard) => dashboard.id === selectedDashboardId) || null;
|
||||
openGitManagerForDashboard(selectedDashboard);
|
||||
}
|
||||
// [/DEF:handleInitializeRepositories:Function]
|
||||
// #endregion handleInitializeRepositories:Function
|
||||
|
||||
// [DEF:getSortStatusValue:Function]
|
||||
// #region getSortStatusValue:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Returns sort value for status column based on mode.
|
||||
*/
|
||||
@@ -451,9 +450,9 @@
|
||||
}
|
||||
return String(dashboard.status || "").toLowerCase();
|
||||
}
|
||||
// [/DEF:getSortStatusValue:Function]
|
||||
// #endregion getSortStatusValue:Function
|
||||
|
||||
// [DEF:getStatusLabel:Function]
|
||||
// #region getStatusLabel:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Returns localized label for status column.
|
||||
*/
|
||||
@@ -464,9 +463,9 @@
|
||||
const token = getRepositoryStatusToken(dashboard.id);
|
||||
return $t.git?.repo_status?.[token] || token;
|
||||
}
|
||||
// [/DEF:getStatusLabel:Function]
|
||||
// #endregion getStatusLabel:Function
|
||||
|
||||
// [DEF:getStatusBadgeClass:Function]
|
||||
// #region getStatusBadgeClass:Function [TYPE Function]
|
||||
/**
|
||||
* @purpose Returns badge style for status column.
|
||||
*/
|
||||
@@ -487,7 +486,7 @@
|
||||
if (token === "diverged") return "bg-purple-100 text-purple-800";
|
||||
return "bg-rose-100 text-rose-800";
|
||||
}
|
||||
// [/DEF:getStatusBadgeClass:Function]
|
||||
// #endregion getStatusBadgeClass:Function
|
||||
|
||||
$effect(() => {
|
||||
dashboards;
|
||||
|
||||
Reference in New Issue
Block a user