Preserve history when navigating the secrets page

This commit is contained in:
2025-06-09 15:44:21 +02:00
parent d1fa6c0076
commit 43d00cecb4
4 changed files with 192 additions and 13 deletions

View File

@ -4,6 +4,12 @@
class="tree-entry-item"
data-type="entry"
data-name="{{ entry.name }}"
data-group-path="/"
{% if secret | default(false) %}
{% if secret.name == entry.name %}
selected=""
{% endif %}
{% endif %}
>
<sl-icon name="shield"> </sl-icon>
<span class="px-2">{{ entry.name }}</span>
@ -16,6 +22,13 @@
class="secret-group-list-item"
data-type="group"
data-name="{{ group.group_name }}"
data-group-path="{{ group.path }}"
{% if group_path_nodes | default(false) %}
{% if group.group_name in group_path_nodes %}
expanded=""
{% endif %}
{% endif %}
>
<sl-icon name="folder"> </sl-icon>
<span class="px-2">{{ group.group_name }}</span>
@ -81,7 +94,22 @@
</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' %}
{% if group_page | default(false) %}
<div class="w-full" id="secretdetails">
{% include '/secrets/partials/group_detail.html.j2' %}
</div>
{% elif root_group_page | default(false) %}
<div class="w-full" id="secretdetails">
{% include '/secrets/partials/edit_root.html.j2' %}
</div>
{% elif secret_page | default(false) %}
<div class="w-full" id="secretdetails">
{% include '/secrets/partials/tree_detail.html.j2' %}
</div>
{% else %}
{% include '/secrets/partials/default_detail.html.j2' %}
{% endif %}
</div>
</div>
</div>
@ -99,17 +127,19 @@
const type = selectedEl.dataset.type;
const name = selectedEl.dataset.name;
console.log(`Event on ${type} ${name}`);
const groupPath = selectedEl.dataset.groupPath;
console.log(`Event on ${type} ${name} path: ${groupPath}`);
if (!type || !name) return;
let url = '';
if (type === 'entry') {
url = `/secrets/partial/secret/${encodeURIComponent(name)}`;
url = `/secrets/secret/${encodeURIComponent(name)}`;
} else if (type === 'group') {
url = `/secrets/partial/group/${encodeURIComponent(name)}`;
//url = `/secrets/partial/group/${encodeURIComponent(name)}`;
url = `/secrets/group/${encodeURIComponent(groupPath)}`;
} else if (type == 'root') {
url = `/secrets/partial/root_group`;
url = `/secrets/group/`;
}
if (url) {

View File

@ -64,7 +64,6 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
):
groups = await admin.get_secret_groups()
LOG.info("Groups: %r", groups)
return templates.TemplateResponse(
request,
"secrets/index.html.j2",
@ -85,12 +84,13 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
request,
"secrets/partials/edit_root.html.j2",
{
"group_path_nodes": [],
"clients": clients,
},
)
@app.get("/secrets/partial/secret/{name}")
async def get_secret_tree_detail(
async def get_secret_tree_detail_partial(
request: Request,
name: str,
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
@ -114,6 +114,118 @@ def create_router(dependencies: FrontendDependencies) -> APIRouter:
},
)
@app.get("/secrets/group/")
async def show_root_group(
request: Request,
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
):
"""Show the root path."""
clients = await admin.get_clients()
context: dict[str, Any] = {
"clients": clients,
"root_group_page": True,
}
headers: dict[str, str] = {}
if request.headers.get("HX-Request"):
# This is a HTMX request.
template_name = "secrets/partials/edit_root.html.j2"
headers["HX-Push-Url"] = request.url.path
else:
groups = await admin.get_secret_groups()
template_name = "secrets/index.html.j2"
context["user"] = current_user
context["groups"] = groups
context["group_path_nodes"] = ["/"]
return templates.TemplateResponse(
request, template_name, context, headers=headers
)
@app.get("/secrets/group/{group_path:path}")
async def show_group(
request: Request,
group_path: str,
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
):
"""Show a group."""
group = await admin.get_secret_group_by_path(group_path)
if not group:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Group not found"
)
clients = await admin.get_clients()
headers: dict[str, str] = {}
context: dict[str, Any] = {
"group_page": True,
"name": group.group_name,
"description": group.description,
"clients": clients,
}
if request.headers.get("HX-Request"):
# This is a HTMX request.
template_name = "secrets/partials/group_detail.html.j2"
headers["HX-Push-Url"] = request.url.path
else:
template_name = "secrets/index.html.j2"
groups = await admin.get_secret_groups()
context["user"] = current_user
context["groups"] = groups
context["group_path_nodes"] = group.path.split("/")
return templates.TemplateResponse(
request, template_name, context, headers=headers
)
@app.get("/secrets/secret/{name}")
async def get_secret_tree_detail(
request: Request,
name: str,
admin: Annotated[AdminBackend, Depends(dependencies.get_admin_backend)],
current_user: Annotated[LocalUserInfo, Depends(dependencies.get_user_info)],
):
"""Get secret detail."""
secret = await admin.get_secret(name)
groups = await admin.get_secret_groups(flat=True)
events = await admin.get_audit_log_detailed(limit=10, secret_name=name)
if not secret:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND, detail="Secret not found"
)
context: dict[str, Any] = {
"secret": secret,
"groups": groups,
"events": events,
"secret_page": True,
}
headers: dict[str, str] = {}
if request.headers.get("HX-Request"):
# This is a HTMX request.
template_name = "secrets/partials/tree_detail.html.j2"
headers["HX-Push-Url"] = request.url.path
else:
group_path = ["/"]
if secret.group:
group = await admin.get_secret_group(secret.group)
if group:
group_path = group.path.split("/")
template_name = "secrets/index.html.j2"
context["user"] = current_user
context["groups"] = groups
context["group_path_nodes"] = group_path
return templates.TemplateResponse(
request, template_name, context, headers=headers
)
@app.get("/secrets/partial/group/{name}")
async def get_group_details(
request: Request,