Changeset View
Changeset View
Standalone View
Standalone View
web/modals/threads/members/change-member-role-modal.react.js
// @flow | // @flow | ||||
import invariant from 'invariant'; | import invariant from 'invariant'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { | |||||
changeThreadMemberRoles, | |||||
changeThreadMemberRolesActionTypes, | |||||
} from 'lib/actions/thread-actions.js'; | |||||
import { useModalContext } from 'lib/components/modal-provider.react.js'; | import { useModalContext } from 'lib/components/modal-provider.react.js'; | ||||
import type { RelativeMemberInfo, ThreadInfo } from 'lib/types/thread-types'; | import type { RelativeMemberInfo, ThreadInfo } from 'lib/types/thread-types'; | ||||
import { | |||||
useDispatchActionPromise, | |||||
useServerCall, | |||||
} from 'lib/utils/action-utils.js'; | |||||
import { values } from 'lib/utils/objects.js'; | import { values } from 'lib/utils/objects.js'; | ||||
import css from './change-member-role-modal.css'; | import css from './change-member-role-modal.css'; | ||||
import UserAvatar from '../../../avatars/user-avatar.react.js'; | import UserAvatar from '../../../avatars/user-avatar.react.js'; | ||||
import Button, { buttonThemes } from '../../../components/button.react.js'; | import Button, { buttonThemes } from '../../../components/button.react.js'; | ||||
import Dropdown from '../../../components/dropdown.react.js'; | import Dropdown from '../../../components/dropdown.react.js'; | ||||
import Modal from '../../modal.react.js'; | import Modal from '../../modal.react.js'; | ||||
import UnsavedChangesModal from '../../unsaved-changes-modal.react.js'; | import UnsavedChangesModal from '../../unsaved-changes-modal.react.js'; | ||||
type ChangeMemberRoleModalProps = { | type ChangeMemberRoleModalProps = { | ||||
+memberInfo: RelativeMemberInfo, | +memberInfo: RelativeMemberInfo, | ||||
+threadInfo: ThreadInfo, | +threadInfo: ThreadInfo, | ||||
}; | }; | ||||
function ChangeMemberRoleModal(props: ChangeMemberRoleModalProps): React.Node { | function ChangeMemberRoleModal(props: ChangeMemberRoleModalProps): React.Node { | ||||
const { memberInfo, threadInfo } = props; | const { memberInfo, threadInfo } = props; | ||||
const { pushModal, popModal } = useModalContext(); | const { pushModal, popModal } = useModalContext(); | ||||
const dispatchActionPromise = useDispatchActionPromise(); | |||||
const callChangeThreadMemberRoles = useServerCall(changeThreadMemberRoles); | |||||
const roleOptions = React.useMemo( | const roleOptions = React.useMemo( | ||||
() => | () => | ||||
values(threadInfo.roles).map(role => ({ | values(threadInfo.roles).map(role => ({ | ||||
id: role.id, | id: role.id, | ||||
name: role.name, | name: role.name, | ||||
})), | })), | ||||
[threadInfo.roles], | [threadInfo.roles], | ||||
); | ); | ||||
const initialSelectedRole = memberInfo.role; | const initialSelectedRole = memberInfo.role; | ||||
invariant(initialSelectedRole, "Member's role must be defined"); | invariant(initialSelectedRole, "Member's role must be defined"); | ||||
const [selectedRole, setSelectedRole] = React.useState(initialSelectedRole); | const [selectedRole, setSelectedRole] = React.useState(initialSelectedRole); | ||||
const onBackClick = React.useCallback(() => { | const onBackClick = React.useCallback(() => { | ||||
if (selectedRole === initialSelectedRole) { | if (selectedRole === initialSelectedRole) { | ||||
popModal(); | popModal(); | ||||
return; | return; | ||||
} | } | ||||
pushModal(<UnsavedChangesModal />); | pushModal(<UnsavedChangesModal />); | ||||
}, [initialSelectedRole, popModal, pushModal, selectedRole]); | }, [initialSelectedRole, popModal, pushModal, selectedRole]); | ||||
const onSave = React.useCallback(() => { | |||||
if (selectedRole === initialSelectedRole) { | |||||
popModal(); | |||||
return; | |||||
} | |||||
const createChangeThreadMemberRolesPromise = () => { | |||||
return callChangeThreadMemberRoles( | |||||
threadInfo.id, | |||||
[memberInfo.id], | |||||
selectedRole, | |||||
); | |||||
}; | |||||
ashoat: Shorthand | |||||
dispatchActionPromise( | |||||
changeThreadMemberRolesActionTypes, | |||||
createChangeThreadMemberRolesPromise(), | |||||
); | |||||
popModal(); | |||||
}, [ | |||||
callChangeThreadMemberRoles, | |||||
dispatchActionPromise, | |||||
initialSelectedRole, | |||||
memberInfo.id, | |||||
popModal, | |||||
selectedRole, | |||||
threadInfo.id, | |||||
]); | |||||
return ( | return ( | ||||
<Modal name="Change Role" onClose={popModal} size="large"> | <Modal name="Change Role" onClose={popModal} size="large"> | ||||
<div className={css.roleModalDescription}> | <div className={css.roleModalDescription}> | ||||
Members can only be assigned to one role at a time. Changing a | Members can only be assigned to one role at a time. Changing a | ||||
member’s role will replace their previously assigned role. | member’s role will replace their previously assigned role. | ||||
</div> | </div> | ||||
<div className={css.roleModalMember}> | <div className={css.roleModalMember}> | ||||
<div className={css.roleModalMemberAvatar}> | <div className={css.roleModalMemberAvatar}> | ||||
Show All 15 Lines | <Modal name="Change Role" onClose={popModal} size="large"> | ||||
onClick={onBackClick} | onClick={onBackClick} | ||||
> | > | ||||
Back | Back | ||||
</Button> | </Button> | ||||
<Button | <Button | ||||
variant="filled" | variant="filled" | ||||
className={css.roleModalSaveButton} | className={css.roleModalSaveButton} | ||||
buttonColor={buttonThemes.primary} | buttonColor={buttonThemes.primary} | ||||
onClick={onSave} | |||||
> | > | ||||
Save | Save | ||||
</Button> | </Button> | ||||
</div> | </div> | ||||
</Modal> | </Modal> | ||||
); | ); | ||||
} | } | ||||
export default ChangeMemberRoleModal; | export default ChangeMemberRoleModal; |
Shorthand