From 8f960275b9ba2a9a7e7dd5cdf6c84d9b0c2c7395 Mon Sep 17 00:00:00 2001
From: Soulter <905617992@qq.com>
Date: Tue, 6 Oct 2026 16:45:32 +0800
Subject: [PATCH 1/6] refactor(dashboard): complete the plugin pages to views
rename
Finish the remaining Pages -> Views rename on the dashboard:
- Fix the plugin card "Open View" button crash by pointing
openPluginWebui at the renamed PluginView route
- Rename PluginPagePage.vue to PluginViewPage.vue and update its
internals (loadPluginView, pluginViewTitle, .plugin-view-* classes)
- Rename openPluginWebui -> openPluginView and the open-webui emit to
open-view; pluginPageTitle/Description -> pluginViewTitle/Description;
isPluginPageRoute -> isPluginViewRoute
- Rename i18n keys (pluginWebui -> pluginView, openWebui -> openView,
pluginPageType -> pluginViewType, messages) across en/zh/ja/ru locales
The postMessage bridge channel name (astrbot-plugin-page) is kept
unchanged because it is part of the wire protocol shared with
plugin_page_bridge.js.
---
.../src/components/shared/ExtensionCard.vue | 10 +++----
.../src/composables/usePluginSidebarItems.ts | 2 +-
.../i18n/locales/en-US/core/navigation.json | 4 +--
.../locales/en-US/features/extension.json | 8 ++---
.../i18n/locales/ja-JP/core/navigation.json | 4 +--
.../locales/ja-JP/features/extension.json | 6 ++--
.../i18n/locales/ru-RU/core/navigation.json | 4 +--
.../locales/ru-RU/features/extension.json | 6 ++--
.../i18n/locales/zh-CN/core/navigation.json | 4 +--
.../locales/zh-CN/features/extension.json | 8 ++---
dashboard/src/layouts/full/FullLayout.vue | 6 ++--
.../layouts/full/vertical-sidebar/NavItem.vue | 2 +-
dashboard/src/router/MainRoutes.ts | 2 +-
dashboard/src/utils/pluginI18n.js | 8 ++---
...{PluginPagePage.vue => PluginViewPage.vue} | 30 +++++++++----------
.../views/extension/InstalledPluginsTab.vue | 6 ++--
.../src/views/extension/PluginDetailPage.vue | 10 +++----
17 files changed, 60 insertions(+), 60 deletions(-)
rename dashboard/src/views/{PluginPagePage.vue => PluginViewPage.vue} (96%)
diff --git a/dashboard/src/components/shared/ExtensionCard.vue b/dashboard/src/components/shared/ExtensionCard.vue
index e5e487de48..d7a83112e6 100644
--- a/dashboard/src/components/shared/ExtensionCard.vue
+++ b/dashboard/src/components/shared/ExtensionCard.vue
@@ -38,7 +38,7 @@ const emit = defineEmits([
"view-readme",
"view-changelog",
"toggle-pin",
- "open-webui",
+ "open-view",
"change-source",
]);
@@ -179,8 +179,8 @@ const togglePin = () => {
emit("toggle-pin", props.extension);
};
-const openWebui = () => {
- emit("open-webui", props.extension);
+const openView = () => {
+ emit("open-view", props.extension);
};
@@ -403,7 +403,7 @@ const openWebui = () => {
{
variant="tonal"
color="primary"
:disabled="!extension.activated"
- @click.stop="openWebui"
+ @click.stop="openView"
>
diff --git a/dashboard/src/composables/usePluginSidebarItems.ts b/dashboard/src/composables/usePluginSidebarItems.ts
index 2ad2789722..3a4f257dc0 100644
--- a/dashboard/src/composables/usePluginSidebarItems.ts
+++ b/dashboard/src/composables/usePluginSidebarItems.ts
@@ -3,7 +3,7 @@ import { pluginApi } from "@/api/v1";
import type { menu } from "@/layouts/full/vertical-sidebar/sidebarItem";
const DEFAULT_ICON = "mdi-puzzle";
-const GROUP_I18N_KEY = "core.navigation.pluginWebui";
+const GROUP_I18N_KEY = "core.navigation.pluginView";
const GROUP_ICON = "mdi-puzzle-outline";
interface PluginEntry {
diff --git a/dashboard/src/i18n/locales/en-US/core/navigation.json b/dashboard/src/i18n/locales/en-US/core/navigation.json
index 3ab84921fc..43a442aa4b 100644
--- a/dashboard/src/i18n/locales/en-US/core/navigation.json
+++ b/dashboard/src/i18n/locales/en-US/core/navigation.json
@@ -63,6 +63,6 @@
"normal": "Normal Config",
"system": "System Config"
},
- "pluginWebui": "Plugin Views",
- "pluginPageType": "Plugin View"
+ "pluginView": "Plugin Views",
+ "pluginViewType": "Plugin View"
}
diff --git a/dashboard/src/i18n/locales/en-US/features/extension.json b/dashboard/src/i18n/locales/en-US/features/extension.json
index 45e2901dd3..bddea57813 100644
--- a/dashboard/src/i18n/locales/en-US/features/extension.json
+++ b/dashboard/src/i18n/locales/en-US/features/extension.json
@@ -47,7 +47,7 @@
"viewRepo": "Repository",
"openPages": "Pages",
"openPage": "Open",
- "openWebui": "Open Plugin UI",
+ "openView": "Open View",
"close": "Close",
"save": "Save",
"saveAndClose": "Save and Close",
@@ -305,9 +305,9 @@
"invalidRepositoryUrl": "Please enter a valid Git repository URL",
"enterJsonUrl": "Please enter a URL that returns plugin list JSON data",
"pluginNotFound": "Plugin not found",
- "pluginDisabled": "This plugin is closed. Open it before accessing its page.",
- "pluginPageNotFound": "Plugin view not found",
- "pluginPageLoadFailed": "Failed to load the plugin view",
+ "pluginDisabled": "This plugin is closed. Open it before accessing its view.",
+ "pluginViewNotFound": "Plugin view not found",
+ "pluginViewLoadFailed": "Failed to load the plugin view",
"missingMarketPluginId": "This source record is missing legal plugin identifiers, so it cannot be installed from the market",
"sourceBindSuccess": "Plugin source updated",
"validatingPlugin": "Validating plugin...",
diff --git a/dashboard/src/i18n/locales/ja-JP/core/navigation.json b/dashboard/src/i18n/locales/ja-JP/core/navigation.json
index 9693d69cae..75cd4e4df4 100644
--- a/dashboard/src/i18n/locales/ja-JP/core/navigation.json
+++ b/dashboard/src/i18n/locales/ja-JP/core/navigation.json
@@ -63,6 +63,6 @@
"normal": "一般設定",
"system": "システム設定"
},
- "pluginWebui": "プラグインビュー",
- "pluginPageType": "プラグインビュー"
+ "pluginView": "プラグインビュー",
+ "pluginViewType": "プラグインビュー"
}
diff --git a/dashboard/src/i18n/locales/ja-JP/features/extension.json b/dashboard/src/i18n/locales/ja-JP/features/extension.json
index 205a266a8a..a8d0b991a3 100644
--- a/dashboard/src/i18n/locales/ja-JP/features/extension.json
+++ b/dashboard/src/i18n/locales/ja-JP/features/extension.json
@@ -47,7 +47,7 @@
"viewRepo": "リポジトリ",
"openPages": "Pages",
"openPage": "開く",
- "openWebui": "プラグイン UI を開く",
+ "openView": "ビューを開く",
"close": "閉じる",
"save": "保存",
"saveAndClose": "保存して閉じる",
@@ -306,8 +306,8 @@
"enterJsonUrl": "プラグイン一覧の JSON データを返す URL を入力してください",
"pluginNotFound": "プラグインが見つかりません",
"pluginDisabled": "このプラグインは無効です。ページにアクセスする前に有効化してください。",
- "pluginPageNotFound": "プラグインビューが見つかりません",
- "pluginPageLoadFailed": "プラグインビューの読み込みに失敗しました",
+ "pluginViewNotFound": "プラグインビューが見つかりません",
+ "pluginViewLoadFailed": "プラグインビューの読み込みに失敗しました",
"missingMarketPluginId": "有効なプラグイン識別子がないため、このプラグインマーケットのソースからインストールできません",
"sourceBindSuccess": "プラグインソースを更新しました",
"validatingPlugin": "プラグインを検証中…",
diff --git a/dashboard/src/i18n/locales/ru-RU/core/navigation.json b/dashboard/src/i18n/locales/ru-RU/core/navigation.json
index c11d098c18..e4bd5e89d6 100644
--- a/dashboard/src/i18n/locales/ru-RU/core/navigation.json
+++ b/dashboard/src/i18n/locales/ru-RU/core/navigation.json
@@ -63,6 +63,6 @@
"normal": "Обычная конфигурация",
"system": "Системная конфигурация"
},
- "pluginWebui": "Представления плагинов",
- "pluginPageType": "Представление плагина"
+ "pluginView": "Представления плагинов",
+ "pluginViewType": "Представление плагина"
}
diff --git a/dashboard/src/i18n/locales/ru-RU/features/extension.json b/dashboard/src/i18n/locales/ru-RU/features/extension.json
index 5552873beb..f7d0ad1195 100644
--- a/dashboard/src/i18n/locales/ru-RU/features/extension.json
+++ b/dashboard/src/i18n/locales/ru-RU/features/extension.json
@@ -47,7 +47,7 @@
"viewRepo": "Репозиторий",
"openPages": "Pages",
"openPage": "Открыть",
- "openWebui": "Открыть UI плагина",
+ "openView": "Открыть представление",
"close": "Закрыть",
"save": "Сохранить",
"saveAndClose": "Сохранить и закрыть",
@@ -306,8 +306,8 @@
"enterJsonUrl": "Введите URL, возвращающий список плагинов в формате JSON",
"pluginNotFound": "Плагин не найден",
"pluginDisabled": "Этот плагин сейчас отключён. Включите его, чтобы открыть страницу.",
- "pluginPageNotFound": "Представление плагина не найдено",
- "pluginPageLoadFailed": "Не удалось загрузить представление плагина",
+ "pluginViewNotFound": "Представление плагина не найдено",
+ "pluginViewLoadFailed": "Не удалось загрузить представление плагина",
"missingMarketPluginId": "Эта запись источника не содержит идентификаторов плагина, поэтому его нельзя установить из магазина",
"sourceBindSuccess": "Источник плагина обновлен",
"validatingPlugin": "Проверка плагина...",
diff --git a/dashboard/src/i18n/locales/zh-CN/core/navigation.json b/dashboard/src/i18n/locales/zh-CN/core/navigation.json
index 93a08ecd7a..523ed864d9 100644
--- a/dashboard/src/i18n/locales/zh-CN/core/navigation.json
+++ b/dashboard/src/i18n/locales/zh-CN/core/navigation.json
@@ -63,6 +63,6 @@
"normal": "普通配置",
"system": "系统配置"
},
- "pluginWebui": "插件可视化视图",
- "pluginPageType": "插件可视化视图"
+ "pluginView": "插件可视化视图",
+ "pluginViewType": "插件可视化视图"
}
diff --git a/dashboard/src/i18n/locales/zh-CN/features/extension.json b/dashboard/src/i18n/locales/zh-CN/features/extension.json
index 0c80993ce2..c6d4c55e80 100644
--- a/dashboard/src/i18n/locales/zh-CN/features/extension.json
+++ b/dashboard/src/i18n/locales/zh-CN/features/extension.json
@@ -47,7 +47,7 @@
"viewRepo": "仓库",
"openPages": "Pages",
"openPage": "打开",
- "openWebui": "打开插件UI界面",
+ "openView": "打开视图",
"close": "关闭",
"save": "保存",
"saveAndClose": "保存并关闭",
@@ -305,9 +305,9 @@
"invalidRepositoryUrl": "请输入有效的 Git 仓库链接",
"enterJsonUrl": "请输入返回插件列表JSON数据的URL地址",
"pluginNotFound": "未找到该插件",
- "pluginDisabled": "该插件当前已关闭,请先打开后再访问页面",
- "pluginPageNotFound": "未找到该插件可视化视图",
- "pluginPageLoadFailed": "加载插件可视化视图失败",
+ "pluginDisabled": "该插件当前已关闭,请先打开后再访问视图",
+ "pluginViewNotFound": "未找到该插件可视化视图",
+ "pluginViewLoadFailed": "加载插件可视化视图失败",
"missingMarketPluginId": "缺少合法的插件标识,无法从该插件市场源安装",
"sourceBindSuccess": "插件源已更新",
"validatingPlugin": "正在校验插件...",
diff --git a/dashboard/src/layouts/full/FullLayout.vue b/dashboard/src/layouts/full/FullLayout.vue
index 1e8b6ec699..8143c4b5c4 100644
--- a/dashboard/src/layouts/full/FullLayout.vue
+++ b/dashboard/src/layouts/full/FullLayout.vue
@@ -23,7 +23,7 @@ const routerLoadingStore = useRouterLoadingStore();
const isCurrentChatRoute = computed(
() => route.path === "/chat" || route.path.startsWith("/chat/"),
);
-const isPluginPageRoute = computed(
+const isPluginViewRoute = computed(
() => route.path.startsWith("/plugin-view/") || route.path.startsWith("/plugin-page/"),
);
const isProviderPageRoute = computed(() => route.path === "/providers");
@@ -35,7 +35,7 @@ const isViewportLockedRoute = computed(
isPlatformPageRoute.value,
);
const isFullScreenRoute = computed(
- () => isCurrentChatRoute.value || isPluginPageRoute.value,
+ () => isCurrentChatRoute.value || isPluginViewRoute.value,
);
const shouldMountChat = ref(isCurrentChatRoute.value);
@@ -160,7 +160,7 @@ onMounted(() => {
height: '100%',
width: '100%',
overflow: isViewportLockedRoute ? 'hidden' : undefined,
- position: isPluginPageRoute ? 'relative' : undefined,
+ position: isPluginViewRoute ? 'relative' : undefined,
}"
>
typeof props.item?.icon === 'string');
-
{{ t('core.navigation.pluginPageType') }}
+
{{ t('core.navigation.pluginViewType') }}
diff --git a/dashboard/src/router/MainRoutes.ts b/dashboard/src/router/MainRoutes.ts
index eaf4aa4cf9..aa40411a64 100644
--- a/dashboard/src/router/MainRoutes.ts
+++ b/dashboard/src/router/MainRoutes.ts
@@ -99,7 +99,7 @@ const MainRoutes = {
{
name: 'PluginView',
path: '/plugin-view/:pluginName/:pageName',
- component: () => import('@/views/PluginPagePage.vue')
+ component: () => import('@/views/PluginViewPage.vue')
},
{
// Legacy alias of the plugin view route.
diff --git a/dashboard/src/utils/pluginI18n.js b/dashboard/src/utils/pluginI18n.js
index 3a8b503338..ecf46d6c14 100644
--- a/dashboard/src/utils/pluginI18n.js
+++ b/dashboard/src/utils/pluginI18n.js
@@ -79,7 +79,7 @@ export function usePluginI18n() {
return resolve(plugin?.i18n, `${base}.${attr}`, fallback);
};
- const pluginPageTitle = (plugin, page, fallback = "") => {
+ const pluginViewTitle = (plugin, page, fallback = "") => {
const pageFallback =
fallback ||
(page && typeof page === "object"
@@ -89,7 +89,7 @@ export function usePluginI18n() {
return pluginPageText(plugin, page, "title", pageFallback);
};
- const pluginPageDescription = (plugin, page, fallback = "") => {
+ const pluginViewDescription = (plugin, page, fallback = "") => {
const pageFallback =
fallback ||
(page && typeof page === "object" ? page.description || page.desc : "") ||
@@ -109,8 +109,8 @@ export function usePluginI18n() {
pluginDesc,
pluginShortDesc,
pluginPageText,
- pluginPageTitle,
- pluginPageDescription,
+ pluginViewTitle,
+ pluginViewDescription,
configText,
};
}
diff --git a/dashboard/src/views/PluginPagePage.vue b/dashboard/src/views/PluginViewPage.vue
similarity index 96%
rename from dashboard/src/views/PluginPagePage.vue
rename to dashboard/src/views/PluginViewPage.vue
index 2621d7acf2..471d3451f5 100644
--- a/dashboard/src/views/PluginPagePage.vue
+++ b/dashboard/src/views/PluginViewPage.vue
@@ -15,7 +15,7 @@ const { tm } = useModuleI18n("features/extension");
const {
locale,
pluginName: pluginDisplayName,
- pluginPageTitle,
+ pluginViewTitle,
} = usePluginI18n();
const customizer = useCustomizerStore();
@@ -32,7 +32,7 @@ let iframeMessageOrigin = null;
const pluginName = computed(() => String(route.params.pluginName || ""));
const pageName = computed(() => String(route.params.pageName || ""));
const localizedPageTitle = computed(() =>
- pluginPageTitle(
+ pluginViewTitle(
plugin.value,
page.value || pageName.value,
page.value?.title || pageName.value || tm("buttons.openPages"),
@@ -551,7 +551,7 @@ const handleIframeLoad = () => {
sendIframeContext();
};
-const loadPluginPage = async () => {
+const loadPluginView = async () => {
loading.value = true;
errorMessage.value = "";
plugin.value = null;
@@ -564,7 +564,7 @@ const loadPluginPage = async () => {
const detailResponse = await pluginApi.get(pluginName.value);
if (detailResponse.data?.status === "error") {
throw new Error(
- detailResponse.data.message || tm("messages.pluginPageLoadFailed"),
+ detailResponse.data.message || tm("messages.pluginViewLoadFailed"),
);
}
@@ -582,7 +582,7 @@ const loadPluginPage = async () => {
const entryResponse = await pluginApi.page(pluginName.value, pageName.value);
if (entryResponse.data?.status === "error") {
throw new Error(
- entryResponse.data.message || tm("messages.pluginPageLoadFailed"),
+ entryResponse.data.message || tm("messages.pluginViewLoadFailed"),
);
}
@@ -592,7 +592,7 @@ const loadPluginPage = async () => {
typeof pageEntry.content_path !== "string" ||
!pageEntry.content_path.length
) {
- errorMessage.value = tm("messages.pluginPageNotFound");
+ errorMessage.value = tm("messages.pluginViewNotFound");
return;
}
@@ -605,7 +605,7 @@ const loadPluginPage = async () => {
errorMessage.value =
error?.response?.data?.message ||
error?.message ||
- tm("messages.pluginPageLoadFailed");
+ tm("messages.pluginViewLoadFailed");
} finally {
loading.value = false;
}
@@ -620,7 +620,7 @@ onBeforeUnmount(() => {
cleanupSSEConnections();
});
-watch([pluginName, pageName], loadPluginPage, { immediate: true });
+watch([pluginName, pageName], loadPluginView, { immediate: true });
watch(locale, () => {
sendIframeContext();
});
@@ -630,13 +630,13 @@ watch(() => customizer.uiTheme, () => {
-
-
+
+
{{ tm("status.loading") }}
-
+
{{ errorMessage }}
@@ -646,7 +646,7 @@ watch(() => customizer.uiTheme, () => {
v-else
ref="iframeRef"
:src="iframeSrc"
- class="plugin-page-frame"
+ class="plugin-view-frame"
referrerpolicy="no-referrer"
sandbox="allow-scripts allow-forms allow-downloads"
@load="handleIframeLoad"
@@ -655,7 +655,7 @@ watch(() => customizer.uiTheme, () => {