Compare commits

..

8 Commits

Author SHA1 Message Date
2b50c686d0 Add heading back 2025-06-19 07:23:26 +02:00
57e69390b2 Fix dark-mode 2025-06-19 07:21:36 +02:00
23d354bc12 Clean up style elements 2025-06-19 06:43:36 +02:00
cad9849019 Update audit and change-password page 2025-06-19 06:23:19 +02:00
b4c395f0da Update secrets page to new layout 2025-06-19 06:12:36 +02:00
d55c699549 Set breadcrumb dynamically 2025-06-18 19:15:12 +02:00
05775a2e1e Complete inital re-design of client page 2025-06-18 08:54:45 +02:00
9b0588679f fix tabs and tables 2025-06-18 08:34:45 +02:00
29 changed files with 484 additions and 491 deletions

View File

@ -1,60 +1,6 @@
{% extends "/dashboard/_base.html" %} {% block content %} {% extends "/base/page.html.j2" %}
<div {% block title %}Audit{% endblock %}
class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200 lg:mt-1.5 dark:bg-gray-800 dark:border-gray-700" {% block page_content %}
>
<div class="w-full mb-1">
<div class="mb-4">
<nav class="flex mb-5" aria-label="Breadcrumb">
<ol
class="inline-flex items-center space-x-1 text-sm font-medium md:space-x-2"
>
<li class="inline-flex items-center">
<a
href="/"
class="inline-flex items-center text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-white"
>
<svg
class="w-5 h-5 mr-2.5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"
></path>
</svg>
Home
</a>
</li>
<li>
<div class="flex items-center">
<svg
class="w-6 h-6 text-gray-800 dark:text-white"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M9 8h6m-6 4h6m-6 4h6M6 3v18l2-2 2 2 2-2 2 2 2-2 2 2V3l-2 2-2-2-2 2-2-2-2 2-2-2Z"
/>
<span class="ml-1 text-gray-400 md:ml-2 dark:text-gray-500" aria-current="page">Audit Log</span>
</svg>
</div>
</li>
</ol>
</nav>
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Audit Log</h1>
</div>
</div>
</div>
<div id="auditContent"> <div id="auditContent">
{% include 'audit/inner.html.j2' %} {% include 'audit/inner.html.j2' %}
</div> </div>

View File

@ -1,5 +1,5 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en" class="dark">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@ -9,25 +9,21 @@
{% include 'base/partials/stylesheets.html.j2' %} {% include 'base/partials/stylesheets.html.j2' %}
{% endblock %} {% endblock %}
</head> </head>
<body class="bg-gray-50 text-gray-900 min-h-screen flex flex-col"> <body class="bg-gray-50 text-gray-900 dark:bg-gray-900 min-h-screen flex flex-col">
<!-- Optional: Shoelace modals, toasts -->
<sl-alert id="global-alert" variant="primary" duration="4000" closable></sl-alert>
<sl-dialog id="global-dialog" label="Dialog"></sl-dialog>
<!-- Layout Container --> <!-- Layout Container -->
<div class="flex flex-1 h-full overflow-hidden"> <div class="flex flex-1 h-full overflow-hidden">
<!-- Sidebar --> <!-- Sidebar -->
<aside class="hidden md:flex md:w-64 flex-col h-full min-h-screen bg-white border-r border-gray-300" id="sidebar" aria-label="sidebar"> <aside class="hidden md:flex md:w-64 flex-col h-full min-h-screen bg-white border-r border-gray-300 dark:bg-gray-800 dark:border-gray-700" id="sidebar" aria-label="sidebar">
{% include "base/partials/sidebar.html.j2" %} {% include "base/partials/sidebar.html.j2" %}
</aside> </aside>
<!-- Main Panel --> <!-- Main Panel -->
<div class="flex-1 flex flex-col overflow-hidden"> <div class="flex-1 flex flex-col overflow-hidden">
<!-- Topbar --> <!-- Topbar -->
<header class="bg-white border-b px-4 py-3 border-gray-300"> <header class="bg-white border-b px-4 py-3 border-gray-300 dark:bg-gray-800 dark:border-gray-700">
{% include "base/partials/navbar.html.j2" %} {% include "base/partials/navbar.html.j2" %}
</header> </header>
@ -35,7 +31,7 @@
<main id="content" class="flex-1 overflow-y-auto" hx-target="this" hx-swap="innerHTML"> <main id="content" class="flex-1 overflow-y-auto" hx-target="this" hx-swap="innerHTML">
{% block breadcrumbs %} {% block breadcrumbs %}
{% endblock %} {% endblock %}
<div class="p-4" id="maincontent"> <div class="" id="maincontent">
{% block content %}{% endblock %} {% block content %}{% endblock %}
</div> </div>
</main> </main>
@ -43,8 +39,12 @@
</div> </div>
</div> </div>
{% block scripts %} {% block scripts %}
{% include 'base/partials/scripts.html.j2' %} {% include 'base/partials/scripts.html.j2' %}
{% endblock %} {% endblock %}
{% block local_scripts %}
{% endblock %}
</body> </body>
</html> </html>

View File

