mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-06-26 04:50:36 +03:00
Implement RSForm clone
This commit is contained in:
parent
e83ccd63fc
commit
ff75bef064
|
@ -38,7 +38,7 @@ function Modal({ title, show, hideWindow, onSubmit, onCancel, canSubmit, childre
|
|||
<>
|
||||
<div className='fixed top-0 left-0 z-50 w-full h-full opacity-50 clr-modal'>
|
||||
</div>
|
||||
<div ref={ref} className='fixed bottom-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 px-6 py-4 flex flex-col w-fit z-[60] clr-card border shadow-md'>
|
||||
<div ref={ref} className='fixed bottom-1/2 left-1/2 translate-y-1/2 -translate-x-1/2 px-6 py-4 flex flex-col w-fit h-fit z-[60] clr-card border shadow-md mb-[5rem]'>
|
||||
{ title && <h1 className='mb-4 text-xl font-bold text-center'>{title}</h1> }
|
||||
<div className='py-2'>
|
||||
{children}
|
||||
|
@ -46,7 +46,7 @@ function Modal({ title, show, hideWindow, onSubmit, onCancel, canSubmit, childre
|
|||
<div className='flex justify-between w-full pt-4 mt-2 border-t-4'>
|
||||
<Button
|
||||
text={submitText}
|
||||
widthClass='min-w-[6rem] w-fit h-fit'
|
||||
widthClass='min-w-[6rem] min-h-[2.6rem] w-fit h-fit'
|
||||
colorClass='clr-btn-primary'
|
||||
disabled={!canSubmit}
|
||||
onClick={handleSubmit}
|
||||
|
@ -54,6 +54,7 @@ function Modal({ title, show, hideWindow, onSubmit, onCancel, canSubmit, childre
|
|||
/>
|
||||
<Button
|
||||
text='Отмена'
|
||||
widthClass='min-w-[6rem] min-h-[2.6rem] w-fit h-fit'
|
||||
onClick={handleCancel}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -7,10 +7,10 @@ import {
|
|||
type DataCallback, deleteRSForm, getTRSFile,
|
||||
patchConstituenta, patchDeleteConstituenta, patchMoveConstituenta, patchResetAliases,
|
||||
patchRSForm,
|
||||
patchUploadTRS, postClaimRSForm, postNewConstituenta} from '../utils/backendAPI'
|
||||
patchUploadTRS, postClaimRSForm, postCloneRSForm,postNewConstituenta} from '../utils/backendAPI'
|
||||
import {
|
||||
IConstituenta, IConstituentaList, IConstituentaMeta, ICstCreateData,
|
||||
ICstMovetoData, ICstUpdateData, IRSForm, IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
|
||||
ICstMovetoData, ICstUpdateData, IRSForm, IRSFormCreateData, IRSFormData, IRSFormMeta, IRSFormUpdateData, IRSFormUploadData
|
||||
} from '../utils/models'
|
||||
import { useAuth } from './AuthContext'
|
||||
|
||||
|
@ -40,6 +40,7 @@ interface IRSFormContext {
|
|||
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
|
||||
|
@ -165,6 +166,21 @@ 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: callback
|
||||
});
|
||||
}, [schemaID, setError, schema, user])
|
||||
|
||||
const resetAliases = useCallback(
|
||||
(callback?: () => void) => {
|
||||
if (!schema || !user) {
|
||||
|
@ -262,7 +278,7 @@ export const RSFormState = ({ schemaID, children }: RSFormStateProps) => {
|
|||
toggleForceAdmin: () => { setIsForceAdmin(prev => !prev) },
|
||||
toggleReadonly: () => { setIsReadonly(prev => !prev) },
|
||||
toggleTracking,
|
||||
update, download, upload, destroy, claim, resetAliases,
|
||||
update, download, upload, destroy, claim, resetAliases, clone,
|
||||
cstUpdate, cstCreate, cstDelete, cstMoveTo
|
||||
}}>
|
||||
{ children }
|
||||
|
|
82
rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx
Normal file
82
rsconcept/frontend/src/pages/RSFormPage/DlgCloneRSForm.tsx
Normal file
|
@ -0,0 +1,82 @@
|
|||
import { useEffect, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
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 { useRSForm } from '../../context/RSFormContext';
|
||||
import { IRSFormCreateData } from '../../utils/models';
|
||||
import { getCloneTitle } from '../../utils/staticUI';
|
||||
|
||||
interface DlgCloneRSFormProps {
|
||||
show: boolean
|
||||
hideWindow: () => void
|
||||
}
|
||||
|
||||
function DlgCloneRSForm({ show, hideWindow }: DlgCloneRSFormProps) {
|
||||
const navigate = useNavigate();
|
||||
const [title, setTitle] = useState('');
|
||||
const [alias, setAlias] = useState('');
|
||||
const [comment, setComment] = useState('');
|
||||
const [common, setCommon] = useState(false);
|
||||
|
||||
const { schema, clone } = useRSForm();
|
||||
|
||||
useEffect(() => {
|
||||
if (schema) {
|
||||
setTitle(getCloneTitle(schema))
|
||||
setAlias(schema.alias)
|
||||
setComment(schema.comment)
|
||||
setCommon(schema.is_common)
|
||||
}
|
||||
}, [schema, schema?.title, schema?.alias, schema?.comment, schema?.is_common]);
|
||||
|
||||
const handleSubmit = () => {
|
||||
hideWindow();
|
||||
const data: IRSFormCreateData = {
|
||||
title: title,
|
||||
alias: alias,
|
||||
comment: comment,
|
||||
is_common: common
|
||||
};
|
||||
clone(data, newSchema => {
|
||||
toast.success(`Схема создана: ${newSchema.alias}`);
|
||||
navigate(`/rsforms/${newSchema.id}`);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title='Создание копии концептуальной схемы'
|
||||
show={show}
|
||||
hideWindow={hideWindow}
|
||||
canSubmit={true}
|
||||
submitText='Создать'
|
||||
onSubmit={handleSubmit}
|
||||
>
|
||||
<TextInput id='title' label='Полное название' type='text'
|
||||
required
|
||||
value={title}
|
||||
onChange={event => { setTitle(event.target.value); }}
|
||||
/>
|
||||
<TextInput id='alias' label='Сокращение' type='text'
|
||||
required
|
||||
value={alias}
|
||||
widthClass='max-w-sm'
|
||||
onChange={event => { setAlias(event.target.value); }}
|
||||
/>
|
||||
<TextArea id='comment' label='Комментарий'
|
||||
value={comment}
|
||||
onChange={event => { setComment(event.target.value); }}
|
||||
/>
|
||||
<Checkbox id='common' label='Общедоступная схема'
|
||||
value={common}
|
||||
onChange={event => { setCommon(event.target.checked); }}
|
||||
/>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default DlgCloneRSForm;
|
|
@ -25,7 +25,6 @@ function RSTabs() {
|
|||
const [init, setInit] = useState(false);
|
||||
|
||||
const onEditCst = (cst: IConstituenta) => {
|
||||
console.log(`Set active cst: ${cst.alias}`);
|
||||
setActiveID(cst.id);
|
||||
setTabIndex(RSTabsList.CST_EDIT)
|
||||
};
|
||||
|
@ -38,11 +37,17 @@ function RSTabs() {
|
|||
if (schema) {
|
||||
const url = new URL(window.location.href);
|
||||
const activeQuery = url.searchParams.get('active');
|
||||
const activeCst = schema?.items?.find((cst) => cst.id === Number(activeQuery));
|
||||
const activeCst = schema.items.find((cst) => cst.id === Number(activeQuery));
|
||||
setActiveID(activeCst?.id);
|
||||
setInit(true);
|
||||
|
||||
const oldTitle = document.title
|
||||
document.title = schema.title
|
||||
return () => {
|
||||
document.title = oldTitle
|
||||
}
|
||||
}
|
||||
}, [setActiveID, schema, setInit]);
|
||||
}, [setActiveID, schema, schema?.title, setInit]);
|
||||
|
||||
useEffect(() => {
|
||||
const url = new URL(window.location.href);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { useCallback, useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import Button from '../../components/Common/Button';
|
||||
import Checkbox from '../../components/Common/Checkbox';
|
||||
|
@ -11,6 +10,7 @@ import { useAuth } from '../../context/AuthContext';
|
|||
import { useRSForm } from '../../context/RSFormContext';
|
||||
import useDropdown from '../../hooks/useDropdown';
|
||||
import { claimOwnershipProc, deleteRSFormProc, downloadRSFormProc, shareCurrentURLProc } from '../../utils/procedures';
|
||||
import DlgCloneRSForm from './DlgCloneRSForm';
|
||||
import DlgUploadRSForm from './DlgUploadRSForm';
|
||||
|
||||
function RSTabsMenu() {
|
||||
|
@ -24,7 +24,8 @@ function RSTabsMenu() {
|
|||
} = useRSForm();
|
||||
const schemaMenu = useDropdown();
|
||||
const editMenu = useDropdown();
|
||||
const [showUploadModal, setShowUploadModal] = useState(false);
|
||||
const [showUploadDialog, setShowUploadDialog] = useState(false);
|
||||
const [showCloneDialog, setShowCloneDialogl] = useState(false);
|
||||
|
||||
const handleClaimOwner = useCallback(() => {
|
||||
editMenu.hide();
|
||||
|
@ -44,13 +45,12 @@ function RSTabsMenu() {
|
|||
|
||||
const handleUpload = useCallback(() => {
|
||||
schemaMenu.hide();
|
||||
setShowUploadModal(true);
|
||||
setShowUploadDialog(true);
|
||||
}, [schemaMenu]);
|
||||
|
||||
const handleClone = useCallback(() => {
|
||||
// TODO: implement
|
||||
schemaMenu.hide();
|
||||
toast.info('Клонирование РС-формы');
|
||||
setShowCloneDialogl(true);
|
||||
}, [schemaMenu]);
|
||||
|
||||
const handleShare = useCallback(() => {
|
||||
|
@ -61,8 +61,12 @@ function RSTabsMenu() {
|
|||
return (
|
||||
<>
|
||||
<DlgUploadRSForm
|
||||
show={showUploadModal}
|
||||
hideWindow={() => { setShowUploadModal(false); }}
|
||||
show={showUploadDialog}
|
||||
hideWindow={() => { setShowUploadDialog(false); }}
|
||||
/>
|
||||
<DlgCloneRSForm
|
||||
show={showCloneDialog}
|
||||
hideWindow={() => { setShowCloneDialogl(false); }}
|
||||
/>
|
||||
<div className='flex items-center w-fit'>
|
||||
<div ref={schemaMenu.ref}>
|
||||
|
|
|
@ -120,6 +120,14 @@ export function postNewRSForm(request: FrontExchange<IRSFormCreateData, IRSFormM
|
|||
});
|
||||
}
|
||||
|
||||
export function postCloneRSForm(schema: string, request: FrontExchange<IRSFormCreateData, IRSFormData>) {
|
||||
AxiosPost({
|
||||
title: 'clone RSForm',
|
||||
endpoint: `${config.url.BASE}rsforms/${schema}/clone/`,
|
||||
request: request
|
||||
});
|
||||
}
|
||||
|
||||
export function getRSFormDetails(target: string, request: FrontPull<IRSFormData>) {
|
||||
AxiosGet({
|
||||
title: `RSForm details for id=${target}`,
|
||||
|
|
|
@ -314,3 +314,11 @@ export function getMockConstituenta(id: number, alias: string, type: CstType, co
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getCloneTitle(schema: IRSForm): string {
|
||||
if (!schema.title.includes('[клон]')) {
|
||||
return schema.title + ' [клон]';
|
||||
} else {
|
||||
return (schema.title + '+');
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user