diff --git a/bin/links.js b/bin/links.js
new file mode 100644
index 0000000..5850281
--- /dev/null
+++ b/bin/links.js
@@ -0,0 +1,106 @@
+const { LogType } = require("loguix")
+const fs = require("fs")
+const path = require("path")
+const { __glob } = require("./global-variables")
+const ulog = new LogType("Links")
+const uuid = require("uuid")
+const config = require("./config")
+const {ApplyLinks} = require("../routes/link")
+
+
+
+if(!fs.existsSync(__glob.DATA + path.sep + "links.json")) {
+ fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify([], null, 2))
+}
+
+module.exports.getLinks = function() {
+ return JSON.parse(fs.readFileSync(__glob.DATA + path.sep + "links.json"))
+}
+
+const FirstLinkManager = new ApplyLinks(this.getLinks())
+
+
+module.exports.addLink = function(settings) {
+
+ var canDo = true
+ const links = this.getLinks()
+ var id = makeid(8)
+
+ if(settings.abstractLink) {
+ settings.dest = id.toString()
+ }
+
+
+
+ // Check if a destination already exists between links and if it's the case, we return an error "ALREADY_EXiST"
+ links.forEach((link) => {
+ if(link.dest == settings.dest) {
+
+ canDo = false
+ }
+
+ })
+
+ const link = {
+ id: id,
+ title: settings.title,
+ url: settings.url,
+ dest: settings.dest,
+ }
+
+ if(canDo) {
+
+ links.push(link)
+ fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(links, null, 2))
+ const LinkManager = new ApplyLinks(this.getLinks())
+ return "OK"
+
+ } else {
+
+ return "ALREADY_EXIST"
+ }
+
+
+}
+
+module.exports.removeLink = function(id) {
+ const links = this.getLinks()
+ const newLinks = []
+ links.forEach((link) => {
+ if(link.id != id) {
+ newLinks.push(link)
+ }
+ })
+ fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(newLinks, null, 2))
+ const LinkManager = new ApplyLinks(this.getLinks())
+ return "OK"
+}
+
+module.exports.updateLink = function(id, settings) {
+ const links = this.getLinks()
+ const newLinks = []
+ links.forEach((link) => {
+ if(link.id == id) {
+ link.title = settings.title
+ link.url = settings.url
+ }
+ newLinks.push(link)
+ })
+ fs.writeFileSync(__glob.DATA + path.sep + "links.json", JSON.stringify(newLinks, null, 2))
+ const LinkManager = new ApplyLinks(this.getLinks())
+ return "OK"
+}
+
+
+
+function makeid(length) {
+ let result = '';
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+ const charactersLength = characters.length;
+ let counter = 0;
+ while (counter < length) {
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
+ counter += 1;
+ }
+ return result;
+}
diff --git a/bin/server.js b/bin/server.js
index 4e55afa..feaeb66 100644
--- a/bin/server.js
+++ b/bin/server.js
@@ -4,6 +4,7 @@ const path = require("path")
const { __glob } = require("./global-variables")
const auth = require("./auth")
const files = require("./files")
+const links = require("./links.js")
const service = require("./services")
const plog = new LogType("Web")
const cook = require("cookie")
@@ -113,6 +114,24 @@ module.exports.serverIO = function(server) {
PostAnswer("SV_RESTART_SERVICE", {answer: await service.restartService(sv), name: sv})
})
+ }
+
+ if(user.checkPermission("LINKS")) {
+ PostRequest("LINKS_GET_ALL", () => {
+ PostAnswer("LINKS_GET_ALL", {answer: "OK", links: links.getLinks()})
+ })
+
+ PostRequest("LINKS_ADD", (settings) => {
+ PostAnswer("LINKS_ADD", {answer: links.addLink(settings)})
+ })
+
+ PostRequest("LINKS_DELETE", (id) => {
+ PostAnswer("LINKS_DELETE", links.removeLink(id))
+ })
+
+ PostRequest("LINKS_EDIT", (settings) => {
+ PostAnswer("LINKS_EDIT", links.updateLink(settings.id, settings))
+ })
}
diff --git a/main.js b/main.js
index d8a00d6..955a27c 100644
--- a/main.js
+++ b/main.js
@@ -49,6 +49,7 @@ function setup() {
app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')))
app.use("/shared", express.static(__glob.SHARED))
+
getRouters()
users.fetchUsers()
diff --git a/package.json b/package.json
index ab54ce6..186159c 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "neutral",
- "version": "0.3.2",
+ "version": "0.3.3",
"description": "Panel d'administration de Raphix",
"main": "index.js",
"scripts": {
diff --git a/public/javascripts/basics.js b/public/javascripts/basics.js
index b57320a..c4fb625 100644
--- a/public/javascripts/basics.js
+++ b/public/javascripts/basics.js
@@ -249,7 +249,11 @@ function createView(viewType) {
}
if(viewType == 'service') {
- generateServiceView()
+ generateServiceView()
+ }
+ if(viewType == "links") {
+
+ generateLinksView()
}
}
diff --git a/public/javascripts/indexscript.js b/public/javascripts/indexscript.js
index a833d32..a934865 100644
--- a/public/javascripts/indexscript.js
+++ b/public/javascripts/indexscript.js
@@ -55,7 +55,7 @@ REQ_user.then((ANS_user) => {
`)
}
if(permValue == "LINKS") {
- AvailableViews.push(`
+ AvailableViews.push(`
`)
diff --git a/public/javascripts/link.js b/public/javascripts/link.js
new file mode 100644
index 0000000..ee6e1ed
--- /dev/null
+++ b/public/javascripts/link.js
@@ -0,0 +1,295 @@
+function generateLinksView() {
+
+ const View = new ViewWindow({
+ title: `
Générateur de liens`,
+ width: "600px",
+ height: "600px",
+ })
+
+ View.setContent(`
+
+
+
+
+
+ `)
+
+ const addBtn = getID(`${View.getViewTitle()}_add`)
+ const linksDiv = getID(`${View.getViewTitle()}_links`)
+ var links = new Array()
+
+ addBtn.addEventListener("click", () => {
+
+ View.createPopup({
+ title: `
Ajouter un lien`,
+ content: `
+
+
+
+
+
Abstraire le lien :
+
+
+
+
+
+
+ `
+ })
+
+ const titleInput = getID(`${View.getViewTitle()}_title`)
+ const urlInput = getID(`${View.getViewTitle()}_url`)
+ const addBtn = getID(`${View.getViewTitle()}_confirm`)
+ const info = new InfoPop(`${View.getViewTitle()}_info`)
+ const ablink = getID(`${View.getViewTitle()}_ablink`)
+ const newlinkSpan = getID(`${View.getViewTitle()}_newlink_span`)
+
+ ablink.checked = true
+
+ ablink.addEventListener("click", () => {
+
+ if(!ablink.checked) {
+
+ newlinkSpan.innerHTML = `
+
+ `
+
+
+
+ } else {
+
+ newlinkSpan.innerHTML = ""
+
+ }
+
+ })
+
+
+
+ addBtn.addEventListener("click", () => {
+ info.clear()
+ console.log(ablink.checked)
+
+ if(!titleInput.value) {
+
+ info.err("Un titre est nécéssaire")
+
+ } else if(!urlInput.value) {
+
+ info.err("Une URL est nécéssaire")
+
+ } else {
+
+ var newlink = getID(`${View.getViewTitle()}_newlink`)
+
+ if(!newlink) {
+
+ newlink = { value: "" }
+
+
+ } else {
+
+ if(!newlink.value) {
+
+ info.err("Un nouveau lien est nécéssaire")
+ return false
+ }
+ }
+
+ if(!newlink.value.match(/^[a-zA-Z0-9-_]+$/)) {
+ info.err("L'URL n'est pas valide")
+ return false
+
+ }
+
+
+
+
+
+ const request = post(`LINKS_ADD`, {
+ title: titleInput.value,
+ url: urlInput.value,
+ abstractLink: ablink.checked,
+ dest: newlink.value
+ })
+
+ request.then((answer) => {
+
+ if(answer.answer == "OK") {
+
+ info.info("Le lien a bien été ajouté")
+ View.destroyPopup()
+ getLinks()
+
+
+ } else if(answer.answer == "ALREADY_EXISTS") {
+
+ info.err("Ce lien existe déjà")
+
+ } else {
+
+ info.err("Impossible d'ajouter le lien")
+
+ }
+
+ })
+
+ }
+
+ })
+
+ })
+
+ getLinks()
+
+ function getLinks() {
+
+
+ linksDiv.innerHTML = ""
+ links = new Array()
+
+ const request = post(`LINKS_GET_ALL`)
+ request.then((answer) => {
+
+ if(answer.answer == "OK") {
+
+ if(answer.links.length == 0) {
+
+ linksDiv.innerHTML = `
Aucun lien disponible
`
+ }
+
+ answer.links.forEach((link) => {
+
+ links.push(link)
+
+ })
+
+ links.forEach((link) => {
+
+ linksDiv.innerHTML += `
+
+
${link.title}
+
+
+
+
+
+
+ `
+
+
+
+ })
+
+ links.forEach((link) => {
+ const editBtn = getID(`${link.id}_edit`)
+
+ editBtn.addEventListener("click", () => {
+
+ View.createPopup({
+ title: `
Modifier un lien`,
+ content: `
+
+ `
+ })
+
+ const titleInput = getID(`${View.getViewTitle()}_edittitle`)
+ const urlInput = getID(`${View.getViewTitle()}_editurl`)
+ const editBtnConfirm = getID(`${View.getViewTitle()}_editconfirm`)
+ const info = new InfoPop(`${View.getViewTitle()}_editinfo`)
+
+ titleInput.value = link.title
+ urlInput.value = link.url
+
+ editBtnConfirm.addEventListener("click", () => {
+
+ if(!titleInput.value) {
+
+ info.err("Un titre est nécéssaire")
+
+ } else if(!urlInput.value) {
+
+ info.err("Une URL est nécéssaire")
+
+ } else {
+
+ const request = post(`LINKS_EDIT`, {
+ id: link.id,
+ title: titleInput.value,
+ url: urlInput.value
+ })
+
+ request.then((answer) => {
+
+ if(answer == "OK") {
+
+ info.info("Le lien a bien été modifié")
+ View.destroyPopup()
+ getLinks()
+
+
+ } else {
+
+ info.err("Impossible de modifier le lien")
+
+ }
+
+ })
+
+ }
+
+ })
+
+
+
+
+ })
+
+
+ const delBtn = getID(`${link.id}_remove`)
+ delBtn.addEventListener("click", () => {
+
+ const request = post(`LINKS_DELETE`, link.id)
+ request.then((answer) => {
+
+ if(answer != "OK") {
+
+ View.createPopup({
+ title: `
Erreur`,
+ content: `
+
Impossible de supprimer le lien
+ `
+ })
+
+
+ } else {
+
+ getLinks()
+ }
+
+ })
+
+ })
+ })
+
+ } else {
+
+ info.err("Impossible de récupérer les liens")
+
+ }
+
+
+
+ })
+ }
+
+
+}
\ No newline at end of file
diff --git a/public/javascripts/service.js b/public/javascripts/service.js
index 5dbe1d8..1263c38 100644
--- a/public/javascripts/service.js
+++ b/public/javascripts/service.js
@@ -23,7 +23,7 @@ async function generateServiceView() {
${this.name}
${this.description}
-
Etat :
+
Etat : Vérification en cours ...
diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css
index bb271e1..a6a74a9 100644
--- a/public/stylesheets/style.css
+++ b/public/stylesheets/style.css
@@ -593,10 +593,10 @@ a {
}
.fx-editor-content {
-
+ border: none;
+ border-top: 1px solid rgb(70, 67, 67);
background-color: transparent;
color: white;
- border: none;
padding: 15px;
height: 100%;
@@ -722,4 +722,74 @@ a {
display: flex;
flex-direction: column;
gap: 10px;
+}
+
+/* Links */
+
+.ln-bar {
+
+ display: flex;
+ justify-content: right;
+ padding: 10px;
+ gap: 10px;
+}
+
+.ln-create {
+
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.ln-abstract-label {
+
+ text-align: center;
+ font-size: 12px;
+}
+
+.ln-abstract-div {
+
+ display: flex;
+ flex-direction: row;
+ text-align: center;
+ align-items: center;
+ justify-content: center;
+}
+
+.ln-link-actions {
+
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: flex-end;
+
+}
+
+.ln-link {
+
+ display: grid;
+ grid-template-columns: 1fr 3fr 1fr;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px;
+ border-radius: 10px;
+ background-color: #1b1b1bc1;
+ transition: 0.1s;
+
+
+}
+
+.ln-links {
+
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 75%;
+ padding: 10px;
+ overflow-y: auto;
+}
+
+.ln-link-url {
+
+ font-size: 12px;
}
\ No newline at end of file
diff --git a/routes/link.js b/routes/link.js
new file mode 100644
index 0000000..69e32cc
--- /dev/null
+++ b/routes/link.js
@@ -0,0 +1,23 @@
+var express = require('express');
+var router = express.Router();
+var path = require("path")
+
+module.exports = router;
+
+
+module.exports.ApplyLinks = class {
+ constructor(links) {
+ // Remove all routes
+ router.stack = []
+
+ for(var link of links) {
+ const url = link.url
+ router.get("/" + link.dest, (req,res,next) => {
+ res.redirect(302, url)
+ })
+ }
+
+ module.exports = router;
+ }
+
+}
\ No newline at end of file
diff --git a/views/index.ejs b/views/index.ejs
index 3d84902..c733f4a 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -53,10 +53,10 @@
-
+