@ -0,0 +1,26 @@
{% extends 'base/page.html.j2' %}
{% block page_content %}
<!-- Master-Detail Split View -->
<div class="flex h-[calc(100vh-8rem)] overflow-hidden">
<!-- Master Pane -->
<aside id="master-pane"
class="md:w-80 w-full shrink-0 border-r overflow-y-auto bg-white md:block border-gray-200 p-4 dark:bg-gray-800 dark:border-gray-700">
{% block master %}
<p class="p-4 text-gray-500">Master view (e.g. list/tree)</p>
{% endblock %}
</aside>
<!-- Detail Pane -->
<section id="detail-pane"
class="flex-1 flex overflow-y-auto bg-white p-4 hidden md:block dark:bg-gray-800">
{% block detail %}
<p class="p-4 text-gray-500 dark:text-gray-200">Select an item to view details</p>
{% endblock %}
</section>
</div>
{% endblock %}

View File

@ -1,20 +1,19 @@
{% extends "/base/base.html.j2" %} {% extends "/base/base.html.j2" %}
{% block title %}{{ title or "Page" }}{% endblock %}
{% block breadcrumbs %} {% block breadcrumbs %}
<div class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200"> <div class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200 dark:bg-gray-800 dark:border-gray-700">
<nav class="text-sm text-gray-500" aria-label="Breadcrumb"> <nav class="text-sm text-gray-500" aria-label="Breadcrumb">
<sl-breadcrumb> <sl-breadcrumb id="breadcrumbs">
<sl-breadcrumb-item> <sl-breadcrumb-item>
<sl-icon slot="prefix" name="house"></sl-icon> <sl-icon slot="prefix" name="house"></sl-icon>
<a href="/">Home</a> <a href="/">Home</a>
</sl-breadcrumb-item> </sl-breadcrumb-item>
{% if breadcrumbs %} {% if breadcrumbs %}
{% for label, url in breadcrumbs %} {% for label, url in breadcrumbs %}
<sl-breadcrumb-item> <sl-breadcrumb-item class="page-breadcrumb">
{% if url %} {% if url %}
<a href="{{url}}">{{label}}</a> <a href="{{url}}">{{label}}</a>
{% else %} {% else %}
@ -32,7 +31,7 @@
<!-- Breadcrumbs --> <!-- Breadcrumbs -->
<!-- Page Content --> <!-- Page Content -->
<section> <section class="bg-white dark:bg-gray-800">
{% block page_content %} {% block page_content %}
<p>This is a generic page.</p> <p>This is a generic page.</p>
{% endblock %} {% endblock %}

View File

@ -15,18 +15,9 @@
</button> </button>
<!-- Page title or logo --> <!-- Page title or logo -->
<a href="/" class="flex ml-2 md:mr-24"> {% if page_title %}
<img <h1 class="text-xl flex ml-2 md:mr-24 font-semibold text-gray-900 sm:text-2xl dark:text-white">{{page_title}}</h1>
src="{{ url_for('static', path='logo.svg') }}" {% endif %}
class="h-11 mr-3"
alt="Sshecret Logo"
/>
<span
class="self-center text-xl font-semibold sm:text-2xl whitespace-nowrap dark:text-white"
>Sshecret</span
>
</a>
</div> </div>
<!-- Right: User menu --> <!-- Right: User menu -->

View File

@ -3,8 +3,9 @@
<!-- Top: Brand --> <!-- Top: Brand -->
<div class="px-4 py-6"> <div class="px-4 py-6">
<a href="/" class="text-xl font-semibold text-gray-800"> <a href="/" class="text-xl font-semibold text-gray-800 dark:text-gray-100">
🐚 Sshecret <sl-icon src="{{ url_for('static', path='logo.svg') }}"></sl-icon>
Sshecret
</a> </a>
</div> </div>
@ -12,28 +13,28 @@
<ul class="space-y-"> <ul class="space-y-">
<li> <li>
<a href="/" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"> <a href="/" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700">
<sl-icon name="house"></sl-icon> <sl-icon name="house"></sl-icon>
Dashboard Dashboard
</a> </a>
</li> </li>
<li> <li>
<a href="/clients/" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"> <a href="/clients/" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700">
<sl-icon name="person-fill-lock"> </sl-icon> <sl-icon name="person-fill-lock"> </sl-icon>
Clients Clients
</a> </a>
</li> </li>
<li> <li>
<a href="/admin/secrets" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"> <a href="/secrets" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700">
<sl-icon name="database-lock"></sl-icon> <sl-icon name="database-lock"></sl-icon>
Secrets Secrets
</a> </a>
</li> </li>
<li> <li>
<a href="/admin/audit" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"> <a href="/audit" class="flex items-center px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-700">
<sl-icon name="card-list"></sl-icon> <sl-icon name="card-list"></sl-icon>
Audit Log Audit Log
</a> </a>

View File

