feat: add UI to edit role default page permissions
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 4m24s
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 4m24s
This commit is contained in:
@@ -140,6 +140,8 @@
|
||||
let editingUser = $state("");
|
||||
let editPages = $state([]);
|
||||
let newUsername = $state("");
|
||||
let editingRole = $state("");
|
||||
let editRolePages = $state([]);
|
||||
|
||||
async function loadRbac() {
|
||||
rbacLoading = true;
|
||||
@@ -153,18 +155,38 @@
|
||||
editingUser = username;
|
||||
editPages = [...pages];
|
||||
newUsername = "";
|
||||
editingRole = "";
|
||||
}
|
||||
|
||||
function startAdd() {
|
||||
editingUser = "__new__";
|
||||
editPages = ["dashboard"];
|
||||
newUsername = "";
|
||||
editingRole = "";
|
||||
}
|
||||
|
||||
function cancelEdit() {
|
||||
editingUser = "";
|
||||
editPages = [];
|
||||
newUsername = "";
|
||||
editingRole = "";
|
||||
editRolePages = [];
|
||||
}
|
||||
|
||||
function startEditRole(role, pages) {
|
||||
editingRole = role;
|
||||
editRolePages = pages === "*" ? ["*"] : [...pages];
|
||||
editingUser = "";
|
||||
}
|
||||
|
||||
function toggleRolePage(p) {
|
||||
if (p === "*") {
|
||||
editRolePages = ["*"];
|
||||
} else {
|
||||
if (editRolePages.includes("*")) editRolePages = [];
|
||||
if (editRolePages.includes(p)) editRolePages = editRolePages.filter(x => x !== p);
|
||||
else editRolePages = [...editRolePages, p];
|
||||
}
|
||||
}
|
||||
|
||||
function togglePage(p) {
|
||||
@@ -199,6 +221,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function saveRoleDefault() {
|
||||
rbacMsg = ""; rbacErr = "";
|
||||
if (!editingRole) return;
|
||||
if (!editRolePages.length) { rbacErr = "Select at least one page or '*' for all"; return; }
|
||||
try {
|
||||
const pages = editRolePages.includes("*") ? "*" : editRolePages;
|
||||
await put(`/auth/rbac/roles/${encodeURIComponent(editingRole)}`, { pages });
|
||||
rbacMsg = `Updated role default for ${editingRole}`;
|
||||
cancelEdit();
|
||||
await loadRbac();
|
||||
} catch (e) {
|
||||
rbacErr = e.body?.detail || "Failed to save role";
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
loadPasskeys();
|
||||
if (currentUser.role === "admin") loadRbac();
|
||||
@@ -299,12 +336,31 @@
|
||||
<!-- Role Defaults -->
|
||||
<div class="mb-4">
|
||||
<p class="text-xs font-medium text-surface-500 mb-2">Role Defaults</p>
|
||||
<div class="space-y-1.5">
|
||||
<div class="space-y-2">
|
||||
{#each Object.entries(rbacConfig.role_defaults || {}) as [role, cfg]}
|
||||
<div class="flex items-center gap-2 text-xs">
|
||||
<span class="font-medium text-surface-700 dark:text-surface-300 w-16">{role}</span>
|
||||
<span class="text-surface-400">{cfg.pages === "*" ? "All pages" : (cfg.pages || []).join(", ")}</span>
|
||||
</div>
|
||||
{#if editingRole === role}
|
||||
<div class="p-3 bg-surface-50 dark:bg-surface-700 rounded-lg space-y-2">
|
||||
<p class="text-xs font-medium text-surface-700 dark:text-surface-200">{role}</p>
|
||||
<div class="flex flex-wrap gap-1.5">
|
||||
<button onclick={() => toggleRolePage("*")} class="px-2 py-0.5 text-xs rounded-md transition-colors {editRolePages.includes('*') ? 'bg-primary-600 text-white' : 'bg-surface-200 dark:bg-surface-600 text-surface-500'}">* (all)</button>
|
||||
{#each allPages as p}
|
||||
<button onclick={() => toggleRolePage(p)} class="px-2 py-0.5 text-xs rounded-md transition-colors {editRolePages.includes(p) ? 'bg-primary-600 text-white' : 'bg-surface-200 dark:bg-surface-600 text-surface-500'}">{p}</button>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button onclick={saveRoleDefault} class="px-3 py-1 text-xs font-medium text-white bg-primary-600 hover:bg-primary-700 rounded-md transition-colors">Save</button>
|
||||
<button onclick={cancelEdit} class="px-3 py-1 text-xs font-medium text-surface-600 hover:text-surface-800 dark:text-surface-400 dark:hover:text-surface-200">Cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="flex items-center justify-between p-2 bg-surface-50 dark:bg-surface-700 rounded-lg">
|
||||
<div class="flex items-center gap-2 text-xs">
|
||||
<span class="font-medium text-surface-700 dark:text-surface-300 w-16">{role}</span>
|
||||
<span class="text-surface-400">{cfg.pages === "*" ? "All pages" : (cfg.pages || []).join(", ")}</span>
|
||||
</div>
|
||||
<button onclick={() => startEditRole(role, cfg.pages)} class="text-xs text-primary-500 hover:text-primary-700">Edit</button>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user