pl-fe: migrate backups to tanstack query
Signed-off-by: mkljczk <git@mkljczk.pl>
This commit is contained in:
parent
15d7d4dfc3
commit
29cd637a6b
10 changed files with 42 additions and 129 deletions
|
@ -256,7 +256,7 @@ interface PlApiClientConstructorOpts {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Clients
|
* @category Clients
|
||||||
*
|
*
|
||||||
* Mastodon API client.
|
* Mastodon API client.
|
||||||
*/
|
*/
|
||||||
class PlApiClient {
|
class PlApiClient {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { datetimeSchema, mimeSchema } from './utils';
|
||||||
*/
|
*/
|
||||||
const backupSchema = v.object({
|
const backupSchema = v.object({
|
||||||
id: v.pipe(v.unknown(), v.transform(String)),
|
id: v.pipe(v.unknown(), v.transform(String)),
|
||||||
contentType: mimeSchema,
|
content_type: mimeSchema,
|
||||||
file_size: v.fallback(v.number(), 0),
|
file_size: v.fallback(v.number(), 0),
|
||||||
inserted_at: datetimeSchema,
|
inserted_at: datetimeSchema,
|
||||||
processed: v.fallback(v.boolean(), false),
|
processed: v.fallback(v.boolean(), false),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pl-api",
|
"name": "pl-api",
|
||||||
"version": "1.0.0-rc.3",
|
"version": "1.0.0-rc.4",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"homepage": "https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-api",
|
"homepage": "https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-api",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
@ -101,7 +101,7 @@
|
||||||
"multiselect-react-dropdown": "^2.0.25",
|
"multiselect-react-dropdown": "^2.0.25",
|
||||||
"mutative": "^1.1.0",
|
"mutative": "^1.1.0",
|
||||||
"path-browserify": "^1.0.1",
|
"path-browserify": "^1.0.1",
|
||||||
"pl-api": "^1.0.0-rc.3",
|
"pl-api": "^1.0.0-rc.4",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"punycode": "^2.1.1",
|
"punycode": "^2.1.1",
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
import { getClient } from '../api';
|
|
||||||
|
|
||||||
import type { Backup } from 'pl-api';
|
|
||||||
import type { AppDispatch, RootState } from 'pl-fe/store';
|
|
||||||
|
|
||||||
const BACKUPS_FETCH_REQUEST = 'BACKUPS_FETCH_REQUEST' as const;
|
|
||||||
const BACKUPS_FETCH_SUCCESS = 'BACKUPS_FETCH_SUCCESS' as const;
|
|
||||||
const BACKUPS_FETCH_FAIL = 'BACKUPS_FETCH_FAIL' as const;
|
|
||||||
|
|
||||||
const BACKUPS_CREATE_REQUEST = 'BACKUPS_CREATE_REQUEST' as const;
|
|
||||||
const BACKUPS_CREATE_SUCCESS = 'BACKUPS_CREATE_SUCCESS' as const;
|
|
||||||
const BACKUPS_CREATE_FAIL = 'BACKUPS_CREATE_FAIL' as const;
|
|
||||||
|
|
||||||
interface BackupsFetchRequestAction {
|
|
||||||
type: typeof BACKUPS_FETCH_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BackupsFetchSuccessAction {
|
|
||||||
type: typeof BACKUPS_FETCH_SUCCESS;
|
|
||||||
backups: Array<Backup>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BackupsFetchFailAction {
|
|
||||||
type: typeof BACKUPS_FETCH_FAIL;
|
|
||||||
error: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchBackups = () =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
dispatch<BackupsFetchRequestAction>({ type: BACKUPS_FETCH_REQUEST });
|
|
||||||
|
|
||||||
return getClient(getState).settings.getBackups().then((backups) =>
|
|
||||||
dispatch<BackupsFetchSuccessAction>({ type: BACKUPS_FETCH_SUCCESS, backups }),
|
|
||||||
).catch(error => {
|
|
||||||
dispatch<BackupsFetchFailAction>({ type: BACKUPS_FETCH_FAIL, error });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
interface BackupsCreateRequestAction {
|
|
||||||
type: typeof BACKUPS_CREATE_REQUEST;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BackupsCreateSuccessAction {
|
|
||||||
type: typeof BACKUPS_CREATE_SUCCESS;
|
|
||||||
backups: Array<Backup>;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BackupsCreateFailAction {
|
|
||||||
type: typeof BACKUPS_CREATE_FAIL;
|
|
||||||
error: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
const createBackup = () =>
|
|
||||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
|
||||||
dispatch<BackupsCreateRequestAction>({ type: BACKUPS_CREATE_REQUEST });
|
|
||||||
return getClient(getState).settings.createBackup().then((backup) =>
|
|
||||||
dispatch<BackupsCreateSuccessAction>({ type: BACKUPS_CREATE_SUCCESS, backups: [backup] }),
|
|
||||||
).catch(error => {
|
|
||||||
dispatch<BackupsCreateFailAction>({ type: BACKUPS_CREATE_FAIL, error });
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
type BackupsAction =
|
|
||||||
| BackupsFetchRequestAction
|
|
||||||
| BackupsFetchSuccessAction
|
|
||||||
| BackupsFetchFailAction
|
|
||||||
| BackupsCreateRequestAction
|
|
||||||
| BackupsCreateSuccessAction
|
|
||||||
| BackupsCreateFailAction;
|
|
||||||
|
|
||||||
export {
|
|
||||||
BACKUPS_FETCH_REQUEST,
|
|
||||||
BACKUPS_FETCH_SUCCESS,
|
|
||||||
BACKUPS_FETCH_FAIL,
|
|
||||||
BACKUPS_CREATE_REQUEST,
|
|
||||||
BACKUPS_CREATE_SUCCESS,
|
|
||||||
BACKUPS_CREATE_FAIL,
|
|
||||||
fetchBackups,
|
|
||||||
createBackup,
|
|
||||||
type BackupsAction,
|
|
||||||
};
|
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useEffect, useState } from 'react';
|
import React from 'react';
|
||||||
import { FormattedDate, defineMessages, useIntl } from 'react-intl';
|
import { FormattedDate, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { fetchBackups, createBackup } from 'pl-fe/actions/backups';
|
|
||||||
import Button from 'pl-fe/components/ui/button';
|
import Button from 'pl-fe/components/ui/button';
|
||||||
import Card from 'pl-fe/components/ui/card';
|
import Card from 'pl-fe/components/ui/card';
|
||||||
import Column from 'pl-fe/components/ui/column';
|
import Column from 'pl-fe/components/ui/column';
|
||||||
|
@ -10,8 +9,7 @@ import HStack from 'pl-fe/components/ui/hstack';
|
||||||
import Spinner from 'pl-fe/components/ui/spinner';
|
import Spinner from 'pl-fe/components/ui/spinner';
|
||||||
import Stack from 'pl-fe/components/ui/stack';
|
import Stack from 'pl-fe/components/ui/stack';
|
||||||
import Text from 'pl-fe/components/ui/text';
|
import Text from 'pl-fe/components/ui/text';
|
||||||
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
|
import { useBackupsQuery, useCreateBackupMutation } from 'pl-fe/queries/settings/use-backups';
|
||||||
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
|
|
||||||
|
|
||||||
import type { Backup as BackupEntity } from 'pl-api';
|
import type { Backup as BackupEntity } from 'pl-api';
|
||||||
|
|
||||||
|
@ -63,23 +61,15 @@ const Backup: React.FC<IBackup> = ({ backup }) => {
|
||||||
|
|
||||||
const Backups = () => {
|
const Backups = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
|
|
||||||
const backups = useAppSelector((state) => Object.values(state.backups).toSorted((a, b) => a.inserted_at.localeCompare(b.inserted_at)));
|
const { data: backups = [], isLoading } = useBackupsQuery();
|
||||||
|
const { mutate: createBackup } = useCreateBackupMutation();
|
||||||
const [isLoading, setIsLoading] = useState(true);
|
|
||||||
|
|
||||||
const handleCreateBackup: React.MouseEventHandler = e => {
|
const handleCreateBackup: React.MouseEventHandler = e => {
|
||||||
dispatch(createBackup());
|
createBackup();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(fetchBackups()).then(() => {
|
|
||||||
setIsLoading(false);
|
|
||||||
}).catch(() => {});
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const showLoading = isLoading && backups.length === 0;
|
const showLoading = isLoading && backups.length === 0;
|
||||||
|
|
||||||
const emptyMessage = (
|
const emptyMessage = (
|
||||||
|
|
29
packages/pl-fe/src/queries/settings/use-backups.ts
Normal file
29
packages/pl-fe/src/queries/settings/use-backups.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { useClient } from 'pl-fe/hooks/use-client';
|
||||||
|
|
||||||
|
import { queryClient } from '../client';
|
||||||
|
|
||||||
|
const useBackupsQuery = () => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useQuery({
|
||||||
|
queryKey: ['settings', 'backups'],
|
||||||
|
queryFn: () => client.settings.getBackups(),
|
||||||
|
select: (backups) => backups.toSorted((a, b) => a.inserted_at.localeCompare(b.inserted_at)),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const useCreateBackupMutation = () => {
|
||||||
|
const client = useClient();
|
||||||
|
|
||||||
|
return useMutation({
|
||||||
|
mutationKey: ['settings', 'backups'],
|
||||||
|
mutationFn: () => client.settings.createBackup(),
|
||||||
|
onSuccess: () => queryClient.invalidateQueries({
|
||||||
|
queryKey: ['settings', 'backups'],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export { useBackupsQuery, useCreateBackupMutation };
|
|
@ -1,23 +0,0 @@
|
||||||
import { create } from 'mutative';
|
|
||||||
|
|
||||||
import { BACKUPS_FETCH_SUCCESS, BACKUPS_CREATE_SUCCESS, type BackupsAction } from '../actions/backups';
|
|
||||||
|
|
||||||
import type { Backup } from 'pl-api';
|
|
||||||
|
|
||||||
type State = Record<string, Backup>;
|
|
||||||
|
|
||||||
const initialState: State = {};
|
|
||||||
|
|
||||||
const backups = (state = initialState, action: BackupsAction) => {
|
|
||||||
switch (action.type) {
|
|
||||||
case BACKUPS_FETCH_SUCCESS:
|
|
||||||
case BACKUPS_CREATE_SUCCESS:
|
|
||||||
return create(state, (draft) => action.backups.forEach((backup) => draft[backup.inserted_at] = backup));
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export {
|
|
||||||
backups as default,
|
|
||||||
};
|
|
|
@ -9,7 +9,6 @@ import admin from './admin';
|
||||||
import admin_user_index from './admin-user-index';
|
import admin_user_index from './admin-user-index';
|
||||||
import aliases from './aliases';
|
import aliases from './aliases';
|
||||||
import auth from './auth';
|
import auth from './auth';
|
||||||
import backups from './backups';
|
|
||||||
import compose from './compose';
|
import compose from './compose';
|
||||||
import contexts from './contexts';
|
import contexts from './contexts';
|
||||||
import conversations from './conversations';
|
import conversations from './conversations';
|
||||||
|
@ -43,7 +42,6 @@ const reducers = {
|
||||||
admin_user_index,
|
admin_user_index,
|
||||||
aliases,
|
aliases,
|
||||||
auth,
|
auth,
|
||||||
backups,
|
|
||||||
compose,
|
compose,
|
||||||
contexts,
|
contexts,
|
||||||
conversations,
|
conversations,
|
||||||
|
|
|
@ -7834,10 +7834,10 @@ pkg-dir@^4.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
find-up "^4.0.0"
|
find-up "^4.0.0"
|
||||||
|
|
||||||
pl-api@^1.0.0-rc.3:
|
pl-api@^1.0.0-rc.4:
|
||||||
version "1.0.0-rc.3"
|
version "1.0.0-rc.4"
|
||||||
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-1.0.0-rc.3.tgz#36a3f093bd2935e4b59a2efaa225a5baa4af5dea"
|
resolved "https://registry.yarnpkg.com/pl-api/-/pl-api-1.0.0-rc.4.tgz#6119fdef8362104ba238a0e33620d35982b91be6"
|
||||||
integrity sha512-ILNesTpz+Y+4S/65S2KX597YBXxEmYuuxKGkzX56cny8tBReiw4ar07H6ZrjEBog8Ramq6N6IaRch5Dt9ZPE3A==
|
integrity sha512-TsORtRUV41NAp4McbYrhcw4pCAiiM99q+gGJpPoPOnyw/5G69JQ1lBCcDFYQzsbgvuQ4yseM5kZolNO6sTxRGg==
|
||||||
dependencies:
|
dependencies:
|
||||||
blurhash "^2.0.5"
|
blurhash "^2.0.5"
|
||||||
http-link-header "^1.1.3"
|
http-link-header "^1.1.3"
|
||||||
|
|
Loading…
Reference in a new issue