From 523a756f5c4895b670b8c44eee87d27bad49b37b Mon Sep 17 00:00:00 2001 From: Mikhail Date: Sat, 16 May 2026 20:48:31 +0300 Subject: [PATCH] Wire IDE symbol navigation panel --- .../sfera-web/scripts/smoke-editor-modes.mjs | 2 +- .../scripts/smoke-editor-runtime.mjs | 15 +-- .../src/components/editor/ide-workspace.tsx | 120 ++++++++++++------ 3 files changed, 89 insertions(+), 48 deletions(-) diff --git a/frontend/sfera-web/scripts/smoke-editor-modes.mjs b/frontend/sfera-web/scripts/smoke-editor-modes.mjs index 6b09483..5f88187 100644 --- a/frontend/sfera-web/scripts/smoke-editor-modes.mjs +++ b/frontend/sfera-web/scripts/smoke-editor-modes.mjs @@ -106,7 +106,7 @@ const checks = [ { name: "module mode", url: `${baseUrl}/editor?lang=ru&project=${projectId}&mode=module&routine=${routine}`, - mustInclude: ["data-ide-workspace", "data-left-navigation-panel", "data-right-context-inspector", "data-open-objects-bar", "data-open-document-pin", "data-open-document-close", "data-fallback-tree-search", "data-fallback-tree-filters", "Alt+1 Alt+2 Alt+3", "Редактор BSL", "Код модуля не загружен", "Выберите реальный модуль", "Основная конфигурация", "Расширение: <Имя>", "SFERA", "Среды"] + mustInclude: ["data-ide-workspace", "data-active-mode=\"module\"", "data-left-navigation-panel", "data-right-context-inspector", "data-open-objects-bar", "data-open-document-pin", "data-open-document-close", "data-fallback-tree-search", "data-fallback-tree-filters", "data-fast-bsl-editor", "data-symbol-navigation-panel", "symbol-search-input", "Alt+1 Alt+2 Alt+3", "Основная конфигурация", "SFERA", "Среды"] }, { name: "form mode", diff --git a/frontend/sfera-web/scripts/smoke-editor-runtime.mjs b/frontend/sfera-web/scripts/smoke-editor-runtime.mjs index 7593877..8f8ab2f 100644 --- a/frontend/sfera-web/scripts/smoke-editor-runtime.mjs +++ b/frontend/sfera-web/scripts/smoke-editor-runtime.mjs @@ -186,16 +186,13 @@ try { await restoredModuleTabs.first().click(); } await page.locator("[data-fast-bsl-editor]").waitFor({ state: "visible", timeout: 15000 }); - const symbolNavigationPanel = page.locator("[data-symbol-navigation-panel]"); - if ((await symbolNavigationPanel.count()) > 0) { - await symbolNavigationPanel.waitFor({ state: "visible", timeout: 15000 }); - } + await page.locator("[data-symbol-navigation-panel]").waitFor({ state: "visible", timeout: 15000 }); const symbolSearchInput = page.locator("#symbol-search-input"); - if ((await symbolSearchInput.count()) > 0) { - await symbolSearchInput.fill("Проверить"); - await symbolSearchInput.press("Enter"); - await page.locator("[data-symbol-result]").first().waitFor({ state: "visible", timeout: 15000 }); - } + await symbolSearchInput.fill("demo"); + await symbolSearchInput.press("Enter"); + await page.locator("[data-symbol-result]").first().waitFor({ state: "visible", timeout: 15000 }); + await page.locator('button[data-editor-action="symbol-definition-row"]').first().click(); + await page.locator("[data-symbol-definition]").waitFor({ state: "visible", timeout: 15000 }); const findUsagesButton = page.locator('button[data-editor-action="find-usages"]'); if ((await findUsagesButton.count()) > 0 && await findUsagesButton.isEnabled()) { await findUsagesButton.click(); diff --git a/frontend/sfera-web/src/components/editor/ide-workspace.tsx b/frontend/sfera-web/src/components/editor/ide-workspace.tsx index a77c8b3..b434bfe 100644 --- a/frontend/sfera-web/src/components/editor/ide-workspace.tsx +++ b/frontend/sfera-web/src/components/editor/ide-workspace.tsx @@ -2255,6 +2255,19 @@ function EditorPanel({ value={monacoValue} /> + ); } @@ -2262,63 +2275,94 @@ function EditorPanel({ function SymbolNavigationPanel({ definition, language, + message, onDefinition, + onQueryChange, onReferences, + onSearch, + query, references, - results + results, + state }: Readonly<{ definition: SymbolResult | null; language: UiLanguage; + message: string; onDefinition: (lineageId?: string) => void; + onQueryChange: (value: string) => void; onReferences: (lineageId?: string) => void; + onSearch: () => void; + query: string; references: SymbolReferences | null; results: SymbolResult[]; + state: "idle" | "loading" | "error"; }>) { const t = messages[language]; const referenceRows = references?.references.slice(0, 8) ?? []; return ( -
-
-
{t.referencesPanel}
- {referenceRows.length} +
+
+ + onQueryChange(event.target.value)} + onKeyDown={(event) => { + if (event.key === "Enter") { + event.preventDefault(); + onSearch(); + } + }} + placeholder={language === "ru" ? "Найти символ" : "Find symbol"} + value={query} + /> + + 0 ? "success" : "neutral"}>{referenceRows.length}
-
- {results.length === 0 ? ( -
{language === "ru" ? "Выполните поиск символа или откройте использования выбранного объекта." : "Search a symbol or open references for the selected object."}
- ) : ( - results.map((result) => ( -
-
{result.node.qualified_name}
-
{result.node.kind} · {formatSourceLocation(result.source, language)}
-
- - + {message ? ( +
{message}
+ ) : null} +
+
+ {results.length === 0 ? ( +
{language === "ru" ? "Выполните поиск символа или откройте использования выбранного объекта." : "Search a symbol or open references for the selected object."}
+ ) : ( + results.map((result) => ( +
+
{result.node.qualified_name}
+
{result.node.kind} · {formatSourceLocation(result.source, language)}
+
+ + +
+ )) + )} +
+
+ {definition ? ( +
+
{definition.node.qualified_name}
+
{formatSourceLocation(definition.source, language)}
- )) - )} + ) : null} + {referenceRows.length > 0 ? ( +
+ {referenceRows.map((reference) => ( +
+
{reference.source?.qualified_name ?? reference.target?.qualified_name ?? reference.kind}
+
{reference.kind} · {reference.direction} · {formatSourceLocation(reference.location, language)}
+
+ ))} +
+ ) : null} +
- {definition ? ( -
-
{definition.node.qualified_name}
-
{formatSourceLocation(definition.source, language)}
-
- ) : null} - {referenceRows.length > 0 ? ( -
- {referenceRows.map((reference) => ( -
-
{reference.source?.qualified_name ?? reference.target?.qualified_name ?? reference.kind}
-
{reference.kind} · {reference.direction} · {formatSourceLocation(reference.location, language)}
-
- ))} -
- ) : null}
); }