ui(server/files): add validation for duplicate directory names
This commit is contained in:
parent
be011906e6
commit
26438fa034
3 changed files with 17 additions and 10 deletions
|
@ -18,6 +18,7 @@ import useFlash from '@/plugins/useFlash';
|
||||||
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
import ConfirmationModal from '@/components/elements/ConfirmationModal';
|
||||||
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper';
|
||||||
import { Textarea } from '@/components/elements/Input';
|
import { Textarea } from '@/components/elements/Input';
|
||||||
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
interface Values {
|
interface Values {
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -145,6 +146,10 @@ export default () => {
|
||||||
<FontAwesomeIcon icon={faKey} css={tw`text-neutral-300`}/>
|
<FontAwesomeIcon icon={faKey} css={tw`text-neutral-300`}/>
|
||||||
<div css={tw`ml-4 flex-1 overflow-hidden`}>
|
<div css={tw`ml-4 flex-1 overflow-hidden`}>
|
||||||
<p css={tw`text-sm break-words`}>{key.name}</p>
|
<p css={tw`text-sm break-words`}>{key.name}</p>
|
||||||
|
<p css={tw`text-2xs text-neutral-300 uppercase`}>
|
||||||
|
Added at:
|
||||||
|
{key.createdAt ? format(key.createdAt, 'MMM do, yyyy HH:mm') : 'Never'}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button css={tw`ml-4 p-2 text-sm`} onClick={() => setDeleteId(key.id)}>
|
<button css={tw`ml-4 p-2 text-sm`} onClick={() => setDeleteId(key.id)}>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
|
|
|
@ -58,11 +58,9 @@ const inputStyle = css<Props>`
|
||||||
${tw`opacity-75`};
|
${tw`opacity-75`};
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.ignoreReadOnly):read-only {
|
${props => props.isLight ? light : css`&:not(.ignoreReadOnly):read-only {
|
||||||
${tw`border-neutral-800 bg-neutral-900`};
|
${tw`border-neutral-800 bg-neutral-900`};
|
||||||
}
|
}`};
|
||||||
|
|
||||||
${props => props.isLight && light};
|
|
||||||
${props => props.hasError && tw`text-red-100 border-red-400 hover:border-red-300`};
|
${props => props.hasError && tw`text-red-100 border-red-400 hover:border-red-300`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,6 @@ interface Values {
|
||||||
directoryName: string;
|
directoryName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const schema = object().shape({
|
|
||||||
directoryName: string().required('A valid directory name must be provided.'),
|
|
||||||
});
|
|
||||||
|
|
||||||
const generateDirectoryData = (name: string): FileObject => ({
|
const generateDirectoryData = (name: string): FileObject => ({
|
||||||
key: `dir_${name.split('/', 1)[0] ?? name}`,
|
key: `dir_${name.split('/', 1)[0] ?? name}`,
|
||||||
name: name.replace(/^(\/*)/, '').split('/', 1)[0] ?? name,
|
name: name.replace(/^(\/*)/, '').split('/', 1)[0] ?? name,
|
||||||
|
@ -42,7 +38,7 @@ export default ({ className }: WithClassname) => {
|
||||||
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
const { clearFlashes, clearAndAddHttpError } = useFlash();
|
||||||
const [ visible, setVisible ] = useState(false);
|
const [ visible, setVisible ] = useState(false);
|
||||||
|
|
||||||
const { mutate } = useFileManagerSwr();
|
const { data, mutate } = useFileManagerSwr();
|
||||||
const directory = ServerContext.useStoreState(state => state.files.directory);
|
const directory = ServerContext.useStoreState(state => state.files.directory);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -68,8 +64,16 @@ export default ({ className }: WithClassname) => {
|
||||||
<>
|
<>
|
||||||
<Formik
|
<Formik
|
||||||
onSubmit={submit}
|
onSubmit={submit}
|
||||||
validationSchema={schema}
|
|
||||||
initialValues={{ directoryName: '' }}
|
initialValues={{ directoryName: '' }}
|
||||||
|
validationSchema={object().shape({
|
||||||
|
directoryName: string()
|
||||||
|
.required('A valid directory name must be provided.')
|
||||||
|
.test('unique', 'Directory with that name already exists.', v => {
|
||||||
|
return v !== undefined &&
|
||||||
|
data !== undefined &&
|
||||||
|
data.filter(f => f.name.toLowerCase() === v.toLowerCase()).length < 1;
|
||||||
|
}),
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
{({ resetForm, isSubmitting, values }) => (
|
{({ resetForm, isSubmitting, values }) => (
|
||||||
<Modal
|
<Modal
|
||||||
|
|
Loading…
Reference in a new issue