From c0a82470ed75c7309f9eb2b9c468b03f69a9fb51 Mon Sep 17 00:00:00 2001 From: alexa Date: Fri, 31 May 2024 22:57:07 +0200 Subject: [PATCH] work on admin panel --- ui/base.css | 1 + ui/classes.css | 33 +++++++++++++++++++++++++++--- ui/components/common.mjs | 11 ++++++++++ ui/components/layout.mjs | 33 ++++++++++++++++++++---------- ui/components/pages/admin.mjs | 38 +++++++++++++---------------------- 5 files changed, 78 insertions(+), 38 deletions(-) diff --git a/ui/base.css b/ui/base.css index cb0293b..4e8ab78 100644 --- a/ui/base.css +++ b/ui/base.css @@ -19,6 +19,7 @@ --input-border-radius: 0.25rem; --input-border-width: 1px; --avatar-border-width: 2px; + --animation-time: 0.35s; } @media (prefers-color-scheme: light) { diff --git a/ui/classes.css b/ui/classes.css index 76eaedc..86e08bc 100644 --- a/ui/classes.css +++ b/ui/classes.css @@ -68,6 +68,7 @@ .icon { width: 1em; height: 1em; + transition: transform var(--animation-time) ease; } .highlight { @@ -170,7 +171,7 @@ align-self: end; } -.card, .main-card { +.card, .main-card, .small-card { padding: calc(var(--gap-v) * 2); background: var(--bg-2); border-radius: var(--input-border-radius); @@ -182,6 +183,10 @@ justify-content: space-between; } +.small-card { + padding: var(--gap-v); +} + .space-between { justify-content: space-between; } @@ -337,11 +342,33 @@ .collapsible { background: var(--bg-2); - padding: var(--gap-h) var(--gap-v); + padding: var(--gap-v); border-radius: var(--input-border-radius); border: var(--input-border-width) solid var(--bg-4); } .fixed { position: fixed; -} \ No newline at end of file +} + +.collapsible-content { + max-height: 0; + overflow: hidden; + transition: max-height var(--animation-time) ease-out; +} + +.rot0 { + transform: rotate(0deg); +} + +.rot90 { + transform: rotate(90deg); +} + +.rot180 { + transform: rotate(180deg); +} + +.rot270 { + transform: rotate(270deg); +} diff --git a/ui/components/common.mjs b/ui/components/common.mjs index 3af826e..24eb8db 100644 --- a/ui/components/common.mjs +++ b/ui/components/common.mjs @@ -305,4 +305,15 @@ export class CommonTemplates { .build() ).build(); } + + static smallCard(icon, text) { + return create("div") + .classes("small-card", "flex", "align-center") + .children( + CommonTemplates.icon(icon), + create("span") + .text(text) + .build() + ).build(); + } } \ No newline at end of file diff --git a/ui/components/layout.mjs b/ui/components/layout.mjs index 1cb6255..d6d51f8 100644 --- a/ui/components/layout.mjs +++ b/ui/components/layout.mjs @@ -91,29 +91,40 @@ export class LayoutTemplates { static collapsible(text, content) { const uniqueId = Math.random().toString(36).substring(7); const toggled = signal(false); - const icon = computedSignal(toggled, on => on ? "expand_circle_up" : "expand_circle_down"); - const display = computedSignal(toggled, on => on ? "block" : "none"); + const iconClass = computedSignal(toggled, on => on ? "rot90" : "rot0"); + const gapClass = computedSignal(toggled, v => v ? "gap" : "no-gap"); + let contentElement; + const setMaxHeight = () => { + if (toggled.value) { + contentElement.style.maxHeight = contentElement.scrollHeight + 'px'; + } else { + contentElement.style.maxHeight = '0'; + } + }; + + contentElement = create("div") + .classes("collapsible-content") + .id(uniqueId) + .children(content) + .build() return create("div") - .classes("collapsible", "flex-v") + .classes("collapsible", "flex-v", gapClass) .children( create("div") .classes("collapsible-header", "flex", "align-center") .onclick(() => { toggled.value = !toggled.value; - }).children( - CommonTemplates.icon(icon), + setMaxHeight(); + }) + .children( + CommonTemplates.icon("expand_circle_right", [iconClass]), create("span") .classes("collapsible-title") .text(text) .build() ).build(), - create("div") - .classes("collapsible-content") - .styles("display", display) - .id(uniqueId) - .children(content) - .build() + contentElement ).build(); } } \ No newline at end of file diff --git a/ui/components/pages/admin.mjs b/ui/components/pages/admin.mjs index 10bc4ff..9102e08 100644 --- a/ui/components/pages/admin.mjs +++ b/ui/components/pages/admin.mjs @@ -29,8 +29,7 @@ export class AdminComponent { create("h1") .text("Administration") .build(), - AdminComponent.roleList(user), - AdminComponent.permissionList(user), + AdminComponent.yourInfo(user), AdminComponent.usersSettings(permissions), AdminComponent.bridgeInstanceSettings(permissions) ).build() @@ -39,19 +38,24 @@ export class AdminComponent { ).build(); } - static roleList(user) { + static yourInfo(user) { const roles = signalFromProperty(user, 'roles'); + const permissions = signalFromProperty(user, 'permissions'); return create("div") .classes("flex-v", "card") .children( create("h2") - .text("Your Roles") + .text("Your Access as @" + user.value.username) .build(), - signalMap(roles, + LayoutTemplates.collapsible("Roles", signalMap(roles, + create("div") + .classes("flex"), + role => AdminComponent.role(role))), + LayoutTemplates.collapsible("Permissions", signalMap(permissions, create("div") .classes("flex"), - role => AdminComponent.role(role)), + permission => AdminComponent.permission(permission))) ).build(); } @@ -63,22 +67,6 @@ export class AdminComponent { .build(); } - static permissionList(user) { - const permissions = signalFromProperty(user, 'permissions'); - - return create("div") - .classes("flex-v", "card") - .children( - create("h2") - .text("Your Permissions") - .build(), - signalMap(permissions, - create("div") - .classes("flex"), - permission => AdminComponent.permission(permission)), - ).build(); - } - static permission(permission) { return create("span") .classes("pill") @@ -311,8 +299,10 @@ export class AdminComponent { ifjs(hasDeletePermission, CommonTemplates.buttonWithIcon("delete", "Delete", () => {})), ).build(), ).build(), - LayoutTemplates.collapsible("Roles", AdminComponent.userRoles(user)), - LayoutTemplates.collapsible("Permissions", AdminComponent.userPermissions(user)), + ifjs(user.roles.length > 0, LayoutTemplates.collapsible("Roles", AdminComponent.userRoles(user))), + ifjs(user.roles.length > 0, CommonTemplates.error("No roles"), true), + ifjs(user.permissions.length > 0, LayoutTemplates.collapsible("Permissions", AdminComponent.userPermissions(user))), + ifjs(user.permissions.length > 0, CommonTemplates.smallCard("info", "No permissions"), true), ).build(); }