mirror of
				https://github.com/louislam/uptime-kuma.git
				synced 2025-10-31 19:39:20 +08:00 
			
		
		
		
	Merge pull request #3346 from louislam/revert-plugin-code
Drop unused code
This commit is contained in:
		
							
								
								
									
										19
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										19
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -133,6 +133,15 @@ | ||||
|                 "node": "14.* || 16.* || 18.*" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@aashutoshrathi/word-wrap": { | ||||
|             "version": "1.2.6", | ||||
|             "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", | ||||
|             "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", | ||||
|             "dev": true, | ||||
|             "engines": { | ||||
|                 "node": ">=0.10.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@actions/github": { | ||||
|             "version": "5.0.3", | ||||
|             "resolved": "https://registry.npmjs.org/@actions/github/-/github-5.0.3.tgz", | ||||
| @@ -15193,17 +15202,17 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/optionator": { | ||||
|             "version": "0.9.1", | ||||
|             "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", | ||||
|             "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", | ||||
|             "version": "0.9.3", | ||||
|             "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", | ||||
|             "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", | ||||
|             "dev": true, | ||||
|             "dependencies": { | ||||
|                 "@aashutoshrathi/word-wrap": "^1.2.3", | ||||
|                 "deep-is": "^0.1.3", | ||||
|                 "fast-levenshtein": "^2.0.6", | ||||
|                 "levn": "^0.4.1", | ||||
|                 "prelude-ls": "^1.2.1", | ||||
|                 "type-check": "^0.4.0", | ||||
|                 "word-wrap": "^1.2.3" | ||||
|                 "type-check": "^0.4.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": ">= 0.8.0" | ||||
|   | ||||
| @@ -3,7 +3,7 @@ const { R } = require("redbean-node"); | ||||
| const { setSetting, setting } = require("./util-server"); | ||||
| const { log, sleep } = require("../src/util"); | ||||
| const knex = require("knex"); | ||||
| const { PluginsManager } = require("./plugins-manager"); | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * Database & App Data Folder | ||||
| @@ -88,12 +88,6 @@ class Database { | ||||
|         // Data Directory (must be end with "/") | ||||
|         Database.dataDir = process.env.DATA_DIR || args["data-dir"] || "./data/"; | ||||
|  | ||||
|         // Plugin feature is working only if the dataDir = "./data"; | ||||
|         if (Database.dataDir !== "./data/") { | ||||
|             log.warn("PLUGIN", "Warning: In order to enable plugin feature, you need to use the default data directory: ./data/"); | ||||
|             PluginsManager.disable = true; | ||||
|         } | ||||
|  | ||||
|         Database.path = Database.dataDir + "kuma.db"; | ||||
|         if (! fs.existsSync(Database.dataDir)) { | ||||
|             fs.mkdirSync(Database.dataDir, { recursive: true }); | ||||
|   | ||||
| @@ -1,24 +0,0 @@ | ||||
| const childProcess = require("child_process"); | ||||
|  | ||||
| class Git { | ||||
|  | ||||
|     static clone(repoURL, cwd, targetDir = ".") { | ||||
|         let result = childProcess.spawnSync("git", [ | ||||
|             "clone", | ||||
|             repoURL, | ||||
|             targetDir, | ||||
|         ], { | ||||
|             cwd: cwd, | ||||
|         }); | ||||
|  | ||||
|         if (result.status !== 0) { | ||||
|             throw new Error(result.stderr.toString("utf-8")); | ||||
|         } else { | ||||
|             return result.stdout.toString("utf-8") + result.stderr.toString("utf-8"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     Git, | ||||
| }; | ||||
| @@ -1,13 +0,0 @@ | ||||
| class Plugin { | ||||
|     async load() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     async unload() { | ||||
|  | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     Plugin, | ||||
| }; | ||||
| @@ -1,256 +0,0 @@ | ||||
| const fs = require("fs"); | ||||
| const { log } = require("../src/util"); | ||||
| const path = require("path"); | ||||
| const axios = require("axios"); | ||||
| const { Git } = require("./git"); | ||||
| const childProcess = require("child_process"); | ||||
|  | ||||
| class PluginsManager { | ||||
|  | ||||
|     static disable = false; | ||||
|  | ||||
|     /** | ||||
|      * Plugin List | ||||
|      * @type {PluginWrapper[]} | ||||
|      */ | ||||
|     pluginList = []; | ||||
|  | ||||
|     /** | ||||
|      * Plugins Dir | ||||
|      */ | ||||
|     pluginsDir; | ||||
|  | ||||
|     server; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param {UptimeKumaServer} server | ||||
|      */ | ||||
|     constructor(server) { | ||||
|         this.server = server; | ||||
|  | ||||
|         if (!PluginsManager.disable) { | ||||
|             this.pluginsDir = "./data/plugins/"; | ||||
|  | ||||
|             if (! fs.existsSync(this.pluginsDir)) { | ||||
|                 fs.mkdirSync(this.pluginsDir, { recursive: true }); | ||||
|             } | ||||
|  | ||||
|             log.debug("plugin", "Scanning plugin directory"); | ||||
|             let list = fs.readdirSync(this.pluginsDir); | ||||
|  | ||||
|             this.pluginList = []; | ||||
|             for (let item of list) { | ||||
|                 this.loadPlugin(item); | ||||
|             } | ||||
|  | ||||
|         } else { | ||||
|             log.warn("PLUGIN", "Skip scanning plugin directory"); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Install a Plugin | ||||
|      */ | ||||
|     async loadPlugin(name) { | ||||
|         log.info("plugin", "Load " + name); | ||||
|         let plugin = new PluginWrapper(this.server, this.pluginsDir + name); | ||||
|  | ||||
|         try { | ||||
|             await plugin.load(); | ||||
|             this.pluginList.push(plugin); | ||||
|         } catch (e) { | ||||
|             log.error("plugin", "Failed to load plugin: " + this.pluginsDir + name); | ||||
|             log.error("plugin", "Reason: " + e.message); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Download a Plugin | ||||
|      * @param {string} repoURL Git repo url | ||||
|      * @param {string} name Directory name, also known as plugin unique name | ||||
|      */ | ||||
|     downloadPlugin(repoURL, name) { | ||||
|         if (fs.existsSync(this.pluginsDir + name)) { | ||||
|             log.info("plugin", "Plugin folder already exists? Removing..."); | ||||
|             fs.rmSync(this.pluginsDir + name, { | ||||
|                 recursive: true | ||||
|             }); | ||||
|         } | ||||
|         log.info("plugin", "Installing plugin: " + name + " " + repoURL); | ||||
|         let result = Git.clone(repoURL, this.pluginsDir, name); | ||||
|         log.info("plugin", "Install result: " + result); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Remove a plugin | ||||
|      * @param {string} name | ||||
|      */ | ||||
|     async removePlugin(name) { | ||||
|         log.info("plugin", "Removing plugin: " + name); | ||||
|         for (let plugin of this.pluginList) { | ||||
|             if (plugin.info.name === name) { | ||||
|                 await plugin.unload(); | ||||
|  | ||||
|                 // Delete the plugin directory | ||||
|                 fs.rmSync(this.pluginsDir + name, { | ||||
|                     recursive: true | ||||
|                 }); | ||||
|  | ||||
|                 this.pluginList.splice(this.pluginList.indexOf(plugin), 1); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         log.warn("plugin", "Plugin not found: " + name); | ||||
|         throw new Error("Plugin not found: " + name); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * TODO: Update a plugin | ||||
|      * Only available for plugins which were downloaded from the official list | ||||
|      * @param pluginID | ||||
|      */ | ||||
|     updatePlugin(pluginID) { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the plugin list from server + local installed plugin list | ||||
|      * Item will be merged if the `name` is the same. | ||||
|      * @returns {Promise<[]>} | ||||
|      */ | ||||
|     async fetchPluginList() { | ||||
|         let remotePluginList; | ||||
|         try { | ||||
|             const res = await axios.get("https://uptime.kuma.pet/c/plugins.json"); | ||||
|             remotePluginList = res.data.pluginList; | ||||
|         } catch (e) { | ||||
|             log.error("plugin", "Failed to fetch plugin list: " + e.message); | ||||
|             remotePluginList = []; | ||||
|         } | ||||
|  | ||||
|         for (let plugin of this.pluginList) { | ||||
|             let find = false; | ||||
|             // Try to merge | ||||
|             for (let remotePlugin of remotePluginList) { | ||||
|                 if (remotePlugin.name === plugin.info.name) { | ||||
|                     find = true; | ||||
|                     remotePlugin.installed = true; | ||||
|                     remotePlugin.name = plugin.info.name; | ||||
|                     remotePlugin.fullName = plugin.info.fullName; | ||||
|                     remotePlugin.description = plugin.info.description; | ||||
|                     remotePlugin.version = plugin.info.version; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Local plugin | ||||
|             if (!find) { | ||||
|                 plugin.info.local = true; | ||||
|                 remotePluginList.push(plugin.info); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Sort Installed first, then sort by name | ||||
|         return remotePluginList.sort((a, b) => { | ||||
|             if (a.installed === b.installed) { | ||||
|                 if (a.fullName < b.fullName) { | ||||
|                     return -1; | ||||
|                 } | ||||
|                 if (a.fullName > b.fullName) { | ||||
|                     return 1; | ||||
|                 } | ||||
|                 return 0; | ||||
|             } else if (a.installed) { | ||||
|                 return -1; | ||||
|             } else { | ||||
|                 return 1; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| class PluginWrapper { | ||||
|  | ||||
|     server = undefined; | ||||
|     pluginDir = undefined; | ||||
|  | ||||
|     /** | ||||
|      * Must be an `new-able` class. | ||||
|      * @type {function} | ||||
|      */ | ||||
|     pluginClass = undefined; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @type {Plugin} | ||||
|      */ | ||||
|     object = undefined; | ||||
|     info = {}; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param {UptimeKumaServer} server | ||||
|      * @param {string} pluginDir | ||||
|      */ | ||||
|     constructor(server, pluginDir) { | ||||
|         this.server = server; | ||||
|         this.pluginDir = pluginDir; | ||||
|     } | ||||
|  | ||||
|     async load() { | ||||
|         let indexFile = this.pluginDir + "/index.js"; | ||||
|         let packageJSON = this.pluginDir + "/package.json"; | ||||
|  | ||||
|         log.info("plugin", "Installing dependencies"); | ||||
|  | ||||
|         if (fs.existsSync(indexFile)) { | ||||
|             // Install dependencies | ||||
|             let result = childProcess.spawnSync("npm", [ "install" ], { | ||||
|                 cwd: this.pluginDir, | ||||
|                 env: { | ||||
|                     ...process.env, | ||||
|                     PLAYWRIGHT_BROWSERS_PATH: "../../browsers",    // Special handling for read-browser-monitor | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|             if (result.stdout) { | ||||
|                 log.info("plugin", "Install dependencies result: " + result.stdout.toString("utf-8")); | ||||
|             } else { | ||||
|                 log.warn("plugin", "Install dependencies result: no output"); | ||||
|             } | ||||
|  | ||||
|             this.pluginClass = require(path.join(process.cwd(), indexFile)); | ||||
|  | ||||
|             let pluginClassType = typeof this.pluginClass; | ||||
|  | ||||
|             if (pluginClassType === "function") { | ||||
|                 this.object = new this.pluginClass(this.server); | ||||
|                 await this.object.load(); | ||||
|             } else { | ||||
|                 throw new Error("Invalid plugin, it does not export a class"); | ||||
|             } | ||||
|  | ||||
|             if (fs.existsSync(packageJSON)) { | ||||
|                 this.info = require(path.join(process.cwd(), packageJSON)); | ||||
|             } else { | ||||
|                 this.info.fullName = this.pluginDir; | ||||
|                 this.info.name = "[unknown]"; | ||||
|                 this.info.version = "[unknown-version]"; | ||||
|             } | ||||
|  | ||||
|             this.info.installed = true; | ||||
|             log.info("plugin", `${this.info.fullName} v${this.info.version} loaded`); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     async unload() { | ||||
|         await this.object.unload(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|     PluginsManager, | ||||
|     PluginWrapper | ||||
| }; | ||||
| @@ -147,7 +147,6 @@ const { apiKeySocketHandler } = require("./socket-handlers/api-key-socket-handle | ||||
| const { generalSocketHandler } = require("./socket-handlers/general-socket-handler"); | ||||
| const { Settings } = require("./settings"); | ||||
| const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent"); | ||||
| const { pluginsHandler } = require("./socket-handlers/plugins-handler"); | ||||
| const apicache = require("./modules/apicache"); | ||||
|  | ||||
| app.use(express.json()); | ||||
| @@ -177,7 +176,6 @@ let needSetup = false; | ||||
|     Database.init(args); | ||||
|     await initDatabase(testMode); | ||||
|     await server.initAfterDatabaseReady(); | ||||
|     server.loadPlugins(); | ||||
|     server.entryPage = await Settings.get("entryPage"); | ||||
|     await StatusPage.loadDomainMappingList(); | ||||
|  | ||||
| @@ -1537,7 +1535,6 @@ let needSetup = false; | ||||
|         maintenanceSocketHandler(socket); | ||||
|         apiKeySocketHandler(socket); | ||||
|         generalSocketHandler(socket, server); | ||||
|         pluginsHandler(socket, server); | ||||
|  | ||||
|         log.debug("server", "added all socket handlers"); | ||||
|  | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| const { checkLogin } = require("../util-server"); | ||||
| const { PluginsManager } = require("../plugins-manager"); | ||||
| const { log } = require("../../src/util.js"); | ||||
|  | ||||
| /** | ||||
|  * Handlers for plugins | ||||
|  * @param {Socket} socket Socket.io instance | ||||
|  * @param {UptimeKumaServer} server | ||||
|  */ | ||||
| module.exports.pluginsHandler = (socket, server) => { | ||||
|  | ||||
|     const pluginManager = server.getPluginManager(); | ||||
|  | ||||
|     // Get Plugin List | ||||
|     socket.on("getPluginList", async (callback) => { | ||||
|         try { | ||||
|             checkLogin(socket); | ||||
|  | ||||
|             log.debug("plugin", "PluginManager.disable: " + PluginsManager.disable); | ||||
|  | ||||
|             if (PluginsManager.disable) { | ||||
|                 throw new Error("Plugin Disabled: In order to enable plugin feature, you need to use the default data directory: ./data/"); | ||||
|             } | ||||
|  | ||||
|             let pluginList = await pluginManager.fetchPluginList(); | ||||
|             callback({ | ||||
|                 ok: true, | ||||
|                 pluginList, | ||||
|             }); | ||||
|         } catch (error) { | ||||
|             log.warn("plugin", "Error: " + error.message); | ||||
|             callback({ | ||||
|                 ok: false, | ||||
|                 msg: error.message, | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     socket.on("installPlugin", async (repoURL, name, callback) => { | ||||
|         try { | ||||
|             checkLogin(socket); | ||||
|             pluginManager.downloadPlugin(repoURL, name); | ||||
|             await pluginManager.loadPlugin(name); | ||||
|             callback({ | ||||
|                 ok: true, | ||||
|             }); | ||||
|         } catch (error) { | ||||
|             callback({ | ||||
|                 ok: false, | ||||
|                 msg: error.message, | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     socket.on("uninstallPlugin", async (name, callback) => { | ||||
|         try { | ||||
|             checkLogin(socket); | ||||
|             await pluginManager.removePlugin(name); | ||||
|             callback({ | ||||
|                 ok: true, | ||||
|             }); | ||||
|         } catch (error) { | ||||
|             callback({ | ||||
|                 ok: false, | ||||
|                 msg: error.message, | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
| }; | ||||
| @@ -10,7 +10,6 @@ const util = require("util"); | ||||
| const { CacheableDnsHttpAgent } = require("./cacheable-dns-http-agent"); | ||||
| const { Settings } = require("./settings"); | ||||
| const dayjs = require("dayjs"); | ||||
| const { PluginsManager } = require("./plugins-manager"); | ||||
| // DO NOT IMPORT HERE IF THE MODULES USED `UptimeKumaServer.getInstance()` | ||||
|  | ||||
| /** | ||||
| @@ -47,12 +46,6 @@ class UptimeKumaServer { | ||||
|      */ | ||||
|     indexHTML = ""; | ||||
|  | ||||
|     /** | ||||
|      * Plugins Manager | ||||
|      * @type {PluginsManager} | ||||
|      */ | ||||
|     pluginsManager = null; | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @type {{}} | ||||
| @@ -289,46 +282,6 @@ class UptimeKumaServer { | ||||
|     async stop() { | ||||
|  | ||||
|     } | ||||
|  | ||||
|     loadPlugins() { | ||||
|         this.pluginsManager = new PluginsManager(this); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @returns {PluginsManager} | ||||
|      */ | ||||
|     getPluginManager() { | ||||
|         return this.pluginsManager; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param {MonitorType} monitorType | ||||
|      */ | ||||
|     addMonitorType(monitorType) { | ||||
|         if (monitorType instanceof MonitorType && monitorType.name) { | ||||
|             if (monitorType.name in UptimeKumaServer.monitorTypeList) { | ||||
|                 log.error("", "Conflict Monitor Type name"); | ||||
|             } | ||||
|             UptimeKumaServer.monitorTypeList[monitorType.name] = monitorType; | ||||
|         } else { | ||||
|             log.error("", "Invalid Monitor Type: " + monitorType.name); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * | ||||
|      * @param {MonitorType} monitorType | ||||
|      */ | ||||
|     removeMonitorType(monitorType) { | ||||
|         if (UptimeKumaServer.monitorTypeList[monitorType.name] === monitorType) { | ||||
|             delete UptimeKumaServer.monitorTypeList[monitorType.name]; | ||||
|         } else { | ||||
|             log.error("", "Remove MonitorType failed: " + monitorType.name); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| module.exports = { | ||||
|   | ||||
| @@ -1,102 +0,0 @@ | ||||
| <template> | ||||
|     <div v-if="! (!plugin.installed && plugin.local)" class="plugin-item pt-4 pb-2"> | ||||
|         <div class="info"> | ||||
|             <h5>{{ plugin.fullName }}</h5> | ||||
|             <p class="description"> | ||||
|                 {{ plugin.description }} | ||||
|             </p> | ||||
|             <span class="version">{{ $t("Version") }}: {{ plugin.version }} <a v-if="plugin.repo" :href="plugin.repo" target="_blank">Repo</a></span> | ||||
|         </div> | ||||
|         <div class="buttons"> | ||||
|             <button v-if="status === 'installing'" class="btn btn-primary" disabled>{{ $t("installing") }}</button> | ||||
|             <button v-else-if="status === 'uninstalling'" class="btn btn-danger" disabled>{{ $t("uninstalling") }}</button> | ||||
|             <button v-else-if="plugin.installed || status === 'installed'" class="btn btn-danger" @click="deleteConfirm">{{ $t("uninstall") }}</button> | ||||
|             <button v-else class="btn btn-primary" @click="install">{{ $t("install") }}</button> | ||||
|         </div> | ||||
|  | ||||
|         <Confirm ref="confirmDelete" btn-style="btn-danger" :yes-text="$t('Yes')" :no-text="$t('No')" @yes="uninstall"> | ||||
|             {{ $t("confirmUninstallPlugin") }} | ||||
|         </Confirm> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import Confirm from "./Confirm.vue"; | ||||
|  | ||||
| export default { | ||||
|     components: { | ||||
|         Confirm, | ||||
|     }, | ||||
|     props: { | ||||
|         plugin: { | ||||
|             type: Object, | ||||
|             required: true, | ||||
|         }, | ||||
|     }, | ||||
|     data() { | ||||
|         return { | ||||
|             status: "", | ||||
|         }; | ||||
|     }, | ||||
|     methods: { | ||||
|         /** | ||||
|          * Show confirmation for deleting a tag | ||||
|          */ | ||||
|         deleteConfirm() { | ||||
|             this.$refs.confirmDelete.show(); | ||||
|         }, | ||||
|  | ||||
|         install() { | ||||
|             this.status = "installing"; | ||||
|  | ||||
|             this.$root.getSocket().emit("installPlugin", this.plugin.repo, this.plugin.name, (res) => { | ||||
|                 if (res.ok) { | ||||
|                     this.status = ""; | ||||
|                     // eslint-disable-next-line vue/no-mutating-props | ||||
|                     this.plugin.installed = true; | ||||
|                 } else { | ||||
|                     this.$root.toastRes(res); | ||||
|                 } | ||||
|             }); | ||||
|         }, | ||||
|  | ||||
|         uninstall() { | ||||
|             this.status = "uninstalling"; | ||||
|  | ||||
|             this.$root.getSocket().emit("uninstallPlugin", this.plugin.name, (res) => { | ||||
|                 if (res.ok) { | ||||
|                     this.status = ""; | ||||
|                     // eslint-disable-next-line vue/no-mutating-props | ||||
|                     this.plugin.installed = false; | ||||
|                 } else { | ||||
|                     this.$root.toastRes(res); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
| @import "../assets/vars.scss"; | ||||
|  | ||||
| .plugin-item { | ||||
|     display: flex; | ||||
|     justify-content: space-between; | ||||
|     align-content: center; | ||||
|     align-items: center; | ||||
|  | ||||
|     .info { | ||||
|         margin-right: 10px; | ||||
|     } | ||||
|  | ||||
|     .description { | ||||
|         font-size: 13px; | ||||
|         margin-bottom: 0; | ||||
|     } | ||||
|  | ||||
|     .version { | ||||
|         font-size: 13px; | ||||
|     } | ||||
| } | ||||
| </style> | ||||
| @@ -1,57 +0,0 @@ | ||||
| <template> | ||||
|     <div> | ||||
|         <div class="mt-3">{{ remotePluginListMsg }}</div> | ||||
|         <PluginItem v-for="plugin in remotePluginList" :key="plugin.id" :plugin="plugin" /> | ||||
|     </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import PluginItem from "../PluginItem.vue"; | ||||
|  | ||||
| export default { | ||||
|     components: { | ||||
|         PluginItem | ||||
|     }, | ||||
|  | ||||
|     data() { | ||||
|         return { | ||||
|             remotePluginList: [], | ||||
|             remotePluginListMsg: "", | ||||
|         }; | ||||
|     }, | ||||
|  | ||||
|     computed: { | ||||
|         pluginList() { | ||||
|             return this.$parent.$parent.$parent.pluginList; | ||||
|         }, | ||||
|         settings() { | ||||
|             return this.$parent.$parent.$parent.settings; | ||||
|         }, | ||||
|         saveSettings() { | ||||
|             return this.$parent.$parent.$parent.saveSettings; | ||||
|         }, | ||||
|         settingsLoaded() { | ||||
|             return this.$parent.$parent.$parent.settingsLoaded; | ||||
|         }, | ||||
|     }, | ||||
|  | ||||
|     async mounted() { | ||||
|         this.loadList(); | ||||
|     }, | ||||
|  | ||||
|     methods: { | ||||
|         loadList() { | ||||
|             this.remotePluginListMsg = this.$t("Loading") + "..."; | ||||
|  | ||||
|             this.$root.getSocket().emit("getPluginList", (res) => { | ||||
|                 if (res.ok) { | ||||
|                     this.remotePluginList = res.pluginList; | ||||
|                     this.remotePluginListMsg = ""; | ||||
|                 } else { | ||||
|                     this.remotePluginListMsg = this.$t("loadingError") + " " + res.msg; | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     }, | ||||
| }; | ||||
| </script> | ||||
| @@ -116,12 +116,6 @@ export default { | ||||
|                 backup: { | ||||
|                     title: this.$t("Backup"), | ||||
|                 }, | ||||
|                 /* | ||||
|                 Hidden for now: Unfortunately, after some test, I found that Playwright requires a lot of libraries to be installed on the Linux host in order to start Chrome or Firefox. | ||||
|                 It will be hard to install, so I hide this feature for now. But it still accessible via URL: /settings/plugins. | ||||
|                 plugins: { | ||||
|                     title: this.$tc("plugin", 2), | ||||
|                 },*/ | ||||
|                 about: { | ||||
|                     title: this.$t("About"), | ||||
|                 }, | ||||
|   | ||||
| @@ -19,7 +19,6 @@ import DockerHosts from "./components/settings/Docker.vue"; | ||||
| import MaintenanceDetails from "./pages/MaintenanceDetails.vue"; | ||||
| import ManageMaintenance from "./pages/ManageMaintenance.vue"; | ||||
| import APIKeys from "./components/settings/APIKeys.vue"; | ||||
| import Plugins from "./components/settings/Plugins.vue"; | ||||
|  | ||||
| // Settings - Sub Pages | ||||
| import Appearance from "./components/settings/Appearance.vue"; | ||||
| @@ -130,10 +129,6 @@ const routes = [ | ||||
|                                 path: "backup", | ||||
|                                 component: Backup, | ||||
|                             }, | ||||
|                             { | ||||
|                                 path: "plugins", | ||||
|                                 component: Plugins, | ||||
|                             }, | ||||
|                             { | ||||
|                                 path: "about", | ||||
|                                 component: About, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user