Browse Source

Fixes #2 Sidebar menu and search bar

isundil 1 year ago
parent
commit
b408cdf89e
6 changed files with 93 additions and 6 deletions
  1. 3 1
      app.ts
  2. 54 0
      public/javascripts/tree.js
  3. 14 2
      public/stylesheets/main.css
  4. 14 0
      src/LDAPTree.ts
  5. 1 1
      templates/tree.pug
  6. 7 2
      views/index.pug

+ 3 - 1
app.ts

@@ -1,3 +1,5 @@
+if (process.env.DEBUG_FULL !== undefined)
+    process.env.DEBUG = process.env.DEBUG || "*";
 import * as express from 'express';
 import { AddressInfo } from "net";
 import * as path from 'path';
@@ -33,7 +35,7 @@ app.use(bodyParser.urlencoded({ extended: true }));
 app.use((req, res, next) => {
     req.ldapManager = new LDAPFactory();
     req.session = Security.GetSession(req);
-    req.isUserLogged = Security.IsUserLogged(req);
+    req.isUserLogged = Security.IsUserLogged(req) || process.env.DEBUG_FULL !== undefined;
     res.socket && res.socket.once('close', () => {
         req.ldapManager.Release();
     });

+ 54 - 0
public/javascripts/tree.js

@@ -27,3 +27,57 @@ window["makeTree"] = function (ulRoot) {
 	for (var i = 0; i < ulRoot.children.length; ++i)
 		makeTree(ulRoot.children[i]);
 }
+
+$(() => {
+    var FILTER = "";
+
+    function treeChildren(root) {
+        let result = [];
+        if (root.classList.contains("treeroot"))
+            return root.children;
+        for (var i of root.children)
+            if (i.classList.contains("treebranch"))
+                for (var j of i.children)
+                    if (j.classList.contains("treeitem"))
+                        result.push(j);
+        return result;
+    }
+
+    function updateUiFilter(filterText, treeNode) {
+        if (isFiltered(filterText, treeNode)) {
+            treeNode.classList.add("hidden");
+        } else {
+            setChildVisibility(treeNode);
+            if ((treeNode.dataset?.fullname?.toLowerCase() || "").indexOf(filterText) >= 0)
+                return;
+            for (var treeBranch of treeChildren(treeNode))
+                updateUiFilter(filterText, treeBranch);
+        }
+    }
+
+    function setChildVisibility(treeNode) {
+        treeNode.classList.remove("hidden");
+        for (var i of treeNode.querySelectorAll(".treeitem.hidden"))
+            i.classList.remove("hidden");
+    }
+
+    function isFiltered(filterText, node) {
+        return node.textContent.toLowerCase().indexOf(filterText) < 0;
+    }
+
+    function filterUpdated() {
+        updateUiFilter(FILTER.toLowerCase(), document.querySelector(".treeroot"));
+    }
+
+    const searchInput = document.getElementById("searchinput");
+
+    function onSearchInputChanged() {
+        if (FILTER === searchInput.value)
+            return;
+        FILTER = searchInput.value;
+        filterUpdated();
+    }
+    searchInput.addEventListener('input', onSearchInputChanged);
+    onSearchInputChanged();
+});
+

+ 14 - 2
public/stylesheets/main.css

@@ -43,8 +43,17 @@ a {
     overflow: auto;
     resize: horizontal;
 }
+#menuBar .nav {
+    background: #edf6fb;
+}
+#menuBar .nav-item.input-group-wrapper {
+    flex: 1;
+    width: initial;
+    max-width: 350px;
+    margin: 5px;
+}
 #menuBar > div {
-    margin: 2em;
+    margin: 1em 2em;
 }
 .treeroot {
     padding: 0;
@@ -57,6 +66,9 @@ a {
     font-weight: bold !important;
     padding-right: 5px;
 }
+.treeroot .hidden {
+    display: none !important;
+}
 iframe#page {
     display: inline-flex;
     flex: 1;
@@ -152,7 +164,7 @@ label.LDAPAttribute .editlink {
 label.LDAPAttribute .editlink a {
     flex: 1;
     margin: 3px;
-    background: rgba(255, 255, 255, 0.2);
+    background: rgba(var(--bs-secondary-bg), 0.5);
     backdrop-filter: blur(2px);
     padding-left: .375rem;
 }

+ 14 - 0
src/LDAPTree.ts

@@ -61,6 +61,20 @@ export default class LDAPTree {
 		return result;
 	}
 
+    public GetChildrenSorted(): Array<LDAPTree> {
+        let result = [...this.GetChildren()];
+        result.sort((a, b) => {
+            const aChild = a.HasChildren();
+            const bChild = b.HasChildren();
+            if (aChild && !bChild)
+                return -1;
+            if (!aChild && bChild)
+                return 1;
+            return a.GetName().localeCompare(b.GetName());
+        });
+        return result;
+    }
+
 	public HasChildren(): boolean {
 		return this.fChildren.size > 0;
 	}

+ 1 - 1
templates/tree.pug

@@ -4,7 +4,7 @@ mixin tree(item)
     if item.HasChildren()
       span(data-name=item.GetName())=item.GetName()
       ul(class="treebranch")
-        for i in item.GetChildren()
+        for i in item.GetChildrenSorted()
           +tree(i)
     else
       a(href="entity/"+DnToLnk(item.FullName()),target="page")=item.GetName()

+ 7 - 2
views/index.pug

@@ -9,8 +9,13 @@ block append scripts
 block content
   div(class='page-index')
     div(id="menuBar")
+      ul(class="nav justify-content-center sticky-top")
+        li(class="nav-item input-group-wrapper")
+          div(class="input-group")
+            span(class="input-group-text bi bi-search")
+            input(type="text" class="form-control" id="searchinput")
+        li(class="nav-item ms-auto d-flex align-items-center")
+          a(href="/logout" class="nav-link bi bi-box-arrow-right")
       div
         +treeroot(tree)
-      a(href="/logout")
-        p Logout
     iframe(id="page",name="page",src="home")