feat(15-06): group member management + delete dialog with concrete impact numbers
- GroupMembersModal.tsx: chip list of current members with source badge (MANUAL/LDAP); LDAP-sourced chips carry a disabled remove button with a "managed via AD sync" tooltip (D-19) instead of an active one; second section adds manual members via GET /users + POST /groups/:id/members, already-member candidates shown disabled (upsert on the API is folgenlos, no special-case needed) - DeleteGroupDialog.tsx: loads GET /groups/:id/impact and interpolates memberCount/grantCount into the confirmation text (D-17); deliberately breaks from the project's silent-delete-failure precedent -- stays open and shows a visible error on a failed DELETE, since a silent failure here would leave an admin believing a group (and its grants) is gone while it still grants access (T-15-24) - page.tsx: wires both dialogs in, refetches the group list after any member/delete mutation so member counts and badges stay current - groups-page.test.tsx: disabled-vs-active remove button by membership source, delete text shows both numbers, visible error + dialog stays open on failed delete
This commit is contained in:
@@ -4,6 +4,8 @@ import { useCallback, useEffect, useState } from 'react';
|
||||
import { useTranslations } from 'next-intl';
|
||||
import { useAuthStore } from '@/lib/stores/auth-store';
|
||||
import { GroupFormModal } from './components/GroupFormModal';
|
||||
import { GroupMembersModal } from './components/GroupMembersModal';
|
||||
import { DeleteGroupDialog } from './components/DeleteGroupDialog';
|
||||
|
||||
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001';
|
||||
|
||||
@@ -252,8 +254,21 @@ export default function AdminGroupsPage() {
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* GroupMembersModal / DeleteGroupDialog are wired in here by Task 3
|
||||
(member/delete state above is already in place for that). */}
|
||||
{membersGroup && (
|
||||
<GroupMembersModal
|
||||
group={membersGroup}
|
||||
onClose={() => setMembersGroup(null)}
|
||||
onChanged={fetchGroups}
|
||||
/>
|
||||
)}
|
||||
|
||||
{deleteTarget && (
|
||||
<DeleteGroupDialog
|
||||
group={deleteTarget}
|
||||
onClose={() => setDeleteTarget(null)}
|
||||
onDeleted={fetchGroups}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user