mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
#34 made error handling and resetting
This commit is contained in:
parent
dad416e6e2
commit
29e5aef01b
6 changed files with 136 additions and 43 deletions
|
@ -1,9 +1,10 @@
|
|||
@import "~/styles/variables.scss";
|
||||
@import '~/styles/variables.scss';
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
height: 32px;
|
||||
flex: 1;
|
||||
|
||||
@media(max-width: 480px) {
|
||||
display: none;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { FC, useState } from 'react';
|
||||
import React, { FC, useCallback, useState } from 'react';
|
||||
import { useCommentFormFormik } from '~/utils/hooks/useCommentFormFormik';
|
||||
import { FormikProvider } from 'formik';
|
||||
import { LocalCommentFormTextarea } from '~/components/comment/LocalCommentFormTextarea';
|
||||
|
@ -11,6 +11,10 @@ import { LocalCommentFormAttaches } from '~/components/comment/LocalCommentFormA
|
|||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
import { IComment, INode } from '~/redux/types';
|
||||
import { EMPTY_COMMENT } from '~/redux/node/constants';
|
||||
import { CommentFormDropzone } from '~/components/comment/CommentFormDropzone';
|
||||
import styles from './styles.module.scss';
|
||||
import { ERROR_LITERAL } from '~/constants/errors';
|
||||
import { Group } from '~/components/containers/Group';
|
||||
|
||||
interface IProps {
|
||||
comment?: IComment;
|
||||
|
@ -20,41 +24,73 @@ interface IProps {
|
|||
|
||||
const LocalCommentForm: FC<IProps> = ({ comment, nodeId, onCancelEdit }) => {
|
||||
const [textarea, setTextarea] = useState<HTMLTextAreaElement>();
|
||||
const uploader = useFileUploader(UPLOAD_SUBJECTS.COMMENT, UPLOAD_TARGETS.COMMENTS);
|
||||
const uploader = useFileUploader(
|
||||
UPLOAD_SUBJECTS.COMMENT,
|
||||
UPLOAD_TARGETS.COMMENTS,
|
||||
comment?.files
|
||||
);
|
||||
const formik = useCommentFormFormik(comment || EMPTY_COMMENT, nodeId, uploader, onCancelEdit);
|
||||
const isLoading = formik.isSubmitting || uploader.isUploading;
|
||||
const isEditing = !!comment?.id;
|
||||
|
||||
const clearError = useCallback(() => {
|
||||
if (formik.status) {
|
||||
formik.setStatus('');
|
||||
}
|
||||
|
||||
if (formik.errors.text) {
|
||||
formik.setErrors({
|
||||
...formik.errors,
|
||||
text: '',
|
||||
});
|
||||
}
|
||||
}, [formik]);
|
||||
|
||||
const error = formik.status || formik.errors.text;
|
||||
|
||||
return (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<FormikProvider value={formik}>
|
||||
<FileUploaderProvider value={uploader}>
|
||||
<LocalCommentFormTextarea setRef={setTextarea} />
|
||||
<CommentFormDropzone onUpload={uploader.uploadFiles}>
|
||||
<form onSubmit={formik.handleSubmit} className={styles.wrap}>
|
||||
<FormikProvider value={formik}>
|
||||
<FileUploaderProvider value={uploader}>
|
||||
<div className={styles.input}>
|
||||
<LocalCommentFormTextarea setRef={setTextarea} />
|
||||
|
||||
<CommentFormAttachButtons onUpload={uploader.uploadFiles} />
|
||||
<CommentFormFormatButtons element={textarea} handler={formik.handleChange('text')} />
|
||||
<LocalCommentFormAttaches />
|
||||
{!!error && (
|
||||
<div className={styles.error} onClick={clearError}>
|
||||
{ERROR_LITERAL[error] || error}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{isLoading && <LoaderCircle size={20} />}
|
||||
<LocalCommentFormAttaches />
|
||||
|
||||
{isEditing && (
|
||||
<Button size="small" color="link" type="button" onClick={onCancelEdit}>
|
||||
Отмена
|
||||
</Button>
|
||||
)}
|
||||
<Group horizontal className={styles.buttons}>
|
||||
<CommentFormAttachButtons onUpload={uploader.uploadFiles} />
|
||||
<CommentFormFormatButtons element={textarea} handler={formik.handleChange('text')} />
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
size="small"
|
||||
color="gray"
|
||||
iconRight={!isEditing ? 'enter' : 'check'}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{!isEditing ? 'Сказать' : 'Сохранить'}
|
||||
</Button>
|
||||
</FileUploaderProvider>
|
||||
</FormikProvider>
|
||||
</form>
|
||||
{isLoading && <LoaderCircle size={20} />}
|
||||
|
||||
{isEditing && (
|
||||
<Button size="small" color="link" type="button" onClick={onCancelEdit}>
|
||||
Отмена
|
||||
</Button>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
size="small"
|
||||
color="gray"
|
||||
iconRight={!isEditing ? 'enter' : 'check'}
|
||||
disabled={isLoading}
|
||||
>
|
||||
{!isEditing ? 'Сказать' : 'Сохранить'}
|
||||
</Button>
|
||||
</Group>
|
||||
</FileUploaderProvider>
|
||||
</FormikProvider>
|
||||
</form>
|
||||
</CommentFormDropzone>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
57
src/components/comment/LocalCommentForm/styles.module.scss
Normal file
57
src/components/comment/LocalCommentForm/styles.module.scss
Normal file
|
@ -0,0 +1,57 @@
|
|||
@import "src/styles/variables";
|
||||
|
||||
.wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
textarea {
|
||||
min-height: 62px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.input {
|
||||
@include outer_shadow();
|
||||
position: relative;
|
||||
flex: 1;
|
||||
padding: ($gap / 2) ($gap / 2 + 1px);
|
||||
}
|
||||
|
||||
.buttons {
|
||||
@include outer_shadow();
|
||||
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: transparentize(black, 0.8);
|
||||
padding: $gap / 2;
|
||||
border-radius: 0 0 $radius $radius;
|
||||
flex-wrap: wrap;
|
||||
|
||||
}
|
||||
|
||||
.uploads {
|
||||
padding: ($gap / 2);
|
||||
display: grid;
|
||||
grid-column-gap: $gap / 2;
|
||||
grid-row-gap: $gap / 2;
|
||||
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
|
||||
}
|
||||
|
||||
.attaches {
|
||||
@include outer_shadow();
|
||||
}
|
||||
|
||||
.error {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
background: $red;
|
||||
z-index: 10;
|
||||
font: $font_12_regular;
|
||||
box-sizing: border-box;
|
||||
padding: 0 $gap;
|
||||
border-radius: 4px 4px 0 0;
|
||||
transform: translate(-50%, 0);
|
||||
cursor: pointer;
|
||||
}
|
|
@ -178,17 +178,6 @@
|
|||
fill: white;
|
||||
}
|
||||
}
|
||||
|
||||
> * {
|
||||
margin: 0 5px;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.micro {
|
||||
|
|
|
@ -10,12 +10,13 @@ import { selectUploads } from '~/redux/uploads/selectors';
|
|||
|
||||
export const useFileUploader = (
|
||||
subject: typeof UPLOAD_SUBJECTS[keyof typeof UPLOAD_SUBJECTS],
|
||||
target: typeof UPLOAD_TARGETS[keyof typeof UPLOAD_TARGETS]
|
||||
target: typeof UPLOAD_TARGETS[keyof typeof UPLOAD_TARGETS],
|
||||
initialFiles?: IFile[]
|
||||
) => {
|
||||
const dispatch = useDispatch();
|
||||
const { files: uploadedFiles, statuses } = useShallowSelect(selectUploads);
|
||||
|
||||
const [files, setFiles] = useState<IFile[]>([]);
|
||||
const [files, setFiles] = useState<IFile[]>(initialFiles || []);
|
||||
const [pendingIDs, setPendingIDs] = useState<string[]>([]);
|
||||
|
||||
const uploadFiles = useCallback(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { IComment, INode } from '~/redux/types';
|
||||
import { useCallback, useRef } from 'react';
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { FormikHelpers, useFormik, useFormikContext } from 'formik';
|
||||
import { array, object, string } from 'yup';
|
||||
import { FileUploader } from '~/utils/hooks/fileUploader';
|
||||
|
@ -58,13 +58,22 @@ export const useCommentFormFormik = (
|
|||
if (stopEditing) stopEditing();
|
||||
}, [uploader, stopEditing]);
|
||||
|
||||
return useFormik({
|
||||
const formik = useFormik({
|
||||
initialValues,
|
||||
validationSchema,
|
||||
onSubmit,
|
||||
initialStatus: '',
|
||||
onReset,
|
||||
validateOnChange: true,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (formik.status) {
|
||||
formik.setStatus('');
|
||||
}
|
||||
}, [formik.values.text]);
|
||||
|
||||
return formik;
|
||||
};
|
||||
|
||||
export const useCommentFormContext = () => useFormikContext<IComment>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue