Page MenuHomePhabricator

D8625.id29102.diff
No OneTemporary

D8625.id29102.diff

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,111 @@
+// @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 { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
+import { useRoleMemberCountsForCommunity } from 'lib/shared/thread-utils.js';
+import type { LoadingStatus } from 'lib/types/loading-types.js';
+import type { ThreadInfo } from 'lib/types/thread-types.js';
+import {
+ useServerCall,
+ useDispatchActionPromise,
+} from 'lib/utils/action-utils.js';
+import { constructRoleDeletionMessagePrompt } from 'lib/utils/role-utils.js';
+
+import css from './delete-role-modal.css';
+import Button, { buttonThemes } from '../components/button.react.js';
+import LoadingIndicator from '../loading-indicator.react.js';
+import Modal from '../modals/modal.react.js';
+import { useSelector } from '../redux/redux-utils.js';
+
+const deleteRoleLoadingStatusSelector = createLoadingStatusSelector(
+ deleteCommunityRoleActionTypes,
+);
+
+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 deleteRoleLoadingStatus: LoadingStatus = useSelector(
+ deleteRoleLoadingStatusSelector,
+ );
+
+ const roleNamesToMemberCounts = useRoleMemberCountsForCommunity(threadInfo);
+ const roleName = threadInfo.roles[roleID].name;
+ const memberCount = roleNamesToMemberCounts[roleName];
+ const defaultRoleName = threadInfo.roles[defaultRoleID].name;
+
+ const message = constructRoleDeletionMessagePrompt(
+ defaultRoleName,
+ memberCount,
+ );
+
+ const onDeleteRole = React.useCallback(() => {
+ dispatchActionPromise(
+ deleteCommunityRoleActionTypes,
+ (async () => {
+ const response = await callDeleteCommunityRole({
+ community: threadInfo.id,
+ roleID: roleID,
+ });
+ popModal();
+ return response;
+ })(),
+ );
+ }, [
+ callDeleteCommunityRole,
+ dispatchActionPromise,
+ roleID,
+ threadInfo.id,
+ popModal,
+ ]);
+
+ const deleteButtonContent = React.useMemo(() => {
+ if (deleteRoleLoadingStatus === 'loading') {
+ return (
+ <LoadingIndicator status={deleteRoleLoadingStatus} size="medium" />
+ );
+ }
+ return 'Yes, delete role';
+ }, [deleteRoleLoadingStatus]);
+
+ return (
+ <Modal name="Delete role" onClose={popModal} size="large">
+ <div className={css.roleDeletionText}>{message}</div>
+ <div className={css.buttonsContainer}>
+ <Button
+ variant="outline"
+ className={css.cancelButton}
+ buttonColor={buttonThemes.outline}
+ onClick={popModal}
+ >
+ Cancel
+ </Button>
+ <Button
+ variant="filled"
+ className={css.deleteRoleButton}
+ buttonColor={buttonThemes.danger}
+ onClick={onDeleteRole}
+ >
+ {deleteButtonContent}
+ </Button>
+ </div>
+ </Modal>
+ );
+}
+
+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
@@ -10,6 +10,7 @@
import { useRoleDeletableAndEditableStatus } from 'lib/utils/role-utils.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';
@@ -63,7 +64,15 @@
threadInfo,
],
);
- const openDeleteRoleModal = React.useCallback(() => {}, []);
+ const openDeleteRoleModal = React.useCallback(() => {
+ pushModal(
+ <DeleteRoleModal
+ threadInfo={threadInfo}
+ defaultRoleID={defaultRoleID}
+ roleID={existingRoleID}
+ />,
+ );
+ }, [existingRoleID, pushModal, threadInfo, defaultRoleID]);
const menuItems = React.useMemo(() => {
const availableOptions = [];

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 30, 5:06 PM (21 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2601724
Default Alt Text
D8625.id29102.diff (4 KB)

Event Timeline