CSS/styles fixes

Signed-off-by: apeters <apeters@korves.net>
This commit is contained in:
apeters 2025-05-21 09:53:05 +00:00
parent f38132c4f3
commit ee1f3e59b5
11 changed files with 166 additions and 126 deletions

View File

@ -60,6 +60,7 @@ async def user_profile_patch():
response_code=204, response_code=204,
title="Profile updated", title="Profile updated",
message="Your profile was updated", message="Your profile was updated",
additional_triggers={"profileUpdate": session["profile"]["tresor"]},
) )

View File

@ -3188,17 +3188,17 @@ dialog article {
margin: calc(var(--pico-spacing) / 2) auto; margin: calc(var(--pico-spacing) / 2) auto;
} }
.grid-3-cols { .grid-auto-cols {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(5, 1fr);
gap: calc(var(--pico-spacing) / 2); gap: calc(var(--pico-spacing) / 2);
} }
.grid-3-cols .span-3 { .grid-auto-cols .grid-span-all {
grid-column: span 3; grid-column: 1/-1;
} }
.grid-3-cols > article { .grid-auto-cols > article {
margin-bottom: 0; margin-bottom: 0;
padding-bottom: var(--pico-form-element-spacing-vertical); padding-bottom: var(--pico-form-element-spacing-vertical);
--pico-border-radius: .5rem; --pico-border-radius: .5rem;
@ -3220,28 +3220,6 @@ fieldset.vault-unlock {
padding: var(--pico-spacing) 0; padding: var(--pico-spacing) 0;
} }
@media only screen and (max-width: 600px) {
#notification-container {
left: 0;
bottom: 0;
width: 100%;
}
dialog article {
max-width: 95%;
}
.grid-3-cols {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: calc(var(--pico-spacing) / 2);
}
.grid-3-cols .span-3 {
grid-column: span 1;
}
.grid-3-cols > article {
margin-bottom: 0;
--pico-border-radius: .5rem;
}
}
@media (max-width: 1024px) { @media (max-width: 1024px) {
.split-grid.grid { .split-grid.grid {
gap: calc(var(--pico-spacing) / 2); gap: calc(var(--pico-spacing) / 2);
@ -3251,11 +3229,46 @@ fieldset.vault-unlock {
background-color: transparent; background-color: transparent;
box-shadow: none; box-shadow: none;
} }
.grid-auto-cols {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: calc(var(--pico-spacing) / 2);
}
.grid-auto-cols .grid-span-all {
grid-column: 1/-1;
}
.grid-auto-cols > article {
margin-bottom: 0;
padding-bottom: var(--pico-form-element-spacing-vertical);
--pico-border-radius: .5rem;
}
th, td { th, td {
--pico-spacing: 0.75rem; --pico-spacing: 0.75rem;
} }
} }
.group { @media only screen and (max-width: 576px) {
#notification-container {
left: 0;
bottom: 0;
width: 100%;
}
dialog article {
max-width: 95%;
}
.grid-auto-cols {
display: grid;
grid-template-columns: repeat(1, 1fr);
gap: calc(var(--pico-spacing) / 2);
}
.grid-auto-cols .grid-span-all {
grid-column: 1/-1;
}
.grid-auto-cols > article {
margin-bottom: 0;
--pico-border-radius: .5rem;
}
}
.user-group {
opacity: 0; opacity: 0;
} }
@ -3269,7 +3282,7 @@ fieldset.system-field label:before {
content: "🔒 "; content: "🔒 ";
} }
fieldset.keypair { fieldset.keypair, fieldset.tresor {
border: 1px solid var(--pico-form-element-border-color); border: 1px solid var(--pico-form-element-border-color);
padding: var(--pico-spacing); padding: var(--pico-spacing);
} }

View File

