diff --git a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/base/page.html.j2 b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/base/page.html.j2 index fd54b7d..1a06ee6 100644 --- a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/base/page.html.j2 +++ b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/base/page.html.j2 @@ -14,7 +14,7 @@ {% if breadcrumbs %} {% for label, url in breadcrumbs %} - + {% if url %} {{label}} {% else %} diff --git a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/clients/index.html.j2 b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/clients/index.html.j2 index 1342079..a1ecdac 100644 --- a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/clients/index.html.j2 +++ b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/clients/index.html.j2 @@ -11,9 +11,8 @@

Click an item to view details

-{% endblock %} - {% include '/clients/partials/drawer_create.html.j2' %} +{% endblock %} {% block local_scripts %} {% endblock %} + + diff --git a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/secrets/partials/tree_event.js b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/secrets/partials/tree_event.js index f0b3a29..9aa54a5 100644 --- a/packages/sshecret-admin/src/sshecret_admin/frontend/templates/secrets/partials/tree_event.js +++ b/packages/sshecret-admin/src/sshecret_admin/frontend/templates/secrets/partials/tree_event.js @@ -1,4 +1,61 @@ -document.addEventListener("DOMContentLoaded", () => { +function createCrumb(name, url = null) { + // Create a breadcrumb + const crumb = document.createElement("sl-breadcrumb-item"); + crumb.classList.add("page-breadcrumb"); + + if (url) { + var crumbChild = document.createElement("a"); + crumbChild.setAttribute("href", url); + const crumbChildText = document.createTextNode(name); + crumbChild.appendChild(crumbChildText); + } else { + var crumbChild = document.createTextNode(name); + } + + crumb.appendChild(crumbChild); + + return crumb; +} + +function setGroupBreadcrumbs(name, path, secret = null) { + // Set breadcrumbs for a whole group. + const breadcrumbs = document.getElementById("breadcrumbs"); + // First, remove all existing page breadcrumbs + console.log(`setGroupBreadcrumbs: ${name} ${path}`); + let pageCrumbs = document.getElementsByClassName("page-breadcrumb"); + for (let i = 0; i < pageCrumbs.length; i++) { + breadcrumbs.removeChild(pageCrumbs[i]); + } + // Re-create the breadcrumbs + const newcrumbs = [ + ["Secrets", "/secrets/"], + ["Groups", "/secrets/groups/"], + ]; + if (path) { + const pathnodes = path.split("/"); + for (let i = 0; i < pathnodes.length; i++) { + let pathnode = pathnodes[i]; + let nextnode = i + 1; + let groupPathNodes = pathnodes.slice(0, nextnode); + let groupPath = groupPathNodes.join("/"); + newcrumbs.push([pathnode, `/secrets/groups/${groupPath}`]); + } + } else { + newcrumbs.push(["Ungrouped", "/secrets/groups/"]); + } + + if (secret) { + newcrumbs.push([secret, `/secrets/secret/${secret}`]); + } + + for (let i = 0; i < newcrumbs.length; i++) { + let crumbParam = newcrumbs[i]; + let newcrumb = createCrumb(crumbParam[0], crumbParam[1]); + breadcrumbs.appendChild(newcrumb); + } +} + +function addTreeListener() { const tree = document.querySelector("sl-tree"); if (!tree) return; @@ -33,4 +90,12 @@ document.addEventListener("DOMContentLoaded", () => { }); } }); +} + +document.addEventListener("DOMContentLoaded", () => { + addTreeListener(); +}); + +document.addEventListener("htmx:afterSwap", () => { + addTreeListener(); }); diff --git a/packages/sshecret-admin/src/sshecret_admin/frontend/views/secrets.py b/packages/sshecret-admin/src/sshecret_admin/frontend/views/secrets.py index 57592da..af924ab 100644 --- a/packages/sshecret-admin/src/sshecret_admin/frontend/views/secrets.py +++ b/packages/sshecret-admin/src/sshecret_admin/frontend/views/secrets.py @@ -63,12 +63,14 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter: admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)], current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)], ): + breadcrumbs = [("secrets", "/secrets/")] groups = await admin.get_secret_groups() return templates.TemplateResponse( request, "secrets/index.html.j2", { "groups": groups, + "breadcrumbs": breadcrumbs, "user": current_user, "selected_group": None, "group_path_nodes": ["/"], @@ -83,8 +85,15 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter: ): """Show the root path.""" clients = await admin.get_clients() + + breadcrumbs = [ + ("secrets", "/secrets/"), + ("groups", "/secrets/groups/"), + ("Ungrouped", "/secrets/groups/"), + ] context: dict[str, Any] = { "clients": clients, + "breadcrumbs": breadcrumbs, "root_group_page": True, } headers: dict[str, str] = {} @@ -119,11 +128,20 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter: ) clients = await admin.get_clients() + breadcrumbs = [("secrets", "/secrets/"), ("groups", "/secrets/groups/")] + path_nodes = group.path.split("/") + for x in range(len(path_nodes)): + next_node = x + 1 + group_path = "/".join(path_nodes[:next_node]) + crumb_path = os.path.join("/secrets", group_path) + breadcrumbs.append((path_nodes[x], crumb_path)) + headers: dict[str, str] = {} context: dict[str, Any] = { "group_page": True, "group": group, "clients": clients, + "breadcrumbs": breadcrumbs, } if request.headers.get("HX-Request"): # This is a HTMX request.