diff --git a/src/web/src/features/users/pages/UserEditPage.tsx b/src/web/src/features/users/pages/UserEditPage.tsx index 8ac581d..78605e7 100644 --- a/src/web/src/features/users/pages/UserEditPage.tsx +++ b/src/web/src/features/users/pages/UserEditPage.tsx @@ -8,6 +8,7 @@ import { AlertCircle } from 'lucide-react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import { Alert, AlertDescription } from '@/components/ui/alert' +import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs' import { Form, FormControl, @@ -19,6 +20,7 @@ import { import { useUser } from '../hooks/useUser' import { useUpdateUser } from '../hooks/useUpdateUser' import { ResetPasswordModal } from '../components/ResetPasswordModal' +import { PermisosEditor } from '../components/PermisosEditor' import { useAuthStore } from '@/stores/authStore' const editSchema = z.object({ @@ -111,12 +113,14 @@ export function UserEditPage() { ) } + const isSelf = loggedUserId === userId + return (

Editar Usuario

- {loggedUserId !== userId && } + {!isSelf && } @@ -129,105 +133,120 @@ export function UserEditPage() {

{user.username}

-
- - {backendError && ( - - - {backendError} - - )} + + + Perfil + + Permisos + + - ( - - Nombre - - - - - - )} - /> + + + + {backendError && ( + + + {backendError} + + )} - ( - - Apellido - - - - - - )} - /> + ( + + Nombre + + + + + + )} + /> - ( - - Email (opcional) - - - - - - )} - /> + ( + + Apellido + + + + + + )} + /> - ( - - Rol - - - - - - )} - /> + ( + + Email (opcional) + + + + + + )} + /> - ( - - - - - Activo - - )} - /> + ( + + Rol + + + + + + )} + /> - - - + ( + + + + + Activo + + )} + /> + + + + + + + + + +
) } diff --git a/src/web/src/tests/features/users/UserEditPage.test.tsx b/src/web/src/tests/features/users/UserEditPage.test.tsx index 5b8882c..c9284c4 100644 --- a/src/web/src/tests/features/users/UserEditPage.test.tsx +++ b/src/web/src/tests/features/users/UserEditPage.test.tsx @@ -162,4 +162,40 @@ describe('UserEditPage', () => { await waitFor(() => expect(screen.getByDisplayValue('Juan')).toBeInTheDocument()) expect(screen.queryByRole('button', { name: /resetear contraseña/i })).not.toBeInTheDocument() }) + + // FP-01: tabs Perfil and Permisos visible when editing another user + it('shows tabs "Perfil" and "Permisos" when editing another user', async () => { + server.use( + http.get(`${API_URL}/api/v1/users/5`, () => HttpResponse.json(mockUserDetail)), + http.get(`${API_URL}/api/v1/users/5/permisos`, () => + HttpResponse.json({ + usuarioId: 5, rol: 'cajero', rolPermisos: [], grant: [], deny: [], effective: [], + }), + ), + http.get(`${API_URL}/api/v1/permisos`, () => HttpResponse.json([])), + ) + + renderEditPage(5) + + await waitFor(() => expect(screen.getByDisplayValue('Juan')).toBeInTheDocument()) + + expect(screen.getByRole('tab', { name: /perfil/i })).toBeInTheDocument() + expect(screen.getByRole('tab', { name: /permisos/i })).toBeInTheDocument() + }) + + // FP-10: self-edit — tab Permisos is disabled + it('disables tab "Permisos" when editing own profile (self-edit)', async () => { + server.use( + http.get(`${API_URL}/api/v1/users/1`, () => + HttpResponse.json({ ...mockUserDetail, id: 1, username: 'admin' }), + ), + ) + + renderEditPage(1) + + await waitFor(() => expect(screen.getByDisplayValue('Juan')).toBeInTheDocument()) + + const permisosTab = screen.getByRole('tab', { name: /permisos/i }) + expect(permisosTab).toBeDisabled() + }) })