@ -98,6 +98,10 @@
--pico-line-height: 1.4; --pico-line-height: 1.4;
} }
$sm-breakpoint: map-get(map-get($breakpoints, sm), breakpoint);
$md-breakpoint: map-get(map-get($breakpoints, md), breakpoint);
$lg-breakpoint: map-get(map-get($breakpoints, lg), breakpoint);
small { small {
font-size: .875rem; font-size: .875rem;
color: var(--pico-muted-color); color: var(--pico-muted-color);
@ -312,20 +316,21 @@ dialog article {
justify-content: space-between; justify-content: space-between;
grid-auto-columns: max-content; grid-auto-columns: max-content;
grid-auto-flow: column; grid-auto-flow: column;
gap: calc(var(--pico-spacing) /2); gap: calc(var(--pico-spacing)/2);
white-space: nowrap; white-space: nowrap;
align-items: baseline; align-items: baseline;
margin: calc(var(--pico-spacing) /2) auto; margin: calc(var(--pico-spacing) /2) auto;
} }
.grid-3-cols {
.grid-auto-cols {
display: grid; display: grid;
grid-template-columns: repeat(3, 1fr); grid-template-columns: repeat(5, 1fr);
gap: calc(var(--pico-spacing) /2); gap: calc(var(--pico-spacing)/2);
} }
.grid-3-cols .span-3 { .grid-auto-cols .grid-span-all {
grid-column: span 3; grid-column: 1 / -1;
} }
.grid-3-cols > article { .grid-auto-cols > article {
margin-bottom: 0; margin-bottom: 0;
padding-bottom: var(--pico-form-element-spacing-vertical); padding-bottom: var(--pico-form-element-spacing-vertical);
--pico-border-radius: .5rem; --pico-border-radius: .5rem;
@ -347,7 +352,37 @@ fieldset.vault-unlock {
padding: var(--pico-spacing) 0; padding: var(--pico-spacing) 0;
} }
@media only screen and (max-width: 600px) { article.user-group {
}
@media (max-width: $lg-breakpoint) {
.split-grid.grid {
gap: calc(var(--pico-spacing)/2);
}
.split-grid.grid > article {
padding: 0;
background-color: transparent;
box-shadow: none;
}
.grid-auto-cols {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: calc(var(--pico-spacing)/2);
}
.grid-auto-cols .grid-span-all {
grid-column: 1 / -1;
}
.grid-auto-cols > article {
margin-bottom: 0;
padding-bottom: var(--pico-form-element-spacing-vertical);
--pico-border-radius: .5rem;
}
th, td {
--pico-spacing: 0.75rem;
}
}
@media only screen and (max-width: $sm-breakpoint) {
#notification-container { #notification-container {
left: 0; left: 0;
bottom: 0; bottom: 0;
@ -356,35 +391,21 @@ fieldset.vault-unlock {
dialog article { dialog article {
max-width: 95%; max-width: 95%;
} }
.grid-3-cols { .grid-auto-cols {
display: grid; display: grid;
grid-template-columns: repeat(1, 1fr); grid-template-columns: repeat(1, 1fr);
gap: calc(var(--pico-spacing)/2); gap: calc(var(--pico-spacing)/2);
} }
.grid-3-cols .span-3 { .grid-auto-cols .grid-span-all {
grid-column: span 1; grid-column: 1 / -1;
} }
.grid-3-cols > article { .grid-auto-cols > article {
margin-bottom: 0; margin-bottom: 0;
--pico-border-radius: .5rem; --pico-border-radius: .5rem;
} }
} }
@media (max-width: 1024px) {
.split-grid.grid {
gap: calc(var(--pico-spacing) /2);
}
.split-grid.grid > article {
padding: 0;
background-color: transparent;
box-shadow: none;
}
th, td { .user-group {
--pico-spacing: 0.75rem;
}
}
.group {
opacity: 0; opacity: 0;
} }
@ -398,7 +419,7 @@ fieldset.system-field label:before {
content:"\1f512\0020"; content:"\1f512\0020";
} }
fieldset.keypair { fieldset.keypair, fieldset.tresor {
border: 1px solid var(--pico-form-element-border-color); border: 1px solid var(--pico-form-element-border-color);
padding: var(--pico-spacing); padding: var(--pico-spacing);
} }

View File

@ -178,6 +178,11 @@ behavior tresorToggle
end end
end end
end end
on profileUpdate from body
exit unless #vault-unlock's @data-tresor == ""
set #vault-unlock's @data-tresor to (value of event.detail)
call setLocked()
end
on keydown[keyCode == 13] from #vault-unlock-pin on keydown[keyCode == 13] from #vault-unlock-pin
trigger click on #vault-unlock unless #vault-unlock-pin's value is empty trigger click on #vault-unlock unless #vault-unlock-pin's value is empty
end end

View File

@ -60,7 +60,7 @@ DATA FIELDS
{% elif v.type == "tresor" %} {% elif v.type == "tresor" %}
{% if request.path == "/profile/" %} {% if request.path == "/profile/" %}
<fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %} class="keypair"> <fieldset data-loading-disable {% if k in system_fields and not "system" in session["acl"] %}class="system-field" disabled{% endif %} class="tresor">
<label>{{ v.title }}</label> <label>{{ v.title }}</label>
<input id="{{ v.form_id }}" type="hidden" {{ v.input_extra|safe }} <input id="{{ v.form_id }}" type="hidden" {{ v.input_extra|safe }}
name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}" name="{% if root_key %}{{ root_key }}.{{ k }}{% else %}{{ k }}{% endif %}"
@ -82,7 +82,7 @@ DATA FIELDS
call VaultSetupUserCryptoAndSend(value of #{{ v.form_id }}-password) call VaultSetupUserCryptoAndSend(value of #{{ v.form_id }}-password)
set value of #{{ v.form_id }} to (result as JSON) set value of #{{ v.form_id }} to (result as JSON)
call window.vault.lock() call window.vault.lock()
add @disabled to <input[type=password]/> in closest <fieldset/> add @disabled to <input[type=password]/> in closest .tresor
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)"> on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">
Setup encryption Setup encryption
@ -112,7 +112,7 @@ DATA FIELDS
call VaultChangePassword(value of #old-{{ v.form_id }}, value of #new-{{ v.form_id }}, keyData) call VaultChangePassword(value of #old-{{ v.form_id }}, value of #new-{{ v.form_id }}, keyData)
call window.vault.exportPayload() call window.vault.exportPayload()
set value of #{{ v.form_id }} to (result as JSON) set value of #{{ v.form_id }} to (result as JSON)
add @disabled to closest <fieldset/> add @disabled to closest .tresor
if not previousLock call window.vault.lock() end if not previousLock call window.vault.lock() end
put '<mark>Pending</mark> - please save changes to apply.' after me then remove me put '<mark>Pending</mark> - please save changes to apply.' after me then remove me
on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)"> on exception(error) trigger notification(level: 'error', title: 'Tresor error', message: error, duration: 3000)">

