diff --git a/web/roles/delete-role-modal.css b/web/roles/delete-role-modal.css new file mode 100644 --- /dev/null +++ b/web/roles/delete-role-modal.css @@ -0,0 +1,20 @@ +.roleDeletionText { + color: var(--modal-fg); + font-size: var(--m-font-14); + padding: 16px 32px; +} + +.buttonsContainer { + display: flex; + flex-direction: row; + justify-content: flex-end; + padding: 16px 32px; +} + +.cancelButton { + width: 100px; +} + +.deleteRoleButton { + margin-left: 8px; +} diff --git a/web/roles/delete-role-modal.react.js b/web/roles/delete-role-modal.react.js new file mode 100644 --- /dev/null +++ b/web/roles/delete-role-modal.react.js @@ -0,0 +1,94 @@ +// @flow + +import * as React from 'react'; + +import { + deleteCommunityRole, + deleteCommunityRoleActionTypes, +} from 'lib/actions/thread-actions.js'; +import { useModalContext } from 'lib/components/modal-provider.react.js'; +import { useRoleMemberCountsForCommunity } from 'lib/shared/thread-utils.js'; +import type { ThreadInfo } from 'lib/types/thread-types.js'; +import { + useServerCall, + useDispatchActionPromise, +} from 'lib/utils/action-utils.js'; + +import css from './delete-role-modal.css'; +import Button, { buttonThemes } from '../components/button.react.js'; +import Modal from '../modals/modal.react.js'; + +type DeleteRoleModalProps = { + +threadInfo: ThreadInfo, + +defaultRoleID: string, + +roleID: string, +}; + +function DeleteRoleModal(props: DeleteRoleModalProps): React.Node { + const { threadInfo, defaultRoleID, roleID } = props; + const { popModal } = useModalContext(); + + const callDeleteCommunityRole = useServerCall(deleteCommunityRole); + const dispatchActionPromise = useDispatchActionPromise(); + + const roleNamesToMemberCounts = useRoleMemberCountsForCommunity(threadInfo); + const roleName = threadInfo.roles[roleID].name; + const memberCount = roleNamesToMemberCounts[roleName]; + const defaultRoleName = threadInfo.roles[defaultRoleID].name; + + let message; + if (memberCount === 0) { + message = 'Are you sure you want to delete this role?'; + } else { + const messageNoun = memberCount === 1 ? 'member' : 'members'; + const messageVerb = memberCount === 1 ? 'is' : 'are'; + + message = + `There ${messageVerb} currently ${memberCount} ${messageNoun} with ` + + `this role. Deleting this role will automatically assign the members ` + + `affected to the ${defaultRoleName} role.`; + } + + const onDeleteRole = React.useCallback(() => { + dispatchActionPromise( + deleteCommunityRoleActionTypes, + callDeleteCommunityRole({ + community: threadInfo.id, + roleID: roleID, + }), + ); + popModal(); + }, [ + callDeleteCommunityRole, + dispatchActionPromise, + roleID, + threadInfo.id, + popModal, + ]); + + return ( + +
{message}
+
+ + +
+
+ ); +} + +export default DeleteRoleModal; diff --git a/web/roles/role-actions-menu.react.js b/web/roles/role-actions-menu.react.js --- a/web/roles/role-actions-menu.react.js +++ b/web/roles/role-actions-menu.react.js @@ -1,5 +1,6 @@ // @flow +import invariant from 'invariant'; import * as React from 'react'; import { useModalContext } from 'lib/components/modal-provider.react.js'; @@ -8,6 +9,7 @@ import type { ThreadInfo } from 'lib/types/thread-types.js'; import CreateRolesModal from './create-roles-modal.react.js'; +import DeleteRoleModal from './delete-role-modal.react.js'; import css from './role-actions-menu.css'; import MenuItem from '../components/menu-item.react.js'; import Menu from '../components/menu.react.js'; @@ -26,9 +28,11 @@ const defaultRoleID = Object.keys(threadInfo.roles).find( roleID => threadInfo.roles[roleID].isDefault, ); + invariant(defaultRoleID, 'id should exist for default role'); const existingRoleID = Object.keys(threadInfo.roles).find( roleID => threadInfo.roles[roleID].name === roleName, ); + invariant(existingRoleID, 'id should exist for an existing role'); const isDeletableRole = roleName !== 'Admins' && defaultRoleID !== existingRoleID; @@ -56,7 +60,15 @@ threadInfo, ], ); - const openDeleteRoleModal = React.useCallback(() => {}, []); + const openDeleteRoleModal = React.useCallback(() => { + pushModal( + , + ); + }, [existingRoleID, pushModal, threadInfo, defaultRoleID]); const items = React.useMemo(() => { const availableOptions = [];