Version 0.5.0 - Ajout des pipelines
	
		
			
	
		
	
	
		
	
		
			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:
		
							
								
								
									
										138
									
								
								bin/pipelines.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								bin/pipelines.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
const { LogType } = require("loguix")
 | 
			
		||||
const fs = require("fs")
 | 
			
		||||
const path = require("path")
 | 
			
		||||
const { __glob } = require("./global-variables")
 | 
			
		||||
const clog = new LogType("Pïpeline")
 | 
			
		||||
const config = require("./config")
 | 
			
		||||
 | 
			
		||||
const tokenkey = config.getFile().JENKINS_TOKEN
 | 
			
		||||
 | 
			
		||||
module.exports.getAllPipelines = function() {
 | 
			
		||||
 | 
			
		||||
    return new Promise((resolve, reject) => {
 | 
			
		||||
       
 | 
			
		||||
        
 | 
			
		||||
        fetch(`https://jenkins.raphix.fr/api/json`, {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Accept": "application/json",
 | 
			
		||||
                "Authorization": `Basic ${tokenkey}`
 | 
			
		||||
            },
 | 
			
		||||
            credentials: "include"
 | 
			
		||||
        })
 | 
			
		||||
        .then(res => res.json())
 | 
			
		||||
        .then(async list  => {
 | 
			
		||||
 | 
			
		||||
            const pipelinesJobs = new Array()
 | 
			
		||||
 | 
			
		||||
            for(const job of list.jobs) {
 | 
			
		||||
                    await fetch(`${job.url}/api/json`, {
 | 
			
		||||
                    method: "GET",
 | 
			
		||||
                    headers: {
 | 
			
		||||
                        "Accept": "application/json",
 | 
			
		||||
                        "Authorization": `Basic ${tokenkey}`
 | 
			
		||||
                    },
 | 
			
		||||
                    credentials: "include"
 | 
			
		||||
                    })
 | 
			
		||||
                    .then(res => res.json())
 | 
			
		||||
                    .then(async res => {
 | 
			
		||||
 | 
			
		||||
                       if(res._class == "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject") {
 | 
			
		||||
                            await getJobMain(res).then(resJ => {
 | 
			
		||||
                                res.jobs[0] = resJ
 | 
			
		||||
                                pipelinesJobs.push(res)
 | 
			
		||||
                            })
 | 
			
		||||
                       } else {
 | 
			
		||||
                            pipelinesJobs.push(res)
 | 
			
		||||
 | 
			
		||||
                       }
 | 
			
		||||
 | 
			
		||||
                 
 | 
			
		||||
                    })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            list.jobs = pipelinesJobs
 | 
			
		||||
 | 
			
		||||
            resolve(list)
 | 
			
		||||
 | 
			
		||||
           
 | 
			
		||||
        })
 | 
			
		||||
        .catch(err => {
 | 
			
		||||
            resolve("UNAVAILABLE")
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports.startPipeline = function(pipeline) {
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
// If it's a freestyle job, build with params
 | 
			
		||||
 | 
			
		||||
    if(pipeline.type == "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject") {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            fetch(`${pipeline.url}/job/${pipeline.jobname}/build?delay=0sec`, {
 | 
			
		||||
                method: "POST",
 | 
			
		||||
                headers: {
 | 
			
		||||
                    "Authorization": `Basic ${tokenkey}`
 | 
			
		||||
                },
 | 
			
		||||
                credentials: "include"
 | 
			
		||||
            })
 | 
			
		||||
            .then(res => {
 | 
			
		||||
                resolve("OK")
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
    } else {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            const parameters = pipeline.fields
 | 
			
		||||
 | 
			
		||||
            const formatedParams = new URLSearchParams()
 | 
			
		||||
 | 
			
		||||
            for(const param of parameters) {
 | 
			
		||||
                formatedParams.append(param.name, param.value)
 | 
			
		||||
            }
 | 
			
		||||
         
 | 
			
		||||
          
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            fetch(`${pipeline.url}/buildWithParameters?delay=0sec`, {
 | 
			
		||||
                method: "POST",
 | 
			
		||||
                headers: {
 | 
			
		||||
                    "Authorization": `Basic ${tokenkey}`,
 | 
			
		||||
                    "Content-Type": "application/x-www-form-urlencoded"
 | 
			
		||||
                },
 | 
			
		||||
                credentials: "include",
 | 
			
		||||
                body: formatedParams
 | 
			
		||||
            })
 | 
			
		||||
            .then(res => {
 | 
			
		||||
                resolve("OK")
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getJobMain(res) {
 | 
			
		||||
 | 
			
		||||
    return new Promise(async (resolve,  reject) => {
 | 
			
		||||
        
 | 
			
		||||
        await fetch(`${res.jobs[0].url}/api/json`, {
 | 
			
		||||
            method: "GET",
 | 
			
		||||
            headers: {
 | 
			
		||||
                'Accept': 'application/json',
 | 
			
		||||
                'Authorization': `Basic ${tokenkey}`
 | 
			
		||||
            },
 | 
			
		||||
            credentials: 'include'
 | 
			
		||||
        }).then(res => res.json())
 | 
			
		||||
        .then(res => {
 | 
			
		||||
            resolve(res)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
       
 | 
			
		||||
    })
 | 
			
		||||
        
 | 
			
		||||
}
 | 
			
		||||
@@ -6,6 +6,7 @@ const auth = require("./auth.js")
 | 
			
		||||
const files = require("./files.js")
 | 
			
		||||
const links = require("./links.js")
 | 
			
		||||
const service = require("./services.js")
 | 
			
		||||
const pipeline = require("./pipelines.js")
 | 
			
		||||
const plog = new LogType("Web")
 | 
			
		||||
const cook = require("cookie")
 | 
			
		||||
const http = require("http")
 | 
			
		||||
@@ -151,6 +152,17 @@ module.exports.serverIO = function(server) {
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(user.checkPermission("PIPELINES")) {
 | 
			
		||||
                GetRequest("PL_GET_ALL", async () => {
 | 
			
		||||
                    GetAnswer("PL_GET_ALL", await pipeline.getAllPipelines())
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                PostRequest("PL_START", async (settings) => {
 | 
			
		||||
                    PostAnswer("PL_START", await pipeline.startPipeline(settings))
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            socket.on("disconnect", () => {
 | 
			
		||||
 | 
			
		||||
                plog.log("Déconnexion du panel par '" + user.username + "' avec le socket : " + socket.id)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "neutral",
 | 
			
		||||
  "version": "0.4.0",
 | 
			
		||||
  "version": "0.5.0",
 | 
			
		||||
  "description": "Panel d'administration de Raphix",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
 
 | 
			
		||||
@@ -201,6 +201,7 @@ class ViewWindow {
 | 
			
		||||
            let offsetX, offsetY;
 | 
			
		||||
            windowDiv.style.zIndex = zIndex + 1
 | 
			
		||||
 | 
			
		||||
         
 | 
			
		||||
            header.addEventListener('mousedown', (e) => {
 | 
			
		||||
                isDragging = true;
 | 
			
		||||
                
 | 
			
		||||
@@ -244,6 +245,8 @@ class ViewWindow {
 | 
			
		||||
 | 
			
		||||
        this.ViewItem.show()
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    destroy() {
 | 
			
		||||
@@ -577,12 +580,14 @@ class Service {
 | 
			
		||||
    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() {
 | 
			
		||||
@@ -633,7 +638,7 @@ class Service {
 | 
			
		||||
            // 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({
 | 
			
		||||
                this.View.createPopup({
 | 
			
		||||
                    title: `<i class='fa-solid fa-power-off'></i> Gestion de l'alimentation du service`,
 | 
			
		||||
                    content: `
 | 
			
		||||
                    
 | 
			
		||||
@@ -650,7 +655,7 @@ class Service {
 | 
			
		||||
                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")
 | 
			
		||||
                const info = new TextResponse("sv-power-info")
 | 
			
		||||
                
 | 
			
		||||
                
 | 
			
		||||
 | 
			
		||||
@@ -670,7 +675,7 @@ class Service {
 | 
			
		||||
                    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.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")
 | 
			
		||||
@@ -687,7 +692,7 @@ class Service {
 | 
			
		||||
                        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`")
 | 
			
		||||
                            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")
 | 
			
		||||
@@ -706,7 +711,7 @@ class Service {
 | 
			
		||||
                    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.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")
 | 
			
		||||
@@ -724,6 +729,227 @@ class 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")
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Permet de créer un item de la barre des tâches
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@ const infoUsername = getID("infoUsername")
 | 
			
		||||
const infoUserimage = getID("infoUserimage")
 | 
			
		||||
const infoDisplayname = getID("infoDisplayname")
 | 
			
		||||
const views = getID("views")
 | 
			
		||||
 | 
			
		||||
const panelBox = getID("panel-box")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// User Request
 | 
			
		||||
@@ -32,8 +32,10 @@ REQ_user.then((ANS_user) => {
 | 
			
		||||
 | 
			
		||||
    if(AvailableViews.join("") == "") {
 | 
			
		||||
 | 
			
		||||
        AvailableViews.push("<p style='position: absolute; width: 100%;' class='yellow t-center'><i class='fa-solid fa-warning'></i> Aucune permission ne semble vous êtes accordée<br>Demandez à Raphix afin de résoudre ce problème</p>")
 | 
			
		||||
        AvailableViews.push("<p style='width: 100%;' class='yellow t-center'><i class='fa-solid fa-warning'></i> Aucune permission ne semble vous êtes accordée<br>Demandez à Raphix afin de résoudre ce problème</p>")
 | 
			
		||||
        views.classList.remove("views-box")
 | 
			
		||||
        panelBox.style.justifyContent = "unset"
 | 
			
		||||
        console.log(panelBox.style)
 | 
			
		||||
    } else {
 | 
			
		||||
 | 
			
		||||
        views.classList.add("views-box")
 | 
			
		||||
@@ -47,7 +49,6 @@ REQ_user.then((ANS_user) => {
 | 
			
		||||
        component.bindView()
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    servers.forceWindow()
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ const explorer = new ViewComponent({
 | 
			
		||||
  })
 | 
			
		||||
  
 | 
			
		||||
  const links = new ViewComponent({
 | 
			
		||||
    name: "Gestion des liens",
 | 
			
		||||
    name: "Générateur des liens",
 | 
			
		||||
    icon: "fa-solid fa-link",
 | 
			
		||||
    permission: "LINKS"
 | 
			
		||||
  })
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										66
									
								
								public/javascripts/pipeline.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								public/javascripts/pipeline.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
pipelines.createWindow(() => {
 | 
			
		||||
 | 
			
		||||
    const View = new ViewWindow({
 | 
			
		||||
        title: `<i class="fa fa-code-merge"></i> Gestion des pipelines`,
 | 
			
		||||
        width: "900px",
 | 
			
		||||
        height: "600px"
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const pipelinesList = new Array()
 | 
			
		||||
 | 
			
		||||
    View.setContent(`<div style='font-size: 24px; margin-top: 225px;'  class='t-center'>
 | 
			
		||||
        <p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
 | 
			
		||||
    </div>`)
 | 
			
		||||
 | 
			
		||||
    var AllPipelines = new Array()
 | 
			
		||||
 | 
			
		||||
    function getPipelines() {
 | 
			
		||||
 | 
			
		||||
        const pipes = get("PL_GET_ALL")
 | 
			
		||||
        pipes.then((ANS_pipes) => {
 | 
			
		||||
        
 | 
			
		||||
            AllPipelines.length = 0
 | 
			
		||||
           pipelinesList.length = 0
 | 
			
		||||
 | 
			
		||||
            if(ANS_pipes != "UNAVAILABLE") {
 | 
			
		||||
                ANS_pipes.jobs.forEach((pipe) => {
 | 
			
		||||
                    console.log(pipe)
 | 
			
		||||
                    const pipeline = new Pipeline({
 | 
			
		||||
                        pipeline: pipe,
 | 
			
		||||
                        View: View
 | 
			
		||||
                    })
 | 
			
		||||
        
 | 
			
		||||
                    pipelinesList.push(pipeline.generateHTML())
 | 
			
		||||
                    AllPipelines.push(pipeline)
 | 
			
		||||
                })
 | 
			
		||||
        
 | 
			
		||||
                View.setContent(`
 | 
			
		||||
                <div class="pipelines">
 | 
			
		||||
                    <div id='reload_Btn_pipeline' class='pl-reload'><i class='fa fa-rotate-left'></i> Recharger les pipelines</div>
 | 
			
		||||
                    ${pipelinesList.join("")}
 | 
			
		||||
                </div>`)
 | 
			
		||||
 | 
			
		||||
                for(const pipeline of AllPipelines) {
 | 
			
		||||
                    pipeline.loadScript()
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                getID("reload_Btn_pipeline").addEventListener("click", () => {
 | 
			
		||||
                    View.setContent(`<div style='font-size: 24px; margin-top: 225px;'  class='t-center'>
 | 
			
		||||
                    <p><i class="fa-solid fa-rotate fa-spin"></i> Chargement en cours ...</p>
 | 
			
		||||
                    </div>`)
 | 
			
		||||
                    getPipelines()
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            } else {
 | 
			
		||||
                View.setContent(`<div style='font-size: 24px; margin-top: 225px;'  class='t-center lightred'>
 | 
			
		||||
                <p><i class="fa-solid fa-warning"></i> Une erreur est survenue lors du chargement des pipelines</p>
 | 
			
		||||
                </div>`)
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getPipelines()
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
@@ -15,8 +15,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Bot de streaming musical sur Discord",
 | 
			
		||||
        icon: "/images/services/subsonics.png",
 | 
			
		||||
        url: "https://subsonics.raphix.fr" ,
 | 
			
		||||
        canAccess: true
 | 
			
		||||
        
 | 
			
		||||
        canAccess: true,
 | 
			
		||||
        View: View
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@@ -25,7 +25,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Gestionnaire de dépôt Git",
 | 
			
		||||
        icon: "/images/services/gitea.svg",
 | 
			
		||||
        url: "https://git.raphix.fr" ,
 | 
			
		||||
        canAccess: true
 | 
			
		||||
        canAccess: true,
 | 
			
		||||
        View: View
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@@ -34,7 +35,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Gestionnaire de pipeline",
 | 
			
		||||
        icon: "/images/services/jenkins.svg",
 | 
			
		||||
        url: "https://jenkins.raphix.fr" ,
 | 
			
		||||
        canAccess: true
 | 
			
		||||
        canAccess: true,
 | 
			
		||||
        View: View
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@@ -43,7 +45,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Site web de Raphix",
 | 
			
		||||
        icon: "/images/services/raphix.png",
 | 
			
		||||
        url: "https://raphix.fr",
 | 
			
		||||
        canAccess: true
 | 
			
		||||
        canAccess: true,
 | 
			
		||||
        View: View
 | 
			
		||||
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@@ -52,7 +55,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Curriculum Vitae de Raphix",
 | 
			
		||||
        icon: "/images/services/cv.png",
 | 
			
		||||
        url: "https://cv.raphix.fr",
 | 
			
		||||
        canAccess: true
 | 
			
		||||
        canAccess: true,
 | 
			
		||||
        View: View
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    const lavalink = new Service({
 | 
			
		||||
@@ -60,7 +64,8 @@ services.createWindow(async () => {
 | 
			
		||||
        description: "Serveur Lavalink pour Subsonics",
 | 
			
		||||
        icon: "/images/services/lavalink.svg",
 | 
			
		||||
        url: "http://omega.raphix.fr:2333",
 | 
			
		||||
        canAccess: false
 | 
			
		||||
        canAccess: false,
 | 
			
		||||
        View: View
 | 
			
		||||
    })
 | 
			
		||||
    
 | 
			
		||||
    allServices.push(subsonicsService.generateHTML())
 | 
			
		||||
 
 | 
			
		||||
@@ -291,7 +291,7 @@ a {
 | 
			
		||||
  backdrop-filter: blur(10px);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-box {
 | 
			
		||||
.taskbar-box {
 | 
			
		||||
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
@@ -303,31 +303,31 @@ a {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-content {
 | 
			
		||||
.taskbar-content {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-image {
 | 
			
		||||
.taskbar-image {
 | 
			
		||||
 | 
			
		||||
  width: 50px;
 | 
			
		||||
  height: 50px;
 | 
			
		||||
  border-radius: 100%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-logo {
 | 
			
		||||
.taskbar-logo {
 | 
			
		||||
  width: 50px;
 | 
			
		||||
  
 | 
			
		||||
  transition: 0.3s;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-logo:hover {
 | 
			
		||||
.taskbar-logo:hover {
 | 
			
		||||
  transform: scale(0.9);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-user {
 | 
			
		||||
.taskbar-user {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
@@ -335,14 +335,14 @@ a {
 | 
			
		||||
  align-items: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-userinfo {
 | 
			
		||||
.taskbar-userinfo {
 | 
			
		||||
  text-align: end;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  gap: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-actions {
 | 
			
		||||
.taskbar-actions {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
@@ -351,7 +351,7 @@ a {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.subpanel-username {
 | 
			
		||||
.taskbar-username {
 | 
			
		||||
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
  color: rgba(255, 255, 255, 0.68);
 | 
			
		||||
@@ -419,7 +419,7 @@ a {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.subpanel-dispname {
 | 
			
		||||
.taskbar-dispname {
 | 
			
		||||
 | 
			
		||||
  margin-block: 0 !important;
 | 
			
		||||
}
 | 
			
		||||
@@ -967,3 +967,87 @@ a {
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* PIPELINES */
 | 
			
		||||
 | 
			
		||||
.pipelines {
 | 
			
		||||
  
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
  overflow-y: auto;
 | 
			
		||||
  height: 85%;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  justify-content: space-between;
 | 
			
		||||
  padding: 10px;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  background-color: #1b1b1bc1;
 | 
			
		||||
  transition: 0.1s;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline-info {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  font-size: 50px;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline-title {
 | 
			
		||||
 | 
			
		||||
  font-size: 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline-text {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  font-size: 14px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline-actions {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
  align-items: flex-end;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.pipeline-options {
 | 
			
		||||
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.pl-reload {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  font-size: 17px;
 | 
			
		||||
  transition: 0.1s;
 | 
			
		||||
  gap: 10px;
 | 
			
		||||
  padding: 5px;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.pl-reload:hover {
 | 
			
		||||
 | 
			
		||||
  background-color: rgba(44, 40, 42, 0.614);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,16 +5,16 @@
 | 
			
		||||
    <link rel='stylesheet' href='/stylesheets/style.css' />
 | 
			
		||||
  </head>
 | 
			
		||||
  <body class="LOG_body">
 | 
			
		||||
    <div class="panel-box m-align t-center">
 | 
			
		||||
    <div id='panel-box' class="panel-box m-align t-center">
 | 
			
		||||
      <div class="logo"><img class="logo-img" src="/images/FormatLogo_WHITE.svg"><p>Neutral</p></div>
 | 
			
		||||
      <div id="views" class="views-box">
 | 
			
		||||
        <p style="position: absolute; width: 100%;" class='yellow t-center'><i class='fa-solid fa-warning'></i> Aucune permission ne semble vous êtes accordée<br>Demandez à Raphix afin de résoudre ce problème</p>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="subpanel-box m-align t-center">
 | 
			
		||||
      <div class="subpanel-content">
 | 
			
		||||
        <div class="subpanel-actions">
 | 
			
		||||
          <img id="menu-logo" class="subpanel-logo" src="/images/FormatLogo_WHITE.svg">
 | 
			
		||||
    <div class="taskbar-box m-align t-center">
 | 
			
		||||
      <div class="taskbar-content">
 | 
			
		||||
        <div class="taskbar-actions">
 | 
			
		||||
          <img id="menu-logo" class="taskbar-logo" src="/images/FormatLogo_WHITE.svg">
 | 
			
		||||
          <div id="views-items" class="views-items">
 | 
			
		||||
            <div class="view-item menu-signout" onclick="window.location = '/login/signout'">
 | 
			
		||||
              <i class="fas fa-sign-out-alt"></i>
 | 
			
		||||
@@ -23,12 +23,12 @@
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <div class="subpanel-user">
 | 
			
		||||
          <div class="subpanel-userinfo">
 | 
			
		||||
            <p id="infoDisplayname" class="subpanel-dispname">DisplayName</p>
 | 
			
		||||
            <p id="infoUsername" class="subpanel-username">Username</p>
 | 
			
		||||
        <div class="taskbar-user">
 | 
			
		||||
          <div class="taskbar-userinfo">
 | 
			
		||||
            <p id="infoDisplayname" class="taskbar-dispname">DisplayName</p>
 | 
			
		||||
            <p id="infoUsername" class="taskbar-username">Username</p>
 | 
			
		||||
          </div>
 | 
			
		||||
          <img id="infoUserimage" class="subpanel-image" src="/images/users/default.jpg">
 | 
			
		||||
          <img id="infoUserimage" class="taskbar-image" src="/images/users/default.jpg">
 | 
			
		||||
 
 | 
			
		||||
        </div>
 | 
			
		||||
       
 | 
			
		||||
@@ -43,6 +43,7 @@
 | 
			
		||||
    <script src="/javascripts/link.js"></script>
 | 
			
		||||
    <script src="/javascripts/service.js"></script>
 | 
			
		||||
    <script src="/javascripts/server.js"></script>
 | 
			
		||||
    <script src="/javascripts/pipeline.js"></script>
 | 
			
		||||
    <script src="/javascripts/filexplorer.js"></script>
 | 
			
		||||
    <script src="/javascripts/indexscript.js"></script>
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user