import React, { 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);