Spaces:
Running
Running
Download webui/components/plugins/list/pluginListStore.js from Leon4gr45/openoperator: direct link, hf CLI and curl.
- Browser
- Download file 7.71 kB
-
https://huggingface.co/spaces/Leon4gr45/openoperator/resolve/main/webui/components/plugins/list/pluginListStore.js
- Command line
-
hf download hf://spaces/Leon4gr45/openoperator/webui/components/plugins/list/pluginListStore.js
-
curl -L -o pluginListStore.js https://huggingface.co/spaces/Leon4gr45/openoperator/resolve/main/webui/components/plugins/list/pluginListStore.js
7.71 kB
| import { createStore } from "/js/AlpineStore.js"; | |
| import * as api from "/js/api.js"; | |
| import { renderSafeMarkdown } from "/js/safe-markdown.js"; | |
| import { store as pluginSettingsStore } from "/components/plugins/plugin-settings-store.js"; | |
| import { store as pluginExecuteStore } from "/components/plugins/list/plugin-execute-store.js"; | |
| import { store as fileBrowserStore } from "/components/modals/file-browser/file-browser-store.js"; | |
| import { store as markdownModalStore } from "/components/modals/markdown/markdown-store.js"; | |
| import { callJsExtensions } from "/js/extensions.js"; | |
| import { | |
| store as notificationStore, | |
| defaultPriority, | |
| } from "/components/notifications/notification-store.js"; | |
| const MODAL_PATH = "components/plugins/list/plugin-list.html"; | |
| // define the model object holding data and functions | |
| const model = { | |
| loading: false, | |
| plugins: [], | |
| selectedPlugin: null, | |
| activeTab: "custom", | |
| readmeContent: "", | |
| readmeLoading: false, | |
| readmeError: "", | |
| async open(tab = "custom") { | |
| await this.setTab(tab); | |
| window.openModal?.(MODAL_PATH); | |
| }, | |
| async init() { | |
| this.loading = false; | |
| // If a tab is already selected (e.g. via open()), use it. | |
| // Otherwise default to custom -> builtin fallback. | |
| if (this.activeTab && this.activeTab !== "custom") { | |
| await this.setTab(this.activeTab); | |
| } else { | |
| await this.setTab("custom"); | |
| if (this.plugins.length === 0) { | |
| await this.setTab("builtin"); | |
| } | |
| } | |
| }, | |
| async loadPluginList(filter) { | |
| this.loading = true; | |
| this.selectedPlugin = null; | |
| try { | |
| const response = await api.callJsonApi("plugins_list", { filter }); | |
| this.plugins = Array.isArray(response.plugins) ? response.plugins : []; | |
| void callJsExtensions("plugins_list_after_load", { | |
| filter: filter ? { ...filter } : null, | |
| plugins: this.plugins, | |
| store: this, | |
| }); | |
| } catch (e) { | |
| this.plugins = []; | |
| showErrorNotification(e, "Failed to load plugins list"); | |
| } finally { | |
| this.loading = false; | |
| } | |
| }, | |
| async setTab(tab) { | |
| if (tab === "pluginHub") { | |
| this.activeTab = "pluginHub"; | |
| this.loading = false; | |
| return; | |
| } | |
| this.activeTab = tab === "builtin" ? "builtin" : "custom"; | |
| const filter = | |
| this.activeTab === "builtin" | |
| ? { builtin: true, custom: false, search: "" } | |
| : { builtin: false, custom: true, search: "" }; | |
| await this.loadPluginList(filter); | |
| }, | |
| async refresh() { | |
| if (this.activeTab === "pluginHub") { | |
| return; | |
| } | |
| await this.setTab(this.activeTab); | |
| }, | |
| openPlugin(plugin) { | |
| if (!plugin?.name || !plugin?.has_main_screen) return; | |
| window.openModal?.(`/plugins/${plugin.name}/webui/main.html`); | |
| }, | |
| openPluginExecute(plugin) { | |
| if (!plugin?.name || !plugin?.has_execute_script) return; | |
| pluginExecuteStore.open(plugin); | |
| }, | |
| canOpenPluginConfig(plugin) { | |
| return !!( | |
| plugin?.has_config_screen || | |
| plugin?.per_project_config || | |
| plugin?.per_agent_config | |
| ); | |
| }, | |
| async openPluginConfig(pluginOrName) { | |
| const pluginName = | |
| typeof pluginOrName === "string" ? pluginOrName : pluginOrName?.name; | |
| if (!pluginName) return; | |
| if ( | |
| typeof pluginOrName === "object" && | |
| !this.canOpenPluginConfig(pluginOrName) | |
| ) | |
| return; | |
| try { | |
| if (!pluginSettingsStore?.openConfig) { | |
| throw new Error("Plugin settings store is unavailable."); | |
| } | |
| await pluginSettingsStore.openConfig(pluginName); | |
| } catch (e) { | |
| showErrorNotification(e, "Failed to open plugin config"); | |
| } | |
| }, | |
| isPluginEnabled(plugin) { | |
| if (plugin?.always_enabled) return true; | |
| return plugin?.toggle_state === "enabled"; | |
| }, | |
| toggleStatusLabel(plugin) { | |
| return this.isPluginEnabled(plugin) ? "ON" : "OFF"; | |
| }, | |
| async updateToggle(plugin, enabled) { | |
| if (!plugin?.name) return; | |
| if (plugin.always_enabled) return; | |
| const nextEnabled = !!enabled; | |
| const previousState = plugin.toggle_state; | |
| plugin.toggle_state = nextEnabled ? "enabled" : "disabled"; | |
| this.loading = true; | |
| try { | |
| const response = await api.callJsonApi("plugins", { | |
| action: "toggle_plugin", | |
| plugin_name: plugin.name, | |
| enabled: nextEnabled, | |
| project_name: "", | |
| agent_profile: "", | |
| clear_overrides: false, | |
| }); | |
| if (response?.error) throw new Error(response.error); | |
| await this.refresh(); | |
| } catch (e) { | |
| plugin.toggle_state = previousState; | |
| showErrorNotification(e, "Failed to toggle plugin"); | |
| this.loading = false; | |
| } | |
| }, | |
| async openPluginDoc(plugin, doc) { | |
| try { | |
| const response = await api.callJsonApi("plugins", { | |
| action: "get_doc", | |
| plugin_name: plugin.name, | |
| doc, | |
| }); | |
| if (response?.error) throw new Error(response.error); | |
| if (!markdownModalStore?.open) throw new Error("Markdown modal store unavailable."); | |
| markdownModalStore.open(response.filename, response.content); | |
| window.openModal?.("components/modals/markdown/markdown-modal.html"); | |
| } catch (e) { | |
| showErrorNotification(e, "Failed to open document"); | |
| } | |
| }, | |
| async loadPluginReadme(plugin) { | |
| this.readmeLoading = true; | |
| this.readmeContent = ""; | |
| this.readmeError = ""; | |
| try { | |
| const response = await api.callJsonApi("plugins", { | |
| action: "get_doc", | |
| plugin_name: plugin.name, | |
| doc: "readme", | |
| }); | |
| if (response?.error) throw new Error(response.error); | |
| this.readmeContent = renderSafeMarkdown(response.content || ""); | |
| } catch (e) { | |
| const error = e instanceof Error ? e : new Error(String(e)); | |
| this.readmeError = error.message || "Failed to load README"; | |
| } finally { | |
| this.readmeLoading = false; | |
| } | |
| }, | |
| openPluginInfo(plugin) { | |
| if (!plugin) return; | |
| this.selectedPlugin = plugin; | |
| this.readmeContent = ""; | |
| this.readmeLoading = false; | |
| this.readmeError = ""; | |
| if (plugin.has_readme) { | |
| void this.loadPluginReadme(plugin); | |
| } | |
| window.openModal?.("components/plugins/plugin-info.html"); | |
| }, | |
| async openPluginFolder(plugin) { | |
| if (!plugin?.path) return; | |
| await fileBrowserStore.open(plugin.path); | |
| }, | |
| async openPluginHub(plugin) { | |
| const pluginKey = (plugin?.pluginHub?.key || "").trim(); | |
| if (!pluginKey) return; | |
| const { store: pluginInstallStore } = await import( | |
| "/plugins/_plugin_installer/webui/pluginInstallStore.js" | |
| ); | |
| await pluginInstallStore.openPluginHubDetailByKey(pluginKey); | |
| }, | |
| async deletePlugin(plugin) { | |
| if (!plugin?.name) return; | |
| if (!plugin.is_custom) { | |
| showErrorNotification( | |
| new Error("Only custom plugins can be deleted from this modal."), | |
| "Delete blocked", | |
| ); | |
| return; | |
| } | |
| try { | |
| const response = await api.callJsonApi("plugins", { | |
| action: "delete_plugin", | |
| plugin_name: plugin.name, | |
| }); | |
| if (response?.error) { | |
| throw new Error(response.error); | |
| } | |
| if (window.toastFrontendSuccess) { | |
| window.toastFrontendSuccess("Plugin deleted", "Plugins"); | |
| } | |
| await this.refresh(); | |
| } catch (e) { | |
| showErrorNotification(e, "Failed to delete plugin"); | |
| } | |
| }, | |
| }; | |
| function showErrorNotification(error, heading) { | |
| const text = error.message || error.text || JSON.stringify(error); | |
| notificationStore.frontendError( | |
| text, | |
| heading, | |
| 3, | |
| "pluginsList", | |
| defaultPriority, | |
| true, | |
| ); | |
| } | |
| // convert it to alpine store | |
| const store = createStore("pluginListStore", model); | |
| // export for use in other files | |
| export { store }; | |