View File

@ -145,7 +145,7 @@
{% if session["login"] %} {% if session["login"] %}
<section> <section>
<hr> <hr>
<fieldset _="install tresorToggle" role="group" class="" {{ "disabled" if not session.profile.tresor }}> <fieldset _="install tresorToggle" role="group">
<input hx-disable <input hx-disable
id="vault-unlock-pin" id="vault-unlock-pin"
name="vault-unlock-pin" name="vault-unlock-pin"

View File

@ -1,5 +1,5 @@
<article id="profile-authenticators"> <article id="profile-authenticators">
<h6>Authenticators</h6> <h5>Passkeys</h5>
<p>The authenticator that started the session is indicated as active.</p> <p>The authenticator that started the session is indicated as active.</p>
<div class="overflow-auto"> <div class="overflow-auto">
<table> <table>

View File

@ -13,21 +13,19 @@
{% block body %} {% block body %}
<article hx-trigger="htmx:afterRequest[event.detail.successful==true] from:#profile-form" hx-select="#profile-form" hx-get="/profile/" hx-target="#profile-form"> <h4>Your data</h4>
<h6>Profile data</h6>
<form hx-trigger="submit throttle:1s" hx-patch="/profile/edit" id="profile-form">
<article hx-trigger="htmx:afterRequest[event.detail.successful==true] from:#profile-form" hx-select="#profile-form" hx-get="/profile/" hx-target="#profile-form">
<h5>Profile</h5>
<form hx-trigger="submit throttle:1s" hx-patch="/profile/edit" id="profile-form">
{% with {% with
schema=schemas.user_profile, schema=schemas.user_profile,
current_data=data.user.profile current_data=data.user.profile
%} %}
{% include "includes/form_builder.html" %} {% include "includes/form_builder.html" %}
{% endwith %} {% endwith %}
<button data-loading-disable data-loading-aria-busy type="submit">Save changes</button> <button data-loading-disable data-loading-aria-busy type="submit">Save changes</button>
</form> </form>
</article> </article>
{% include "profile/includes/credentials.html" %} {% include "profile/includes/credentials.html" %}

View File

