2026-03-23 18:32:45 +01:00
|
|
|
import { useState, useMemo } from 'react';
|
|
|
|
|
import {
|
|
|
|
|
Avatar,
|
|
|
|
|
Badge,
|
|
|
|
|
Button,
|
|
|
|
|
Input,
|
|
|
|
|
MonoText,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
SectionHeader,
|
2026-03-23 18:32:45 +01:00
|
|
|
Tag,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
InlineEdit,
|
|
|
|
|
RadioGroup,
|
|
|
|
|
RadioItem,
|
2026-03-23 18:32:45 +01:00
|
|
|
InfoCallout,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
MultiSelect,
|
2026-03-23 18:32:45 +01:00
|
|
|
ConfirmDialog,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
AlertDialog,
|
|
|
|
|
SplitPane,
|
|
|
|
|
EntityList,
|
2026-03-23 18:32:45 +01:00
|
|
|
Spinner,
|
|
|
|
|
useToast,
|
|
|
|
|
} from '@cameleer/design-system';
|
|
|
|
|
import {
|
|
|
|
|
useUsers,
|
|
|
|
|
useCreateUser,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
useUpdateUser,
|
2026-03-23 18:32:45 +01:00
|
|
|
useDeleteUser,
|
|
|
|
|
useAssignRoleToUser,
|
|
|
|
|
useRemoveRoleFromUser,
|
|
|
|
|
useAddUserToGroup,
|
|
|
|
|
useRemoveUserFromGroup,
|
|
|
|
|
useSetPassword,
|
|
|
|
|
useGroups,
|
|
|
|
|
useRoles,
|
|
|
|
|
} from '../../api/queries/admin/rbac';
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
import type { UserDetail } from '../../api/queries/admin/rbac';
|
2026-03-23 18:32:45 +01:00
|
|
|
import { useAuthStore } from '../../auth/auth-store';
|
|
|
|
|
import styles from './UserManagement.module.css';
|
|
|
|
|
|
|
|
|
|
export default function UsersTab() {
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const { toast } = useToast();
|
2026-03-23 18:32:45 +01:00
|
|
|
const { data: users, isLoading } = useUsers();
|
|
|
|
|
const { data: allGroups } = useGroups();
|
|
|
|
|
const { data: allRoles } = useRoles();
|
|
|
|
|
const currentUsername = useAuthStore((s) => s.username);
|
|
|
|
|
|
|
|
|
|
const [search, setSearch] = useState('');
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const [selectedId, setSelectedId] = useState<string | null>(null);
|
|
|
|
|
const [creating, setCreating] = useState(false);
|
|
|
|
|
const [deleteTarget, setDeleteTarget] = useState<UserDetail | null>(null);
|
|
|
|
|
const [removeGroupTarget, setRemoveGroupTarget] = useState<string | null>(null);
|
2026-03-23 18:32:45 +01:00
|
|
|
|
|
|
|
|
// Create form state
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const [newUsername, setNewUsername] = useState('');
|
|
|
|
|
const [newDisplay, setNewDisplay] = useState('');
|
|
|
|
|
const [newEmail, setNewEmail] = useState('');
|
2026-03-23 18:32:45 +01:00
|
|
|
const [newPassword, setNewPassword] = useState('');
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const [newProvider, setNewProvider] = useState<'local' | 'oidc'>('local');
|
|
|
|
|
|
|
|
|
|
// Password reset state
|
|
|
|
|
const [resettingPassword, setResettingPassword] = useState(false);
|
|
|
|
|
const [newPw, setNewPw] = useState('');
|
2026-03-23 18:32:45 +01:00
|
|
|
|
|
|
|
|
// Mutations
|
|
|
|
|
const createUser = useCreateUser();
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const updateUser = useUpdateUser();
|
2026-03-23 18:32:45 +01:00
|
|
|
const deleteUser = useDeleteUser();
|
|
|
|
|
const assignRole = useAssignRoleToUser();
|
|
|
|
|
const removeRole = useRemoveRoleFromUser();
|
|
|
|
|
const addToGroup = useAddUserToGroup();
|
|
|
|
|
const removeFromGroup = useRemoveUserFromGroup();
|
|
|
|
|
const setPassword = useSetPassword();
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const userList = users ?? [];
|
|
|
|
|
|
|
|
|
|
const filtered = useMemo(() => {
|
|
|
|
|
if (!search) return userList;
|
2026-03-23 18:32:45 +01:00
|
|
|
const q = search.toLowerCase();
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
return userList.filter(
|
2026-03-23 18:32:45 +01:00
|
|
|
(u) =>
|
|
|
|
|
u.displayName.toLowerCase().includes(q) ||
|
|
|
|
|
(u.email ?? '').toLowerCase().includes(q) ||
|
|
|
|
|
u.userId.toLowerCase().includes(q),
|
|
|
|
|
);
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}, [userList, search]);
|
2026-03-23 18:32:45 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const selected = userList.find((u) => u.userId === selectedId) ?? null;
|
|
|
|
|
|
|
|
|
|
const isSelf =
|
|
|
|
|
currentUsername != null &&
|
|
|
|
|
selected != null &&
|
|
|
|
|
selected.displayName === currentUsername;
|
|
|
|
|
|
|
|
|
|
const duplicateUsername =
|
|
|
|
|
newUsername.trim() !== '' &&
|
|
|
|
|
userList.some(
|
|
|
|
|
(u) => u.displayName.toLowerCase() === newUsername.trim().toLowerCase(),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Derived data for detail pane
|
|
|
|
|
const directGroupIds = new Set(selected?.directGroups.map((g) => g.id) ?? []);
|
|
|
|
|
const directRoleIds = new Set(selected?.directRoles.map((r) => r.id) ?? []);
|
|
|
|
|
const inheritedRoles =
|
|
|
|
|
selected?.effectiveRoles.filter((r) => !directRoleIds.has(r.id)) ?? [];
|
|
|
|
|
|
|
|
|
|
const availableGroups = (allGroups ?? [])
|
|
|
|
|
.filter((g) => !directGroupIds.has(g.id))
|
|
|
|
|
.map((g) => ({ value: g.id, label: g.name }));
|
2026-03-23 18:32:45 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
const availableRoles = (allRoles ?? [])
|
|
|
|
|
.filter((r) => !directRoleIds.has(r.id))
|
|
|
|
|
.map((r) => ({ value: r.id, label: r.name }));
|
2026-03-23 18:32:45 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
function handleCreate() {
|
|
|
|
|
if (!newUsername.trim()) return;
|
|
|
|
|
if (newProvider === 'local' && !newPassword.trim()) return;
|
2026-03-23 18:32:45 +01:00
|
|
|
createUser.mutate(
|
|
|
|
|
{
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
username: newUsername.trim(),
|
|
|
|
|
displayName: newDisplay.trim() || undefined,
|
|
|
|
|
email: newEmail.trim() || undefined,
|
|
|
|
|
password: newProvider === 'local' ? newPassword : undefined,
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () => {
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
toast({
|
|
|
|
|
title: 'User created',
|
|
|
|
|
description: newDisplay.trim() || newUsername.trim(),
|
|
|
|
|
variant: 'success',
|
|
|
|
|
});
|
|
|
|
|
setCreating(false);
|
|
|
|
|
setNewUsername('');
|
|
|
|
|
setNewDisplay('');
|
|
|
|
|
setNewEmail('');
|
|
|
|
|
setNewPassword('');
|
|
|
|
|
setNewProvider('local');
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
|
|
|
|
onError: () => {
|
2026-04-02 19:08:00 +02:00
|
|
|
toast({ title: 'Failed to create user', variant: 'error', duration: 86_400_000 });
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
function handleDelete() {
|
|
|
|
|
if (!deleteTarget) return;
|
|
|
|
|
deleteUser.mutate(deleteTarget.userId, {
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
toast({
|
|
|
|
|
title: 'User deleted',
|
|
|
|
|
description: deleteTarget.displayName,
|
|
|
|
|
variant: 'warning',
|
|
|
|
|
});
|
|
|
|
|
if (selectedId === deleteTarget.userId) setSelectedId(null);
|
|
|
|
|
setDeleteTarget(null);
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
onError: () => {
|
2026-04-02 19:08:00 +02:00
|
|
|
toast({ title: 'Failed to delete user', variant: 'error', duration: 86_400_000 });
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
setDeleteTarget(null);
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
});
|
2026-03-23 18:32:45 +01:00
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
function handleResetPassword() {
|
|
|
|
|
if (!selected || !newPw.trim()) return;
|
|
|
|
|
setPassword.mutate(
|
|
|
|
|
{ userId: selected.userId, password: newPw },
|
2026-03-23 18:32:45 +01:00
|
|
|
{
|
|
|
|
|
onSuccess: () => {
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
toast({
|
|
|
|
|
title: 'Password updated',
|
|
|
|
|
description: selected.displayName,
|
|
|
|
|
variant: 'success',
|
|
|
|
|
});
|
|
|
|
|
setResettingPassword(false);
|
|
|
|
|
setNewPw('');
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
|
|
|
|
onError: () => {
|
2026-04-02 19:08:00 +02:00
|
|
|
toast({ title: 'Failed to update password', variant: 'error', duration: 86_400_000 });
|
2026-03-23 18:32:45 +01:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
function getUserGroupPath(user: UserDetail): string {
|
|
|
|
|
if (user.directGroups.length === 0) return 'no groups';
|
|
|
|
|
return user.directGroups.map((g) => g.name).join(', ');
|
2026-03-23 18:32:45 +01:00
|
|
|
}
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
if (isLoading) return <Spinner size="md" />;
|
2026-03-23 18:32:45 +01:00
|
|
|
|
|
|
|
|
return (
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<>
|
|
|
|
|
<SplitPane
|
|
|
|
|
list={
|
|
|
|
|
<>
|
|
|
|
|
{creating && (
|
|
|
|
|
<div className={styles.createForm}>
|
|
|
|
|
<RadioGroup
|
|
|
|
|
name="provider"
|
|
|
|
|
value={newProvider}
|
|
|
|
|
onChange={(v) => setNewProvider(v as 'local' | 'oidc')}
|
|
|
|
|
orientation="horizontal"
|
|
|
|
|
>
|
|
|
|
|
<RadioItem value="local" label="Local" />
|
|
|
|
|
<RadioItem value="oidc" label="OIDC" />
|
|
|
|
|
</RadioGroup>
|
|
|
|
|
<div className={styles.createFormRow}>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Username *"
|
|
|
|
|
value={newUsername}
|
|
|
|
|
onChange={(e) => setNewUsername(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Display name"
|
|
|
|
|
value={newDisplay}
|
|
|
|
|
onChange={(e) => setNewDisplay(e.target.value)}
|
|
|
|
|
/>
|
2026-03-24 08:21:11 +01:00
|
|
|
</div>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{duplicateUsername && (
|
|
|
|
|
<span style={{ color: 'var(--error)', fontSize: 11 }}>
|
|
|
|
|
Username already exists
|
|
|
|
|
</span>
|
2026-03-23 18:32:45 +01:00
|
|
|
)}
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<Input
|
|
|
|
|
placeholder="Email"
|
|
|
|
|
value={newEmail}
|
|
|
|
|
onChange={(e) => setNewEmail(e.target.value)}
|
2026-03-23 18:32:45 +01:00
|
|
|
/>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{newProvider === 'local' && (
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Password *"
|
|
|
|
|
type="password"
|
|
|
|
|
value={newPassword}
|
|
|
|
|
onChange={(e) => setNewPassword(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{newProvider === 'oidc' && (
|
|
|
|
|
<InfoCallout variant="amber">
|
|
|
|
|
OIDC users authenticate via the configured identity provider.
|
|
|
|
|
Pre-register to assign roles/groups before their first login.
|
|
|
|
|
</InfoCallout>
|
2026-03-23 18:32:45 +01:00
|
|
|
)}
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<div className={styles.createFormActions}>
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
onClick={() => setCreating(false)}
|
|
|
|
|
>
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
|
|
|
|
variant="primary"
|
|
|
|
|
onClick={handleCreate}
|
|
|
|
|
loading={createUser.isPending}
|
|
|
|
|
disabled={
|
|
|
|
|
!newUsername.trim() ||
|
|
|
|
|
(newProvider === 'local' && !newPassword.trim()) ||
|
|
|
|
|
duplicateUsername
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
Create
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2026-03-23 18:32:45 +01:00
|
|
|
</div>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
)}
|
2026-03-23 18:32:45 +01:00
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<EntityList
|
|
|
|
|
items={filtered}
|
|
|
|
|
renderItem={(user) => (
|
2026-03-23 18:32:45 +01:00
|
|
|
<>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<Avatar name={user.displayName} size="sm" />
|
|
|
|
|
<div className={styles.entityInfo}>
|
|
|
|
|
<div className={styles.entityName}>
|
|
|
|
|
{user.displayName}
|
|
|
|
|
{user.provider !== 'local' && (
|
|
|
|
|
<Badge
|
|
|
|
|
label={user.provider}
|
|
|
|
|
color="running"
|
|
|
|
|
variant="outlined"
|
|
|
|
|
className={styles.providerBadge}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
2026-03-23 18:32:45 +01:00
|
|
|
</div>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<div className={styles.entityMeta}>
|
|
|
|
|
{user.email || user.userId} ·{' '}
|
|
|
|
|
{getUserGroupPath(user)}
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.entityTags}>
|
|
|
|
|
{user.directRoles.map((r) => (
|
|
|
|
|
<Badge key={r.id} label={r.name} color="warning" />
|
|
|
|
|
))}
|
|
|
|
|
{user.directGroups.map((g) => (
|
|
|
|
|
<Badge key={g.id} label={g.name} color="success" />
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-23 18:32:45 +01:00
|
|
|
</>
|
|
|
|
|
)}
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
getItemId={(user) => user.userId}
|
|
|
|
|
selectedId={selectedId ?? undefined}
|
|
|
|
|
onSelect={(id) => {
|
|
|
|
|
setSelectedId(id);
|
|
|
|
|
setResettingPassword(false);
|
|
|
|
|
}}
|
|
|
|
|
searchPlaceholder="Search users..."
|
|
|
|
|
onSearch={setSearch}
|
|
|
|
|
addLabel="+ Add user"
|
|
|
|
|
onAdd={() => setCreating(true)}
|
|
|
|
|
emptyMessage="No users match your search"
|
|
|
|
|
/>
|
|
|
|
|
</>
|
|
|
|
|
}
|
|
|
|
|
detail={
|
|
|
|
|
selected ? (
|
|
|
|
|
<>
|
|
|
|
|
<div className={styles.detailHeader}>
|
|
|
|
|
<Avatar name={selected.displayName} size="lg" />
|
|
|
|
|
<div className={styles.detailHeaderInfo}>
|
|
|
|
|
<div className={styles.detailName}>
|
|
|
|
|
<InlineEdit
|
|
|
|
|
value={selected.displayName}
|
|
|
|
|
onSave={(v) =>
|
|
|
|
|
updateUser.mutate(
|
|
|
|
|
{ userId: selected.userId, displayName: v },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Display name updated',
|
|
|
|
|
variant: 'success',
|
|
|
|
|
}),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to update name',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className={styles.detailEmail}>
|
|
|
|
|
{selected.email || selected.userId}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-03-23 18:32:45 +01:00
|
|
|
<Button
|
|
|
|
|
size="sm"
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
variant="danger"
|
|
|
|
|
onClick={() => setDeleteTarget(selected)}
|
|
|
|
|
disabled={isSelf}
|
2026-03-23 18:32:45 +01:00
|
|
|
>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
Delete
|
2026-03-23 18:32:45 +01:00
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
<SectionHeader>Status</SectionHeader>
|
|
|
|
|
<div className={styles.sectionTags}>
|
|
|
|
|
<Tag label="Active" color="success" />
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className={styles.metaGrid}>
|
|
|
|
|
<span className={styles.metaLabel}>ID</span>
|
|
|
|
|
<MonoText size="xs">{selected.userId}</MonoText>
|
|
|
|
|
<span className={styles.metaLabel}>Created</span>
|
|
|
|
|
<span className={styles.metaValue}>
|
|
|
|
|
{new Date(selected.createdAt).toLocaleDateString()}
|
|
|
|
|
</span>
|
|
|
|
|
<span className={styles.metaLabel}>Provider</span>
|
|
|
|
|
<span className={styles.metaValue}>{selected.provider}</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SectionHeader>Security</SectionHeader>
|
|
|
|
|
<div className={styles.securitySection}>
|
|
|
|
|
{selected.provider === 'local' ? (
|
|
|
|
|
<>
|
|
|
|
|
<div className={styles.securityRow}>
|
|
|
|
|
<span className={styles.metaLabel}>Password</span>
|
|
|
|
|
<span className={styles.passwordDots}>
|
|
|
|
|
••••••••
|
|
|
|
|
</span>
|
|
|
|
|
{!resettingPassword && (
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setResettingPassword(true);
|
|
|
|
|
setNewPw('');
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
Reset password
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
{resettingPassword && (
|
|
|
|
|
<div className={styles.resetForm}>
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="New password"
|
|
|
|
|
type="password"
|
|
|
|
|
value={newPw}
|
|
|
|
|
onChange={(e) => setNewPw(e.target.value)}
|
|
|
|
|
className={styles.resetInput}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
onClick={() => setResettingPassword(false)}
|
|
|
|
|
>
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
size="sm"
|
|
|
|
|
variant="primary"
|
|
|
|
|
onClick={handleResetPassword}
|
|
|
|
|
loading={setPassword.isPending}
|
|
|
|
|
disabled={!newPw.trim()}
|
|
|
|
|
>
|
|
|
|
|
Set
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
) : (
|
|
|
|
|
<>
|
|
|
|
|
<div className={styles.securityRow}>
|
|
|
|
|
<span className={styles.metaLabel}>Authentication</span>
|
|
|
|
|
<span className={styles.metaValue}>
|
|
|
|
|
OIDC ({selected.provider})
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<InfoCallout variant="amber">
|
|
|
|
|
Password managed by the identity provider.
|
|
|
|
|
</InfoCallout>
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SectionHeader>Group membership (direct only)</SectionHeader>
|
|
|
|
|
<div className={styles.sectionTags}>
|
|
|
|
|
{selected.directGroups.map((g) => (
|
|
|
|
|
<Tag
|
|
|
|
|
key={g.id}
|
|
|
|
|
label={g.name}
|
|
|
|
|
color="success"
|
|
|
|
|
onRemove={() => {
|
|
|
|
|
removeFromGroup.mutate(
|
|
|
|
|
{ userId: selected.userId, groupId: g.id },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({ title: 'Group removed', variant: 'success' }),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to remove group',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
{selected.directGroups.length === 0 && (
|
|
|
|
|
<span className={styles.inheritedNote}>(no groups)</span>
|
|
|
|
|
)}
|
|
|
|
|
<MultiSelect
|
|
|
|
|
options={availableGroups}
|
|
|
|
|
value={[]}
|
|
|
|
|
onChange={(ids) => {
|
|
|
|
|
for (const groupId of ids) {
|
|
|
|
|
addToGroup.mutate(
|
|
|
|
|
{ userId: selected.userId, groupId },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({ title: 'Added to group', variant: 'success' }),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to add group',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
placeholder="+ Add"
|
2026-03-23 18:32:45 +01:00
|
|
|
/>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SectionHeader>
|
|
|
|
|
Effective roles (direct + inherited)
|
|
|
|
|
</SectionHeader>
|
|
|
|
|
<div className={styles.sectionTags}>
|
|
|
|
|
{selected.directRoles.map((r) => (
|
|
|
|
|
<Tag
|
|
|
|
|
key={r.id}
|
|
|
|
|
label={r.name}
|
|
|
|
|
color="warning"
|
|
|
|
|
onRemove={() => {
|
|
|
|
|
removeRole.mutate(
|
|
|
|
|
{ userId: selected.userId, roleId: r.id },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Role removed',
|
|
|
|
|
description: r.name,
|
|
|
|
|
variant: 'success',
|
|
|
|
|
}),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to remove role',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
{inheritedRoles.map((r) => (
|
2026-03-23 18:32:45 +01:00
|
|
|
<Badge
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
key={r.id}
|
|
|
|
|
label={`${r.name} ↑ group`}
|
|
|
|
|
color="warning"
|
2026-03-23 18:32:45 +01:00
|
|
|
variant="dashed"
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
className={styles.inherited}
|
2026-03-23 18:32:45 +01:00
|
|
|
/>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
))}
|
|
|
|
|
{selected.directRoles.length === 0 &&
|
|
|
|
|
inheritedRoles.length === 0 && (
|
|
|
|
|
<span className={styles.inheritedNote}>(no roles)</span>
|
|
|
|
|
)}
|
|
|
|
|
<MultiSelect
|
|
|
|
|
options={availableRoles}
|
|
|
|
|
value={[]}
|
|
|
|
|
onChange={(roleIds) => {
|
|
|
|
|
for (const roleId of roleIds) {
|
|
|
|
|
assignRole.mutate(
|
|
|
|
|
{ userId: selected.userId, roleId },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Role assigned',
|
|
|
|
|
variant: 'success',
|
|
|
|
|
}),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to assign role',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
placeholder="+ Add"
|
2026-03-23 18:32:45 +01:00
|
|
|
/>
|
|
|
|
|
</div>
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
{inheritedRoles.length > 0 && (
|
|
|
|
|
<span className={styles.inheritedNote}>
|
|
|
|
|
Roles with ↑ are inherited through group membership
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
) : null
|
|
|
|
|
}
|
|
|
|
|
emptyMessage="Select a user to view details"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<ConfirmDialog
|
|
|
|
|
open={deleteTarget !== null}
|
|
|
|
|
onClose={() => setDeleteTarget(null)}
|
|
|
|
|
onConfirm={handleDelete}
|
|
|
|
|
message={`Delete user "${deleteTarget?.displayName}"? This cannot be undone.`}
|
|
|
|
|
confirmText={deleteTarget?.displayName ?? ''}
|
|
|
|
|
loading={deleteUser.isPending}
|
|
|
|
|
/>
|
|
|
|
|
<AlertDialog
|
|
|
|
|
open={removeGroupTarget !== null}
|
|
|
|
|
onClose={() => setRemoveGroupTarget(null)}
|
|
|
|
|
onConfirm={() => {
|
|
|
|
|
if (removeGroupTarget && selected) {
|
|
|
|
|
removeFromGroup.mutate(
|
|
|
|
|
{ userId: selected.userId, groupId: removeGroupTarget },
|
|
|
|
|
{
|
|
|
|
|
onSuccess: () =>
|
|
|
|
|
toast({ title: 'Group removed', variant: 'success' }),
|
|
|
|
|
onError: () =>
|
|
|
|
|
toast({
|
|
|
|
|
title: 'Failed to remove group',
|
|
|
|
|
variant: 'error',
|
2026-04-02 19:08:00 +02:00
|
|
|
duration: 86_400_000,
|
feat: replace UI with design system example pages wired to real API
Migrate all page components from the @cameleer/design-system v0.0.3
example UI, replacing mock data with real backend API hooks. This brings
richer visuals (KpiStrip, GroupCard, RouteFlow, ProcessorTimeline,
DateRangePicker, expandable rows) while preserving all existing API
integration, auth, and routing infrastructure.
Pages migrated: Dashboard, RoutesMetrics, RouteDetail, ExchangeDetail,
AgentHealth, AgentInstance, OidcConfig, AuditLog, RBAC (Users/Groups/Roles).
Also enhanced LayoutShell CommandPalette with real search data from catalog.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:42:16 +01:00
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
setRemoveGroupTarget(null);
|
|
|
|
|
}}
|
|
|
|
|
title="Remove group membership"
|
|
|
|
|
description="Removing this group may also revoke inherited roles. Continue?"
|
|
|
|
|
confirmLabel="Remove"
|
|
|
|
|
variant="warning"
|
|
|
|
|
/>
|
|
|
|
|
</>
|
2026-03-23 18:32:45 +01:00
|
|
|
);
|
|
|
|
|
}
|