Built-in Groups admin screen (todo §5); /admin/groups list (search/sort/paginate) + create/delete + membership (add/remove users & nested groups), writing only to Keto — gated admin-only + CSRF-guarded like Users (Kratos read only to label pickers). A group = Keto subject set Group:<name>#members, exists while it has ≥1 member: create writes the first-member tuple, delete removes all by partial-filter. Extracted shared admin-nav.ts (Dashboard·Users·Groups); new generic rowHeader <th scope=row> data-table cell. Stability-reviewer run as a local PR: symmetric subject UUID-validation, duplicate-name rejection, malformed-%→404. 228→237 units + typecheck green; core Keto interactions boot-verified live
This commit is contained in:
21
views/admin/groups.ejs
Normal file
21
views/admin/groups.ejs
Normal file
@@ -0,0 +1,21 @@
|
||||
<%#
|
||||
Groups admin list (todo §5): the same building blocks as the Users screen, around the shell, but
|
||||
backed by live Keto subject sets (src/admin-groups.ts). Filter/sort/page round-trip the URL.
|
||||
%><%
|
||||
const nav = include("partials/nav-tree", { nodes: model.nav });
|
||||
const filters = include("partials/filter-bar", model.filterBar);
|
||||
const table = include("partials/data-table", model.table);
|
||||
const pager = include("partials/pagination", model.pagination);
|
||||
const actions = '<a class="btn btn-primary" href="/admin/groups/new"><svg class="ico ico-sm" aria-hidden="true"><use href="#i-plus"/></svg>Add group</a>';
|
||||
-%>
|
||||
<%- include("partials/shell", {
|
||||
actions,
|
||||
body: filters + table + pager,
|
||||
brand: model.shell.brand,
|
||||
breadcrumbs: model.shell.breadcrumbs,
|
||||
csrfToken: model.shell.csrfToken,
|
||||
nav,
|
||||
theme: model.shell.theme,
|
||||
title: model.shell.title,
|
||||
user: model.shell.user,
|
||||
}) %>
|
||||
Reference in New Issue
Block a user