diff --git a/understand-anything-plugin/packages/dashboard/src/App.tsx b/understand-anything-plugin/packages/dashboard/src/App.tsx index cd1b33c79..db8c4938a 100644 --- a/understand-anything-plugin/packages/dashboard/src/App.tsx +++ b/understand-anything-plugin/packages/dashboard/src/App.tsx @@ -207,7 +207,7 @@ function Dashboard({ accessToken }: { accessToken: string }) { }, [setDomainGraph]); return ( - + s.toggleShowFunctionsInClassView); const [showKeyboardHelp, setShowKeyboardHelp] = useState(false); const [sidebarTab, setSidebarTab] = useState("info"); + const sidebarPosition = useDashboardStore((s) => s.sidebarPosition); + const setSidebarPosition = useDashboardStore((s) => s.setSidebarPosition); + const sidebarCollapsed = useDashboardStore((s) => s.sidebarCollapsed); + const toggleSidebarCollapsed = useDashboardStore((s) => s.toggleSidebarCollapsed); + const nodeHistory = useDashboardStore((s) => s.nodeHistory); + const goBackNode = useDashboardStore((s) => s.goBackNode); const [showOnboarding, setShowOnboarding] = useState(shouldShowOnboarding); const dismissOnboarding = useCallback((remember: boolean) => { if (remember && typeof window !== "undefined") { @@ -420,6 +426,41 @@ function DashboardContent({ {tab === "info" ? t.sidebar.info : t.sidebar.files} ))} + {/* Sidebar position & collapse controls */} +
+ + +
{sidebarTab === "files" ? : infoSidebarContent} @@ -635,6 +676,38 @@ function DashboardContent({ {/* Main content: Graph + Sidebar */}
+ {/* Sidebar on the left side */} + {sidebarPosition === "left" && !sidebarCollapsed && ( + + )} + {/* Collapsed sidebar edge button */} + {sidebarCollapsed && sidebarPosition === "left" && ( + + )} + {sidebarCollapsed && sidebarPosition === "right" && ( + + )} + {/* Graph area */}
{viewMode === "knowledge" ? ( @@ -649,10 +722,12 @@ function DashboardContent({
- {/* Right sidebar — telescopes at narrower widths */} - + {/* Sidebar on the right side */} + {sidebarPosition === "right" && !sidebarCollapsed && ( + + )} {/* Code viewer slide-up overlay (collapsed state) */} {codeViewerOpen && !codeViewerExpanded && ( diff --git a/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx b/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx index 592fb1a3e..5430b805b 100644 --- a/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx +++ b/understand-anything-plugin/packages/dashboard/src/components/CodeViewer.tsx @@ -67,6 +67,9 @@ export default function CodeViewer({ const viewMode = useDashboardStore((s) => s.viewMode); const codeViewerNodeId = useDashboardStore((s) => s.codeViewerNodeId); const closeCodeViewer = useDashboardStore((s) => s.closeCodeViewer); + const nodeHistory = useDashboardStore((s) => s.nodeHistory); + const goBackNode = useDashboardStore((s) => s.goBackNode); + const openCodeViewer = useDashboardStore((s) => s.openCodeViewer); const activeGraph = viewMode === "domain" && domainGraph ? domainGraph : graph; // Files tab always builds its tree from the structural graph, so a node ID opened from // there may not exist in the active (domain) graph — fall back to the structural graph. @@ -167,6 +170,24 @@ export default function CodeViewer({ )}
+ {/* Go back button — navigate to previous node in history */} + {nodeHistory.length > 0 && ( + + )} {onExpand && (
+ + {/* Language */} +
+
+ {t.common.language} +
+
+ {LANGUAGE_OPTIONS.map((opt) => ( + + ))} +
+
)} diff --git a/understand-anything-plugin/packages/dashboard/src/contexts/I18nContext.tsx b/understand-anything-plugin/packages/dashboard/src/contexts/I18nContext.tsx index 08adb7b91..8b69a0a30 100644 --- a/understand-anything-plugin/packages/dashboard/src/contexts/I18nContext.tsx +++ b/understand-anything-plugin/packages/dashboard/src/contexts/I18nContext.tsx @@ -1,10 +1,11 @@ -import { createContext, useContext, useMemo, type ReactNode } from "react"; +import { createContext, useCallback, useContext, useMemo, type ReactNode } from "react"; import { getLocale, resolveLocaleKey, type Locale, type LocaleKey } from "../locales"; interface I18nContextValue { locale: Locale; localeKey: LocaleKey; t: Locale; + setLanguage: (lang: string) => void; } const I18nContext = createContext(null); @@ -19,21 +20,31 @@ export function useI18n(): I18nContextValue { export function I18nProvider({ language, + onLanguageChange, children, }: { language?: string; + onLanguageChange?: (lang: string) => void; children: ReactNode; }) { const localeKey = useMemo(() => resolveLocaleKey(language), [language]); const locale = useMemo(() => getLocale(localeKey), [localeKey]); + const setLanguage = useCallback( + (lang: string) => { + onLanguageChange?.(lang); + }, + [onLanguageChange] + ); + const value = useMemo( () => ({ locale, localeKey, t: locale, + setLanguage, }), - [locale, localeKey] + [locale, localeKey, setLanguage] ); return ( diff --git a/understand-anything-plugin/packages/dashboard/src/locales/en.ts b/understand-anything-plugin/packages/dashboard/src/locales/en.ts index 837771821..cae513811 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/en.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/en.ts @@ -21,6 +21,7 @@ export const en = { pressKeyboard: "Press ? for keyboard shortcuts", path: "Path", theme: "Theme", + language: "Language", }, projectOverview: { nodes: "Nodes", @@ -81,6 +82,10 @@ export const en = { sidebar: { info: "Info", files: "Files", + moveLeft: "Move sidebar left", + moveRight: "Move sidebar right", + collapse: "Collapse sidebar", + expand: "Expand sidebar", }, mobile: { graph: "Graph", @@ -179,6 +184,7 @@ export const en = { closeExpanded: "Close expanded code viewer", closeViewer: "Close code viewer", sourceUnavailable: "Source unavailable", + goBack: "Go back", }, customNode: { tested: "Tested", diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ja.ts b/understand-anything-plugin/packages/dashboard/src/locales/ja.ts index e222d266d..809056b10 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/ja.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/ja.ts @@ -21,6 +21,7 @@ export const ja = { pressKeyboard: "? を押してキーボードショートカットを表示", path: "パス", theme: "テーマ", + language: "言語", }, projectOverview: { nodes: "ノード", @@ -81,6 +82,10 @@ export const ja = { sidebar: { info: "情報", files: "ファイル", + moveLeft: "サイドバーを左に移動", + moveRight: "サイドバーを右に移動", + collapse: "サイドバーを折りたたむ", + expand: "サイドバーを展開", }, mobile: { graph: "グラフ", @@ -179,6 +184,7 @@ export const ja = { closeExpanded: "展開したコードビューアを閉じる", closeViewer: "コードビューアを閉じる", sourceUnavailable: "ソースが利用できません", + goBack: "戻る", }, customNode: { tested: "テスト済み", diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ko.ts b/understand-anything-plugin/packages/dashboard/src/locales/ko.ts index de894a795..8313b588b 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/ko.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/ko.ts @@ -21,6 +21,7 @@ export const ko = { pressKeyboard: "? 키를 눌러 키보드 단축키 보기", path: "경로", theme: "테마", + language: "언어", }, projectOverview: { nodes: "노드", @@ -81,6 +82,10 @@ export const ko = { sidebar: { info: "정보", files: "파일", + moveLeft: "사이드바 왼쪽으로 이동", + moveRight: "사이드바 오른쪽으로 이동", + collapse: "사이드바 축소", + expand: "사이드바 확장", }, mobile: { graph: "그래프", @@ -179,6 +184,7 @@ export const ko = { closeExpanded: "확장된 코드 뷰어 닫기", closeViewer: "코드 뷰어 닫기", sourceUnavailable: "소스 사용 불가", + goBack: "돌아가기", }, customNode: { tested: "테스트됨", diff --git a/understand-anything-plugin/packages/dashboard/src/locales/ru.ts b/understand-anything-plugin/packages/dashboard/src/locales/ru.ts index 27cc55461..35661229c 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/ru.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/ru.ts @@ -21,6 +21,7 @@ export const ru = { pressKeyboard: "Нажмите ? для горячих клавиш", path: "Путь", theme: "Тема", + language: "Язык", }, projectOverview: { nodes: "Узлы", @@ -81,6 +82,10 @@ export const ru = { sidebar: { info: "Информация", files: "Файлы", + moveLeft: "Переместить влево", + moveRight: "Переместить вправо", + collapse: "Свернуть", + expand: "Развернуть", }, mobile: { graph: "Граф", @@ -179,6 +184,7 @@ export const ru = { closeExpanded: "Закрыть расширенный просмотрщик кода", closeViewer: "Закрыть просмотрщик кода", sourceUnavailable: "Исходный код недоступен", + goBack: "Назад", }, customNode: { tested: "Покрыт тестами", diff --git a/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts b/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts index 2ffab4820..39dd5922d 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/zh-TW.ts @@ -21,6 +21,7 @@ export const zhTW = { pressKeyboard: "按 ? 查看鍵盤快捷鍵", path: "路徑", theme: "主題", + language: "語言", }, projectOverview: { nodes: "節點", @@ -81,6 +82,10 @@ export const zhTW = { sidebar: { info: "資訊", files: "檔案", + moveLeft: "側邊欄移至左側", + moveRight: "側邊欄移至右側", + collapse: "收起側邊欄", + expand: "展開側邊欄", }, mobile: { graph: "圖谱", @@ -179,6 +184,7 @@ export const zhTW = { closeExpanded: "關閉展開的程式碼檢視器", closeViewer: "關閉程式碼檢視器", sourceUnavailable: "原始碼不可用", + goBack: "返回", }, customNode: { tested: "已測試", diff --git a/understand-anything-plugin/packages/dashboard/src/locales/zh.ts b/understand-anything-plugin/packages/dashboard/src/locales/zh.ts index c308eb48d..b75a7c4b2 100644 --- a/understand-anything-plugin/packages/dashboard/src/locales/zh.ts +++ b/understand-anything-plugin/packages/dashboard/src/locales/zh.ts @@ -21,6 +21,7 @@ export const zh = { pressKeyboard: "按 ? 查看键盘快捷键", path: "路径", theme: "主题", + language: "语言", }, projectOverview: { nodes: "节点", @@ -81,6 +82,10 @@ export const zh = { sidebar: { info: "信息", files: "文件", + moveLeft: "侧边栏移至左侧", + moveRight: "侧边栏移至右侧", + collapse: "收起侧边栏", + expand: "展开侧边栏", }, mobile: { graph: "图谱", @@ -179,6 +184,7 @@ export const zh = { closeExpanded: "关闭展开的代码查看器", closeViewer: "关闭代码查看器", sourceUnavailable: "源码不可用", + goBack: "返回", }, customNode: { tested: "已测试", diff --git a/understand-anything-plugin/packages/dashboard/src/store.ts b/understand-anything-plugin/packages/dashboard/src/store.ts index b3b2a96c7..ae2eb0839 100644 --- a/understand-anything-plugin/packages/dashboard/src/store.ts +++ b/understand-anything-plugin/packages/dashboard/src/store.ts @@ -237,6 +237,12 @@ interface DashboardStore { layoutIssues: GraphIssue[]; appendLayoutIssues: (issues: GraphIssue[]) => void; clearLayoutIssues: () => void; + + // Sidebar position & collapse + sidebarPosition: "left" | "right"; + setSidebarPosition: (pos: "left" | "right") => void; + sidebarCollapsed: boolean; + toggleSidebarCollapsed: () => void; } function getSortedTour(graph: KnowledgeGraph): TourStep[] { @@ -780,5 +786,10 @@ export const useDashboardStore = create()((set, get) => ({ return { layoutIssues: [...state.layoutIssues, ...fresh] }; }), clearLayoutIssues: () => set({ layoutIssues: [] }), + + sidebarPosition: "right", + setSidebarPosition: (pos) => set({ sidebarPosition: pos }), + sidebarCollapsed: false, + toggleSidebarCollapsed: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })), }));