@ -35,3 +35,16 @@
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/dark.css" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/dark.css"
onload="document.documentElement.classList.add('sl-theme-dark');" onload="document.documentElement.classList.add('sl-theme-dark');"
/> />
<script>
// On page load or when changing themes, best to add inline in `head` to avoid FOUC
if (
localStorage.getItem("color-theme") === "dark" ||
(!("color-theme" in localStorage) &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
) {
document.documentElement.classList.add("dark");
} else {
document.documentElement.classList.remove("dark");
}
</script>

View File

@ -1,5 +1,9 @@
{% extends "/dashboard/_base.html" %} {% block content %} {% extends "/base/page.html.j2" %}
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4"> {% block title %}Change Password{% endblock %}
{% block page_content %}
<div class="h-[calc(100vh-8rem)] bg-gray-100 flex items-center justify-center p-4">
<div class="w-full max-w-xl p-6 space-y-8 bg-white rounded-lg shadow sm:p-8 dark:bg-gray-800"> <div class="w-full max-w-xl p-6 space-y-8 bg-white rounded-lg shadow sm:p-8 dark:bg-gray-800">
<h2 class="text-2xl font-bold text-gray-900 dark:text-white"> <h2 class="text-2xl font-bold text-gray-900 dark:text-white">
Change Password Change Password

View File

@ -1,5 +1,8 @@
{% extends "/dashboard/_base.html" %} {% block content %}
<div class="min-h-screen bg-gray-100 flex items-center justify-center p-4"> {% extends "/base/page.html.j2" %}
{% block page_content %}
<div class="h-[calc(100vh-8rem)] bg-gray-100 flex items-center justify-center p-4">
<div class="text-center xl:max-w-4xl"> <div class="text-center xl:max-w-4xl">
<h1 class="mb-3 text-2xl font-bold leading-tight text-gray-900 sm:text-4xl lg:text-5xl dark:text-white">Password Changed</h1> <h1 class="mb-3 text-2xl font-bold leading-tight text-gray-900 sm:text-4xl lg:text-5xl dark:text-white">Password Changed</h1>
<p class="mb-5 text-base font-normal text-gray-500 md:text-lg dark:text-gray-400">Your password was changed sucessfully. Next time you log in, use your new password.</p> <p class="mb-5 text-base font-normal text-gray-500 md:text-lg dark:text-gray-400">Your password was changed sucessfully. Next time you log in, use your new password.</p>
@ -9,4 +12,4 @@
</a> </a>
</div> </div>
</div> </div>
{% endblock content %} {% endblock %}

View File

@ -1,46 +1,24 @@
{% extends "/dashboard/_base.html" %} {% block content %} {% extends 'base/master-detail-email.html.j2' %}
<div class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200 lg:mt-1.5 dark:bg-gray-800 dark:border-gray-700"> {% block title %}Client {{ client.name }}{% endblock %}
<div class="w-full mb-1">
<div class="mb-4">
<nav class="flex mb-5" aria-label="Breadcrumb">
<ol class="inline-flex items-center space-x-1 text-sm font-medium md:space-x-2">
<li class="inline-flex items-center">
<a href="/" class="inline-flex items-center text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-white">
<svg class="w-5 h-5 mr-2.5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
Home
</a>
</li>
<li>
<div class="flex items-center">
<svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
<span class="ml-1 text-gray-400 md:ml-2 dark:text-gray-500" aria-current="page">Clients</span>
</div>
</li>
<li>
<div class="flex items-center">
<svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
<span class="ml-1 text-gray-400 md:ml-2 dark:text-gray-500" aria-current="page">View</span>
</div>
</li>
</ol>
</nav>
{% block master %}
</div>
<div class="grid w-full grid-cols-1 gap-4 mt-4 xl:grid-cols-3">
<div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm sm:flex dark:border-gray-700 sm:p-6 dark:bg-gray-800 h-full" id="client-tree">
{% include '/clients/partials/tree.html.j2' %} {% include '/clients/partials/tree.html.j2' %}
</div> {% endblock %}
<div class="2xl:col-span-2 xl:col-span-2 p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<div class="w-full" id="clientdetails">
{% block detail %}
<div id="clientdetails" class="w-full">
{% include '/clients/partials/client_details.html.j2' %} {% include '/clients/partials/client_details.html.j2' %}
</div> </div>
</div>
</div>
</div>
</div>
{% include '/clients/partials/drawer_create.html.j2' %}
{% endblock %} {% endblock %}
{% include '/clients/partials/drawer_create.html.j2' %}
{% block local_scripts %}
<script>
{% include '/clients/partials/tree_event.js' %}
</script>
{% endblock local_scripts %}

View File

@ -1,41 +1,21 @@
{% extends "/dashboard/_base.html" %} {% block content %} {% extends 'base/master-detail-email.html.j2' %}
<div class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200 lg:mt-1.5 dark:bg-gray-800 dark:border-gray-700"> {% block title %}Clients{% endblock %}
<div class="w-full mb-1">
<div class="mb-4">
<nav class="flex mb-5" aria-label="Breadcrumb">
<ol class="inline-flex items-center space-x-1 text-sm font-medium md:space-x-2">
<li class="inline-flex items-center">
<a href="/" class="inline-flex items-center text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-white">
<svg class="w-5 h-5 mr-2.5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
Home
</a>
</li>
<li>
<div class="flex items-center"> {% block master %}
<svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
<span class="ml-1 text-gray-400 md:ml-2 dark:text-gray-500" aria-current="page">Clients</span>
</div>
</li>
</ol>
</nav>
</div>
<div class="grid w-full grid-cols-1 gap-4 mt-4 xl:grid-cols-3">
<div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm sm:flex dark:border-gray-700 sm:p-6 dark:bg-gray-800 h-full" id="client-tree">
{% include '/clients/partials/tree.html.j2' %} {% include '/clients/partials/tree.html.j2' %}
</div> {% endblock %}
<div class="2xl:col-span-2 xl:col-span-2 p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
<div class="w-full" id="clientdetails">
{% block detail %}
<div id="clientdetails" class="w-full bg-white dark:bg-gray-800">
<h3 class="mb-4 text-sm italic text-gray-400 dark:text-white">Click an item to view details</h3> <h3 class="mb-4 text-sm italic text-gray-400 dark:text-white">Click an item to view details</h3>
</div> </div>
</div>
</div>
</div>
</div>
{% include '/clients/partials/drawer_create.html.j2' %} {% include '/clients/partials/drawer_create.html.j2' %}
{% endblock %} {% endblock %}
{% block local_scripts %}
<script>
{% include '/clients/partials/tree_event.js' %}
</script>
{% endblock local_scripts %}

View File

@ -38,7 +38,7 @@
</ul> </ul>
</div> </div>
</div> </div>
<sl-tab-group placement="end"> <sl-tab-group >
<sl-tab slot="nav" panel="client_data">Client Data</sl-tab> <sl-tab slot="nav" panel="client_data">Client Data</sl-tab>
<sl-tab slot="nav" panel="events">Events</sl-tab> <sl-tab slot="nav" panel="events">Events</sl-tab>
@ -47,37 +47,37 @@
<div id="client_details"> <div id="client_details">
<div class="w-full p-2"> <div class="w-full p-2">
<div class="px-4 sm:px-0"> <div class="px-4 sm:px-0">
<h3 class="text-base/7 font-semibold text-gray-900">{{client.name}}</h3> <h3 class="text-base/7 font-semibold text-gray-900 dark:text-gray-50">{{client.name}}</h3>
{% if client.description %} {% if client.description %}
<p class="mt-1 max-w-2xl text-sm/6 text-gray-500">{{ client.description }}</p> <p class="mt-1 max-w-2xl text-sm/6 text-gray-500 dark:text-gray-100">{{ client.description }}</p>
{% endif %} {% endif %}
</div> </div>
<div class="mt-6 border-t border-gray-100"> <div class="mt-6 border-t border-gray-100">
<dl class="divide-y divide-gray-100"> <dl class="divide-y divide-gray-100">
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Client ID</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Client ID</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.id}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">{{client.id}}</dd>
</div> </div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Client Description</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Client Description</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.description}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">{{client.description}}</dd>
</div> </div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Client Version</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Client Version</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.version}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">{{client.version}}</dd>
</div> </div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Public Key</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Public Key</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 truncate">{{client.public_key}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300 truncate">{{client.public_key}}</dd>
</div> </div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Assigned Secrets</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Assigned Secrets</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.secrets|length}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">{{client.secrets|length}}</dd>
</div> </div>
<div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0"> <div class="px-4 py-6 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm/6 font-medium text-gray-900">Allowed sources</dt> <dt class="text-sm/6 font-medium text-gray-900 dark:text-gray-200">Allowed sources</dt>
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.policies|join(', ')}}</dd> <dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 dark:text-gray-300">{{client.policies|join(', ')}}</dd>
</div> </div>
</dl> </dl>
</div> </div>
@ -86,7 +86,7 @@
</sl-tab-panel> </sl-tab-panel>
<sl-tab-panel name="events"> <sl-tab-panel name="events">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-600" id="last-audit-events"> <table class="min-w-full lg:table-fixed divide-y divide-gray-200 dark:divide-gray-600" id="last-audit-events">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>
<th scope="col" class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white">Timestamp</th> <th scope="col" class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white">Timestamp</th>

