diff --git a/web/roles/create-roles-modal.react.js b/web/roles/create-roles-modal.react.js --- a/web/roles/create-roles-modal.react.js +++ b/web/roles/create-roles-modal.react.js @@ -1,32 +1,61 @@ // @flow import classNames from 'classnames'; +import invariant from 'invariant'; import * as React from 'react'; +import { + modifyCommunityRole, + modifyCommunityRoleActionTypes, +} from 'lib/actions/thread-actions.js'; import { useModalContext } from 'lib/components/modal-provider.react.js'; +import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js'; +import type { LoadingStatus } from 'lib/types/loading-types.js'; import type { UserSurfacedPermission, UserSurfacedPermissionOption, } from 'lib/types/thread-permission-types.js'; -import type { ThreadInfo } from 'lib/types/thread-types.js'; +import type { + ThreadInfo, + RoleModificationRequest, +} from 'lib/types/thread-types.js'; +import { + useServerCall, + useDispatchActionPromise, +} from 'lib/utils/action-utils.js'; import { useFilterPermissionOptionsByThreadType } from 'lib/utils/role-utils.js'; import css from './create-roles-modal.css'; import Button, { buttonThemes } from '../components/button.react.js'; import EnumSettingsOption from '../components/enum-settings-option.react.js'; +import LoadingIndicator from '../loading-indicator.react.js'; import Input from '../modals/input.react.js'; import Modal from '../modals/modal.react.js'; +import { useSelector } from '../redux/redux-utils.js'; + +const createRolesLoadingStatusSelector = createLoadingStatusSelector( + modifyCommunityRoleActionTypes, +); type CreateRolesModalProps = { +threadInfo: ThreadInfo, +action: 'create_role' | 'edit_role', + +existingRoleID?: string, +roleName: string, +rolePermissions: $ReadOnlySet, }; function CreateRolesModal(props: CreateRolesModalProps): React.Node { const { popModal } = useModalContext(); - const { threadInfo, roleName, rolePermissions } = props; + const { threadInfo, action, existingRoleID, roleName, rolePermissions } = + props; + + const callModifyCommunityRole = useServerCall(modifyCommunityRole); + const dispatchActionPromise = useDispatchActionPromise(); + + const createRolesLoadingStatus: LoadingStatus = useSelector( + createRolesLoadingStatusSelector, + ); const [pendingRoleName, setPendingRoleName] = React.useState(roleName); @@ -101,6 +130,59 @@ ], ); + const onClickCreateRole = React.useCallback(() => { + // TODO: Error handling in a later diff + + let callModifyCommunityRoleParams: RoleModificationRequest; + if (action === 'create_role') { + callModifyCommunityRoleParams = { + community: threadInfo.id, + action, + name: pendingRoleName, + permissions: [...pendingRolePermissions], + }; + } else { + invariant(existingRoleID, 'existingRoleID should be defined'); + callModifyCommunityRoleParams = { + community: threadInfo.id, + existingRoleID, + action, + name: pendingRoleName, + permissions: [...pendingRolePermissions], + }; + } + + dispatchActionPromise( + modifyCommunityRoleActionTypes, + (async () => { + const response = await callModifyCommunityRole( + callModifyCommunityRoleParams, + ); + popModal(); + return response; + })(), + ); + }, [ + callModifyCommunityRole, + dispatchActionPromise, + threadInfo, + action, + existingRoleID, + pendingRoleName, + pendingRolePermissions, + popModal, + ]); + + const saveButtonContent = React.useMemo(() => { + if (createRolesLoadingStatus === 'loading') { + return ( + + ); + } + + return 'Save'; + }, [createRolesLoadingStatus]); + return (
@@ -137,9 +219,9 @@ variant="filled" className={css.createRoleButton} buttonColor={buttonThemes.standard} - onClick={null} + onClick={onClickCreateRole} > - Create + {saveButtonContent}