From 7a2ecee0106a509eeafd81ca9308486754aafa50 Mon Sep 17 00:00:00 2001 From: fujie Date: Mon, 16 Mar 2026 14:24:48 +0800 Subject: [PATCH] feat: improve batch installer selection dialog --- .../tools/batch-install-plugins-tool.md | 6 +- .../tools/batch-install-plugins-tool.zh.md | 6 +- docs/plugins/tools/batch-install-plugins.md | 6 +- .../plugins/tools/batch-install-plugins.zh.md | 6 +- .../batch-install-plugins/ANNOUNCEMENT.md | 3 +- .../batch-install-plugins/ANNOUNCEMENT_CN.md | 3 +- plugins/tools/batch-install-plugins/README.md | 6 +- .../tools/batch-install-plugins/README_CN.md | 6 +- .../batch_install_plugins.py | 87 ++++++++++++++++++- plugins/tools/batch-install-plugins/v1.1.0.md | 4 +- .../tools/batch-install-plugins/v1.1.0_CN.md | 4 +- 11 files changed, 109 insertions(+), 28 deletions(-) diff --git a/docs/plugins/tools/batch-install-plugins-tool.md b/docs/plugins/tools/batch-install-plugins-tool.md index 5301673..fd7d161 100644 --- a/docs/plugins/tools/batch-install-plugins-tool.md +++ b/docs/plugins/tools/batch-install-plugins-tool.md @@ -10,7 +10,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta - **Auto-Update**: Automatically updates previously installed plugins - **Public GitHub Support**: Install plugins from any public GitHub repository - **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins -- **Interactive Selection Dialog**: Review the filtered list, check the plugins you want, then install only that subset +- **Interactive Selection Dialog**: Review the filtered list with type tags and plugin descriptions, then install only the checked subset - **i18n**: Supports 11 languages ## Flow @@ -33,7 +33,7 @@ User Input ▼ ┌─────────────────────────────────────┐ │ Show Selection Dialog │ -│ (checkbox list + exclude hint) │ +│ (checkbox list + type tags + desc) │ └─────────────────────────────────────┘ │ ├── [Cancel] → End @@ -59,7 +59,7 @@ User Input Each request handles one repository. To mix repositories, send another request after the previous installation completes. -After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can check exactly which plugins to install before the API calls start. +After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can review plugin descriptions, use type tags for quick batch selection, and check exactly which plugins to install before the API calls start. ## Quick Start: Install Popular Collections diff --git a/docs/plugins/tools/batch-install-plugins-tool.zh.md b/docs/plugins/tools/batch-install-plugins-tool.zh.md index 6a5e239..270c19d 100644 --- a/docs/plugins/tools/batch-install-plugins-tool.zh.md +++ b/docs/plugins/tools/batch-install-plugins-tool.zh.md @@ -10,7 +10,7 @@ - 自动更新:自动更新之前安装过的插件 - 公开 GitHub 支持:支持从任何公开 GitHub 仓库安装插件 - 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件 -- 交互式选择对话框:先查看过滤后的列表,再勾选要安装的插件,只安装所选子集 +- 交互式选择对话框:先查看带类型标签和描述信息的过滤列表,再勾选要安装的插件,只安装所选子集 - 国际化:支持 11 种语言 ## 流程 @@ -33,7 +33,7 @@ ▼ ┌─────────────────────────────────────┐ │ 显示选择对话框 │ -│ (复选列表 + 排除提示) │ +│ (复选列表 + 类型标签 + 描述) │ └─────────────────────────────────────┘ │ ├── [取消] → 结束 @@ -59,7 +59,7 @@ 每次请求处理一个仓库。如需混合多个来源,请在上一次安装完成后再发起下一次请求。 -在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框,你可以先勾选真正想安装的插件,再开始调用安装 API。 +在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。你可以先查看插件描述,使用类型标签进行批量勾选,再开始调用安装 API。 ## 快速开始:安装热门插件集 diff --git a/docs/plugins/tools/batch-install-plugins.md b/docs/plugins/tools/batch-install-plugins.md index c9a4e31..e8fd4c7 100644 --- a/docs/plugins/tools/batch-install-plugins.md +++ b/docs/plugins/tools/batch-install-plugins.md @@ -14,7 +14,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta - **Auto-Update**: Automatically updates previously installed plugins - **Public GitHub Support**: Install plugins from any public GitHub repository - **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins -- **Interactive Selection Dialog**: Review the filtered list, check the plugins you want, then install only that subset +- **Interactive Selection Dialog**: Review the filtered list with type tags and plugin descriptions, then install only the checked subset - **i18n**: Supports 11 languages ## Flow @@ -37,7 +37,7 @@ User Input ▼ ┌─────────────────────────────────────┐ │ Show Selection Dialog │ -│ (checkbox list + exclude hint) │ +│ (checkbox list + type tags + desc) │ └─────────────────────────────────────┘ │ ├── [Cancel] → End @@ -63,7 +63,7 @@ User Input Each request handles one repository. To mix repositories, send another request after the previous installation completes. -After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can check exactly which plugins to install before the API calls start. +After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can review plugin descriptions, use type tags for quick batch selection, and check exactly which plugins to install before the API calls start. ## Quick Start: Install Popular Collections diff --git a/docs/plugins/tools/batch-install-plugins.zh.md b/docs/plugins/tools/batch-install-plugins.zh.md index 5338255..ab81ffe 100644 --- a/docs/plugins/tools/batch-install-plugins.zh.md +++ b/docs/plugins/tools/batch-install-plugins.zh.md @@ -14,7 +14,7 @@ - 自动更新:自动更新之前安装过的插件 - 公开 GitHub 支持:支持从任何公开 GitHub 仓库安装插件 - 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件 -- 交互式选择对话框:先查看过滤后的列表,再勾选要安装的插件,只安装所选子集 +- 交互式选择对话框:先查看带类型标签和描述信息的过滤列表,再勾选要安装的插件,只安装所选子集 - 国际化:支持 11 种语言 ## 流程 @@ -37,7 +37,7 @@ ▼ ┌─────────────────────────────────────┐ │ 显示选择对话框 │ -│ (复选列表 + 排除提示) │ +│ (复选列表 + 类型标签 + 描述) │ └─────────────────────────────────────┘ │ ├── [取消] → 结束 @@ -63,7 +63,7 @@ 每次请求处理一个仓库。如需混合多个来源,请在上一次安装完成后再发起下一次请求。 -在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框,你可以先勾选真正想安装的插件,再开始调用安装 API。 +在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。你可以先查看插件描述,使用类型标签进行批量勾选,再开始调用安装 API。 ## 快速开始:安装热门插件集 diff --git a/plugins/tools/batch-install-plugins/ANNOUNCEMENT.md b/plugins/tools/batch-install-plugins/ANNOUNCEMENT.md index e676bfe..5c66c3b 100644 --- a/plugins/tools/batch-install-plugins/ANNOUNCEMENT.md +++ b/plugins/tools/batch-install-plugins/ANNOUNCEMENT.md @@ -10,12 +10,13 @@ Installing plugins in OpenWebUI should not feel like an all-or-nothing jump. Wit ### 🚀 Interactive Plugin Selection - Uses the OpenWebUI `execute` event to open a custom browser dialog -- Displays the filtered plugin list with checkboxes, repository context, and exclude hints +- Displays the filtered plugin list with checkboxes, type tags, plugin descriptions, and repository context - Installs only the plugins the user keeps selected ### ✅ Smart Safety Features - Replaces the basic confirmation event with a richer selective install flow - Users can uncheck plugins they do not want without rewriting the request +- Removes the noisy copy-to-exclude helper when it is not needed - Automatically excludes the tool itself from installation ### 🌍 Multi-Repository Support diff --git a/plugins/tools/batch-install-plugins/ANNOUNCEMENT_CN.md b/plugins/tools/batch-install-plugins/ANNOUNCEMENT_CN.md index 7d2d353..a10db62 100644 --- a/plugins/tools/batch-install-plugins/ANNOUNCEMENT_CN.md +++ b/plugins/tools/batch-install-plugins/ANNOUNCEMENT_CN.md @@ -10,12 +10,13 @@ ### 🚀 交互式插件选择 - 基于 OpenWebUI 的 `execute` 事件打开自定义浏览器选择对话框 -- 显示过滤后的插件列表、仓库信息与排除提示 +- 显示带复选框、类型标签、插件描述和仓库信息的过滤结果 - 只安装用户保留勾选的插件 ### ✅ 智能安全保障 - 用更丰富的选择流程替代基础 confirmation 事件 - 用户无需改写请求,也能取消勾选不想安装的插件 +- 不再显示多余的“复制 exclude_keywords”提示 - 自动排除工具自身,避免重复安装 ### 🌍 多仓库支持 diff --git a/plugins/tools/batch-install-plugins/README.md b/plugins/tools/batch-install-plugins/README.md index c9a4e31..e8fd4c7 100644 --- a/plugins/tools/batch-install-plugins/README.md +++ b/plugins/tools/batch-install-plugins/README.md @@ -14,7 +14,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta - **Auto-Update**: Automatically updates previously installed plugins - **Public GitHub Support**: Install plugins from any public GitHub repository - **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins -- **Interactive Selection Dialog**: Review the filtered list, check the plugins you want, then install only that subset +- **Interactive Selection Dialog**: Review the filtered list with type tags and plugin descriptions, then install only the checked subset - **i18n**: Supports 11 languages ## Flow @@ -37,7 +37,7 @@ User Input ▼ ┌─────────────────────────────────────┐ │ Show Selection Dialog │ -│ (checkbox list + exclude hint) │ +│ (checkbox list + type tags + desc) │ └─────────────────────────────────────┘ │ ├── [Cancel] → End @@ -63,7 +63,7 @@ User Input Each request handles one repository. To mix repositories, send another request after the previous installation completes. -After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can check exactly which plugins to install before the API calls start. +After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event so you can review plugin descriptions, use type tags for quick batch selection, and check exactly which plugins to install before the API calls start. ## Quick Start: Install Popular Collections diff --git a/plugins/tools/batch-install-plugins/README_CN.md b/plugins/tools/batch-install-plugins/README_CN.md index 5338255..ab81ffe 100644 --- a/plugins/tools/batch-install-plugins/README_CN.md +++ b/plugins/tools/batch-install-plugins/README_CN.md @@ -14,7 +14,7 @@ - 自动更新:自动更新之前安装过的插件 - 公开 GitHub 支持:支持从任何公开 GitHub 仓库安装插件 - 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件 -- 交互式选择对话框:先查看过滤后的列表,再勾选要安装的插件,只安装所选子集 +- 交互式选择对话框:先查看带类型标签和描述信息的过滤列表,再勾选要安装的插件,只安装所选子集 - 国际化:支持 11 种语言 ## 流程 @@ -37,7 +37,7 @@ ▼ ┌─────────────────────────────────────┐ │ 显示选择对话框 │ -│ (复选列表 + 排除提示) │ +│ (复选列表 + 类型标签 + 描述) │ └─────────────────────────────────────┘ │ ├── [取消] → 结束 @@ -63,7 +63,7 @@ 每次请求处理一个仓库。如需混合多个来源,请在上一次安装完成后再发起下一次请求。 -在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框,你可以先勾选真正想安装的插件,再开始调用安装 API。 +在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。你可以先查看插件描述,使用类型标签进行批量勾选,再开始调用安装 API。 ## 快速开始:安装热门插件集 diff --git a/plugins/tools/batch-install-plugins/batch_install_plugins.py b/plugins/tools/batch-install-plugins/batch_install_plugins.py index afb332b..940b4b2 100644 --- a/plugins/tools/batch-install-plugins/batch_install_plugins.py +++ b/plugins/tools/batch-install-plugins/batch_install_plugins.py @@ -303,111 +303,133 @@ SELECTION_DIALOG_TEXTS = { "en-US": { "select_all": "Select all", "clear_all": "Clear all", + "quick_select": "Types", "selected_count": "{count} selected", "install_selected": "Install Selected", "cancel": "Cancel", "version_label": "Version", "file_label": "File", + "description_label": "Description", "repo_label": "Repository", }, "zh-CN": { "select_all": "全选", "clear_all": "清空", + "quick_select": "类型标签", "selected_count": "已选 {count} 项", "install_selected": "安装所选插件", "cancel": "取消", "version_label": "版本", "file_label": "文件", + "description_label": "描述", "repo_label": "仓库", }, "zh-HK": { "select_all": "全選", "clear_all": "清空", + "quick_select": "類型標籤", "selected_count": "已選 {count} 項", "install_selected": "安裝所選外掛", "cancel": "取消", "version_label": "版本", "file_label": "檔案", + "description_label": "描述", "repo_label": "倉庫", }, "zh-TW": { "select_all": "全選", "clear_all": "清空", + "quick_select": "類型標籤", "selected_count": "已選 {count} 項", "install_selected": "安裝所選外掛", "cancel": "取消", "version_label": "版本", "file_label": "檔案", + "description_label": "描述", "repo_label": "倉庫", }, "ko-KR": { "select_all": "전체 선택", "clear_all": "선택 해제", + "quick_select": "유형", "selected_count": "{count}개 선택됨", "install_selected": "선택한 플러그인 설치", "cancel": "취소", "version_label": "버전", "file_label": "파일", + "description_label": "설명", "repo_label": "저장소", }, "ja-JP": { "select_all": "すべて選択", "clear_all": "クリア", + "quick_select": "タイプ", "selected_count": "{count}件を選択", "install_selected": "選択したプラグインをインストール", "cancel": "キャンセル", "version_label": "バージョン", "file_label": "ファイル", + "description_label": "説明", "repo_label": "リポジトリ", }, "fr-FR": { "select_all": "Tout sélectionner", "clear_all": "Tout effacer", + "quick_select": "Types", "selected_count": "{count} sélectionnés", "install_selected": "Installer la sélection", "cancel": "Annuler", "version_label": "Version", "file_label": "Fichier", + "description_label": "Description", "repo_label": "Dépôt", }, "de-DE": { "select_all": "Alle auswählen", "clear_all": "Auswahl löschen", + "quick_select": "Typen", "selected_count": "{count} ausgewählt", "install_selected": "Auswahl installieren", "cancel": "Abbrechen", "version_label": "Version", "file_label": "Datei", + "description_label": "Beschreibung", "repo_label": "Repository", }, "es-ES": { "select_all": "Seleccionar todo", "clear_all": "Limpiar", + "quick_select": "Tipos", "selected_count": "{count} seleccionados", "install_selected": "Instalar seleccionados", "cancel": "Cancelar", "version_label": "Versión", "file_label": "Archivo", + "description_label": "Descripción", "repo_label": "Repositorio", }, "it-IT": { "select_all": "Seleziona tutto", "clear_all": "Cancella", + "quick_select": "Tipi", "selected_count": "{count} selezionati", "install_selected": "Installa selezionati", "cancel": "Annulla", "version_label": "Versione", "file_label": "File", + "description_label": "Descrizione", "repo_label": "Repository", }, "vi-VN": { "select_all": "Chọn tất cả", "clear_all": "Bỏ chọn", + "quick_select": "Loại", "selected_count": "Đã chọn {count}", "install_selected": "Cài đặt mục đã chọn", "cancel": "Hủy", "version_label": "Phiên bản", "file_label": "Tệp", + "description_label": "Mô tả", "repo_label": "Kho", }, } @@ -862,7 +884,7 @@ def _build_confirmation_hint(lang: str, repo: str, exclude_keywords: str) -> str if excluded_parts: return _t(lang, "confirm_excluded_hint", excluded=", ".join(excluded_parts)) - return _t(lang, "confirm_copy_exclude_hint", keywords=SELF_EXCLUDE_HINT) + return "" def _build_selection_dialog_js( @@ -919,12 +941,18 @@ def _build_selection_dialog_js( " ", "
", " ", - "
", - "
", + "
", + "
", + "
", " ", " ", + "
", + "
", + "
", + "
", + "
${escapeHtml(ui.quick_select)}
", + "
", "
", - "
", "
", "
", "
", @@ -939,21 +967,68 @@ def _build_selection_dialog_js( " const listEl = overlay.querySelector('#batch-install-plugin-selector-list');", " const countEl = overlay.querySelector('#batch-install-plugin-selector-count');", " const hintEl = overlay.querySelector('#batch-install-plugin-selector-hint');", + " const typesEl = overlay.querySelector('#batch-install-plugin-selector-types');", " const submitBtn = overlay.querySelector('#batch-install-plugin-selector-submit');", " const cancelBtn = overlay.querySelector('#batch-install-plugin-selector-cancel');", " const selectAllBtn = overlay.querySelector('#batch-install-plugin-selector-select-all');", " const clearAllBtn = overlay.querySelector('#batch-install-plugin-selector-clear-all');", + " const typeMap = options.reduce((groups, item) => {", + " if (!groups[item.type]) {", + " groups[item.type] = [];", + " }", + " groups[item.type].push(item);", + " return groups;", + " }, {});", + " const typeEntries = Object.entries(typeMap);", + " const formatMultilineText = (value) => escapeHtml(value).replace(/\\n+/g, '
');", " hintEl.textContent = ui.hint || '';", " hintEl.style.display = ui.hint ? 'block' : 'none';", + " const renderTypeButtons = () => {", + " typesEl.innerHTML = typeEntries.map(([type, items]) => {", + " const allSelected = items.every((item) => selected.has(item.id));", + " const anySelected = items.some((item) => selected.has(item.id));", + " const background = allSelected ? '#0f172a' : '#ffffff';", + " const color = allSelected ? '#ffffff' : '#0f172a';", + " const border = anySelected ? '#94a3b8' : '#cbd5e1';", + " return `", + " ", + " `;", + " }).join('');", + " typesEl.querySelectorAll('button[data-plugin-type]').forEach((button) => {", + " button.addEventListener('click', () => {", + " const pluginType = button.getAttribute('data-plugin-type') || '';", + " const items = typeMap[pluginType] || [];", + " const allSelected = items.length > 0 && items.every((item) => selected.has(item.id));", + " items.forEach((item) => {", + " if (allSelected) {", + " selected.delete(item.id);", + " } else {", + " selected.add(item.id);", + " }", + " });", + " renderList();", + " });", + " });", + " };", " const updateState = () => {", " countEl.textContent = ui.selected_count.replace('{count}', String(selected.size));", " submitBtn.disabled = selected.size === 0;", " submitBtn.style.opacity = selected.size === 0 ? '0.45' : '1';", " submitBtn.style.cursor = selected.size === 0 ? 'not-allowed' : 'pointer';", + " renderTypeButtons();", " };", " const renderList = () => {", " listEl.innerHTML = options.map((item) => {", " const checked = selected.has(item.id) ? 'checked' : '';", + " const description = item.description ? `", + "
", + "
${escapeHtml(ui.description_label)}
", + "
${formatMultilineText(item.description)}
", + "
", + " ` : '';", " return `", "
", "
${escapeHtml(ui.version_label)}: ${escapeHtml(item.version)} · ${escapeHtml(ui.file_label)}: ${escapeHtml(item.file_path)}
", + " ${description}", "
", " ", " `;", @@ -1049,6 +1125,7 @@ async def _request_plugin_selection( "type": candidate.plugin_type, "version": candidate.version, "file_path": candidate.file_path, + "description": candidate.metadata.get("description", ""), } for candidate in candidates ] @@ -1060,11 +1137,13 @@ async def _request_plugin_selection( "hint": hint.strip(), "select_all": _selection_t(lang, "select_all"), "clear_all": _selection_t(lang, "clear_all"), + "quick_select": _selection_t(lang, "quick_select"), "selected_count": _selection_t(lang, "selected_count", count="{count}"), "install_selected": _selection_t(lang, "install_selected"), "cancel": _selection_t(lang, "cancel"), "version_label": _selection_t(lang, "version_label"), "file_label": _selection_t(lang, "file_label"), + "description_label": _selection_t(lang, "description_label"), } js_code = _build_selection_dialog_js(options, ui_text) diff --git a/plugins/tools/batch-install-plugins/v1.1.0.md b/plugins/tools/batch-install-plugins/v1.1.0.md index 65ef20c..63bfeaf 100644 --- a/plugins/tools/batch-install-plugins/v1.1.0.md +++ b/plugins/tools/batch-install-plugins/v1.1.0.md @@ -8,9 +8,9 @@ Batch Install Plugins from GitHub v1.1.0 upgrades the install confirmation step ## Highlights -- **Interactive Selection Dialog**: Opens a checkbox-based browser dialog instead of using the basic confirmation event +- **Interactive Selection Dialog**: Opens a checkbox-based browser dialog with type tags and visible plugin descriptions - **Selective Installation**: The install loop now runs only for the plugins the user keeps selected -- **Repository Context**: Displays the current repository and exclusion hint inside the dialog +- **Repository Context**: Displays the current repository and only shows useful exclusion information inside the dialog - **Localized UI**: Dialog controls are localized for all supported languages - **No Workflow Regression**: Existing discovery, filtering, auto-update, and fallback connection logic remain unchanged diff --git a/plugins/tools/batch-install-plugins/v1.1.0_CN.md b/plugins/tools/batch-install-plugins/v1.1.0_CN.md index c1e4729..575c097 100644 --- a/plugins/tools/batch-install-plugins/v1.1.0_CN.md +++ b/plugins/tools/batch-install-plugins/v1.1.0_CN.md @@ -8,9 +8,9 @@ Batch Install Plugins from GitHub v1.1.0 将原本的安装确认步骤升级为 ## 亮点 -- **交互式选择对话框**:不再只使用基础 confirmation 事件,而是打开支持复选框的浏览器对话框 +- **交互式选择对话框**:不再只使用基础 confirmation 事件,而是打开带类型标签、描述信息和复选框的浏览器对话框 - **选择性安装**:安装循环只会处理用户最终保留勾选的插件 -- **仓库上下文**:对话框中会显示当前仓库与排除提示 +- **仓库上下文**:对话框中会显示当前仓库,并且只展示真正有用的排除信息 - **本地化 UI**:对话框控件已为所有支持语言提供本地化文本 - **工作流不回退**:原有的插件发现、过滤、自动更新和连接回退逻辑保持不变