Version 0.3.0 - Add of Services
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Neutral/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Neutral/pipeline/head This commit looks good
				
			This commit is contained in:
		| @@ -4,6 +4,7 @@ const path = require("path") | |||||||
| const { __glob } = require("./global-variables") | const { __glob } = require("./global-variables") | ||||||
| const auth = require("./auth") | const auth = require("./auth") | ||||||
| const files = require("./files") | const files = require("./files") | ||||||
|  | const service = require("./services") | ||||||
| const plog = new LogType("Web") | const plog = new LogType("Web") | ||||||
| const cook = require("cookie") | const cook = require("cookie") | ||||||
| const http = require("http") | const http = require("http") | ||||||
| @@ -44,6 +45,8 @@ module.exports.serverIO = function(server) { | |||||||
|              * POST REQUEST |              * POST REQUEST | ||||||
|              */ |              */ | ||||||
|  |  | ||||||
|  |             if(user.checkPermission("FILES_EXPLORER")) { | ||||||
|  |  | ||||||
|             PostRequest("FX_GET", (root) => { |             PostRequest("FX_GET", (root) => { | ||||||
|  |  | ||||||
|                 PostAnswer("FX_GET", files.getFiles(root)) |                 PostAnswer("FX_GET", files.getFiles(root)) | ||||||
| @@ -90,6 +93,30 @@ module.exports.serverIO = function(server) { | |||||||
|  |  | ||||||
|             }) |             }) | ||||||
|  |  | ||||||
|  |             }  | ||||||
|  |  | ||||||
|  |             if(user.checkPermission("SERVICES")) { | ||||||
|  |  | ||||||
|  |                 PostRequest("SV_GET_SERVICE_STATUS", async (sv) => { | ||||||
|  |                     PostAnswer("SV_GET_SERVICE_STATUS", {answer: await service.getServiceStatus(sv), name: sv}) | ||||||
|  |                 })   | ||||||
|  |  | ||||||
|  |                 PostRequest("SV_START_SERVICE", async (sv) => { | ||||||
|  |                     PostAnswer("SV_START_SERVICE", {answer: await service.startService(sv), name: sv}) | ||||||
|  |                 }) | ||||||
|  |  | ||||||
|  |                 PostRequest("SV_STOP_SERVICE", async (sv) => { | ||||||
|  |                     PostAnswer("SV_STOP_SERVICE", {answer: await service.stopService(sv), name: sv}) | ||||||
|  |                 }) | ||||||
|  |  | ||||||
|  |                 PostRequest("SV_RESTART_SERVICE", async (sv) => { | ||||||
|  |                     PostAnswer("SV_RESTART_SERVICE", {answer: await service.restartService(sv), name: sv}) | ||||||
|  |                 }) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |  | ||||||
|             socket.on("disconnect", () => { |             socket.on("disconnect", () => { | ||||||
|  |  | ||||||
|                 plog.log("Déconnexion au panel par '" + user.username + "' avec le socket : " + socket.id) |                 plog.log("Déconnexion au panel par '" + user.username + "' avec le socket : " + socket.id) | ||||||
|   | |||||||
							
								
								
									
										136
									
								
								bin/services.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								bin/services.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | |||||||
|  | const { LogType } = require("loguix") | ||||||
|  | const fs = require("fs") | ||||||
|  | const path = require("path") | ||||||
|  | const { __glob } = require("./global-variables") | ||||||
|  | const clog = new LogType("Services") | ||||||
|  |  | ||||||
|  | const http = require('http'); | ||||||
|  | const https = require('https'); | ||||||
|  |  | ||||||
|  | module.exports.getServiceStatus = function(service) { | ||||||
|  |     const protocol = service.startsWith('https') ? https : http; | ||||||
|  |     const url = new URL(service); | ||||||
|  |     const options = { | ||||||
|  |         method: 'HEAD', | ||||||
|  |         host: url.hostname, | ||||||
|  |         port: url.port, | ||||||
|  |         path: url.pathname, | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |         const req = protocol.request(options, (res) => { | ||||||
|  |             if(res.statusCode !== 502) { | ||||||
|  |                 resolve("ONLINE"); | ||||||
|  |             } else { | ||||||
|  |  | ||||||
|  |                 resolve("OFFLINE"); | ||||||
|  |             } | ||||||
|  |          | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         req.on('error', (err) => { | ||||||
|  |             resolve("OFFLINE"); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         req.end(); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports.stopService = function(service) { | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |         | ||||||
|  |         const child_process = require('child_process'); | ||||||
|  |         if(service == "https://subsonics.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 stop 'Subsonics'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://git.raphix.fr" ) { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl stop gitea") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://jenkins.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl stop jenkins ") | ||||||
|  |             resolve("OK") | ||||||
|  |  | ||||||
|  |         } else if(service == 'https://raphix.fr') { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 stop 'Website - Raphix'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://cv.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 stop 'CV - Raphael'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "http://omega.raphix.fr:2333") { | ||||||
|  |             let req = child_process.exec(" ssh raphix@omega.raphix.fr sudo -S systemctl stop lavalink ") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else { | ||||||
|  |             resolve(false) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports.startService = function(service) { | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |         | ||||||
|  |         const child_process = require('child_process'); | ||||||
|  |         if(service == "https://subsonics.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 start /home/gitlab-ci/subsonic.config.js") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://git.raphix.fr" ) { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl start gitea") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://jenkins.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl start jenkins ") | ||||||
|  |             resolve("OK") | ||||||
|  |  | ||||||
|  |         } else if(service == 'https://raphix.fr') { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 start /home/gitlab-ci/website.config.js") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://cv.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 start /home/gitlab-ci/cv.config.js") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "http://omega.raphix.fr:2333") { | ||||||
|  |             let req = child_process.exec(" ssh raphix@omega.raphix.fr sudo -S systemctl start lavalink ") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else { | ||||||
|  |             resolve(false) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports.restartService = function(service) { | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     return new Promise((resolve, reject) => { | ||||||
|  |         | ||||||
|  |         const child_process = require('child_process'); | ||||||
|  |         if(service == "https://subsonics.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 restart 'Subsonics'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://git.raphix.fr" ) { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl restart gitea") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://jenkins.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@omega.raphix.fr sudo -S systemctl restart jenkins ") | ||||||
|  |             resolve("OK") | ||||||
|  |  | ||||||
|  |         } else if(service == 'https://raphix.fr') { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 restart 'Website - Raphix'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "https://cv.raphix.fr") { | ||||||
|  |             let req = child_process.exec("ssh raphix@alpha.raphix.fr sudo -S -u gitlab-ci pm2 restart 'CV - Raphael'") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else if(service == "http://omega.raphix.fr:2333") { | ||||||
|  |             let req = child_process.exec(" ssh raphix@omega.raphix.fr sudo -S systemctl restart lavalink ") | ||||||
|  |             resolve("OK") | ||||||
|  |         } else { | ||||||
|  |             resolve(false) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     }); | ||||||
|  |      | ||||||
|  | } | ||||||
| @@ -204,7 +204,6 @@ module.exports.User =  class { | |||||||
|         this.#sync() |         this.#sync() | ||||||
|         if(this.permission.includes(name)) { |         if(this.permission.includes(name)) { | ||||||
|             return true |             return true | ||||||
|  |  | ||||||
|         } else { |         } else { | ||||||
|  |  | ||||||
|             return false |             return false | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								public/images/services/cv.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/images/services/cv.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 137 KiB | 
							
								
								
									
										1
									
								
								public/images/services/gitea.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/images/services/gitea.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="main_outline" x="0px" y="0px" viewBox="0 0 640 640" style="enable-background:new 0 0 640 640;" xml:space="preserve"><g><path id="teabag" style="fill:#ffffff00" d="M395.9,484.2l-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5,21.2-17.9,33.8-11.8   c17.2,8.3,27.1,13,27.1,13l-0.1-109.2l16.7-0.1l0.1,117.1c0,0,57.4,24.2,83.1,40.1c3.7,2.3,10.2,6.8,12.9,14.4   c2.1,6.1,2,13.1-1,19.3l-61,126.9C423.6,484.9,408.4,490.3,395.9,484.2z"/><g><g><path style="fill: white;" d="M622.7,149.8c-4.1-4.1-9.6-4-9.6-4s-117.2,6.6-177.9,8c-13.3,0.3-26.5,0.6-39.6,0.7c0,39.1,0,78.2,0,117.2     c-5.5-2.6-11.1-5.3-16.6-7.9c0-36.4-0.1-109.2-0.1-109.2c-29,0.4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5     c-9.8-0.6-22.5-2.1-39,1.5c-8.7,1.8-33.5,7.4-53.8,26.9C-4.9,212.4,6.6,276.2,8,285.8c1.7,11.7,6.9,44.2,31.7,72.5     c45.8,56.1,144.4,54.8,144.4,54.8s12.1,28.9,30.6,55.5c25,33.1,50.7,58.9,75.7,62c63,0,188.9-0.1,188.9-0.1s12,0.1,28.3-10.3     c14-8.5,26.5-23.4,26.5-23.4s12.9-13.8,30.9-45.3c5.5-9.7,10.1-19.1,14.1-28c0,0,55.2-117.1,55.2-231.1     C633.2,157.9,624.7,151.8,622.7,149.8z M125.6,353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6,321.8,60,295.4     c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5,38.5-30c13.8-3.7,31-3.1,31-3.1s7.1,59.4,15.7,94.2c7.2,29.2,24.8,77.7,24.8,77.7     S142.5,359.9,125.6,353.9z M425.9,461.5c0,0-6.1,14.5-19.6,15.4c-5.8,0.4-10.3-1.2-10.3-1.2s-0.3-0.1-5.3-2.1l-112.9-55     c0,0-10.9-5.7-12.8-15.6c-2.2-8.1,2.7-18.1,2.7-18.1L322,273c0,0,4.8-9.7,12.2-13c0.6-0.3,2.3-1,4.5-1.5c8.1-2.1,18,2.8,18,2.8     l110.7,53.7c0,0,12.6,5.7,15.3,16.2c1.9,7.4-0.5,14-1.8,17.2C474.6,363.8,425.9,461.5,425.9,461.5z"/><path style="fill:white;" d="M326.8,380.1c-8.2,0.1-15.4,5.8-17.3,13.8c-1.9,8,2,16.3,9.1,20c7.7,4,17.5,1.8,22.7-5.4     c5.1-7.1,4.3-16.9-1.8-23.1l24-49.1c1.5,0.1,3.7,0.2,6.2-0.5c4.1-0.9,7.1-3.6,7.1-3.6c4.2,1.8,8.6,3.8,13.2,6.1     c4.8,2.4,9.3,4.9,13.4,7.3c0.9,0.5,1.8,1.1,2.8,1.9c1.6,1.3,3.4,3.1,4.7,5.5c1.9,5.5-1.9,14.9-1.9,14.9     c-2.3,7.6-18.4,40.6-18.4,40.6c-8.1-0.2-15.3,5-17.7,12.5c-2.6,8.1,1.1,17.3,8.9,21.3c7.8,4,17.4,1.7,22.5-5.3     c5-6.8,4.6-16.3-1.1-22.6c1.9-3.7,3.7-7.4,5.6-11.3c5-10.4,13.5-30.4,13.5-30.4c0.9-1.7,5.7-10.3,2.7-21.3     c-2.5-11.4-12.6-16.7-12.6-16.7c-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3c4.7-9.7,9.4-19.3,14.1-29     c-4.1-2-8.1-4-12.2-6.1c-4.8,9.8-9.7,19.7-14.5,29.5c-6.7-0.1-12.9,3.5-16.1,9.4c-3.4,6.3-2.7,14.1,1.9,19.8     C343.2,346.5,335,363.3,326.8,380.1z"/></g></g></g></svg> | ||||||
| After Width: | Height: | Size: 2.5 KiB | 
							
								
								
									
										1
									
								
								public/images/services/jenkins.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								public/images/services/jenkins.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| After Width: | Height: | Size: 47 KiB | 
							
								
								
									
										48
									
								
								public/images/services/lavalink.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								public/images/services/lavalink.svg
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <svg | ||||||
|  |    viewBox="0 0 100 100" | ||||||
|  |    width="100%" | ||||||
|  |    height="100%" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg13" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs7"> | ||||||
|  |     <linearGradient | ||||||
|  |        id="grad" | ||||||
|  |        x1="0" | ||||||
|  |        y1="0" | ||||||
|  |        x2="100" | ||||||
|  |        y2="100" | ||||||
|  |        spreadMethod="pad" | ||||||
|  |        gradientUnits="userSpaceOnUse"> | ||||||
|  |       <stop | ||||||
|  |          offset="0" | ||||||
|  |          stop-color="#ff8c00" | ||||||
|  |          id="stop2" | ||||||
|  |          style="stop-color:#fa9800;stop-opacity:1;" /> | ||||||
|  |       <stop | ||||||
|  |          offset="100" | ||||||
|  |          stop-color="#ff0000" | ||||||
|  |          id="stop4" | ||||||
|  |          style="stop-color:#ff005e;stop-opacity:1;" /> | ||||||
|  |     </linearGradient> | ||||||
|  |   </defs> | ||||||
|  |   <rect | ||||||
|  |      width="100%" | ||||||
|  |      height="100%" | ||||||
|  |      fill="url(#grad)" | ||||||
|  |      id="rect9" | ||||||
|  |      x="0" | ||||||
|  |      y="0" | ||||||
|  |      style="fill:url(#grad)" /> | ||||||
|  |   <path | ||||||
|  |      style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:1.27808;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000" | ||||||
|  |      d="m 57,25 h 13 l -7,27 h 12 l -2,8.5 H 48 Z" | ||||||
|  |      id="path724-5" /> | ||||||
|  |   <path | ||||||
|  |      style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:1.33907;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1" | ||||||
|  |      d="m 37.5,25 h 14 l -10,40 H 72 L 70,75 H 25 Z" | ||||||
|  |      id="path724" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/images/services/raphix.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/images/services/raphix.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 86 KiB | 
							
								
								
									
										
											BIN
										
									
								
								public/images/services/subsonics.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/images/services/subsonics.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 213 KiB | 
| @@ -93,7 +93,7 @@ class ViewWindow { | |||||||
|                     <div id='${properties.title}_header' class='view-window-header'> |                     <div id='${properties.title}_header' class='view-window-header'> | ||||||
|                     <span style='width: 40px'></span> |                     <span style='width: 40px'></span> | ||||||
|                     <p>${properties.title}</p> |                     <p>${properties.title}</p> | ||||||
|                     <button id='${properties.title}_close' class='btn min red'><span><i class='fa fa-xmark'></i></span></button> |                     <span id='${properties.title}_close' class='view-close'><i class='fa fa-xmark'></i></span> | ||||||
|                     </div> |                     </div> | ||||||
|                     <div id='${properties.title}_content' class='view-window-content'> |                     <div id='${properties.title}_content' class='view-window-content'> | ||||||
|                     </div> |                     </div> | ||||||
| @@ -182,10 +182,10 @@ class ViewWindow { | |||||||
|  |  | ||||||
|     createPopup(properties) { |     createPopup(properties) { | ||||||
|  |  | ||||||
|         this.ViewPopupHTML = `<div id='${properties.title}_popup' class='view-popup'> |         this.ViewPopupHTML = `<div id="${properties.title}_popup" class='view-popup'> | ||||||
|             <div class='view-popup-bar'> |             <div class='view-popup-bar'> | ||||||
|                 <p>${properties.title}</p> |                 <p>${properties.title}</p> | ||||||
|                 <span id='${properties.title}_popupClose' class='btn-cover'><i  class='fa fa-xmark'></i></span> |                 <span id="${properties.title}_popupClose" class='btn-cover'><i  class='fa fa-xmark'></i></span> | ||||||
|             </div> |             </div> | ||||||
|             ${properties.content} |             ${properties.content} | ||||||
|         </div>` |         </div>` | ||||||
| @@ -243,17 +243,13 @@ class ViewWindow { | |||||||
| function createView(viewType) { | function createView(viewType) { | ||||||
|     if(viewType == 'files_explorer') { |     if(viewType == 'files_explorer') { | ||||||
|  |  | ||||||
|         generateFileExplorer() |         generateFileExplorerView() | ||||||
|  |  | ||||||
|  |  | ||||||
|     } |     } | ||||||
|     if(viewType == 'service') { |     if(viewType == 'service') { | ||||||
|  |  | ||||||
|         const View = new ViewWindow({ |        generateServiceView() | ||||||
|             title: "Gestionnaire des services", |  | ||||||
|             width: "1000px", |  | ||||||
|             height: "600px" |  | ||||||
|         }) |  | ||||||
|     } |     } | ||||||
|     |     | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ document.addEventListener("contextmenu", (e) => { | |||||||
|     e.preventDefault() |     e.preventDefault() | ||||||
| }) | }) | ||||||
|  |  | ||||||
| function generateFileExplorer() { | function generateFileExplorerView() { | ||||||
|  |  | ||||||
|     const View = new ViewWindow({ |     const View = new ViewWindow({ | ||||||
|         title: `<i class="fa fa-folder"></i> Gestionnaire de fichiers`, |         title: `<i class="fa fa-folder"></i> Gestionnaire de fichiers`, | ||||||
| @@ -68,7 +68,7 @@ function generateFileExplorer() { | |||||||
|     newFolder.addEventListener("click", () => { |     newFolder.addEventListener("click", () => { | ||||||
|  |  | ||||||
|         View.createPopup({ |         View.createPopup({ | ||||||
|             title: `<i class="fa fa-folder"></i> Nouveau dossier`, |             title: `<i class='fa fa-folder'></i> Nouveau dossier`, | ||||||
|             content: ` |             content: ` | ||||||
|                 <input type='text' class='field' id='${View.getViewTitle()}_foldername'> |                 <input type='text' class='field' id='${View.getViewTitle()}_foldername'> | ||||||
|                 <div id='${View.getViewTitle()}_folderInfo'></div> |                 <div id='${View.getViewTitle()}_folderInfo'></div> | ||||||
| @@ -126,7 +126,7 @@ function generateFileExplorer() { | |||||||
|     newFile.addEventListener("click", () => { |     newFile.addEventListener("click", () => { | ||||||
|  |  | ||||||
|         View.createPopup({ |         View.createPopup({ | ||||||
|             title: `<i class="fa-solid fa-file-arrow-up"></i> Nouveau fichier`, |             title: `<i class='fa-solid fa-file-arrow-up'></i> Nouveau fichier`, | ||||||
|             content: ` |             content: ` | ||||||
|                 <input type='text' class='field' id='${View.getViewTitle()}_filename'> |                 <input type='text' class='field' id='${View.getViewTitle()}_filename'> | ||||||
|                 <div id='${View.getViewTitle()}_fileInfo'></div> |                 <div id='${View.getViewTitle()}_fileInfo'></div> | ||||||
| @@ -181,7 +181,7 @@ function generateFileExplorer() { | |||||||
|             fileInfo.clear() |             fileInfo.clear() | ||||||
|             View.destroyPopup(`<i class="fa-solid fa-file-arrow-up"></i> Nouveau fichier`) |             View.destroyPopup(`<i class="fa-solid fa-file-arrow-up"></i> Nouveau fichier`) | ||||||
|             View.createPopup({ |             View.createPopup({ | ||||||
|                 title: `<i class="fa-solid fa-file-arrow-up"></i> Upload`, |                 title: `<i class='fa-solid fa-file-arrow-up'></i> Upload`, | ||||||
|                 content: ` |                 content: ` | ||||||
|                     <input type='file' class='field' id='${View.getViewTitle()}_fileuploadInput'> |                     <input type='file' class='field' id='${View.getViewTitle()}_fileuploadInput'> | ||||||
|                     <div id='${View.getViewTitle()}_fileuploadInfo'></div> |                     <div id='${View.getViewTitle()}_fileuploadInfo'></div> | ||||||
| @@ -374,7 +374,7 @@ function generateFileExplorer() { | |||||||
|                                     loadFiles(result) |                                     loadFiles(result) | ||||||
|                                 })  |                                 })  | ||||||
|                                 View.createPopup({ |                                 View.createPopup({ | ||||||
|                                     title: `<i class="fa fa-warning"></i> Erreur`, |                                     title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour supprimer ce fichier.</p>` |                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour supprimer ce fichier.</p>` | ||||||
|                                 }) |                                 }) | ||||||
|                             } else { |                             } else { | ||||||
| @@ -383,7 +383,7 @@ function generateFileExplorer() { | |||||||
|                                     loadFiles(result) |                                     loadFiles(result) | ||||||
|                                 })  |                                 })  | ||||||
|                                 View.createPopup({ |                                 View.createPopup({ | ||||||
|                                     title: `<i class="fa fa-warning"></i> Erreur`, |                                     title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                     content: `<p class='yellow'>Une erreur est survenue.</p>` |                                     content: `<p class='yellow'>Une erreur est survenue.</p>` | ||||||
|                                 }) |                                 }) | ||||||
|                               |                               | ||||||
| @@ -394,7 +394,7 @@ function generateFileExplorer() { | |||||||
|  |  | ||||||
|                         dropMenu.hide() |                         dropMenu.hide() | ||||||
|                         View.createPopup({ |                         View.createPopup({ | ||||||
|                             title: `<i class="fa fa-file-signature"></i> Renommer`, |                             title: `<i class='fa fa-file-signature'></i> Renommer`, | ||||||
|                             content: ` |                             content: ` | ||||||
|                                 <input type='text' class='field' id='${View.getViewTitle()}_rename'> |                                 <input type='text' class='field' id='${View.getViewTitle()}_rename'> | ||||||
|                                 <div id='${View.getViewTitle()}_renameInfo'></div> |                                 <div id='${View.getViewTitle()}_renameInfo'></div> | ||||||
| @@ -416,7 +416,7 @@ function generateFileExplorer() { | |||||||
|                                 return |                                 return | ||||||
|                             } |                             } | ||||||
|              |              | ||||||
|                             const regex = new RegExp(/^[a-zA-Z0-9-_]+$/) |                             const regex = new RegExp(/^[a-zA-Z0-9-_.]+$/) | ||||||
|              |              | ||||||
|                             if(!regex.test(rename.value) | rename.value.replace(/\s/g, '').length < 1) { |                             if(!regex.test(rename.value) | rename.value.replace(/\s/g, '').length < 1) { | ||||||
|                                 renameInfo.err("Le nom du fichier / dossier est invalide.") |                                 renameInfo.err("Le nom du fichier / dossier est invalide.") | ||||||
| @@ -451,12 +451,12 @@ function generateFileExplorer() { | |||||||
|                         reqFiles.then((result) => { |                         reqFiles.then((result) => { | ||||||
|                             if(result == "NOT_PERMITTED") { |                             if(result == "NOT_PERMITTED") { | ||||||
|                                 View.createPopup({ |                                 View.createPopup({ | ||||||
|                                     title: `<i class="fa fa-warning"></i> Erreur`, |                                     title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour partager ce fichier.</p>` |                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour partager ce fichier.</p>` | ||||||
|                                 }) |                                 }) | ||||||
|                             } else { |                             } else { | ||||||
|                                 View.createPopup({ |                                 View.createPopup({ | ||||||
|                                     title: `<i class="fa fa-share"></i> Partager`, |                                     title: `<i class='fa fa-share'></i> Partager`, | ||||||
|                                     content: ` |                                     content: ` | ||||||
|                                         <input style='width: 300px' type='text' class='field' id='${View.getViewTitle()}_sharelink'> |                                         <input style='width: 300px' type='text' class='field' id='${View.getViewTitle()}_sharelink'> | ||||||
|                                         <div id='${View.getViewTitle()}_shareInfo'></div> |                                         <div id='${View.getViewTitle()}_shareInfo'></div> | ||||||
| @@ -495,7 +495,7 @@ function generateFileExplorer() { | |||||||
|                         reqFiles.then((result) => { |                         reqFiles.then((result) => { | ||||||
|                             if(result == "NOT_PERMITTED") { |                             if(result == "NOT_PERMITTED") { | ||||||
|                                 View.createPopup({ |                                 View.createPopup({ | ||||||
|                                     title: `<i class="fa fa-warning"></i> Erreur`, |                                     title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour télécharger ce fichier.</p>` |                                     content: `<p class='yellow'>Vous n'avez pas les permissions pour télécharger ce fichier.</p>` | ||||||
|                                 }) |                                 }) | ||||||
|                             } else { |                             } else { | ||||||
| @@ -527,7 +527,7 @@ function generateFileExplorer() { | |||||||
|                     reqFiles.then((result) => { |                     reqFiles.then((result) => { | ||||||
|                         if(result == "NOT_PERMITTED") { |                         if(result == "NOT_PERMITTED") { | ||||||
|                             View.createPopup({ |                             View.createPopup({ | ||||||
|                                 title: `<i class="fa fa-warning"></i> Erreur`, |                                 title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                 content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>` |                                 content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>` | ||||||
|                             }) |                             }) | ||||||
|                         } else { |                         } else { | ||||||
| @@ -564,13 +564,13 @@ function generateFileExplorer() { | |||||||
|                                             loadFiles(result) |                                             loadFiles(result) | ||||||
|                                         }) |                                         }) | ||||||
|                                     } else if(result == "NOT_PERMITTED") { |                                     } else if(result == "NOT_PERMITTED") { | ||||||
|                                         View.createPopup({ |                                         editor.createPopup({ | ||||||
|                                             title: `<i class="fa fa-warning"></i> Erreur`, |                                             title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                             content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>` |                                             content: `<p class='yellow'>Vous n'avez pas les permissions pour éditer ce fichier.</p>` | ||||||
|                                         }) |                                         }) | ||||||
|                                     } else { |                                     } else { | ||||||
|                                         View.createPopup({ |                                         editor.createPopup({ | ||||||
|                                             title: `<i class="fa fa-warning"></i> Erreur`, |                                             title: `<i class='fa fa-warning'></i> Erreur`, | ||||||
|                                             content: `<p class='yellow'>Une erreur est survenue.</p>` |                                             content: `<p class='yellow'>Une erreur est survenue.</p>` | ||||||
|                                         }) |                                         }) | ||||||
|                                     } |                                     } | ||||||
|   | |||||||
							
								
								
									
										240
									
								
								public/javascripts/service.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										240
									
								
								public/javascripts/service.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,240 @@ | |||||||
|  | async function generateServiceView() { | ||||||
|  |  | ||||||
|  |     class Service { | ||||||
|  |         name = null | ||||||
|  |         description = null | ||||||
|  |         icon = null | ||||||
|  |         url = null | ||||||
|  |         canAccess = false | ||||||
|  |         isOnline  = false | ||||||
|  |         constructor(properties) { | ||||||
|  |             this.name = properties.name | ||||||
|  |             this.description = properties.description | ||||||
|  |             this.icon = properties.icon | ||||||
|  |             this.url = properties.url | ||||||
|  |             this.canAccess = properties.canAccess | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |         generateHTML() { | ||||||
|  |             return ` | ||||||
|  |             <div class="sv"> | ||||||
|  |                 <div class='sv-info'> | ||||||
|  |                     <img class="sv-icon" src="${this.icon}" alt="${this.name}"> | ||||||
|  |                     <div> | ||||||
|  |                         <h1>${this.name}</h1> | ||||||
|  |                         <p>${this.description}</p> | ||||||
|  |                         <p>Etat : <span id='${this.name}_status' class="sv-status"></span></p> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                  | ||||||
|  |                 <div class="sv-actions"> | ||||||
|  |                     ${this.canAccess ? `<a href="${this.url}" target="_blank"><button class="btn green"><span>Accéder au service</span></button></a>` : ""} | ||||||
|  |                     <button id='${this.name}_svpower' class='btn yellow'n><span>Options d'alimentation<span></button> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |             ` | ||||||
|  |      | ||||||
|  |              | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |         loadScript() { | ||||||
|  |      | ||||||
|  |             return new Promise((resolve, reject) => { | ||||||
|  |                 const statusSpan = getID(`${this.name}_status`) | ||||||
|  |                 const request = post(`SV_GET_SERVICE_STATUS`, this.url)  | ||||||
|  |              | ||||||
|  |  | ||||||
|  |                 request.then((answer) => { | ||||||
|  |                     if(answer.name == this.url) { | ||||||
|  |                         if(answer.answer == "ONLINE") { | ||||||
|  |                             statusSpan.innerHTML = '<span style="font-size: 12px;"><i class="fa-solid fa-circle green"></i> En ligne</span>' | ||||||
|  |                             this.isOnline  = true | ||||||
|  |                         } else { | ||||||
|  |                             statusSpan.innerHTML = '<span style="font-size: 12px;"><i class="fa-solid fa-circle red"></i> Hors ligne</span>' | ||||||
|  |                    | ||||||
|  |                         } | ||||||
|  |                         resolve("LOADED") | ||||||
|  |                     } | ||||||
|  |                  | ||||||
|  |                 }) | ||||||
|  |      | ||||||
|  |                 const powerButton = getID(`${this.name}_svpower`) | ||||||
|  |      | ||||||
|  |                 // Make a popup of View to select if you want to start, stop or restart the service by doing a request | ||||||
|  |      | ||||||
|  |                 powerButton.addEventListener("click", () => { | ||||||
|  |                     View.createPopup({ | ||||||
|  |                         title: `<i class='fa-solid fa-power-off'></i> Gestion de l'alimentation du service`, | ||||||
|  |                         content: ` | ||||||
|  |                          | ||||||
|  |                         <p class='sv-power-select'>${this.name}</p> | ||||||
|  |                         <p id='sv-power-info'></p> | ||||||
|  |                         <div class="sv-power"> | ||||||
|  |                             <button id="${this.name}_start" class="btn green"><span>Démarrer</span></button> | ||||||
|  |                             <button id="${this.name}_restart" class="btn yellow"><span>Redémarrer</span></button> | ||||||
|  |                             <button id="${this.name}_stop" class="btn red"><span> Arrêter</span></button> | ||||||
|  |                         </div> | ||||||
|  |                         ` | ||||||
|  |                     }) | ||||||
|  |      | ||||||
|  |                     const startButton = getID(`${this.name}_start`) | ||||||
|  |                     const stopButton = getID(`${this.name}_stop`) | ||||||
|  |                     const restartButton = getID(`${this.name}_restart`) | ||||||
|  |                     const info = new InfoPop("sv-power-info") | ||||||
|  |                      | ||||||
|  |                      | ||||||
|  |  | ||||||
|  |                     if(this.isOnline) { | ||||||
|  |                         startButton.style.display = "none" | ||||||
|  |                         info.info("Verifiez que le service n'est pas utilisé par quelqu'un d'autre avant de le redémarrer ou de l'arrêter") | ||||||
|  |                     } else { | ||||||
|  |                         stopButton.style.display = "none" | ||||||
|  |                         restartButton.style.display = "none" | ||||||
|  |                         info.info("Si le service ne démarre pas, vérifiez l'intégrité du service") | ||||||
|  |                     } | ||||||
|  |      | ||||||
|  |                     startButton.addEventListener("click", () => { | ||||||
|  |                         const request = post(`SV_START_SERVICE`, this.url)  | ||||||
|  |                          | ||||||
|  |  | ||||||
|  |                         request.then((answer) => { | ||||||
|  |                             if(answer.answer == "OK") { | ||||||
|  |                                 statusSpan.innerHTML = '<span style="font-size: 12px;"><i class="fa-solid fa-circle green"></i> En ligne</span>' | ||||||
|  |                                 View.destroyPopup("`<i class='fa-solid fa-power-off'></i> Gestion de l'alimentation du service`") | ||||||
|  |                                 this.isOnline  = true | ||||||
|  |                             } else { | ||||||
|  |                                 info.err("Impossible de démarrer le service") | ||||||
|  |  | ||||||
|  |                             } | ||||||
|  |                         }) | ||||||
|  |      | ||||||
|  |                     }) | ||||||
|  |  | ||||||
|  |                     stopButton.addEventListener("click", () => { | ||||||
|  |                         const request = post(`SV_STOP_SERVICE`, this.url)  | ||||||
|  |      | ||||||
|  |                         request.then((answer) => { | ||||||
|  |                             if(answer.answer == "OK") { | ||||||
|  |                                 statusSpan.innerHTML = '<span style="font-size: 12px;"><i class="fa-solid fa-circle red"></i> Hors ligne</span>' | ||||||
|  |                                 this.isOnline  = false | ||||||
|  |                                 View.destroyPopup("`<i class='fa-solid fa-power-off'></i> Gestion de l'alimentation du service`") | ||||||
|  |                                | ||||||
|  |                             } else { | ||||||
|  |                                 info.err("Impossible d'arrêter le service") | ||||||
|  |  | ||||||
|  |                             } | ||||||
|  |                          | ||||||
|  |                         }) | ||||||
|  |                     }) | ||||||
|  |  | ||||||
|  |                     restartButton.addEventListener("click", () => { | ||||||
|  |  | ||||||
|  |                         console.log("RESTART") | ||||||
|  |  | ||||||
|  |                         const request = post(`SV_RESTART_SERVICE`, this.url)  | ||||||
|  |      | ||||||
|  |                         request.then((answer) => { | ||||||
|  |                             if(answer.answer == "OK") { | ||||||
|  |                                 statusSpan.innerHTML = '<span style="font-size: 12px;"><i class="fa-solid fa-circle green"></i> En ligne</span>' | ||||||
|  |                                 View.destroyPopup("`<i class='fa-solid fa-power-off'></i> Gestion de l'alimentation du service`") | ||||||
|  |                                 this.isOnline  = true | ||||||
|  |                             } else { | ||||||
|  |                                 info.err("Impossible de redémarrer le service") | ||||||
|  |  | ||||||
|  |                             } | ||||||
|  |                              | ||||||
|  |                         }) | ||||||
|  |                     }) | ||||||
|  |      | ||||||
|  |      | ||||||
|  |             }) | ||||||
|  |              | ||||||
|  |          }) | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * CODE OF SERVICE.JS | ||||||
|  |     */ | ||||||
|  |  | ||||||
|  |     const allServices = new Array() | ||||||
|  |  | ||||||
|  |     const View = new ViewWindow({ | ||||||
|  |         title: '<i class="fa fa-layer-group"></i> Gestion des services', | ||||||
|  |         width: "700px", | ||||||
|  |         height: "600px" | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const subsonicsService = new Service({ | ||||||
|  |         name: "Subsonics", | ||||||
|  |         description: "Bot de streaming musical sur Discord", | ||||||
|  |         icon: "/images/services/subsonics.png", | ||||||
|  |         url: "https://subsonics.raphix.fr" , | ||||||
|  |         canAccess: true | ||||||
|  |          | ||||||
|  |  | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const giteaService = new Service({ | ||||||
|  |         name: "Gitea", | ||||||
|  |         description: "Gestionnaire de dépôt Git", | ||||||
|  |         icon: "/images/services/gitea.svg", | ||||||
|  |         url: "https://git.raphix.fr" , | ||||||
|  |         canAccess: true | ||||||
|  |  | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const jenkinsService = new Service({ | ||||||
|  |         name: "Jenkins", | ||||||
|  |         description: "Gestionnaire de pipeline", | ||||||
|  |         icon: "/images/services/jenkins.svg", | ||||||
|  |         url: "https://jenkins.raphix.fr" , | ||||||
|  |         canAccess: true | ||||||
|  |  | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const raphixwebsite = new Service({ | ||||||
|  |         name: "Raphix.fr", | ||||||
|  |         description: "Site web de Raphix", | ||||||
|  |         icon: "/images/services/raphix.png", | ||||||
|  |         url: "https://raphix.fr", | ||||||
|  |         canAccess: true | ||||||
|  |  | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const cvraphix = new Service({ | ||||||
|  |         name: "CV Raphix", | ||||||
|  |         description: "Curriculum Vitae de Raphix", | ||||||
|  |         icon: "/images/services/cv.png", | ||||||
|  |         url: "https://cv.raphix.fr", | ||||||
|  |         canAccess: true | ||||||
|  |     }) | ||||||
|  |  | ||||||
|  |     const lavalink = new Service({ | ||||||
|  |         name: "Lavalink", | ||||||
|  |         description: "Serveur Lavalink pour Subsonics", | ||||||
|  |         icon: "/images/services/lavalink.svg", | ||||||
|  |         url: "http://omega.raphix.fr:2333", | ||||||
|  |         canAccess: false | ||||||
|  |     }) | ||||||
|  |      | ||||||
|  |     allServices.push(subsonicsService.generateHTML()) | ||||||
|  |     allServices.push(lavalink.generateHTML()) | ||||||
|  |     allServices.push(giteaService.generateHTML()) | ||||||
|  |     allServices.push(jenkinsService.generateHTML()) | ||||||
|  |     allServices.push(raphixwebsite.generateHTML()) | ||||||
|  |     allServices.push(cvraphix.generateHTML()) | ||||||
|  |  | ||||||
|  |     View.setContent(`<div class='sv-list'>${allServices.join("")}</div>`) | ||||||
|  |  | ||||||
|  |     await subsonicsService.loadScript() | ||||||
|  |     await giteaService.loadScript() | ||||||
|  |     await jenkinsService.loadScript() | ||||||
|  |     await raphixwebsite.loadScript() | ||||||
|  |     await cvraphix.loadScript() | ||||||
|  |     await lavalink.loadScript() | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
| @@ -430,28 +430,7 @@ a { | |||||||
|   font-size: 72px; |   font-size: 72px; | ||||||
| } | } | ||||||
|  |  | ||||||
| .view-popup { |  | ||||||
|   position: absolute; |  | ||||||
|   background-color: #3D3B3C; |  | ||||||
|   backdrop-filter: blur(10px); |  | ||||||
|   display: flex; |  | ||||||
|   flex-direction: column; |  | ||||||
|   gap: 20px; |  | ||||||
|   align-items: center; |  | ||||||
|   justify-content: center; |  | ||||||
|   padding: 2%; |  | ||||||
|   border-radius: 10px; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .view-popup-bar { |  | ||||||
|  |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: space-between; |  | ||||||
|     flex-direction: row; |  | ||||||
|     align-items: center; |  | ||||||
|     gap: 20px; |  | ||||||
|     width: 100%; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| .blur { | .blur { | ||||||
|  |  | ||||||
| @@ -494,6 +473,46 @@ a { | |||||||
|    |    | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .view-popup { | ||||||
|  |   position: absolute; | ||||||
|  |   background-color: #3D3B3C; | ||||||
|  |   backdrop-filter: blur(10px); | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   gap: 20px; | ||||||
|  |   align-items: center; | ||||||
|  |   justify-content: center; | ||||||
|  |   padding: 2%; | ||||||
|  |   border-radius: 10px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .view-popup-bar { | ||||||
|  |  | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |     flex-direction: row; | ||||||
|  |     align-items: center; | ||||||
|  |     gap: 20px; | ||||||
|  |     width: 100%; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .view-close { | ||||||
|  |   color: white; | ||||||
|  |   transition: 0.1s; | ||||||
|  |   cursor: pointer; | ||||||
|  |   margin-right: 10px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .view-close:hover { | ||||||
|  |   color: #f01000; | ||||||
|  |    | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .view-close:active { | ||||||
|  |  | ||||||
|  |   color: #ff5d51; | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /* Files Explorer */ | /* Files Explorer */ | ||||||
|  |  | ||||||
| @@ -641,3 +660,66 @@ a { | |||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* Services */ | ||||||
|  |  | ||||||
|  | .sv { | ||||||
|  |  | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  |   align-items: center; | ||||||
|  |   justify-content: space-between; | ||||||
|  |   padding: 10px; | ||||||
|  |   border-radius: 10px; | ||||||
|  |   background-color: #1b1b1bc1; | ||||||
|  |   transition: 0.1s; | ||||||
|  |   user-select: none; | ||||||
|  |   -webkit-user-select: none; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sv-icon { | ||||||
|  |   width: 150px; | ||||||
|  |   border-radius: 15px; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sv-info { | ||||||
|  |  | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  |   gap: 20px; | ||||||
|  |   font-size: 15px; | ||||||
|  |   align-items: center; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sv-list { | ||||||
|  |  | ||||||
|  |   padding: 10px; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   gap: 10px; | ||||||
|  |   overflow-y: auto; | ||||||
|  |   height: 85%; | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sv-actions { | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column;  | ||||||
|  |   gap: 10px; | ||||||
|  |   align-items: flex-end; | ||||||
|  | } | ||||||
|  | .sv-power-select { | ||||||
|  |  | ||||||
|  |   background-color: #323031; | ||||||
|  |   padding: 10px; | ||||||
|  |   font-size: 14px; | ||||||
|  |   border-radius: 10px ; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .sv-power { | ||||||
|  |  | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: column; | ||||||
|  |   gap: 10px; | ||||||
|  | } | ||||||
| @@ -57,10 +57,9 @@ | |||||||
|     <script src="/socket.io/socket.io.js"></script> |     <script src="/socket.io/socket.io.js"></script> | ||||||
|     <script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script> |     <script defer="" src="https://use.fontawesome.com/releases/v6.4.2/js/all.js" crossorigin="anonymous"></script> | ||||||
|     <script src="/javascripts/io.js"></script> |     <script src="/javascripts/io.js"></script> | ||||||
|  |     <script src="/javascripts/service.js"></script> | ||||||
|     <script src="/javascripts/filexplorer.js"></script> |     <script src="/javascripts/filexplorer.js"></script> | ||||||
|     <script src="/javascripts/basics.js"></script> |     <script src="/javascripts/basics.js"></script> | ||||||
|  |  | ||||||
|  |  | ||||||
|     <script src="/javascripts/indexscript.js"></script> |     <script src="/javascripts/indexscript.js"></script> | ||||||
|   |   | ||||||
|   </body> |   </body> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user