Feature/streamline backend requests (#297)

* Introduce "RequestManager"

* Use "RequestManager" - Simple replacements

 - Get rid of all "util/client" imports
 - replace old requests with new "RequestManager"
 - remove "fetcher" from global SWR config
     instead of using the SWR hooks by themselves, the "requestManager" is supposed to be used

* Use "RequestManager" - Do requests via SWR hooks

Use SWR hooks at places where it's easily usable

* Prevent trailing slashes in the "baseUrl"
This commit is contained in:
schroda
2023-05-18 13:25:19 +02:00
committed by GitHub
parent f86c7ea08a
commit a457d80c44
34 changed files with 950 additions and 333 deletions

View File

@@ -13,9 +13,8 @@ import ListItemText from '@mui/material/ListItemText';
import ListItemLink from 'components/util/ListItemLink';
import NavbarContext from 'components/context/NavbarContext';
import LoadingPlaceholder from 'components/util/LoadingPlaceholder';
import { useQuery } from 'util/client';
import { IAbout } from 'typings';
import { useTranslation } from 'react-i18next';
import requestManager from 'lib/RequestManager';
export default function About() {
const { t } = useTranslation();
@@ -26,7 +25,7 @@ export default function About() {
setAction(null);
}, [t]);
const { data: about } = useQuery<IAbout>('/api/v1/settings/about');
const { data: about } = requestManager.useGetAbout();
if (about === undefined) {
return <LoadingPlaceholder />;

View File

@@ -11,11 +11,11 @@ import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import { fromEvent } from 'file-selector';
import client from 'util/client';
import makeToast from 'components/util/Toast';
import ListItemLink from 'components/util/ListItemLink';
import NavbarContext from 'components/context/NavbarContext';
import { useTranslation } from 'react-i18next';
import requestManager from 'lib/RequestManager';
export default function Backup() {
const { t } = useTranslation();
@@ -25,18 +25,11 @@ export default function Backup() {
setAction(null);
}, [t]);
const { baseURL } = client.defaults;
const submitBackup = (file: File) => {
if (file.name.toLowerCase().endsWith('proto.gz')) {
const formData = new FormData();
formData.append('backup.proto.gz', file);
makeToast(t('settings.backup.label.restoring_backup'), 'info');
client
.post('/api/v1/backup/import/file', formData, {
headers: { 'Content-Type': 'multipart/form-data' },
})
requestManager
.restoreBackupFile(file)
.then(() => makeToast(t('settings.backup.label.restored_backup'), 'success'))
.catch(() => makeToast(t('settings.backup.label.backup_restore_failed'), 'error'));
} else if (file.name.toLowerCase().endsWith('json')) {
@@ -76,7 +69,7 @@ export default function Backup() {
return (
<>
<List sx={{ padding: 0 }}>
<ListItemLink to={`${baseURL}/api/v1/backup/export/file`} directLink>
<ListItemLink to={requestManager.getExportBackupUrl()} directLink>
<ListItemText
primary={t('settings.backup.label.create_backup')}
secondary={t('settings.backup.label.create_backup_info')}

View File

@@ -31,10 +31,10 @@ import DialogTitle from '@mui/material/DialogTitle';
import Checkbox from '@mui/material/Checkbox';
import FormControlLabel from '@mui/material/FormControlLabel';
import NavbarContext from 'components/context/NavbarContext';
import client, { useQuery } from 'util/client';
import { ICategory } from 'typings';
import { useTranslation } from 'react-i18next';
import { DEFAULT_FULL_FAB_HEIGHT } from 'components/util/StyledFab';
import requestManager from 'lib/RequestManager';
const getItemStyle = (
isDragging: boolean,
@@ -58,7 +58,7 @@ export default function Categories() {
setAction(null);
}, [t]);
const { data, mutate } = useQuery<ICategory[]>('/api/v1/category/');
const { data, mutate } = requestManager.useGetCategories();
const categories = useMemo(() => {
const res = [...(data ?? [])];
if (res.length > 0 && res[0].name === 'Default') {
@@ -79,10 +79,7 @@ export default function Categories() {
newData.splice(to, 0, removed);
mutate(newData, { revalidate: false });
const formData = new FormData();
formData.append('from', `${from + 1}`);
formData.append('to', `${to + 1}`);
client.patch('/api/v1/category/reorder', formData).finally(() => mutate());
requestManager.reorderCategory(from + 1, to + 1).finally(() => mutate());
};
const onDragEnd = (result: DropResult) => {
@@ -119,21 +116,19 @@ export default function Categories() {
const handleDialogSubmit = () => {
setDialogOpen(false);
const formData = new FormData();
formData.append('name', dialogName);
formData.append('default', dialogDefault.toString());
if (categoryToEdit === -1) {
client.post('/api/v1/category/', formData).finally(() => mutate());
requestManager.createCategory(dialogName).finally(() => mutate());
} else {
const category = categories[categoryToEdit];
client.patch(`/api/v1/category/${category.id}`, formData).finally(() => mutate());
requestManager
.updateCategory(category.id, { name: dialogName, default: dialogDefault })
.finally(() => mutate());
}
};
const deleteCategory = (index: number) => {
const category = categories[index];
client.delete(`/api/v1/category/${category.id}`).finally(() => mutate());
requestManager.deleteCategory(category.id).finally(() => mutate());
};
return (

View File

@@ -11,7 +11,6 @@ import List from '@mui/material/List';
import ListItemText from '@mui/material/ListItemText';
import NavbarContext from 'components/context/NavbarContext';
import ListSubheader from '@mui/material/ListSubheader';
import client, { useQuery } from 'util/client';
import { ICategory, IncludeInGlobalUpdate } from 'typings';
import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
@@ -25,6 +24,7 @@ import { styled } from '@mui/system';
import makeToast from 'components/util/Toast';
import { t as translate } from 'i18next';
import { useTranslation } from 'react-i18next';
import requestManager from 'lib/RequestManager';
const CategoriesDiv = styled('div')({
display: 'flex',
@@ -77,7 +77,7 @@ export default function LibrarySettings() {
setAction(null);
}, [t]);
const { data: categories, isLoading, error: requestError, mutate } = useQuery<ICategory[]>('/api/v1/category/');
const { data: categories, isLoading, error: requestError, mutate } = requestManager.useGetCategories();
const [currentCategories, setCurrentCategories] = useState<ICategory[]>(categories ?? []); // categories to check if response categories changed
const [dialogCategories, setDialogCategories] = useState<ICategory[]>(categories ?? []); // categories that are shown and updated in the dialog
@@ -110,12 +110,8 @@ export default function LibrarySettings() {
requestError,
);
const updateCategory = (category: ICategory) => {
const formData = new FormData();
formData.append('includeInUpdate', `${category.includeInUpdate}`);
return client.patch(`/api/v1/category/${category.id}`, formData);
};
const updateCategory = (category: ICategory) =>
requestManager.updateCategory(category.id, { includeInUpdate: category.includeInUpdate });
const updateCategories = async () => {
const categoriesToUpdate = dialogCategories.filter((category) => {