From 3e9fbc36c7bd90da5130c3cb8702d4ce6d2a0846 Mon Sep 17 00:00:00 2001 From: Kohaku-Blueleaf <59680068+KohakuBlueleaf@users.noreply.github.com> Date: Mon, 27 Oct 2025 03:44:13 +0800 Subject: [PATCH] Re org kohakuboard ui routes --- src/kohaku-board-ui/src/App.vue | 15 +- src/kohaku-board-ui/src/pages/index.vue | 82 +- .../src/pages/projects/[project]/[id].vue | 1087 +++++++++++++++++ .../src/pages/projects/[project]/index.vue | 140 +++ .../src/pages/projects/index.vue | 75 ++ src/kohaku-board-ui/src/typed-router.d.ts | 15 + src/kohaku-board-ui/src/utils/api.js | 151 ++- 7 files changed, 1501 insertions(+), 64 deletions(-) create mode 100644 src/kohaku-board-ui/src/pages/projects/[project]/[id].vue create mode 100644 src/kohaku-board-ui/src/pages/projects/[project]/index.vue create mode 100644 src/kohaku-board-ui/src/pages/projects/index.vue diff --git a/src/kohaku-board-ui/src/App.vue b/src/kohaku-board-ui/src/App.vue index 30bb421..0ecbe1a 100644 --- a/src/kohaku-board-ui/src/App.vue +++ b/src/kohaku-board-ui/src/App.vue @@ -2,11 +2,13 @@ import { ref, onMounted } from "vue"; import { initializeSliderSync } from "@/composables/useSliderSync"; import { useAnimationPreference } from "@/composables/useAnimationPreference"; +import { getSystemInfo } from "@/utils/api"; const darkMode = ref(false); const { animationsEnabled, toggleAnimations } = useAnimationPreference(); +const systemInfo = ref(null); -onMounted(() => { +onMounted(async () => { const savedTheme = localStorage.getItem("theme"); darkMode.value = savedTheme === "dark" || @@ -15,6 +17,13 @@ onMounted(() => { // Initialize global slider synchronization initializeSliderSync(); + + // Fetch system info for mode detection + try { + systemInfo.value = await getSystemInfo(); + } catch (error) { + console.error("Failed to fetch system info:", error); + } }); function toggleDarkMode() { @@ -59,13 +68,13 @@ function updateTheme() { to="/" class="px-3 py-1.5 rounded-md text-sm font-medium transition-colors text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 hover:text-blue-600 dark:hover:text-blue-400" > - Dashboard + Projects - Experiments + Experiments (Legacy) diff --git a/src/kohaku-board-ui/src/pages/index.vue b/src/kohaku-board-ui/src/pages/index.vue index 0e080e2..fb1b253 100644 --- a/src/kohaku-board-ui/src/pages/index.vue +++ b/src/kohaku-board-ui/src/pages/index.vue @@ -1,24 +1,25 @@ + + diff --git a/src/kohaku-board-ui/src/pages/projects/[project]/index.vue b/src/kohaku-board-ui/src/pages/projects/[project]/index.vue new file mode 100644 index 0000000..d5bb268 --- /dev/null +++ b/src/kohaku-board-ui/src/pages/projects/[project]/index.vue @@ -0,0 +1,140 @@ + + + diff --git a/src/kohaku-board-ui/src/pages/projects/index.vue b/src/kohaku-board-ui/src/pages/projects/index.vue new file mode 100644 index 0000000..da4c82b --- /dev/null +++ b/src/kohaku-board-ui/src/pages/projects/index.vue @@ -0,0 +1,75 @@ + + + diff --git a/src/kohaku-board-ui/src/typed-router.d.ts b/src/kohaku-board-ui/src/typed-router.d.ts index 43918f9..ebf3b90 100644 --- a/src/kohaku-board-ui/src/typed-router.d.ts +++ b/src/kohaku-board-ui/src/typed-router.d.ts @@ -22,6 +22,9 @@ declare module 'vue-router/auto-routes' { '/dashboard/[id]': RouteRecordInfo<'/dashboard/[id]', '/dashboard/:id', { id: ParamValue }, { id: ParamValue }>, '/experiments/': RouteRecordInfo<'/experiments/', '/experiments', Record, Record>, '/experiments/[id]': RouteRecordInfo<'/experiments/[id]', '/experiments/:id', { id: ParamValue }, { id: ParamValue }>, + '/projects/': RouteRecordInfo<'/projects/', '/projects', Record, Record>, + '/projects/[project]/': RouteRecordInfo<'/projects/[project]/', '/projects/:project', { project: ParamValue }, { project: ParamValue }>, + '/projects/[project]/[id]': RouteRecordInfo<'/projects/[project]/[id]', '/projects/:project/:id', { project: ParamValue, id: ParamValue }, { project: ParamValue, id: ParamValue }>, } /** @@ -51,6 +54,18 @@ declare module 'vue-router/auto-routes' { routes: '/experiments/[id]' views: never } + 'src/pages/projects/index.vue': { + routes: '/projects/' + views: never + } + 'src/pages/projects/[project]/index.vue': { + routes: '/projects/[project]/' + views: never + } + 'src/pages/projects/[project]/[id].vue': { + routes: '/projects/[project]/[id]' + views: never + } } /** diff --git a/src/kohaku-board-ui/src/utils/api.js b/src/kohaku-board-ui/src/utils/api.js index 6116272..73c82aa 100644 --- a/src/kohaku-board-ui/src/utils/api.js +++ b/src/kohaku-board-ui/src/utils/api.js @@ -74,7 +74,43 @@ export async function generateMockData(config) { } // ============================================================================ -// BOARDS API - Real data from file system +// SYSTEM API - Mode detection +// ============================================================================ + +/** + * Get system information (mode, auth requirements, user info) + * @returns {Promise} System info + */ +export async function getSystemInfo() { + const response = await api.get("/system/info"); + return response.data; +} + +// ============================================================================ +// PROJECTS API - Project and run management +// ============================================================================ + +/** + * Fetch all accessible projects + * @returns {Promise} Projects list + */ +export async function fetchProjects() { + const response = await api.get("/projects"); + return response.data; +} + +/** + * Fetch runs in a project + * @param {string} projectName - Project name + * @returns {Promise} Runs list with project info + */ +export async function fetchProjectRuns(projectName) { + const response = await api.get(`/projects/${projectName}/runs`); + return response.data; +} + +// ============================================================================ +// BOARDS API - Real data from file system (LEGACY - kept for compatibility) // ============================================================================ /** @@ -106,6 +142,119 @@ export async function fetchBoardSummary(boardId) { return response.data; } +// ============================================================================ +// RUN DATA API - Project-based run access +// ============================================================================ + +/** + * Fetch run summary + * @param {string} project - Project name + * @param {string} runId - Run ID + * @returns {Promise} Run summary + */ +export async function fetchRunSummary(project, runId) { + const response = await api.get(`/projects/${project}/runs/${runId}/summary`); + return response.data; +} + +/** + * Fetch available scalar metrics for a run + * @param {string} project - Project name + * @param {string} runId - Run ID + * @returns {Promise} Object with metrics array + */ +export async function fetchRunScalars(project, runId) { + const response = await api.get(`/projects/${project}/runs/${runId}/scalars`); + return response.data; +} + +/** + * Fetch scalar data for a specific metric + * @param {string} project - Project name + * @param {string} runId - Run ID + * @param {string} metric - Metric name + * @param {Object} params - Query parameters (limit, etc.) + * @returns {Promise} Object with metric name and data array + */ +export async function fetchRunScalarData(project, runId, metric, params = {}) { + const response = await api.get( + `/projects/${project}/runs/${runId}/scalars/${metric}`, + { + params, + }, + ); + return response.data; +} + +/** + * Fetch available media log names + * @param {string} project - Project name + * @param {string} runId - Run ID + * @returns {Promise} Object with media array + */ +export async function fetchRunMedia(project, runId) { + const response = await api.get(`/projects/${project}/runs/${runId}/media`); + return response.data; +} + +/** + * Fetch media data for a specific log name + * @param {string} project - Project name + * @param {string} runId - Run ID + * @param {string} name - Media log name + * @param {Object} params - Query parameters (limit, etc.) + * @returns {Promise} Object with name and data array + */ +export async function fetchRunMediaData(project, runId, name, params = {}) { + const response = await api.get( + `/projects/${project}/runs/${runId}/media/${name}`, + { + params, + }, + ); + return response.data; +} + +/** + * Get media file URL + * @param {string} project - Project name + * @param {string} runId - Run ID + * @param {string} filename - Media filename + * @returns {string} Media file URL + */ +export function getRunMediaFileUrl(project, runId, filename) { + return `/api/projects/${project}/runs/${runId}/media/files/${filename}`; +} + +/** + * Fetch available table log names + * @param {string} project - Project name + * @param {string} runId - Run ID + * @returns {Promise} Object with tables array + */ +export async function fetchRunTables(project, runId) { + const response = await api.get(`/projects/${project}/runs/${runId}/tables`); + return response.data; +} + +/** + * Fetch table data for a specific log name + * @param {string} project - Project name + * @param {string} runId - Run ID + * @param {string} name - Table log name + * @param {Object} params - Query parameters (limit, etc.) + * @returns {Promise} Object with name and data array + */ +export async function fetchRunTableData(project, runId, name, params = {}) { + const response = await api.get( + `/projects/${project}/runs/${runId}/tables/${name}`, + { + params, + }, + ); + return response.data; +} + /** * Fetch available scalar metrics for a board * @param {string} boardId - Board identifier