Browse Source

Added buttons to the navbar. some file cleanup.

lllllllillllllillll 1 year ago
parent
commit
4e46052770

+ 19 - 0
controllers/account.js

@@ -14,6 +14,16 @@ export const Account = async (req, res) => {
             role: 'admin',
             avatar: 'L',
             alert: '',
+            link1: '',
+            link2: '',
+            link3: '',
+            link4: '',
+            link5: '',
+            link6: '',
+            link7: '',
+            link8: '',
+            link9: '',
+
         });
         return;
     }
@@ -29,6 +39,15 @@ export const Account = async (req, res) => {
         role: user.role,
         avatar: req.session.user.charAt(0).toUpperCase(),
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 

+ 20 - 2
controllers/apps.js

@@ -135,7 +135,16 @@ export const Apps = async (req, res) => {
     template_list: '',
     json_templates: json_templates,
     pages: pages,
-    remove_button: remove_button
+    remove_button: remove_button,
+    link1: '',
+    link2: '',
+    link3: '',
+    link4: '',
+    link5: '',
+    link6: '',
+    link7: '',
+    link8: '',
+    link9: '',
   });
   alert = '';
 }
@@ -243,7 +252,16 @@ export const appSearch = async (req, res) => {
       template_list: '',
       json_templates: json_templates,
       pages: pages,
-      remove_button: remove_button
+      remove_button: remove_button,
+      link1: '',
+      link2: '',
+      link3: '',
+      link4: '',
+      link5: '',
+      link6: '',
+      link7: '',
+      link8: '',
+      link9: '',
   });
 }
 

+ 36 - 6
controllers/dashboard.js

@@ -5,23 +5,54 @@ import { readFileSync } from 'fs';
 import { currentLoad, mem, networkStats, fsSize, dockerContainerStats } from 'systeminformation';
 import { Op } from 'sequelize';
 
-let hidden = '';
-let alert = '';
-let [ cardList, newCards, stats ] = [ '', '', {}];
-let [ports_data, volumes_data, env_data, label_data] = [[], [], [], []];
+let [ hidden, alert, newCards, stats ] = [ '', '', '', {} ];
 
 // The page
