import { useContext, useEffect, useRef } from 'react'; import { Subuser } from '@/state/server/subusers'; import { Form, Formik } from 'formik'; import { array, object, string } from 'yup'; import Field from '@/components/elements/Field'; import { Actions, useStoreActions, useStoreState } from 'easy-peasy'; import { ApplicationStore } from '@/state'; import createOrUpdateSubuser from '@/api/server/users/createOrUpdateSubuser'; import { ServerContext } from '@/state/server'; import FlashMessageRender from '@/components/FlashMessageRender'; import Can from '@/components/elements/Can'; import { usePermissions } from '@/plugins/usePermissions'; import { useDeepCompareMemo } from '@/plugins/useDeepCompareMemo'; import tw from 'twin.macro'; import Button from '@/components/elements/Button'; import PermissionTitleBox from '@/components/server/users/PermissionTitleBox'; import asModal from '@/hoc/asModal'; import PermissionRow from '@/components/server/users/PermissionRow'; import ModalContext from '@/context/ModalContext'; type Props = { subuser?: Subuser; }; interface Values { email: string; permissions: string[]; } const EditSubuserModal = ({ subuser }: Props) => { const ref = useRef(null); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const appendSubuser = ServerContext.useStoreActions(actions => actions.subusers.appendSubuser); const { clearFlashes, clearAndAddHttpError } = useStoreActions( (actions: Actions) => actions.flashes, ); const { dismiss, setPropOverrides } = useContext(ModalContext); const isRootAdmin = useStoreState(state => state.user.data!.rootAdmin); const permissions = useStoreState(state => state.permissions.data); // The currently logged in user's permissions. We're going to filter out any permissions // that they should not need. const loggedInPermissions = ServerContext.useStoreState(state => state.server.permissions); const [canEditUser] = usePermissions(subuser ? ['user.update'] : ['user.create']); // The permissions that can be modified by this user. const editablePermissions = useDeepCompareMemo(() => { const cleaned = Object.keys(permissions).map(key => Object.keys(permissions[key]?.keys ?? {}).map(pkey => `${key}.${pkey}`), ); const list: string[] = ([] as string[]).concat.apply([], Object.values(cleaned)); if (isRootAdmin || (loggedInPermissions.length === 1 && loggedInPermissions[0] === '*')) { return list; } return list.filter(key => loggedInPermissions.indexOf(key) >= 0); }, [isRootAdmin, permissions, loggedInPermissions]); const submit = (values: Values) => { setPropOverrides({ showSpinnerOverlay: true }); clearFlashes('user:edit'); createOrUpdateSubuser(uuid, values, subuser) .then(subuser => { appendSubuser(subuser); dismiss(); }) .catch(error => { console.error(error); setPropOverrides(null); clearAndAddHttpError({ key: 'user:edit', error }); if (ref.current) { ref.current.scrollIntoView(); } }); }; useEffect( () => () => { clearFlashes('user:edit'); }, [], ); return (

{subuser ? `${canEditUser ? 'Modify' : 'View'} permissions for ${subuser.email}` : 'Create new subuser'}

{!isRootAdmin && loggedInPermissions[0] !== '*' && (

Only permissions which your account is currently assigned may be selected when creating or modifying other users.

)} {!subuser && (
)}
{Object.keys(permissions) .filter(key => key !== 'websocket') .map((key, index) => ( `${key}.${pkey}`)} css={index > 0 ? tw`mt-4` : undefined} >

{permissions[key]?.description}

{Object.keys(permissions[key]?.keys ?? {}).map(pkey => ( ))}
))}
); }; export default asModal({ top: false, })(EditSubuserModal);