1333 lines
46 KiB
JavaScript
1333 lines
46 KiB
JavaScript
|
|
var xMousePos = null;
|
|
var yMousePos = null;
|
|
|
|
document.onmousemove = function(e) {
|
|
xMousePos = e.clientX + window.scrollX;
|
|
yMousePos = e.clientY + window.scrollY;
|
|
|
|
}
|
|
|
|
document.oncontextmenu = function(e) {
|
|
|
|
xMousePos = e.clientX + window.scrollX;
|
|
yMousePos = e.clientY + window.scrollY;
|
|
|
|
}
|
|
|
|
/**
|
|
* Récupère depuis le document l'identifiant de l'élément
|
|
* @param {string} id Identifiant de l'élément `id='identifiant'`
|
|
* @returns
|
|
*/
|
|
function getID(id) {
|
|
|
|
return document.getElementById(id)
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {Date} GetDate
|
|
* @returns
|
|
*/
|
|
function getFormattedDate(GetDate) {
|
|
|
|
const date = new Date(GetDate)
|
|
|
|
var gmonth = date.getMonth() + 1
|
|
var gday = date.getDate()
|
|
var gHour = date.getHours()
|
|
var gMinute = date.getMinutes()
|
|
var gSecondes = date.getSeconds()
|
|
|
|
|
|
if(date.getMonth() + 1 < 10) {
|
|
gmonth = "0" + (date.getMonth() + 1)
|
|
}
|
|
|
|
if(date.getDate() + 1 <= 10) {
|
|
gday = "0" + date.getDate()
|
|
}
|
|
|
|
if(date.getHours() + 1 <= 10) {
|
|
gHour = "0" + date.getHours()
|
|
}
|
|
|
|
if(date.getMinutes() + 1 <= 10) {
|
|
gMinute = "0" + date.getMinutes()
|
|
}
|
|
|
|
if(date.getSeconds() + 1 <= 10) {
|
|
gSecondes = "0" + date.getSeconds()
|
|
}
|
|
|
|
return gday + "/" + gmonth + "/" + date.getFullYear() + " - " + gHour + ":" + gMinute
|
|
}
|
|
|
|
|
|
/**
|
|
* Permet de faire une pop-up automatique
|
|
*/
|
|
class TextResponse {
|
|
constructor(name) {
|
|
this.name = name
|
|
this.element = getID(this.name)
|
|
this.element.innerHTML = " "
|
|
this.element.style.fontSize = "14px"
|
|
this.element.style.textAlign = "center"
|
|
}
|
|
|
|
clear() {
|
|
|
|
this.element.innerHTML = " "
|
|
}
|
|
|
|
err(text) {
|
|
|
|
this.element.classList.add("yellow")
|
|
this.element.innerHTML = "<i class='fa fa-warning'></i> " + text
|
|
|
|
}
|
|
|
|
info(text) {
|
|
|
|
this.element.classList.remove("yellow")
|
|
|
|
this.element.innerHTML = "<i class='fa fa-info-circle'></i> " + text
|
|
}
|
|
|
|
setSize(size) {
|
|
|
|
this.element.style.fontSize = size
|
|
}
|
|
|
|
setWidth(width) {
|
|
this.element.style.width = width
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
const AllViews = new Map()
|
|
var zIndex = 5
|
|
|
|
|
|
|
|
/**
|
|
* Permet de créer une fenêtre
|
|
* @param {object} properties Propriétés de la fenêtre
|
|
*/
|
|
class ViewWindow {
|
|
ViewHTML = null
|
|
ViewWindowDiv
|
|
ViewProperties = null
|
|
ViewSpanInteger = null
|
|
ViewPopupSpanInteger = null
|
|
ViewPopupHTML = null
|
|
ViewPopupTitle = null
|
|
ViewItem = new ViewItem(this)
|
|
constructor (properties) {
|
|
if(!AllViews.has(properties.title)) {
|
|
|
|
this.ViewProperties = properties
|
|
AllViews.set(properties.title, true)
|
|
|
|
|
|
|
|
this.ViewHTML = `
|
|
<div draggable="true" id='${properties.title}_window' style='width: ${properties.width}; height: ${properties.height}' class='view-window'>
|
|
|
|
<div id='${properties.title}_header' class='view-window-header'>
|
|
<span style='width: 40px'></span>
|
|
<p>${properties.title}</p>
|
|
<div class='view-closediv'>
|
|
<span id='${properties.title}_reduce' class='btn-cover'><i class="fa-solid fa-window-minimize"></i></span>
|
|
<span id='${properties.title}_minimize' class='btn-cover'><i class="fa-solid fa-window-maximize"></i></span>
|
|
<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>
|
|
<div id='${properties.title}_popupDiv'></div>
|
|
|
|
</div>
|
|
`
|
|
this.ViewSpanInteger = document.createElement("div")
|
|
document.body.appendChild(this.ViewSpanInteger);
|
|
this.ViewSpanInteger.outerHTML = this.ViewHTML
|
|
|
|
const header = document.getElementById(properties.title + "_header")
|
|
const windowDiv = document.getElementById(properties.title + "_window")
|
|
this.ViewWindowDiv = windowDiv
|
|
const closeWindow = document.getElementById(properties.title + "_close")
|
|
const minimizeWindow = document.getElementById(properties.title + "_minimize")
|
|
const reduceWindow = document.getElementById(properties.title + "_reduce")
|
|
|
|
closeWindow.addEventListener("click", () => {
|
|
|
|
this.destroy()
|
|
|
|
})
|
|
|
|
reduceWindow.addEventListener("click", () => {
|
|
windowDiv.style.display = "none"
|
|
|
|
})
|
|
|
|
minimizeWindow.addEventListener("click", () => {
|
|
|
|
const windowDiv = document.getElementById(properties.title + "_window")
|
|
const contentDiv = document.getElementById(properties.title + "_content")
|
|
const minimizeIcon = document.getElementById(properties.title + "_minimize").children[0]
|
|
|
|
|
|
if(windowDiv.classList.contains("minimized")) {
|
|
windowDiv.classList.remove("minimized")
|
|
contentDiv.style.display = "unset"
|
|
windowDiv.style.backgroundColor = "#605e58c1"
|
|
minimizeIcon.classList.remove("fa-window-restore")
|
|
minimizeIcon.classList.add("fa-window-maximize")
|
|
} else {
|
|
windowDiv.classList.add("minimized")
|
|
contentDiv.style.display = "none"
|
|
windowDiv.style.backgroundColor = "transparent"
|
|
minimizeIcon.classList.remove("fa-window-maximize")
|
|
minimizeIcon.classList.add("fa-window-restore")
|
|
this.destroyPopup()
|
|
}
|
|
})
|
|
|
|
|
|
|
|
|
|
let isDragging = false;
|
|
let offsetX, offsetY;
|
|
windowDiv.style.zIndex = zIndex + 1
|
|
|
|
|
|
header.addEventListener('mousedown', (e) => {
|
|
isDragging = true;
|
|
|
|
zIndex+=2
|
|
windowDiv.style.zIndex = zIndex
|
|
|
|
|
|
// Enregistrez la position de la souris par rapport à la fenêtre
|
|
offsetX = e.clientX - windowDiv.getBoundingClientRect().left;
|
|
offsetY = e.clientY - windowDiv.getBoundingClientRect().top;
|
|
});
|
|
|
|
// Gérer le déplacement
|
|
document.addEventListener('mousemove', (e) => {
|
|
if (isDragging) {
|
|
|
|
header.style.cursor = "grab"
|
|
|
|
// Calculez la nouvelle position de la fenêtre en fonction de la position de la souris
|
|
const newLeft = e.clientX - offsetX;
|
|
const newTop = e.clientY - offsetY;
|
|
|
|
// Limitation de la position pour éviter un débordement
|
|
const maxX = window.innerWidth - windowDiv.offsetWidth;
|
|
const maxY = window.innerHeight - windowDiv.offsetHeight;
|
|
|
|
windowDiv.style.left = Math.min(Math.max(newLeft, 0), maxX) + 'px';
|
|
windowDiv.style.top = Math.min(Math.max(newTop, 0), maxY) + 'px';
|
|
}
|
|
});
|
|
|
|
// Gérer la fin du glisser-déposer
|
|
document.addEventListener('mouseup', () => {
|
|
header.style.cursor = "unset"
|
|
isDragging = false;
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
this.ViewItem.show()
|
|
|
|
|
|
|
|
}
|
|
|
|
destroy() {
|
|
const win = getID(`${this.ViewProperties.title}_window`)
|
|
win.outerHTML = " "
|
|
AllViews.delete(this.ViewProperties.title)
|
|
this.ViewItem.hide()
|
|
}
|
|
|
|
setContent(text) {
|
|
const contentDiv = document.getElementById(this.ViewProperties.title + "_content")
|
|
contentDiv.innerHTML = text
|
|
}
|
|
|
|
getViewTitle() {
|
|
|
|
return this.ViewProperties.title
|
|
}
|
|
|
|
|
|
|
|
createPopup(properties) {
|
|
|
|
this.ViewPopupHTML = `<div id="${properties.title}_popup" class='view-popup'>
|
|
<div class='view-popup-bar'>
|
|
<p>${properties.title}</p>
|
|
<span id="${properties.title}_popupClose" class='btn-cover'><i class='fa fa-xmark'></i></span>
|
|
</div>
|
|
${properties.content}
|
|
</div>`
|
|
|
|
const contentDiv = getID(this.ViewProperties.title + "_content")
|
|
const popupDiv = getID(this.ViewProperties.title + "_popupDiv")
|
|
this.ViewPopupSpanInteger = document.createElement("div")
|
|
popupDiv.appendChild(this.ViewPopupSpanInteger);
|
|
this.ViewPopupSpanInteger.outerHTML = this.ViewPopupHTML
|
|
|
|
this.ViewPopupTitle = properties.title
|
|
|
|
const popup = getID(properties.title + "_popup")
|
|
const popupClose = getID(properties.title + "_popupClose")
|
|
|
|
popupClose.addEventListener("click", () => {
|
|
|
|
this.destroyPopup()
|
|
|
|
})
|
|
|
|
// Center the popup to the window div
|
|
|
|
popup.style.left = (contentDiv.offsetWidth / 2) - (popup.offsetWidth / 2) + "px"
|
|
popup.style.top = (contentDiv.offsetHeight / 2) - (popup.offsetHeight / 2) + "px"
|
|
|
|
// Render parent element styled blur
|
|
contentDiv.classList.add("blur")
|
|
|
|
// Disable all interractions like click and events with contentDiv children
|
|
|
|
for(var child of contentDiv.children) {
|
|
|
|
child.style.pointerEvents = "none"
|
|
}
|
|
|
|
}
|
|
|
|
destroyPopup() {
|
|
|
|
const popup = getID(this.ViewPopupTitle + "_popup")
|
|
|
|
if(popup) {
|
|
const contentDiv = getID(this.ViewProperties.title + "_content")
|
|
for(var child of contentDiv.children) {
|
|
|
|
child.style.pointerEvents = "unset"
|
|
}
|
|
contentDiv.classList.remove("blur")
|
|
|
|
|
|
popup.outerHTML = ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var AllComponents = new Array()
|
|
|
|
/**
|
|
* Permet de créer un composant de vue
|
|
* @param {object} properties Propriétés du composant de vue
|
|
*/
|
|
class ViewComponent {
|
|
name;
|
|
icon;
|
|
permission;
|
|
window;
|
|
constructor (properties) {
|
|
this.name = properties.name
|
|
this.icon = properties.icon
|
|
this.permission = properties.permission
|
|
|
|
AllComponents.push(this)
|
|
}
|
|
|
|
inject(array) {
|
|
|
|
array.push(`<div id='${this.name}' class='view'>
|
|
<span class='view-image'><i class='${this.icon}'></i></span>
|
|
<p class='view-text'>${this.name}</p>
|
|
</div>`)
|
|
|
|
|
|
}
|
|
|
|
createWindow(functionToExecute) {
|
|
|
|
this.window = functionToExecute
|
|
}
|
|
|
|
bindView() {
|
|
|
|
const component = getID(this.name)
|
|
if(component) {
|
|
component.addEventListener("click", () => {
|
|
console.log(component)
|
|
if(this.window) {
|
|
this.window()
|
|
}
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
forceWindow() {
|
|
|
|
if(this.window) {
|
|
this.window()
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Permet de créer un menu déroulant
|
|
* @param {object} properties Propriétés du menu déroulant
|
|
*/
|
|
|
|
|
|
var ActualDroppableMenu = null
|
|
class DroppableMenu {
|
|
options = new Array()
|
|
id = null
|
|
DMSpanInteger = null
|
|
#enableHide = false
|
|
constructor() {
|
|
|
|
this.id = Math.random().toString(36).substring(7)
|
|
this.options.push(`<div id='dm-${this.id}' class='dm-menu'>`)
|
|
|
|
}
|
|
|
|
add(action, string) {
|
|
|
|
this.options.push("<div id='" + this.id + "_" + action + "' class='dm-element'>" + string + "</div>")
|
|
|
|
}
|
|
|
|
show() {
|
|
console.log("DROPPABLE MENU - " + this.id)
|
|
if(ActualDroppableMenu) {
|
|
ActualDroppableMenu.hide()
|
|
}
|
|
ActualDroppableMenu = this
|
|
|
|
this.options.push(`</div>`)
|
|
|
|
if(xMousePos && yMousePos) {
|
|
|
|
this.DMSpanInteger = document.createElement("span")
|
|
|
|
document.body.appendChild(this.DMSpanInteger);
|
|
this.DMSpanInteger.outerHTML = this.options.join('')
|
|
|
|
const menu = getID(`dm-${this.id}`)
|
|
|
|
menu.style.zIndex = zIndex + 2
|
|
zIndex+=1
|
|
|
|
menu.style.left = (xMousePos - 40) + "px"
|
|
menu.style.top = (yMousePos - 40) + "px"
|
|
|
|
}
|
|
|
|
this.#enableHide = false
|
|
|
|
document.addEventListener("click", () => {
|
|
|
|
this.hide()
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
get(action) {
|
|
|
|
return getID(this.id + "_" + action)
|
|
}
|
|
|
|
hide() {
|
|
|
|
const menu = getID(`dm-${this.id}`)
|
|
if(menu) {
|
|
menu.outerHTML = ""
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Permet de créer un composant de type "Serveur"
|
|
*/
|
|
class Server {
|
|
constructor(properties) {
|
|
this.name = properties.name
|
|
this.description = properties.description
|
|
this.icon = properties.icon
|
|
}
|
|
|
|
generateHTML() {
|
|
return `
|
|
<div class="servers-box">
|
|
<div class="servers-box-title">
|
|
<div class='servers-box-title-info'>
|
|
<i class='${this.icon}'></i>
|
|
<p>${this.name}</p>
|
|
|
|
</div>
|
|
<p style='font-size: 12px;'>${this.description}</p>
|
|
</div>
|
|
<div class="servers-box-content">
|
|
<div class='servers-metrics'>
|
|
<div class='servers-metrics-box'>
|
|
<div>
|
|
<i class='fa-solid fa-memory'></i>
|
|
<p>RAM</p>
|
|
</div>
|
|
<p id='${this.name}_ram'>-- Mo / -- Mo</p>
|
|
</div>
|
|
<div class='servers-metrics-box'>
|
|
<div>
|
|
<i class='fa-solid fa-microchip'></i>
|
|
<p>CPU</p>
|
|
</div>
|
|
<p id='${this.name}_cpu'>---%</p>
|
|
</div>
|
|
<div class='servers-metrics-box'>
|
|
<div>
|
|
<i class='fa-solid fa-hdd'></i>
|
|
<p>DISK</p>
|
|
</div>
|
|
<p id='${this.name}_disk'>-- Go / -- Go</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
`
|
|
}
|
|
|
|
|
|
loadScript() {
|
|
|
|
const ramSpan = getID(`${this.name}_ram`)
|
|
const cpuSpan = getID(`${this.name}_cpu`)
|
|
const diskSpan = getID(`${this.name}_disk`)
|
|
|
|
|
|
setInterval(() => {
|
|
|
|
if(getID(`${this.name}_ram`)) {
|
|
|
|
const request = post(`SERVER_GET_METRICS_` + this.name, this.name )
|
|
console.log(this.name)
|
|
|
|
|
|
request.then((answer) => {
|
|
console.log(answer)
|
|
console.log(this.name)
|
|
//Transform all metrics in mb to answer.metrics to Go or %
|
|
answer.metrics.usedram = Math.round(answer.metrics.usedram)
|
|
answer.metrics.totalram = Math.round(answer.metrics.totalram)
|
|
|
|
//Transform all metrics in blocks to Go
|
|
answer.metrics.usedisk = Math.round((answer.metrics.usedisk * 3.814697265625) / 1000000)
|
|
answer.metrics.totaldisk = Math.round((answer.metrics.totaldisk * 3.814697265625) / 1000000)
|
|
|
|
if(answer.metrics.name == this.name) {
|
|
ramSpan.innerHTML = `${answer.metrics.usedram} Mo / ${answer.metrics.totalram} Mo`
|
|
cpuSpan.innerHTML = answer.metrics.cpu + "%"
|
|
diskSpan.innerHTML = `${answer.metrics.usedisk} Go / ${answer.metrics.totaldisk} Go`
|
|
|
|
}
|
|
|
|
})
|
|
}
|
|
|
|
|
|
|
|
}, 1000)
|
|
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Créer un composant de vue de type "Service"
|
|
* @param {object} properties Propriétés du composant de vue
|
|
*/
|
|
class Service {
|
|
name = null
|
|
description = null
|
|
icon = null
|
|
url = null
|
|
canAccess = false
|
|
isOnline = false
|
|
View = null
|
|
constructor(properties) {
|
|
this.name = properties.name
|
|
this.description = properties.description
|
|
this.icon = properties.icon
|
|
this.url = properties.url
|
|
this.canAccess = properties.canAccess
|
|
this.View = properties.View
|
|
}
|
|
|
|
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">Vérification en cours ...</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", () => {
|
|
this.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 TextResponse("sv-power-info")
|
|
info.setWidth("350px")
|
|
|
|
|
|
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>'
|
|
this.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
|
|
this.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>'
|
|
this.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")
|
|
|
|
}
|
|
|
|
})
|
|
})
|
|
|
|
|
|
})
|
|
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Permet de créer un composant de vue de type "Pipeline"
|
|
* @param {object} properties Propriétés du composant de vue
|
|
*/
|
|
|
|
class Pipeline {
|
|
name;
|
|
pipe;
|
|
class;
|
|
url;
|
|
View;
|
|
constructor(properties) {
|
|
this.name = properties.pipeline.name
|
|
this.class = properties.pipeline._class
|
|
this.url = properties.pipeline.url
|
|
this.pipe = properties.pipeline
|
|
this.View = properties.View
|
|
|
|
if(!this.pipe.description) {
|
|
this.pipe.description = "Aucune description"
|
|
}
|
|
}
|
|
|
|
generateHTML() {
|
|
var image = null
|
|
var classInfo = null
|
|
var lastBuildStatus = ""
|
|
|
|
if(this.class == "hudson.model.FreeStyleProject") {
|
|
image = `<i class="fa fa-folder"></i>`
|
|
|
|
if(this.pipe.lastBuild) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle yellow"></i> Construction en cours ... - N°${this.pipe.nextBuildNumber - 1} </p>`
|
|
if(this.pipe.lastSuccessfulBuild) {
|
|
if(this.pipe.lastSuccessfulBuild.number == this.pipe.nextBuildNumber - 1) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle green"></i> Dernière construction réussie - N°${this.pipe.nextBuildNumber - 1} </p>`
|
|
}
|
|
|
|
}
|
|
if(this.pipe.lastFailedBuild) {
|
|
if(this.pipe.lastFailedBuild.number == this.pipe.nextBuildNumber - 1) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle red"></i> Dernière construction échouée - N°${this.pipe.nextBuildNumber - 1} </p>`
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle"></i> Aucune construction</p>`
|
|
}
|
|
|
|
|
|
// TRUE : lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle green"></i> Dernière construction réussie - N°${this.pipe.jobs[0].lastSuccessfulBuild.number}</p>`
|
|
// BUILDING : lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle yellow"></i> Construction en cours ... - N°${this.pipe.nextBuildNumber - 1} </p>`
|
|
// FAILED : lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle red"></i> Dernière construction échouée - N°${this.pipe.jobs[0].nextBuildNumber - 1} </p>`
|
|
// NOITHING : lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle"></i> Aucune construction</p>`
|
|
} else {
|
|
|
|
image = `<i class="fa fa-code-merge"></i>`
|
|
if(this.pipe.jobs[0].lastBuild) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle yellow"></i> Construction en cours ... - N°${this.pipe.jobs[0].nextBuildNumber - 1} </p>`
|
|
if(this.pipe.jobs[0].lastSuccessfulBuild) {
|
|
if(this.pipe.jobs[0].lastSuccessfulBuild.number == this.pipe.jobs[0].nextBuildNumber - 1) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle green"></i> Dernière construction réussie - N°${this.pipe.jobs[0].nextBuildNumber - 1} </p>`
|
|
}
|
|
|
|
}
|
|
if(this.pipe.jobs[0].lastFailedBuild) {
|
|
if(this.pipe.jobs[0].lastFailedBuild.number == this.pipe.jobs[0].nextBuildNumber - 1) {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle red"></i> Dernière construction échouée - N°${this.pipe.jobs[0].nextBuildNumber - 1} </p>`
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
lastBuildStatus = `<p class='pipeline-status'><i class="fa-solid fa-circle"></i> Aucune construction</p>`
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return `
|
|
<div class="pipeline">
|
|
<div class="pipeline-info">
|
|
${image}
|
|
<div class="pipeline-text">
|
|
<p class='pipeline-title'><strong>${this.name}</strong></p>
|
|
<p><i>${this.pipe.description}</i></p>
|
|
${lastBuildStatus}
|
|
</div>
|
|
</div>
|
|
<div class="pipeline-actions">
|
|
<a href="${this.url}" target="_blank"><button class="btn blue"><span><i class='fa fa-arrow-right'></i> Accéder à la pipeline</span></button></a>
|
|
<button id='${this.name}_pipelinepower' class='btn green'><span><i class='fa fa-play'></i> Démarrer la pipeline<span></button>
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
|
|
loadScript() {
|
|
|
|
const powerButton = getID(`${this.name}_pipelinepower`)
|
|
|
|
powerButton.addEventListener("click", () => {
|
|
if(this.class == "hudson.model.FreeStyleProject" && this.pipe.property[0].parameterDefinitions.length > 0) {
|
|
|
|
var allProperties = new Array()
|
|
|
|
for(const property of this.pipe.property[0].parameterDefinitions) {
|
|
console.log(property)
|
|
if(property.type == "StringParameterDefinition") {
|
|
allProperties.push("<p>" + property.name + "</p><input class='field' type='text' id='" + property.name + "'>")
|
|
}
|
|
if(property.type == "ChoiceParameterDefinition") {
|
|
|
|
var options = new Array()
|
|
for(const option of property.choices) {
|
|
options.push(`<option value='${option}'>${option}</option>`)
|
|
}
|
|
|
|
allProperties.push("<p>" + property.name + "</p><select class='field' id='" + property.name + "'>" + options.join("") + "</select>")
|
|
}
|
|
}
|
|
|
|
|
|
|
|
this.View.createPopup({
|
|
title: `<i class='fa fa-play'></i> Démarrer la pipeline`,
|
|
content: `
|
|
|
|
<p class='sv-power-select'>${this.name}</p>
|
|
<div class='pipeline-options'>
|
|
${allProperties.join("")}
|
|
</div>
|
|
<p id='pl-power-info'></p>
|
|
<button id="${this.name}_start" class="btn green"><span>Démarrer</span></button>
|
|
`
|
|
})
|
|
|
|
const startButton = getID(`${this.name}_start`)
|
|
const info = new TextResponse("pl-power-info")
|
|
|
|
startButton.addEventListener("click", () => {
|
|
info.clear()
|
|
|
|
|
|
var allFields = new Array()
|
|
|
|
for(const property of this.pipe.property[0].parameterDefinitions) {
|
|
|
|
|
|
if(getID(property.name).value == "") {
|
|
info.err("Veuillez remplir tous les champs")
|
|
return
|
|
}
|
|
allFields.push({name: property.name,value: getID(property.name).value} )
|
|
|
|
}
|
|
|
|
const request = post(`PL_START`, {name: this.name, fields: allFields, url: this.url, type: this.class})
|
|
|
|
request.then((answer) => {
|
|
|
|
if(answer == "OK") {
|
|
info.info("La pipeline a été démarrée avec succès")
|
|
this.View.destroyPopup()
|
|
|
|
} else {
|
|
info.err("Impossible de démarrer la pipeline")
|
|
|
|
}
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
} else {
|
|
|
|
// Open a confirmation popup to start the pipeline
|
|
|
|
this.View.createPopup({
|
|
title: `<i class='fa fa-play'></i> Démarrer la pipeline`,
|
|
content: `
|
|
|
|
<p class='sv-power-select'>${this.name}</p>
|
|
<p id='pl-power-info'></p>
|
|
<button id="${this.name}_start" class="btn green"><span>Démarrer</span></button>
|
|
`
|
|
})
|
|
|
|
const startButton = getID(`${this.name}_start`)
|
|
const info = new TextResponse("pl-power-info")
|
|
|
|
startButton.addEventListener("click", () => {
|
|
info.clear()
|
|
const request = post(`PL_START`, {name: this.name, url: this.url, type: this.class, jobname: this.pipe.jobs[0].name})
|
|
|
|
request.then((answer) => {
|
|
console.log(answer)
|
|
if(answer == "OK") {
|
|
info.info("La pipeline a été démarrée avec succès")
|
|
this.View.destroyPopup()
|
|
|
|
} else {
|
|
info.err("Impossible de démarrer la pipeline")
|
|
|
|
}
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
class User {
|
|
constructor(properties) {
|
|
this.username = properties.username
|
|
this.display_name = properties.display_name
|
|
this.picture = properties.picture
|
|
this.permission = properties.permission
|
|
this.View = properties.window
|
|
this.Component = properties.component
|
|
}
|
|
|
|
generateHTML() {
|
|
return `
|
|
<div class='user-line'>
|
|
<div class='user-line-info'>
|
|
<img class='taskbar-image' src='${this.picture}' alt='${this.username}'>
|
|
<div>
|
|
<p class='user-line-displayname'>${this.display_name}</p>
|
|
<p class='taskbar-username'>${this.username}</p>
|
|
</div>
|
|
</div>
|
|
<div class='user-actions'>
|
|
<button id='${this.username}_edit' class='btn blue'><span><i class='fa fa-pencil'></i> Editer<span></button>
|
|
${this.username == "raphix" ? "" : `<button id='${this.username}_delete' class='btn red'><span><i class='fa fa-trash'></i> Supprimer<span></button>`}
|
|
</div>
|
|
</div>
|
|
`
|
|
}
|
|
|
|
loadScript() {
|
|
const editButton = getID(`${this.username}_edit`)
|
|
const deleteButton = getID(`${this.username}_delete`)
|
|
|
|
editButton.addEventListener("click", () => {
|
|
this.View.createPopup({
|
|
title: `<i class='fa fa-pencil'></i> Editer l'utilisateur : ${this.username}`,
|
|
content: `
|
|
<div class='us-edit'>
|
|
<div class='user-edit-actual'>
|
|
<img class='taskbar-image' src='${this.picture}' alt='${this.username}'>
|
|
<p class='user-line-displayname'>${this.display_name}</p>
|
|
<p class='taskbar-username'>${this.username}</p>
|
|
</div>
|
|
<div class='user-edit-line'>
|
|
<p class='user-edit-info'>Nom d'utilisateur</p>
|
|
<input id='${this.username}_editusername' class='field' type='text' value='${this.username}'>
|
|
</div>
|
|
<div class='user-edit-line'>
|
|
<p class='user-edit-info'>Nom d'affichage</p>
|
|
<input id='${this.username}_editdisplay' class='field' type='text' value='${this.display_name}'>
|
|
</div>
|
|
<div class='user-edit-line'>
|
|
<p class='user-edit-info'>Mot de passe</p>
|
|
<input id='${this.username}_editpassword' class='field' type='password' id='user-edit-password'>
|
|
</div>
|
|
<div class='user-edit-line'>
|
|
<p class='user-edit-info'>Permissions</p>
|
|
<div class='permissions'>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_FILES_EXPLORER">
|
|
<label for="${this.username}_perm_FILES_EXPLORER">Fichiers</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_SERVICES">
|
|
<label for="${this.username}_perm_SERVICES">Services</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_LINKS">
|
|
<label for="${this.username}_perm_LINKS">Liens</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_SERVERS">
|
|
<label for="${this.username}_perm_SERVERS">Serveurs</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_PIPELINES">
|
|
<label for="${this.username}_perm_PIPELINES">Pipelines</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_METRICS">
|
|
<label for="${this.username}_perm_METRICS">Metrics</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_USERS">
|
|
<label for="${this.username}_perm_USERS">Utilisateurs</label>
|
|
</div>
|
|
<div>
|
|
<input type="checkbox" id="${this.username}_perm_SETTINGS">
|
|
<label for="${this.username}_perm_SETTINGS">Paramètres</label>
|
|
</div>
|
|
</div>
|
|
<br>
|
|
<div class='user-edit-line'>
|
|
<p class='user-edit-info'>Photo de profil</p>
|
|
<input type="file" id="${this.username}_addpicture" accept="image/png, image/jpeg">
|
|
</div>
|
|
<br>
|
|
<span id="${this.username}_returninfo"></span>
|
|
|
|
</div>
|
|
<div class="user-edit-actions">
|
|
<button id="${this.username}_cedit" class="btn green"><span><i class='fa fa-pencil'></i> Editer</span></button>
|
|
<button id="${this.username}_edittokens" class="btn yellow"><span><i class='fa fa-trash'></i> Tokens</span></button>
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
`
|
|
})
|
|
|
|
const editCButton = getID(`${this.username}_cedit`)
|
|
const editTokensButton = getID(`${this.username}_edittokens`)
|
|
const editUsername = getID(`${this.username}_editusername`)
|
|
const editDisplay = getID(`${this.username}_editdisplay`)
|
|
const editPassword = getID(`${this.username}_editpassword`)
|
|
const editPicture = getID(`${this.username}_addpicture`)
|
|
const returnInfo = new TextResponse(`${this.username}_returninfo`)
|
|
|
|
const editPermissions = new Array()
|
|
|
|
editTokensButton.addEventListener("click", () => {
|
|
const request = post(`US_CLEAR_TOKENS`, this.username)
|
|
request.then((answer) => {
|
|
if(answer == "NO_TOKENS") {
|
|
returnInfo.err("Aucun token n'a été généré pour cet utilisateur")
|
|
} else {
|
|
returnInfo.info("Les tokens ont été éffacés avec succès")
|
|
}
|
|
})
|
|
})
|
|
|
|
|
|
editPermissions.push(getID(`${this.username}_perm_FILES_EXPLORER`))
|
|
editPermissions.push(getID(`${this.username}_perm_SERVICES`))
|
|
editPermissions.push(getID(`${this.username}_perm_LINKS`))
|
|
editPermissions.push(getID(`${this.username}_perm_SERVERS`))
|
|
editPermissions.push(getID(`${this.username}_perm_PIPELINES`))
|
|
editPermissions.push(getID(`${this.username}_perm_METRICS`))
|
|
editPermissions.push(getID(`${this.username}_perm_USERS`))
|
|
editPermissions.push(getID(`${this.username}_perm_SETTINGS`))
|
|
|
|
|
|
for(const actualPerm of this.permission) {
|
|
|
|
getID(`${this.username}_perm_${actualPerm}`).checked = true
|
|
}
|
|
|
|
editUsername.addEventListener("change", () => {
|
|
editUsername.value = editUsername.value.replace(/[^a-zA-Z0-9]/g, '')
|
|
})
|
|
|
|
|
|
|
|
|
|
editCButton.addEventListener("click", () => {
|
|
const newPerms = new Array()
|
|
for(const permission of editPermissions) {
|
|
if(permission.checked) {
|
|
newPerms.push(permission.id.replace(`${this.username}_perm_`, ""))
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const request = post(`US_EDIT`, {username: this.username, newusername: editUsername.value, display_name: editDisplay.value, password: editPassword.value, permissions: newPerms, picture: editPicture.files[0]})
|
|
request.then((answer) => {
|
|
if(answer == "ALREADY_EXIST") {
|
|
|
|
returnInfo.err("L'utilisateur existe déjà !")
|
|
|
|
} else if(answer == "USERNAME_MISSING") {
|
|
|
|
returnInfo.err("Le nom d'utilisateur est manquant !")
|
|
} else if(answer == "DISPLAY_NAME_MISSING") {
|
|
|
|
returnInfo.err("Le nom d'affichage est manquant !")
|
|
} else if(answer == "PASSWORD_MISSING") {
|
|
|
|
returnInfo.err("Le mot de passe est manquant !")
|
|
} else {
|
|
|
|
this.View.destroyPopup()
|
|
this.View.destroy()
|
|
this.Component.forceWindow()
|
|
loadUserInfo()
|
|
}
|
|
})
|
|
})
|
|
|
|
|
|
})
|
|
|
|
if(this.username != "raphix") {
|
|
deleteButton.addEventListener("click", () => {
|
|
this.View.createPopup({
|
|
title: `<i class='fa fa-trash'></i> Supprimer l'utilisateur : ${this.username}`,
|
|
content: `
|
|
<p class='us-delete'>Voulez-vous vraiment supprimer l'utilisateur <strong>${this.username}</strong> ?</p>
|
|
|
|
<button id="${this.username}_deleteconfirm" class="btn red"><span><i class='fa fa-trash'></i> Supprimer</span></button>
|
|
|
|
`
|
|
})
|
|
|
|
const deleteCButton = getID(`${this.username}_deleteconfirm`)
|
|
|
|
deleteCButton.addEventListener("click", () => {
|
|
const request = post(`US_DELETE`, this.username)
|
|
request.then((answer) => {
|
|
if(answer == "OK") {
|
|
this.View.destroyPopup()
|
|
this.View.destroy()
|
|
this.Component.forceWindow()
|
|
} else {
|
|
console.log(answer)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Permet de créer un composant de vue de type "Metrics"
|
|
*/
|
|
class Metric {
|
|
properties;
|
|
View;
|
|
Component;
|
|
data;
|
|
constructor(settings) {
|
|
this.properties = settings.properties
|
|
this.View = settings.View
|
|
this.Component = settings.Component
|
|
this.data = settings.properties.data
|
|
}
|
|
|
|
generateHTML() {
|
|
return `
|
|
<div class="metric">
|
|
<div class="metric-info">
|
|
<div class="metric-text">
|
|
<p class='metric-title'><strong>${this.properties.name}</strong></p>
|
|
<p class='metric-id'>${this.properties.id}</p>
|
|
</div>
|
|
</div>
|
|
<div id='${this.properties.id}_content' class="metric-content">
|
|
</div>
|
|
<div class="metric-actions">
|
|
|
|
<button id='${this.properties.id}_metricpower' class='btn red'><span><i class='fa fa-trash'></i> Supprimer<span></button>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
`
|
|
|
|
}
|
|
|
|
loadScript() {
|
|
|
|
const contentDiv = getID(`${this.properties.id}_content`)
|
|
|
|
if(this.data == "ERROR") {
|
|
contentDiv.innerHTML += `<p class='metric-error'>Impossible de charger les données de la métrique</p>`
|
|
|
|
} else {
|
|
for(const data of this.data) {
|
|
contentDiv.innerHTML += `<div class='metric-data'><div class='metric-data-div'><p class='metric-data-title'>${data.description}</p><p class='metric-data-id'>${data.name}</p></div><p class='metric-data-value'>Valeur : <span>${data.value}<span></p></div>`
|
|
|
|
}
|
|
}
|
|
|
|
|
|
const deleteButton = getID(`${this.properties.id}_metricpower`)
|
|
|
|
deleteButton.addEventListener("click", () => {
|
|
this.View.createPopup({
|
|
title: `<i class='fa fa-trash'></i> Supprimer la métrique : ${this.properties.name}`,
|
|
content: `
|
|
<p class='us-delete'>Voulez-vous vraiment supprimer la métrique <strong>${this.properties.name}</strong> ?</p>
|
|
|
|
<button id="${this.properties.id}_deleteconfirm" class="btn red"><span><i class='fa fa-trash'></i> Supprimer</span></button>
|
|
|
|
`
|
|
})
|
|
|
|
const deleteCButton = getID(`${this.properties.id}_deleteconfirm`)
|
|
|
|
deleteCButton.addEventListener("click", () => {
|
|
const request = post(`MT_DELETE`, this.properties.id)
|
|
request.then((answer) => {
|
|
if(answer == "OK") {
|
|
this.View.destroyPopup()
|
|
this.View.destroy()
|
|
this.Component.forceWindow()
|
|
|
|
} else {
|
|
console.log(answer)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Permet de créer un item de la barre des tâches
|
|
* @param {ViewWindow} window ViewWindow associé à l'item
|
|
*/
|
|
class ViewItem {
|
|
/**
|
|
*
|
|
* @param {ViewWindow} window
|
|
*/
|
|
constructor(window) {
|
|
this.window = window
|
|
}
|
|
|
|
show() {
|
|
const viewItems = getID("views-items")
|
|
const item = document.createElement("div")
|
|
item.id = `${this.window.ViewProperties.title}_item`
|
|
item.classList.add("view-item")
|
|
item.innerHTML = this.window.ViewProperties.title
|
|
|
|
viewItems.appendChild(item)
|
|
|
|
item.addEventListener("click", () => {
|
|
zIndex+=1
|
|
this.window.ViewWindowDiv.style.zIndex = zIndex + 1
|
|
this.window.ViewWindowDiv.style.display = "unset"
|
|
})
|
|
|
|
item.addEventListener("contextmenu", () => {
|
|
const dp = new DroppableMenu()
|
|
|
|
dp.add("index", `<i class='fa fa-window-restore'></i> Afficher`)
|
|
dp.add("close", `<span class='menu-signout'><i class='fa fa-xmark'></i> Fermer</span>`)
|
|
dp.show()
|
|
|
|
const index = dp.get("index")
|
|
const close = dp.get("close")
|
|
|
|
index.addEventListener("click", () => {
|
|
zIndex+=1
|
|
this.window.ViewWindowDiv.style.display = "unset"
|
|
this.window.ViewWindowDiv.style.zIndex = zIndex + 1
|
|
dp.hide()
|
|
})
|
|
|
|
close.addEventListener("click", () => {
|
|
this.window.destroy()
|
|
dp.hide()
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
hide() {
|
|
const viewItems = getID("views-items")
|
|
const item = getID(`${this.window.ViewProperties.title}_item`)
|
|
|
|
item.outerHTML = ""
|
|
}
|
|
|
|
}
|
|
|