diff --git a/frontend/src/routes/dashboards/[id]/+page.svelte b/frontend/src/routes/dashboards/[id]/+page.svelte
index 998ae417..b72b93e0 100644
--- a/frontend/src/routes/dashboards/[id]/+page.svelte
+++ b/frontend/src/routes/dashboards/[id]/+page.svelte
@@ -46,16 +46,20 @@
import BranchSelector from "../../../components/git/BranchSelector.svelte";
import CommitHistory from "../../../components/git/CommitHistory.svelte";
import GitManager from "../../../components/git/GitManager.svelte";
+ import DashboardHeader from "./components/DashboardHeader.svelte";
+ import DashboardGitManager from "./components/DashboardGitManager.svelte";
+ import DashboardLinkedResources from "./components/DashboardLinkedResources.svelte";
+ import DashboardTaskHistory from "./components/DashboardTaskHistory.svelte";
let dashboardRef = $derived(page.params.id);
let envId = $derived(page.url.searchParams.get("env_id") || "");
+ let dashboard = $state(null);
let gitDashboardRef = $derived(dashboard?.slug || dashboardRef || "");
let resolvedDashboardId = $derived(
dashboard?.id ??
(/^\d+$/.test(String(dashboardRef || "")) ? Number(dashboardRef) : null),
);
- let dashboard = $state(null);
let isLoading = $state(true);
let error = $state(null);
let taskHistory = $state([]);
@@ -531,87 +535,26 @@
-
-
-
-
- {$t.common?.back}
-
-
-
-
- {dashboard?.title || $t.dashboard?.overview}
-
- {#if hasGitRepository() && gitDashboardRef}
-
-
-
- {/if}
-
-
-
- {$t.common?.id}: {resolvedDashboardId ?? dashboardRef}{#if dashboard?.slug} • {dashboard.slug}{/if}
- |
-
-
- Git: {gitMeta.label}
- {#if gitStatus?.ahead_count > 0}
- ({gitStatus.ahead_count})
- {/if}
-
-
-
-
-
- (showGitManager = true)}
- >
- {$t.git?.management || "Manage Git"}
-
-
- {isStartingBackup
- ? $t.common?.loading || "Loading..."
- : $t.dashboard?.run_backup || "Run backup"}
-
-
- {isStartingValidation
- ? $t.common?.loading || "Loading..."
- : $t.dashboard?.run_llm_check || "Run LLM check"}
-
-
- {$t.common?.refresh}
-
-
-
+
{#if !llmReady}
-
-
-
- {$t.git?.management || "Git Repository"}
-
-
- {$t.common?.refresh || "Refresh"}
-
-
-
- {#if isGitStatusLoading}
-
- {#each Array(3) as _}
-
- {/each}
-
- {:else if gitStatusError}
-
- {gitStatusError}
-
- {:else if !hasGitRepository()}
-
-
- {$t.git?.not_linked || "Этот дашборд еще не привязан к Git-репозиторию."}
-
-
(showGitManager = true)}
- >
- Инициализировать Git-репозиторий
-
-
- {:else}
-
-
- {#if gitSyncState === "CHANGES"}
- Обнаружены изменения конфигурации в Superset.
- {:else}
- Конфигурация Superset совпадает с веткой {gitStatus?.current_branch || "main"}.
- {/if}
-
-
-
-
- charts: {changedChartsCount}
-
-
- datasets: {changedDatasetsCount}
-
-
- files: {allChangedFiles().length}
-
-
-
-
-
- {isSyncingGit
- ? $t.common?.loading || "Loading..."
- : "Синхронизировать и зафиксировать"}
-
-
- {isGitDiffLoading ? $t.common?.loading || "Loading..." : "Показать diff"}
-
-
-
-
-
- {isPullingGit ? $t.common?.loading || "Loading..." : $t.git?.pull || "Pull"}
-
-
- {#if isPushingGit}
- {$t.common?.loading || "Loading..."}
- {:else}
- {$t.git?.push || "Push"}{#if gitStatus?.ahead_count > 0} ({gitStatus.ahead_count}){/if}
- {/if}
-
-
-
- {#if gitDiffPreview}
-
- {/if}
-
- {/if}
-
+
@@ -853,111 +712,11 @@
{#if activeTab === "resources"}
- {#if dashboard.description}
-
-
- {$t.dashboard?.overview}
-
-
{dashboard.description}
-
- {/if}
-
-
-
-
- {$t.dashboard?.charts}
-
-
- {#if dashboard.charts && dashboard.charts.length > 0}
-
-
-
-
-
- {$t.settings?.type_chart}
-
-
- {$t.nav?.datasets}
-
-
- {$t.dashboard?.overview}
-
-
- {$t.dashboard?.last_modified}
-
-
-
-
- {#each dashboard.charts as chart}
-
-
- {chart.title}
-
- ID: {chart.id}{#if chart.viz_type} • {chart.viz_type}{/if}
-
-
-
- {#if chart.dataset_id}
- openDataset(chart.dataset_id)}
- title={`${$t.datasets?.table_name} ${chart.dataset_id}`}
- >
- {$t.nav?.datasets}
- {chart.dataset_id}
-
-
- {:else}
- -
- {/if}
-
- {chart.overview || "-"}
- {formatDate(chart.last_modified)}
-
- {/each}
-
-
-
- {:else}
-
- {$t.dashboard?.no_charts}
-
- {/if}
-
-
-
-
-
{$t.nav?.datasets}
-
- {#if dashboard.datasets && dashboard.datasets.length > 0}
-
- {#each dashboard.datasets as dataset}
-
openDataset(dataset.id)}
- >
-
-
- {dataset.table_name}
-
-
- {dataset.overview || `${dataset.schema || ""}.${dataset.table_name}`}
- {#if dataset.database} • {dataset.database}{/if}
-
-
-
- {formatDate(dataset.last_modified)}
-
-
-
- {/each}
-
- {:else}
-
- {$t.dashboard?.no_datasets}
-
- {/if}
-
+
{:else if activeTab === "git-history"}
{#if hasGitRepository() && gitDashboardRef}
@@ -967,87 +726,18 @@
{/if}
{:else}
-
-
-
- {$t.tasks?.recent || "Recent tasks"}
-
-
- {$t.common?.refresh || "Refresh"}
-
-
- {#if isTaskHistoryLoading}
-
- {#each Array(4) as _}
-
- {/each}
-
- {:else if taskHistoryError}
-
- {taskHistoryError}
-
- {:else if taskHistory.length === 0}
-
- {$t.tasks?.select_task || "No backup/LLM tasks yet"}
-
- {:else}
-
-
-
-
- {$t.common?.type || "Type"}
- {$t.common?.status || "Status"}
- {$t.tasks?.result || "Check"}
- {$t.common?.started || "Started"}
- {$t.common?.finished || "Finished"}
- {$t.common?.actions || "Actions"}
-
-
-
- {#each taskHistory as task}
- {@const validation = getValidationStatus(task)}
-
- {toTaskTypeLabel(task.plugin_id)}
-
-
- {task.status}
-
-
-
-
- {#if validation.icon}
-
- {validation.icon}
-
- {/if}
- {validation.label}
-
-
- {formatDate(task.started_at)}
- {formatDate(task.finished_at)}
-
-
- {#if task.plugin_id === "llm_dashboard_validation"}
- openLlmReport(task.id)}
- >
- {$t.tasks?.open_llm_report || "LLM report"}
-
- {/if}
-
-
-
- {/each}
-
-
-
- {/if}
-
+
{/if}
diff --git a/frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte b/frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte
new file mode 100644
index 00000000..6d24ebc3
--- /dev/null
+++ b/frontend/src/routes/dashboards/[id]/components/DashboardGitManager.svelte
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+ {$t.git?.management || "Git Repository"}
+
+
+ {$t.common?.refresh || "Refresh"}
+
+
+
+ {#if isGitStatusLoading}
+
+ {#each Array(3) as _}
+
+ {/each}
+
+ {:else if gitStatusError}
+
+ {gitStatusError}
+
+ {:else if !hasGitRepo}
+
+
+ {$t.git?.not_linked || "Этот дашборд еще не привязан к Git-репозиторию."}
+
+
(showGitManager = true)}
+ >
+ Инициализировать Git-репозиторий
+
+
+ {:else}
+
+
+ {#if gitSyncState === "CHANGES"}
+ Обнаружены изменения конфигурации в Superset.
+ {:else}
+ Конфигурация Superset совпадает с веткой {gitStatus?.current_branch || "main"}.
+ {/if}
+
+
+
+
+ charts: {changedChartsCount}
+
+
+ datasets: {changedDatasetsCount}
+
+
+ files: {allChangedFiles.length}
+
+
+
+
+
+ {isSyncingGit ? $t.common?.loading || "Loading..." : "Синхронизировать и зафиксировать"}
+
+
+ {isGitDiffLoading ? $t.common?.loading || "Loading..." : "Показать diff"}
+
+
+
+
+
+ {isPullingGit ? $t.common?.loading || "Loading..." : $t.git?.pull || "Pull"}
+
+
+ {#if isPushingGit}
+ {$t.common?.loading || "Loading..."}
+ {:else}
+ {$t.git?.push || "Push"}{#if gitStatus?.ahead_count > 0} ({gitStatus.ahead_count}){/if}
+ {/if}
+
+
+
+ {#if gitDiffPreview}
+
+ {/if}
+
+ {/if}
+
+
\ No newline at end of file
diff --git a/frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte b/frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte
new file mode 100644
index 00000000..81c68f9f
--- /dev/null
+++ b/frontend/src/routes/dashboards/[id]/components/DashboardHeader.svelte
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+ {$t.common?.back}
+
+
+
+
+ {dashboard?.title || $t.dashboard?.overview}
+
+ {#if hasGitRepo && gitDashboardRef}
+
+
+
+ {/if}
+
+
+
+ {$t.common?.id}: {resolvedDashboardId ?? dashboardRef}{#if dashboard?.slug} • {dashboard.slug}{/if}
+ |
+
+
+ Git: {gitMeta.label}
+ {#if gitStatus?.ahead_count > 0}
+ ({gitStatus.ahead_count})
+ {/if}
+
+
+
+
+
+ (showGitManager = true)}
+ >
+ {$t.git?.management || "Manage Git"}
+
+
+ {isStartingBackup ? $t.common?.loading || "Loading..." : $t.dashboard?.run_backup || "Run backup"}
+
+
+ {isStartingValidation ? $t.common?.loading || "Loading..." : $t.dashboard?.run_llm_check || "Run LLM check"}
+
+
+ {$t.common?.refresh}
+
+
+
+
\ No newline at end of file
diff --git a/frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte b/frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte
new file mode 100644
index 00000000..135b914f
--- /dev/null
+++ b/frontend/src/routes/dashboards/[id]/components/DashboardLinkedResources.svelte
@@ -0,0 +1,123 @@
+
+
+
+{#if dashboard.description}
+
+
+ {$t.dashboard?.overview}
+
+
{dashboard.description}
+
+{/if}
+
+
+
+
+ {$t.dashboard?.charts}
+
+
+ {#if dashboard.charts && dashboard.charts.length > 0}
+
+
+
+
+
+ {$t.settings?.type_chart}
+
+
+ {$t.nav?.datasets}
+
+
+ {$t.dashboard?.overview}
+
+
+ {$t.dashboard?.last_modified}
+
+
+
+
+ {#each dashboard.charts as chart}
+
+
+ {chart.title}
+
+ ID: {chart.id}{#if chart.viz_type} • {chart.viz_type}{/if}
+
+
+
+ {#if chart.dataset_id}
+ openDataset(chart.dataset_id)}
+ title={`${$t.datasets?.table_name} ${chart.dataset_id}`}
+ >
+ {$t.nav?.datasets}
+ {chart.dataset_id}
+
+
+ {:else}
+ -
+ {/if}
+
+ {chart.overview || "-"}
+ {formatDate(chart.last_modified)}
+
+ {/each}
+
+
+
+ {:else}
+
+ {$t.dashboard?.no_charts}
+
+ {/if}
+
+
+
+
+
{$t.nav?.datasets}
+
+ {#if dashboard.datasets && dashboard.datasets.length > 0}
+
+ {#each dashboard.datasets as dataset}
+
openDataset(dataset.id)}
+ >
+
+
+ {dataset.table_name}
+
+
+ {dataset.overview || `${dataset.schema || ""}.${dataset.table_name}`}
+ {#if dataset.database} • {dataset.database}{/if}
+
+
+
+ {formatDate(dataset.last_modified)}
+
+
+
+ {/each}
+
+ {:else}
+
+ {$t.dashboard?.no_datasets}
+
+ {/if}
+
+
\ No newline at end of file
diff --git a/frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte b/frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte
new file mode 100644
index 00000000..857ea9b6
--- /dev/null
+++ b/frontend/src/routes/dashboards/[id]/components/DashboardTaskHistory.svelte
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ {$t.tasks?.recent || "Recent tasks"}
+
+
+ {$t.common?.refresh || "Refresh"}
+
+
+ {#if isTaskHistoryLoading}
+
+ {#each Array(4) as _}
+
+ {/each}
+
+ {:else if taskHistoryError}
+
+ {taskHistoryError}
+
+ {:else if taskHistory.length === 0}
+
+ {$t.tasks?.select_task || "No backup/LLM tasks yet"}
+
+ {:else}
+
+
+
+
+ {$t.common?.type || "Type"}
+ {$t.common?.status || "Status"}
+ {$t.tasks?.result || "Check"}
+ {$t.common?.started || "Started"}
+ {$t.common?.finished || "Finished"}
+ {$t.common?.actions || "Actions"}
+
+
+
+ {#each taskHistory as task}
+ {@const validation = getValidationStatus(task)}
+
+ {toTaskTypeLabel(task.plugin_id)}
+
+
+ {task.status}
+
+
+
+
+ {#if validation.icon}
+
+ {validation.icon}
+
+ {/if}
+ {validation.label}
+
+
+ {formatDate(task.started_at)}
+ {formatDate(task.finished_at)}
+
+
+ {#if task.plugin_id === "llm_dashboard_validation"}
+ openLlmReport(task.id)}
+ >
+ {$t.tasks?.open_llm_report || "LLM report"}
+
+ {/if}
+
+
+
+ {/each}
+
+
+
+ {/if}
+
+
\ No newline at end of file