-export const Dashboard = (req, res) => {
+export const Dashboard = async (req, res) => {
 
     let name = req.session.user ;
     let role = req.session.role;
     alert = req.session.alert;
+
+    let link1 = `<a href="#" class="btn text-green">
+                    Host 1
+                </a>`
+
+    async function hostInfo(host) {
+        let info = await ServerSettings.findOne({ where: {key: host}});
+        try {
+            if (info.value != 'off' && info.value != '') {
+                let values = info.value.split(',');
+                return { tag: values[0], ip: values[1], port: values[2] };
+            }
+        } catch {
+            console.log(`${host}: No Value Set`);
+        }
+    }
+
+    let link2 = '';
+    let host2 = await hostInfo('host2');
+    if (host2) {
+        link2 = `<button class="btn text-green" hx-post="/dashboard/host2" hx-trigger="mousedown" hx-swap="none">
+                    ${host2.tag}
+                </button>`
+    }
+    
     
     res.render("dashboard", {
         name: name,
         avatar: name.charAt(0).toUpperCase(),
         role: role,
         alert: alert,
+        link1: '',
+        link2: link2,
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 }
 
@@ -31,7 +62,6 @@ export const DashboardAction = async (req, res) => {
     let value = req.header('hx-trigger');
     let action = req.params.action;
     let modal = '';
-    let hostip = req.connection.remoteAddress;
 
     switch (action) {
         case 'permissions':

+ 9 - 0
controllers/images.js

@@ -107,6 +107,15 @@ export const Images = async function(req, res) {
         image_list: image_list,
         image_count: images.length,
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 }

+ 9 - 0
controllers/networks.js

@@ -54,6 +54,15 @@ export const Networks = async function(req, res) {
         network_list: network_list,
         network_count: networks.length,
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 }
 

+ 0 - 389
controllers/portal.js

@@ -1,389 +0,0 @@
-import { Readable } from 'stream';
-import { Permission, Container, User } from '../database/models.js';
-import { docker } from '../server.js';
-import { readFileSync } from 'fs';
-
-let hidden = '';
-
-// The actual page
-export const Portal = (req, res) => {
-    let name = req.session.user;
-    let role = req.session.role;
-    let avatar = name.charAt(0).toUpperCase();
-
-    res.render("portal", {
-        name: name,
-        avatar: avatar,
-        role: role,
-        alert: '',
-    });
-}
-
-
-async function CardList () {
-    let name = req.session.user;
-    let containers = await Permission.findAll({ attributes: ['containerName'], where: { user: name }});
-    for (let i = 0; i < containers.length; i++) {
-        let details = await containerInfo(containers[i].containerName);
-        let card = await createCard(details);
-        cardList += card;
-    }
-}
-
-export const UserContainers = async (req, res) => {
-    let cardList = '';
-    let name = req.session.user;
-    let containers = await Permission.findAll({ attributes: ['containerName'], where: { user: name }});
-
-    for (let i = 0; i < containers.length; i++) {
-        if (containers[i].containerName == null) { continue; }
-        let details = await containerInfo(containers[i].containerName);
-        let card = await createCard(details);
-        cardList += card;
-    }
-    res.send(cardList);
-}
-
-
-
-async function containerInfo (containerName) {
-    let container = docker.getContainer(containerName);
-    let info = await container.inspect();
-    let image = info.Config.Image.split('/');
-    let ports_list = [];
-    try {
-        for (const [key, value] of Object.entries(info.HostConfig.PortBindings)) {
-            let ports = {
-                check: 'checked',
-                external: value[0].HostPort,
-                internal: key.split('/')[0],
-                protocol: key.split('/')[1]
-            }
-            ports_list.push(ports);
-        }
-    } catch {
-        // no exposed ports
-    }
-
-    let external = 0;
-    let internal = 0;
-    try {
-        external = ports_list[0].external;
-        internal = ports_list[0].internal;
-    }   catch {
-        // no exposed ports
-    }
-    
-
-    let details = {
-        name: containerName,
-        image: image,
-        service: image[image.length - 1].split(':')[0],
-        state: info.State.Status,
-        external_port: external,
-        internal_port: internal,
-        ports: ports_list,
-        link: 'localhost',
-    }
-    return details;
-}
-
-async function createCard (details) {
-    if (hidden.includes(details.name)) { return;}
-    let shortname = details.name.slice(0, 10) + '...';
-    let trigger = 'data-hx-trigger="load, every 3s"';
-    let state = details.state;
-    let state_color = '';
-    switch (state) {
-        case 'running':
-            state_color = 'green';
-            break;
-        case 'exited':
-            state = 'stopped';
-            state_color = 'red';
-            trigger = 'data-hx-trigger="load"';
-            break;
-        case 'paused':
-            state_color = 'orange';
-            trigger = 'data-hx-trigger="load"';
-            break;
-        case 'installing':
-            state_color = 'blue';
-            trigger = 'data-hx-trigger="load"';
-            break;
-    }
-    // if (name.startsWith('dweebui')) { disable = 'disabled=""'; }
-    let card  = readFileSync('./views/partials/containerSimple.html', 'utf8');
-    card = card.replace(/AppName/g, details.name);
-    card = card.replace(/AppShortName/g, shortname);
-    card = card.replace(/AppIcon/g, details.service);
-    card = card.replace(/AppState/g, state);
-    card = card.replace(/StateColor/g, state_color);
-    card = card.replace(/ExternalPort/g, details.external_port);
-    card = card.replace(/InternalPort/g, details.internal_port);
-    card = card.replace(/ChartName/g, details.name.replace(/-/g, ''));
-    card = card.replace(/AppNameState/g, `${details.name}State`);
-    card = card.replace(/data-trigger=""/, trigger);
-    return card;
-}
-
-
-let [ cardList, newCards, containersArray, sentArray, updatesArray ] = [ '', '', [], [], [] ];
-
-export async function addCard (name, state) {
-    console.log(`Adding card for ${name}: ${state}`);
-
-    let details = {
-        name: name,
-        image: name,
-        service: name,
-        state: 'installing',
-        external_port: 0,
-        internal_port: 0,
-        ports: [],
-        link: 'localhost',
-    
-    }
-    createCard(details).then(card => {
-        cardList += card;
-    });
-}
-
-
-
-
-// HTMX server-side events
-export const SSE = async (req, res) => {
-    res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
-
-    let eventCheck = setInterval(async () => {
-        // builds array of containers and their states
-        containersArray = [];
-        await docker.listContainers({ all: true }).then(containers => {
-            containers.forEach(container => {
-                let name = container.Names[0].replace('/', '');
-                if (!hidden.includes(name)) { // if not hidden
-                    containersArray.push({ container: name, state: container.State });
-                } 
-            });
-        });
-
-        if ((JSON.stringify(containersArray) !== JSON.stringify(sentArray))) {
-            cardList = '';
-            newCards = '';
-            containersArray.forEach(container => {
-                const { container: containerName, state } = container;
-                const existingContainer = sentArray.find(c => c.container === containerName);
-                if (!existingContainer) {
-                    containerInfo(containerName).then(details => {
-                        createCard(details).then(card => {
-                            newCards += card;
-                        });
-                    });
-                    res.write(`event: update\n`);
-                    res.write(`data: 'update cards'\n\n`);
-                } else if (existingContainer.state !== state) {
-                    updatesArray.push(containerName);
-                }
-                containerInfo(containerName).then(details => {
-                    createCard(details).then(card => {
-                        cardList += card;
-                    });
-                });
-            });
-
-            sentArray.forEach(container => {
-                const { container: containerName } = container;
-                const existingContainer = containersArray.find(c => c.container === containerName);
-                if (!existingContainer) {
-                    updatesArray.push(containerName);
-                }
-            });
-
-            for (let i = 0; i < updatesArray.length; i++) {
-                res.write(`event: ${updatesArray[i]}\n`);
-                res.write(`data: 'update cards'\n\n`);
-            }
-            updatesArray = [];
-            sentArray = containersArray.slice();
-        }
-
-    }, 500);
-
-
-    req.on('close', () => {
-        clearInterval(eventCheck);
-    });
-};
-
-
-export const updateCards = async (req, res) => {
-    console.log('updateCards called');
-    res.send(newCards);
-    newCards = '';
-}
-
-
-export const Containers = async (req, res) => {
-    CardList();
-    // res.send(cardList);
-}
-
-export const Card = async (req, res) => {
-    let name = req.header('hx-trigger-name');
-    console.log(`${name} requesting updated card`);
-    // return nothing if in hidden or not found in containersArray
-    if (hidden.includes(name) || !containersArray.find(c => c.container === name)) {
-        res.send('');
-        return;
-    } else {
-        let details = await containerInfo(name);
-        let card = await createCard(details);
-        res.send(card);
-    }
-}
-
-
-function status (state) {
-    let status = `<span class="text-yellow align-items-center lh-1">
-                    <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-point-filled" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 7a5 5 0 1 1 -4.995 5.217l-.005 -.217l.005 -.217a5 5 0 0 1 4.995 -4.783z" stroke-width="0" fill="currentColor"></path></svg>
-                    ${state}
-                </span>`;
-    return status;
-}
-
-
-export const Logs = (req, res) => {
-    let name = req.header('hx-trigger-name');
-    function containerLogs (data) {
-        return new Promise((resolve, reject) => {
-            let logString = '';
-            var options = { follow: false, stdout: true, stderr: false, timestamps: false };
-            var containerName = docker.getContainer(data);
-            containerName.logs(options, function (err, stream) {
-                if (err) { reject(err); return; }
-                const readableStream = Readable.from(stream);
-                readableStream.on('data', function (chunk) {
-                    logString += chunk.toString('utf8');
-                });
-                readableStream.on('end', function () {
-                    resolve(logString);
-                });
-            });
-        });
-    };
-    containerLogs(name).then((data) => {
-        res.send(`<pre>${data}</pre> `)
-    });
-}
-
-export const Action = async (req, res) => {
-    let name = req.header('hx-trigger-name');
-    let state = req.header('hx-trigger');
-    let action = req.params.action;
-    // Start
-    if ((action == 'start') && (state == 'stopped')) {
-        var containerName = docker.getContainer(name);
-        containerName.start();
-        res.send(status('starting'));
-    } else if ((action == 'start') && (state == 'paused')) {
-        var containerName = docker.getContainer(name);
-        containerName.unpause();
-        res.send(status('starting'));
-    // Stop
-    } else if ((action == 'stop') && (state != 'stopped')) {
-        var containerName = docker.getContainer(name);
-        containerName.stop();
-        res.send(status('stopping'));
-    // Pause
-    } else if ((action == 'pause') && (state == 'paused')) {
-        var containerName = docker.getContainer(name);
-        containerName.unpause();
-        res.send(status('starting'));
-    }   else if ((action == 'pause') && (state == 'running')) {
-        var containerName = docker.getContainer(name);
-        containerName.pause();
-        res.send(status('pausing'));
-    // Restart
-    } else if (action == 'restart') {
-        var containerName = docker.getContainer(name);
-        containerName.restart();
-        res.send(status('restarting'));
-    // Hide
-    } else if (action == 'hide') {
-        let exists = await Container.findOne({ where: {name: name}});
-        if (!exists) {
-            const newContainer = await Container.create({ name: name, visibility: false, });
-        } else {
-            exists.update({ visibility: false });
-        }
-        hidden = await Container.findAll({ where: {visibility:false}});
-        hidden = hidden.map((container) => container.name);
-        res.send("ok");
-    // Reset View
-    } else if (action == 'reset') {
-        await Container.update({ visibility: true }, { where: {} });
-        hidden = await Container.findAll({ where: {visibility:false}});
-        hidden = hidden.map((container) => container.name);
-        res.send("ok");
-    }   
-}
-
-
-export const Modals = async (req, res) => {
-    let name = req.header('hx-trigger-name');
-    let id = req.header('hx-trigger');
-    let title = name.charAt(0).toUpperCase() + name.slice(1);
-
-    if (id == 'permissions') {
-        let permissions_list = '';
-        let permissions_modal = readFileSync('./views/modals/permissions.html', 'utf8');
-        permissions_modal = permissions_modal.replace(/PermissionsTitle/g, title);
-        let users = await User.findAll({ attributes: ['username', 'UUID']});
-
-        for (let i = 0; i < users.length; i++) {
-            let user_permissions = readFileSync('./views/partials/user_permissions.html', 'utf8');
-            let exists = await Permission.findOne({ where: {containerName: name, user: users[i].username}});
-            if (!exists) {
-                const newPermission = await Permission.create({ containerName: name, user: users[i].username, userID: users[i].UUID});
-            }
-            
-            let permissions = await Permission.findOne({ where: {containerName: name, user: users[i].username}});
-            if (permissions.uninstall == true) { user_permissions = user_permissions.replace(/data-UninstallCheck/g, 'checked'); }
-            if (permissions.edit == true) { user_permissions = user_permissions.replace(/data-EditCheck/g, 'checked'); }
-            if (permissions.upgrade == true) { user_permissions = user_permissions.replace(/data-UpgradeCheck/g, 'checked'); }
-            if (permissions.start == true) { user_permissions = user_permissions.replace(/data-StartCheck/g, 'checked'); }
-            if (permissions.stop == true) { user_permissions = user_permissions.replace(/data-StopCheck/g, 'checked'); }
-            if (permissions.pause == true) { user_permissions = user_permissions.replace(/data-PauseCheck/g, 'checked'); }
-            if (permissions.restart == true) { user_permissions = user_permissions.replace(/data-RestartCheck/g, 'checked'); }
-            if (permissions.logs == true) { user_permissions = user_permissions.replace(/data-LogsCheck/g, 'checked'); }
-
-            user_permissions = user_permissions.replace(/EntryNumber/g, i);
-            user_permissions = user_permissions.replace(/PermissionsUsername/g, users[i].username);
-            user_permissions = user_permissions.replace(/PermissionsContainer/g, name);
-
-            permissions_list += user_permissions;
-        }
-
-        permissions_modal = permissions_modal.replace(/PermissionsList/g, permissions_list);
-        res.send(permissions_modal);
-        return;
-    }
-
-
-
-    if (id == 'uninstall') {
-        let modal = readFileSync('./views/modals/uninstall.html', 'utf8');
-        modal = modal.replace(/AppName/g, name);
-        // let containerPermissions = await Permission.findAll({ where: {containerName: name}});
-        res.send(modal);
-        return;
-    }
-
-    let modal = readFileSync('./views/modals/details.html', 'utf8');
-    let details = await containerInfo(name);
-
-    modal = modal.replace(/AppName/g, details.name);
-    modal = modal.replace(/AppImage/g, details.image);
-    res.send(modal);
-}

+ 9 - 0
controllers/settings.js

@@ -69,6 +69,15 @@ export const Settings = async (req, res) => {
         avatar: req.session.user.charAt(0).toUpperCase(),
         alert: '',
         settings: settings,
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 }
 

+ 9 - 0
controllers/supporters.js

@@ -14,6 +14,15 @@ export const Supporters = async (req, res) => {
         role: user.role,
         avatar: req.session.user.charAt(0).toUpperCase(),
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 

+ 9 - 0
controllers/syslogs.js

@@ -32,6 +32,15 @@ export const Syslogs = async function(req, res) {
         avatar: req.session.user.charAt(0).toUpperCase(),
         logs: logs,
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 }

+ 10 - 1
controllers/users.js

@@ -56,7 +56,16 @@ export const Users = async (req, res) => {
         role: req.session.role,
         avatar: req.session.user.charAt(0).toUpperCase(),
         user_list: user_list,
-        alert: ''
+        alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 }

+ 0 - 9
controllers/variables.js

@@ -1,9 +0,0 @@
-
-export const Variables = (req, res) => {
-
-    res.render("variables", {
-        name: req.session.user,
-        role: req.session.role,
-        avatar: req.session.avatar,
-    });
-}

+ 9 - 0
controllers/volumes.js

@@ -73,6 +73,15 @@ export const Volumes = async function(req, res) {
         volume_list: volume_list,
         volume_count: volumes.length,
         alert: '',
+        link1: '',
+        link2: '',
+        link3: '',
+        link4: '',
+        link5: '',
+        link6: '',
+        link7: '',
+        link8: '',
+        link9: '',
     });
 
 }

+ 0 - 3
router/index.js

@@ -12,7 +12,6 @@ import { Images } from "../controllers/images.js";
 import { Networks, removeNetwork } from "../controllers/networks.js";
 import { Volumes, addVolume, removeVolume } from "../controllers/volumes.js";
 import { Account } from "../controllers/account.js";
-import { Variables } from "../controllers/variables.js";
 import { Settings, updateSettings } from "../controllers/settings.js";
 import { Supporters, Thanks } from "../controllers/supporters.js";
 import { Syslogs } from "../controllers/syslogs.js";
@@ -96,8 +95,6 @@ router.post("/upload", adminOnly, Upload);
 router.get("/users", adminOnly, Users);
 router.get("/syslogs", adminOnly, Syslogs);
 
-router.get("/variables", adminOnly, Variables);
-
 router.get("/settings", adminOnly, Settings);
 router.post("/settings", adminOnly, updateSettings);
 

+ 1 - 3
views/partials/containerFull.html

@@ -6,8 +6,7 @@
         </div>
         <div class="d-flex align-items-center">
           <div class="subheader text-yellow">ExternalPort:InternalPort</div>
-          <div class="ms-auto lh-1">
-            <div class="card-actions btn-actions">
+            <div class="ms-auto lh-1">
               <div class="card-actions btn-actions">
                 <button class="btn-action" title="Start" data-hx-post="/dashboard/start" data-hx-trigger="mousedown" data-hx-target="#AppNameState" name="AppName" id="AppState" ${disable}>
                   <svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-play" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 4v16l13 -8z"></path></svg>
@@ -41,7 +40,6 @@
                     <button class="dropdown-item text-secondary" data-hx-post="/dashboard/hide" data-hx-trigger="mousedown" data-hx-swap="none" name="AppName" id="hide" value="hide">Hide</button>
                     <button class="dropdown-item text-secondary" data-hx-post="/dashboard/permissions" name="AppName" data-hx-target="#modals-here" hx-swap="innerHTML" data-hx-trigger="mousedown" data-bs-toggle="modal" data-bs-target="#modals-here">Permissions</button>
                   </div>
-                </div>
               </div>
             </div>
           </div>

+ 47 - 14
views/partials/navbar.html

@@ -48,18 +48,47 @@
 
     <div class="navbar-nav flex-row order-md-last">
       <div class="nav-item d-none d-md-flex me-3">
-        <!-- 
+        
         
         <div class="btn-list">
-          <a href="#" class="btn text-blue">
-            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-screen-share" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M21 12v3a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1h9"></path> <path d="M7 20l10 0"></path> <path d="M9 16l0 4"></path> <path d="M15 16l0 4"></path> <path d="M17 4h4v4"></path> <path d="M16 9l5 -5"></path> </svg>
-            Host 1
-          </a>
-          <a href="#" class="btn text-blue">
-            <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-screen-share" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M21 12v3a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1h9"></path> <path d="M7 20l10 0"></path> <path d="M9 16l0 4"></path> <path d="M15 16l0 4"></path> <path d="M17 4h4v4"></path> <path d="M16 9l5 -5"></path> </svg>
-            Host 2
-          </a>
-          <a href="#" class="btn text-green">
+
+          <% if(link1) { %>
+            <%- link1 %>
+          <% } %>
+
+          <% if(link2) { %>
+            <%- link2 %>
+          <% } %>
+
+          <% if(link3) { %>
+            <%- link3 %>
+          <% } %>
+
+          <% if(link4) { %>
+            <%- link4 %>
+          <% } %>
+
+          <% if(link5) { %>
+            <%- link5 %>
+          <% } %>
+          
+          <% if(link6) { %>
+            <%- link6 %>
+          <% } %>
+
+          <% if(link7) { %>
+            <%- link7 %>
+          <% } %>
+
+          <% if(link8) { %>
+            <%- link8 %>
+          <% } %>
+
+          <% if(link9) { %>
+            <%- link9 %>
+          <% } %>
+
+          <!-- <a href="#" class="btn text-green">
             <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-lock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z"></path> <path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path> <path d="M8 11v-4a4 4 0 1 1 8 0v4"></path> </svg>
             VPN
           </a>
@@ -70,10 +99,11 @@
           <a href="#" class="btn text-green">
             <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-screen-share" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M21 12v3a1 1 0 0 1 -1 1h-16a1 1 0 0 1 -1 -1v-10a1 1 0 0 1 1 -1h9"></path> <path d="M7 20l10 0"></path> <path d="M9 16l0 4"></path> <path d="M15 16l0 4"></path> <path d="M17 4h4v4"></path> <path d="M16 9l5 -5"></path> </svg>
             VNC
-          </a>
+          </a> -->
+
         </div> 
         
-        -->
+       
 
         <!-- 
         
@@ -278,10 +308,13 @@
         <div class="my-2 my-md-0 flex-grow-1 flex-md-grow-0 order-first order-md-last">
 
           <div class="card-actions btn-actions">
-            <button class="btn-action" title="Grid View" data-hx-post="/dashboard/view" data-hx-trigger="mousedown" data-hx-target="#" name="grid" id="AppState">
+
+            <!-- <input type="text" class="form-control mx-2" placeholder="Search..." aria-label="search" name="search"> -->
+
+            <button class="btn-action mx-1" title="Grid View" data-hx-post="/dashboard/view" data-hx-trigger="mousedown" data-hx-target="#" name="grid" id="AppState">
               <svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="1.5"  stroke-linecap="round"  stroke-linejoin="round"  class="icon-tabler icons-tabler-outline icon-tabler-layout-grid"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M4 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z" /><path d="M14 4m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z" /><path d="M4 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z" /><path d="M14 14m0 1a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v4a1 1 0 0 1 -1 1h-4a1 1 0 0 1 -1 -1z" /></svg>
             </button>
-            <button class="btn-action" title="List View" data-hx-post="/dashboard/view" data-hx-trigger="mousedown" data-hx-target="#" name="list" id="AppState">
+            <button class="btn-action mx-1" title="List View" data-hx-post="/dashboard/view" data-hx-trigger="mousedown" data-hx-target="#" name="list" id="AppState">
               <svg  xmlns="http://www.w3.org/2000/svg"  width="24"  height="24"  viewBox="0 0 24 24"  fill="none"  stroke="currentColor"  stroke-width="1.5"  stroke-linecap="round"  stroke-linejoin="round"  class="icon-tabler icons-tabler-outline icon-tabler-layout-grid"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 6l11 0" /><path d="M9 12l11 0" /><path d="M9 18l11 0" /><path d="M5 6l0 .01" /><path d="M5 12l0 .01" /><path d="M5 18l0 .01" /></svg>
             </button>
             <div class="dropdown">

+ 0 - 120
views/variables.html

@@ -1,120 +0,0 @@
-	<!doctype html>
-	<html lang="en">
-	<head>
-		<meta charset="utf-8"/>
-		<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
-		<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
-		<title>DweebUI - Settings</title>
-		<!-- CSS files -->
-		<link href="/css/tabler.min.css" rel="stylesheet"/>
-		<link href="/css/demo.min.css" rel="stylesheet"/>
-		<style>
-			@import url('/fonts/inter.css');
-			:root {
-			  --tblr-font-sans-serif: 'Inter Var', -apple-system, BlinkMacSystemFont, San Francisco, Segoe UI, Roboto, Helvetica Neue, sans-serif;
-			}
-			body {
-			  font-feature-settings: "cv03", "cv04", "cv11";
-			}
-		  </style>
-	</head>
-	<body >
-		<div class="page">
-		<!-- Navbar -->
-		<%- include('partials/navbar.html') %>
-		<div class="page-wrapper">
-			<!-- Page header -->
-			<div class="page-header d-print-none">
-			<div class="container-xl">
-				<div class="row g-2 align-items-center">
-				<div class="col">
-					<h2 class="page-title">
-					Settings
-					</h2>
-				</div>
-				</div>
-			</div>
-			</div>
-			<!-- Page body -->
-			<div class="page-body">
-				<div class="container-xl">
-				  <div class="card">
-					<div class="row g-0">
-						<%- include('partials/sidebar.html') %>
-					  	<div class="col d-flex flex-column">
-					  
-							<div class="card-body">
-								<h2 class="mb-2">Variables</h2>
-								<p class="text-muted mb-4">Configure default variables below.</p>
-								
-								<!-- <div class="row align-items-center">
-									<div class="col">								
-									</div>
-								</div> -->
-								
-								<div class="row mt-4">
-									<div class="col-md">
-									<div class="form-label">Match 1</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Match 2</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Default</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-								</div>
-
-
-								<div class="row mt-4">
-									<div class="col-md">
-									<div class="form-label">Match 1</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Match 2</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Default</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-								</div>
-
-
-								<div class="row mt-4">
-									<div class="col-md">
-									<div class="form-label">Match 1</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Match 2</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-									<div class="col-md">
-									<div class="form-label">Default</div>
-									<input type="text" class="form-control" value="" readonly="">
-									</div>
-								</div>
-								
-
-							</div>
-	  
-					  	</div>
-					  
-					</div>
-				  </div>
-				</div>
-			  </div>
-
-			<%- include('partials/footer.html') %>
-		</div>
-		</div>
-		<!-- Libs JS -->
-		<!-- Tabler Core -->
-		<script src="/js/tabler.min.js" defer></script>
-		<script src="/js/demo.min.js" defer></script>
-	</body>
-	</html>