Web:Accounts: delete withPeopleContextOptions HOC and add context group menu

This commit is contained in:
TimofeyBoyko 2022-08-30 14:39:15 +03:00
parent b737830e69
commit 143f9a148a
6 changed files with 198 additions and 127 deletions

View File

@ -1,5 +1,7 @@
import React, { useCallback } from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
import Link from "@docspace/components/link";
import LinkWithDropdown from "@docspace/components/link-with-dropdown";
import Avatar from "@docspace/components/avatar";
@ -20,6 +22,7 @@ export default function withContent(WrappedContent) {
deselectUser,
isAdmin,
theme,
getModel,
} = props;
const { userName, mobilePhone, email, role, displayName, avatar } = item;
@ -121,6 +124,20 @@ export default function withContent(WrappedContent) {
const onPhoneClick = () => window.open(`sms:${mobilePhone}`);
const onEmailClick = () => window.open(`mailto:${email}`);
const { t } = useTranslation([
"People",
"Common",
"PeopleTranslations",
"DeleteProfileEverDialog",
"Translations",
"Files",
"ChangeUserTypeDialog",
]);
const contextOptionsProps = {
contextOptions: getModel(item, t),
};
return (
<WrappedContent
onContentRowSelect={onContentRowSelect}
@ -131,6 +148,7 @@ export default function withContent(WrappedContent) {
checkedProps={checkedProps}
element={element}
isAdmin={isAdmin}
contextOptionsProps={contextOptionsProps}
{...props}
/>
);
@ -141,7 +159,9 @@ export default function withContent(WrappedContent) {
const { selectGroup } = peopleStore.selectedGroupStore;
const { getTargetUser } = peopleStore.targetUserStore;
const { selectionStore } = peopleStore;
const { selectionStore, contextOptionsStore } = peopleStore;
const { getModel } = contextOptionsStore;
const {
selection,
@ -158,10 +178,12 @@ export default function withContent(WrappedContent) {
selectGroup,
fetchProfile: getTargetUser,
checked: selection.some((el) => el.id === item.id),
isSeveralSelection: selection.length > 1,
isActive: bufferSelection?.id === item?.id,
setBufferSelection,
selectUser,
deselectUser,
getModel,
};
})(observer(WithContent));
}

View File

@ -1,76 +0,0 @@
import React from "react";
import { inject, observer } from "mobx-react";
import { useTranslation } from "react-i18next";
export default function withContextOptions(WrappedComponent) {
const WithContextOptions = (props) => {
const {
isAdmin,
item,
getUserContextOptions,
} = props;
const { id, options, currentUserId } = item;
const { t } = useTranslation([
"People",
"Common",
"PeopleTranslations",
"DeleteProfileEverDialog",
"Translations",
]);
const showContextMenu = options && options.length > 0;
const contextOptionsProps =
(isAdmin && showContextMenu) || (showContextMenu && id === currentUserId)
? {
contextOptions: getUserContextOptions(t, options, item),
}
: {};
return (
<WrappedComponent
t={t}
contextOptionsProps={contextOptionsProps}
{...props}
/>
);
};
return inject(({ auth, peopleStore }) => {
const { isAdmin } = auth;
const {
dialogStore,
targetUserStore,
usersStore,
contextOptionsStore,
} = peopleStore;
const { getTargetUser } = targetUserStore;
const { updateUserStatus } = usersStore;
const {
setDialogData,
closeDialogs,
setDeleteSelfProfileDialogVisible,
setChangePasswordDialogVisible,
setChangeEmailDialogVisible,
setDeleteProfileDialogVisible,
} = dialogStore;
const { getUserContextOptions } = contextOptionsStore;
return {
isAdmin,
fetchProfile: getTargetUser,
setDialogData,
closeDialogs,
setDeleteSelfProfileDialogVisible,
setChangePasswordDialogVisible,
setChangeEmailDialogVisible,
updateUserStatus,
setDeleteProfileDialogVisible,
getUserContextOptions,
};
})(observer(WithContextOptions));
}

View File

@ -6,7 +6,6 @@ import { isMobile } from "react-device-detect";
import Row from "@docspace/components/row";
import { Base } from "@docspace/components/themes";
import withContextOptions from "SRC_DIR/HOCs/withPeopleContextOptions";
import withContent from "SRC_DIR/HOCs/withPeopleContent";
import UserContent from "./userContent";
@ -97,13 +96,17 @@ const SimpleUserRow = (props) => {
element,
setBufferSelection,
isActive,
isSeveralSelection,
} = props;
const isChecked = checkedProps.checked;
const userContextClick = React.useCallback(() => {
if (isSeveralSelection && isChecked) {
return;
}
setBufferSelection(item);
}, [item, setBufferSelection]);
}, [isChecked, isSeveralSelection, item, setBufferSelection]);
return (
<StyledWrapper
@ -130,4 +133,4 @@ const SimpleUserRow = (props) => {
);
};
export default withRouter(withContextOptions(withContent(SimpleUserRow)));
export default withRouter(withContent(SimpleUserRow));

