Create views for organizing secrets in groups
This commit is contained in:
@ -1,4 +1,36 @@
|
||||
{% macro display_entry(entry) %}
|
||||
<sl-tree-item
|
||||
id="entry_{{ entry.name }}"
|
||||
class="tree-entry-item"
|
||||
data-type="entry"
|
||||
data-name="{{ entry.name }}"
|
||||
>
|
||||
<sl-icon name="shield"> </sl-icon>
|
||||
<span class="px-2">{{ entry.name }}</span>
|
||||
</sl-tree-item>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro display_group(group) %}
|
||||
<sl-tree-item
|
||||
class="secret-group-list-item"
|
||||
data-type="group"
|
||||
data-name="{{ group.group_name }}"
|
||||
>
|
||||
<sl-icon name="folder"> </sl-icon>
|
||||
<span class="px-2">{{ group.group_name }}</span>
|
||||
{% for entry in group.entries %}
|
||||
{{ display_entry(entry) }}
|
||||
{% endfor %}
|
||||
{% for child in group.children %}
|
||||
{{ display_group(child) }}
|
||||
{% endfor %}
|
||||
</sl-tree-item>
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% 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">
|
||||
@ -14,7 +46,6 @@
|
||||
<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>
|
||||
</svg>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
@ -22,24 +53,73 @@
|
||||
<h1 class="text-xl font-semibold text-gray-900 sm:text-2xl dark:text-white">Secrets</h1>
|
||||
</div>
|
||||
|
||||
<div class="items-center justify-between block sm:flex">
|
||||
<div class="flex items-center mb-4 sm:mb-0">
|
||||
<label for="secret-search" class="sr-only">Search</label>
|
||||
<div class="relative w-48 mt-1 sm:w-64 xl:w-96">
|
||||
<input type="search" name="query" id="secret-search" class="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" placeholder="Search for secrets" hx-post="/secrets/query" hx-trigger="keyup changed delay:500ms, query" hx-target="#secretsContent">
|
||||
</div>
|
||||
</div>
|
||||
<button id="createSecretButton" class="text-white bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 dark:bg-primary-600 dark:hover:bg-primary-700 focus:outline-none dark:focus:ring-primary-800" type="button" data-drawer-target="drawer-create-secret-default" data-drawer-show="drawer-create-secret-default" aria-controls="drawer-create-secret-default" data-drawer-placement="right">
|
||||
Add new secret
|
||||
</button>
|
||||
</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-col">
|
||||
<div class="h-full">
|
||||
<sl-tree class="tree-with-icons">
|
||||
<sl-tree-item
|
||||
id="secret-group-root-item"
|
||||
data-type="root"
|
||||
data-name="root"
|
||||
expanded=""
|
||||
>
|
||||
<sl-icon name="folder"> </sl-icon>
|
||||
<span class="px-2">Ungrouped</span>
|
||||
{% for entry in groups.ungrouped %}
|
||||
{{ display_entry(entry) }}
|
||||
{% endfor %}
|
||||
</sl-tree-item>
|
||||
{% for child in groups.groups %}
|
||||
{{ display_group(child) }}
|
||||
{% endfor %}
|
||||
</sl-tree>
|
||||
</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">
|
||||
{% include '/secrets/partials/default_detail.html.j2' %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="secretsContent">
|
||||
{% include '/secrets/inner.html.j2' %}
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const tree = document.querySelector('sl-tree');
|
||||
|
||||
{% include '/secrets/drawer_secret_create.html.j2' %}
|
||||
if (!tree) return;
|
||||
|
||||
tree.addEventListener('sl-selection-change', (event) => {
|
||||
const selectedEl = event.detail.selection[0];
|
||||
|
||||
if (!selectedEl) return;
|
||||
|
||||
const type = selectedEl.dataset.type;
|
||||
const name = selectedEl.dataset.name;
|
||||
console.log(`Event on ${type} ${name}`);
|
||||
|
||||
if (!type || !name) return;
|
||||
|
||||
let url = '';
|
||||
if (type === 'entry') {
|
||||
url = `/secrets/partial/secret/${encodeURIComponent(name)}`;
|
||||
} else if (type === 'group') {
|
||||
url = `/secrets/partial/group/${encodeURIComponent(name)}`;
|
||||
} else if (type == 'root') {
|
||||
url = `/secrets/partial/root_group`;
|
||||
}
|
||||
|
||||
if (url) {
|
||||
htmx.ajax('GET', url, {
|
||||
target: '#secretdetails',
|
||||
swap: 'OuterHTML',
|
||||
indicator: '.secret-spinner'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user