diff --git a/resources/scripts/components/admin/AdminBox.tsx b/resources/scripts/components/admin/AdminBox.tsx
new file mode 100644
index 000000000..9519dbdc0
--- /dev/null
+++ b/resources/scripts/components/admin/AdminBox.tsx
@@ -0,0 +1,31 @@
+import React, { memo } from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { IconProp } from '@fortawesome/fontawesome-svg-core';
+import tw from 'twin.macro';
+import isEqual from 'react-fast-compare';
+
+interface Props {
+ icon?: IconProp;
+ title: string | React.ReactNode;
+ className?: string;
+ children: React.ReactNode;
+}
+
+const AdminBox = ({ icon, title, children, className }: Props) => (
+
+
+ {typeof title === 'string' ?
+
+ {icon && }{title}
+
+ :
+ title
+ }
+
+
+ {children}
+
+
+);
+
+export default memo(AdminBox, isEqual);
diff --git a/resources/scripts/components/admin/databases/DatabasesContainer.tsx b/resources/scripts/components/admin/databases/DatabasesContainer.tsx
index 0410da1e0..acf34297e 100644
--- a/resources/scripts/components/admin/databases/DatabasesContainer.tsx
+++ b/resources/scripts/components/admin/databases/DatabasesContainer.tsx
@@ -44,7 +44,7 @@ const DatabasesContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'databases' });
+ clearAndAddHttpError({ key: 'databases', error });
}, [ error ]);
const length = databases?.items?.length || 0;
diff --git a/resources/scripts/components/admin/locations/LocationsContainer.tsx b/resources/scripts/components/admin/locations/LocationsContainer.tsx
index dcd3ed758..af37bc326 100644
--- a/resources/scripts/components/admin/locations/LocationsContainer.tsx
+++ b/resources/scripts/components/admin/locations/LocationsContainer.tsx
@@ -44,7 +44,7 @@ const LocationsContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'locations' });
+ clearAndAddHttpError({ key: 'locations', error });
}, [ error ]);
const length = locations?.items?.length || 0;
diff --git a/resources/scripts/components/admin/locations/NewLocationButton.tsx b/resources/scripts/components/admin/locations/NewLocationButton.tsx
index 915db921c..8ed4aab02 100644
--- a/resources/scripts/components/admin/locations/NewLocationButton.tsx
+++ b/resources/scripts/components/admin/locations/NewLocationButton.tsx
@@ -38,7 +38,7 @@ export default () => {
setVisible(false);
})
.catch(error => {
- clearAndAddHttpError(error);
+ clearAndAddHttpError({ key: 'location:create', error });
setSubmitting(false);
});
};
diff --git a/resources/scripts/components/admin/mounts/MountsContainer.tsx b/resources/scripts/components/admin/mounts/MountsContainer.tsx
index 7a0319a33..b78b97282 100644
--- a/resources/scripts/components/admin/mounts/MountsContainer.tsx
+++ b/resources/scripts/components/admin/mounts/MountsContainer.tsx
@@ -44,7 +44,7 @@ const MountsContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'mounts' });
+ clearAndAddHttpError({ key: 'mounts', error });
}, [ error ]);
const length = mounts?.items?.length || 0;
diff --git a/resources/scripts/components/admin/nests/NestEditContainer.tsx b/resources/scripts/components/admin/nests/NestEditContainer.tsx
index 78e034f72..803da829f 100644
--- a/resources/scripts/components/admin/nests/NestEditContainer.tsx
+++ b/resources/scripts/components/admin/nests/NestEditContainer.tsx
@@ -1,20 +1,113 @@
-import React, { useEffect, useState } from 'react';
+import React, { createContext, useContext, useEffect, useState } from 'react';
import { useRouteMatch } from 'react-router-dom';
import tw from 'twin.macro';
-import useFlash from '@/plugins/useFlash';
import AdminContentBlock from '@/components/admin/AdminContentBlock';
import Spinner from '@/components/elements/Spinner';
import FlashMessageRender from '@/components/FlashMessageRender';
import { Nest } from '@/api/admin/nests/getNests';
import getNest from '@/api/admin/nests/getNest';
+import updateNest from '@/api/admin/nests/updateNest';
+import { object, string } from 'yup';
+import Button from '@/components/elements/Button';
+import Field from '@/components/elements/Field';
+import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
+import { ApplicationStore } from '@/state';
+import { Actions, useStoreActions } from 'easy-peasy';
+import { Form, Formik, FormikHelpers } from 'formik';
+import AdminBox from '@/components/admin/AdminBox';
-export default () => {
+interface ctx {
+ nest: Nest | undefined;
+ setNest: (value: Nest | undefined) => void;
+}
+
+export const Context = createContext({ nest: undefined, setNest: () => 1 });
+
+interface Values {
+ name: string;
+ description: string | null;
+}
+
+const NestEditBox = () => {
+ const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes);
+ const { nest, setNest } = useContext(Context);
+
+ if (nest === undefined) {
+ return (
+ <>>
+ );
+ }
+
+ const submit = ({ name, description }: Values, { setSubmitting }: FormikHelpers) => {
+ clearFlashes('nest');
+
+ updateNest(nest.id, name, description || undefined)
+ .then(() => setNest({ ...nest, name, description }))
+ .catch(error => {
+ console.error(error);
+ clearAndAddHttpError({ key: 'nest', error });
+ })
+ .then(() => setSubmitting(false));
+ };
+
+ return (
+
+ {
+ ({ isSubmitting, isValid }) => (
+
+
+
+
+
+
+
+ )
+ }
+
+ );
+};
+
+const NestEditContainer = () => {
const match = useRouteMatch<{ nestId?: string }>();
- const { clearFlashes, clearAndAddHttpError } = useFlash();
+ const { clearFlashes, clearAndAddHttpError } = useStoreActions((actions: Actions) => actions.flashes);
const [ loading, setLoading ] = useState(true);
- const [ nest, setNest ] = useState(undefined);
+ const { nest, setNest } = useContext(Context);
useEffect(() => {
clearFlashes('nest');
@@ -23,7 +116,7 @@ export default () => {
.then(nest => setNest(nest))
.catch(error => {
console.error(error);
- clearAndAddHttpError(error);
+ clearAndAddHttpError({ key: 'nest', error });
})
.then(() => setLoading(false));
}, []);
@@ -31,11 +124,11 @@ export default () => {
if (loading || nest === undefined) {
return (
+
+
-
-
);
}
@@ -49,7 +142,19 @@ export default () => {
- {JSON.stringify(nest.relations.eggs)}
+
+
+
);
};
+
+export default () => {
+ const [ nest, setNest ] = useState(undefined);
+
+ return (
+
+
+
+ );
+};
diff --git a/resources/scripts/components/admin/nests/NestsContainer.tsx b/resources/scripts/components/admin/nests/NestsContainer.tsx
index 56201656a..3baa14d95 100644
--- a/resources/scripts/components/admin/nests/NestsContainer.tsx
+++ b/resources/scripts/components/admin/nests/NestsContainer.tsx
@@ -44,7 +44,7 @@ const NestsContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'nests' });
+ clearAndAddHttpError({ key: 'nests', error });
}, [ error ]);
const length = nests?.items?.length || 0;
diff --git a/resources/scripts/components/admin/nodes/NodesContainer.tsx b/resources/scripts/components/admin/nodes/NodesContainer.tsx
index baafede68..11fc70a9d 100644
--- a/resources/scripts/components/admin/nodes/NodesContainer.tsx
+++ b/resources/scripts/components/admin/nodes/NodesContainer.tsx
@@ -45,7 +45,7 @@ const NodesContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'nodes' });
+ clearAndAddHttpError({ key: 'nodes', error });
}, [ error ]);
const length = nodes?.items?.length || 0;
diff --git a/resources/scripts/components/admin/overview/OverviewContainer.tsx b/resources/scripts/components/admin/overview/OverviewContainer.tsx
index 7db8f0e9b..91141f037 100644
--- a/resources/scripts/components/admin/overview/OverviewContainer.tsx
+++ b/resources/scripts/components/admin/overview/OverviewContainer.tsx
@@ -26,7 +26,7 @@ export default () => {
.then(versionData => setVersionData(versionData))
.catch(error => {
console.error(error);
- clearAndAddHttpError(error);
+ clearAndAddHttpError({ key: 'overview', error });
})
.then(() => setLoading(false));
}, []);
diff --git a/resources/scripts/components/admin/roles/NewRoleButton.tsx b/resources/scripts/components/admin/roles/NewRoleButton.tsx
index 2e2119fa0..5259dfe0a 100644
--- a/resources/scripts/components/admin/roles/NewRoleButton.tsx
+++ b/resources/scripts/components/admin/roles/NewRoleButton.tsx
@@ -1,6 +1,5 @@
import React, { useState } from 'react';
import createRole from '@/api/admin/roles/createRole';
-import { httpErrorToHuman } from '@/api/http';
import { AdminContext } from '@/state/admin';
import Button from '@/components/elements/Button';
import Field from '@/components/elements/Field';
@@ -26,7 +25,7 @@ const schema = object().shape({
export default () => {
const [ visible, setVisible ] = useState(false);
- const { addError, clearFlashes } = useFlash();
+ const { clearFlashes, clearAndAddHttpError } = useFlash();
const appendRole = AdminContext.useStoreActions(actions => actions.roles.appendRole);
@@ -40,7 +39,7 @@ export default () => {
setVisible(false);
})
.catch(error => {
- addError({ key: 'role:create', message: httpErrorToHuman(error) });
+ clearAndAddHttpError({ key: 'role:create', error });
setSubmitting(false);
});
};
diff --git a/resources/scripts/components/admin/roles/RolesContainer.tsx b/resources/scripts/components/admin/roles/RolesContainer.tsx
index fb7cc4380..9c87a348d 100644
--- a/resources/scripts/components/admin/roles/RolesContainer.tsx
+++ b/resources/scripts/components/admin/roles/RolesContainer.tsx
@@ -52,7 +52,7 @@ export default () => {
.then(roles => setRoles(roles))
.catch(error => {
console.error(error);
- clearAndAddHttpError(error);
+ clearAndAddHttpError({ key: 'roles', error });
})
.then(() => setLoading(false));
}, []);
diff --git a/resources/scripts/components/admin/servers/ServersContainer.tsx b/resources/scripts/components/admin/servers/ServersContainer.tsx
index 3ea269374..3fbb21b76 100644
--- a/resources/scripts/components/admin/servers/ServersContainer.tsx
+++ b/resources/scripts/components/admin/servers/ServersContainer.tsx
@@ -44,7 +44,7 @@ const UsersContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'servers' });
+ clearAndAddHttpError({ key: 'servers', error });
}, [ error ]);
const length = servers?.items?.length || 0;
diff --git a/resources/scripts/components/admin/users/UsersContainer.tsx b/resources/scripts/components/admin/users/UsersContainer.tsx
index 83d5fbddb..7c83960b2 100644
--- a/resources/scripts/components/admin/users/UsersContainer.tsx
+++ b/resources/scripts/components/admin/users/UsersContainer.tsx
@@ -44,7 +44,7 @@ const UsersContainer = () => {
return;
}
- clearAndAddHttpError({ error, key: 'users' });
+ clearAndAddHttpError({ key: 'users', error });
}, [ error ]);
const length = users?.items?.length || 0;