Skip to content

Commit 17bd46b

Browse files
committed
Merge branch 'main' into feature/#62-crear-layout-contrato-abierto-temporalidad
2 parents dcce104 + 907ebdd commit 17bd46b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+958
-106
lines changed

mock-server/.env.example

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
NODE_ENV=development
22
PORT=3000
3-
SIMULATED_DELAY=2000
3+
SIMULATED_DELAY=2000

mock-server/src/dals/mock.data.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export interface DB {
1111
export const db: DB = {
1212
users: [
1313
{
14-
_id: new ObjectId(),
14+
_id: new ObjectId('67e29f6498ec8fa00c141af1'),
1515
nombre: 'Carlos',
1616
apellido: 'González Pérez',
1717
@@ -33,7 +33,7 @@ export const db: DB = {
3333
},
3434
},
3535
{
36-
_id: new ObjectId(),
36+
_id: new ObjectId('67e2a2a01faec0c33a18c24a'),
3737
nombre: 'María',
3838
apellido: 'Martínez López',
3939
@@ -55,7 +55,7 @@ export const db: DB = {
5555
},
5656
},
5757
{
58-
_id: new ObjectId(),
58+
_id: new ObjectId('67e2a2a9bdf6ec804964701e'),
5959
nombre: 'Juan',
6060
apellido: 'Rodríguez Sánchez',
6161
@@ -77,7 +77,7 @@ export const db: DB = {
7777
},
7878
},
7979
{
80-
_id: new ObjectId(),
80+
_id: new ObjectId('67e2a2b17f7177a8b57ceed7'),
8181
nombre: 'Laura',
8282
apellido: 'García Ruiz',
8383
@@ -99,7 +99,7 @@ export const db: DB = {
9999
},
100100
},
101101
{
102-
_id: new ObjectId(),
102+
_id: new ObjectId('67e2a2bb61e3836ad14d746e'),
103103
nombre: 'Miguel',
104104
apellido: 'Fernández Gómez',
105105

mock-server/src/dals/user/user.model.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export interface Usuario {
1313
esProponente?: boolean;
1414
esAutorizante?: boolean;
1515
esContraseñaTemporal?: boolean;
16-
contraseña: string;
16+
contraseña?: string;
1717
unidad: Lookup;
1818
}

mock-server/src/dals/user/user.repository.ts

+8
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,12 @@ export const userRepository = {
1919
db.users.push(newUser);
2020
return true;
2121
},
22+
getUserById: async (id: string): Promise<model.Usuario> => db.users.find(user => user._id.toHexString() === id),
23+
actualizarUsuario: async (id: string, usuarioActualizado: model.Usuario): Promise<boolean> => {
24+
const index = db.users.findIndex(user => user._id.toHexString() === id);
25+
if (index !== -1) {
26+
db.users[index] = { ...db.users[index], ...usuarioActualizado };
27+
}
28+
return index !== -1;
29+
},
2230
};

mock-server/src/pods/user/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './user.api.js';
1+
export * from './user.rest-api.js';

mock-server/src/pods/user/user.api-model.ts

+22
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,25 @@ export interface Usuario {
1313
contraseña?: string;
1414
unidad: string;
1515
}
16+
17+
export interface UsuarioSummary {
18+
id: string;
19+
nombre: string;
20+
apellido: string;
21+
email: string;
22+
unidad: string;
23+
}
24+
25+
export interface UsuarioActualizado {
26+
_id: string;
27+
nombre: string;
28+
apellido: string;
29+
email: string;
30+
telefono?: string;
31+
movil?: string;
32+
rol: string;
33+
esResponsable?: boolean;
34+
esProponente?: boolean;
35+
esAutorizante?: boolean;
36+
unidad: string;
37+
}

mock-server/src/pods/user/user.mappers.ts

+34-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ import * as model from '#dals/user/user.model.js';
66
import * as apiModel from './user.api-model.js';
77

88
export const mapUserFromModelToApi = (user: model.Usuario): apiModel.Usuario => ({
9+
id: mapObjectIdToString(user._id),
10+
nombre: user.nombre,
11+
apellido: user.apellido,
12+
email: user.email,
13+
unidad: user.unidad.id,
14+
esAutorizante: user.esAutorizante,
15+
esProponente: user.esProponente,
16+
esResponsable: user.esResponsable,
17+
rol: user.rol.id,
18+
movil: user.movil,
19+
telefono: user.telefono,
20+
});
21+
22+
export const mapUserSummaryFromModelToApi = (user: model.Usuario): apiModel.UsuarioSummary => ({
923
id: mapObjectIdToString(user._id),
1024
nombre: user.nombre,
1125
apellido: user.apellido,
@@ -16,7 +30,7 @@ export const mapUserFromModelToApi = (user: model.Usuario): apiModel.Usuario =>
1630
export const mapUserListFromModelToApi = (
1731
userList: CollectionQuery<model.Usuario>
1832
): CollectionQuery<apiModel.Usuario> => ({
19-
data: mapToCollection(userList.data, mapUserFromModelToApi),
33+
data: mapToCollection(userList.data, mapUserSummaryFromModelToApi),
2034
pagination: {
2135
totalPages: userList.pagination.totalPages,
2236
},
@@ -42,3 +56,22 @@ export const mapUserFromApiToModel = (user: apiModel.Usuario): model.Usuario =>
4256
esAutorizante: user.esAutorizante,
4357
};
4458
};
59+
60+
export const mapUserFromApiToModelUpdate = (user: apiModel.UsuarioActualizado): model.Usuario => {
61+
const role = db.roles.find(role => role.id === user.rol);
62+
const unit = db.unidadProponentes.find(unit => unit.id === user.unidad);
63+
64+
return {
65+
_id: new ObjectId(),
66+
nombre: user.nombre,
67+
apellido: user.apellido,
68+
telefono: user.telefono,
69+
movil: user.movil,
70+
email: user.email,
71+
rol: role,
72+
unidad: unit,
73+
esResponsable: user.esResponsable,
74+
esProponente: user.esProponente,
75+
esAutorizante: user.esAutorizante,
76+
};
77+
};

mock-server/src/pods/user/user.api.ts renamed to mock-server/src/pods/user/user.rest-api.ts

+29-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { Router } from 'express';
22
import { userRepository } from '#dals/user/user.repository.js';
3-
import { mapUserFromApiToModel, mapUserListFromModelToApi } from './user.mappers.js';
4-
import { Usuario } from './user.api-model.js';
3+
import {
4+
mapUserFromModelToApi,
5+
mapUserListFromModelToApi,
6+
mapUserFromApiToModel,
7+
mapUserFromApiToModelUpdate,
8+
} from './user.mappers.js';
9+
import { Usuario, UsuarioActualizado } from './user.api-model.js';
510

611
export const userApi = Router();
712

@@ -25,6 +30,7 @@ userApi
2530
next(error);
2631
}
2732
})
33+
2834
.post('/', async (req, res, next) => {
2935
try {
3036
const newUser: Usuario = req.body;
@@ -36,4 +42,25 @@ userApi
3642
} catch (error) {
3743
next(error);
3844
}
45+
})
46+
.get('/:id', async (req, res, next) => {
47+
try {
48+
const { id } = req.params;
49+
const user = await userRepository.getUserById(id);
50+
res.send(mapUserFromModelToApi(user));
51+
} catch (error) {
52+
next(error);
53+
}
54+
})
55+
.put('/:id', async (req, res, next) => {
56+
try {
57+
const { id } = req.params;
58+
const usuarioActualizado: UsuarioActualizado = req.body;
59+
const modelUser = mapUserFromApiToModelUpdate(usuarioActualizado);
60+
const estaActualizado = await userRepository.actualizarUsuario(id, modelUser);
61+
62+
res.status(201).send(estaActualizado);
63+
} catch (error) {
64+
next(error);
65+
}
3966
});

src/common/hooks/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './form-field.hook';
2+
export * from './toogle.hook';

src/common/hooks/toogle.hook.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import * as React from 'react';
2+
3+
export const useToggle = (initialState: boolean) => {
4+
const [isOpen, setIsOpen] = React.useState(initialState);
5+
6+
const onToggle = () => setIsOpen(!isOpen);
7+
8+
return {
9+
isOpen,
10+
onToggle,
11+
setIsOpen,
12+
};
13+
};

src/core/react-query/common-query-keys.ts

-4
This file was deleted.

src/core/react-query/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
export * from './query';
2-
export * from './common-query-keys';
2+
export * from './query-keys';

src/core/react-query/query-keys.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export const commonQueryKeys = {
2+
all: ['common'],
3+
unidadRolList: () => ['common', 'unidadRolList'],
4+
};
5+
6+
export const usersQueryKeys = {
7+
all: ['users'],
8+
userCollection: (page?: number, pageSize?: number) => ['users', page, pageSize],
9+
user: (id: string) => ['user', id],
10+
};
11+
12+
export const expedientesQueryKeys = {
13+
all: ['expedientes'],
14+
expedienteCollection: (page?: number, pageSize?: number) => ['expedientes', page, pageSize],
15+
};
16+
17+
export const certificacionesQueryKeys = {
18+
all: ['certificaciones'],
19+
certificacionCollection: (page?: number, pageSize?: number) => ['certificaciones', page, pageSize],
20+
};

src/core/theme/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './theme-provider.component';
22
export * from './theme.hooks';
3+
export * from './theme';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './table.component';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import { Pagination, Paper, Table, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material';
3+
import { ColumnDef, flexRender, getCoreRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
4+
import { Certificacion } from '../editar-certificaciones.vm';
5+
import * as classes from './table.styles';
6+
7+
interface Props {
8+
columns: ColumnDef<Certificacion>[];
9+
certificacionCollection: Certificacion[];
10+
totalItems: number;
11+
currentPage: number;
12+
onPageChange: (event: React.ChangeEvent<unknown>, page: number) => void;
13+
}
14+
15+
export const TableComponent: React.FC<Props> = props => {
16+
const { columns, certificacionCollection: data, totalItems, currentPage, onPageChange } = props;
17+
const tableInstance = useReactTable({
18+
data,
19+
columns,
20+
getCoreRowModel: getCoreRowModel(),
21+
getPaginationRowModel: getPaginationRowModel(),
22+
rowCount: totalItems,
23+
});
24+
25+
const { getRowModel, getHeaderGroups, getPageCount } = tableInstance;
26+
27+
return (
28+
<TableContainer component={Paper}>
29+
<Table className={classes.table}>
30+
<TableHead>
31+
{getHeaderGroups().map(headerGroup => (
32+
<TableRow key={headerGroup.id}>
33+
{headerGroup.headers.map(header => (
34+
<TableCell key={header.id}>{flexRender(header.column.columnDef.header, header.getContext())}</TableCell>
35+
))}
36+
</TableRow>
37+
))}
38+
</TableHead>
39+
<TableBody>
40+
{getRowModel().rows.map(row => (
41+
<TableRow key={row.id}>
42+
{row.getVisibleCells().map(cell => (
43+
<TableCell key={cell.id}>{flexRender(cell.column.columnDef.cell, cell.getContext())}</TableCell>
44+
))}
45+
</TableRow>
46+
))}
47+
</TableBody>
48+
</Table>
49+
<Pagination
50+
count={getPageCount()}
51+
page={currentPage + 1}
52+
onChange={onPageChange}
53+
className={classes.pagination}
54+
/>
55+
</TableContainer>
56+
);
57+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { css } from '@emotion/css';
2+
3+
export const table = css`
4+
min-width: 1200px;
5+
`;
6+
7+
export const pagination = css`
8+
display: flex;
9+
justify-content: center;
10+
padding: 10px;
11+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { ColumnDef } from '@tanstack/react-table';
2+
import { Link } from '@tanstack/react-router';
3+
import { Box } from '@mui/material';
4+
import { Edit as EditIcon, Visibility as VisibilityIcon } from '@mui/icons-material';
5+
import { Certificacion } from './editar-certificaciones.vm';
6+
import * as classes from './editar-certificaciones.styles';
7+
8+
export const useColumns = (): ColumnDef<Certificacion>[] => {
9+
return [
10+
{ accessorKey: 'id', header: 'ID' },
11+
{ accessorKey: 'numeroFactura', header: 'Número de factura' },
12+
{ accessorKey: 'fechaFactura', header: 'Fecha de factura' },
13+
{ accessorKey: 'periodoGasto', header: 'Periodo de gasto' },
14+
{ accessorKey: 'importe', header: 'Importe' },
15+
{ accessorKey: 'fechaCertificacion', header: 'Fecha de certificación' },
16+
{ accessorKey: 'certifica', header: 'Certifica' },
17+
{
18+
accessorKey: 'acciones',
19+
header: 'Acciones',
20+
cell: ({ row }) => (
21+
<Box display="flex" alignItems="center" gap={2}>
22+
<Link to={`/certificaciones/${row.original.id}`} className={classes.link}>
23+
<VisibilityIcon sx={{ color: 'gray' }} />
24+
</Link>
25+
<Link to={`/editar-certificacion/${row.original.id}`} className={classes.link}>
26+
<EditIcon sx={{ color: 'gray' }} />
27+
</Link>
28+
</Box>
29+
),
30+
},
31+
];
32+
};

0 commit comments

Comments
 (0)