feat: add repository filters to selection dialog
This commit is contained in:
@@ -11,7 +11,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta
|
||||
- **Public GitHub Support**: Install plugins from one or many public GitHub repositories
|
||||
- **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins
|
||||
- **Multi-Repository Picker**: Combine multiple repositories in one request and review them in a single grouped dialog
|
||||
- **Interactive Selection Dialog**: Filter by type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **Interactive Selection Dialog**: Filter by repository and type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **i18n**: Supports 11 languages
|
||||
|
||||
## Flow
|
||||
@@ -60,7 +60,7 @@ User Input
|
||||
|
||||
The `repo` parameter accepts one or more `owner/repo` values separated by commas, semicolons, or new lines.
|
||||
|
||||
After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event. The dialog merges results from every requested repository, groups them by repository, supports type filters and keyword search, and lets you 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. The dialog merges results from every requested repository, groups them by repository, supports repository tags, type filters, and keyword search, and lets you check exactly which plugins to install before the API calls start.
|
||||
|
||||
If one user request mentions multiple repositories, keep them in the same request so the model can pass them into a single tool call.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
- 公开 GitHub 支持:支持从一个或多个公开 GitHub 仓库安装插件
|
||||
- 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件
|
||||
- 多仓库选择器:一次请求可合并多个仓库,并在同一个分组对话框中查看
|
||||
- 交互式选择对话框:先按类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 交互式选择对话框:先按仓库和类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 国际化:支持 11 种语言
|
||||
|
||||
## 流程
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
`repo` 参数现在支持多个 `owner/repo`,可用逗号、分号或换行分隔。
|
||||
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持仓库标签、类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
|
||||
如果一次用户请求里提到了多个仓库,尽量保持在同一次请求里,让模型把它们合并到一次工具调用中。
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta
|
||||
- **Public GitHub Support**: Install plugins from one or many public GitHub repositories
|
||||
- **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins
|
||||
- **Multi-Repository Picker**: Combine multiple repositories in one request and review them in a single grouped dialog
|
||||
- **Interactive Selection Dialog**: Filter by type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **Interactive Selection Dialog**: Filter by repository and type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **i18n**: Supports 11 languages
|
||||
|
||||
## Flow
|
||||
@@ -64,7 +64,7 @@ User Input
|
||||
|
||||
The `repo` parameter accepts one or more `owner/repo` values separated by commas, semicolons, or new lines.
|
||||
|
||||
After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event. The dialog merges results from every requested repository, groups them by repository, supports type filters and keyword search, and lets you 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. The dialog merges results from every requested repository, groups them by repository, supports repository tags, type filters, and keyword search, and lets you check exactly which plugins to install before the API calls start.
|
||||
|
||||
If one user request mentions multiple repositories, keep them in the same request so the model can pass them into a single tool call.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- 公开 GitHub 支持:支持从一个或多个公开 GitHub 仓库安装插件
|
||||
- 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件
|
||||
- 多仓库选择器:一次请求可合并多个仓库,并在同一个分组对话框中查看
|
||||
- 交互式选择对话框:先按类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 交互式选择对话框:先按仓库和类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 国际化:支持 11 种语言
|
||||
|
||||
## 流程
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
`repo` 参数现在支持多个 `owner/repo`,可用逗号、分号或换行分隔。
|
||||
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持仓库标签、类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
|
||||
如果一次用户请求里提到了多个仓库,尽量保持在同一次请求里,让模型把它们合并到一次工具调用中。
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ One-click batch install plugins from GitHub repositories to your OpenWebUI insta
|
||||
- **Public GitHub Support**: Install plugins from one or many public GitHub repositories
|
||||
- **Multi-Type Support**: Supports Pipe, Action, Filter, and Tool plugins
|
||||
- **Multi-Repository Picker**: Combine multiple repositories in one request and review them in a single grouped dialog
|
||||
- **Interactive Selection Dialog**: Filter by type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **Interactive Selection Dialog**: Filter by repository and type, search by keyword, review plugin descriptions, then install only the checked subset
|
||||
- **i18n**: Supports 11 languages
|
||||
|
||||
## Flow
|
||||
@@ -64,7 +64,7 @@ User Input
|
||||
|
||||
The `repo` parameter accepts one or more `owner/repo` values separated by commas, semicolons, or new lines.
|
||||
|
||||
After plugin discovery and filtering, OpenWebUI opens a browser dialog built with the `execute` event. The dialog merges results from every requested repository, groups them by repository, supports type filters and keyword search, and lets you 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. The dialog merges results from every requested repository, groups them by repository, supports repository tags, type filters, and keyword search, and lets you check exactly which plugins to install before the API calls start.
|
||||
|
||||
If one user request mentions multiple repositories, keep them in the same request so the model can pass them into a single tool call.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
- 公开 GitHub 支持:支持从一个或多个公开 GitHub 仓库安装插件
|
||||
- 多类型支持:支持 Pipe、Action、Filter 和 Tool 插件
|
||||
- 多仓库选择器:一次请求可合并多个仓库,并在同一个分组对话框中查看
|
||||
- 交互式选择对话框:先按类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 交互式选择对话框:先按仓库和类型筛选、按关键词搜索并查看描述信息,再勾选要安装的插件,只安装所选子集
|
||||
- 国际化:支持 11 种语言
|
||||
|
||||
## 流程
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
`repo` 参数现在支持多个 `owner/repo`,可用逗号、分号或换行分隔。
|
||||
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
在插件发现和过滤完成后,OpenWebUI 会通过 `execute` 事件打开浏览器选择对话框。对话框会合并所有目标仓库的结果,按仓库分组展示,并支持仓库标签、类型筛选、关键词搜索和描述查看,再开始调用安装 API。
|
||||
|
||||
如果一次用户请求里提到了多个仓库,尽量保持在同一次请求里,让模型把它们合并到一次工具调用中。
|
||||
|
||||
|
||||
@@ -305,6 +305,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Clear all",
|
||||
"quick_select": "Filter by type",
|
||||
"all_types": "All",
|
||||
"repo_filter": "Filter by repository",
|
||||
"all_repos": "All repositories",
|
||||
"search_label": "Search",
|
||||
"search_placeholder": "Search title, description, file path...",
|
||||
"no_results": "No plugins match the current filter.",
|
||||
@@ -321,6 +323,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "清空",
|
||||
"quick_select": "按类型筛选",
|
||||
"all_types": "全部",
|
||||
"repo_filter": "按仓库筛选",
|
||||
"all_repos": "全部仓库",
|
||||
"search_label": "搜索",
|
||||
"search_placeholder": "搜索标题、描述、文件路径...",
|
||||
"no_results": "当前筛选条件下没有匹配的插件。",
|
||||
@@ -337,6 +341,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "清空",
|
||||
"quick_select": "按類型篩選",
|
||||
"all_types": "全部",
|
||||
"repo_filter": "按倉庫篩選",
|
||||
"all_repos": "全部倉庫",
|
||||
"search_label": "搜尋",
|
||||
"search_placeholder": "搜尋標題、描述、檔案路徑...",
|
||||
"no_results": "目前篩選條件下沒有相符的外掛。",
|
||||
@@ -353,6 +359,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "清空",
|
||||
"quick_select": "按類型篩選",
|
||||
"all_types": "全部",
|
||||
"repo_filter": "按倉庫篩選",
|
||||
"all_repos": "全部倉庫",
|
||||
"search_label": "搜尋",
|
||||
"search_placeholder": "搜尋標題、描述、檔案路徑...",
|
||||
"no_results": "目前篩選條件下沒有符合的外掛。",
|
||||
@@ -369,6 +377,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "선택 해제",
|
||||
"quick_select": "유형별 필터",
|
||||
"all_types": "전체",
|
||||
"repo_filter": "저장소별 필터",
|
||||
"all_repos": "전체 저장소",
|
||||
"search_label": "검색",
|
||||
"search_placeholder": "제목, 설명, 파일 경로 검색...",
|
||||
"no_results": "현재 필터와 일치하는 플러그인이 없습니다.",
|
||||
@@ -385,6 +395,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "クリア",
|
||||
"quick_select": "タイプで絞り込み",
|
||||
"all_types": "すべて",
|
||||
"repo_filter": "リポジトリで絞り込み",
|
||||
"all_repos": "すべてのリポジトリ",
|
||||
"search_label": "検索",
|
||||
"search_placeholder": "タイトル、説明、ファイルパスを検索...",
|
||||
"no_results": "現在の条件に一致するプラグインはありません。",
|
||||
@@ -401,6 +413,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Tout effacer",
|
||||
"quick_select": "Filtrer par type",
|
||||
"all_types": "Tous",
|
||||
"repo_filter": "Filtrer par dépôt",
|
||||
"all_repos": "Tous les dépôts",
|
||||
"search_label": "Rechercher",
|
||||
"search_placeholder": "Rechercher par titre, description, fichier...",
|
||||
"no_results": "Aucun plugin ne correspond au filtre actuel.",
|
||||
@@ -417,6 +431,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Auswahl löschen",
|
||||
"quick_select": "Nach Typ filtern",
|
||||
"all_types": "Alle",
|
||||
"repo_filter": "Nach Repository filtern",
|
||||
"all_repos": "Alle Repositories",
|
||||
"search_label": "Suchen",
|
||||
"search_placeholder": "Titel, Beschreibung, Dateipfad durchsuchen...",
|
||||
"no_results": "Keine Plugins entsprechen dem aktuellen Filter.",
|
||||
@@ -433,6 +449,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Limpiar",
|
||||
"quick_select": "Filtrar por tipo",
|
||||
"all_types": "Todos",
|
||||
"repo_filter": "Filtrar por repositorio",
|
||||
"all_repos": "Todos los repositorios",
|
||||
"search_label": "Buscar",
|
||||
"search_placeholder": "Buscar por titulo, descripcion o archivo...",
|
||||
"no_results": "Ningun plugin coincide con el filtro actual.",
|
||||
@@ -449,6 +467,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Cancella",
|
||||
"quick_select": "Filtra per tipo",
|
||||
"all_types": "Tutti",
|
||||
"repo_filter": "Filtra per repository",
|
||||
"all_repos": "Tutti i repository",
|
||||
"search_label": "Cerca",
|
||||
"search_placeholder": "Cerca per titolo, descrizione o file...",
|
||||
"no_results": "Nessun plugin corrisponde al filtro attuale.",
|
||||
@@ -465,6 +485,8 @@ SELECTION_DIALOG_TEXTS = {
|
||||
"clear_all": "Bỏ chọn",
|
||||
"quick_select": "Lọc theo loại",
|
||||
"all_types": "Tất cả",
|
||||
"repo_filter": "Lọc theo kho",
|
||||
"all_repos": "Tất cả kho",
|
||||
"search_label": "Tìm kiếm",
|
||||
"search_placeholder": "Tìm theo tiêu đề, mô tả, đường dẫn tệp...",
|
||||
"no_results": "Không có plugin nào khớp với bộ lọc hiện tại.",
|
||||
@@ -1006,6 +1028,7 @@ def _build_selection_dialog_js(
|
||||
" }",
|
||||
" const selected = new Set(options.map((item) => item.id));",
|
||||
" let activeFilter = '';",
|
||||
" let activeRepoFilter = '';",
|
||||
" let searchTerm = '';",
|
||||
" const escapeHtml = (value) => String(value ?? '').replace(/[&<>\"']/g, (char) => ({",
|
||||
" '&': '&',",
|
||||
@@ -1056,6 +1079,10 @@ def _build_selection_dialog_js(
|
||||
" <div style=\"font-size:12px;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:0.04em\">${escapeHtml(ui.quick_select)}</div>",
|
||||
" <div id=\"batch-install-plugin-selector-types\" style=\"display:flex;gap:8px;flex-wrap:wrap\"></div>",
|
||||
" </div>",
|
||||
" <div id=\"batch-install-plugin-selector-repo-row\" style=\"display:flex;gap:10px;align-items:center;flex-wrap:wrap\">",
|
||||
" <div style=\"font-size:12px;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:0.04em\">${escapeHtml(ui.repo_filter)}</div>",
|
||||
" <div id=\"batch-install-plugin-selector-repos\" style=\"display:flex;gap:8px;flex-wrap:wrap\"></div>",
|
||||
" </div>",
|
||||
" <div style=\"display:grid;gap:6px\">",
|
||||
" <div style=\"font-size:12px;font-weight:700;color:#475569;text-transform:uppercase;letter-spacing:0.04em\">${escapeHtml(ui.search_label)}</div>",
|
||||
" <input id=\"batch-install-plugin-selector-search\" type=\"text\" placeholder=\"${escapeHtml(ui.search_placeholder)}\" style=\"width:100%;padding:10px 12px;border:1px solid #cbd5e1;border-radius:12px;background:#fff;color:#0f172a;font-size:14px;outline:none;box-sizing:border-box\" />",
|
||||
@@ -1076,6 +1103,8 @@ def _build_selection_dialog_js(
|
||||
" 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 repoRowEl = overlay.querySelector('#batch-install-plugin-selector-repo-row');",
|
||||
" const reposEl = overlay.querySelector('#batch-install-plugin-selector-repos');",
|
||||
" const searchInput = overlay.querySelector('#batch-install-plugin-selector-search');",
|
||||
" const submitBtn = overlay.querySelector('#batch-install-plugin-selector-submit');",
|
||||
" const cancelBtn = overlay.querySelector('#batch-install-plugin-selector-cancel');",
|
||||
@@ -1088,18 +1117,37 @@ def _build_selection_dialog_js(
|
||||
" groups[item.type].push(item);",
|
||||
" return groups;",
|
||||
" }, {});",
|
||||
" const repoMap = options.reduce((groups, item) => {",
|
||||
" if (!groups[item.repo]) {",
|
||||
" groups[item.repo] = [];",
|
||||
" }",
|
||||
" groups[item.repo].push(item);",
|
||||
" return groups;",
|
||||
" }, {});",
|
||||
" const typeEntries = Object.entries(typeMap);",
|
||||
" const repoEntries = Object.entries(repoMap);",
|
||||
" const matchesSearch = (item) => {",
|
||||
" const haystack = [item.title, item.description, item.file_path, item.type, item.repo].join(' ').toLowerCase();",
|
||||
" return !searchTerm || haystack.includes(searchTerm);",
|
||||
" };",
|
||||
" const getVisibleOptions = () => options.filter((item) => {",
|
||||
" const matchesType = !activeFilter || item.type === activeFilter;",
|
||||
" const haystack = [item.title, item.description, item.file_path, item.type, item.repo].join(' ').toLowerCase();",
|
||||
" const matchesSearch = !searchTerm || haystack.includes(searchTerm);",
|
||||
" return matchesType && matchesSearch;",
|
||||
" const matchesRepo = !activeRepoFilter || item.repo === activeRepoFilter;",
|
||||
" return matchesType && matchesRepo && matchesSearch(item);",
|
||||
" });",
|
||||
" const syncSelectionToVisible = () => {",
|
||||
" selected.clear();",
|
||||
" getVisibleOptions().forEach((item) => selected.add(item.id));",
|
||||
" };",
|
||||
" const formatMultilineText = (value) => escapeHtml(value).replace(/\\n+/g, '<br />');",
|
||||
" hintEl.textContent = ui.hint || '';",
|
||||
" hintEl.style.display = ui.hint ? 'block' : 'none';",
|
||||
" const renderTypeButtons = () => {",
|
||||
" const filterEntries = [['', options], ...typeEntries];",
|
||||
" const scopedOptions = options.filter((item) => {",
|
||||
" const matchesRepo = !activeRepoFilter || item.repo === activeRepoFilter;",
|
||||
" return matchesRepo && matchesSearch(item);",
|
||||
" });",
|
||||
" const filterEntries = [['', scopedOptions], ...typeEntries.map(([type]) => [type, scopedOptions.filter((item) => item.type === type)])];",
|
||||
" typesEl.innerHTML = filterEntries.map(([type, items]) => {",
|
||||
" const isActive = activeFilter === type;",
|
||||
" const background = isActive ? '#0f172a' : '#ffffff';",
|
||||
@@ -1117,8 +1165,42 @@ def _build_selection_dialog_js(
|
||||
" button.addEventListener('click', () => {",
|
||||
" const pluginType = button.getAttribute('data-plugin-type') || '';",
|
||||
" activeFilter = activeFilter === pluginType ? '' : pluginType;",
|
||||
" selected.clear();",
|
||||
" getVisibleOptions().forEach((item) => selected.add(item.id));",
|
||||
" syncSelectionToVisible();",
|
||||
" renderList();",
|
||||
" });",
|
||||
" });",
|
||||
" };",
|
||||
" const renderRepoButtons = () => {",
|
||||
" if (repoEntries.length <= 1) {",
|
||||
" repoRowEl.style.display = 'none';",
|
||||
" reposEl.innerHTML = '';",
|
||||
" activeRepoFilter = '';",
|
||||
" return;",
|
||||
" }",
|
||||
" repoRowEl.style.display = 'flex';",
|
||||
" const scopedOptions = options.filter((item) => {",
|
||||
" const matchesType = !activeFilter || item.type === activeFilter;",
|
||||
" return matchesType && matchesSearch(item);",
|
||||
" });",
|
||||
" const filterEntries = [['', scopedOptions], ...repoEntries.map(([repoName]) => [repoName, scopedOptions.filter((item) => item.repo === repoName)])];",
|
||||
" reposEl.innerHTML = filterEntries.map(([repoName, items]) => {",
|
||||
" const isActive = activeRepoFilter === repoName;",
|
||||
" const background = isActive ? '#1d4ed8' : '#ffffff';",
|
||||
" const color = isActive ? '#ffffff' : '#1d4ed8';",
|
||||
" const border = isActive ? '#1d4ed8' : '#bfdbfe';",
|
||||
" const label = repoName || ui.all_repos;",
|
||||
" return `",
|
||||
" <button type=\"button\" data-plugin-repo=\"${escapeHtml(repoName)}\" style=\"padding:7px 12px;border:1px solid ${border};border-radius:999px;background:${background};color:${color};font-size:12px;font-weight:700;cursor:pointer;display:inline-flex;gap:8px;align-items:center\">",
|
||||
" <span>${escapeHtml(label)}</span>",
|
||||
" <span style=\"display:inline-flex;align-items:center;justify-content:center;min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:${isActive ? 'rgba(255,255,255,0.16)' : '#dbeafe'};color:${isActive ? '#ffffff' : '#1e3a8a'}\">${items.length}</span>",
|
||||
" </button>",
|
||||
" `;",
|
||||
" }).join('');",
|
||||
" reposEl.querySelectorAll('button[data-plugin-repo]').forEach((button) => {",
|
||||
" button.addEventListener('click', () => {",
|
||||
" const repoName = button.getAttribute('data-plugin-repo') || '';",
|
||||
" activeRepoFilter = activeRepoFilter === repoName ? '' : repoName;",
|
||||
" syncSelectionToVisible();",
|
||||
" renderList();",
|
||||
" });",
|
||||
" });",
|
||||
@@ -1129,6 +1211,7 @@ def _build_selection_dialog_js(
|
||||
" submitBtn.style.opacity = selected.size === 0 ? '0.45' : '1';",
|
||||
" submitBtn.style.cursor = selected.size === 0 ? 'not-allowed' : 'pointer';",
|
||||
" renderTypeButtons();",
|
||||
" renderRepoButtons();",
|
||||
" };",
|
||||
" const renderOptionCard = (item) => {",
|
||||
" const checked = selected.has(item.id) ? 'checked' : '';",
|
||||
@@ -1144,9 +1227,10 @@ def _build_selection_dialog_js(
|
||||
" <div style=\"min-width:0;display:grid;gap:6px\">",
|
||||
" <div style=\"display:flex;gap:10px;align-items:center;flex-wrap:wrap\">",
|
||||
" <span style=\"display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:#f1f5f9;color:#334155;font-size:12px;font-weight:700;text-transform:uppercase\">${escapeHtml(item.type)}</span>",
|
||||
" <span style=\"display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:#eff6ff;color:#1d4ed8;font-size:12px;font-weight:700\">${escapeHtml(item.repo)}</span>",
|
||||
" <span style=\"font-size:15px;font-weight:700;color:#0f172a;word-break:break-word\">${escapeHtml(item.title)}</span>",
|
||||
" </div>",
|
||||
" <div style=\"font-size:12px;color:#475569;word-break:break-word\">${escapeHtml(ui.repo_label)}: ${escapeHtml(item.repo)} · ${escapeHtml(ui.version_label)}: ${escapeHtml(item.version)} · ${escapeHtml(ui.file_label)}: ${escapeHtml(item.file_path)}</div>",
|
||||
" <div style=\"font-size:12px;color:#475569;word-break:break-word\">${escapeHtml(ui.version_label)}: ${escapeHtml(item.version)} · ${escapeHtml(ui.file_label)}: ${escapeHtml(item.file_path)}</div>",
|
||||
" ${description}",
|
||||
" </div>",
|
||||
" </label>",
|
||||
@@ -1169,7 +1253,7 @@ def _build_selection_dialog_js(
|
||||
" listEl.innerHTML = Object.entries(groups).map(([repoName, items]) => `",
|
||||
" <section style=\"display:grid;gap:10px\">",
|
||||
" <div style=\"display:flex;justify-content:space-between;gap:12px;align-items:center;flex-wrap:wrap;padding:0 2px\">",
|
||||
" <div style=\"font-size:13px;font-weight:700;color:#0f172a;word-break:break-word\">${escapeHtml(repoName)}</div>",
|
||||
" <div style=\"display:inline-flex;align-items:center;gap:8px;padding:6px 12px;border-radius:999px;background:#eff6ff;color:#1d4ed8;font-size:12px;font-weight:700;word-break:break-word\">${escapeHtml(repoName)}</div>",
|
||||
" <div style=\"display:inline-flex;align-items:center;gap:8px;padding:4px 10px;border-radius:999px;background:#f8fafc;color:#475569;font-size:12px;font-weight:600\">${items.length}</div>",
|
||||
" </div>",
|
||||
" <div style=\"display:grid;gap:12px\">${items.map((item) => renderOptionCard(item)).join('')}</div>",
|
||||
@@ -1219,8 +1303,7 @@ def _build_selection_dialog_js(
|
||||
" });",
|
||||
" searchInput.addEventListener('input', () => {",
|
||||
" searchTerm = searchInput.value.trim().toLowerCase();",
|
||||
" selected.clear();",
|
||||
" getVisibleOptions().forEach((item) => selected.add(item.id));",
|
||||
" syncSelectionToVisible();",
|
||||
" renderList();",
|
||||
" });",
|
||||
" cancelBtn.addEventListener('click', () => finish(false));",
|
||||
@@ -1279,6 +1362,8 @@ async def _request_plugin_selection(
|
||||
"clear_all": _selection_t(lang, "clear_all"),
|
||||
"quick_select": _selection_t(lang, "quick_select"),
|
||||
"all_types": _selection_t(lang, "all_types"),
|
||||
"repo_filter": _selection_t(lang, "repo_filter"),
|
||||
"all_repos": _selection_t(lang, "all_repos"),
|
||||
"search_label": _selection_t(lang, "search_label"),
|
||||
"search_placeholder": _selection_t(lang, "search_placeholder"),
|
||||
"no_results": _selection_t(lang, "no_results"),
|
||||
|
||||
Reference in New Issue
Block a user