View File

@ -1,7 +1,8 @@
<div class="flex flex-1 flex-col justify-between h-full flowbite-init-target"> {# This is the master block #}
<div class="grid grid-cols-2 place-content-between mb-6">
<div> <div class="flowbite-init-target">
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Clients</h1> <div class="tree-header grid grid-cols-2 place-content-between mb-6">
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Client List</h1>
<div class="flex"> <div class="flex">
<div <div
class="htmx-indicator mt-2" class="htmx-indicator mt-2"
@ -14,10 +15,8 @@
<span class="sr-only">Loading...</span> <span class="sr-only">Loading...</span>
</div> </div>
</div> </div>
</div>
</div>
<div <div
class="flex justify-end px-4" class="flex w-full justify-end"
> >
<sl-icon-button <sl-icon-button
name="plus-square" name="plus-square"
@ -31,8 +30,8 @@
></sl-icon-button> ></sl-icon-button>
</div> </div>
</div> </div>
<div class="flex-1 overflow-auto"> <div class="col-span-full">
<div class="relative w-full "> <div class="relative">
<div class="border-b border-gray-200 py-2 mb-6"> <div class="border-b border-gray-200 py-2 mb-6">
<label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label> <label for="default-search" class="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">Search</label>
<div class="relative"> <div class="relative">
@ -56,12 +55,10 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
<div id="client-tree-items"> <div id="client-tree-items">
{% include '/clients/partials/tree_items.html.j2' %} {% include '/clients/partials/tree_items.html.j2' %}
</div> </div>
</div>
</div> </div>
<script>
{% include '/clients/partials/tree_event.js' %}
</script>

View File

@ -1,3 +1,16 @@
function setBreadcrumb(name) {
// Set the current client name as the final breadcrumb
const breadcrumbs = document.getElementById("breadcrumbs");
const existingNode = document.getElementById("bc-dynamic-client");
if (existingNode) {
breadcrumbs.removeChild(existingNode);
}
const newCrumb = document.createElement("sl-breadcrumb-item");
newCrumb.setAttribute("id", "bc-dynamic-client");
const bcTitle = document.createTextNode(name);
newCrumb.appendChild(bcTitle);
breadcrumbs.appendChild(newCrumb);
}
function addTreeListener() { function addTreeListener() {
const tree = document.querySelector("sl-tree"); const tree = document.querySelector("sl-tree");
@ -8,6 +21,8 @@ function addTreeListener() {
if (!selectedEl) return; if (!selectedEl) return;
const masterPane = document.getElementById("master-pane");
const detailPane = document.getElementById("detail-pane");
const type = selectedEl.dataset.nodeType; const type = selectedEl.dataset.nodeType;
const clientId = selectedEl.dataset.clientId; const clientId = selectedEl.dataset.clientId;
const name = selectedEl.dataset.clientName; const name = selectedEl.dataset.clientName;
@ -17,10 +32,16 @@ function addTreeListener() {
let url = `/clients/client/${encodeURIComponent(clientId)}`; let url = `/clients/client/${encodeURIComponent(clientId)}`;
if (url) { if (url) {
htmx.ajax("GET", url, { htmx
.ajax("GET", url, {
target: "#clientdetails", target: "#clientdetails",
//swap: 'OuterHTML', //swap: 'OuterHTML',
indicator: "#client-spinner", indicator: "#client-spinner",
})
.then(() => {
masterPane.classList.add("hidden");
detailPane.classList.remove("hidden");
setBreadcrumb(name);
}); });
} }
}); });

View File

@ -38,5 +38,4 @@
{% include 'clients/partials/pagination.html.j2' %} {% include 'clients/partials/pagination.html.j2' %}
</div> </div>
{% endif %} {% endif %}
</div> </div>

View File

@ -1,4 +1,4 @@
{% extends "/shared/_base.html" %} {% block content %} {% if login_error %} {% extends "/base/bare.html.j2" %} {% block content %} {% if login_error %}
<div class="flex bg-gray-100"> <div class="flex bg-gray-100">
<div <div
@ -88,7 +88,5 @@
</a> </a>
</div> </div>
</div> </div>
{% endif %} {% endif %} {% endblock %}
{% endblock %}
</div> </div>

View File

@ -47,36 +47,15 @@
{% endmacro %} {% endmacro %}
{% extends "/dashboard/_base.html" %} {% block content %} {% extends 'base/master-detail-email.html.j2' %}
<div class="p-4 bg-white block sm:flex items-center justify-between border-b border-gray-200 lg:mt-1.5 dark:bg-gray-800 dark:border-gray-700"> {% block title %}Secrets{% endblock %}
<div class="w-full mb-1">
<div class="mb-4">
<nav class="flex mb-5" aria-label="Breadcrumb">
<ol class="inline-flex items-center space-x-1 text-sm font-medium md:space-x-2">
<li class="inline-flex items-center">
<a href="/" class="inline-flex items-center text-gray-700 hover:text-primary-600 dark:text-gray-300 dark:hover:text-white">
<svg class="w-5 h-5 mr-2.5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10.707 2.293a1 1 0 00-1.414 0l-7 7a1 1 0 001.414 1.414L4 10.414V17a1 1 0 001 1h2a1 1 0 001-1v-2a1 1 0 011-1h2a1 1 0 011 1v2a1 1 0 001 1h2a1 1 0 001-1v-6.586l.293.293a1 1 0 001.414-1.414l-7-7z"></path></svg>
Home
</a>
</li>
<li>
<div class="flex items-center">
<svg class="w-6 h-6 text-gray-400" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path></svg>
<span class="ml-1 text-gray-400 md:ml-2 dark:text-gray-500" aria-current="page">Secrets</span>
</div>
</li>
</ol>
</nav>
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Secrets</h1>
</div>
<div class="grid w-full grid-cols-1 gap-4 mt-4 xl:grid-cols-3">
<div class="p-4 bg-white border border-gray-200 rounded-lg shadow-sm sm:flex dark:border-gray-700 sm:p-6 dark:bg-gray-800" id="secret-tree">
<div class="flex flex-1 flex-col"> {% block master %}
<div class="h-full w-full">
<div class="flowbite-init-target">
<div id="secret-tree">
<sl-tree class="tree-with-icons"> <sl-tree class="tree-with-icons">
<sl-tree-item <sl-tree-item
id="secret-group-root-item" id="secret-group-root-item"
@ -101,10 +80,11 @@
{% endfor %} {% endfor %}
</sl-tree> </sl-tree>
</div> </div>
</div> </div>
</div> {% endblock %}
<div class="2xl:col-span-2 xl:col-span-2 p-4 mb-4 bg-white border border-gray-200 rounded-lg shadow-sm 2xl:col-span-2 dark:border-gray-700 sm:p-6 dark:bg-gray-800">
{% block detail %}
{% if group_page | default(false) %} {% if group_page | default(false) %}
<div class="w-full" id="secretdetails"> <div class="w-full" id="secretdetails">
{% include '/secrets/partials/group_detail.html.j2' %} {% include '/secrets/partials/group_detail.html.j2' %}
@ -121,11 +101,13 @@
{% include '/secrets/partials/default_detail.html.j2' %} {% include '/secrets/partials/default_detail.html.j2' %}
{% endif %} {% endif %}
</div> {% endblock %}
</div>
</div>
</div> {% block local_scripts %}
<script> <script>
{% include '/secrets/partials/tree_event.js' %} {% include '/secrets/partials/tree_event.js' %}
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,4 +1,4 @@
<div class="w-full my-2"> <div class="w-full my-2 dark:text-white">
<ul class="w-48 text-sm font-medium text-gray-900 bg-white dark:bg-gray-700 dark:text-white" id="secretclientlist"> <ul class="w-48 text-sm font-medium text-gray-900 bg-white dark:bg-gray-700 dark:text-white" id="secretclientlist">
{% include '/secrets/partials/client_list_inner.html.j2' %} {% include '/secrets/partials/client_list_inner.html.j2' %}
</ul> </ul>

View File

@ -1,4 +1,4 @@
<div class="w-full"> <div class="w-full dark:text-white">
<sl-details summary="Create secret"> <sl-details summary="Create secret">
<form <form
hx-post="/secrets/create/root" hx-post="/secrets/create/root"

View File

@ -1,4 +1,4 @@
<div class="w-full"> <div class="w-full dark:text-white">
<div class="mb-4"> <div class="mb-4">
<h3 class="text-xl font-semibold dark:text-white">Group {{group.group_name}}</h3> <h3 class="text-xl font-semibold dark:text-white">Group {{group.group_name}}</h3>
{% if description %} {% if description %}

View File

@ -1,8 +1,8 @@
<div class="w-full flowbite-init-target" id="secretdetails"> <div class="w-full flowbite-init-target dark:text-white" id="secretdetails">
<!-- menu --> <!-- menu -->
<div class="flex justify-end px-4"> <div class="flex justify-end px-4">
<button id="secret-menu-button" data-dropdown-toggle="secret-edit-menu" class="inline-block text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-1.5" type="button"> <button id="secret-menu-button" data-dropdown-toggle="secret-edit-menu" class="inline-block text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-1.5" type="button">
<span class="sr-only">Open dropdown</span> <span class="sr-only">Open dropdown</span>
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 3"> <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 16 3">
@ -27,7 +27,7 @@
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<h3 class="mb-4 text-xl font-semibold dark:text-white">{{secret.name}}</h3> <h3 class="mb-4 text-xl font-semibold dark:text-white">{{secret.name}}</h3>
@ -110,8 +110,8 @@
</form> </form>
</sl-details> </sl-details>
{% endif %} {% endif %}
{% endif %} {% endif %}
<sl-details summary="Events"> <sl-details summary="Events" class="dark:text-white">
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-600" id="last-audit-events"> <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-600" id="last-audit-events">
<thead class="bg-gray-50 dark:bg-gray-700"> <thead class="bg-gray-50 dark:bg-gray-700">
<tr> <tr>

View File

@ -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"); const tree = document.querySelector("sl-tree");
if (!tree) return; if (!tree) return;
@ -33,4 +90,12 @@ document.addEventListener("DOMContentLoaded", () => {
}); });
} }
}); });
}
document.addEventListener("DOMContentLoaded", () => {
addTreeListener();
});
document.addEventListener("htmx:afterSwap", () => {
addTreeListener();
}); });

