refactor EditGroupMembersDialog
This commit is contained in:
parent
2798591800
commit
89235ef2d2
@ -0,0 +1,89 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import { Base } from "@docspace/shared/themes";
|
||||
|
||||
export const GroupMember = styled.div<{ isExpect: boolean }>`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 0;
|
||||
|
||||
.avatar {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.user_body-wrapper {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.name-wrapper,
|
||||
.role-email {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-weight: 600;
|
||||
font-size: ${(props) => props.theme.getCorrectFontSize("14px")};
|
||||
line-height: ${({ theme }) =>
|
||||
theme.interfaceDirection === "rtl" ? `20px` : `16px`};
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
${(props) =>
|
||||
props.isExpect && `color: ${props.theme.infoPanel.members.isExpectName}`};
|
||||
}
|
||||
|
||||
.me-label {
|
||||
font-weight: 600;
|
||||
font-size: ${(props) => props.theme.getCorrectFontSize("14px")};
|
||||
line-height: ${({ theme }) =>
|
||||
theme.interfaceDirection === "rtl" ? `20px` : `16px`};
|
||||
color: ${(props) => props.theme.infoPanel.members.meLabelColor};
|
||||
padding-inline-start: 8px;
|
||||
margin-inline-start: -8px;
|
||||
}
|
||||
|
||||
.role-wrapper {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
padding-right: 8px;
|
||||
margin-right: auto;
|
||||
`
|
||||
: css`
|
||||
padding-left: 8px;
|
||||
margin-left: auto;
|
||||
`}
|
||||
|
||||
font-weight: 600;
|
||||
font-size: ${(props) => props.theme.getCorrectFontSize("13px")};
|
||||
line-height: 20px;
|
||||
white-space: nowrap;
|
||||
|
||||
.disabled-role-combobox {
|
||||
color: ${(props) =>
|
||||
props.theme.infoPanel.members.disabledRoleSelectorColor};
|
||||
|
||||
margin-inline-end: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.role-view_remove-icon {
|
||||
cursor: pointer;
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) => props.theme.iconButton.color};
|
||||
}
|
||||
}
|
||||
|
||||
:hover {
|
||||
svg {
|
||||
path {
|
||||
fill: ${(props) => props.theme.iconButton.hoverColor};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
GroupMember.defaultProps = { theme: Base };
|
@ -0,0 +1,111 @@
|
||||
import { inject, observer } from "mobx-react";
|
||||
import AtReactSvgUrl from "PUBLIC_DIR/images/@.react.svg?url";
|
||||
// import { StyledUser } from "../../styles/members";
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { ComboBox } from "@docspace/shared/components/combobox";
|
||||
import DefaultUserPhotoUrl from "PUBLIC_DIR/images/default_user_photo_size_82-82.png";
|
||||
import { isMobileOnly, isMobile } from "react-device-detect";
|
||||
import { decode } from "he";
|
||||
import { filterUserRoleOptions } from "SRC_DIR/helpers";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import * as Styled from "./index.styled";
|
||||
import { getUserRoleOptionsByUserAccess } from "@docspace/shared/utils/room-members/getUserRoleOptionsByUserAccess";
|
||||
import { getUserRoleOptionsByRoomType } from "@docspace/shared/utils/room-members/getUserRoleOptionsByRoomType";
|
||||
|
||||
interface GroupMemberProps {
|
||||
t: any;
|
||||
user: any;
|
||||
infoPanelSelection: any;
|
||||
}
|
||||
|
||||
const GroupMember = ({ t, user, infoPanelSelection }: GroupMemberProps) => {
|
||||
const { roomType } = infoPanelSelection;
|
||||
|
||||
const fullRoomRoleOptions = getUserRoleOptionsByRoomType(
|
||||
t,
|
||||
roomType,
|
||||
user.canEditAccess,
|
||||
);
|
||||
const selectedUserRoleCBOption = getUserRoleOptionsByUserAccess(
|
||||
t,
|
||||
user.userAccess || user.groupAccess,
|
||||
);
|
||||
const availableUserRoleCBOptions = filterUserRoleOptions(
|
||||
fullRoomRoleOptions,
|
||||
user,
|
||||
);
|
||||
|
||||
console.log(
|
||||
"GroupMember",
|
||||
user,
|
||||
selectedUserRoleCBOption,
|
||||
availableUserRoleCBOptions,
|
||||
fullRoomRoleOptions,
|
||||
);
|
||||
|
||||
return (
|
||||
<Styled.GroupMember isExpect={user.isExpect} key={user.id}>
|
||||
<Avatar
|
||||
role={selectedUserRoleCBOption?.type}
|
||||
className="avatar"
|
||||
size="min"
|
||||
userName={user.isExpect ? "" : user.displayName || user.name}
|
||||
source={
|
||||
user.isExpect
|
||||
? AtReactSvgUrl
|
||||
: user.hasAvatar
|
||||
? user.avatar
|
||||
: DefaultUserPhotoUrl
|
||||
}
|
||||
//
|
||||
tooltipContent={undefined}
|
||||
hideRoleIcon={false}
|
||||
withTooltip={false}
|
||||
/>
|
||||
|
||||
<div className="user_body-wrapper">
|
||||
<div className="name-wrapper">
|
||||
<Text
|
||||
className="name"
|
||||
data-tooltip-id={`userTooltip_${Math.random()}`}
|
||||
>
|
||||
{decode(user.displayName)}
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedUserRoleCBOption && availableUserRoleCBOptions && (
|
||||
<div className="role-wrapper">
|
||||
{user.canEditAccess ? (
|
||||
<ComboBox
|
||||
className="role-combobox"
|
||||
selectedOption={selectedUserRoleCBOption}
|
||||
options={availableUserRoleCBOptions}
|
||||
scaled={false}
|
||||
withBackdrop={isMobile}
|
||||
size="content"
|
||||
modernView
|
||||
title={t("Common:Role")}
|
||||
manualWidth={"fit-content"}
|
||||
isMobileView={isMobileOnly}
|
||||
directionY="both"
|
||||
displaySelectedOption
|
||||
//
|
||||
onSelect={() => {}}
|
||||
isLoading={false}
|
||||
onToggle={() => {}}
|
||||
/>
|
||||
) : (
|
||||
<div className="disabled-role-combobox" title={t("Common:Role")}>
|
||||
{selectedUserRoleCBOption.label}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</Styled.GroupMember>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ infoPanelStore }) => ({
|
||||
infoPanelSelection: infoPanelStore.infoPanelSelection,
|
||||
}))(observer(GroupMember));
|
@ -5,27 +5,25 @@ import {
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { useState, useEffect, useTransition } from "react";
|
||||
import { getGroupMembersInRoom } from "@docspace/shared/api/groups";
|
||||
import User from "SRC_DIR/pages/Home/InfoPanel/Body/views/Members/User";
|
||||
import MembersHelper from "SRC_DIR/pages/Home/InfoPanel/Body/helpers/MembersHelper";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { InputSize } from "@docspace/shared/components/text-input";
|
||||
import { SearchInput } from "@docspace/shared/components/search-input";
|
||||
import GroupMember from "./GroupMember";
|
||||
|
||||
interface EditGroupMembersProps {
|
||||
selfId: string;
|
||||
visible: boolean;
|
||||
setVisible: (visible: boolean) => void;
|
||||
group: any;
|
||||
infoPanelSelection: any;
|
||||
}
|
||||
|
||||
const EditGroupMembers = ({
|
||||
infoPanelSelection,
|
||||
selfId,
|
||||
groupId,
|
||||
group,
|
||||
visible,
|
||||
setVisible,
|
||||
}: EditGroupMembersProps) => {
|
||||
const { t } = useTranslation(["Common"]);
|
||||
const membersHelper = new MembersHelper({ t });
|
||||
|
||||
const [searchValue, setSearchValue] = useState<string>("");
|
||||
const onChangeSearchValue = (newValue: string) => {
|
||||
@ -37,27 +35,20 @@ const EditGroupMembers = ({
|
||||
const filteredGroupMembers = groupMembers?.filter((groupMember) =>
|
||||
groupMember.user.displayName.includes(searchValue),
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [, startTransition] = useTransition();
|
||||
|
||||
const onClose = () => setVisible(false);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchGroup = async () => {
|
||||
if (!groupId) return;
|
||||
setIsLoading(true);
|
||||
if (!group) return;
|
||||
|
||||
console.log("infoPanelSelection", infoPanelSelection);
|
||||
getGroupMembersInRoom(infoPanelSelection.id, groupId)!
|
||||
.then((data: any) => {
|
||||
startTransition(() => setGroupMembers(data.items));
|
||||
console.log(data);
|
||||
})
|
||||
.catch((err: any) => console.error(err))
|
||||
.finally(() => setIsLoading(false));
|
||||
getGroupMembersInRoom(infoPanelSelection.id, group.id)!
|
||||
.then((data: any) => startTransition(() => setGroupMembers(data.items)))
|
||||
.catch((err: any) => console.error(err));
|
||||
};
|
||||
fetchGroup();
|
||||
}, [groupId]);
|
||||
}, [group, infoPanelSelection.id]);
|
||||
|
||||
return (
|
||||
<ModalDialog
|
||||
@ -65,13 +56,13 @@ const EditGroupMembers = ({
|
||||
onClose={onClose}
|
||||
displayType={ModalDialogType.aside}
|
||||
>
|
||||
<ModalDialog.Header>EditGroupMembers</ModalDialog.Header>
|
||||
<ModalDialog.Header>{group.name}</ModalDialog.Header>
|
||||
|
||||
<ModalDialog.Body>
|
||||
<SearchInput
|
||||
className="search-input"
|
||||
placeholder={"Search by group members"}
|
||||
value={""}
|
||||
placeholder={t("Search by group members")}
|
||||
value={searchValue}
|
||||
onChange={onChangeSearchValue}
|
||||
onClearSearch={onClearSearch}
|
||||
size={InputSize.base}
|
||||
@ -80,16 +71,8 @@ const EditGroupMembers = ({
|
||||
<div style={{ height: "12px", width: "100%" }} />
|
||||
|
||||
{filteredGroupMembers &&
|
||||
filteredGroupMembers.map(({ user, groupAccess, canEditAccess }) => (
|
||||
<div key={user.id} style={{ paddingRight: "12px" }}>
|
||||
<User
|
||||
t={t}
|
||||
key={user.id}
|
||||
user={{ ...user, access: groupAccess, canEditAccess }}
|
||||
membersHelper={membersHelper}
|
||||
currentMember={{ id: selfId }}
|
||||
/>
|
||||
</div>
|
||||
filteredGroupMembers.map(({ user, ...rest }) => (
|
||||
<GroupMember t={t} key={user.id} user={{ ...user, ...rest }} />
|
||||
))}
|
||||
</ModalDialog.Body>
|
||||
</ModalDialog>
|
||||
@ -99,7 +82,7 @@ const EditGroupMembers = ({
|
||||
export default inject(({ infoPanelStore, userStore, dialogsStore }) => ({
|
||||
infoPanelSelection: infoPanelStore.infoPanelSelection,
|
||||
selfId: userStore.user.id,
|
||||
groupId: dialogsStore.editMembersGroupId,
|
||||
group: dialogsStore.editMembersGroup,
|
||||
visible: dialogsStore.editGroupMembersDialogVisible,
|
||||
setVisible: dialogsStore.setEditGroupMembersDialogVisible,
|
||||
}))(observer(EditGroupMembers));
|
||||
|
@ -36,10 +36,9 @@ const User = ({
|
||||
setInfoPanelMembers,
|
||||
searchValue,
|
||||
resendEmailInvitations,
|
||||
setEditMembersGroupId,
|
||||
setEditMembersGroup,
|
||||
setEditGroupMembersDialogVisible,
|
||||
}) => {
|
||||
console.log(user);
|
||||
if (!infoPanelSelection) return null;
|
||||
if (!user.displayName && !user.name && !user.email) return null;
|
||||
|
||||
@ -58,7 +57,6 @@ const User = ({
|
||||
);
|
||||
|
||||
const userRole = membersHelper.getOptionByUserAccess(user.access, user);
|
||||
console.log("userRole", userRole);
|
||||
const userRoleOptions = user.isGroup
|
||||
? filterGroupRoleOptions(fullRoomRoleOptions)
|
||||
: filterUserRoleOptions(fullRoomRoleOptions, user);
|
||||
@ -239,8 +237,8 @@ const User = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
const onOpenGroup = (groupId) => {
|
||||
setEditMembersGroupId(groupId);
|
||||
const onOpenGroup = (group) => {
|
||||
setEditMembersGroup(group);
|
||||
setEditGroupMembersDialogVisible(true);
|
||||
};
|
||||
|
||||
@ -292,7 +290,7 @@ const User = ({
|
||||
<Link
|
||||
className="name"
|
||||
type="action"
|
||||
onClick={() => onOpenGroup(user.id)}
|
||||
onClick={() => onOpenGroup(user)}
|
||||
>
|
||||
{decode(user.name)}
|
||||
</Link>
|
||||
@ -382,7 +380,7 @@ export default inject(
|
||||
|
||||
const { changeType: changeUserType } = peopleStore;
|
||||
|
||||
const { setEditMembersGroupId, setEditGroupMembersDialogVisible } =
|
||||
const { setEditMembersGroup, setEditGroupMembersDialogVisible } =
|
||||
dialogsStore;
|
||||
|
||||
return {
|
||||
@ -397,7 +395,7 @@ export default inject(
|
||||
setInfoPanelMembers,
|
||||
fetchMembers,
|
||||
searchValue,
|
||||
setEditMembersGroupId,
|
||||
setEditMembersGroup,
|
||||
setEditGroupMembersDialogVisible,
|
||||
};
|
||||
},
|
||||
|
@ -79,7 +79,7 @@ class DialogsStore {
|
||||
leaveRoomDialogVisible = false;
|
||||
changeRoomOwnerIsVisible = false;
|
||||
changeRoomOwnerData = null;
|
||||
editMembersGroupId = null;
|
||||
editMembersGroup = null;
|
||||
|
||||
shareFolderDialogVisible = false;
|
||||
|
||||
@ -290,8 +290,8 @@ class DialogsStore {
|
||||
this.editGroupMembersDialogVisible = editGroupMembersDialogVisible;
|
||||
};
|
||||
|
||||
setEditMembersGroupId = (editMembersGroupId) => {
|
||||
this.editMembersGroupId = editMembersGroupId;
|
||||
setEditMembersGroup = (editMembersGroup) => {
|
||||
this.editMembersGroup = editMembersGroup;
|
||||
};
|
||||
|
||||
setConflictResolveDialogVisible = (conflictResolveDialogVisible) => {
|
||||
|
52
packages/shared/utils/room-members/getUserRoleOptions.ts
Normal file
52
packages/shared/utils/room-members/getUserRoleOptions.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { ShareAccessRights } from "@docspace/shared/enums";
|
||||
|
||||
export const getUserRoleOptions = (t: any) => ({
|
||||
docSpaceAdmin: {
|
||||
key: "owner",
|
||||
label: t("Common:Owner"),
|
||||
access: ShareAccessRights.FullAccess,
|
||||
type: "admin",
|
||||
},
|
||||
roomAdmin: {
|
||||
key: "roomAdmin",
|
||||
label: t("Common:RoomAdmin"),
|
||||
access: ShareAccessRights.RoomManager,
|
||||
type: "manager",
|
||||
},
|
||||
collaborator: {
|
||||
key: "collaborator",
|
||||
label: t("Common:PowerUser"),
|
||||
access: ShareAccessRights.Collaborator,
|
||||
type: "collaborator",
|
||||
},
|
||||
viewer: {
|
||||
key: "viewer",
|
||||
label: t("Translations:RoleViewer"),
|
||||
access: ShareAccessRights.ReadOnly,
|
||||
type: "user",
|
||||
},
|
||||
editor: {
|
||||
key: "editor",
|
||||
label: t("Translations:RoleEditor"),
|
||||
access: ShareAccessRights.Editing,
|
||||
type: "user",
|
||||
},
|
||||
formFiller: {
|
||||
key: "formFiller",
|
||||
label: t("Translations:RoleFormFiller"),
|
||||
access: ShareAccessRights.FormFilling,
|
||||
type: "user",
|
||||
},
|
||||
reviewer: {
|
||||
key: "reviewer",
|
||||
label: t("Translations:RoleReviewer"),
|
||||
access: ShareAccessRights.Review,
|
||||
type: "user",
|
||||
},
|
||||
commentator: {
|
||||
key: "commentator",
|
||||
label: t("Translations:RoleCommentator"),
|
||||
access: ShareAccessRights.Comment,
|
||||
type: "user",
|
||||
},
|
||||
});
|
@ -0,0 +1,81 @@
|
||||
import { RoomsType, ShareAccessRights } from "@docspace/shared/enums";
|
||||
import { getUserRoleOptions } from "./getUserRoleOptions";
|
||||
|
||||
export const getUserRoleOptionsByRoomType = (
|
||||
t: any,
|
||||
roomType: RoomsType,
|
||||
canChangeUserRole: boolean = false,
|
||||
) => {
|
||||
if (!roomType) return;
|
||||
|
||||
const options = getUserRoleOptions(t);
|
||||
|
||||
const deleteOption = canChangeUserRole
|
||||
? [
|
||||
{ key: "s2", isSeparator: true },
|
||||
{
|
||||
key: "remove",
|
||||
label: t("Common:Remove"),
|
||||
access: ShareAccessRights.None,
|
||||
},
|
||||
]
|
||||
: [];
|
||||
|
||||
switch (roomType) {
|
||||
case RoomsType.FillingFormsRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.formFiller,
|
||||
options.viewer,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.EditingRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.editor,
|
||||
options.viewer,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.ReviewRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.reviewer,
|
||||
options.commentator,
|
||||
options.viewer,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.ReadOnlyRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.viewer,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.CustomRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.editor,
|
||||
options.formFiller,
|
||||
options.reviewer,
|
||||
options.commentator,
|
||||
options.viewer,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.FormRoom:
|
||||
return [
|
||||
options.roomAdmin,
|
||||
options.collaborator,
|
||||
options.viewer,
|
||||
options.formFiller,
|
||||
...deleteOption,
|
||||
];
|
||||
case RoomsType.PublicRoom:
|
||||
return [options.roomAdmin, options.collaborator, ...deleteOption];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
};
|
@ -0,0 +1,16 @@
|
||||
import { ShareAccessRights } from "enums";
|
||||
import { getUserRoleOptions } from "./getUserRoleOptions";
|
||||
|
||||
export const getUserRoleOptionsByUserAccess = (
|
||||
t: any,
|
||||
access: ShareAccessRights,
|
||||
) => {
|
||||
if (!access) return;
|
||||
|
||||
const options = getUserRoleOptions(t);
|
||||
const [userOption] = Object.values(options).filter(
|
||||
(opt) => opt.access === access,
|
||||
);
|
||||
|
||||
return userOption;
|
||||
};
|
Loading…
Reference in New Issue
Block a user