From 56556e9660ffb7a0df3fa0fea75cc6be83040576 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Wed, 4 Aug 2021 22:41:52 -0600 Subject: [PATCH] ui(admin): implement new mount page --- .../admin/mounts/MountEditContainer.tsx | 210 +++--------------- .../components/admin/mounts/MountForm.tsx | 170 ++++++++++++++ .../admin/mounts/MountsContainer.tsx | 8 +- .../admin/mounts/NewMountContainer.tsx | 47 ++++ resources/scripts/routers/AdminRouter.tsx | 2 + 5 files changed, 258 insertions(+), 179 deletions(-) create mode 100644 resources/scripts/components/admin/mounts/MountForm.tsx create mode 100644 resources/scripts/components/admin/mounts/NewMountContainer.tsx diff --git a/resources/scripts/components/admin/mounts/MountEditContainer.tsx b/resources/scripts/components/admin/mounts/MountEditContainer.tsx index 9c3a04800..174720fa0 100644 --- a/resources/scripts/components/admin/mounts/MountEditContainer.tsx +++ b/resources/scripts/components/admin/mounts/MountEditContainer.tsx @@ -1,23 +1,18 @@ +import { action, Action, Actions, createContextStore, useStoreActions } from 'easy-peasy'; import React, { useEffect, useState } from 'react'; import { useHistory } from 'react-router'; -import tw from 'twin.macro'; import { useRouteMatch } from 'react-router-dom'; -import { action, Action, Actions, createContextStore, useStoreActions } from 'easy-peasy'; +import tw from 'twin.macro'; import { Mount } from '@/api/admin/mounts/getMounts'; import getMount from '@/api/admin/mounts/getMount'; import AdminContentBlock from '@/components/admin/AdminContentBlock'; import Spinner from '@/components/elements/Spinner'; import FlashMessageRender from '@/components/FlashMessageRender'; -import { ApplicationStore } from '@/state'; -import { boolean, object, string } from 'yup'; -import updateMount from '@/api/admin/mounts/updateMount'; -import AdminBox from '@/components/admin/AdminBox'; -import Button from '@/components/elements/Button'; -import Field from '@/components/elements/Field'; -import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; -import { Field as FormikField, Form, Formik, FormikHelpers } from 'formik'; -import Label from '@/components/elements/Label'; import MountDeleteButton from '@/components/admin/mounts/MountDeleteButton'; +import MountForm from '@/components/admin/mounts/MountForm'; +import { ApplicationStore } from '@/state'; +import { FormikHelpers } from 'formik'; +import updateMount from '@/api/admin/mounts/updateMount'; interface ctx { mount: Mount | undefined; @@ -32,30 +27,22 @@ export const Context = createContextStore({ }), }); -interface Values { - name: string; - description: string; - source: string; - target: string; - readOnly: string; - userMountable: string; -} - -const EditInformationContainer = () => { +const MountEditContainer = () => { const history = useHistory(); + const match = useRouteMatch<{ id?: string }>(); + const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); + const [ loading, setLoading ] = useState(true); const mount = Context.useStoreState(state => state.mount); const setMount = Context.useStoreActions(actions => actions.setMount); - if (mount === undefined) { - return ( - <> - ); - } + const submit = ({ name, description, source, target, readOnly, userMountable }: any, { setSubmitting }: FormikHelpers) => { + if (mount === undefined) { + return; + } - const submit = ({ name, description, source, target, readOnly, userMountable }: Values, { setSubmitting }: FormikHelpers) => { clearFlashes('mount'); updateMount(mount.id, name, description, source, target, readOnly === '1', userMountable === '1') @@ -67,154 +54,6 @@ const EditInformationContainer = () => { .then(() => setSubmitting(false)); }; - return ( - - { - ({ isSubmitting, isValid }) => ( - - - - -
-
- -
- -
- -
- -
-
- -
- -
- -
-
- -
-
- - -
- - - -
-
- -
- - -
- - - -
-
-
- -
-
- history.push('/admin/mounts')} - /> -
- -
- -
-
-
-
-
- ) - } -
- ); -}; - -const MountEditContainer = () => { - const match = useRouteMatch<{ id?: string }>(); - - const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); - const [ loading, setLoading ] = useState(true); - - const mount = Context.useStoreState(state => state.mount); - const setMount = Context.useStoreActions(actions => actions.setMount); - useEffect(() => { clearFlashes('mount'); @@ -257,7 +96,26 @@ const MountEditContainer = () => { - + +
+ history.push('/admin/mounts')} + /> +
+
); }; diff --git a/resources/scripts/components/admin/mounts/MountForm.tsx b/resources/scripts/components/admin/mounts/MountForm.tsx new file mode 100644 index 000000000..ba1c44694 --- /dev/null +++ b/resources/scripts/components/admin/mounts/MountForm.tsx @@ -0,0 +1,170 @@ +import { boolean, object, string } from 'yup'; +import { Field as FormikField, Form, Formik, FormikHelpers } from 'formik'; +import React from 'react'; +import AdminBox from '@/components/admin/AdminBox'; +import tw from 'twin.macro'; +import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; +import Field from '@/components/elements/Field'; +import Label from '@/components/elements/Label'; +import Button from '@/components/elements/Button'; + +interface Values { + name: string; + description: string; + source: string; + target: string; + readOnly: string; + userMountable: string; +} + +interface Props { + action: string; + title: string, + initialValues?: Values; + + onSubmit: (values: Values, helpers: FormikHelpers) => void; + + children?: React.ReactNode +} + +function MountForm ({ action, title, initialValues, children, onSubmit }: Props) { + const submit = (values: Values, helpers: FormikHelpers) => { + onSubmit(values, helpers); + }; + + if (!initialValues) { + initialValues = { + name: '', + description: '', + source: '', + target: '', + readOnly: '0', + userMountable: '0', + }; + } + + return ( + + { + ({ isSubmitting, isValid }) => ( + + + +
+
+ +
+ +
+ +
+ +
+
+ +
+ +
+ +
+
+ +
+
+ + +
+ + + +
+
+ +
+ + +
+ + + +
+
+
+ +
+ {children} + +
+ +
+
+
+
+ ) + } +
+ ); +} + +export default MountForm; diff --git a/resources/scripts/components/admin/mounts/MountsContainer.tsx b/resources/scripts/components/admin/mounts/MountsContainer.tsx index e627a3a85..d20171e28 100644 --- a/resources/scripts/components/admin/mounts/MountsContainer.tsx +++ b/resources/scripts/components/admin/mounts/MountsContainer.tsx @@ -80,9 +80,11 @@ const MountsContainer = () => {
- + + +
diff --git a/resources/scripts/components/admin/mounts/NewMountContainer.tsx b/resources/scripts/components/admin/mounts/NewMountContainer.tsx new file mode 100644 index 000000000..83f0c03db --- /dev/null +++ b/resources/scripts/components/admin/mounts/NewMountContainer.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import tw from 'twin.macro'; +import AdminContentBlock from '@/components/admin/AdminContentBlock'; +import FlashMessageRender from '@/components/FlashMessageRender'; +import MountForm from '@/components/admin/mounts/MountForm'; +import { FormikHelpers } from 'formik'; +import { useHistory } from 'react-router-dom'; +import { Actions, useStoreActions } from 'easy-peasy'; +import { ApplicationStore } from '@/state'; +import createMount from '@/api/admin/mounts/createMount'; + +export default () => { + const history = useHistory(); + + const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes); + + const submit = ({ name, description, source, target, readOnly, userMountable }: any, { setSubmitting }: FormikHelpers) => { + clearFlashes('mount:create'); + + createMount(name, description, source, target, readOnly === '1', userMountable === '1') + .then(mount => history.push(`/admin/mounts/${mount.id}`)) + .catch(error => { + console.error(error); + clearAndAddHttpError({ key: 'mount:create', error }); + }) + .then(() => setSubmitting(false)); + }; + + return ( + +
+
+

Create Mount

+

Add a new mount to the panel.

+
+
+ + + + +
+ ); +}; diff --git a/resources/scripts/routers/AdminRouter.tsx b/resources/scripts/routers/AdminRouter.tsx index 7f34bde32..02800c7f4 100644 --- a/resources/scripts/routers/AdminRouter.tsx +++ b/resources/scripts/routers/AdminRouter.tsx @@ -30,6 +30,7 @@ import EggRouter from '@/components/admin/nests/eggs/EggRouter'; import ServerRouter from '@/components/admin/servers/ServerRouter'; import { NotFound } from '@/components/elements/ScreenBlock'; import { usePersistedState } from '@/plugins/usePersistedState'; +import NewMountContainer from '@/components/admin/mounts/NewMountContainer'; const Sidebar = styled.div<{ collapsed?: boolean }>` ${tw`fixed h-screen hidden md:flex flex-col items-center flex-shrink-0 bg-neutral-900 overflow-x-hidden transition-all duration-250 ease-linear`}; @@ -255,6 +256,7 @@ const AdminRouter = ({ location, match }: RouteComponentProps) => { /> +