feat: move settings creation flows into dialogs

This commit is contained in:
2026-07-02 05:49:50 -07:00
parent ba8097e583
commit f6b7924d0c
8 changed files with 590 additions and 206 deletions

View File

@@ -4,7 +4,7 @@ import Link from "next/link";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { getCurrentAuthContext } from "@/modules/core/server/auth";
import { hasPermission } from "@/modules/core/server/permissions";
import { getRoleDefinitions, hasPermission } from "@/modules/core/server/permissions";
import { readData } from "@/modules/core/server/store";
import {
OrganizationManagementClient,
@@ -37,17 +37,29 @@ export default async function OrganizationsPage({ searchParams }: OrganizationsP
);
const pageCount = getPageCount(filteredOrganizations.length);
const visibleOrganizations = paginate(filteredOrganizations, page);
const canManageOrganizations = hasPermission(context.permissions, "organization:manage");
const canInviteMembers = hasPermission(context.permissions, "account:manage");
const organizationRoleGroups = await Promise.all(
visibleOrganizations.map(async (organization) => ({
organizationId: organization.id,
roles: await getRoleDefinitions(organization.id),
})),
);
const rolesByOrganizationId = new Map(
organizationRoleGroups.map((group) => [group.organizationId, group.roles]),
);
return (
<div className="flex flex-col gap-5">
<section>
<Badge variant="success">Organizations</Badge>
<h2 className="mt-3 text-xl font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
<section className="flex flex-col gap-4 border-b pb-5 lg:flex-row lg:items-end lg:justify-between">
<div>
<Badge variant="success">Organizations</Badge>
<h2 className="mt-3 text-xl font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
{canManageOrganizations ? <OrganizationManagementClient /> : null}
</section>
{hasPermission(context.permissions, "organization:manage") ? <OrganizationManagementClient /> : null}
<Card>
<CardHeader>
<CardTitle></CardTitle>
@@ -89,7 +101,11 @@ export default async function OrganizationsPage({ searchParams }: OrganizationsP
{new Date(organization.createdAt).toLocaleString("zh-CN")}
</td>
<td className="px-4 py-3">
<OrganizationRowActions organization={organization} />
<OrganizationRowActions
canInvite={canInviteMembers}
organization={organization}
roles={rolesByOrganizationId.get(organization.id) ?? []}
/>
</td>
</tr>
))}

View File

@@ -32,17 +32,19 @@ export default async function RolesPage({ searchParams }: RolesPageProps): Promi
);
const pageCount = getPageCount(filteredRoles.length);
const visibleRoles = paginate(filteredRoles, page);
const canManageRoles = hasPermission(context.permissions, "role:manage");
return (
<div className="flex flex-col gap-5">
<section>
<Badge variant="success">RBAC</Badge>
<h2 className="mt-3 text-xl font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
<section className="flex flex-col gap-4 border-b pb-5 lg:flex-row lg:items-end lg:justify-between">
<div>
<Badge variant="success">RBAC</Badge>
<h2 className="mt-3 text-xl font-semibold"></h2>
<p className="mt-1 text-sm text-muted-foreground"></p>
</div>
{canManageRoles ? <RoleManagementClient permissions={PERMISSION_DEFINITIONS} /> : null}
</section>
{hasPermission(context.permissions, "role:manage") ? <RoleManagementClient permissions={PERMISSION_DEFINITIONS} /> : null}
<Card>
<CardHeader>
<CardTitle></CardTitle>

View File

@@ -69,7 +69,12 @@ export default async function UsersPage({ searchParams }: UsersPageProps): Promi
<p className="mt-1 text-sm text-muted-foreground"></p>
</section>
<UserManagementClient organizations={data.organizations} roles={roles} joinRequests={data.joinRequests} />
<UserManagementClient
canManageAccounts={hasPermission(context.permissions, "account:manage")}
organizations={data.organizations}
roles={roles}
joinRequests={data.joinRequests}
/>
<Card>
<CardHeader>