mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 13:00:39 +03:00
Frontend: Implement Cst reordering
This commit is contained in:
parent
a5ec7c4fde
commit
8104b57097
|
@ -222,7 +222,6 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
listCst=serializer.validated_data['items'],
|
listCst=serializer.validated_data['items'],
|
||||||
target=serializer.validated_data['move_to']
|
target=serializer.validated_data['move_to']
|
||||||
)
|
)
|
||||||
schema.item.refresh_from_db()
|
|
||||||
return Response(
|
return Response(
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data=s.RSFormParseSerializer(schema.item).data
|
data=s.RSFormParseSerializer(schema.item).data
|
||||||
|
@ -247,6 +246,27 @@ class RSFormViewSet(viewsets.GenericViewSet, generics.ListAPIView, generics.Retr
|
||||||
status=c.HTTP_200_OK,
|
status=c.HTTP_200_OK,
|
||||||
data=s.RSFormParseSerializer(schema.item).data
|
data=s.RSFormParseSerializer(schema.item).data
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@extend_schema(
|
||||||
|
summary='restore order based on types and term graph',
|
||||||
|
tags=['RSForm'],
|
||||||
|
request=None,
|
||||||
|
responses={
|
||||||
|
c.HTTP_200_OK: s.RSFormParseSerializer,
|
||||||
|
c.HTTP_403_FORBIDDEN: None,
|
||||||
|
c.HTTP_404_NOT_FOUND: None
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@action(detail=True, methods=['patch'], url_path='restore-order')
|
||||||
|
def restore_order(self, request: Request, pk):
|
||||||
|
''' Endpoint: Restore order based on types and term graph. '''
|
||||||
|
schema = self._get_schema()
|
||||||
|
# TODO: implement reordering
|
||||||
|
# schema.reset_aliases()
|
||||||
|
return Response(
|
||||||
|
status=c.HTTP_200_OK,
|
||||||
|
data=s.RSFormParseSerializer(schema.item).data
|
||||||
|
)
|
||||||
|
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
summary='load data from TRS file',
|
summary='load data from TRS file',
|
||||||
|
|
|
@ -42,7 +42,7 @@ import {
|
||||||
} from '@/models/rsform';
|
} from '@/models/rsform';
|
||||||
import { IExpressionParse, IRSExpression } from '@/models/rslang';
|
import { IExpressionParse, IRSExpression } from '@/models/rslang';
|
||||||
|
|
||||||
import { buildConstants } from './constants';
|
import { buildConstants } from '../utils/constants';
|
||||||
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
xsrfCookieName: 'csrftoken',
|
xsrfCookieName: 'csrftoken',
|
||||||
|
@ -369,6 +369,14 @@ export function patchResetAliases(target: string, request: FrontPull<IRSFormData
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function patchRestoreOrder(target: string, request: FrontPull<IRSFormData>) {
|
||||||
|
AxiosPatch({
|
||||||
|
title: `Restore order for RSForm id=${target}`,
|
||||||
|
endpoint: `/api/rsforms/${target}/restore-order`,
|
||||||
|
request: request
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function patchUploadTRS(target: string, request: FrontExchange<IRSFormUploadData, IRSFormData>) {
|
export function patchUploadTRS(target: string, request: FrontExchange<IRSFormUploadData, IRSFormData>) {
|
||||||
AxiosPatch({
|
AxiosPatch({
|
||||||
title: `Replacing data with trs file for RSForm id=${target}`,
|
title: `Replacing data with trs file for RSForm id=${target}`,
|
|
@ -21,6 +21,7 @@ export { BiMeteor as IconAdmin } from 'react-icons/bi';
|
||||||
export { LuGlasses as IconReader } from 'react-icons/lu';
|
export { LuGlasses as IconReader } from 'react-icons/lu';
|
||||||
export { FiBell as IconFollow } from 'react-icons/fi';
|
export { FiBell as IconFollow } from 'react-icons/fi';
|
||||||
export { FiBellOff as IconFollowOff } from 'react-icons/fi';
|
export { FiBellOff as IconFollowOff } from 'react-icons/fi';
|
||||||
|
export { FaSortAmountDownAlt as IconSortText } from 'react-icons/fa';
|
||||||
|
|
||||||
export { LuChevronDown as IconDropArrow } from 'react-icons/lu';
|
export { LuChevronDown as IconDropArrow } from 'react-icons/lu';
|
||||||
export { LuChevronUp as IconDropArrowUp } from 'react-icons/lu';
|
export { LuChevronUp as IconDropArrowUp } from 'react-icons/lu';
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
postResetPassword,
|
postResetPassword,
|
||||||
postSignup,
|
postSignup,
|
||||||
postValidatePasswordToken
|
postValidatePasswordToken
|
||||||
} from '@/utils/backendAPI';
|
} from '@/app/backendAPI';
|
||||||
|
|
||||||
import { useUsers } from './UsersContext';
|
import { useUsers } from './UsersContext';
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
getTemplates,
|
getTemplates,
|
||||||
postCloneLibraryItem,
|
postCloneLibraryItem,
|
||||||
postNewRSForm
|
postNewRSForm
|
||||||
} from '@/utils/backendAPI';
|
} from '@/app/backendAPI';
|
||||||
|
|
||||||
import { useAuth } from './AuthContext';
|
import { useAuth } from './AuthContext';
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,28 @@
|
||||||
|
|
||||||
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
||||||
|
|
||||||
|
import {
|
||||||
|
type DataCallback,
|
||||||
|
deleteUnsubscribe,
|
||||||
|
deleteVersion,
|
||||||
|
getTRSFile,
|
||||||
|
patchConstituenta,
|
||||||
|
patchDeleteConstituenta,
|
||||||
|
patchInlineSynthesis,
|
||||||
|
patchLibraryItem,
|
||||||
|
patchMoveConstituenta,
|
||||||
|
patchProduceStructure,
|
||||||
|
patchRenameConstituenta,
|
||||||
|
patchResetAliases,
|
||||||
|
patchRestoreOrder,
|
||||||
|
patchSubstituteConstituents,
|
||||||
|
patchUploadTRS,
|
||||||
|
patchVersion,
|
||||||
|
postClaimLibraryItem,
|
||||||
|
postCreateVersion,
|
||||||
|
postNewConstituenta,
|
||||||
|
postSubscribe
|
||||||
|
} from '@/app/backendAPI';
|
||||||
import { type ErrorData } from '@/components/info/InfoError';
|
import { type ErrorData } from '@/components/info/InfoError';
|
||||||
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
import useRSFormDetails from '@/hooks/useRSFormDetails';
|
||||||
import { ILibraryItem, IVersionData } from '@/models/library';
|
import { ILibraryItem, IVersionData } from '@/models/library';
|
||||||
|
@ -21,27 +43,6 @@ import {
|
||||||
IRSFormData,
|
IRSFormData,
|
||||||
IRSFormUploadData
|
IRSFormUploadData
|
||||||
} from '@/models/rsform';
|
} from '@/models/rsform';
|
||||||
import {
|
|
||||||
type DataCallback,
|
|
||||||
deleteUnsubscribe,
|
|
||||||
deleteVersion,
|
|
||||||
getTRSFile,
|
|
||||||
patchConstituenta,
|
|
||||||
patchDeleteConstituenta,
|
|
||||||
patchInlineSynthesis,
|
|
||||||
patchLibraryItem,
|
|
||||||
patchMoveConstituenta,
|
|
||||||
patchProduceStructure,
|
|
||||||
patchRenameConstituenta,
|
|
||||||
patchResetAliases,
|
|
||||||
patchSubstituteConstituents,
|
|
||||||
patchUploadTRS,
|
|
||||||
patchVersion,
|
|
||||||
postClaimLibraryItem,
|
|
||||||
postCreateVersion,
|
|
||||||
postNewConstituenta,
|
|
||||||
postSubscribe
|
|
||||||
} from '@/utils/backendAPI';
|
|
||||||
|
|
||||||
import { useAuth } from './AuthContext';
|
import { useAuth } from './AuthContext';
|
||||||
import { useLibrary } from './LibraryContext';
|
import { useLibrary } from './LibraryContext';
|
||||||
|
@ -67,6 +68,7 @@ interface IRSFormContext {
|
||||||
upload: (data: IRSFormUploadData, callback: () => void) => void;
|
upload: (data: IRSFormUploadData, callback: () => void) => void;
|
||||||
|
|
||||||
resetAliases: (callback: () => void) => void;
|
resetAliases: (callback: () => void) => void;
|
||||||
|
restoreOrder: (callback: () => void) => void;
|
||||||
produceStructure: (data: ICstTarget, callback?: DataCallback<ConstituentaID[]>) => void;
|
produceStructure: (data: ICstTarget, callback?: DataCallback<ConstituentaID[]>) => void;
|
||||||
inlineSynthesis: (data: IInlineSynthesisData, callback?: DataCallback<IRSFormData>) => void;
|
inlineSynthesis: (data: IInlineSynthesisData, callback?: DataCallback<IRSFormData>) => void;
|
||||||
|
|
||||||
|
@ -268,6 +270,26 @@ export const RSFormState = ({ schemaID, versionID, children }: RSFormStateProps)
|
||||||
[schemaID, setError, schema, library, user, setSchema]
|
[schemaID, setError, schema, library, user, setSchema]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const restoreOrder = useCallback(
|
||||||
|
(callback?: () => void) => {
|
||||||
|
if (!schema || !user) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setError(undefined);
|
||||||
|
patchRestoreOrder(schemaID, {
|
||||||
|
showError: true,
|
||||||
|
setLoading: setProcessing,
|
||||||
|
onError: setError,
|
||||||
|
onSuccess: newData => {
|
||||||
|
setSchema(Object.assign(schema, newData));
|
||||||
|
library.localUpdateTimestamp(newData.id);
|
||||||
|
if (callback) callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[schemaID, setError, schema, library, user, setSchema]
|
||||||
|
);
|
||||||
|
|
||||||
const produceStructure = useCallback(
|
const produceStructure = useCallback(
|
||||||
(data: ICstTarget, callback?: DataCallback<ConstituentaID[]>) => {
|
(data: ICstTarget, callback?: DataCallback<ConstituentaID[]>) => {
|
||||||
setError(undefined);
|
setError(undefined);
|
||||||
|
@ -502,6 +524,7 @@ export const RSFormState = ({ schemaID, versionID, children }: RSFormStateProps)
|
||||||
download,
|
download,
|
||||||
upload,
|
upload,
|
||||||
claim,
|
claim,
|
||||||
|
restoreOrder,
|
||||||
resetAliases,
|
resetAliases,
|
||||||
produceStructure,
|
produceStructure,
|
||||||
inlineSynthesis,
|
inlineSynthesis,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { createContext, useCallback, useContext, useEffect, useState } from 'rea
|
||||||
import { ErrorData } from '@/components/info/InfoError';
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
import { IUserProfile } from '@/models/library';
|
import { IUserProfile } from '@/models/library';
|
||||||
import { IUserUpdateData } from '@/models/library';
|
import { IUserUpdateData } from '@/models/library';
|
||||||
import { DataCallback, getProfile, patchProfile } from '@/utils/backendAPI';
|
import { DataCallback, getProfile, patchProfile } from '@/app/backendAPI';
|
||||||
|
|
||||||
import { useUsers } from './UsersContext';
|
import { useUsers } from './UsersContext';
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
import { createContext, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { type IUserInfo } from '@/models/library';
|
import { type IUserInfo } from '@/models/library';
|
||||||
import { getActiveUsers } from '@/utils/backendAPI';
|
import { getActiveUsers } from '@/app/backendAPI';
|
||||||
|
|
||||||
interface IUsersContext {
|
interface IUsersContext {
|
||||||
users: IUserInfo[];
|
users: IUserInfo[];
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { CstType, IConstituenta, type IRSForm } from '@/models/rsform';
|
||||||
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
import { getDefinitionPrefix } from '@/models/rsformAPI';
|
||||||
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
|
import { IArgumentInfo, IExpressionParse } from '@/models/rslang';
|
||||||
import { RSErrorType } from '@/models/rslang';
|
import { RSErrorType } from '@/models/rslang';
|
||||||
import { DataCallback, postCheckExpression } from '@/utils/backendAPI';
|
import { DataCallback, postCheckExpression } from '@/app/backendAPI';
|
||||||
import { PARAMETER } from '@/utils/constants';
|
import { PARAMETER } from '@/utils/constants';
|
||||||
|
|
||||||
function useCheckExpression({ schema }: { schema?: IRSForm }) {
|
function useCheckExpression({ schema }: { schema?: IRSForm }) {
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useCallback, useState } from 'react';
|
||||||
|
|
||||||
import { ErrorData } from '@/components/info/InfoError';
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
import { ILexemeData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
|
import { ILexemeData, ITextRequest, ITextResult, IWordFormPlain } from '@/models/language';
|
||||||
import { DataCallback, postGenerateLexeme, postInflectText, postParseText } from '@/utils/backendAPI';
|
import { DataCallback, postGenerateLexeme, postInflectText, postParseText } from '@/app/backendAPI';
|
||||||
|
|
||||||
function useConceptText() {
|
function useConceptText() {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useCallback, useEffect, useState } from 'react';
|
||||||
import { type ErrorData } from '@/components/info/InfoError';
|
import { type ErrorData } from '@/components/info/InfoError';
|
||||||
import { IRSForm, IRSFormData } from '@/models/rsform';
|
import { IRSForm, IRSFormData } from '@/models/rsform';
|
||||||
import { RSFormLoader } from '@/models/RSFormLoader';
|
import { RSFormLoader } from '@/models/RSFormLoader';
|
||||||
import { getRSFormDetails } from '@/utils/backendAPI';
|
import { getRSFormDetails } from '@/app/backendAPI';
|
||||||
|
|
||||||
function useRSFormDetails({ target, version }: { target?: string; version?: string }) {
|
function useRSFormDetails({ target, version }: { target?: string; version?: string }) {
|
||||||
const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined);
|
const [schema, setInnerSchema] = useState<IRSForm | undefined>(undefined);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { useCallback, useState } from 'react';
|
||||||
import { ErrorData } from '@/components/info/InfoError';
|
import { ErrorData } from '@/components/info/InfoError';
|
||||||
import { IResolutionData } from '@/models/language';
|
import { IResolutionData } from '@/models/language';
|
||||||
import { IRSForm } from '@/models/rsform';
|
import { IRSForm } from '@/models/rsform';
|
||||||
import { DataCallback, postResolveText } from '@/utils/backendAPI';
|
import { DataCallback, postResolveText } from '@/app/backendAPI';
|
||||||
|
|
||||||
function useResolveText({ schema }: { schema?: IRSForm }) {
|
function useResolveText({ schema }: { schema?: IRSForm }) {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
|
@ -83,6 +83,7 @@ interface IRSEditContext {
|
||||||
download: () => void;
|
download: () => void;
|
||||||
|
|
||||||
reindex: () => void;
|
reindex: () => void;
|
||||||
|
reorder: () => void;
|
||||||
produceStructure: () => void;
|
produceStructure: () => void;
|
||||||
inlineSynthesis: () => void;
|
inlineSynthesis: () => void;
|
||||||
substitute: () => void;
|
substitute: () => void;
|
||||||
|
@ -392,6 +393,7 @@ export const RSEditState = ({
|
||||||
}, [isModified, activeCst]);
|
}, [isModified, activeCst]);
|
||||||
|
|
||||||
const reindex = useCallback(() => model.resetAliases(() => toast.success('Имена конституент обновлены')), [model]);
|
const reindex = useCallback(() => model.resetAliases(() => toast.success('Имена конституент обновлены')), [model]);
|
||||||
|
const reorder = useCallback(() => model.restoreOrder(() => toast.success('Конституенты упорядочены')), [model]);
|
||||||
|
|
||||||
const canProduceStructure = useMemo(() => {
|
const canProduceStructure = useMemo(() => {
|
||||||
return (
|
return (
|
||||||
|
@ -510,6 +512,7 @@ export const RSEditState = ({
|
||||||
toggleSubscribe,
|
toggleSubscribe,
|
||||||
|
|
||||||
reindex,
|
reindex,
|
||||||
|
reorder,
|
||||||
inlineSynthesis: () => setShowInlineSynthesis(true),
|
inlineSynthesis: () => setShowInlineSynthesis(true),
|
||||||
produceStructure,
|
produceStructure,
|
||||||
substitute
|
substitute
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
IconReader,
|
IconReader,
|
||||||
IconReplace,
|
IconReplace,
|
||||||
IconShare,
|
IconShare,
|
||||||
|
IconSortText,
|
||||||
IconUpload
|
IconUpload
|
||||||
} from '@/components/Icons';
|
} from '@/components/Icons';
|
||||||
import Button from '@/components/ui/Button';
|
import Button from '@/components/ui/Button';
|
||||||
|
@ -82,6 +83,11 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
|
||||||
controller.reindex();
|
controller.reindex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleRestoreOrder() {
|
||||||
|
editMenu.hide();
|
||||||
|
controller.reorder();
|
||||||
|
}
|
||||||
|
|
||||||
function handleSubstituteCst() {
|
function handleSubstituteCst() {
|
||||||
editMenu.hide();
|
editMenu.hide();
|
||||||
controller.substitute();
|
controller.substitute();
|
||||||
|
@ -218,6 +224,13 @@ function RSTabsMenu({ onDestroy }: RSTabsMenuProps) {
|
||||||
/>
|
/>
|
||||||
<DropdownButton
|
<DropdownButton
|
||||||
className='border-t-2'
|
className='border-t-2'
|
||||||
|
text='Упорядочить список'
|
||||||
|
title='Упорядочить список конституент исходя из логики типов и связей конституент'
|
||||||
|
icon={<IconSortText size='1rem' className='icon-primary' />}
|
||||||
|
disabled={!controller.isContentEditable || controller.isProcessing}
|
||||||
|
onClick={handleRestoreOrder}
|
||||||
|
/>
|
||||||
|
<DropdownButton
|
||||||
text='Порядковые имена'
|
text='Порядковые имена'
|
||||||
title='Присвоить порядковые имена и обновить выражения'
|
title='Присвоить порядковые имена и обновить выражения'
|
||||||
icon={<LuWand2 size='1rem' className='icon-primary' />}
|
icon={<LuWand2 size='1rem' className='icon-primary' />}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user