Improve dashboard LLM validation UX and report flow

This commit is contained in:
2026-02-26 17:53:41 +03:00
parent 669ed92642
commit b85b19f066
10 changed files with 1199 additions and 30 deletions

View File

@@ -80,7 +80,7 @@ function getAuthHeaders() {
// @POST: Returns Promise resolving to JSON data or throws on error.
// @PARAM: endpoint (string) - API endpoint.
// @RETURN: Promise<any> - JSON response.
async function fetchApi(endpoint) {
async function fetchApi(endpoint) {
try {
console.log(`[api.fetchApi][Action] Fetching from context={{'endpoint': '${endpoint}'}}`);
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
@@ -98,7 +98,37 @@ async function fetchApi(endpoint) {
throw error;
}
}
// [/DEF:fetchApi:Function]
// [/DEF:fetchApi:Function]
// [DEF:fetchApiBlob:Function]
// @PURPOSE: Generic GET wrapper for binary payloads.
// @PRE: endpoint string is provided.
// @POST: Returns Blob or throws on error.
async function fetchApiBlob(endpoint, options = {}) {
const notifyError = options.notifyError !== false;
try {
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
headers: getAuthHeaders()
});
if (response.status === 202) {
const payload = await response.json().catch(() => ({ message: "Resource is being prepared" }));
const error = new Error(payload?.message || "Resource is being prepared");
error.status = 202;
throw error;
}
if (!response.ok) {
throw await buildApiError(response);
}
return await response.blob();
} catch (error) {
console.error(`[api.fetchApiBlob][Coherence:Failed] Error fetching blob from ${endpoint}:`, error);
if (notifyError) {
notifyApiError(error);
}
throw error;
}
}
// [/DEF:fetchApiBlob:Function]
// [DEF:postApi:Function]
// @PURPOSE: Generic POST request wrapper.
@@ -183,10 +213,20 @@ export const api = {
const query = params.toString();
return fetchApi(`/tasks${query ? `?${query}` : ''}`);
},
getTask: (taskId) => fetchApi(`/tasks/${taskId}`),
createTask: (pluginId, params) => postApi('/tasks', { plugin_id: pluginId, params }),
getTask: (taskId) => fetchApi(`/tasks/${taskId}`),
getTaskLogs: (taskId, options = {}) => {
const params = new URLSearchParams();
if (options.level) params.append('level', options.level);
if (options.source) params.append('source', options.source);
if (options.search) params.append('search', options.search);
if (options.offset != null) params.append('offset', String(options.offset));
if (options.limit != null) params.append('limit', String(options.limit));
const query = params.toString();
return fetchApi(`/tasks/${taskId}/logs${query ? `?${query}` : ''}`);
},
createTask: (pluginId, params) => postApi('/tasks', { plugin_id: pluginId, params }),
// Settings
// Settings
getSettings: () => fetchApi('/settings'),
updateGlobalSettings: (settings) => requestApi('/settings/global', 'PATCH', settings),
getEnvironments: () => fetchApi('/settings/environments'),
@@ -197,8 +237,9 @@ export const api = {
updateEnvironmentSchedule: (id, schedule) => requestApi(`/environments/${id}/schedule`, 'PUT', schedule),
getStorageSettings: () => fetchApi('/settings/storage'),
updateStorageSettings: (storage) => requestApi('/settings/storage', 'PUT', storage),
getEnvironmentsList: () => fetchApi('/environments'),
getEnvironmentDatabases: (id) => fetchApi(`/environments/${id}/databases`),
getEnvironmentsList: () => fetchApi('/environments'),
getLlmStatus: () => fetchApi('/llm/status'),
getEnvironmentDatabases: (id) => fetchApi(`/environments/${id}/databases`),
// Dashboards
getDashboards: (envId, options = {}) => {
@@ -209,6 +250,18 @@ export const api = {
return fetchApi(`/dashboards?${params.toString()}`);
},
getDashboardDetail: (envId, dashboardId) => fetchApi(`/dashboards/${dashboardId}?env_id=${envId}`),
getDashboardTaskHistory: (envId, dashboardId, options = {}) => {
const params = new URLSearchParams();
if (envId) params.append('env_id', envId);
if (options.limit) params.append('limit', options.limit);
return fetchApi(`/dashboards/${dashboardId}/tasks?${params.toString()}`);
},
getDashboardThumbnail: (envId, dashboardId, options = {}) => {
const params = new URLSearchParams();
params.append('env_id', envId);
if (options.force != null) params.append('force', String(Boolean(options.force)));
return fetchApiBlob(`/dashboards/${dashboardId}/thumbnail?${params.toString()}`, { notifyError: false });
},
getDatabaseMappings: (sourceEnvId, targetEnvId) => fetchApi(`/dashboards/db-mappings?source_env_id=${sourceEnvId}&target_env_id=${targetEnvId}`),
// Datasets