diff --git a/rsconcept/frontend/src/context/RSFormContext.tsx b/rsconcept/frontend/src/context/RSFormContext.tsx
index 109fb8d8..2cbcf24c 100644
--- a/rsconcept/frontend/src/context/RSFormContext.tsx
+++ b/rsconcept/frontend/src/context/RSFormContext.tsx
@@ -5,13 +5,14 @@ import { type ErrorInfo } from '../components/BackendError'
import { useRSFormDetails } from '../hooks/useRSFormDetails'
import {
type DataCallback, getTRSFile,
- patchConstituenta, patchDeleteConstituenta,
- patchMoveConstituenta, patchResetAliases, patchRSForm,
+ patchConstituenta, patchDeleteConstituenta,
+ patchMoveConstituenta, patchRenameConstituenta,
+ patchResetAliases, patchRSForm,
patchUploadTRS, postClaimRSForm, postNewConstituenta
} from '../utils/backendAPI'
import {
IConstituentaList, IConstituentaMeta, ICstCreateData,
- ICstMovetoData, ICstUpdateData, IRSForm,
+ ICstMovetoData, ICstRenameData, ICstUpdateData, IRSForm,
IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
} from '../utils/models'
import { useAuth } from './AuthContext'
@@ -42,6 +43,7 @@ interface IRSFormContext {
resetAliases: (callback: () => void) => void
cstCreate: (data: ICstCreateData, callback?: DataCallback
) => void
+ cstRename: (data: ICstRenameData, callback?: DataCallback) => void
cstUpdate: (data: ICstUpdateData, callback?: DataCallback) => void
cstDelete: (data: IConstituentaList, callback?: () => void) => void
cstMoveTo: (data: ICstMovetoData, callback?: () => void) => void
@@ -153,7 +155,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
patchResetAliases(schemaID, {
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: newData => {
setSchema(Object.assign(schema, newData));
if (callback) callback();
@@ -167,7 +169,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
getTRSFile(schemaID, {
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: callback
});
}, [schemaID, setError]);
@@ -179,7 +181,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
data: data,
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: newData => {
setSchema(newData.schema);
if (callback) callback(newData.new_cst);
@@ -194,7 +196,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
data: data,
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: newData => {
setSchema(newData);
if (callback) callback();
@@ -209,13 +211,27 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
data: data,
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: newData => {
- reload(setProcessing, () => { if (callback != null) callback(newData); })
+ reload(setProcessing, () => { if (callback) callback(newData); })
}
});
}, [setError, reload]);
+ const cstRename = useCallback(
+ (data: ICstRenameData, callback?: DataCallback) => {
+ setError(undefined)
+ patchRenameConstituenta(schemaID, {
+ data: data,
+ showError: true,
+ setLoading: setProcessing,
+ onError: error => setError(error),
+ onSuccess: newData => {
+ reload(setProcessing, () => { if (callback) callback(newData); })
+ }
+ });
+ }, [setError, reload, schemaID]);
+
const cstMoveTo = useCallback(
(data: ICstMovetoData, callback?: () => void) => {
setError(undefined)
@@ -223,7 +239,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
data: data,
showError: true,
setLoading: setProcessing,
- onError: error => { setError(error) },
+ onError: error => setError(error),
onSuccess: newData => {
setSchema(newData);
if (callback) callback();
@@ -237,11 +253,11 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
error, loading, processing,
isForceAdmin, isReadonly, isOwned, isEditable,
isClaimable, isTracking,
- toggleForceAdmin: () => { setIsForceAdmin(prev => !prev) },
- toggleReadonly: () => { setIsReadonly(prev => !prev) },
+ toggleForceAdmin: () => setIsForceAdmin(prev => !prev),
+ toggleReadonly: () => setIsReadonly(prev => !prev),
toggleTracking,
update, download, upload, claim, resetAliases,
- cstUpdate, cstCreate, cstDelete, cstMoveTo
+ cstUpdate, cstCreate, cstRename, cstDelete, cstMoveTo
}}>
{ children }
diff --git a/rsconcept/frontend/src/pages/RSFormPage/DlgRenameCst.tsx b/rsconcept/frontend/src/pages/RSFormPage/DlgRenameCst.tsx
index b3289086..78949e53 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/DlgRenameCst.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/DlgRenameCst.tsx
@@ -1,18 +1,20 @@
-import { useEffect, useState } from 'react';
+import { useLayoutEffect, useState } from 'react';
import ConceptSelect from '../../components/Common/ConceptSelect';
import Modal from '../../components/Common/Modal';
import TextInput from '../../components/Common/TextInput';
+import { useRSForm } from '../../context/RSFormContext';
import { CstType, ICstRenameData } from '../../utils/models';
-import { CstTypeSelector, getCstTypeLabel } from '../../utils/staticUI';
+import { createAliasFor, CstTypeSelector, getCstTypeLabel, getCstTypePrefix } from '../../utils/staticUI';
interface DlgRenameCstProps {
hideWindow: () => void
- initial: ICstRenameData
+ initial?: ICstRenameData
onRename: (data: ICstRenameData) => void
}
function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
+ const { schema } = useRSForm();
const [validated, setValidated] = useState(false);
const [cstType, setCstType] = useState(CstType.BASE);
const [cstID, setCstID] = useState(0)
@@ -26,11 +28,17 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
}
}
- const handleSubmit = () => {
- onRename(getData());
- };
+ const handleSubmit = () => onRename(getData());
- useEffect(() => {
+ useLayoutEffect(
+ () => {
+ if (schema && initial && cstType !== initial.cst_type) {
+ setAlias(createAliasFor(cstType, schema));
+ }
+ }, [initial, cstType, schema]);
+
+ useLayoutEffect(
+ () => {
if (initial) {
setCstType(initial.cst_type);
setAlias(initial.alias);
@@ -38,34 +46,42 @@ function DlgRenameCst({ hideWindow, initial, onRename }: DlgRenameCstProps) {
}
}, [initial]);
- useEffect(() => {
- // setValidated(selectedType !== undefined);
- setValidated(true)
- }, [cstType, alias]
- );
+ useLayoutEffect(
+ () => {
+ if (!initial || !schema) {
+ setValidated(false);
+ } else if(alias === initial.alias || alias.length < 2 || alias[0] !== getCstTypePrefix(cstType)) {
+ setValidated(false);
+ } else {
+ setValidated(!schema.items.find(cst => cst.alias === alias))
+ }
+ }, [cstType, alias, initial, schema]);
return (
-
-
- { setCstType(data.length > 0 ? data[0].value : CstType.BASE); }}
- />
-
-
setAlias(event.target.value)}
- />
+
+
{ setCstType(data.length > 0 ? data[0].value : CstType.BASE); }}
+ />
+
+ setAlias(event.target.value)}
+ />
+
);
diff --git a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
index 477dd901..75b6e3e1 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/EditorConstituenta.tsx
@@ -9,7 +9,7 @@ import TextArea from '../../components/Common/TextArea';
import CstStatusInfo from '../../components/Help/InfoCstStatus';
import { DumpBinIcon, HelpIcon, PenIcon, SaveIcon, SmallPlusIcon } from '../../components/Icons';
import { useRSForm } from '../../context/RSFormContext';
-import { CstType, EditMode, ICstCreateData, ICstUpdateData, SyntaxTree } from '../../utils/models';
+import { CstType, EditMode, ICstCreateData, ICstRenameData, ICstUpdateData, SyntaxTree } from '../../utils/models';
import { getCstTypificationLabel } from '../../utils/staticUI';
import EditorRSExpression from './EditorRSExpression';
import ViewSideConstituents from './elements/ViewSideConstituents';
@@ -22,10 +22,11 @@ interface EditorConstituentaProps {
onOpenEdit: (cstID: number) => void
onShowAST: (expression: string, ast: SyntaxTree) => void
onCreateCst: (initial: ICstCreateData, skipDialog?: boolean) => void
+ onRenameCst: (initial: ICstRenameData) => void
onDeleteCst: (selected: number[], callback?: (items: number[]) => void) => void
}
-function EditorConstituenta({ activeID, onShowAST, onCreateCst, onOpenEdit, onDeleteCst }: EditorConstituentaProps) {
+function EditorConstituenta({ activeID, onShowAST, onCreateCst, onRenameCst, onOpenEdit, onDeleteCst }: EditorConstituentaProps) {
const { schema, processing, isEditable, cstUpdate } = useRSForm();
const activeCst = useMemo(
() => {
@@ -112,7 +113,15 @@ function EditorConstituenta({ activeID, onShowAST, onCreateCst, onOpenEdit, onDe
}
function handleRename() {
- toast.info('Переименование в разработке');
+ if (!activeID || !activeCst) {
+ return;
+ }
+ const data: ICstRenameData = {
+ id: activeID,
+ alias: activeCst?.alias,
+ cst_type: activeCst.cstType
+ };
+ onRenameCst(data);
}
return (
diff --git a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
index 8dbe0057..420cdc7b 100644
--- a/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
+++ b/rsconcept/frontend/src/pages/RSFormPage/RSTabs.tsx
@@ -9,11 +9,12 @@ 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 { ICstCreateData, SyntaxTree } from '../../utils/models';
+import { ICstCreateData, ICstRenameData, SyntaxTree } from '../../utils/models';
import { createAliasFor } from '../../utils/staticUI';
import DlgCloneRSForm from './DlgCloneRSForm';
import DlgCreateCst from './DlgCreateCst';
import DlgDeleteCst from './DlgDeleteCst';
+import DlgRenameCst from './DlgRenameCst';
import DlgShowAST from './DlgShowAST';
import DlgUploadRSForm from './DlgUploadRSForm';
import EditorConstituenta from './EditorConstituenta';
@@ -35,7 +36,7 @@ function RSTabs() {
const search = useLocation().search;
const {
error, schema, loading,
- cstCreate, cstDelete
+ cstCreate, cstDelete, cstRename
} = useRSForm();
const { destroySchema } = useLibrary();
@@ -55,6 +56,9 @@ function RSTabs() {
const [createInitialData, setCreateInitialData] = useState();
const [showCreateCst, setShowCreateCst] = useState(false);
+
+ const [renameInitialData, setRenameInitialData] = useState();
+ const [showRenameCst, setShowRenameCst] = useState(false);
useLayoutEffect(() => {
if (schema) {
@@ -122,6 +126,17 @@ function RSTabs() {
}
}, [handleCreateCst]);
+ const handleRenameCst = useCallback(
+ (data: ICstRenameData) => {
+ cstRename(data, () => toast.success(`Конституента переименована: ${renameInitialData!.alias} -> ${data.alias}`));
+ }, [cstRename, renameInitialData]);
+
+ const promptRenameCst = useCallback(
+ (initialData: ICstRenameData) => {
+ setRenameInitialData(initialData);
+ setShowRenameCst(true);
+ }, []);
+
const handleDeleteCst = useCallback(
(deleted: number[]) => {
if (!schema) {
@@ -205,6 +220,12 @@ function RSTabs() {
onCreate={handleCreateCst}
initial={createInitialData}
/>}
+ {showRenameCst &&
+ setShowRenameCst(false)}
+ onRename={handleRenameCst}
+ initial={renameInitialData}
+ />}
{showDeleteCst &&
setShowDeleteCst(false)}
@@ -254,6 +275,7 @@ function RSTabs() {
onShowAST={onShowAST}
onCreateCst={promptCreateCst}
onDeleteCst={promptDeleteCst}
+ onRenameCst={promptRenameCst}
/>
diff --git a/rsconcept/frontend/src/utils/backendAPI.ts b/rsconcept/frontend/src/utils/backendAPI.ts
index c74807b1..14f391cf 100644
--- a/rsconcept/frontend/src/utils/backendAPI.ts
+++ b/rsconcept/frontend/src/utils/backendAPI.ts
@@ -5,7 +5,7 @@ import { type ErrorInfo } from '../components/BackendError'
import { config } from './constants'
import {
IConstituentaList, IConstituentaMeta,
- ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstUpdateData,
+ ICstCreateData, ICstCreatedResponse, ICstMovetoData, ICstRenameData, ICstUpdateData,
ICurrentUser, IExpressionParse, IRSExpression,
IRSFormCreateData, IRSFormData,
IRSFormMeta, IRSFormUpdateData, IRSFormUploadData, IUserInfo,
@@ -210,6 +210,14 @@ export function patchConstituenta(target: string, request: FrontExchange) {
+ AxiosPatch({
+ title: `Renaming constituenta id=${request.data.id} for schema id=${schema}`,
+ endpoint: `/api/rsforms/${schema}/cst-rename/`,
+ request: request
+ });
+}
+
export function patchMoveConstituenta(schema: string, request: FrontExchange) {
AxiosPatch({
title: `Moving Constituents for RSForm id=${schema}: ${JSON.stringify(request.data.items)} to ${request.data.move_to}`,