Loading frontend/src/components/PartTable/PartTable.tsx +3 −9 Original line number Diff line number Diff line Loading @@ -31,16 +31,16 @@ import { export type PartTableInput<T> = { name: SellablePartName; extraCols: string[]; data: T[]; addPart: (arg0: T) => void; deletePart: (id: string) => void; }; export function PartTable<T extends SellablePart>({ name, extraCols, data, addPart, deletePart, }: PartTableInput<T>) { const navigate = useNavigate(); const setOrdering = useSetRecoilState(sortingAtom); Loading Loading @@ -96,9 +96,6 @@ export function PartTable<T extends SellablePart>({ )}{' '} </IconButton> </TableCell> {extraCols.map((elem) => ( <TableCell key={elem}>{elem}</TableCell> ))} <TableCell> Price <IconButton onClick={handleSortPrice}> Loading @@ -125,9 +122,6 @@ export function PartTable<T extends SellablePart>({ <div>{oneRow.name}</div> </Stack> </TableCell> {extraCols.map((elem) => ( <TableCell key={elem}>{oneRow[elem]}</TableCell> ))} <TableCell>{priceToString(oneRow.price)}</TableCell> <TableCell> <Button Loading @@ -143,7 +137,7 @@ export function PartTable<T extends SellablePart>({ <Button variant="contained" onClick={() => { deletePart(oneRow); deletePart(oneRow.id); }} > Delete Loading frontend/src/components/PresetView.tsx +12 −16 Original line number Diff line number Diff line Loading @@ -2,12 +2,12 @@ import { Preset } from '@pcbuilder/common/api'; import { useNavigate } from 'react-router-dom'; import { Button } from '@mui/material'; import { useRecoilValue } from 'recoil'; import { useMutation, useQueryClient } from 'react-query'; import { auth } from '../state/atoms'; import { LinkButton } from './LinkButton.tsx'; import { useConfiguration } from '../hooks/configurationHook'; import presetApi from '../services/presetApi'; import { ErrorView } from './ErrorView.tsx'; import { useDelete } from '../hooks/deleteHook'; export function PresetView({ buildId, Loading @@ -19,23 +19,16 @@ export function PresetView({ const admin = useRecoilValue(auth); const { addPresetAtributes } = useConfiguration(); const navigate = useNavigate(); const queryClient = useQueryClient(); function setEdit() { addPresetAtributes({ id, name, description, categoryId }); navigate(`/presets/${buildId}`); } const { mutate: deletePreset, isLoading, isError, error, } = useMutation([`delete${id}`], (idPreset) => presetApi.delete(idPreset), { onSuccess: () => { queryClient.invalidateQueries([`category${categoryId}`]); queryClient.invalidateQueries(['presets']); }, }); deleteFn: deletePreset, isErrorDelete, errorDelete, deleteLoading, } = useDelete(['presets'], presetApi.delete, [[`category${categoryId}`]]); function deleteFn() { deletePreset(id); } Loading @@ -44,14 +37,17 @@ export function PresetView({ <article className="preset"> <h3 className="preset__name">{name}</h3> <span className="preset__description">{description}</span> {isError ? <ErrorView dataType="preset" error={error} /> : ''} {isErrorDelete ? <ErrorView dataType="preset" error={errorDelete} /> : ''} {admin ? ( <> <Button variant="contained" onClick={setEdit}> View or Edit </Button> <Button variant="contained" disabled={isLoading} onClick={deleteFn}> {' '} <Button variant="contained" disabled={deleteLoading} onClick={deleteFn} > Delete </Button> </> Loading frontend/src/hooks/configurationHook.ts +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import { ConfigurationType, EditBuildType, EditConfigType, PresetConfig, } from '../types/Configuration'; import presetApi from '../services/presetApi'; Loading Loading @@ -101,7 +102,7 @@ export function useConfiguration() { // if not add is edit function isAdd() { return ( configuration.preset?.id === undefined || configuration.id === undefined configuration.preset.id === undefined || configuration.id === undefined ); } Loading Loading @@ -153,7 +154,7 @@ export function useConfiguration() { }); } function addPresetAtributes(preset: Preset) { function addPresetAtributes(preset: PresetConfig) { setConfiguration({ ...configuration, preset }); } Loading frontend/src/hooks/deleteHook.ts 0 → 100644 +29 −0 Original line number Diff line number Diff line import { MutationFunction, useMutation, useQueryClient } from 'react-query'; import { ApiError } from '../types/Error'; export function useDelete( query: string[], deleteFn: MutationFunction<void, string>, additionalQueryies: string[][] = [] ) { const queryClient = useQueryClient(); const { mutate, isLoading, isError, error } = useMutation< void, ApiError, string >([`${query}del`], (id) => deleteFn(id), { onSuccess: () => { queryClient.invalidateQueries(query); additionalQueryies.map((oneQuery) => queryClient.invalidateQueries(oneQuery) ); }, }); return { deleteFn: mutate, deleteLoading: isLoading, errorDelete: error, isErrorDelete: isError, }; } frontend/src/pages/Parts/MemoryParts.tsx +10 −19 Original line number Diff line number Diff line import { useQuery, useMutation, useQueryClient } from 'react-query'; import { useQuery } from 'react-query'; import { Memory } from '@pcbuilder/common/api'; import { useSetRecoilState, useRecoilValue } from 'recoil'; import { PartTable } from '../../components/PartTable/PartTable.tsx'; import { useConfiguration } from '../../hooks/configurationHook'; import { readManyMemories } from '../../services/memoryApi'; import { readManyMemories, deleteMemory as deleteMemoryApi, } from '../../services/memoryApi'; import { memoriesAtom, memoryFiltersAtom } from '../../state/atoms'; import { filteredMemoriesSelector } from '../../state/selectors'; import { useDelete } from '../../hooks/deleteHook'; export function MemoryParts() { const { addMemory, configuration } = useConfiguration(); const setMemories = useSetRecoilState(memoriesAtom); const setMemoryFilters = useSetRecoilState(memoryFiltersAtom); const mem = ['momories']; const queryClient = useQueryClient(); const { mutate: deleteMemory, /* isLoading, isError, error, */ } = useMutation([`memdel`], (id) => memoryApi.delete(id), { onSuccess: () => { queryClient.invalidateQueries(mem); }, }); function deletePart() { deleteMemory(id); } const mem = ['memories']; const { deleteFn } = useDelete(mem, deleteMemoryApi); useQuery({ queryKey: mem, queryFn: async () => Loading Loading @@ -55,10 +46,10 @@ export function MemoryParts() { return ( <PartTable<Memory> name="Memory" extraCols={[]} data={filteredMemories ?? []} addPart={addMemory} deletePart={deletePart} deletePart={deleteFn} deleteLoad={deleteLoad} /> ); } Loading
frontend/src/components/PartTable/PartTable.tsx +3 −9 Original line number Diff line number Diff line Loading @@ -31,16 +31,16 @@ import { export type PartTableInput<T> = { name: SellablePartName; extraCols: string[]; data: T[]; addPart: (arg0: T) => void; deletePart: (id: string) => void; }; export function PartTable<T extends SellablePart>({ name, extraCols, data, addPart, deletePart, }: PartTableInput<T>) { const navigate = useNavigate(); const setOrdering = useSetRecoilState(sortingAtom); Loading Loading @@ -96,9 +96,6 @@ export function PartTable<T extends SellablePart>({ )}{' '} </IconButton> </TableCell> {extraCols.map((elem) => ( <TableCell key={elem}>{elem}</TableCell> ))} <TableCell> Price <IconButton onClick={handleSortPrice}> Loading @@ -125,9 +122,6 @@ export function PartTable<T extends SellablePart>({ <div>{oneRow.name}</div> </Stack> </TableCell> {extraCols.map((elem) => ( <TableCell key={elem}>{oneRow[elem]}</TableCell> ))} <TableCell>{priceToString(oneRow.price)}</TableCell> <TableCell> <Button Loading @@ -143,7 +137,7 @@ export function PartTable<T extends SellablePart>({ <Button variant="contained" onClick={() => { deletePart(oneRow); deletePart(oneRow.id); }} > Delete Loading
frontend/src/components/PresetView.tsx +12 −16 Original line number Diff line number Diff line Loading @@ -2,12 +2,12 @@ import { Preset } from '@pcbuilder/common/api'; import { useNavigate } from 'react-router-dom'; import { Button } from '@mui/material'; import { useRecoilValue } from 'recoil'; import { useMutation, useQueryClient } from 'react-query'; import { auth } from '../state/atoms'; import { LinkButton } from './LinkButton.tsx'; import { useConfiguration } from '../hooks/configurationHook'; import presetApi from '../services/presetApi'; import { ErrorView } from './ErrorView.tsx'; import { useDelete } from '../hooks/deleteHook'; export function PresetView({ buildId, Loading @@ -19,23 +19,16 @@ export function PresetView({ const admin = useRecoilValue(auth); const { addPresetAtributes } = useConfiguration(); const navigate = useNavigate(); const queryClient = useQueryClient(); function setEdit() { addPresetAtributes({ id, name, description, categoryId }); navigate(`/presets/${buildId}`); } const { mutate: deletePreset, isLoading, isError, error, } = useMutation([`delete${id}`], (idPreset) => presetApi.delete(idPreset), { onSuccess: () => { queryClient.invalidateQueries([`category${categoryId}`]); queryClient.invalidateQueries(['presets']); }, }); deleteFn: deletePreset, isErrorDelete, errorDelete, deleteLoading, } = useDelete(['presets'], presetApi.delete, [[`category${categoryId}`]]); function deleteFn() { deletePreset(id); } Loading @@ -44,14 +37,17 @@ export function PresetView({ <article className="preset"> <h3 className="preset__name">{name}</h3> <span className="preset__description">{description}</span> {isError ? <ErrorView dataType="preset" error={error} /> : ''} {isErrorDelete ? <ErrorView dataType="preset" error={errorDelete} /> : ''} {admin ? ( <> <Button variant="contained" onClick={setEdit}> View or Edit </Button> <Button variant="contained" disabled={isLoading} onClick={deleteFn}> {' '} <Button variant="contained" disabled={deleteLoading} onClick={deleteFn} > Delete </Button> </> Loading
frontend/src/hooks/configurationHook.ts +3 −2 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import { ConfigurationType, EditBuildType, EditConfigType, PresetConfig, } from '../types/Configuration'; import presetApi from '../services/presetApi'; Loading Loading @@ -101,7 +102,7 @@ export function useConfiguration() { // if not add is edit function isAdd() { return ( configuration.preset?.id === undefined || configuration.id === undefined configuration.preset.id === undefined || configuration.id === undefined ); } Loading Loading @@ -153,7 +154,7 @@ export function useConfiguration() { }); } function addPresetAtributes(preset: Preset) { function addPresetAtributes(preset: PresetConfig) { setConfiguration({ ...configuration, preset }); } Loading
frontend/src/hooks/deleteHook.ts 0 → 100644 +29 −0 Original line number Diff line number Diff line import { MutationFunction, useMutation, useQueryClient } from 'react-query'; import { ApiError } from '../types/Error'; export function useDelete( query: string[], deleteFn: MutationFunction<void, string>, additionalQueryies: string[][] = [] ) { const queryClient = useQueryClient(); const { mutate, isLoading, isError, error } = useMutation< void, ApiError, string >([`${query}del`], (id) => deleteFn(id), { onSuccess: () => { queryClient.invalidateQueries(query); additionalQueryies.map((oneQuery) => queryClient.invalidateQueries(oneQuery) ); }, }); return { deleteFn: mutate, deleteLoading: isLoading, errorDelete: error, isErrorDelete: isError, }; }
frontend/src/pages/Parts/MemoryParts.tsx +10 −19 Original line number Diff line number Diff line import { useQuery, useMutation, useQueryClient } from 'react-query'; import { useQuery } from 'react-query'; import { Memory } from '@pcbuilder/common/api'; import { useSetRecoilState, useRecoilValue } from 'recoil'; import { PartTable } from '../../components/PartTable/PartTable.tsx'; import { useConfiguration } from '../../hooks/configurationHook'; import { readManyMemories } from '../../services/memoryApi'; import { readManyMemories, deleteMemory as deleteMemoryApi, } from '../../services/memoryApi'; import { memoriesAtom, memoryFiltersAtom } from '../../state/atoms'; import { filteredMemoriesSelector } from '../../state/selectors'; import { useDelete } from '../../hooks/deleteHook'; export function MemoryParts() { const { addMemory, configuration } = useConfiguration(); const setMemories = useSetRecoilState(memoriesAtom); const setMemoryFilters = useSetRecoilState(memoryFiltersAtom); const mem = ['momories']; const queryClient = useQueryClient(); const { mutate: deleteMemory, /* isLoading, isError, error, */ } = useMutation([`memdel`], (id) => memoryApi.delete(id), { onSuccess: () => { queryClient.invalidateQueries(mem); }, }); function deletePart() { deleteMemory(id); } const mem = ['memories']; const { deleteFn } = useDelete(mem, deleteMemoryApi); useQuery({ queryKey: mem, queryFn: async () => Loading Loading @@ -55,10 +46,10 @@ export function MemoryParts() { return ( <PartTable<Memory> name="Memory" extraCols={[]} data={filteredMemories ?? []} addPart={addMemory} deletePart={deletePart} deletePart={deleteFn} deleteLoad={deleteLoad} /> ); }