F: Implement react-query for backend interactions
This commit is contained in:
parent
519b5f6634
commit
fe65dcd574
|
@ -1,8 +1,7 @@
|
|||
import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
|
||||
import { useQuery, useSuspenseQuery } from '@tanstack/react-query';
|
||||
|
||||
import { useLibrary, useLibrarySuspense } from '@/backend/library/useLibrary';
|
||||
import { LibraryItemID } from '@/models/library';
|
||||
import { IOperationSchema, IOperationSchemaData } from '@/models/oss';
|
||||
import { OssLoader } from '@/models/OssLoader';
|
||||
|
||||
import { ossApi } from './api';
|
||||
|
@ -25,23 +24,3 @@ export function useOssSuspense({ itemID }: { itemID: LibraryItemID }) {
|
|||
const schema = new OssLoader(data!, libraryItems).produceOSS();
|
||||
return { schema };
|
||||
}
|
||||
|
||||
export function useOssUpdate({ itemID }: { itemID?: LibraryItemID }) {
|
||||
const { items: libraryItems } = useLibrary();
|
||||
const client = useQueryClient();
|
||||
const queryKey = [ossApi.getOssQueryOptions({ itemID }).queryKey];
|
||||
return {
|
||||
update: (data: IOperationSchemaData) =>
|
||||
client.setQueryData(queryKey, new OssLoader(data, libraryItems).produceOSS()),
|
||||
partialUpdate: (data: Partial<IOperationSchema>) =>
|
||||
client.setQueryData(queryKey, (prev: IOperationSchema) => (prev ? { ...prev, ...data } : prev))
|
||||
};
|
||||
}
|
||||
|
||||
export function useOssInvalidate({ itemID }: { itemID?: LibraryItemID }) {
|
||||
const client = useQueryClient();
|
||||
const queryKey = [ossApi.getOssQueryOptions({ itemID }).queryKey];
|
||||
return {
|
||||
invalidate: () => client.invalidateQueries({ queryKey })
|
||||
};
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ export const useCheckConstituenta = () => {
|
|||
onSuccess?: DataCallback<IExpressionParse>
|
||||
) => mutation.mutate(data, { onSuccess }),
|
||||
isPending: mutation.isPending,
|
||||
error: mutation.error,
|
||||
reset: mutation.reset
|
||||
error: mutation.error
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
'use client';
|
||||
|
||||
import { useCallback, useState } from 'react';
|
||||
|
||||
import { DataCallback } from '@/backend/apiTransport';
|
||||
import { ICheckConstituentaDTO } from '@/backend/rsform/api';
|
||||
import { useCheckConstituenta } from '@/backend/rsform/useCheckConstituenta';
|
||||
import { IConstituenta, type IRSForm } from '@/models/rsform';
|
||||
import { IExpressionParse } from '@/models/rslang';
|
||||
|
||||
function useRSParse({ schema }: { schema?: IRSForm }) {
|
||||
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
|
||||
|
||||
const resetParse = useCallback(() => setParseData(undefined), []);
|
||||
const { checkConstituenta: checkInternal, isPending, error, reset } = useCheckConstituenta();
|
||||
|
||||
function checkConstituenta(expression: string, activeCst: IConstituenta, onSuccess?: DataCallback<IExpressionParse>) {
|
||||
const data: ICheckConstituentaDTO = {
|
||||
definition_formal: expression,
|
||||
alias: activeCst.alias,
|
||||
cst_type: activeCst.cst_type
|
||||
};
|
||||
checkInternal({ itemID: schema!.id, data }, parse => {
|
||||
setParseData(parse);
|
||||
onSuccess?.(parse);
|
||||
});
|
||||
}
|
||||
|
||||
return { parseData, checkConstituenta, resetParse, error, reset, isPending };
|
||||
}
|
||||
|
||||
export default useRSParse;
|
|
@ -1,6 +1,6 @@
|
|||
'use client';
|
||||
|
||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||
import { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { useConceptNavigation } from '@/app/Navigation/NavigationContext';
|
||||
|
@ -130,16 +130,13 @@ export const OssEditState = ({ itemID, children }: React.PropsWithChildren<OssEd
|
|||
router.push(url);
|
||||
}
|
||||
|
||||
const navigateOperationSchema = useCallback(
|
||||
(target: OperationID) => {
|
||||
function navigateOperationSchema(target: OperationID) {
|
||||
const node = schema.operationByID.get(target);
|
||||
if (!node?.result) {
|
||||
return;
|
||||
}
|
||||
router.push(urls.schema_props({ id: node.result, tab: RSTabID.CST_LIST }));
|
||||
},
|
||||
[router, schema]
|
||||
);
|
||||
}
|
||||
|
||||
function deleteSchema() {
|
||||
if (!schema || !window.confirm(prompts.deleteOSS)) {
|
||||
|
|
|
@ -4,6 +4,9 @@ import { ReactCodeMirrorRef } from '@uiw/react-codemirror';
|
|||
import { useEffect, useRef, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { DataCallback } from '@/backend/apiTransport';
|
||||
import { ICheckConstituentaDTO } from '@/backend/rsform/api';
|
||||
import { useCheckConstituenta } from '@/backend/rsform/useCheckConstituenta';
|
||||
import { useIsProcessingRSForm } from '@/backend/rsform/useIsProcessingRSForm';
|
||||
import BadgeHelp from '@/components/info/BadgeHelp';
|
||||
import { CProps } from '@/components/props';
|
||||
|
@ -11,7 +14,6 @@ import RSInput from '@/components/RSInput';
|
|||
import { parser as rslangParser } from '@/components/RSInput/rslang/parserAST';
|
||||
import { RSTextWrapper } from '@/components/RSInput/textEditing';
|
||||
import Overlay from '@/components/ui/Overlay';
|
||||
import useRSParse from '@/hooks/useRSParse';
|
||||
import { HelpTopic } from '@/models/miscellaneous';
|
||||
import { ConstituentaID, IConstituenta } from '@/models/rsform';
|
||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||
|
@ -60,17 +62,31 @@ function EditorRSExpression({
|
|||
const controller = useRSEdit();
|
||||
|
||||
const [isModified, setIsModified] = useState(false);
|
||||
const parser = useRSParse({ schema: controller.schema });
|
||||
const rsInput = useRef<ReactCodeMirrorRef>(null);
|
||||
const [parseData, setParseData] = useState<IExpressionParse | undefined>(undefined);
|
||||
|
||||
const isProcessing = useIsProcessingRSForm();
|
||||
const showControls = usePreferencesStore(state => state.showExpressionControls);
|
||||
const showAST = useDialogsStore(state => state.showShowAST);
|
||||
|
||||
const { checkConstituenta: checkInternal, isPending } = useCheckConstituenta();
|
||||
|
||||
function checkConstituenta(expression: string, activeCst: IConstituenta, onSuccess?: DataCallback<IExpressionParse>) {
|
||||
const data: ICheckConstituentaDTO = {
|
||||
definition_formal: expression,
|
||||
alias: activeCst.alias,
|
||||
cst_type: activeCst.cst_type
|
||||
};
|
||||
checkInternal({ itemID: controller.schema.id, data }, parse => {
|
||||
setParseData(parse);
|
||||
onSuccess?.(parse);
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setIsModified(false);
|
||||
parser.resetParse();
|
||||
}, [activeCst, parser, toggleReset]);
|
||||
setParseData(undefined);
|
||||
}, [activeCst, toggleReset]);
|
||||
|
||||
function handleChange(newValue: string) {
|
||||
onChangeExpression(newValue);
|
||||
|
@ -78,7 +94,7 @@ function EditorRSExpression({
|
|||
}
|
||||
|
||||
function handleCheckExpression(callback?: (parse: IExpressionParse) => void) {
|
||||
parser.checkConstituenta(value, activeCst, parse => {
|
||||
checkConstituenta(value, activeCst, parse => {
|
||||
onChangeLocalParse(parse);
|
||||
if (parse.errors.length > 0) {
|
||||
onShowError(parse.errors[0], parse.prefixLen);
|
||||
|
@ -152,10 +168,10 @@ function EditorRSExpression({
|
|||
className='w-fit pl-[8.5rem] xs:pl-[2rem] flex gap-1'
|
||||
>
|
||||
<StatusBar
|
||||
processing={parser.isPending}
|
||||
processing={isPending}
|
||||
isModified={isModified}
|
||||
activeCst={activeCst}
|
||||
parseData={parser.parseData}
|
||||
parseData={parseData}
|
||||
onAnalyze={() => handleCheckExpression()}
|
||||
/>
|
||||
<BadgeHelp topic={HelpTopic.UI_CST_STATUS} offset={4} />
|
||||
|
@ -181,10 +197,10 @@ function EditorRSExpression({
|
|||
/>
|
||||
|
||||
<ParsingResult
|
||||
isOpen={!!parser.parseData && parser.parseData.errors.length > 0}
|
||||
data={parser.parseData}
|
||||
isOpen={!!parseData && parseData.errors.length > 0}
|
||||
data={parseData}
|
||||
disabled={disabled}
|
||||
onShowError={error => onShowError(error, parser.parseData?.prefixLen ?? 0)}
|
||||
onShowError={error => onShowError(error, parseData?.prefixLen ?? 0)}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -381,7 +381,6 @@ function MenuRSTabs() {
|
|||
</Dropdown>
|
||||
</div>
|
||||
) : null}
|
||||
router.push(urls.schema(itemID, version), newTab);
|
||||
{controller.isArchive && user ? (
|
||||
<Button
|
||||
dense
|
||||
|
|
|
@ -99,13 +99,7 @@ export const RSEditState = ({ itemID, versionID, activeTab, children }: React.Pr
|
|||
const [selected, setSelected] = useState<ConstituentaID[]>([]);
|
||||
const canDeleteSelected = selected.length > 0 && selected.every(id => !schema.cstByID.get(id)?.is_inherited);
|
||||
|
||||
const activeCst: IConstituenta | undefined = (() => {
|
||||
if (!schema || selected.length === 0) {
|
||||
return undefined;
|
||||
} else {
|
||||
return schema.cstByID.get(selected[-1]);
|
||||
}
|
||||
})();
|
||||
const activeCst = selected.length === 0 ? undefined : schema.cstByID.get(selected[selected.length - 1]);
|
||||
|
||||
const { cstCreate } = useCstCreate();
|
||||
const { cstMove } = useCstMove();
|
||||
|
|
|
@ -37,14 +37,14 @@ function RSTabs() {
|
|||
return () => {
|
||||
document.title = oldTitle;
|
||||
};
|
||||
}, [schema?.title]);
|
||||
}, [schema.title]);
|
||||
|
||||
useEffect(() => {
|
||||
hideFooter(activeTab !== RSTabID.CARD);
|
||||
setIsModified(false);
|
||||
if (activeTab === RSTabID.CST_EDIT) {
|
||||
const cstID = Number(cstQuery);
|
||||
if (cstID && schema?.cstByID.has(cstID)) {
|
||||
if (cstID && schema.cstByID.has(cstID)) {
|
||||
setSelected([cstID]);
|
||||
} else {
|
||||
setSelected([]);
|
||||
|
|
|
@ -1 +1 @@
|
|||
export { default } from './RSTabs';
|
||||
export { default } from './RSFormPage';
|
||||
|
|
Loading…
Reference in New Issue
Block a user