View File

@ -11,7 +11,6 @@ import Checkbox from "@docspace/components/checkbox";
import ComboBox from "@docspace/components/combobox";
import DropDownItem from "@docspace/components/drop-down-item";
import withContextOptions from "SRC_DIR/HOCs/withPeopleContextOptions";
import withContent from "SRC_DIR/HOCs/withPeopleContent";
import Badges from "../Badges";
@ -136,6 +135,7 @@ const PeopleTableRow = (props) => {
userId,
setBufferSelection,
isActive,
isSeveralSelection,
} = props;
const {
@ -233,8 +233,12 @@ const PeopleTableRow = (props) => {
const isChecked = checkedProps.checked;
const userContextClick = React.useCallback(() => {
if (isSeveralSelection && isChecked) {
return;
}
setBufferSelection(item);
}, [item, setBufferSelection]);
}, [isSeveralSelection, isChecked, item, setBufferSelection]);
return (
<StyledWrapper
@ -371,5 +375,5 @@ const PeopleTableRow = (props) => {
};
export default withTranslation(["People", "Common", "Settings"])(
withRouter(withContextOptions(withContent(PeopleTableRow)))
withRouter(withContent(PeopleTableRow))
);

View File

@ -18,27 +18,14 @@ const PROFILE_SELF_URL = combineUrl(PROXY_HOMEPAGE_URL, "/accounts/view/@self");
class AccountsContextOptionsStore {
authStore = null;
dialogStore = null;
targetUserStore = null;
usersStore = null;
selectionStore = null;
infoPanelStore = null;
constructor(
authStore,
dialogStore,
targetUserStore,
usersStore,
selectionStore,
infoPanelStore
) {
peopleStore = null;
constructor(authStore, peopleStore) {
makeAutoObservable(this);
this.authStore = authStore;
this.dialogStore = dialogStore;
this.targetUserStore = targetUserStore;
this.usersStore = usersStore;
this.selectionStore = selectionStore;
this.infoPanelStore = infoPanelStore;
this.peopleStore = peopleStore;
}
getUserContextOptions = (t, options, item) => {
@ -155,12 +142,135 @@ class AccountsContextOptionsStore {
return contextMenu;
};
getUserGroupContextOptions = (t) => {
const { onChangeType } = this.peopleStore;
const {
hasUsersToMakeEmployees,
hasUsersToActivate,
hasUsersToDisable,
hasUsersToInvite,
hasUsersToRemove,
} = this.peopleStore.selectionStore;
const {
setActiveDialogVisible,
setDisableDialogVisible,
setSendInviteDialogVisible,
setDeleteDialogVisible,
} = this.peopleStore.dialogStore;
const { isAdmin, isOwner } = this.authStore.userStore.user;
const { setVisible, isVisible } = this.peopleStore.infoPanelStore;
const options = [];
const adminOption = {
id: "context-menu_administrator",
className: "context-menu_drop-down",
label: t("Administrator"),
title: t("Administrator"),
onClick: (e) => onChangeType(e, t),
action: "admin",
key: "cm-administrator",
};
const managerOption = {
id: "context-menu_manager",
className: "context-menu_drop-down",
label: t("Manager"),
title: t("Manager"),
onClick: (e) => onChangeType(e, t),
action: "manager",
key: "cm-manager",
};
const userOption = {
id: "context-menu_user",
className: "context-menu_drop-down",
label: t("Common:User"),
title: t("Common:User"),
onClick: (e) => onChangeType(e, t),
action: "user",
key: "cm-user",
};
isOwner && options.push(adminOption);
isAdmin && options.push(managerOption);
options.push(userOption);
const headerMenu = [
{
key: "cm-change-type",
label: t("ChangeUserTypeDialog:ChangeUserTypeButton"),
disabled: (isAdmin || isOwner) && !hasUsersToMakeEmployees,
icon: "/static/images/change.to.employee.react.svg",
items: options,
},
{
key: "cm-info",
label: t("PeopleTranslations:Details"),
disabled: isVisible,
onClick: setVisible,
icon: "images/info.react.svg",
},
{
key: "cm-invite",
label: t("Common:Invite"),
disabled: !hasUsersToInvite,
onClick: () => setSendInviteDialogVisible(true),
icon: "/static/images/invite.again.react.svg",
},
{
key: "cm-enable",
label: t("Common:Enable"),
disabled: !hasUsersToActivate,
onClick: () => setActiveDialogVisible(true),
icon: "images/enable.react.svg",
},
{
key: "cm-disable",
label: t("PeopleTranslations:DisableUserButton"),
disabled: !hasUsersToDisable,
onClick: () => setDisableDialogVisible(true),
icon: "images/disable.react.svg",
},
{
key: "cm-delete",
label: t("Common:Delete"),
disabled: !hasUsersToRemove,
onClick: () => setDeleteDialogVisible(true),
icon: "/static/images/delete.react.svg",
},
];
return headerMenu;
};
getModel = (item, t) => {
const { selection } = this.peopleStore.selectionStore;
const { options } = item;
const contextOptionsProps =
options && options.length > 0
? selection.length > 1
? this.getUserGroupContextOptions(t)
: this.getUserContextOptions(t, options, item)
: [];
return contextOptionsProps;
};
onProfileClick = () => {
history.push(PROFILE_SELF_URL);
};
toggleChangeNameDialog = (item) => {
const { setDialogData, setChangeNameDialogVisible } = this.dialogStore;
const {
setDialogData,
setChangeNameDialogVisible,
} = this.peopleStore.dialogStore;
const { id, firstName, lastName } = item;
setDialogData({ id, firstName, lastName });
@ -169,7 +279,10 @@ class AccountsContextOptionsStore {
};
toggleChangeEmailDialog = (item) => {
const { setDialogData, setChangeEmailDialogVisible } = this.dialogStore;
const {
setDialogData,
setChangeEmailDialogVisible,
} = this.peopleStore.dialogStore;
const { id, email } = item;
setDialogData({
@ -181,7 +294,10 @@ class AccountsContextOptionsStore {
};
toggleChangePasswordDialog = (item) => {
const { setDialogData, setChangePasswordDialogVisible } = this.dialogStore;
const {
setDialogData,
setChangePasswordDialogVisible,
} = this.peopleStore.dialogStore;
const { email } = item;
setDialogData({
email,
@ -191,14 +307,14 @@ class AccountsContextOptionsStore {
};
toggleChangeOwnerDialog = () => {
const { setChangeOwnerDialogVisible } = this.dialogStore;
const { setChangeOwnerDialogVisible } = this.peopleStore.dialogStore;
setChangeOwnerDialogVisible(true);
};
onEnableClick = (t, item) => {
const { id } = item;
const { updateUserStatus } = this.usersStore;
const { updateUserStatus } = this.peopleStore.usersStore;
updateUserStatus(EmployeeStatus.Active, [id], true)
.then(() =>
@ -209,7 +325,7 @@ class AccountsContextOptionsStore {
onDisableClick = (t, item) => {
const { id } = item;
const { updateUserStatus } = this.usersStore;
const { updateUserStatus } = this.peopleStore.usersStore;
updateUserStatus(EmployeeStatus.Disabled, [id], true)
.then(() =>
@ -235,7 +351,10 @@ class AccountsContextOptionsStore {
};
toggleDeleteProfileEverDialog = (item) => {
const { setDialogData, setDeleteProfileDialogVisible } = this.dialogStore;
const {
setDialogData,
setDeleteProfileDialogVisible,
} = this.peopleStore.dialogStore;
const { id, displayName, userName } = item;
closeDialogs();
@ -250,7 +369,7 @@ class AccountsContextOptionsStore {
};
onDetailsClick = () => {
const { setVisible } = this.infoPanelStore;
const { setVisible } = this.peopleStore.infoPanelStore;
setVisible();
};
@ -272,10 +391,10 @@ class AccountsContextOptionsStore {
)
.catch((error) => toastr.error(error));
};
onResetAuth = (item) => {
console.log(item);
};
}
const onResetAuth = (item) => {
console.log(item);
};
export default AccountsContextOptionsStore;

View File

@ -54,14 +54,7 @@ class PeopleStore {
this.infoPanelStore = infoPanelStore;
this.setupStore = setupStore;
this.contextOptionsStore = new AccountsContextOptionsStore(
authStore,
this.dialogStore,
this.targetUserStore,
this.usersStore,
this.selectionStore,
this.infoPanelStore
);
this.contextOptionsStore = new AccountsContextOptionsStore(authStore, this);
makeAutoObservable(this);
}
@ -96,12 +89,12 @@ class PeopleStore {
return getUsersList(newFilter);
};
onChangeType = (e) => {
const action = e.target.dataset.action;
onChangeType = (e, t) => {
const action = e?.action ? e.action : e?.target?.dataset?.action;
const { getUsersToMakeEmployeesIds } = this.selectionStore;
this.changeType(action, getUsersToMakeEmployeesIds);
this.changeType(action, getUsersToMakeEmployeesIds, t);
};
changeType = (type, users, t, needClearSelection = true) => {
@ -159,7 +152,7 @@ class PeopleStore {
className: "group-menu_drop-down",
label: t("Administrator"),
title: t("Administrator"),
onClick: this.onChangeType,
onClick: (e) => this.onChangeType(e, t),
"data-action": "admin",
key: "administrator",
};
@ -168,7 +161,7 @@ class PeopleStore {
className: "group-menu_drop-down",
label: t("Manager"),
title: t("Manager"),
onClick: this.onChangeType,
onClick: (e) => this.onChangeType(e, t),
"data-action": "manager",
key: "manager",
};
@ -177,7 +170,7 @@ class PeopleStore {
className: "group-menu_drop-down",
label: t("Common:User"),
title: t("Common:User"),
onClick: this.onChangeType,
onClick: (e) => this.onChangeType(e, t),
"data-action": "user",
key: "user",
};
@ -190,6 +183,7 @@ class PeopleStore {
const headerMenu = [
{
key: "change-user",
label: t("ChangeUserTypeDialog:ChangeUserTypeButton"),
disabled: (isAdmin || isOwner) && !hasUsersToMakeEmployees,
iconUrl: "/static/images/change.to.employee.react.svg",
@ -197,30 +191,35 @@ class PeopleStore {
options: options,
},
{
key: "info",
label: t("PeopleTranslations:Details"),
disabled: isVisible,
onClick: setVisible,
iconUrl: "images/info.react.svg",
},
{
key: "invite",
label: t("Common:Invite"),
disabled: !hasUsersToInvite,
onClick: () => setSendInviteDialogVisible(true),
iconUrl: "/static/images/invite.again.react.svg",
},
{
key: "enable",
label: t("Common:Enable"),
disabled: !hasUsersToActivate,
onClick: () => setActiveDialogVisible(true),
iconUrl: "images/enable.react.svg",
},
{
key: "disable",
label: t("PeopleTranslations:DisableUserButton"),
disabled: !hasUsersToDisable,
onClick: () => setDisableDialogVisible(true),
iconUrl: "images/disable.react.svg",
},
{
key: "delete",
label: t("Common:Delete"),
disabled: !hasUsersToRemove,
onClick: () => setDeleteDialogVisible(true),