import React, { forwardRef, useRef } from 'react'; import { Subuser } from '@/state/server/subusers'; import { Form, Formik, FormikHelpers, useFormikContext } from 'formik'; import { array, object, string } from 'yup'; import Modal, { RequiredModalProps } from '@/components/elements/Modal'; import Field from '@/components/elements/Field'; import { Actions, useStoreActions, useStoreState } from 'easy-peasy'; import { ApplicationStore } from '@/state'; import TitledGreyBox from '@/components/elements/TitledGreyBox'; import Checkbox from '@/components/elements/Checkbox'; import styled from 'styled-components'; import classNames from 'classnames'; import createOrUpdateSubuser from '@/api/server/users/createOrUpdateSubuser'; import { ServerContext } from '@/state/server'; import { httpErrorToHuman } from '@/api/http'; import FlashMessageRender from '@/components/FlashMessageRender'; import Can from '@/components/elements/Can'; import { usePermissions } from '@/plugins/usePermissions'; type Props = { subuser?: Subuser; } & RequiredModalProps; interface Values { email: string; permissions: string[]; } const PermissionLabel = styled.label` ${tw`flex items-center border border-transparent rounded p-2`}; text-transform: none; &:not(.disabled) { ${tw`cursor-pointer`}; &:hover { ${tw`border-neutral-500 bg-neutral-800`}; } } `; const EditSubuserModal = forwardRef(({ subuser, ...props }, ref) => { const { values, isSubmitting, setFieldValue } = useFormikContext(); const [ canEditUser ] = usePermissions([ 'user.update' ]); const permissions = useStoreState((state: ApplicationStore) => state.permissions.data); return (

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

{!subuser &&
}
{Object.keys(permissions).filter(key => key !== 'websocket').map((key, index) => (

{key}

{canEditUser && { if (e.currentTarget.checked) { setFieldValue('permissions', [ ...values.permissions, ...Object.keys(permissions[key].keys) .map(pkey => `${key}.${pkey}`) .filter(permission => values.permissions.indexOf(permission) === -1), ]); } else { setFieldValue('permissions', [ ...values.permissions.filter( permission => Object.keys(permissions[key].keys) .map(pkey => `${key}.${pkey}`) .indexOf(permission) < 0, ), ]); } }} /> }
} className={index !== 0 ? 'mt-4' : undefined} >

{permissions[key].description}

{Object.keys(permissions[key].keys).map((pkey, index) => (
{pkey} {permissions[key].keys[pkey].length > 0 &&

{permissions[key].keys[pkey]}

}
))} ))}
); }); export default ({ subuser, ...props }: Props) => { const ref = useRef(null); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const appendSubuser = ServerContext.useStoreActions(actions => actions.subusers.appendSubuser); const { addError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); const submit = (values: Values, { setSubmitting }: FormikHelpers) => { clearFlashes('user:edit'); createOrUpdateSubuser(uuid, values, subuser) .then(subuser => { appendSubuser(subuser); props.onDismissed(); }) .catch(error => { console.error(error); setSubmitting(false); addError({ key: 'user:edit', message: httpErrorToHuman(error) }); if (ref.current) { ref.current.scrollIntoView(); } }); }; return (
); };