2023-07-15 17:46:19 +03:00
|
|
|
|
import { useIntl } from 'react-intl';
|
|
|
|
|
import Checkbox from '../../components/Common/Checkbox';
|
|
|
|
|
import SubmitButton from '../../components/Common/SubmitButton';
|
|
|
|
|
import TextArea from '../../components/Common/TextArea';
|
|
|
|
|
import TextInput from '../../components/Common/TextInput';
|
|
|
|
|
import { useRSForm } from '../../context/RSFormContext';
|
2023-07-16 22:25:23 +03:00
|
|
|
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
import Button from '../../components/Common/Button';
|
2023-07-16 22:53:22 +03:00
|
|
|
|
import { CrownIcon, DownloadIcon, DumpBinIcon, ShareIcon } from '../../components/Icons';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
import { useUsers } from '../../context/UsersContext';
|
|
|
|
|
import { useNavigate } from 'react-router-dom';
|
2023-07-15 17:57:25 +03:00
|
|
|
|
import { toast } from 'react-toastify';
|
2023-07-16 22:25:23 +03:00
|
|
|
|
import { AxiosResponse } from 'axios';
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
|
|
function RSFormCard() {
|
|
|
|
|
const navigate = useNavigate();
|
|
|
|
|
const intl = useIntl();
|
|
|
|
|
const { getUserLabel } = useUsers();
|
2023-07-16 22:25:23 +03:00
|
|
|
|
const { schema, update, download, reload, isEditable, isClaimable, processing, destroy, claim } = useRSForm();
|
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-07-16 22:25:23 +03:00
|
|
|
|
const fileRef = useRef<HTMLAnchorElement | null>(null);
|
|
|
|
|
const [fileURL, setFileUrl] = useState<string>();
|
|
|
|
|
const [fileName, setFileName] = useState<string>();
|
|
|
|
|
|
2023-07-15 17:46:19 +03:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
setTitle(schema!.title)
|
|
|
|
|
setAlias(schema!.alias)
|
|
|
|
|
setComment(schema!.comment)
|
|
|
|
|
setCommon(schema!.is_common)
|
|
|
|
|
}, [schema]);
|
|
|
|
|
|
|
|
|
|
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
|
|
|
|
event.preventDefault();
|
2023-07-16 22:25:23 +03:00
|
|
|
|
const data = {
|
|
|
|
|
'title': title,
|
|
|
|
|
'alias': alias,
|
|
|
|
|
'comment': comment,
|
|
|
|
|
'is_common': common,
|
|
|
|
|
};
|
|
|
|
|
update(data, () => {
|
|
|
|
|
toast.success('Изменения сохранены');
|
|
|
|
|
reload();
|
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleDelete = useCallback(() => {
|
|
|
|
|
if (window.confirm('Вы уверены, что хотите удалить данную схему?')) {
|
2023-07-15 17:57:25 +03:00
|
|
|
|
destroy(() => {
|
|
|
|
|
toast.success('Схема удалена');
|
2023-07-16 20:25:55 +03:00
|
|
|
|
navigate('/rsforms?filter=personal');
|
2023-07-15 17:57:25 +03:00
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
|
}
|
|
|
|
|
}, [destroy, navigate]);
|
|
|
|
|
|
|
|
|
|
const handleClaimOwner = useCallback(() => {
|
|
|
|
|
if (window.confirm('Вы уверены, что хотите стать владельцем данной схемы?')) {
|
2023-07-15 17:57:25 +03:00
|
|
|
|
claim(() => {
|
|
|
|
|
toast.success('Вы стали владельцем схемы');
|
|
|
|
|
reload();
|
|
|
|
|
});
|
2023-07-15 17:46:19 +03:00
|
|
|
|
}
|
|
|
|
|
}, [claim, reload]);
|
|
|
|
|
|
|
|
|
|
const handleDownload = useCallback(() => {
|
2023-07-16 22:25:23 +03:00
|
|
|
|
download((response: AxiosResponse) => {
|
|
|
|
|
try {
|
|
|
|
|
setFileName((schema?.alias || 'Schema') + '.trs')
|
|
|
|
|
setFileUrl(URL.createObjectURL(new Blob([response.data])));
|
|
|
|
|
fileRef.current?.click();
|
|
|
|
|
if (fileURL) URL.revokeObjectURL(fileURL);
|
|
|
|
|
} catch (error: any) {
|
|
|
|
|
toast.error(error.message);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}, [download, schema?.alias, fileURL]);
|
2023-07-16 22:53:22 +03:00
|
|
|
|
|
|
|
|
|
const handleShare = useCallback(() => {
|
|
|
|
|
const url = window.location.href + '&share';
|
|
|
|
|
navigator.clipboard.writeText(url);
|
|
|
|
|
toast.success(`Ссылка скопирована: ${url}`);
|
|
|
|
|
}, []);
|
2023-07-15 17:46:19 +03:00
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<form onSubmit={handleSubmit} className='flex-grow max-w-xl px-4 py-2 border'>
|
|
|
|
|
<TextInput id='title' label='Полное название' type='text'
|
|
|
|
|
required
|
|
|
|
|
value={title}
|
|
|
|
|
disabled={!isEditable}
|
|
|
|
|
onChange={event => setTitle(event.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
<TextInput id='alias' label='Сокращение' type='text'
|
|
|
|
|
required
|
|
|
|
|
value={alias}
|
|
|
|
|
disabled={!isEditable}
|
|
|
|
|
widthClass='max-w-sm'
|
|
|
|
|
onChange={event => setAlias(event.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
<TextArea id='comment' label='Комментарий'
|
|
|
|
|
value={comment}
|
|
|
|
|
disabled={!isEditable}
|
|
|
|
|
onChange={event => setComment(event.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
<Checkbox id='common' label='Общедоступная схема'
|
|
|
|
|
value={common}
|
|
|
|
|
disabled={!isEditable}
|
2023-07-16 20:25:55 +03:00
|
|
|
|
onChange={event => setCommon(event.target.checked)}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<div className='flex items-center justify-between gap-1 py-2 mt-2'>
|
2023-07-16 22:25:23 +03:00
|
|
|
|
<SubmitButton text='Сохранить изменения' loading={processing} disabled={!isEditable || processing} />
|
2023-07-15 17:46:19 +03:00
|
|
|
|
<div className='flex justify-end gap-1'>
|
2023-07-16 22:53:22 +03:00
|
|
|
|
<Button
|
|
|
|
|
tooltip='Поделиться схемой'
|
|
|
|
|
icon={<ShareIcon />}
|
|
|
|
|
onClick={handleShare}
|
|
|
|
|
/>
|
2023-07-15 17:46:19 +03:00
|
|
|
|
<Button
|
2023-07-16 22:25:23 +03:00
|
|
|
|
disabled={processing}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
tooltip='Скачать TRS файл'
|
|
|
|
|
icon={<DownloadIcon />}
|
|
|
|
|
loading={processing}
|
|
|
|
|
onClick={handleDownload}
|
|
|
|
|
/>
|
2023-07-16 22:25:23 +03:00
|
|
|
|
<a href={fileURL} download={fileName} className='hidden' ref={fileRef}>
|
|
|
|
|
<i aria-hidden="true"/>
|
|
|
|
|
</a>
|
2023-07-15 17:46:19 +03:00
|
|
|
|
<Button
|
|
|
|
|
tooltip={isClaimable ? 'Стать владельцем' : 'Вы уже являетесь владельцем' }
|
2023-07-16 22:25:23 +03:00
|
|
|
|
disabled={!isClaimable || processing}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
icon={<CrownIcon />}
|
|
|
|
|
colorClass='text-green-400 dark:text-green-500'
|
|
|
|
|
onClick={handleClaimOwner}
|
|
|
|
|
/>
|
|
|
|
|
<Button
|
|
|
|
|
tooltip={ isEditable ? 'Удалить схему' : 'Вы не можете редактировать данную схему'}
|
2023-07-16 22:25:23 +03:00
|
|
|
|
disabled={!isEditable || processing}
|
2023-07-15 17:46:19 +03:00
|
|
|
|
icon={<DumpBinIcon />}
|
|
|
|
|
colorClass='text-red-400 dark:text-red-600'
|
|
|
|
|
loading={processing}
|
|
|
|
|
onClick={handleDelete}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className='flex justify-start mt-2'>
|
|
|
|
|
<label className='font-semibold'>Владелец:</label>
|
|
|
|
|
<span className='min-w-[200px] ml-2 overflow-ellipsis overflow-hidden whitespace-nowrap'>
|
|
|
|
|
{getUserLabel(schema?.owner)}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='flex justify-start mt-2'>
|
|
|
|
|
<label className='font-semibold'>Дата обновления:</label>
|
|
|
|
|
<span className='ml-2'>{new Date(schema!.time_update).toLocaleString(intl.locale)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div className='flex justify-start mt-2'>
|
|
|
|
|
<label className='font-semibold'>Дата создания:</label>
|
|
|
|
|
<span className='ml-8'>{new Date(schema!.time_create).toLocaleString(intl.locale)}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</form>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default RSFormCard;
|