Skip to content

Commit

Permalink
feat(web): add user remove button and improve remove users modal (#1288)
Browse files Browse the repository at this point in the history
* feat: adding user remove button

* add key
  • Loading branch information
caichi-t authored Oct 29, 2024
1 parent 3b29981 commit af0bd0d
Show file tree
Hide file tree
Showing 5 changed files with 1,215 additions and 1,159 deletions.
2 changes: 2 additions & 0 deletions web/src/components/atoms/Icon/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
SearchOutlined,
SettingOutlined,
UsergroupAddOutlined,
UsergroupDeleteOutlined,
UserSwitchOutlined,
CaretDownOutlined,
CaretRightOutlined,
Expand Down Expand Up @@ -98,6 +99,7 @@ export default {
search: SearchOutlined,
settings: SettingOutlined,
userGroupAdd: UsergroupAddOutlined,
userGroupDelete: UsergroupDeleteOutlined,
userSwitch: UserSwitchOutlined,
caretDown: CaretDownOutlined,
caretRight: CaretRightOutlined,
Expand Down
127 changes: 91 additions & 36 deletions web/src/components/molecules/Member/MemberTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import Modal from "@reearth-cms/components/atoms/Modal";
import PageHeader from "@reearth-cms/components/atoms/PageHeader";
import { ListToolBarProps, TableRowSelection } from "@reearth-cms/components/atoms/ProTable";
import Search from "@reearth-cms/components/atoms/Search";
import Space from "@reearth-cms/components/atoms/Space";
import UserAvatar from "@reearth-cms/components/atoms/UserAvatar";
import ResizableProTable from "@reearth-cms/components/molecules/Common/ResizableProTable";
import { User } from "@reearth-cms/components/molecules/Member/types";
import { UserMember } from "@reearth-cms/components/molecules/Workspace/types";
import { useT } from "@reearth-cms/i18n";

Expand Down Expand Up @@ -62,15 +62,37 @@ const MemberTable: React.FC<Props> = ({
const t = useT();

const handleMemberDelete = useCallback(
(userIds: string[]) => {
(users: User[]) => {
confirm({
title: t("Are you sure to remove this member?"),
title:
users.length > 1
? t("Are you sure to remove these members?")
: t("Are you sure to remove this member?"),
icon: <Icon icon="exclamationCircle" />,
content: t(
"Remove this member from workspace means this member will not view any content of this workspace.",
content: (
<>
<RemoveUsers>
{users.map(user => (
<RemoveUser key={user.id}>
<UserAvatar username={user.name} />
<UserInfoWrapper>
<UserInfo>{user.name}</UserInfo>
<Email>{user.email}</Email>
</UserInfoWrapper>
</RemoveUser>
))}
</RemoveUsers>
<div>
{t(
"Remove this member from workspace means this member will not view any content of this workspace.",
)}
</div>
</>
),
okText: t("Yes"),
cancelText: t("No"),
async onOk() {
await handleMemberRemoveFromWorkspace(userIds);
await handleMemberRemoveFromWorkspace(users.map(user => user.id));
},
});
},
Expand Down Expand Up @@ -125,8 +147,8 @@ const MemberTable: React.FC<Props> = ({
title: t("Action"),
dataIndex: "action",
key: "action",
width: 128,
minWidth: 128,
width: 150,
minWidth: 150,
},
],
[t],
Expand All @@ -148,23 +170,38 @@ const MemberTable: React.FC<Props> = ({
disabled={!isOwner || member.userId === me.id}>
{t("Change Role?")}
</ActionButton>
{member.userId === me.id && (
<>
<Divider type="vertical" />
<ActionButton
type="link"
onClick={() => {
leaveConfirm(member.userId);
}}
disabled={!isAbleToLeave}>
{t("Leave")}
</ActionButton>
</>
<Divider type="vertical" />
{member.userId === me.id ? (
<ActionButton
type="link"
onClick={() => {
leaveConfirm(member.userId);
}}
disabled={!isAbleToLeave}>
{t("Leave")}
</ActionButton>
) : (
<ActionButton
type="link"
onClick={() => {
handleMemberDelete([member.user]);
}}>
{t("Remove")}
</ActionButton>
)}
</>
),
})),
[workspaceUserMembers, t, isOwner, me.id, isAbleToLeave, handleRoleModalOpen, leaveConfirm],
[
workspaceUserMembers,
t,
isOwner,
me.id,
isAbleToLeave,
handleRoleModalOpen,
leaveConfirm,
handleMemberDelete,
],
);

const toolbar: ListToolBarProps = useMemo(
Expand Down Expand Up @@ -210,21 +247,15 @@ const MemberTable: React.FC<Props> = ({
const alertOptions = useCallback(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(props: any) => (
<Space size={16}>
<DeselectButton onClick={props.onCleanSelected}>
<Icon icon="clear" /> {t("Deselect")}
</DeselectButton>
<DeleteButton onClick={() => handleMemberDelete(props.selectedRowKeys)}>
<Icon icon="delete" /> {t("Remove")}
</DeleteButton>
</Space>
<DeleteButton onClick={() => handleMemberDelete(props.selectedRows)}>
<Icon icon="userGroupDelete" /> {t("Remove")}
</DeleteButton>
),
[handleMemberDelete, t],
);

const options = useMemo(
() => ({
fullScreen: true,
reload: onReload,
}),
[onReload],
Expand Down Expand Up @@ -263,6 +294,36 @@ const MemberTable: React.FC<Props> = ({
);
};

const RemoveUsers = styled.div`
display: flex;
flex-direction: column;
gap: 8px;
padding-bottom: 8px;
`;

const RemoveUser = styled.div`
display: flex;
align-items: center;
gap: 8px;
padding: 8px 0;
`;

const UserInfoWrapper = styled.div`
flex: 1;
min-width: 0;
`;

const UserInfo = styled.p`
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;

const Email = styled(UserInfo)`
color: #00000073;
`;

const PaddedContent = styled(Content)`
padding: 16px 16px 0;
height: 100%;
Expand All @@ -279,12 +340,6 @@ const ActionButton = styled(Button)`
padding-right: 0;
`;

const DeselectButton = styled.a`
display: flex;
align-items: center;
gap: 8px;
`;

const DeleteButton = styled.a`
color: #ff7875;
:hover {
Expand Down
11 changes: 2 additions & 9 deletions web/src/components/molecules/Workspace/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PublicScope } from "@reearth-cms/components/molecules/Accessibility/types";
import { IntegrationMember } from "@reearth-cms/components/molecules/Integration/types";
import { User } from "@reearth-cms/components/molecules/Member/types";
import { t } from "@reearth-cms/i18n";

export type Project = {
Expand All @@ -12,18 +13,10 @@ export type Project = {
requestRoles?: Role[];
};

export type User = {
name: string;
};

export type UserMember = {
userId: string;
role: Role;
user: {
id: string;
name: string;
email: string;
};
user: User;
};

export type Member = UserMember | IntegrationMember;
Expand Down
Loading

0 comments on commit af0bd0d

Please sign in to comment.