mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
B: Fix cache invalidation and error handling
This commit is contained in:
parent
44b0705521
commit
d182b2d34e
|
@ -1,16 +1,29 @@
|
||||||
import { Suspense } from 'react';
|
import { Suspense } from 'react';
|
||||||
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
import { Outlet } from 'react-router';
|
import { Outlet } from 'react-router';
|
||||||
|
|
||||||
import ConceptToaster from '@/app/ConceptToaster';
|
import ConceptToaster from '@/app/ConceptToaster';
|
||||||
import Footer from '@/app/Footer';
|
import Footer from '@/app/Footer';
|
||||||
import Navigation from '@/app/Navigation';
|
import Navigation from '@/app/Navigation';
|
||||||
import { NavigationState } from '@/app/Navigation/NavigationContext';
|
|
||||||
import Loader from '@/components/ui/Loader';
|
import Loader from '@/components/ui/Loader';
|
||||||
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
|
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/appLayout';
|
||||||
import { globals } from '@/utils/constants';
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
|
import ErrorFallback from './ErrorFallback';
|
||||||
import { GlobalDialogs } from './GlobalDialogs';
|
import { GlobalDialogs } from './GlobalDialogs';
|
||||||
import { GlobalTooltips } from './GlobalTooltips';
|
import { GlobalTooltips } from './GlobalTooltips';
|
||||||
|
import { NavigationState } from './Navigation/NavigationContext';
|
||||||
|
|
||||||
|
const resetState = () => {
|
||||||
|
console.log('Resetting state after error fallback');
|
||||||
|
};
|
||||||
|
|
||||||
|
const logError = (error: Error, info: { componentStack?: string | null | undefined }) => {
|
||||||
|
console.log('Error fallback: ' + error.message);
|
||||||
|
if (info.componentStack) {
|
||||||
|
console.log('Component stack: ' + info.componentStack);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function ApplicationLayout() {
|
function ApplicationLayout() {
|
||||||
const mainHeight = useMainHeight();
|
const mainHeight = useMainHeight();
|
||||||
|
@ -23,6 +36,7 @@ function ApplicationLayout() {
|
||||||
// TODO: prefetch data
|
// TODO: prefetch data
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<ErrorBoundary FallbackComponent={ErrorFallback} onError={logError} onReset={resetState}>
|
||||||
<NavigationState>
|
<NavigationState>
|
||||||
<div className='min-w-[20rem] antialiased h-full max-w-[120rem] mx-auto'>
|
<div className='min-w-[20rem] antialiased h-full max-w-[120rem] mx-auto'>
|
||||||
<ConceptToaster
|
<ConceptToaster
|
||||||
|
@ -54,6 +68,7 @@ function ApplicationLayout() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</NavigationState>
|
</NavigationState>
|
||||||
|
</ErrorBoundary>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ import Button from '@/components/ui/Button';
|
||||||
|
|
||||||
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
function ErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col gap-3 items-center antialiased' role='alert'>
|
<div className='flex flex-col gap-3 my-3 items-center antialiased' role='alert'>
|
||||||
<h1>Что-то пошло не так!</h1>
|
<h1 className='my-2'>Что-то пошло не так!</h1>
|
||||||
<Button onClick={resetErrorBoundary} text='Попробовать еще раз' />
|
<Button onClick={resetErrorBoundary} text='Попробовать еще раз' />
|
||||||
<InfoError error={error as Error} />
|
<InfoError error={error as Error} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,32 +2,13 @@
|
||||||
|
|
||||||
import { QueryClientProvider } from '@tanstack/react-query';
|
import { QueryClientProvider } from '@tanstack/react-query';
|
||||||
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
|
||||||
import { IntlProvider } from 'react-intl';
|
import { IntlProvider } from 'react-intl';
|
||||||
|
|
||||||
import { queryClient } from '@/backend/queryClient';
|
import { queryClient } from '@/backend/queryClient';
|
||||||
|
|
||||||
import ErrorFallback from './ErrorFallback';
|
|
||||||
|
|
||||||
const resetState = () => {
|
|
||||||
console.log('Resetting state after error fallback');
|
|
||||||
};
|
|
||||||
|
|
||||||
const logError = (error: Error, info: { componentStack?: string | null | undefined }) => {
|
|
||||||
console.log('Error fallback: ' + error.message);
|
|
||||||
if (info.componentStack) {
|
|
||||||
console.log('Component stack: ' + info.componentStack);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
function GlobalProviders({ children }: React.PropsWithChildren) {
|
function GlobalProviders({ children }: React.PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary
|
|
||||||
FallbackComponent={ErrorFallback}
|
|
||||||
onReset={resetState}
|
|
||||||
onError={logError}
|
|
||||||
>
|
|
||||||
<IntlProvider locale='ru' defaultLocale='ru'>
|
<IntlProvider locale='ru' defaultLocale='ru'>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
|
|
||||||
|
@ -35,8 +16,7 @@ function GlobalProviders({ children }: React.PropsWithChildren) {
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</IntlProvider>
|
</IntlProvider>);
|
||||||
</ErrorBoundary>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default GlobalProviders;
|
export default GlobalProviders;
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const useChangePassword = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: ['change-password'],
|
mutationKey: ['change-password'],
|
||||||
mutationFn: authApi.changePassword,
|
mutationFn: authApi.changePassword,
|
||||||
onSettled: async () => await client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
onSettled: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
changePassword: (
|
changePassword: (
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const useLogin = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: ['login'],
|
mutationKey: ['login'],
|
||||||
mutationFn: authApi.login,
|
mutationFn: authApi.login,
|
||||||
onSettled: async () => await client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
onSettled: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
login: (
|
login: (
|
||||||
|
|
|
@ -7,7 +7,7 @@ export const useLogout = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: ['logout'],
|
mutationKey: ['logout'],
|
||||||
mutationFn: authApi.logout,
|
mutationFn: authApi.logout,
|
||||||
onSettled: async () => await client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
onSettled: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
||||||
});
|
});
|
||||||
return { logout: (onSuccess?: () => void) => mutation.mutate(undefined, { onSuccess }) };
|
return { logout: (onSuccess?: () => void) => mutation.mutate(undefined, { onSuccess }) };
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,12 +7,12 @@ export const useResetPassword = () => {
|
||||||
const validateMutation = useMutation({
|
const validateMutation = useMutation({
|
||||||
mutationKey: ['reset-password'],
|
mutationKey: ['reset-password'],
|
||||||
mutationFn: authApi.validatePasswordToken,
|
mutationFn: authApi.validatePasswordToken,
|
||||||
onSuccess: async () => await client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
onSuccess: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
||||||
});
|
});
|
||||||
const resetMutation = useMutation({
|
const resetMutation = useMutation({
|
||||||
mutationKey: ['reset-password'],
|
mutationKey: ['reset-password'],
|
||||||
mutationFn: authApi.resetPassword,
|
mutationFn: authApi.resetPassword,
|
||||||
onSuccess: async () => await client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
onSuccess: () => client.invalidateQueries({ queryKey: [authApi.baseKey] })
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
validateToken: (
|
validateToken: (
|
||||||
|
|
|
@ -2,6 +2,8 @@ import { queryOptions } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
|
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
|
||||||
import { DELAYS } from '@/backend/configuration';
|
import { DELAYS } from '@/backend/configuration';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import {
|
import {
|
||||||
AccessPolicy,
|
AccessPolicy,
|
||||||
ILibraryItem,
|
ILibraryItem,
|
||||||
|
@ -15,9 +17,6 @@ import { ConstituentaID, IRSFormData } from '@/models/rsform';
|
||||||
import { UserID } from '@/models/user';
|
import { UserID } from '@/models/user';
|
||||||
import { information } from '@/utils/labels';
|
import { information } from '@/utils/labels';
|
||||||
|
|
||||||
import { ossApi } from '../oss/api';
|
|
||||||
import { rsformsApi } from '../rsform/api';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents update data for renaming Location.
|
* Represents update data for renaming Location.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -10,7 +10,7 @@ export const useCloneItem = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [libraryApi.baseKey, 'clone-item'],
|
mutationKey: [libraryApi.baseKey, 'clone-item'],
|
||||||
mutationFn: libraryApi.cloneItem,
|
mutationFn: libraryApi.cloneItem,
|
||||||
onSuccess: async () => await client.invalidateQueries({ queryKey: [libraryApi.baseKey] })
|
onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] })
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
cloneItem: (
|
cloneItem: (
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
@ -9,11 +11,14 @@ export const useDeleteItem = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [libraryApi.baseKey, 'delete-item'],
|
mutationKey: [libraryApi.baseKey, 'delete-item'],
|
||||||
mutationFn: libraryApi.deleteItem,
|
mutationFn: libraryApi.deleteItem,
|
||||||
onSuccess: async (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
await client.cancelQueries({ queryKey: [libraryApi.libraryListKey] });
|
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.filter(item => item.id !== variables)
|
prev?.filter(item => item.id !== variables)
|
||||||
);
|
);
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({ queryKey: rsformsApi.getRSFormQueryOptions({ itemID: variables }).queryKey })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
import { useQuery } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { ILibraryItemVersioned, LibraryItemID, LibraryItemType } from '@/models/library';
|
|
||||||
|
|
||||||
import { ossApi } from '../oss/api';
|
|
||||||
import { rsformsApi } from '../rsform/api';
|
|
||||||
|
|
||||||
export function useLibraryItem({ itemID, itemType }: { itemID: LibraryItemID; itemType: LibraryItemType }) {
|
|
||||||
const { data: rsForm } = useQuery({
|
|
||||||
...rsformsApi.getRSFormQueryOptions({ itemID }),
|
|
||||||
enabled: itemType === LibraryItemType.RSFORM
|
|
||||||
});
|
|
||||||
const { data: oss } = useQuery({
|
|
||||||
...ossApi.getOssQueryOptions({ itemID }),
|
|
||||||
enabled: itemType === LibraryItemType.OSS
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
item:
|
|
||||||
itemType === LibraryItemType.RSFORM
|
|
||||||
? (rsForm as ILibraryItemVersioned | undefined)
|
|
||||||
: (oss as ILibraryItemVersioned | undefined)
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { useIsMutating } from '@tanstack/react-query';
|
import { useIsMutating } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { ossApi } from '../oss/api';
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { rsformsApi } from '../rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
|
||||||
export const useIsProcessingLibrary = () => {
|
export const useMutatingLibrary = () => {
|
||||||
const countMutations = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
const countMutations = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
||||||
const countOss = useIsMutating({ mutationKey: [ossApi.baseKey] });
|
const countOss = useIsMutating({ mutationKey: [ossApi.baseKey] });
|
||||||
const countRSForm = useIsMutating({ mutationKey: [rsformsApi.baseKey] });
|
const countRSForm = useIsMutating({ mutationKey: [rsformsApi.baseKey] });
|
|
@ -1,5 +1,8 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
|
|
||||||
import { IRenameLocationDTO, libraryApi } from './api';
|
import { IRenameLocationDTO, libraryApi } from './api';
|
||||||
|
|
||||||
export const useRenameLocation = () => {
|
export const useRenameLocation = () => {
|
||||||
|
@ -7,7 +10,12 @@ export const useRenameLocation = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [libraryApi.baseKey, 'rename-location'],
|
mutationKey: [libraryApi.baseKey, 'rename-location'],
|
||||||
mutationFn: libraryApi.renameLocation,
|
mutationFn: libraryApi.renameLocation,
|
||||||
onSuccess: () => client.invalidateQueries({ queryKey: [libraryApi.baseKey] })
|
onSuccess: () =>
|
||||||
|
Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [libraryApi.baseKey] }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] }),
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] })
|
||||||
|
])
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
renameLocation: (
|
renameLocation: (
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { AccessPolicy, ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
|
import { AccessPolicy, ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
import { IOperationSchemaData } from '@/models/oss';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
|
||||||
|
@ -11,21 +13,29 @@ export const useSetAccessPolicy = () => {
|
||||||
mutationKey: [libraryApi.baseKey, 'set-location'],
|
mutationKey: [libraryApi.baseKey, 'set-location'],
|
||||||
mutationFn: libraryApi.setAccessPolicy,
|
mutationFn: libraryApi.setAccessPolicy,
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
|
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
|
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey);
|
||||||
|
if (ossData) {
|
||||||
|
client.setQueryData(ossKey, { ...ossData, access_policy: variables.policy });
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
...ossData.items
|
||||||
|
.map(item => {
|
||||||
|
if (!item.result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
||||||
|
return client.invalidateQueries({ queryKey: itemKey });
|
||||||
|
})
|
||||||
|
.filter(item => !!item)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
|
client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, access_policy: variables.policy }));
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.map(item => (item.id === variables.itemID ? { ...item, access_policy: variables.policy } : item))
|
prev?.map(item => (item.id === variables.itemID ? { ...item, access_policy: variables.policy } : item))
|
||||||
);
|
);
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, prev => {
|
|
||||||
if (!prev) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (prev.item_type === LibraryItemType.OSS) {
|
|
||||||
client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] }).catch(console.error);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
access_policy: variables.policy
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { UserID } from '@/models/user';
|
import { UserID } from '@/models/user';
|
||||||
|
|
||||||
import { ossApi } from '../oss/api';
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
|
||||||
export const useSetEditors = () => {
|
export const useSetEditors = () => {
|
||||||
|
@ -17,20 +17,22 @@ export const useSetEditors = () => {
|
||||||
const ossData = client.getQueryData(ossKey);
|
const ossData = client.getQueryData(ossKey);
|
||||||
if (ossData) {
|
if (ossData) {
|
||||||
client.setQueryData(ossKey, { ...ossData, editors: variables.editors });
|
client.setQueryData(ossKey, { ...ossData, editors: variables.editors });
|
||||||
Promise.allSettled([
|
return Promise.allSettled(
|
||||||
...ossData.items.map(item => {
|
ossData.items
|
||||||
|
.map(item => {
|
||||||
if (!item.result) {
|
if (!item.result) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
||||||
return client.invalidateQueries({ queryKey: itemKey });
|
return client.invalidateQueries({ queryKey: itemKey });
|
||||||
})
|
})
|
||||||
]).catch(console.error);
|
.filter(item => !!item)
|
||||||
} else {
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, editors: variables.editors }));
|
client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, editors: variables.editors }));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
|
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
import { IOperationSchemaData } from '@/models/oss';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
|
||||||
|
@ -11,43 +13,29 @@ export const useSetLocation = () => {
|
||||||
mutationKey: [libraryApi.baseKey, 'set-location'],
|
mutationKey: [libraryApi.baseKey, 'set-location'],
|
||||||
mutationFn: libraryApi.setLocation,
|
mutationFn: libraryApi.setLocation,
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
// const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
|
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
// const ossData = client.getQueryData(ossKey);
|
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey);
|
||||||
// if (ossData) {
|
if (ossData) {
|
||||||
// client.setQueryData(ossKey, { ...ossData, editors: variables.editors });
|
client.setQueryData(ossKey, { ...ossData, location: variables.location });
|
||||||
// Promise.allSettled([
|
return Promise.allSettled([
|
||||||
// client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
// ...ossData.items.map(item => {
|
...ossData.items
|
||||||
// if (!item.result) {
|
.map(item => {
|
||||||
// return;
|
if (!item.result) {
|
||||||
// }
|
return;
|
||||||
// const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
}
|
||||||
// return client.invalidateQueries({ queryKey: itemKey });
|
const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
||||||
// })
|
return client.invalidateQueries({ queryKey: itemKey });
|
||||||
// ]).catch(console.error);
|
})
|
||||||
// } else {
|
.filter(item => !!item)
|
||||||
// const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
]);
|
||||||
// client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, editors: variables.editors }));
|
}
|
||||||
// client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
|
||||||
// prev?.map(item => (item.id === variables.itemID ? { ...item, editors: variables.editors } : item))
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
|
client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, location: variables.location }));
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.map(item => (item.id === variables.itemID ? { ...item, location: variables.location } : item))
|
prev?.map(item => (item.id === variables.itemID ? { ...item, location: variables.location } : item))
|
||||||
);
|
);
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, prev => {
|
|
||||||
if (!prev) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (prev.item_type === LibraryItemType.OSS) {
|
|
||||||
client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] }).catch(console.error);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
location: variables.location
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { ILibraryItem, LibraryItemID, LibraryItemType } from '@/models/library';
|
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
import { IOperationSchemaData } from '@/models/oss';
|
||||||
import { UserID } from '@/models/user';
|
import { UserID } from '@/models/user';
|
||||||
|
|
||||||
import { libraryApi } from './api';
|
import { libraryApi } from './api';
|
||||||
|
@ -12,21 +14,29 @@ export const useSetOwner = () => {
|
||||||
mutationKey: [libraryApi.baseKey, 'set-owner'],
|
mutationKey: [libraryApi.baseKey, 'set-owner'],
|
||||||
mutationFn: libraryApi.setOwner,
|
mutationFn: libraryApi.setOwner,
|
||||||
onSuccess: (_, variables) => {
|
onSuccess: (_, variables) => {
|
||||||
|
const ossKey = ossApi.getOssQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
|
const ossData: IOperationSchemaData | undefined = client.getQueryData(ossKey);
|
||||||
|
if (ossData) {
|
||||||
|
client.setQueryData(ossKey, { ...ossData, owner: variables.owner });
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
...ossData.items
|
||||||
|
.map(item => {
|
||||||
|
if (!item.result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const itemKey = rsformsApi.getRSFormQueryOptions({ itemID: item.result }).queryKey;
|
||||||
|
return client.invalidateQueries({ queryKey: itemKey });
|
||||||
|
})
|
||||||
|
.filter(item => !!item)
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rsKey = rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey;
|
||||||
|
client.setQueryData(rsKey, prev => (!prev ? undefined : { ...prev, owner: variables.owner }));
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.map(item => (item.id === variables.itemID ? { ...item, owner: variables.owner } : item))
|
prev?.map(item => (item.id === variables.itemID ? { ...item, owner: variables.owner } : item))
|
||||||
);
|
);
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, prev => {
|
|
||||||
if (!prev) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (prev.item_type === LibraryItemType.OSS) {
|
|
||||||
client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] }).catch(console.error);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...prev,
|
|
||||||
owner: variables.owner
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { ILibraryItem } from '@/models/library';
|
import { ILibraryItem, LibraryItemType } from '@/models/library';
|
||||||
|
import { IOperationSchemaData } from '@/models/oss';
|
||||||
|
import { IRSFormData } from '@/models/rsform';
|
||||||
|
|
||||||
import { ILibraryUpdateDTO, libraryApi } from './api';
|
import { ILibraryUpdateDTO, libraryApi } from './api';
|
||||||
|
|
||||||
|
@ -11,17 +13,23 @@ export const useUpdateItem = () => {
|
||||||
mutationKey: [libraryApi.baseKey, 'update-item'],
|
mutationKey: [libraryApi.baseKey, 'update-item'],
|
||||||
mutationFn: libraryApi.updateItem,
|
mutationFn: libraryApi.updateItem,
|
||||||
onSuccess: (data: ILibraryItem) => {
|
onSuccess: (data: ILibraryItem) => {
|
||||||
client
|
const itemKey = libraryApi.getItemQueryOptions({ itemID: data.id, itemType: data.item_type }).queryKey;
|
||||||
.cancelQueries({ queryKey: libraryApi.libraryListKey })
|
|
||||||
.then(async () => {
|
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.map(item => (item.id === data.id ? data : item))
|
prev?.map(item => (item.id === data.id ? data : item))
|
||||||
);
|
);
|
||||||
await client.invalidateQueries({
|
client.setQueryData(itemKey, (prev: IRSFormData | IOperationSchemaData | undefined) =>
|
||||||
queryKey: [rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey]
|
!prev ? undefined : { ...prev, ...data }
|
||||||
});
|
);
|
||||||
})
|
if (data.item_type === LibraryItemType.RSFORM) {
|
||||||
.catch(console.error);
|
const schema: IRSFormData | undefined = client.getQueryData(itemKey);
|
||||||
|
if (schema) {
|
||||||
|
return Promise.allSettled(
|
||||||
|
schema.oss.map(item =>
|
||||||
|
client.invalidateQueries({ queryKey: ossApi.getOssQueryOptions({ itemID: item.id }).queryKey })
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
|
||||||
import { rsformsApi } from '@/backend/rsform/api';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { VersionID } from '@/models/library';
|
import { VersionID } from '@/models/library';
|
||||||
|
|
||||||
|
@ -8,13 +7,12 @@ import { libraryApi } from './api';
|
||||||
|
|
||||||
export const useVersionRestore = () => {
|
export const useVersionRestore = () => {
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
const { updateTimestamp } = useUpdateTimestamp();
|
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [libraryApi.baseKey, 'restore-version'],
|
mutationKey: [libraryApi.baseKey, 'restore-version'],
|
||||||
mutationFn: libraryApi.versionRestore,
|
mutationFn: libraryApi.versionRestore,
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
return client.invalidateQueries({ queryKey: [libraryApi.baseKey] });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { ITargetOperation, ossApi } from './api';
|
import { ITargetOperation, ossApi } from './api';
|
||||||
|
@ -11,9 +12,12 @@ export const useInputCreate = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'input-create'],
|
mutationKey: [ossApi.baseKey, 'input-create'],
|
||||||
mutationFn: ossApi.inputCreate,
|
mutationFn: ossApi.inputCreate,
|
||||||
onSuccess: async data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.oss.id }).queryKey, data.oss);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.oss.id }).queryKey, data.oss);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { IInputUpdateDTO, ossApi } from './api';
|
import { IInputUpdateDTO, ossApi } from './api';
|
||||||
|
@ -10,9 +11,12 @@ export const useInputUpdate = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'input-update'],
|
mutationKey: [ossApi.baseKey, 'input-update'],
|
||||||
mutationFn: ossApi.inputUpdate,
|
mutationFn: ossApi.inputUpdate,
|
||||||
onSuccess: async data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { libraryApi } from '@/backend/library/api';
|
||||||
|
|
||||||
import { ossApi } from './api';
|
import { ossApi } from './api';
|
||||||
|
|
||||||
export const useIsProcessingOss = () => {
|
export const useMutatingOss = () => {
|
||||||
const countLibrary = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
const countLibrary = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
||||||
const countOss = useIsMutating({ mutationKey: [ossApi.baseKey] });
|
const countOss = useIsMutating({ mutationKey: [ossApi.baseKey] });
|
||||||
return countLibrary + countOss !== 0;
|
return countLibrary + countOss !== 0;
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { IOperationDeleteDTO, ossApi } from './api';
|
import { IOperationDeleteDTO, ossApi } from './api';
|
||||||
|
@ -10,9 +11,12 @@ export const useOperationDelete = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'operation-delete'],
|
mutationKey: [ossApi.baseKey, 'operation-delete'],
|
||||||
mutationFn: ossApi.operationDelete,
|
mutationFn: ossApi.operationDelete,
|
||||||
onSuccess: async data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { ITargetOperation, ossApi } from './api';
|
import { ITargetOperation, ossApi } from './api';
|
||||||
|
@ -10,9 +11,12 @@ export const useOperationExecute = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'operation-execute'],
|
mutationKey: [ossApi.baseKey, 'operation-execute'],
|
||||||
mutationFn: ossApi.operationExecute,
|
mutationFn: ossApi.operationExecute,
|
||||||
onSuccess: async data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
|
import { ILibraryItem, LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { IOperationUpdateDTO, ossApi } from './api';
|
import { IOperationUpdateDTO, ossApi } from './api';
|
||||||
|
|
||||||
|
@ -10,9 +11,22 @@ export const useOperationUpdate = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'operation-update'],
|
mutationKey: [ossApi.baseKey, 'operation-update'],
|
||||||
mutationFn: ossApi.operationUpdate,
|
mutationFn: ossApi.operationUpdate,
|
||||||
onSuccess: async data => {
|
onSuccess: (data, variables) => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
const schemaID = data.items.find(item => item.id === variables.data.target)?.result;
|
||||||
|
if (!schemaID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
|
!prev
|
||||||
|
? undefined
|
||||||
|
: prev.map(item =>
|
||||||
|
item.id === schemaID ? { ...item, ...variables.data.item_data, time_update: Date() } : item
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return client.invalidateQueries({
|
||||||
|
queryKey: rsformsApi.getRSFormQueryOptions({ itemID: schemaID }).queryKey
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { rsformsApi } from '@/backend/rsform/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { ICstRelocateDTO, ossApi } from './api';
|
import { ICstRelocateDTO, ossApi } from './api';
|
||||||
|
@ -10,9 +11,12 @@ export const useRelocateConstituents = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [ossApi.baseKey, 'relocate-constituents'],
|
mutationKey: [ossApi.baseKey, 'relocate-constituents'],
|
||||||
mutationFn: ossApi.relocateConstituents,
|
mutationFn: ossApi.relocateConstituents,
|
||||||
onSuccess: async data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(ossApi.getOssQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
await client.invalidateQueries({ queryKey: [libraryApi.libraryListKey] });
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: libraryApi.libraryListKey }),
|
||||||
|
client.invalidateQueries({ queryKey: [rsformsApi.baseKey] })
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -14,7 +14,7 @@ export const queryClient = new QueryClient({
|
||||||
queries: {
|
queries: {
|
||||||
staleTime: DELAYS.staleDefault,
|
staleTime: DELAYS.staleDefault,
|
||||||
gcTime: DELAYS.garbageCollection,
|
gcTime: DELAYS.garbageCollection,
|
||||||
retry: 3,
|
retry: false,
|
||||||
refetchOnWindowFocus: true,
|
refetchOnWindowFocus: true,
|
||||||
refetchOnMount: true,
|
refetchOnMount: true,
|
||||||
refetchOnReconnect: true
|
refetchOnReconnect: true
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { IConstituentaMeta } from '@/models/rsform';
|
import { IConstituentaMeta } from '@/models/rsform';
|
||||||
|
|
||||||
|
@ -16,7 +17,14 @@ export const useCstCreate = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
||||||
updateTimestamp(data.schema.id);
|
updateTimestamp(data.schema.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.schema.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { IConstituentaList } from '@/models/rsform';
|
import { IConstituentaList } from '@/models/rsform';
|
||||||
|
|
||||||
|
@ -15,7 +16,14 @@ export const useCstDelete = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
updateTimestamp(data.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -14,7 +14,6 @@ export const useCstMove = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
updateTimestamp(data.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { ICstRenameDTO, rsformsApi } from './api';
|
import { ICstRenameDTO, rsformsApi } from './api';
|
||||||
|
@ -14,7 +15,14 @@ export const useCstRename = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
||||||
updateTimestamp(data.schema.id);
|
updateTimestamp(data.schema.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.schema.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { ICstSubstitutions } from '@/models/oss';
|
import { ICstSubstitutions } from '@/models/oss';
|
||||||
|
|
||||||
|
@ -15,7 +16,14 @@ export const useCstSubstitute = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
updateTimestamp(data.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { ICstUpdateDTO, rsformsApi } from './api';
|
import { ICstUpdateDTO, rsformsApi } from './api';
|
||||||
|
@ -11,12 +12,24 @@ export const useCstUpdate = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: [rsformsApi.baseKey, 'update-cst'],
|
mutationKey: [rsformsApi.baseKey, 'update-cst'],
|
||||||
mutationFn: rsformsApi.cstUpdate,
|
mutationFn: rsformsApi.cstUpdate,
|
||||||
onSuccess: async (_, variables) => {
|
onSuccess: (newCst, variables) => {
|
||||||
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey, prev =>
|
||||||
|
!prev
|
||||||
|
? undefined
|
||||||
|
: {
|
||||||
|
...prev,
|
||||||
|
items: prev.items.map(item => (item.id === newCst.id ? { ...item, ...newCst } : item))
|
||||||
|
}
|
||||||
|
);
|
||||||
updateTimestamp(variables.itemID);
|
updateTimestamp(variables.itemID);
|
||||||
await client.invalidateQueries({
|
|
||||||
queryKey: [rsformsApi.getRSFormQueryOptions({ itemID: variables.itemID }).queryKey]
|
return Promise.allSettled([
|
||||||
});
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
// TODO: invalidate OSS?
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== variables.itemID
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { IRSFormData } from '@/models/rsform';
|
import { IRSFormData } from '@/models/rsform';
|
||||||
|
|
||||||
|
@ -16,7 +17,14 @@ export const useInlineSynthesis = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
updateTimestamp(data.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { libraryApi } from '@/backend/library/api';
|
||||||
|
|
||||||
import { rsformsApi } from './api';
|
import { rsformsApi } from './api';
|
||||||
|
|
||||||
export const useIsProcessingRSForm = () => {
|
export const useMutatingRSForm = () => {
|
||||||
const countLibrary = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
const countLibrary = useIsMutating({ mutationKey: [libraryApi.baseKey] });
|
||||||
const countRsform = useIsMutating({ mutationKey: [rsformsApi.baseKey] });
|
const countRsform = useIsMutating({ mutationKey: [rsformsApi.baseKey] });
|
||||||
return countLibrary + countRsform !== 0;
|
return countLibrary + countRsform !== 0;
|
|
@ -2,6 +2,7 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
import { ConstituentaID, ITargetCst } from '@/models/rsform';
|
import { ConstituentaID, ITargetCst } from '@/models/rsform';
|
||||||
|
|
||||||
|
@ -16,7 +17,14 @@ export const useProduceStructure = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.schema.id }).queryKey, data.schema);
|
||||||
updateTimestamp(data.schema.id);
|
updateTimestamp(data.schema.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.schema.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
import { useUpdateTimestamp } from '@/backend/library/useUpdateTimestamp';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { LibraryItemID } from '@/models/library';
|
import { LibraryItemID } from '@/models/library';
|
||||||
|
|
||||||
import { rsformsApi } from './api';
|
import { rsformsApi } from './api';
|
||||||
|
@ -14,7 +15,14 @@ export const useResetAliases = () => {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
client.setQueryData(rsformsApi.getRSFormQueryOptions({ itemID: data.id }).queryKey, data);
|
||||||
updateTimestamp(data.id);
|
updateTimestamp(data.id);
|
||||||
// TODO: invalidate OSS?
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { libraryApi } from '@/backend/library/api';
|
import { libraryApi } from '@/backend/library/api';
|
||||||
|
import { ossApi } from '@/backend/oss/api';
|
||||||
import { ILibraryItem } from '@/models/library';
|
import { ILibraryItem } from '@/models/library';
|
||||||
|
|
||||||
import { IRSFormUploadDTO, rsformsApi } from './api';
|
import { IRSFormUploadDTO, rsformsApi } from './api';
|
||||||
|
@ -15,6 +16,14 @@ export const useUploadTRS = () => {
|
||||||
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
client.setQueryData(libraryApi.libraryListKey, (prev: ILibraryItem[] | undefined) =>
|
||||||
prev?.map(item => (item.id === data.id ? data : item))
|
prev?.map(item => (item.id === data.id ? data : item))
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return Promise.allSettled([
|
||||||
|
client.invalidateQueries({ queryKey: [ossApi.baseKey] }),
|
||||||
|
client.invalidateQueries({
|
||||||
|
queryKey: [rsformsApi.baseKey],
|
||||||
|
predicate: query => query.queryKey.length > 2 && query.queryKey[2] !== data.id
|
||||||
|
})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export const useSignup = () => {
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: ['signup'],
|
mutationKey: ['signup'],
|
||||||
mutationFn: usersApi.signup,
|
mutationFn: usersApi.signup,
|
||||||
onSuccess: async () => await client.invalidateQueries({ queryKey: [usersApi.baseKey] })
|
onSuccess: () => client.invalidateQueries({ queryKey: usersApi.getUsersQueryOptions().queryKey })
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
signup: (
|
signup: (
|
||||||
|
|
|
@ -2,14 +2,15 @@ import { useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { IUpdateProfileDTO, usersApi } from './api';
|
import { IUpdateProfileDTO, usersApi } from './api';
|
||||||
|
|
||||||
// TODO: reload users / optimistic update
|
|
||||||
|
|
||||||
export const useUpdateProfile = () => {
|
export const useUpdateProfile = () => {
|
||||||
const client = useQueryClient();
|
const client = useQueryClient();
|
||||||
const mutation = useMutation({
|
const mutation = useMutation({
|
||||||
mutationKey: ['update-profile'],
|
mutationKey: ['update-profile'],
|
||||||
mutationFn: usersApi.updateProfile,
|
mutationFn: usersApi.updateProfile,
|
||||||
onSuccess: async () => await client.invalidateQueries({ queryKey: [usersApi.baseKey] })
|
onSuccess: data => {
|
||||||
|
client.setQueryData(usersApi.getProfileQueryOptions().queryKey, data);
|
||||||
|
return client.invalidateQueries({ queryKey: usersApi.getUsersQueryOptions().queryKey });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
updateProfile: (data: IUpdateProfileDTO) => mutation.mutate(data),
|
updateProfile: (data: IUpdateProfileDTO) => mutation.mutate(data),
|
||||||
|
|
|
@ -16,7 +16,28 @@ function DescribeError({ error }: { error: ErrorData }) {
|
||||||
} else if (typeof error === 'string') {
|
} else if (typeof error === 'string') {
|
||||||
return <p>{error}</p>;
|
return <p>{error}</p>;
|
||||||
} else if (!axios.isAxiosError(error)) {
|
} else if (!axios.isAxiosError(error)) {
|
||||||
return <PrettyJson data={error} />;
|
return (
|
||||||
|
<div className='mt-6'>
|
||||||
|
<p>
|
||||||
|
<b>Error:</b> {error.name}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<b>Message:</b> {error.message}
|
||||||
|
</p>
|
||||||
|
{error.stack && (
|
||||||
|
<pre
|
||||||
|
style={{
|
||||||
|
whiteSpace: 'pre-wrap',
|
||||||
|
wordWrap: 'break-word',
|
||||||
|
padding: '6px',
|
||||||
|
overflowX: 'auto'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{error.stack}
|
||||||
|
</pre>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (!error?.response) {
|
if (!error?.response) {
|
||||||
return <p>Нет ответа от сервера</p>;
|
return <p>Нет ответа от сервера</p>;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useIsProcessingLibrary } from '@/backend/library/useIsProcessingLibrary';
|
import { useMutatingLibrary } from '@/backend/library/useMutatingLibrary';
|
||||||
import { useVersionDelete } from '@/backend/library/useVersionDelete';
|
import { useVersionDelete } from '@/backend/library/useVersionDelete';
|
||||||
import { useVersionUpdate } from '@/backend/library/useVersionUpdate';
|
import { useVersionUpdate } from '@/backend/library/useVersionUpdate';
|
||||||
import { IconReset, IconSave } from '@/components/Icons';
|
import { IconReset, IconSave } from '@/components/Icons';
|
||||||
|
@ -22,7 +22,7 @@ export interface DlgEditVersionsProps {
|
||||||
|
|
||||||
function DlgEditVersions() {
|
function DlgEditVersions() {
|
||||||
const { item, afterDelete } = useDialogsStore(state => state.props as DlgEditVersionsProps);
|
const { item, afterDelete } = useDialogsStore(state => state.props as DlgEditVersionsProps);
|
||||||
const processing = useIsProcessingLibrary();
|
const processing = useMutatingLibrary();
|
||||||
const { versionDelete } = useVersionDelete();
|
const { versionDelete } = useVersionDelete();
|
||||||
const { versionUpdate } = useVersionUpdate();
|
const { versionUpdate } = useVersionUpdate();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import FlexColumn from '@/components/ui/FlexColumn';
|
import FlexColumn from '@/components/ui/FlexColumn';
|
||||||
import { LibraryItemType } from '@/models/library';
|
|
||||||
import EditorLibraryItem from '@/pages/RSFormPage/EditorRSFormCard/EditorLibraryItem';
|
import EditorLibraryItem from '@/pages/RSFormPage/EditorRSFormCard/EditorLibraryItem';
|
||||||
import ToolbarRSFormCard from '@/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard';
|
import ToolbarRSFormCard from '@/pages/RSFormPage/EditorRSFormCard/ToolbarRSFormCard';
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
|
@ -47,7 +46,7 @@ function EditorOssCard() {
|
||||||
>
|
>
|
||||||
<FlexColumn className='px-3'>
|
<FlexColumn className='px-3'>
|
||||||
<FormOSS id={globals.library_item_editor} />
|
<FormOSS id={globals.library_item_editor} />
|
||||||
<EditorLibraryItem itemID={controller.schema.id} itemType={LibraryItemType.OSS} controller={controller} />
|
<EditorLibraryItem controller={controller} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
{controller.schema ? <OssStats stats={controller.schema.stats} /> : null}
|
{controller.schema ? <OssStats stats={controller.schema.stats} /> : null}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
||||||
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
||||||
import { useIsProcessingOss } from '@/backend/oss/useIsProcessingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import { IconSave } from '@/components/Icons';
|
import { IconSave } from '@/components/Icons';
|
||||||
import SubmitButton from '@/components/ui/SubmitButton';
|
import SubmitButton from '@/components/ui/SubmitButton';
|
||||||
import TextArea from '@/components/ui/TextArea';
|
import TextArea from '@/components/ui/TextArea';
|
||||||
|
@ -24,7 +24,7 @@ function FormOSS({ id }: FormOSSProps) {
|
||||||
const { updateItem: update } = useUpdateItem();
|
const { updateItem: update } = useUpdateItem();
|
||||||
const controller = useOssEdit();
|
const controller = useOssEdit();
|
||||||
const { isModified, setIsModified } = useModificationStore();
|
const { isModified, setIsModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingOss();
|
const isProcessing = useMutatingOss();
|
||||||
const schema = controller.schema;
|
const schema = controller.schema;
|
||||||
|
|
||||||
const [title, setTitle] = useState(schema.title);
|
const [title, setTitle] = useState(schema.title);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
import { useIsProcessingOss } from '@/backend/oss/useIsProcessingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import {
|
import {
|
||||||
IconChild,
|
IconChild,
|
||||||
IconConnect,
|
IconConnect,
|
||||||
|
@ -50,7 +50,7 @@ function NodeContextMenu({
|
||||||
onRelocateConstituents
|
onRelocateConstituents
|
||||||
}: NodeContextMenuProps) {
|
}: NodeContextMenuProps) {
|
||||||
const controller = useOssEdit();
|
const controller = useOssEdit();
|
||||||
const isProcessing = useIsProcessingOss();
|
const isProcessing = useMutatingOss();
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
|
|
|
@ -20,7 +20,7 @@ import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useLibrary } from '@/backend/library/useLibrary';
|
import { useLibrary } from '@/backend/library/useLibrary';
|
||||||
import { useInputCreate } from '@/backend/oss/useInputCreate';
|
import { useInputCreate } from '@/backend/oss/useInputCreate';
|
||||||
import { useIsProcessingOss } from '@/backend/oss/useIsProcessingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import { useOperationExecute } from '@/backend/oss/useOperationExecute';
|
import { useOperationExecute } from '@/backend/oss/useOperationExecute';
|
||||||
import { useUpdatePositions } from '@/backend/oss/useUpdatePositions';
|
import { useUpdatePositions } from '@/backend/oss/useUpdatePositions';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
|
@ -50,7 +50,7 @@ function OssFlow() {
|
||||||
const flow = useReactFlow();
|
const flow = useReactFlow();
|
||||||
const { setIsModified } = useModificationStore();
|
const { setIsModified } = useModificationStore();
|
||||||
|
|
||||||
const isProcessing = useIsProcessingOss();
|
const isProcessing = useMutatingOss();
|
||||||
|
|
||||||
const showGrid = useOSSGraphStore(state => state.showGrid);
|
const showGrid = useOSSGraphStore(state => state.showGrid);
|
||||||
const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
|
const edgeAnimate = useOSSGraphStore(state => state.edgeAnimate);
|
||||||
|
@ -118,7 +118,7 @@ function OssFlow() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNodesChange(changes: NodeChange[]) {
|
function handleNodesChange(changes: NodeChange[]) {
|
||||||
if (changes.some(change => change.type === 'position' && change.position)) {
|
if (controller.isMutable && changes.some(change => change.type === 'position' && change.position)) {
|
||||||
setIsModified(true);
|
setIsModified(true);
|
||||||
}
|
}
|
||||||
onNodesChange(changes);
|
onNodesChange(changes);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { useIsProcessingOss } from '@/backend/oss/useIsProcessingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import {
|
import {
|
||||||
IconAnimation,
|
IconAnimation,
|
||||||
IconAnimationOff,
|
IconAnimationOff,
|
||||||
|
@ -52,7 +52,7 @@ function ToolbarOssGraph({
|
||||||
}: ToolbarOssGraphProps) {
|
}: ToolbarOssGraphProps) {
|
||||||
const controller = useOssEdit();
|
const controller = useOssEdit();
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingOss();
|
const isProcessing = useMutatingOss();
|
||||||
const selectedOperation = controller.schema.operationByID.get(controller.selected[0]);
|
const selectedOperation = controller.schema.operationByID.get(controller.selected[0]);
|
||||||
|
|
||||||
const showGrid = useOSSGraphStore(state => state.showGrid);
|
const showGrid = useOSSGraphStore(state => state.showGrid);
|
||||||
|
@ -89,7 +89,6 @@ function ToolbarOssGraph({
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Сбросить изменения'
|
title='Сбросить изменения'
|
||||||
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
icon={<IconReset size='1.25rem' className='icon-primary' />}
|
||||||
disabled={!isModified}
|
|
||||||
onClick={onResetPositions}
|
onClick={onResetPositions}
|
||||||
/>
|
/>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
import { useAuthSuspense } from '@/backend/auth/useAuth';
|
||||||
import { useIsProcessingOss } from '@/backend/oss/useIsProcessingOss';
|
import { useMutatingOss } from '@/backend/oss/useMutatingOss';
|
||||||
import {
|
import {
|
||||||
IconAdmin,
|
IconAdmin,
|
||||||
IconAlert,
|
IconAlert,
|
||||||
|
@ -35,7 +35,7 @@ function MenuOssTabs() {
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const { user, isAnonymous } = useAuthSuspense();
|
const { user, isAnonymous } = useAuthSuspense();
|
||||||
|
|
||||||
const isProcessing = useIsProcessingOss();
|
const isProcessing = useMutatingOss();
|
||||||
|
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const setRole = useRoleStore(state => state.setRole);
|
const setRole = useRoleStore(state => state.setRole);
|
||||||
|
|
|
@ -86,11 +86,9 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
||||||
const { schema } = useOssSuspense({ itemID: itemID });
|
const { schema } = useOssSuspense({ itemID: itemID });
|
||||||
|
|
||||||
const isOwned = !!user.id && user.id === schema.owner;
|
const isOwned = !!user.id && user.id === schema.owner;
|
||||||
|
|
||||||
const isMutable = role > UserRole.READER && !schema.read_only;
|
const isMutable = role > UserRole.READER && !schema.read_only;
|
||||||
|
|
||||||
const [showTooltip, setShowTooltip] = useState(true);
|
const [showTooltip, setShowTooltip] = useState(true);
|
||||||
|
|
||||||
const [selected, setSelected] = useState<OperationID[]>([]);
|
const [selected, setSelected] = useState<OperationID[]>([]);
|
||||||
|
|
||||||
const showEditInput = useDialogsStore(state => state.showChangeInputSchema);
|
const showEditInput = useDialogsStore(state => state.showChangeInputSchema);
|
||||||
|
|
|
@ -21,13 +21,6 @@ function OssPage() {
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
useBlockNavigation(isModified);
|
useBlockNavigation(isModified);
|
||||||
|
|
||||||
// useBlockNavigation(
|
|
||||||
// isModified &&
|
|
||||||
// schema !== undefined &&
|
|
||||||
// !!user &&
|
|
||||||
// (user.is_staff || user.id == schema.owner || schema.editors.includes(user.id))
|
|
||||||
// );
|
|
||||||
|
|
||||||
if (!itemID) {
|
if (!itemID) {
|
||||||
router.replace(urls.page404);
|
router.replace(urls.page404);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { IPasswordTokenDTO, IResetPasswordDTO } from '@/backend/auth/api';
|
import { IResetPasswordDTO } from '@/backend/auth/api';
|
||||||
import { useResetPassword } from '@/backend/auth/useResetPassword';
|
import { useResetPassword } from '@/backend/auth/useResetPassword';
|
||||||
import InfoError, { ErrorData } from '@/components/info/InfoError';
|
import InfoError, { ErrorData } from '@/components/info/InfoError';
|
||||||
import SubmitButton from '@/components/ui/SubmitButton';
|
import SubmitButton from '@/components/ui/SubmitButton';
|
||||||
|
@ -48,10 +48,7 @@ function PasswordChangePage() {
|
||||||
}, [newPassword, newPasswordRepeat, reset]);
|
}, [newPassword, newPasswordRepeat, reset]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const data: IPasswordTokenDTO = {
|
validateToken({ token: token ?? '' }, () => setIsTokenValid(true));
|
||||||
token: token ?? ''
|
|
||||||
};
|
|
||||||
validateToken(data, () => setIsTokenValid(true));
|
|
||||||
}, [token, validateToken]);
|
}, [token, validateToken]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,7 +4,7 @@ import clsx from 'clsx';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
import { useCstUpdate } from '@/backend/rsform/useCstUpdate';
|
import { useCstUpdate } from '@/backend/rsform/useCstUpdate';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import useWindowSize from '@/hooks/useWindowSize';
|
import useWindowSize from '@/hooks/useWindowSize';
|
||||||
import { useMainHeight } from '@/stores/appLayout';
|
import { useMainHeight } from '@/stores/appLayout';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
|
@ -33,7 +33,7 @@ function EditorConstituenta() {
|
||||||
|
|
||||||
const [toggleReset, setToggleReset] = useState(false);
|
const [toggleReset, setToggleReset] = useState(false);
|
||||||
|
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const disabled = !controller.activeCst || !controller.isContentEditable || isProcessing;
|
const disabled = !controller.activeCst || !controller.isContentEditable || isProcessing;
|
||||||
const isNarrow = !!windowSize.width && windowSize.width <= SIDELIST_LAYOUT_THRESHOLD;
|
const isNarrow = !!windowSize.width && windowSize.width <= SIDELIST_LAYOUT_THRESHOLD;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import clsx from 'clsx';
|
||||||
|
|
||||||
import { ICstRenameDTO } from '@/backend/rsform/api';
|
import { ICstRenameDTO } from '@/backend/rsform/api';
|
||||||
import { useCstRename } from '@/backend/rsform/useCstRename';
|
import { useCstRename } from '@/backend/rsform/useCstRename';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconEdit } from '@/components/Icons';
|
import { IconEdit } from '@/components/Icons';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
import Overlay from '@/components/ui/Overlay';
|
import Overlay from '@/components/ui/Overlay';
|
||||||
|
@ -23,7 +23,7 @@ interface EditorControlsProps {
|
||||||
function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsProps) {
|
function EditorControls({ constituenta, disabled, onEditTerm }: EditorControlsProps) {
|
||||||
const { schema } = useRSEdit();
|
const { schema } = useRSEdit();
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const showRenameCst = useDialogsStore(state => state.showRenameCst);
|
const showRenameCst = useDialogsStore(state => state.showRenameCst);
|
||||||
const { cstRename } = useCstRename();
|
const { cstRename } = useCstRename();
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { ICstUpdateDTO } from '@/backend/rsform/api';
|
import { ICstUpdateDTO } from '@/backend/rsform/api';
|
||||||
import { useCstUpdate } from '@/backend/rsform/useCstUpdate';
|
import { useCstUpdate } from '@/backend/rsform/useCstUpdate';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconChild, IconPredecessor, IconSave } from '@/components/Icons';
|
import { IconChild, IconPredecessor, IconSave } from '@/components/Icons';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
import RefsInput from '@/components/RefsInput';
|
import RefsInput from '@/components/RefsInput';
|
||||||
|
@ -45,7 +45,7 @@ function FormConstituenta({
|
||||||
const { cstUpdate } = useCstUpdate();
|
const { cstUpdate } = useCstUpdate();
|
||||||
const { schema, activeCst } = useRSEdit();
|
const { schema, activeCst } = useRSEdit();
|
||||||
const { isModified, setIsModified } = useModificationStore();
|
const { isModified, setIsModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const [term, setTerm] = useState(activeCst?.term_raw ?? '');
|
const [term, setTerm] = useState(activeCst?.term_raw ?? '');
|
||||||
const [textDefinition, setTextDefinition] = useState(activeCst?.definition_raw ?? '');
|
const [textDefinition, setTextDefinition] = useState(activeCst?.definition_raw ?? '');
|
||||||
|
|
|
@ -5,7 +5,7 @@ import clsx from 'clsx';
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useFindPredecessor } from '@/backend/oss/useFindPredecessor';
|
import { useFindPredecessor } from '@/backend/oss/useFindPredecessor';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import {
|
import {
|
||||||
IconClone,
|
IconClone,
|
||||||
IconDestroy,
|
IconDestroy,
|
||||||
|
@ -53,7 +53,7 @@ function ToolbarConstituenta({
|
||||||
const showList = usePreferencesStore(state => state.showCstSideList);
|
const showList = usePreferencesStore(state => state.showCstSideList);
|
||||||
const toggleList = usePreferencesStore(state => state.toggleShowCstSideList);
|
const toggleList = usePreferencesStore(state => state.toggleShowCstSideList);
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
function viewPredecessor(target: ConstituentaID) {
|
function viewPredecessor(target: ConstituentaID) {
|
||||||
findPredecessor({ target: target }, reference =>
|
findPredecessor({ target: target }, reference =>
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { toast } from 'react-toastify';
|
||||||
import { DataCallback } from '@/backend/apiTransport';
|
import { DataCallback } from '@/backend/apiTransport';
|
||||||
import { ICheckConstituentaDTO } from '@/backend/rsform/api';
|
import { ICheckConstituentaDTO } from '@/backend/rsform/api';
|
||||||
import { useCheckConstituenta } from '@/backend/rsform/useCheckConstituenta';
|
import { useCheckConstituenta } from '@/backend/rsform/useCheckConstituenta';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
import RSInput from '@/components/RSInput';
|
import RSInput from '@/components/RSInput';
|
||||||
|
@ -65,7 +65,7 @@ function EditorRSExpression({
|
||||||
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
||||||
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
|
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
|
||||||
|
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
||||||
const showAST = useDialogsStore(state => state.showShowAST);
|
const showAST = useDialogsStore(state => state.showShowAST);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconControls, IconTree, IconTypeGraph } from '@/components/Icons';
|
import { IconControls, IconTree, IconTypeGraph } from '@/components/Icons';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
|
@ -12,7 +12,7 @@ interface ToolbarRSExpressionProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: ToolbarRSExpressionProps) {
|
function ToolbarRSExpression({ disabled, showTypeGraph, showAST }: ToolbarRSExpressionProps) {
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
||||||
const toggleControls = usePreferencesStore(state => state.toggleShowExpressionControls);
|
const toggleControls = usePreferencesStore(state => state.toggleShowExpressionControls);
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,7 @@ import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { useIsProcessingLibrary } from '@/backend/library/useIsProcessingLibrary';
|
import { useMutatingLibrary } from '@/backend/library/useMutatingLibrary';
|
||||||
import { useLibraryItem } from '@/backend/library/useLibraryItem';
|
|
||||||
import { useSetEditors } from '@/backend/library/useSetEditors';
|
import { useSetEditors } from '@/backend/library/useSetEditors';
|
||||||
import { useSetLocation } from '@/backend/library/useSetLocation';
|
import { useSetLocation } from '@/backend/library/useSetLocation';
|
||||||
import { useSetOwner } from '@/backend/library/useSetOwner';
|
import { useSetOwner } from '@/backend/library/useSetOwner';
|
||||||
|
@ -26,7 +25,7 @@ import Overlay from '@/components/ui/Overlay';
|
||||||
import Tooltip from '@/components/ui/Tooltip';
|
import Tooltip from '@/components/ui/Tooltip';
|
||||||
import ValueIcon from '@/components/ui/ValueIcon';
|
import ValueIcon from '@/components/ui/ValueIcon';
|
||||||
import useDropdown from '@/hooks/useDropdown';
|
import useDropdown from '@/hooks/useDropdown';
|
||||||
import { ILibraryItemEditor, LibraryItemID, LibraryItemType } from '@/models/library';
|
import { ILibraryItemEditor } from '@/models/library';
|
||||||
import { UserID, UserRole } from '@/models/user';
|
import { UserID, UserRole } from '@/models/user';
|
||||||
import { useDialogsStore } from '@/stores/dialogs';
|
import { useDialogsStore } from '@/stores/dialogs';
|
||||||
import { useLibrarySearchStore } from '@/stores/librarySearch';
|
import { useLibrarySearchStore } from '@/stores/librarySearch';
|
||||||
|
@ -36,20 +35,17 @@ import { prefixes } from '@/utils/constants';
|
||||||
import { prompts } from '@/utils/labels';
|
import { prompts } from '@/utils/labels';
|
||||||
|
|
||||||
interface EditorLibraryItemProps {
|
interface EditorLibraryItemProps {
|
||||||
itemID: LibraryItemID;
|
|
||||||
itemType: LibraryItemType;
|
|
||||||
controller: ILibraryItemEditor;
|
controller: ILibraryItemEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemProps) {
|
function EditorLibraryItem({ controller }: EditorLibraryItemProps) {
|
||||||
const getUserLabel = useLabelUser();
|
const getUserLabel = useLabelUser();
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const setGlobalLocation = useLibrarySearchStore(state => state.setLocation);
|
const setGlobalLocation = useLibrarySearchStore(state => state.setLocation);
|
||||||
|
|
||||||
const { item } = useLibraryItem({ itemID, itemType });
|
const isProcessing = useMutatingLibrary();
|
||||||
const isProcessing = useIsProcessingLibrary();
|
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
|
|
||||||
const { setOwner } = useSetOwner();
|
const { setOwner } = useSetOwner();
|
||||||
|
@ -62,47 +58,34 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
const ownerSelector = useDropdown();
|
const ownerSelector = useDropdown();
|
||||||
const onSelectUser = function (newValue: UserID) {
|
const onSelectUser = function (newValue: UserID) {
|
||||||
ownerSelector.hide();
|
ownerSelector.hide();
|
||||||
if (newValue === item?.owner) {
|
if (newValue === controller.schema.owner) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!window.confirm(prompts.ownerChange)) {
|
if (!window.confirm(prompts.ownerChange)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setOwner({ itemID: itemID, owner: newValue });
|
setOwner({ itemID: controller.schema.id, owner: newValue });
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleOpenLibrary(event: CProps.EventMouse) {
|
function handleOpenLibrary(event: CProps.EventMouse) {
|
||||||
if (!item) {
|
setGlobalLocation(controller.schema.location);
|
||||||
return;
|
|
||||||
}
|
|
||||||
setGlobalLocation(item.location);
|
|
||||||
router.push(urls.library, event.ctrlKey || event.metaKey);
|
router.push(urls.library, event.ctrlKey || event.metaKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEditLocation() {
|
function handleEditLocation() {
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showEditLocation({
|
showEditLocation({
|
||||||
initial: item.location,
|
initial: controller.schema.location,
|
||||||
onChangeLocation: newLocation => setLocation({ itemID: itemID, location: newLocation })
|
onChangeLocation: newLocation => setLocation({ itemID: controller.schema.id, location: newLocation })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleEditEditors() {
|
function handleEditEditors() {
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
showEditEditors({
|
showEditEditors({
|
||||||
editors: item.editors,
|
editors: controller.schema.editors,
|
||||||
onChangeEditors: newEditors => setEditors({ itemID: itemID, editors: newEditors })
|
onChangeEditors: newEditors => setEditors({ itemID: controller.schema.id, editors: newEditors })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='flex flex-col'>
|
<div className='flex flex-col'>
|
||||||
<div className='flex justify-stretch sm:mb-1 max-w-[30rem] gap-3'>
|
<div className='flex justify-stretch sm:mb-1 max-w-[30rem] gap-3'>
|
||||||
|
@ -116,7 +99,7 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
<ValueIcon
|
<ValueIcon
|
||||||
className='text-ellipsis flex-grow'
|
className='text-ellipsis flex-grow'
|
||||||
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
|
icon={<IconFolderEdit size='1.25rem' className='icon-primary' />}
|
||||||
value={item.location}
|
value={controller.schema.location}
|
||||||
title={controller.isAttachedToOSS ? 'Путь наследуется от ОСС' : 'Путь'}
|
title={controller.isAttachedToOSS ? 'Путь наследуется от ОСС' : 'Путь'}
|
||||||
onClick={handleEditLocation}
|
onClick={handleEditLocation}
|
||||||
disabled={isModified || isProcessing || controller.isAttachedToOSS || role < UserRole.OWNER}
|
disabled={isModified || isProcessing || controller.isAttachedToOSS || role < UserRole.OWNER}
|
||||||
|
@ -128,7 +111,7 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
{ownerSelector.isOpen ? (
|
{ownerSelector.isOpen ? (
|
||||||
<SelectUser
|
<SelectUser
|
||||||
className='w-[25rem] sm:w-[26rem] text-sm'
|
className='w-[25rem] sm:w-[26rem] text-sm'
|
||||||
value={item.owner ?? undefined}
|
value={controller.schema.owner ?? undefined}
|
||||||
onSelectValue={onSelectUser}
|
onSelectValue={onSelectUser}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
@ -137,7 +120,7 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
<ValueIcon
|
<ValueIcon
|
||||||
className='sm:mb-1'
|
className='sm:mb-1'
|
||||||
icon={<IconOwner size='1.25rem' className='icon-primary' />}
|
icon={<IconOwner size='1.25rem' className='icon-primary' />}
|
||||||
value={getUserLabel(item.owner)}
|
value={getUserLabel(controller.schema.owner)}
|
||||||
title={controller.isAttachedToOSS ? 'Владелец наследуется от ОСС' : 'Владелец'}
|
title={controller.isAttachedToOSS ? 'Владелец наследуется от ОСС' : 'Владелец'}
|
||||||
onClick={ownerSelector.toggle}
|
onClick={ownerSelector.toggle}
|
||||||
disabled={isModified || isProcessing || controller.isAttachedToOSS || role < UserRole.OWNER}
|
disabled={isModified || isProcessing || controller.isAttachedToOSS || role < UserRole.OWNER}
|
||||||
|
@ -148,13 +131,13 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
id='editor_stats'
|
id='editor_stats'
|
||||||
dense
|
dense
|
||||||
icon={<IconEditor size='1.25rem' className='icon-primary' />}
|
icon={<IconEditor size='1.25rem' className='icon-primary' />}
|
||||||
value={item.editors.length}
|
value={controller.schema.editors.length}
|
||||||
onClick={handleEditEditors}
|
onClick={handleEditEditors}
|
||||||
disabled={isModified || isProcessing || role < UserRole.OWNER}
|
disabled={isModified || isProcessing || role < UserRole.OWNER}
|
||||||
/>
|
/>
|
||||||
<Tooltip anchorSelect='#editor_stats' layer='z-modalTooltip'>
|
<Tooltip anchorSelect='#editor_stats' layer='z-modalTooltip'>
|
||||||
<Suspense fallback={<Loader scale={2} />}>
|
<Suspense fallback={<Loader scale={2} />}>
|
||||||
<InfoUsers items={item?.editors ?? []} prefix={prefixes.user_editors} header='Редакторы' />
|
<InfoUsers items={controller.schema.editors} prefix={prefixes.user_editors} header='Редакторы' />
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
|
@ -162,7 +145,7 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
dense
|
dense
|
||||||
disabled
|
disabled
|
||||||
icon={<IconDateUpdate size='1.25rem' className='text-ok-600' />}
|
icon={<IconDateUpdate size='1.25rem' className='text-ok-600' />}
|
||||||
value={new Date(item.time_update).toLocaleString(intl.locale)}
|
value={new Date(controller.schema.time_update).toLocaleString(intl.locale)}
|
||||||
title='Дата обновления'
|
title='Дата обновления'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -170,7 +153,7 @@ function EditorLibraryItem({ itemID, itemType, controller }: EditorLibraryItemPr
|
||||||
dense
|
dense
|
||||||
disabled
|
disabled
|
||||||
icon={<IconDateCreate size='1.25rem' className='text-ok-600' />}
|
icon={<IconDateCreate size='1.25rem' className='text-ok-600' />}
|
||||||
value={new Date(item.time_create).toLocaleString(intl.locale, {
|
value={new Date(controller.schema.time_create).toLocaleString(intl.locale, {
|
||||||
year: '2-digit',
|
year: '2-digit',
|
||||||
month: '2-digit',
|
month: '2-digit',
|
||||||
day: '2-digit'
|
day: '2-digit'
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import FlexColumn from '@/components/ui/FlexColumn';
|
import FlexColumn from '@/components/ui/FlexColumn';
|
||||||
import { LibraryItemType } from '@/models/library';
|
|
||||||
import { useModificationStore } from '@/stores/modification';
|
import { useModificationStore } from '@/stores/modification';
|
||||||
import { globals } from '@/utils/constants';
|
import { globals } from '@/utils/constants';
|
||||||
|
|
||||||
|
@ -46,7 +45,7 @@ function EditorRSFormCard() {
|
||||||
>
|
>
|
||||||
<FlexColumn className='flex-shrink'>
|
<FlexColumn className='flex-shrink'>
|
||||||
<FormRSForm id={globals.library_item_editor} />
|
<FormRSForm id={globals.library_item_editor} />
|
||||||
<EditorLibraryItem itemID={controller.schema.id} itemType={LibraryItemType.RSFORM} controller={controller} />
|
<EditorLibraryItem controller={controller} />
|
||||||
</FlexColumn>
|
</FlexColumn>
|
||||||
|
|
||||||
{controller.schema ? <RSFormStats stats={controller.schema.stats} isArchive={controller.isArchive} /> : null}
|
{controller.schema ? <RSFormStats stats={controller.schema.stats} isArchive={controller.isArchive} /> : null}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
import { ILibraryUpdateDTO } from '@/backend/library/api';
|
||||||
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
import { useUpdateItem } from '@/backend/library/useUpdateItem';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconSave } from '@/components/Icons';
|
import { IconSave } from '@/components/Icons';
|
||||||
import SelectVersion from '@/components/select/SelectVersion';
|
import SelectVersion from '@/components/select/SelectVersion';
|
||||||
import Label from '@/components/ui/Label';
|
import Label from '@/components/ui/Label';
|
||||||
|
@ -31,7 +31,7 @@ function FormRSForm({ id }: FormRSFormProps) {
|
||||||
const schema = controller.schema;
|
const schema = controller.schema;
|
||||||
const { updateItem: update } = useUpdateItem();
|
const { updateItem: update } = useUpdateItem();
|
||||||
const { isModified, setIsModified } = useModificationStore();
|
const { isModified, setIsModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const [title, setTitle] = useState(schema.title);
|
const [title, setTitle] = useState(schema.title);
|
||||||
const [alias, setAlias] = useState(schema.alias);
|
const [alias, setAlias] = useState(schema.alias);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useIsProcessingLibrary } from '@/backend/library/useIsProcessingLibrary';
|
import { useMutatingLibrary } from '@/backend/library/useMutatingLibrary';
|
||||||
import { useSetAccessPolicy } from '@/backend/library/useSetAccessPolicy';
|
import { useSetAccessPolicy } from '@/backend/library/useSetAccessPolicy';
|
||||||
import { VisibilityIcon } from '@/components/DomainIcons';
|
import { VisibilityIcon } from '@/components/DomainIcons';
|
||||||
import { IconImmutable, IconMutable } from '@/components/Icons';
|
import { IconImmutable, IconMutable } from '@/components/Icons';
|
||||||
|
@ -23,7 +23,7 @@ interface ToolbarItemAccessProps {
|
||||||
|
|
||||||
function ToolbarItemAccess({ visible, toggleVisible, readOnly, toggleReadOnly, controller }: ToolbarItemAccessProps) {
|
function ToolbarItemAccess({ visible, toggleVisible, readOnly, toggleReadOnly, controller }: ToolbarItemAccessProps) {
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const isProcessing = useIsProcessingLibrary();
|
const isProcessing = useMutatingLibrary();
|
||||||
const policy = controller.schema.access_policy;
|
const policy = controller.schema.access_policy;
|
||||||
const { setAccessPolicy } = useSetAccessPolicy();
|
const { setAccessPolicy } = useSetAccessPolicy();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useIsProcessingLibrary } from '@/backend/library/useIsProcessingLibrary';
|
import { useMutatingLibrary } from '@/backend/library/useMutatingLibrary';
|
||||||
import { IconDestroy, IconSave, IconShare } from '@/components/Icons';
|
import { IconDestroy, IconSave, IconShare } from '@/components/Icons';
|
||||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||||
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
|
import MiniSelectorOSS from '@/components/select/MiniSelectorOSS';
|
||||||
|
@ -26,7 +26,7 @@ interface ToolbarRSFormCardProps {
|
||||||
function ToolbarRSFormCard({ controller, onSubmit }: ToolbarRSFormCardProps) {
|
function ToolbarRSFormCard({ controller, onSubmit }: ToolbarRSFormCardProps) {
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingLibrary();
|
const isProcessing = useMutatingLibrary();
|
||||||
const canSave = isModified && !isProcessing;
|
const canSave = isModified && !isProcessing;
|
||||||
|
|
||||||
const ossSelector = (() => {
|
const ossSelector = (() => {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import fileDownload from 'js-file-download';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { IconCSV } from '@/components/Icons';
|
import { IconCSV } from '@/components/Icons';
|
||||||
import { type RowSelectionState } from '@/components/ui/DataTable';
|
import { type RowSelectionState } from '@/components/ui/DataTable';
|
||||||
import MiniButton from '@/components/ui/MiniButton';
|
import MiniButton from '@/components/ui/MiniButton';
|
||||||
|
@ -24,7 +24,7 @@ import ToolbarRSList from './ToolbarRSList';
|
||||||
function EditorRSList() {
|
function EditorRSList() {
|
||||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||||
const controller = useRSEdit();
|
const controller = useRSEdit();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const [filtered, setFiltered] = useState<IConstituenta[]>(controller.schema.items);
|
const [filtered, setFiltered] = useState<IConstituenta[]>(controller.schema.items);
|
||||||
const [filterText, setFilterText] = useState('');
|
const [filterText, setFilterText] = useState('');
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { CstTypeIcon } from '@/components/DomainIcons';
|
import { CstTypeIcon } from '@/components/DomainIcons';
|
||||||
import {
|
import {
|
||||||
IconClone,
|
IconClone,
|
||||||
|
@ -25,7 +25,7 @@ import { useRSEdit } from '../RSEditContext';
|
||||||
|
|
||||||
function ToolbarRSList() {
|
function ToolbarRSList() {
|
||||||
const controller = useRSEdit();
|
const controller = useRSEdit();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const insertMenu = useDropdown();
|
const insertMenu = useDropdown();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
import { useStoreApi } from 'reactflow';
|
import { useStoreApi } from 'reactflow';
|
||||||
import { useDebounce } from 'use-debounce';
|
import { useDebounce } from 'use-debounce';
|
||||||
|
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import InfoConstituenta from '@/components/info/InfoConstituenta';
|
import InfoConstituenta from '@/components/info/InfoConstituenta';
|
||||||
import SelectedCounter from '@/components/info/SelectedCounter';
|
import SelectedCounter from '@/components/info/SelectedCounter';
|
||||||
import { CProps } from '@/components/props';
|
import { CProps } from '@/components/props';
|
||||||
|
@ -54,7 +54,7 @@ function TGFlow() {
|
||||||
const flow = useReactFlow();
|
const flow = useReactFlow();
|
||||||
const store = useStoreApi();
|
const store = useStoreApi();
|
||||||
const { addSelectedNodes } = store.getState();
|
const { addSelectedNodes } = store.getState();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const showParams = useDialogsStore(state => state.showGraphParams);
|
const showParams = useDialogsStore(state => state.showGraphParams);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import {
|
import {
|
||||||
IconClustering,
|
IconClustering,
|
||||||
IconClusteringOff,
|
IconClusteringOff,
|
||||||
|
@ -48,7 +48,7 @@ function ToolbarTermGraph({
|
||||||
onSaveImage
|
onSaveImage
|
||||||
}: ToolbarTermGraphProps) {
|
}: ToolbarTermGraphProps) {
|
||||||
const controller = useRSEdit();
|
const controller = useRSEdit();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const showTypeGraph = useDialogsStore(state => state.showShowTypeGraph);
|
const showTypeGraph = useDialogsStore(state => state.showShowTypeGraph);
|
||||||
|
|
||||||
function handleShowTypeGraph() {
|
function handleShowTypeGraph() {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useAuthSuspense } from '@/backend/auth/useAuth';
|
||||||
import { useCstSubstitute } from '@/backend/rsform/useCstSubstitute';
|
import { useCstSubstitute } from '@/backend/rsform/useCstSubstitute';
|
||||||
import { useDownloadRSForm } from '@/backend/rsform/useDownloadRSForm';
|
import { useDownloadRSForm } from '@/backend/rsform/useDownloadRSForm';
|
||||||
import { useInlineSynthesis } from '@/backend/rsform/useInlineSynthesis';
|
import { useInlineSynthesis } from '@/backend/rsform/useInlineSynthesis';
|
||||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
import { useMutatingRSForm } from '@/backend/rsform/useMutatingRSForm';
|
||||||
import { useProduceStructure } from '@/backend/rsform/useProduceStructure';
|
import { useProduceStructure } from '@/backend/rsform/useProduceStructure';
|
||||||
import { useResetAliases } from '@/backend/rsform/useResetAliases';
|
import { useResetAliases } from '@/backend/rsform/useResetAliases';
|
||||||
import { useRestoreOrder } from '@/backend/rsform/useRestoreOrder';
|
import { useRestoreOrder } from '@/backend/rsform/useRestoreOrder';
|
||||||
|
@ -63,7 +63,7 @@ function MenuRSTabs() {
|
||||||
const role = useRoleStore(state => state.role);
|
const role = useRoleStore(state => state.role);
|
||||||
const setRole = useRoleStore(state => state.setRole);
|
const setRole = useRoleStore(state => state.setRole);
|
||||||
const { isModified } = useModificationStore();
|
const { isModified } = useModificationStore();
|
||||||
const isProcessing = useIsProcessingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
|
|
||||||
const { resetAliases } = useResetAliases();
|
const { resetAliases } = useResetAliases();
|
||||||
const { restoreOrder } = useRestoreOrder();
|
const { restoreOrder } = useRestoreOrder();
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { useParams } from 'react-router';
|
||||||
|
|
||||||
import { useBlockNavigation, useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
import { useBlockNavigation, useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||||
import { urls } from '@/app/urls';
|
import { urls } from '@/app/urls';
|
||||||
import InfoError, { ErrorData } from '@/components/info/InfoError';
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
import Divider from '@/components/ui/Divider';
|
import Divider from '@/components/ui/Divider';
|
||||||
import TextURL from '@/components/ui/TextURL';
|
import TextURL from '@/components/ui/TextURL';
|
||||||
import useQueryStrings from '@/hooks/useQueryStrings';
|
import useQueryStrings from '@/hooks/useQueryStrings';
|
||||||
|
@ -33,6 +33,7 @@ function RSFormPage() {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ErrorBoundary
|
<ErrorBoundary
|
||||||
|
onError={filterErrors}
|
||||||
FallbackComponent={({ error }) => (
|
FallbackComponent={({ error }) => (
|
||||||
<ProcessError error={error as ErrorData} isArchive={!!version} itemID={itemID} />
|
<ProcessError error={error as ErrorData} isArchive={!!version} itemID={itemID} />
|
||||||
)}
|
)}
|
||||||
|
@ -47,6 +48,13 @@ function RSFormPage() {
|
||||||
export default RSFormPage;
|
export default RSFormPage;
|
||||||
|
|
||||||
// ====== Internals =========
|
// ====== Internals =========
|
||||||
|
const filterErrors = (error: Error) => {
|
||||||
|
if (axios.isAxiosError(error) && error.response && (error.response.status === 404 || error.response.status === 403)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
};
|
||||||
|
|
||||||
function ProcessError({
|
function ProcessError({
|
||||||
error,
|
error,
|
||||||
isArchive,
|
isArchive,
|
||||||
|
@ -55,7 +63,7 @@ function ProcessError({
|
||||||
error: ErrorData;
|
error: ErrorData;
|
||||||
isArchive: boolean;
|
isArchive: boolean;
|
||||||
itemID?: LibraryItemID;
|
itemID?: LibraryItemID;
|
||||||
}): React.ReactElement {
|
}): React.ReactElement | null {
|
||||||
if (axios.isAxiosError(error) && error.response) {
|
if (axios.isAxiosError(error) && error.response) {
|
||||||
if (error.response.status === 404) {
|
if (error.response.status === 404) {
|
||||||
return (
|
return (
|
||||||
|
@ -77,5 +85,5 @@ function ProcessError({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return <InfoError error={error} />;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user