Skip to content

Commit ec67ee1

Browse files
committed
fix: Replaced fetchpaths with includes
1 parent 4937f0c commit ec67ee1

File tree

21 files changed

+179
-101
lines changed

21 files changed

+179
-101
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
### How to seed your database
2626

27+
- Edit `server/prisma/seed.ts`
28+
2729
- Run `npm run db:seed`
2830

2931
## Deployment

client/src/api/RecordRoutes.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Record } from '@fullstack-typescript-monorepo/prisma';
1+
import { Prisma, Record } from '@fullstack-typescript-monorepo/prisma';
22
import Fetch from '../utils/fetcher';
33
import Super from './Super';
44
import { User } from './UserRoutes';
@@ -7,8 +7,15 @@ export type RecordWithAuthor = Record & {
77
author: User;
88
};
99

10+
export type RecordUpdate = Partial<Record> & {
11+
author?: {
12+
create?: Prisma.RecordCreateWithoutAuthorInput;
13+
update?: Prisma.RecordUpdateWithoutAuthorInput;
14+
}
15+
};
16+
1017
const RecordRoutes = {
11-
...Super<Record>('record'),
18+
...Super<Record, RecordUpdate>('record'),
1219
list: (object?: string) => Fetch<RecordWithAuthor[]>('/api/record/list', {
1320
object,
1421
}),

client/src/api/RequestRoutes.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { Request } from '@fullstack-typescript-monorepo/prisma';
22
import Super from './Super';
33

4+
export type RequestUpdate = Partial<Request>;
5+
46
const RequestRoutes = {
5-
...Super<Request>('request'),
7+
...Super<Request, RequestUpdate>('request'),
68
};
79

810
export default RequestRoutes;

client/src/api/Super.ts

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
1+
import { PrismaInclude } from '@fullstack-typescript-monorepo/core';
12
import { TableState } from '../components/Datatable';
23
import Fetch from '../utils/fetcher';
34

4-
export type RecursivePartial<T> = {
5-
[P in keyof T]?: RecursivePartial<T[P]>;
6-
};
7-
85
export interface getProps {
96
id: number;
10-
fetchPath: string;
7+
include?: PrismaInclude;
118
}
129

13-
const Super = <Model>(model: string) => ({
14-
insert: (data: Partial<Model>, fetchPath?: string) => Fetch<Model>(`/api/${model}`, data, 'PUT', { fetchPath }),
15-
get: ({ id, fetchPath }: getProps) => Fetch<Model>(`/api/${model}/${id}`, {
16-
fetchPath,
17-
}),
18-
getAll: (fetchPath: string) => Fetch<Model[]>(`/api/${model}/all`, {
19-
fetchPath,
20-
}),
21-
getAllAsCsv: (fetchPath: string, title: string) => Fetch<Blob>(`/api/${model}/all/csv`, {
22-
fetchPath,
10+
const Super = <Model, Setter extends object>(model: string) => ({
11+
insert: (data: Setter) => Fetch<Model>(`/api/${model}`, data, 'PUT'),
12+
get: ({ id, include }: getProps) => Fetch<Model>(`/api/${model}/${id}/get`, {
13+
include,
14+
}, 'POST'),
15+
getAll: (include: PrismaInclude) => Fetch<Model[]>(`/api/${model}/all`, {
16+
include,
17+
}, 'POST'),
18+
getAllAsCsv: (title: string) => Fetch<Blob>(`/api/${model}/all/csv`, {
2319
title,
2420
}),
2521
table: (
26-
fetchPath: string,
2722
state: TableState,
23+
include?: PrismaInclude,
2824
) => Fetch<{ data: Model[], count: number }>(`/api/${model}/table`, {
29-
fetchPath,
3025
state,
26+
include,
27+
}, 'POST'),
28+
update: (
29+
id: number,
30+
data: Setter,
31+
include?: PrismaInclude
32+
) => Fetch<Model>(`/api/${model}/${id}/update`, {
33+
data,
34+
include,
3135
}, 'POST'),
32-
update: (id: number, data: RecursivePartial<Model>, fetchPath?: string) => Fetch<Model>(`/api/${model}/${id}`, data, 'POST', { fetchPath }),
3336
delete: (id: number) => Fetch<never>(`/api/${model}/${id}`, {}, 'DELETE'),
3437
});
3538

client/src/api/UserRoutes.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,20 @@
1-
import { Person, User as _User } from '@fullstack-typescript-monorepo/prisma';
1+
import { Person, Prisma, User as _User } from '@fullstack-typescript-monorepo/prisma';
22
import Fetch from '../utils/fetcher';
33
import Super from './Super';
44

55
export interface User extends Omit<_User, 'password'> {
66
person: Person;
77
}
88

9+
export type UserUpdate = Partial<_User> & {
10+
person?: {
11+
create?: Prisma.PersonCreateWithoutUserInput;
12+
update?: Prisma.PersonUpdateWithoutUserInput;
13+
}
14+
};
15+
916
const UserRoutes = {
10-
...Super<User>('user'),
17+
...Super<User, UserUpdate>('user'),
1118
authenticate: (login: string, password: string): Promise<User> => Fetch<User>('/api/user/authenticate', {
1219
login,
1320
password,

client/src/components/Datatable.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@ export interface TableState {
1919
}
2020

2121
interface DatatableProps<DataType, Model> extends Omit<DataGridProps, 'columns' | 'rows'> {
22-
fetchPath: string;
2322
getter: (params: TableState) => Promise<{ data: DataType[], count: number }>;
24-
setter?: (id: number, data: Partial<DataType>, fetchPath: string) => Promise<Model>;
23+
setter?: (id: number, data: Partial<DataType>) => Promise<Model>;
2524
columns: GridColumns;
2625
options?: Omit<DataGridProps, 'columns' | 'rows'>;
2726
globalCsvExport: GlobalCsvExport;
@@ -33,7 +32,6 @@ interface DatatableProps<DataType, Model> extends Omit<DataGridProps, 'columns'
3332
* Datatable component
3433
*/
3534
const Datatable = <DataType extends WithId, Model>({
36-
fetchPath,
3735
getter,
3836
columns,
3937
options,
@@ -140,7 +138,7 @@ const Datatable = <DataType extends WithId, Model>({
140138
},
141139
processRowUpdate: (row: DataType) => {
142140
if (setter) {
143-
const response = setter(row.id, row, fetchPath);
141+
const response = setter(row.id, row);
144142
Alert.open('success', t('updateSuccess'));
145143
return response;
146144
}

client/src/components/DatatableGlobalExport.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import { useLoader } from '../hooks/useLoader';
77
import catchError from '../utils/catchError';
88

99
export type GlobalCsvExport = {
10-
fetcher: (fetchPath: string, title: string) => Promise<Blob>;
11-
fetchPath: string;
10+
fetcher: (title: string) => Promise<Blob>;
1211
title: string;
1312
};
1413

@@ -27,7 +26,6 @@ const DatatableGlobalExport = (props: DatatableGlobalExportProps) => {
2726
const globalExport = useCallback(async () => {
2827
Loader.open();
2928
const blob = await globalCsvExport.fetcher(
30-
globalCsvExport.fetchPath,
3129
globalCsvExport.title,
3230
).catch(catchError(Alert, t));
3331

client/src/components/forms/UserForm.tsx

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { User } from '@fullstack-typescript-monorepo/prisma';
21
import { LoadingButton } from '@mui/lab';
32
import { Box, Checkbox, Divider, FormControlLabel, Grid, TextField } from '@mui/material';
43
import React from 'react';
54
import { useTranslation } from 'react-i18next';
6-
import UserRoutes from '../../api/UserRoutes';
5+
import { useNavigate } from 'react-router';
6+
import UserRoutes, { UserUpdate } from '../../api/UserRoutes';
77
import { useAlert } from '../../hooks/useAlert';
88
import useForm from '../../hooks/useForm';
99
import { useLoader } from '../../hooks/useLoader';
@@ -30,23 +30,21 @@ const UserForm = ({ data }: Props) => {
3030
const Alert = useAlert();
3131
const Loader = useLoader();
3232
const { t } = useTranslation('user');
33+
const navigate = useNavigate();
3334

3435
const { register, handleSubmit, formState: { isSubmitting }, reset } = useForm<Data>('user', {
3536
defaultValues: data,
3637
});
3738

3839
// Submit user data
3940
const onSubmit = async (formData: Data) => {
40-
const processedData: Partial<User> = {
41+
const processedData: UserUpdate = {
4142
admin: formData.admin,
4243
login: formData.login,
4344
active: true,
44-
personId: formData.idperson,
4545
};
4646

47-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4847
const personData = {
49-
id: formData.idperson,
5048
firstName: formData.firstName,
5149
lastName: formData.lastName,
5250
email: formData.email,
@@ -55,21 +53,29 @@ const UserForm = ({ data }: Props) => {
5553

5654
Loader.open();
5755
if (formData.id) { // Edition
58-
processedData.id = formData.id;
5956
if (formData.password.length) {
6057
await UserRoutes.changePassword(formData.id, formData.password);
6158
}
6259

63-
await UserRoutes.update(formData.id, processedData).then(() => {
60+
await UserRoutes.update(formData.id, {
61+
...processedData,
62+
person: {
63+
update: personData,
64+
},
65+
}).then(() => {
6466
Alert.open('success', 'Saved');
6567
}).catch(catchError(Alert, t));
6668
} else { // Addition
6769
processedData.password = formData.password;
6870
await UserRoutes.insert({
6971
...processedData,
7072
connexionToken: '',
73+
person: {
74+
create: personData,
75+
},
7176
}).then(() => {
7277
Alert.open('success', 'New user added');
78+
navigate('/app/admin/user/list');
7379
reset();
7480
}).catch(catchError(Alert, t));
7581
}
@@ -79,7 +85,7 @@ const UserForm = ({ data }: Props) => {
7985
return (
8086
<form autoComplete="off" onSubmit={handleSubmit(onSubmit)}>
8187
<Grid container spacing={3} sx={{ pb: 2 }}>
82-
<Grid item md={6} xs={12}>
88+
<Grid item xs={12}>
8389
<FormControlLabel
8490
control={<Checkbox {...register('admin', 'checkbox')} defaultChecked={data.admin} />}
8591
label={t('giveAdminRights')}

client/src/hooks/useAlert.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const AlertProvider = ({ children }: AlertProviderProps) => {
4141
return (
4242
<AlertContext.Provider value={methods}>
4343
{children}
44-
<Snackbar onClose={closeAlert} open={alert} sx={{ zIndex: 100 }}>
44+
<Snackbar onClose={closeAlert} open={alert} sx={{ zIndex: 2100 }}>
4545
<Alert onClose={closeAlert} severity={alertSeverity} sx={{ boxShadow: 8 }} variant="filled">
4646
{alertMessage}
4747
</Alert>

client/src/layouts/TableLayout.tsx

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { PrismaInclude } from '@fullstack-typescript-monorepo/core';
12
import { Box, BoxProps, Button, ButtonGroup, Paper } from '@mui/material';
23
import { DataGridProps, GridRowId } from '@mui/x-data-grid';
34
import React, { useCallback, useState } from 'react';
@@ -15,12 +16,12 @@ interface TableOptions extends Omit<DataGridProps, 'rows'> {
1516
}
1617

1718
interface TableLayoutProps<DataType, Model> {
18-
fetchPath: string;
19+
include?: PrismaInclude;
1920
getter: (
20-
fetchPath: string,
2121
state: TableState,
22+
include?: PrismaInclude,
2223
) => Promise<{ data: Model[], count: number }>;
23-
setter?: (id: number, data: Partial<DataType>, fetchPath: string) => Promise<Model>;
24+
setter?: (id: number, data: Partial<DataType>, include?: object) => Promise<Model>;
2425
mapper?: (rows: Model) => DataType;
2526
add?: () => void;
2627
edit?: (id: number) => void;
@@ -39,7 +40,7 @@ interface TableLayoutProps<DataType, Model> {
3940
* Datatable component
4041
*/
4142
const TableLayout = <DataType extends WithId, Model extends WithId>({
42-
fetchPath,
43+
include,
4344
getter,
4445
setter,
4546
mapper,
@@ -70,7 +71,7 @@ const TableLayout = <DataType extends WithId, Model extends WithId>({
7071
*/
7172
const handleGetter = useCallback((params: TableState) => {
7273
if (authed) {
73-
return getter(fetchPath, params).then((response) => ({
74+
return getter(params, include).then((response) => ({
7475
data: response.data.map((item) => ({
7576
deleted, // Hack to force data reload on deletion, useless server-side
7677
...mapper ? mapper(item) : item as unknown as DataType,
@@ -82,23 +83,22 @@ const TableLayout = <DataType extends WithId, Model extends WithId>({
8283
});
8384
}
8485
return Promise.resolve({ data: [], count: 0 });
85-
}, [Alert, authed, deleted, fetchPath, getter, mapper, t]);
86+
}, [Alert, authed, deleted, getter, include, mapper, t]);
8687

8788
// Update actions table on setter call
8889
const handleSetter = useCallback((
8990
id: number,
9091
data: Partial<DataType>,
91-
path: string,
9292
) => new Promise<Model>((resolve, reject) => {
9393
if (setter) {
94-
setter(id, data, path).then((response) => {
94+
setter(id, data, include).then((response) => {
9595
resolve(response);
9696
setNewRecord((prev) => prev + 1);
9797
}).catch(reject);
9898
} else {
9999
reject();
100100
}
101-
}), [setter]);
101+
}), [include, setter]);
102102

103103
// Enable/disable buttons based on row selection
104104
const handleSelection = useCallback((data: GridRowId[]) => {
@@ -182,7 +182,6 @@ const TableLayout = <DataType extends WithId, Model extends WithId>({
182182
<Datatable<DataType, Model>
183183
{...tableOptions}
184184
onSelectionModelChange={handleSelection}
185-
fetchPath={fetchPath}
186185
getter={handleGetter}
187186
setter={setter ? handleSetter : undefined}
188187
globalCsvExport={globalCsvExport}

0 commit comments

Comments
 (0)