View File

@ -42,6 +42,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
page=page, limit=per_page, total=audit_log.total, offset=offset page=page, limit=per_page, total=audit_log.total, offset=offset
) )
operations = list(Operation) operations = list(Operation)
breadcrumbs = [("Audit", "/audit/")]
if request.headers.get("HX-Request"): if request.headers.get("HX-Request"):
return templates.TemplateResponse( return templates.TemplateResponse(
request, request,
@ -56,7 +57,8 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
request, request,
"audit/index.html.j2", "audit/index.html.j2",
{ {
"page_title": "Audit", "page_title": "Audit Log",
"breadcrumbs": breadcrumbs,
"entries": audit_log.results, "entries": audit_log.results,
"user": current_user, "user": current_user,
"page_info": page_info, "page_info": page_info,

View File

@ -93,42 +93,14 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
page=page, limit=per_page, total=results.total_results, offset=offset page=page, limit=per_page, total=results.total_results, offset=offset
) )
breadcrumbs = [("clients", "/clients/")]
LOG.info("Results %r", results) LOG.info("Results %r", results)
return templates.TemplateResponse( return templates.TemplateResponse(
request, request,
"clients/index.html.j2", "clients/index.html.j2",
{ {
"page_title": "Clients", "breadcrumbs": breadcrumbs,
"offset": offset,
"pages": paginate,
"clients": results.clients,
"user": current_user,
"results": results,
},
)
@app.get("/clients/new/")
async def get_new_client_tree(
request: Request,
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
) -> Response:
"""Get client tree view."""
page = 1
per_page = CLIENTS_PER_PAGE
offset = 0
client_filter = ClientFilter(offset=offset, limit=per_page)
results = await admin.query_clients(client_filter)
paginate = PagingInfo(
page=page, limit=per_page, total=results.total_results, offset=offset
)
LOG.info("Results %r", results)
return templates.TemplateResponse(
request,
"clients/redesign.html.j2",
{
"page_title": "Clients", "page_title": "Clients",
"offset": offset, "offset": offset,
"pages": paginate, "pages": paginate,
@ -197,6 +169,11 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
) )
template = "clients/client.html.j2" template = "clients/client.html.j2"
breadcrumbs = [
("clients", "/clients/"),
(results.client.name, request.url.path),
]
headers: dict[str, str] = {} headers: dict[str, str] = {}
if request.headers.get("HX-Request"): if request.headers.get("HX-Request"):
headers["HX-Push-Url"] = request.url.path headers["HX-Push-Url"] = request.url.path
@ -207,6 +184,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
template, template,
{ {
"page_title": f"Client {results.client.name}", "page_title": f"Client {results.client.name}",
"breadcrumbs": breadcrumbs,
"pages": results.pages, "pages": results.pages,
"clients": results.results.clients, "clients": results.results.clients,
"client": results.client, "client": results.client,

View File

@ -81,7 +81,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
request, request,
"dashboard.html", "dashboard.html",
{ {
"page_title": "sshecret", "page_title": "Dashboard",
"user": current_user, "user": current_user,
"stats": stats, "stats": stats,
"last_login_events": last_login_events, "last_login_events": last_login_events,

View File

@ -63,12 +63,15 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)], admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)], current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
): ):
breadcrumbs = [("secrets", "/secrets/")]
groups = await admin.get_secret_groups() groups = await admin.get_secret_groups()
return templates.TemplateResponse( return templates.TemplateResponse(
request, request,
"secrets/index.html.j2", "secrets/index.html.j2",
{ {
"page_title": "Secrets",
"groups": groups, "groups": groups,
"breadcrumbs": breadcrumbs,
"user": current_user, "user": current_user,
"selected_group": None, "selected_group": None,
"group_path_nodes": ["/"], "group_path_nodes": ["/"],
@ -83,8 +86,15 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
): ):
"""Show the root path.""" """Show the root path."""
clients = await admin.get_clients() clients = await admin.get_clients()
breadcrumbs = [
("secrets", "/secrets/"),
("groups", "/secrets/groups/"),
("Ungrouped", "/secrets/groups/"),
]
context: dict[str, Any] = { context: dict[str, Any] = {
"clients": clients, "clients": clients,
"breadcrumbs": breadcrumbs,
"root_group_page": True, "root_group_page": True,
} }
headers: dict[str, str] = {} headers: dict[str, str] = {}
@ -95,6 +105,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
else: else:
groups = await admin.get_secret_groups() groups = await admin.get_secret_groups()
template_name = "secrets/index.html.j2" template_name = "secrets/index.html.j2"
context["page_title"] = "Secrets"
context["user"] = current_user context["user"] = current_user
context["groups"] = groups context["groups"] = groups
context["group_path_nodes"] = ["/"] context["group_path_nodes"] = ["/"]
@ -119,11 +130,20 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
) )
clients = await admin.get_clients() 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] = {} headers: dict[str, str] = {}
context: dict[str, Any] = { context: dict[str, Any] = {
"group_page": True, "group_page": True,
"group": group, "group": group,
"clients": clients, "clients": clients,
"breadcrumbs": breadcrumbs,
} }
if request.headers.get("HX-Request"): if request.headers.get("HX-Request"):
# This is a HTMX request. # This is a HTMX request.
@ -133,6 +153,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
template_name = "secrets/index.html.j2" template_name = "secrets/index.html.j2"
groups = await admin.get_secret_groups() groups = await admin.get_secret_groups()
context["page_title"] = "Secrets"
context["user"] = current_user context["user"] = current_user
context["groups"] = groups context["groups"] = groups
context["group_path_nodes"] = group.path.split("/") context["group_path_nodes"] = group.path.split("/")
@ -180,6 +201,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
group_path = group.path.split("/") group_path = group.path.split("/")
template_name = "secrets/index.html.j2" template_name = "secrets/index.html.j2"
context["page_title"] = "Secrets"
context["user"] = current_user context["user"] = current_user
context["groups"] = groups context["groups"] = groups
context["group_path_nodes"] = group_path context["group_path_nodes"] = group_path

View File

@ -382,9 +382,6 @@
.order-1 { .order-1 {
order: 1; order: 1;
} }
.order-2 {
order: 2;
}
.col-span-2 { .col-span-2 {
grid-column: span 2 / span 2; grid-column: span 2 / span 2;
} }
@ -457,9 +454,6 @@
.ms-3 { .ms-3 {
margin-inline-start: calc(var(--spacing) * 3); margin-inline-start: calc(var(--spacing) * 3);
} }
.ms-auto {
margin-inline-start: auto;
}
.me-2 { .me-2 {
margin-inline-end: calc(var(--spacing) * 2); margin-inline-end: calc(var(--spacing) * 2);
} }
@ -682,15 +676,18 @@
.h-\[12px\] { .h-\[12px\] {
height: 12px; height: 12px;
} }
.h-\[16px\] {
height: 16px;
}
.h-\[32px\] {
height: 32px;
}
.h-\[36rem\] { .h-\[36rem\] {
height: 36rem; height: 36rem;
} }
.h-\[calc\(100vh-4rem\)\] {
height: calc(100vh - 4rem);
}
.h-\[calc\(100vh-8rem\)\] {
height: calc(100vh - 8rem);
}
.h-\[calc\(100vh-10rem\)\] {
height: calc(100vh - 10rem);
}
.h-full { .h-full {
height: 100%; height: 100%;
} }
@ -1245,9 +1242,6 @@
.border-blue-300 { .border-blue-300 {
border-color: var(--color-blue-300); border-color: var(--color-blue-300);
} }
.border-blue-700 {
border-color: var(--color-blue-700);
}
.border-gray-100 { .border-gray-100 {
border-color: var(--color-gray-100); border-color: var(--color-gray-100);
} }
@ -1332,9 +1326,6 @@
.bg-blue-600 { .bg-blue-600 {
background-color: var(--color-blue-600); background-color: var(--color-blue-600);
} }
.bg-blue-700 {
background-color: var(--color-blue-700);
}
.bg-emerald-500 { .bg-emerald-500 {
background-color: var(--color-emerald-500); background-color: var(--color-emerald-500);
} }
@ -2175,13 +2166,6 @@
} }
} }
} }
.hover\:bg-blue-800 {
&:hover {
@media (hover: hover) {
background-color: var(--color-blue-800);
}
}
}
.hover\:bg-gray-50 { .hover\:bg-gray-50 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@ -2774,11 +2758,6 @@
inset: calc(var(--spacing) * 0); inset: calc(var(--spacing) * 0);
} }
} }
.md\:order-1 {
@media (width >= 48rem) {
order: 1;
}
}
.md\:order-2 { .md\:order-2 {
@media (width >= 48rem) { @media (width >= 48rem) {
order: 2; order: 2;
@ -2859,6 +2838,16 @@
width: calc(var(--spacing) * 64); width: calc(var(--spacing) * 64);
} }
} }
.md\:w-72 {
@media (width >= 48rem) {
width: calc(var(--spacing) * 72);
}
}
.md\:w-80 {
@media (width >= 48rem) {
width: calc(var(--spacing) * 80);
}
}
.md\:w-\[calc\(100\%-256px\)\] { .md\:w-\[calc\(100\%-256px\)\] {
@media (width >= 48rem) { @media (width >= 48rem) {
width: calc(100% - 256px); width: calc(100% - 256px);
@ -3114,6 +3103,11 @@
width: auto; width: auto;
} }
} }
.lg\:table-fixed {
@media (width >= 64rem) {
table-layout: fixed;
}
}
.lg\:grid-cols-2 { .lg\:grid-cols-2 {
@media (width >= 64rem) { @media (width >= 64rem) {
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
@ -3469,11 +3463,6 @@
border-color: var(--color-red-800); border-color: var(--color-red-800);
} }
} }
.dark\:bg-blue-600 {
&:where(.dark, .dark *) {
background-color: var(--color-blue-600);
}
}
.dark\:bg-blue-900 { .dark\:bg-blue-900 {
&:where(.dark, .dark *) { &:where(.dark, .dark *) {
background-color: var(--color-blue-900); background-color: var(--color-blue-900);
@ -3728,15 +3717,6 @@
} }
} }
} }
.dark\:hover\:bg-blue-700 {
&:where(.dark, .dark *) {
&:hover {
@media (hover: hover) {
background-color: var(--color-blue-700);
}
}
}
}
.dark\:hover\:bg-blue-800 { .dark\:hover\:bg-blue-800 {
&:where(.dark, .dark *) { &:where(.dark, .dark *) {
&:hover { &:hover {

View File

@ -19,3 +19,11 @@ sl-details.small-details::part(header) {
sl-details.small-details::part(base) { sl-details.small-details::part(base) {
font-size: var(--sl-input-font-size-small); font-size: var(--sl-input-font-size-small);
} }
@media (prefers-color-scheme: dark) {
sl-details::part(base) {
background-color: var(--color-gray-700);
border: solid 1px var(--color-gray-500);
color: var(--color-gray-50);
}
}