Compare commits
8 Commits
d9e0052003
...
2b50c686d0
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b50c686d0 | |||
| 57e69390b2 | |||
| 23d354bc12 | |||
| cad9849019 | |||
| b4c395f0da | |||
| d55c699549 | |||
| 05775a2e1e | |||
| 9b0588679f |
@ -1,60 +1,6 @@
|
||||
{% extends "/dashboard/_base.html" %} {% block content %}
|
||||
<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"
|
||||
>
|
||||
<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>
|
||||
{% extends "/base/page.html.j2" %}
|
||||
{% block title %}Audit{% endblock %}
|
||||
{% block page_content %}
|
||||
<div id="auditContent">
|
||||
{% include 'audit/inner.html.j2' %}
|
||||
</div>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="dark">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
@ -9,25 +9,21 @@
|
||||
{% include 'base/partials/stylesheets.html.j2' %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body class="bg-gray-50 text-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>
|
||||
<body class="bg-gray-50 text-gray-900 dark:bg-gray-900 min-h-screen flex flex-col">
|
||||
|
||||
<!-- Layout Container -->
|
||||
<div class="flex flex-1 h-full overflow-hidden">
|
||||
|
||||
<!-- 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" %}
|
||||
</aside>
|
||||
<!-- Main Panel -->
|
||||
<div class="flex-1 flex flex-col overflow-hidden">
|
||||
|
||||
<!-- 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" %}
|
||||
</header>
|
||||
|
||||
@ -35,7 +31,7 @@
|
||||
<main id="content" class="flex-1 overflow-y-auto" hx-target="this" hx-swap="innerHTML">
|
||||
{% block breadcrumbs %}
|
||||
{% endblock %}
|
||||
<div class="p-4" id="maincontent">
|
||||
<div class="" id="maincontent">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</main>
|
||||
@ -43,8 +39,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
{% include 'base/partials/scripts.html.j2' %}
|
||||
{% endblock %}
|
||||
{% block local_scripts %}
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -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 %}
|
||||
@ -1,20 +1,19 @@
|
||||
{% extends "/base/base.html.j2" %}
|
||||
|
||||
{% block title %}{{ title or "Page" }}{% endblock %}
|
||||
|
||||
{% 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">
|
||||
|
||||
<sl-breadcrumb>
|
||||
<sl-breadcrumb id="breadcrumbs">
|
||||
<sl-breadcrumb-item>
|
||||
<sl-icon slot="prefix" name="house"></sl-icon>
|
||||
<a href="/">Home</a>
|
||||
</sl-breadcrumb-item>
|
||||
{% if breadcrumbs %}
|
||||
{% for label, url in breadcrumbs %}
|
||||
<sl-breadcrumb-item>
|
||||
<sl-breadcrumb-item class="page-breadcrumb">
|
||||
{% if url %}
|
||||
<a href="{{url}}">{{label}}</a>
|
||||
{% else %}
|
||||
@ -32,7 +31,7 @@
|
||||
<!-- Breadcrumbs -->
|
||||
|
||||
<!-- Page Content -->
|
||||
<section>
|
||||
<section class="bg-white dark:bg-gray-800">
|
||||
{% block page_content %}
|
||||
<p>This is a generic page.</p>
|
||||
{% endblock %}
|
||||
|
||||
@ -15,18 +15,9 @@
|
||||
</button>
|
||||
|
||||
<!-- Page title or logo -->
|
||||
<a href="/" class="flex ml-2 md:mr-24">
|
||||
<img
|
||||
src="{{ url_for('static', path='logo.svg') }}"
|
||||
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>
|
||||
|
||||
{% if page_title %}
|
||||
<h1 class="text-xl flex ml-2 md:mr-24 font-semibold text-gray-900 sm:text-2xl dark:text-white">{{page_title}}</h1>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Right: User menu -->
|
||||
|
||||
@ -3,8 +3,9 @@
|
||||
<!-- Top: Brand -->
|
||||
<div class="px-4 py-6">
|
||||
|
||||
<a href="/" class="text-xl font-semibold text-gray-800">
|
||||
🐚 Sshecret
|
||||
<a href="/" class="text-xl font-semibold text-gray-800 dark:text-gray-100">
|
||||
<sl-icon src="{{ url_for('static', path='logo.svg') }}"></sl-icon>
|
||||
Sshecret
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -12,28 +13,28 @@
|
||||
<ul class="space-y-">
|
||||
|
||||
<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>
|
||||
Dashboard
|
||||
</a>
|
||||
</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>
|
||||
Clients
|
||||
</a>
|
||||
</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>
|
||||
Secrets
|
||||
</a>
|
||||
</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>
|
||||
Audit Log
|
||||
</a>
|
||||
|
||||
@ -35,3 +35,16 @@
|
||||
href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.20.1/cdn/themes/dark.css"
|
||||
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>
|
||||
|
||||
@ -1,5 +1,9 @@
|
||||
{% 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 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">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">
|
||||
Change Password
|
||||
|
||||
@ -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">
|
||||
<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>
|
||||
@ -9,4 +12,4 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
{% endblock %}
|
||||
|
||||
@ -1,46 +1,24 @@
|
||||
{% extends "/dashboard/_base.html" %} {% block content %}
|
||||
<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">
|
||||
<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>
|
||||
{% extends 'base/master-detail-email.html.j2' %}
|
||||
{% block title %}Client {{ client.name }}{% endblock %}
|
||||
|
||||
|
||||
</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">
|
||||
{% block master %}
|
||||
{% include '/clients/partials/tree.html.j2' %}
|
||||
</div>
|
||||
<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">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block detail %}
|
||||
|
||||
<div id="clientdetails" class="w-full">
|
||||
{% include '/clients/partials/client_details.html.j2' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% include '/clients/partials/drawer_create.html.j2' %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% include '/clients/partials/drawer_create.html.j2' %}
|
||||
{% block local_scripts %}
|
||||
<script>
|
||||
{% include '/clients/partials/tree_event.js' %}
|
||||
</script>
|
||||
{% endblock local_scripts %}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,41 +1,21 @@
|
||||
{% extends "/dashboard/_base.html" %} {% block content %}
|
||||
<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">
|
||||
<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>
|
||||
{% extends 'base/master-detail-email.html.j2' %}
|
||||
{% block title %}Clients{% endblock %}
|
||||
|
||||
<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>
|
||||
</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">
|
||||
{% block master %}
|
||||
{% include '/clients/partials/tree.html.j2' %}
|
||||
</div>
|
||||
<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">
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% 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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% include '/clients/partials/drawer_create.html.j2' %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block local_scripts %}
|
||||
<script>
|
||||
{% include '/clients/partials/tree_event.js' %}
|
||||
</script>
|
||||
{% endblock local_scripts %}
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
</ul>
|
||||
</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="events">Events</sl-tab>
|
||||
|
||||
@ -47,37 +47,37 @@
|
||||
<div id="client_details">
|
||||
<div class="w-full p-2">
|
||||
<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 %}
|
||||
<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 %}
|
||||
</div>
|
||||
<div class="mt-6 border-t border-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">
|
||||
<dt class="text-sm/6 font-medium text-gray-900">Client ID</dt>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.id}}</dd>
|
||||
<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 dark:text-gray-300">{{client.id}}</dd>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.description}}</dd>
|
||||
<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 dark:text-gray-300">{{client.description}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.version}}</dd>
|
||||
<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 dark:text-gray-300">{{client.version}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0 truncate">{{client.public_key}}</dd>
|
||||
<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 dark:text-gray-300 truncate">{{client.public_key}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.secrets|length}}</dd>
|
||||
<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 dark:text-gray-300">{{client.secrets|length}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm/6 text-gray-700 sm:col-span-2 sm:mt-0">{{client.policies|join(', ')}}</dd>
|
||||
<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 dark:text-gray-300">{{client.policies|join(', ')}}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
@ -86,7 +86,7 @@
|
||||
</sl-tab-panel>
|
||||
<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">
|
||||
<tr>
|
||||
<th scope="col" class="p-4 text-xs font-medium tracking-wider text-left text-gray-500 uppercase dark:text-white">Timestamp</th>
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
<div class="flex flex-1 flex-col justify-between h-full flowbite-init-target">
|
||||
<div class="grid grid-cols-2 place-content-between mb-6">
|
||||
<div>
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Clients</h1>
|
||||
{# This is the master block #}
|
||||
|
||||
<div class="flowbite-init-target">
|
||||
<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="htmx-indicator mt-2"
|
||||
@ -14,10 +15,8 @@
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-end px-4"
|
||||
class="flex w-full justify-end"
|
||||
>
|
||||
<sl-icon-button
|
||||
name="plus-square"
|
||||
@ -31,8 +30,8 @@
|
||||
></sl-icon-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-1 overflow-auto">
|
||||
<div class="relative w-full ">
|
||||
<div class="col-span-full">
|
||||
<div class="relative">
|
||||
<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>
|
||||
<div class="relative">
|
||||
@ -56,12 +55,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="client-tree-items">
|
||||
{% include '/clients/partials/tree_items.html.j2' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
{% include '/clients/partials/tree_event.js' %}
|
||||
</script>
|
||||
|
||||
@ -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() {
|
||||
const tree = document.querySelector("sl-tree");
|
||||
|
||||
@ -8,6 +21,8 @@ function addTreeListener() {
|
||||
|
||||
if (!selectedEl) return;
|
||||
|
||||
const masterPane = document.getElementById("master-pane");
|
||||
const detailPane = document.getElementById("detail-pane");
|
||||
const type = selectedEl.dataset.nodeType;
|
||||
const clientId = selectedEl.dataset.clientId;
|
||||
const name = selectedEl.dataset.clientName;
|
||||
@ -17,10 +32,16 @@ function addTreeListener() {
|
||||
|
||||
let url = `/clients/client/${encodeURIComponent(clientId)}`;
|
||||
if (url) {
|
||||
htmx.ajax("GET", url, {
|
||||
htmx
|
||||
.ajax("GET", url, {
|
||||
target: "#clientdetails",
|
||||
//swap: 'OuterHTML',
|
||||
indicator: "#client-spinner",
|
||||
})
|
||||
.then(() => {
|
||||
masterPane.classList.add("hidden");
|
||||
detailPane.classList.remove("hidden");
|
||||
setBreadcrumb(name);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -38,5 +38,4 @@
|
||||
{% include 'clients/partials/pagination.html.j2' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
@ -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
|
||||
@ -88,7 +88,5 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
{% endif %} {% endblock %}
|
||||
</div>
|
||||
|
||||
@ -47,36 +47,15 @@
|
||||
{% 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">
|
||||
<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">
|
||||
{% block title %}Secrets{% endblock %}
|
||||
|
||||
|
||||
<div class="flex flex-1 flex-col">
|
||||
<div class="h-full w-full">
|
||||
{% block master %}
|
||||
|
||||
<div class="flowbite-init-target">
|
||||
<div id="secret-tree">
|
||||
<sl-tree class="tree-with-icons">
|
||||
<sl-tree-item
|
||||
id="secret-group-root-item"
|
||||
@ -101,10 +80,11 @@
|
||||
{% endfor %}
|
||||
</sl-tree>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<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">
|
||||
{% endblock %}
|
||||
|
||||
{% block detail %}
|
||||
{% if group_page | default(false) %}
|
||||
<div class="w-full" id="secretdetails">
|
||||
{% include '/secrets/partials/group_detail.html.j2' %}
|
||||
@ -121,11 +101,13 @@
|
||||
{% include '/secrets/partials/default_detail.html.j2' %}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block local_scripts %}
|
||||
<script>
|
||||
{% include '/secrets/partials/tree_event.js' %}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
|
||||
@ -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">
|
||||
{% include '/secrets/partials/client_list_inner.html.j2' %}
|
||||
</ul>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="w-full">
|
||||
<div class="w-full dark:text-white">
|
||||
<sl-details summary="Create secret">
|
||||
<form
|
||||
hx-post="/secrets/create/root"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div class="w-full">
|
||||
<div class="w-full dark:text-white">
|
||||
<div class="mb-4">
|
||||
<h3 class="text-xl font-semibold dark:text-white">Group {{group.group_name}}</h3>
|
||||
{% if description %}
|
||||
|
||||
@ -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">
|
||||
<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">
|
||||
@ -27,7 +27,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<h3 class="mb-4 text-xl font-semibold dark:text-white">{{secret.name}}</h3>
|
||||
@ -110,8 +110,8 @@
|
||||
</form>
|
||||
</sl-details>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<sl-details summary="Events">
|
||||
{% endif %}
|
||||
<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">
|
||||
<thead class="bg-gray-50 dark:bg-gray-700">
|
||||
<tr>
|
||||
|
||||
@ -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();
|
||||
});
|
||||
|
||||
@ -42,6 +42,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
page=page, limit=per_page, total=audit_log.total, offset=offset
|
||||
)
|
||||
operations = list(Operation)
|
||||
breadcrumbs = [("Audit", "/audit/")]
|
||||
if request.headers.get("HX-Request"):
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
@ -56,7 +57,8 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
request,
|
||||
"audit/index.html.j2",
|
||||
{
|
||||
"page_title": "Audit",
|
||||
"page_title": "Audit Log",
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"entries": audit_log.results,
|
||||
"user": current_user,
|
||||
"page_info": page_info,
|
||||
|
||||
@ -93,42 +93,14 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
page=page, limit=per_page, total=results.total_results, offset=offset
|
||||
)
|
||||
|
||||
breadcrumbs = [("clients", "/clients/")]
|
||||
|
||||
LOG.info("Results %r", results)
|
||||
return templates.TemplateResponse(
|
||||
request,
|
||||
"clients/index.html.j2",
|
||||
{
|
||||
"page_title": "Clients",
|
||||
"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",
|
||||
{
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"page_title": "Clients",
|
||||
"offset": offset,
|
||||
"pages": paginate,
|
||||
@ -197,6 +169,11 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
)
|
||||
template = "clients/client.html.j2"
|
||||
|
||||
breadcrumbs = [
|
||||
("clients", "/clients/"),
|
||||
(results.client.name, request.url.path),
|
||||
]
|
||||
|
||||
headers: dict[str, str] = {}
|
||||
if request.headers.get("HX-Request"):
|
||||
headers["HX-Push-Url"] = request.url.path
|
||||
@ -207,6 +184,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
template,
|
||||
{
|
||||
"page_title": f"Client {results.client.name}",
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"pages": results.pages,
|
||||
"clients": results.results.clients,
|
||||
"client": results.client,
|
||||
|
||||
@ -81,7 +81,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
request,
|
||||
"dashboard.html",
|
||||
{
|
||||
"page_title": "sshecret",
|
||||
"page_title": "Dashboard",
|
||||
"user": current_user,
|
||||
"stats": stats,
|
||||
"last_login_events": last_login_events,
|
||||
|
||||
@ -63,12 +63,15 @@ 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",
|
||||
{
|
||||
"page_title": "Secrets",
|
||||
"groups": groups,
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"user": current_user,
|
||||
"selected_group": None,
|
||||
"group_path_nodes": ["/"],
|
||||
@ -83,8 +86,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] = {}
|
||||
@ -95,6 +105,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
else:
|
||||
groups = await admin.get_secret_groups()
|
||||
template_name = "secrets/index.html.j2"
|
||||
context["page_title"] = "Secrets"
|
||||
context["user"] = current_user
|
||||
context["groups"] = groups
|
||||
context["group_path_nodes"] = ["/"]
|
||||
@ -119,11 +130,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.
|
||||
@ -133,6 +153,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
template_name = "secrets/index.html.j2"
|
||||
|
||||
groups = await admin.get_secret_groups()
|
||||
context["page_title"] = "Secrets"
|
||||
context["user"] = current_user
|
||||
context["groups"] = groups
|
||||
context["group_path_nodes"] = group.path.split("/")
|
||||
@ -180,6 +201,7 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
|
||||
group_path = group.path.split("/")
|
||||
|
||||
template_name = "secrets/index.html.j2"
|
||||
context["page_title"] = "Secrets"
|
||||
context["user"] = current_user
|
||||
context["groups"] = groups
|
||||
context["group_path_nodes"] = group_path
|
||||
|
||||
@ -382,9 +382,6 @@
|
||||
.order-1 {
|
||||
order: 1;
|
||||
}
|
||||
.order-2 {
|
||||
order: 2;
|
||||
}
|
||||
.col-span-2 {
|
||||
grid-column: span 2 / span 2;
|
||||
}
|
||||
@ -457,9 +454,6 @@
|
||||
.ms-3 {
|
||||
margin-inline-start: calc(var(--spacing) * 3);
|
||||
}
|
||||
.ms-auto {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
.me-2 {
|
||||
margin-inline-end: calc(var(--spacing) * 2);
|
||||
}
|
||||
@ -682,15 +676,18 @@
|
||||
.h-\[12px\] {
|
||||
height: 12px;
|
||||
}
|
||||
.h-\[16px\] {
|
||||
height: 16px;
|
||||
}
|
||||
.h-\[32px\] {
|
||||
height: 32px;
|
||||
}
|
||||
.h-\[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 {
|
||||
height: 100%;
|
||||
}
|
||||
@ -1245,9 +1242,6 @@
|
||||
.border-blue-300 {
|
||||
border-color: var(--color-blue-300);
|
||||
}
|
||||
.border-blue-700 {
|
||||
border-color: var(--color-blue-700);
|
||||
}
|
||||
.border-gray-100 {
|
||||
border-color: var(--color-gray-100);
|
||||
}
|
||||
@ -1332,9 +1326,6 @@
|
||||
.bg-blue-600 {
|
||||
background-color: var(--color-blue-600);
|
||||
}
|
||||
.bg-blue-700 {
|
||||
background-color: var(--color-blue-700);
|
||||
}
|
||||
.bg-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 {
|
||||
@media (hover: hover) {
|
||||
@ -2774,11 +2758,6 @@
|
||||
inset: calc(var(--spacing) * 0);
|
||||
}
|
||||
}
|
||||
.md\:order-1 {
|
||||
@media (width >= 48rem) {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
.md\:order-2 {
|
||||
@media (width >= 48rem) {
|
||||
order: 2;
|
||||
@ -2859,6 +2838,16 @@
|
||||
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\)\] {
|
||||
@media (width >= 48rem) {
|
||||
width: calc(100% - 256px);
|
||||
@ -3114,6 +3103,11 @@
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
.lg\:table-fixed {
|
||||
@media (width >= 64rem) {
|
||||
table-layout: fixed;
|
||||
}
|
||||
}
|
||||
.lg\:grid-cols-2 {
|
||||
@media (width >= 64rem) {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@ -3469,11 +3463,6 @@
|
||||
border-color: var(--color-red-800);
|
||||
}
|
||||
}
|
||||
.dark\:bg-blue-600 {
|
||||
&:where(.dark, .dark *) {
|
||||
background-color: var(--color-blue-600);
|
||||
}
|
||||
}
|
||||
.dark\:bg-blue-900 {
|
||||
&:where(.dark, .dark *) {
|
||||
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 {
|
||||
&:where(.dark, .dark *) {
|
||||
&:hover {
|
||||
|
||||
@ -19,3 +19,11 @@ sl-details.small-details::part(header) {
|
||||
sl-details.small-details::part(base) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user