@ -12,24 +12,23 @@
<script type="text/hyperscript"> <script type="text/hyperscript">
on load 1 on load 1
set $names to [] set $names to value of <#user-groups [name=name]/> as Array
{% for group, members in groups_dict.items() %} {% for group, members in groups_dict.items() %}
if $names does not contain "{{- group -}}" if $names does not contain "{{- group -}}"
append "{{- group -}}" to $names append "{{- group -}}" to $names
render #group-template with (name: "{{- group -}}", members: {{ members|list|tojson }}) render #group-template with (name: "{{- group -}}", members: {{ members|list|tojson }})
put the result at the end of #user-groups put the result at the end of #user-groups
call htmx.process(#user-groups) call htmx.process(#user-groups)
add @hidden to .no-groups add @hidden to .no-user-groups
set .group's *opacity to 1 set .user-group's *opacity to 1
{% endfor %}
end end
{% endfor %}
end end
</script> </script>
<section> <section id="user-groups" class="grid-auto-cols"
<div id="user-groups" class="grid-3-cols"
_="on htmx:afterRequest[event.detail.successful==true] queue all _="on htmx:afterRequest[event.detail.successful==true] queue all
set group to closest .group to event.target set group to closest .user-group to event.target
set value of <[name=name]/> in group to value of <[name=new_name]/> in group set value of <[name=name]/> in group to value of <[name=new_name]/> in group
if <[name=members] option:checked/> in group is empty if <[name=members] option:checked/> in group is empty
add @hidden to group add @hidden to group
@ -37,23 +36,25 @@
remove group remove group
trigger deleteName trigger deleteName
else else
add @hidden to .group-unsaved in group add @hidden to .user-group-unsaved in group
end end
end end
on change on change
remove @hidden from .group-unsaved in closest .group to event.target remove @hidden from .user-group-unsaved in closest .user-group to event.target
end end
on deleteName on deleteName
set $names to value of <[name=name]/> as Array set $names to value of <#user-groups [name=name]/> as Array
end"> end">
<article class="span-3 no-groups" hidden>
There is no group assigned to any user.
</article>
</div>
</section> </section>
<p>
<mark class="no-user-groups" >
There is no group assigned to any user.
</mark>
</p>
<section> <section>
<form hx-disable _="on submit <form hx-disable _="on submit
halt the event halt the event
add @disabled to <fieldset/> in me add @disabled to <fieldset/> in me
if $names does not contain #group.value and #group.value is not empty if $names does not contain #group.value and #group.value is not empty
@ -61,8 +62,8 @@
render #group-template with (name: #group.value, members: []) render #group-template with (name: #group.value, members: [])
put the result at the end of #user-groups put the result at the end of #user-groups
call htmx.process(#user-groups) call htmx.process(#user-groups)
add @hidden to .no-groups add @hidden to .no-user-groups
transition .group's opacity to 1 over 175ms transition .user-group's opacity to 1 over 175ms
end end
remove @disabled from <fieldset/> in me remove @disabled from <fieldset/> in me
end"> end">
@ -70,12 +71,12 @@
<input autocomplete="off" id="group" name="group" type="text" placeholder="New group name" /> <input autocomplete="off" id="group" name="group" type="text" placeholder="New group name" />
<button type="submit">Create</button> <button type="submit">Create</button>
</fieldset> </fieldset>
</form> </form>
</section> </section>
<template id="group-template"> <template id="group-template">
@set hidden to "hidden" unless members is empty @set hidden to "hidden" unless members is empty
<article class="group"> <article class="user-group">
<form hx-patch="/system/users/groups"> <form hx-patch="/system/users/groups">
<input type="hidden" name="name" value="${name}"/> <input type="hidden" name="name" value="${name}"/>
<fieldset data-loading-disable> <fieldset data-loading-disable>
@ -97,15 +98,15 @@
{% endfor %} {% endfor %}
</select> </select>
</fieldset> </fieldset>
<small class="color-yellow-200 group-unsaved" ${hidden}>⚠️ unsaved</small> <small class="color-yellow-200 user-group-unsaved" ${hidden}>⚠️ unsaved</small>
<div class="grid-space-between"> <div class="grid-space-between">
<a href="#" _="install confirmButton <a href="#" _="install confirmButton
on confirmedButton on confirmedButton
set selectedIndex of <select/> in closest .group to -1 set selectedIndex of <select/> in closest .user-group to -1
trigger submit on closest <form/> trigger submit on closest <form/>
end">Remove</a> end">Remove</a>
<button data-loading-disable <button data-loading-disable
class="button-green group-unsaved" class="button-green user-group-unsaved"
${hidden} ${hidden}
type="submit"> type="submit">
Save Save

View File

@ -26,7 +26,7 @@
</h4> </h4>
<div id="system-status"> <div id="system-status">
<section id="system-status-cards" class="grid-3-cols"> <section id="system-status-cards" class="grid-auto-cols">
<article> <article>
<h5>{{ data.status.CLUSTER_PEERS_LOCAL.name }} 🏠</h5> <h5>{{ data.status.CLUSTER_PEERS_LOCAL.name }} 🏠</h5>
<p> <p>

View File

@ -13,17 +13,18 @@
{% block body %} {% block body %}
<details name="users-groups"> <h4>Users and groups</h4>
<summary role="button" class="button-slate-800">Manage Groups</summary>
<section id="system-groups">
{% include "system/includes/users/groups.html" %}
</section>
</details>
<hr /> <section>
<h5>Groups</h5>
{% include "system/includes/users/groups.html" %}
</section>
<hr>
<div class="grid split-grid"> <div class="grid split-grid">
<article id="system-users-full-table"> <article id="system-users-full-table">
<h5>Users</h5>
{% include "system/includes/users/table.html" %} {% include "system/includes/users/table.html" %}
</article> </article>
</div> </div>