mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Refactor contexts. Do not share reload in interface
This commit is contained in:
parent
b9d0dd4c20
commit
83e08ca7fc
|
@ -11,7 +11,6 @@ interface IAuthContext {
|
|||
logout: (callback?: DataCallback) => void
|
||||
signup: (data: IUserSignupData, callback?: DataCallback<IUserProfile>) => void
|
||||
updatePassword: (data: IUserUpdatePassword, callback?: () => void) => void
|
||||
reload: (callback?: () => void) => void
|
||||
loading: boolean
|
||||
error: ErrorInfo
|
||||
setError: (error: ErrorInfo) => void
|
||||
|
@ -40,7 +39,7 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
const reload = useCallback(
|
||||
(callback?: () => void) => {
|
||||
getAuth({
|
||||
onError: () => { setUser(undefined); },
|
||||
onError: () => setUser(undefined),
|
||||
onSuccess: currentUser => {
|
||||
if (currentUser.id) {
|
||||
setUser(currentUser);
|
||||
|
@ -58,7 +57,7 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
data: data,
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => { setError(error); },
|
||||
onError: error => setError(error),
|
||||
onSuccess: newData => reload(() => {
|
||||
if (callback) callback(newData);
|
||||
})
|
||||
|
@ -81,8 +80,10 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
data: data,
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => { setError(error); },
|
||||
onSuccess: newData => reload(() => { if (callback) callback(newData); })
|
||||
onError: error => setError(error),
|
||||
onSuccess: newData => reload(() => {
|
||||
if (callback) callback(newData);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -93,13 +94,12 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
data: data,
|
||||
showError: true,
|
||||
setLoading: setLoading,
|
||||
onError: error => { setError(error); },
|
||||
onSuccess: () => {
|
||||
setUser(undefined);
|
||||
reload();
|
||||
onError: error => setError(error),
|
||||
onSuccess: () => reload(() => {
|
||||
if (callback) callback();
|
||||
}});
|
||||
}, [setUser, reload]);
|
||||
})
|
||||
});
|
||||
}, [reload]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
reload();
|
||||
|
@ -107,7 +107,7 @@ export const AuthState = ({ children }: AuthStateProps) => {
|
|||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{ user, login, logout, signup, loading, error, reload, setError, updatePassword }}
|
||||
value={{ user, login, logout, signup, loading, error, setError, updatePassword }}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||
|
||||
import { ErrorInfo } from '../components/BackendError';
|
||||
import { DataCallback, getLibrary, postNewRSForm } from '../utils/backendAPI';
|
||||
import { ILibraryFilter, IRSFormCreateData, IRSFormMeta, matchRSFormMeta } from '../utils/models';
|
||||
import { DataCallback, deleteRSForm, getLibrary, postCloneRSForm, postNewRSForm } from '../utils/backendAPI';
|
||||
import { ILibraryFilter, IRSFormCreateData, IRSFormData, IRSFormMeta, matchRSFormMeta } from '../utils/models';
|
||||
import { useAuth } from './AuthContext';
|
||||
|
||||
interface ILibraryContext {
|
||||
|
@ -12,9 +12,10 @@ interface ILibraryContext {
|
|||
error: ErrorInfo
|
||||
setError: (error: ErrorInfo) => void
|
||||
|
||||
reload: (callback?: () => void) => void
|
||||
filter: (params: ILibraryFilter) => IRSFormMeta[]
|
||||
createSchema: (data: IRSFormCreateData, callback?: DataCallback<IRSFormMeta>) => void
|
||||
cloneSchema: (target:number, data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => void
|
||||
destroySchema: (target: number, callback?: () => void) => void
|
||||
}
|
||||
|
||||
const LibraryContext = createContext<ILibraryContext | null>(null)
|
||||
|
@ -88,10 +89,40 @@ export const LibraryState = ({ children }: LibraryStateProps) => {
|
|||
});
|
||||
}, [reload]);
|
||||
|
||||
const destroySchema = useCallback(
|
||||
(target: number, callback?: () => void) => {
|
||||
setError(undefined)
|
||||
deleteRSForm(String(target), {
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSuccess: () => reload(() => {
|
||||
if (callback) callback();
|
||||
})
|
||||
});
|
||||
}, [setError, reload]);
|
||||
|
||||
const cloneSchema = useCallback(
|
||||
(target: number, data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => {
|
||||
if (!user) {
|
||||
return;
|
||||
}
|
||||
setError(undefined)
|
||||
postCloneRSForm(String(target), {
|
||||
data: data,
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSuccess: newSchema => reload(() => {
|
||||
if (callback) callback(newSchema);
|
||||
})
|
||||
});
|
||||
}, [reload, setError, user]);
|
||||
|
||||
return (
|
||||
<LibraryContext.Provider value={{
|
||||
items, loading, processing, error, setError,
|
||||
reload, filter, createSchema
|
||||
filter, createSchema, cloneSchema, destroySchema
|
||||
}}>
|
||||
{ children }
|
||||
</LibraryContext.Provider>
|
||||
|
|
|
@ -4,18 +4,17 @@ import { toast } from 'react-toastify'
|
|||
import { type ErrorInfo } from '../components/BackendError'
|
||||
import { useRSFormDetails } from '../hooks/useRSFormDetails'
|
||||
import {
|
||||
type DataCallback, deleteRSForm, getTRSFile,
|
||||
type DataCallback, getTRSFile,
|
||||
patchConstituenta, patchDeleteConstituenta,
|
||||
patchMoveConstituenta, patchResetAliases, patchRSForm,
|
||||
patchUploadTRS, postClaimRSForm, postCloneRSForm, postNewConstituenta
|
||||
patchUploadTRS, postClaimRSForm, postNewConstituenta
|
||||
} from '../utils/backendAPI'
|
||||
import {
|
||||
IConstituentaList, IConstituentaMeta, ICstCreateData,
|
||||
ICstMovetoData, ICstUpdateData, IRSForm, IRSFormCreateData,
|
||||
IRSFormData, IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
|
||||
ICstMovetoData, ICstUpdateData, IRSForm,
|
||||
IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
|
||||
} from '../utils/models'
|
||||
import { useAuth } from './AuthContext'
|
||||
import { useLibrary } from './LibraryContext'
|
||||
|
||||
interface IRSFormContext {
|
||||
schema?: IRSForm
|
||||
|
@ -36,11 +35,10 @@ interface IRSFormContext {
|
|||
toggleTracking: () => void
|
||||
|
||||
update: (data: IRSFormUpdateData, callback?: DataCallback<IRSFormMeta>) => void
|
||||
destroy: (callback?: () => void) => void
|
||||
claim: (callback?: DataCallback<IRSFormMeta>) => void
|
||||
download: (callback: DataCallback<Blob>) => void
|
||||
upload: (data: IRSFormUploadData, callback: () => void) => void
|
||||
clone: (data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => void
|
||||
|
||||
resetAliases: (callback: () => void) => void
|
||||
|
||||
cstCreate: (data: ICstCreateData, callback?: DataCallback<IConstituentaMeta>) => void
|
||||
|
@ -69,7 +67,6 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
|||
const { user } = useAuth();
|
||||
const { schema, reload, error, setError, setSchema, loading } = useRSFormDetails({ target: schemaID });
|
||||
const [ processing, setProcessing ] = useState(false);
|
||||
const library = useLibrary();
|
||||
|
||||
const [ isForceAdmin, setIsForceAdmin ] = useState(false);
|
||||
const [ isReadonly, setIsReadonly ] = useState(false);
|
||||
|
@ -130,21 +127,6 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
|||
});
|
||||
}, [schemaID, setError, setSchema, schema]);
|
||||
|
||||
const destroy = useCallback(
|
||||
(callback?: () => void) => {
|
||||
setError(undefined)
|
||||
deleteRSForm(schemaID, {
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSuccess: () => {
|
||||
setSchema(undefined);
|
||||
library.reload();
|
||||
if (callback) callback();
|
||||
}
|
||||
});
|
||||
}, [schemaID, setError, setSchema, library]);
|
||||
|
||||
const claim = useCallback(
|
||||
(callback?: DataCallback<IRSFormMeta>) => {
|
||||
if (!schema || !user) {
|
||||
|
@ -162,24 +144,6 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
|||
});
|
||||
}, [schemaID, setError, schema, user, setSchema]);
|
||||
|
||||
const clone = useCallback(
|
||||
(data: IRSFormCreateData, callback: DataCallback<IRSFormData>) => {
|
||||
if (!schema || !user) {
|
||||
return;
|
||||
}
|
||||
setError(undefined)
|
||||
postCloneRSForm(schemaID, {
|
||||
data: data,
|
||||
showError: true,
|
||||
setLoading: setProcessing,
|
||||
onError: error => setError(error),
|
||||
onSuccess: newSchema => {
|
||||
library.reload();
|
||||
if (callback) callback(newSchema);
|
||||
}
|
||||
});
|
||||
}, [schemaID, setError, schema, user, library]);
|
||||
|
||||
const resetAliases = useCallback(
|
||||
(callback?: () => void) => {
|
||||
if (!schema || !user) {
|
||||
|
@ -276,7 +240,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
|||
toggleForceAdmin: () => { setIsForceAdmin(prev => !prev) },
|
||||
toggleReadonly: () => { setIsReadonly(prev => !prev) },
|
||||
toggleTracking,
|
||||
update, download, upload, destroy, claim, resetAliases, clone,
|
||||
update, download, upload, claim, resetAliases,
|
||||
cstUpdate, cstCreate, cstDelete, cstMoveTo
|
||||
}}>
|
||||
{ children }
|
||||
|
|
|
@ -6,6 +6,7 @@ import Checkbox from '../../components/Common/Checkbox';
|
|||
import Modal from '../../components/Common/Modal';
|
||||
import TextArea from '../../components/Common/TextArea';
|
||||
import TextInput from '../../components/Common/TextInput';
|
||||
import { useLibrary } from '../../context/LibraryContext';
|
||||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { IRSFormCreateData } from '../../utils/models';
|
||||
import { getCloneTitle } from '../../utils/staticUI';
|
||||
|
@ -21,7 +22,8 @@ function DlgCloneRSForm({ hideWindow }: DlgCloneRSFormProps) {
|
|||
const [comment, setComment] = useState('');
|
||||
const [common, setCommon] = useState(false);
|
||||
|
||||
const { schema, clone } = useRSForm();
|
||||
const { cloneSchema } = useLibrary();
|
||||
const { schema } = useRSForm();
|
||||
|
||||
useEffect(() => {
|
||||
if (schema) {
|
||||
|
@ -33,13 +35,16 @@ function DlgCloneRSForm({ hideWindow }: DlgCloneRSFormProps) {
|
|||
}, [schema, schema?.title, schema?.alias, schema?.comment, schema?.is_common]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (!schema) {
|
||||
return;
|
||||
}
|
||||
const data: IRSFormCreateData = {
|
||||
title: title,
|
||||
alias: alias,
|
||||
comment: comment,
|
||||
is_common: common
|
||||
};
|
||||
clone(data, newSchema => {
|
||||
cloneSchema(schema.id, data, newSchema => {
|
||||
toast.success(`Схема создана: ${newSchema.alias}`);
|
||||
navigate(`/rsforms/${newSchema.id}`);
|
||||
});
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useCallback, useLayoutEffect, useState } from 'react';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import Checkbox from '../../components/Common/Checkbox';
|
||||
|
@ -13,15 +12,18 @@ import { useAuth } from '../../context/AuthContext';
|
|||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { useUsers } from '../../context/UsersContext';
|
||||
import { IRSFormCreateData } from '../../utils/models';
|
||||
import { claimOwnershipProc, deleteRSFormProc, downloadRSFormProc, shareCurrentURLProc } from '../../utils/procedures';
|
||||
import { claimOwnershipProc, downloadRSFormProc, shareCurrentURLProc } from '../../utils/procedures';
|
||||
|
||||
function EditorRSForm() {
|
||||
const navigate = useNavigate();
|
||||
interface EditorRSFormProps {
|
||||
onDestroy: () => void
|
||||
}
|
||||
|
||||
function EditorRSForm({ onDestroy }: EditorRSFormProps) {
|
||||
const intl = useIntl();
|
||||
const { getUserLabel } = useUsers();
|
||||
const {
|
||||
schema, update, download,
|
||||
isEditable, isOwned, isClaimable, processing, destroy, claim
|
||||
isEditable, isOwned, isClaimable, processing, claim
|
||||
} = useRSForm();
|
||||
const { user } = useAuth();
|
||||
|
||||
|
@ -66,9 +68,6 @@ function EditorRSForm() {
|
|||
update(data, () => toast.success('Изменения сохранены'));
|
||||
};
|
||||
|
||||
const handleDelete =
|
||||
useCallback(() => { deleteRSFormProc(destroy, navigate); }, [destroy, navigate]);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
const fileName = (schema?.alias ?? 'Schema') + '.trs';
|
||||
downloadRSFormProc(download, fileName);
|
||||
|
@ -97,7 +96,7 @@ function EditorRSForm() {
|
|||
<MiniButton
|
||||
tooltip='Удалить схему'
|
||||
disabled={!isEditable}
|
||||
onClick={handleDelete}
|
||||
onClick={onDestroy}
|
||||
icon={<DumpBinIcon size={5} color={isEditable ? 'text-red' : ''} />}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,7 @@ import { toast } from 'react-toastify';
|
|||
import BackendError from '../../components/BackendError';
|
||||
import ConceptTab from '../../components/Common/ConceptTab';
|
||||
import { Loader } from '../../components/Common/Loader';
|
||||
import { useLibrary } from '../../context/LibraryContext';
|
||||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import { prefixes, TIMEOUT_UI_REFRESH } from '../../utils/constants';
|
||||
import { CstType, ICstCreateData, SyntaxTree } from '../../utils/models';
|
||||
|
@ -36,6 +37,7 @@ function RSTabs() {
|
|||
error, schema, loading,
|
||||
cstCreate, cstDelete
|
||||
} = useRSForm();
|
||||
const { destroySchema } = useLibrary();
|
||||
|
||||
const [activeTab, setActiveTab] = useState(RSTabsList.CARD);
|
||||
const [activeID, setActiveID] = useState<number | undefined>(undefined)
|
||||
|
@ -151,7 +153,6 @@ function RSTabs() {
|
|||
});
|
||||
}, [afterDelete, cstDelete, schema, activeID, activeTab, navigateTo]);
|
||||
|
||||
|
||||
const promptDeleteCst = useCallback(
|
||||
(selected: number[], callback?: (items: number[]) => void) => {
|
||||
setAfterDelete(() => (
|
||||
|
@ -174,6 +175,17 @@ function RSTabs() {
|
|||
navigateTo(RSTabsList.CST_EDIT, cstID)
|
||||
}, [navigateTo]);
|
||||
|
||||
const onDestroySchema = useCallback(
|
||||
() => {
|
||||
if (!schema || !window.confirm('Вы уверены, что хотите удалить данную схему?')) {
|
||||
return;
|
||||
}
|
||||
destroySchema(schema.id, () => {
|
||||
toast.success('Схема удалена');
|
||||
navigate('/library?filter=personal');
|
||||
});
|
||||
}, [schema, destroySchema, navigate]);
|
||||
|
||||
return (
|
||||
<div className='w-full'>
|
||||
{ loading && <Loader /> }
|
||||
|
@ -213,6 +225,7 @@ function RSTabs() {
|
|||
>
|
||||
<TabList className='flex items-start w-fit clr-bg-pop'>
|
||||
<RSTabsMenu
|
||||
onDestroy={onDestroySchema}
|
||||
showCloneDialog={() => setShowClone(true)}
|
||||
showUploadDialog={() => setShowUpload(true)}
|
||||
/>
|
||||
|
@ -226,7 +239,9 @@ function RSTabs() {
|
|||
</TabList>
|
||||
|
||||
<TabPanel className='flex items-start w-full gap-2'>
|
||||
<EditorRSForm />
|
||||
<EditorRSForm
|
||||
onDestroy={onDestroySchema}
|
||||
/>
|
||||
{schema.stats && <RSFormStats stats={schema.stats}/>}
|
||||
</TabPanel>
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { useCallback } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import Button from '../../components/Common/Button';
|
||||
import Checkbox from '../../components/Common/Checkbox';
|
||||
|
@ -9,21 +8,21 @@ import { CloneIcon, CrownIcon, DownloadIcon, DumpBinIcon, EyeIcon, EyeOffIcon, M
|
|||
import { useAuth } from '../../context/AuthContext';
|
||||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import useDropdown from '../../hooks/useDropdown';
|
||||
import { claimOwnershipProc, deleteRSFormProc, downloadRSFormProc, shareCurrentURLProc } from '../../utils/procedures';
|
||||
import { claimOwnershipProc, downloadRSFormProc, shareCurrentURLProc } from '../../utils/procedures';
|
||||
|
||||
interface RSTabsMenuProps {
|
||||
showUploadDialog: () => void
|
||||
showCloneDialog: () => void
|
||||
onDestroy: () => void
|
||||
}
|
||||
|
||||
function RSTabsMenu({showUploadDialog, showCloneDialog}: RSTabsMenuProps) {
|
||||
const navigate = useNavigate();
|
||||
function RSTabsMenu({showUploadDialog, showCloneDialog, onDestroy}: RSTabsMenuProps) {
|
||||
const { user } = useAuth();
|
||||
const {
|
||||
schema,
|
||||
isOwned, isEditable, isTracking, isReadonly: readonly, isForceAdmin: forceAdmin,
|
||||
toggleTracking, toggleForceAdmin, toggleReadonly,
|
||||
claim, destroy, download
|
||||
claim, download
|
||||
} = useRSForm();
|
||||
const schemaMenu = useDropdown();
|
||||
const editMenu = useDropdown();
|
||||
|
@ -35,8 +34,8 @@ function RSTabsMenu({showUploadDialog, showCloneDialog}: RSTabsMenuProps) {
|
|||
|
||||
const handleDelete = useCallback(() => {
|
||||
schemaMenu.hide();
|
||||
deleteRSFormProc(destroy, navigate);
|
||||
}, [destroy, navigate, schemaMenu]);
|
||||
onDestroy();
|
||||
}, [onDestroy, schemaMenu]);
|
||||
|
||||
const handleDownload = useCallback(() => {
|
||||
schemaMenu.hide();
|
||||
|
|
|
@ -20,19 +20,6 @@ export function claimOwnershipProc(
|
|||
claim(() => toast.success('Вы стали владельцем схемы'));
|
||||
}
|
||||
|
||||
export function deleteRSFormProc(
|
||||
destroy: (callback?: () => void) => void,
|
||||
navigate: (path: string) => void
|
||||
) {
|
||||
if (!window.confirm('Вы уверены, что хотите удалить данную схему?')) {
|
||||
return;
|
||||
}
|
||||
destroy(() => {
|
||||
toast.success('Схема удалена');
|
||||
navigate('/library?filter=personal');
|
||||
});
|
||||
}
|
||||
|
||||
export function downloadRSFormProc(
|
||||
download: (callback: DataCallback<Blob>) => void,
|
||||
fileName: string
|
||||
|
|
Loading…
Reference in New Issue
Block a user