2023-12-13 14:32:57 +03:00
|
|
|
|
'use client';
|
|
|
|
|
|
2023-12-15 17:34:50 +03:00
|
|
|
|
import clsx from 'clsx';
|
2023-09-08 13:46:45 +03:00
|
|
|
|
import { useEffect, useRef, useState } from 'react';
|
2023-12-16 19:20:26 +03:00
|
|
|
|
import { BiDownload } from 'react-icons/bi';
|
2023-07-25 20:27:29 +03:00
|
|
|
|
import { toast } from 'react-toastify';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
2024-04-01 21:45:10 +03:00
|
|
|
|
import { urls } from '@/app/urls';
|
2024-03-20 15:27:32 +03:00
|
|
|
|
import InfoError from '@/components/info/InfoError';
|
2024-01-04 19:38:12 +03:00
|
|
|
|
import Button from '@/components/ui/Button';
|
|
|
|
|
import Checkbox from '@/components/ui/Checkbox';
|
|
|
|
|
import Label from '@/components/ui/Label';
|
|
|
|
|
import MiniButton from '@/components/ui/MiniButton';
|
|
|
|
|
import Overlay from '@/components/ui/Overlay';
|
|
|
|
|
import SubmitButton from '@/components/ui/SubmitButton';
|
|
|
|
|
import TextArea from '@/components/ui/TextArea';
|
|
|
|
|
import TextInput from '@/components/ui/TextInput';
|
2024-03-20 15:27:32 +03:00
|
|
|
|
import AnimateFade from '@/components/wrap/AnimateFade';
|
|
|
|
|
import RequireAuth from '@/components/wrap/RequireAuth';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
import { useLibrary } from '@/context/LibraryContext';
|
2023-12-26 14:23:51 +03:00
|
|
|
|
import { useConceptNavigation } from '@/context/NavigationContext';
|
2023-12-13 14:32:57 +03:00
|
|
|
|
import { LibraryItemType } from '@/models/library';
|
|
|
|
|
import { IRSFormCreateData } from '@/models/rsform';
|
2024-03-19 19:19:08 +03:00
|
|
|
|
import { EXTEOR_TRS_FILE, limits, patterns } from '@/utils/constants';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
2023-07-28 00:03:37 +03:00
|
|
|
|
function CreateRSFormPage() {
|
2023-12-13 14:32:57 +03:00
|
|
|
|
const router = useConceptNavigation();
|
2023-11-01 13:41:32 +03:00
|
|
|
|
const { createItem, error, setError, processing } = useLibrary();
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
|
|
const [title, setTitle] = useState('');
|
|
|
|
|
const [alias, setAlias] = useState('');
|
|
|
|
|
const [comment, setComment] = useState('');
|
|
|
|
|
const [common, setCommon] = useState(false);
|
2023-09-08 13:46:45 +03:00
|
|
|
|
|
|
|
|
|
const [fileName, setFileName] = useState('');
|
|
|
|
|
const [file, setFile] = useState<File | undefined>();
|
|
|
|
|
const inputRef = useRef<HTMLInputElement | null>(null);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
2023-07-31 23:47:18 +03:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
setError(undefined);
|
|
|
|
|
}, [title, alias, setError]);
|
|
|
|
|
|
2023-09-02 01:11:27 +03:00
|
|
|
|
function handleCancel() {
|
2023-12-13 14:32:57 +03:00
|
|
|
|
if (router.canBack()) {
|
|
|
|
|
router.back();
|
2023-09-02 01:11:27 +03:00
|
|
|
|
} else {
|
2024-04-01 21:45:10 +03:00
|
|
|
|
router.push(urls.library);
|
2023-09-02 01:11:27 +03:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-28 14:04:44 +03:00
|
|
|
|
|
2023-07-31 23:47:18 +03:00
|
|
|
|
function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
|
2023-07-15 17:46:19 +03:00
|
|
|
|
event.preventDefault();
|
2023-08-09 17:19:12 +03:00
|
|
|
|
if (processing) {
|
2023-07-25 20:27:29 +03:00
|
|
|
|
return;
|
2023-07-15 17:46:19 +03:00
|
|
|
|
}
|
2023-07-25 20:27:29 +03:00
|
|
|
|
const data: IRSFormCreateData = {
|
2023-08-25 22:51:20 +03:00
|
|
|
|
item_type: LibraryItemType.RSFORM,
|
2023-07-26 23:11:00 +03:00
|
|
|
|
title: title,
|
|
|
|
|
alias: alias,
|
|
|
|
|
comment: comment,
|
|
|
|
|
is_common: common,
|
2023-08-25 22:51:20 +03:00
|
|
|
|
is_canonical: false,
|
2023-07-26 23:11:00 +03:00
|
|
|
|
file: file,
|
|
|
|
|
fileName: file?.name
|
2023-07-25 20:27:29 +03:00
|
|
|
|
};
|
2023-12-28 14:04:44 +03:00
|
|
|
|
createItem(data, newSchema => {
|
2023-08-09 17:19:12 +03:00
|
|
|
|
toast.success('Схема успешно создана');
|
2024-04-01 21:45:10 +03:00
|
|
|
|
router.push(urls.schema(newSchema.id));
|
2023-08-09 17:19:12 +03:00
|
|
|
|
});
|
2023-07-31 23:47:18 +03:00
|
|
|
|
}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
2023-09-08 13:46:45 +03:00
|
|
|
|
function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
|
|
|
if (event.target.files && event.target.files.length > 0) {
|
|
|
|
|
setFileName(event.target.files[0].name);
|
|
|
|
|
setFile(event.target.files[0]);
|
|
|
|
|
} else {
|
|
|
|
|
setFileName('');
|
|
|
|
|
setFile(undefined);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
|
return (
|
2024-01-07 03:29:16 +03:00
|
|
|
|
<AnimateFade>
|
2024-01-06 03:15:02 +03:00
|
|
|
|
<RequireAuth>
|
2024-03-19 19:19:08 +03:00
|
|
|
|
<form className={clsx('cc-column', 'px-6 py-3')} onSubmit={handleSubmit}>
|
2024-01-06 03:15:02 +03:00
|
|
|
|
<h1>Создание концептуальной схемы</h1>
|
|
|
|
|
<Overlay position='top-[-2.4rem] right-[-1rem]'>
|
|
|
|
|
<input
|
2024-03-18 16:21:39 +03:00
|
|
|
|
id='schema_file'
|
2024-01-06 03:15:02 +03:00
|
|
|
|
ref={inputRef}
|
|
|
|
|
type='file'
|
|
|
|
|
style={{ display: 'none' }}
|
|
|
|
|
accept={EXTEOR_TRS_FILE}
|
|
|
|
|
onChange={handleFileChange}
|
|
|
|
|
/>
|
|
|
|
|
<MiniButton
|
|
|
|
|
title='Загрузить из Экстеор'
|
2024-03-08 19:37:36 +03:00
|
|
|
|
icon={<BiDownload size='1.25rem' className='icon-primary' />}
|
2024-01-06 03:15:02 +03:00
|
|
|
|
onClick={() => inputRef.current?.click()}
|
|
|
|
|
/>
|
|
|
|
|
</Overlay>
|
|
|
|
|
{fileName ? <Label text={`Загружен файл: ${fileName}`} /> : null}
|
|
|
|
|
|
|
|
|
|
<TextInput
|
2024-03-18 16:21:39 +03:00
|
|
|
|
id='schema_title'
|
2024-01-06 03:15:02 +03:00
|
|
|
|
required={!file}
|
|
|
|
|
label='Полное название'
|
|
|
|
|
placeholder={file && 'Загрузить из файла'}
|
|
|
|
|
value={title}
|
|
|
|
|
onChange={event => setTitle(event.target.value)}
|
2023-12-28 14:04:44 +03:00
|
|
|
|
/>
|
2024-01-06 03:15:02 +03:00
|
|
|
|
<TextInput
|
2024-03-18 16:21:39 +03:00
|
|
|
|
id='schema_alias'
|
2024-01-06 03:15:02 +03:00
|
|
|
|
required={!file}
|
|
|
|
|
label='Сокращение'
|
|
|
|
|
placeholder={file && 'Загрузить из файла'}
|
|
|
|
|
className='w-[14rem]'
|
|
|
|
|
pattern={patterns.library_alias}
|
|
|
|
|
title={`не более ${limits.library_alias_len} символов`}
|
|
|
|
|
value={alias}
|
|
|
|
|
onChange={event => setAlias(event.target.value)}
|
2023-12-28 14:04:44 +03:00
|
|
|
|
/>
|
2024-01-06 03:15:02 +03:00
|
|
|
|
<TextArea
|
2024-03-18 16:21:39 +03:00
|
|
|
|
id='schema_comment'
|
2024-04-01 15:11:17 +03:00
|
|
|
|
label='Описание'
|
2024-01-06 03:15:02 +03:00
|
|
|
|
placeholder={file && 'Загрузить из файла'}
|
|
|
|
|
value={comment}
|
|
|
|
|
onChange={event => setComment(event.target.value)}
|
|
|
|
|
/>
|
2024-03-18 16:21:39 +03:00
|
|
|
|
<Checkbox
|
|
|
|
|
id='schema_common'
|
|
|
|
|
label='Общедоступная схема'
|
|
|
|
|
value={common}
|
|
|
|
|
setValue={value => setCommon(value ?? false)}
|
|
|
|
|
/>
|
2024-01-06 03:15:02 +03:00
|
|
|
|
<div className='flex justify-around gap-6 py-3'>
|
|
|
|
|
<SubmitButton text='Создать схему' loading={processing} className='min-w-[10rem]' />
|
|
|
|
|
<Button text='Отмена' className='min-w-[10rem]' onClick={() => handleCancel()} />
|
|
|
|
|
</div>
|
|
|
|
|
{error ? <InfoError error={error} /> : null}
|
|
|
|
|
</form>
|
|
|
|
|
</RequireAuth>
|
2024-01-07 03:29:16 +03:00
|
|
|
|
</AnimateFade>
|
2023-12-28 14:04:44 +03:00
|
|
|
|
);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
}
|
|
|
|
|
|
2023-12-28 14:04:44 +03:00
|
|
|
|
export default CreateRSFormPage;
|