refactoring
This commit is contained in:
parent
5fda1f912a
commit
ce0e3ed344
@ -51,7 +51,8 @@ export default function withContent(WrappedContent) {
|
||||
itemIndex,
|
||||
} = props;
|
||||
|
||||
const { mobilePhone, email, role, displayName, avatar } = item;
|
||||
const { mobilePhone, email, displayName, avatar, isAdmin, isOwner } = item;
|
||||
const role = isOwner ? "owner" : isAdmin ? "admin" : null;
|
||||
|
||||
const onContentRowSelect = (checked, user) => {
|
||||
setBufferSelection(null);
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { Button } from "@docspace/shared/components/button";
|
||||
import { toastr } from "@docspace/shared/components/toast";
|
||||
@ -22,19 +23,19 @@ const Wrapper = styled.div`
|
||||
const AllSessionsBlock = (props) => {
|
||||
const {
|
||||
t,
|
||||
sessionData,
|
||||
removeAllActiveSessionsById,
|
||||
setSessionModalData,
|
||||
connections,
|
||||
setConnections,
|
||||
fetchData,
|
||||
removeAllActiveSessionsById,
|
||||
} = props;
|
||||
|
||||
const isDisabled = sessionData.length > 0;
|
||||
const isDisabled = connections.length > 0;
|
||||
|
||||
const onLogoutClick = async () => {
|
||||
try {
|
||||
await removeAllActiveSessionsById(sessionData[0]?.userId);
|
||||
await fetchData();
|
||||
setSessionModalData([]);
|
||||
await removeAllActiveSessionsById(connections[0]?.userId);
|
||||
fetchData();
|
||||
setConnections([]);
|
||||
toastr.success("Successfully logout all sessions");
|
||||
} catch (error) {
|
||||
toastr.error(error);
|
||||
@ -56,9 +57,19 @@ const AllSessionsBlock = (props) => {
|
||||
/>
|
||||
</Wrapper>
|
||||
|
||||
<RowWrapper t={t} sessionsData={sessionData} />
|
||||
<RowWrapper t={t} connections={connections} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default AllSessionsBlock;
|
||||
export default inject(({ setup, peopleStore }) => {
|
||||
const { removeAllActiveSessionsById } = setup;
|
||||
const { connections, setConnections, fetchData } = peopleStore.selectionStore;
|
||||
|
||||
return {
|
||||
connections,
|
||||
setConnections,
|
||||
fetchData,
|
||||
removeAllActiveSessionsById,
|
||||
};
|
||||
})(observer(AllSessionsBlock));
|
||||
|
@ -1,6 +1,41 @@
|
||||
import styled, { css } from "styled-components";
|
||||
import { observer, inject } from "mobx-react";
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { ContextMenuButton } from "@docspace/shared/components/context-menu-button";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import LogoutReactSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
|
||||
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
|
||||
|
||||
const StyledUserInfoBlock = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 20px 20px;
|
||||
|
||||
.username {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 13px;
|
||||
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 16px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 16px;
|
||||
`}
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledLastSessionBlock = styled.div`
|
||||
padding: 0px 20px;
|
||||
@ -61,48 +96,142 @@ const StyledLastSessionBlock = styled.div`
|
||||
`;
|
||||
|
||||
const LastSessionBlock = (props) => {
|
||||
const { t, sessionStatus, userData } = props;
|
||||
const { sessions } = userData;
|
||||
const {
|
||||
t,
|
||||
status,
|
||||
userLastSession,
|
||||
setDisplayName,
|
||||
setDisableDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
} = props;
|
||||
|
||||
const {
|
||||
avatar,
|
||||
displayName,
|
||||
sessions,
|
||||
isAdmin,
|
||||
isOwner,
|
||||
isRoomAdmin,
|
||||
isCollaborator,
|
||||
} = userLastSession;
|
||||
|
||||
const { platform, browser, ip, city, country } = sessions;
|
||||
|
||||
const isOnline = sessionStatus === "online";
|
||||
const isOnline = status === "online";
|
||||
|
||||
const getUserType = () => {
|
||||
if (isOwner) return t("Common:Owner");
|
||||
if (isAdmin) return t("Common:DocspaceAdmin");
|
||||
if (isRoomAdmin) return t("Common:RoomAdmin");
|
||||
if (isCollaborator) return t("Common:PowerUser");
|
||||
return t("Common:User");
|
||||
};
|
||||
|
||||
const role = isOwner ? "owner" : isAdmin ? "admin" : null;
|
||||
|
||||
const onClickLogout = () => {
|
||||
setLogoutAllDialogVisible(true);
|
||||
setDisplayName(displayName);
|
||||
};
|
||||
|
||||
const onClickDisable = () => {
|
||||
setDisableDialogVisible(true);
|
||||
};
|
||||
|
||||
const contextOptions = () => {
|
||||
return [
|
||||
{
|
||||
key: "LogoutAllSessions",
|
||||
label: t("Settings:LogoutAllSessions"),
|
||||
icon: LogoutReactSvgUrl,
|
||||
onClick: onClickLogout,
|
||||
},
|
||||
{
|
||||
key: "Separator",
|
||||
isSeparator: true,
|
||||
},
|
||||
{
|
||||
key: "Disable",
|
||||
label: t("Common:DisableUserButton"),
|
||||
icon: RemoveSvgUrl,
|
||||
onClick: onClickDisable,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledLastSessionBlock>
|
||||
<Text className="subtitle">{t("Profile:LastSession")}</Text>
|
||||
<Box className="session-info-wrapper">
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Active")}</Text>
|
||||
<Text className={isOnline ? "online" : "session-info-value"}>
|
||||
{t(`Common:${sessionStatus}`)}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Platform")}</Text>
|
||||
<Text className="session-info-value">{platform}</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Browser")}</Text>
|
||||
<Text className="session-info-value">
|
||||
{browser?.split(".")[0] ?? ""}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Location")}</Text>
|
||||
<Text className="session-info-value" truncate>
|
||||
{(country || city) && (
|
||||
<>
|
||||
{country}
|
||||
{country && city && ", "}
|
||||
{`${city} `}
|
||||
</>
|
||||
)}
|
||||
{ip}
|
||||
</Text>
|
||||
</div>
|
||||
</Box>
|
||||
</StyledLastSessionBlock>
|
||||
<>
|
||||
<StyledUserInfoBlock>
|
||||
<Box displayProp="flex" alignItems="center" justifyContent="center">
|
||||
<Avatar
|
||||
className="avatar"
|
||||
role={role}
|
||||
size="big"
|
||||
userName={displayName}
|
||||
source={avatar}
|
||||
/>
|
||||
<Box displayProp="flex" flexDirection="column">
|
||||
<Text className="username">{displayName}</Text>
|
||||
<span>{getUserType()}</span>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<ContextMenuButton
|
||||
id="user-session-info"
|
||||
className="context-button"
|
||||
getData={contextOptions}
|
||||
/>
|
||||
</StyledUserInfoBlock>
|
||||
|
||||
<StyledLastSessionBlock>
|
||||
<Text className="subtitle">{t("Profile:LastSession")}</Text>
|
||||
<Box className="session-info-wrapper">
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Active")}</Text>
|
||||
<Text className={isOnline ? "online" : "session-info-value"}>
|
||||
{t(`Common:${status}`)}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Platform")}</Text>
|
||||
<Text className="session-info-value">{platform}</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Browser")}</Text>
|
||||
<Text className="session-info-value">
|
||||
{browser?.split(".")[0] ?? ""}
|
||||
</Text>
|
||||
</div>
|
||||
<div className="session-info-row">
|
||||
<Text className="session-info-label">{t("Common:Location")}</Text>
|
||||
<Text className="session-info-value" truncate>
|
||||
{(country || city) && (
|
||||
<>
|
||||
{country}
|
||||
{country && city && ", "}
|
||||
{`${city} `}
|
||||
</>
|
||||
)}
|
||||
{ip}
|
||||
</Text>
|
||||
</div>
|
||||
</Box>
|
||||
</StyledLastSessionBlock>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default LastSessionBlock;
|
||||
export default inject(({ setup, peopleStore }) => {
|
||||
const { setDisableDialogVisible, setLogoutAllDialogVisible } = setup;
|
||||
|
||||
const { status, userLastSession, setDisplayName } =
|
||||
peopleStore.selectionStore;
|
||||
|
||||
return {
|
||||
status,
|
||||
userLastSession,
|
||||
setDisplayName,
|
||||
setDisableDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
};
|
||||
})(observer(LastSessionBlock));
|
||||
|
@ -1,116 +0,0 @@
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { Box } from "@docspace/shared/components/box";
|
||||
import { Text } from "@docspace/shared/components/text";
|
||||
import { ContextMenuButton } from "@docspace/shared/components/context-menu-button";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import LogoutReactSvgUrl from "PUBLIC_DIR/images/logout.react.svg?url";
|
||||
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
|
||||
|
||||
const StyledUserInfoBlock = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24px 20px 20px;
|
||||
|
||||
.username {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 13px;
|
||||
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 16px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 16px;
|
||||
`}
|
||||
}
|
||||
`;
|
||||
|
||||
const UserInfoBlock = (props) => {
|
||||
const {
|
||||
t,
|
||||
userData,
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setDisplayName,
|
||||
} = props;
|
||||
|
||||
const { avatar, displayName, isAdmin, isOwner, isRoomAdmin, isCollaborator } =
|
||||
userData;
|
||||
|
||||
const getUserType = () => {
|
||||
if (isOwner) return t("Common:Owner");
|
||||
if (isAdmin) return t("Common:DocspaceAdmin");
|
||||
if (isRoomAdmin) return t("Common:RoomAdmin");
|
||||
if (isCollaborator) return t("Common:PowerUser");
|
||||
return t("Common:User");
|
||||
};
|
||||
|
||||
const role = isOwner ? "owner" : isAdmin ? "admin" : null;
|
||||
|
||||
const onClickLogout = () => {
|
||||
setLogoutAllDialogVisible(true);
|
||||
setDisplayName(displayName);
|
||||
};
|
||||
|
||||
const onClickDisable = () => {
|
||||
setDisableDialogVisible(true);
|
||||
};
|
||||
|
||||
const contextOptions = () => {
|
||||
return [
|
||||
{
|
||||
key: "LogoutAllSessions",
|
||||
label: t("Settings:LogoutAllSessions"),
|
||||
icon: LogoutReactSvgUrl,
|
||||
onClick: onClickLogout,
|
||||
},
|
||||
{
|
||||
key: "Separator",
|
||||
isSeparator: true,
|
||||
},
|
||||
{
|
||||
key: "Disable",
|
||||
label: t("Common:DisableUserButton"),
|
||||
icon: RemoveSvgUrl,
|
||||
onClick: onClickDisable,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledUserInfoBlock>
|
||||
<Box displayProp="flex" alignItems="center" justifyContent="center">
|
||||
<Avatar
|
||||
className="avatar"
|
||||
role={role}
|
||||
size="big"
|
||||
userName={displayName}
|
||||
source={avatar}
|
||||
/>
|
||||
<Box displayProp="flex" flexDirection="column">
|
||||
<Text className="username">{displayName}</Text>
|
||||
<span>{getUserType()}</span>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<ContextMenuButton
|
||||
id="user-session-info"
|
||||
className="context-button"
|
||||
getData={contextOptions}
|
||||
/>
|
||||
</StyledUserInfoBlock>
|
||||
);
|
||||
};
|
||||
|
||||
export default UserInfoBlock;
|
@ -10,7 +10,6 @@ import { Scrollbar } from "@docspace/shared/components/scrollbar";
|
||||
|
||||
import AllSessionsBlock from "./AllSessionsBlock";
|
||||
import LastSessionBlock from "./LastSessionBlock";
|
||||
import UserInfoBlock from "./UserInfoBlock";
|
||||
|
||||
const StyledSessionsPanel = styled.div`
|
||||
.user-sessions-panel {
|
||||
@ -45,31 +44,9 @@ const StyledScrollbar = styled(Scrollbar)`
|
||||
`;
|
||||
|
||||
const UserSessionsPanel = (props) => {
|
||||
const {
|
||||
t,
|
||||
visible,
|
||||
setVisible,
|
||||
getUsersList,
|
||||
getUserSessionsById,
|
||||
setSessions,
|
||||
setAllSessions,
|
||||
} = props;
|
||||
const { t, visible, setVisible } = props;
|
||||
const scrollRef = useRef(null);
|
||||
|
||||
const fetchAndSetUserSessions = async () => {
|
||||
try {
|
||||
const users = await getUsersList();
|
||||
const sessionsPromises = users.map((user) =>
|
||||
getUserSessionsById(user.id),
|
||||
);
|
||||
const sessions = await Promise.all(sessionsPromises);
|
||||
setSessions(sessions);
|
||||
setAllSessions();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const onClose = () => {
|
||||
setVisible(false);
|
||||
};
|
||||
@ -94,47 +71,20 @@ const UserSessionsPanel = (props) => {
|
||||
</StyledHeaderContent>
|
||||
|
||||
<StyledScrollbar ref={scrollRef}>
|
||||
<UserInfoBlock {...props} />
|
||||
<LastSessionBlock {...props} />
|
||||
<AllSessionsBlock {...props} fetchData={fetchAndSetUserSessions} />
|
||||
<LastSessionBlock t={t} />
|
||||
<AllSessionsBlock t={t} />
|
||||
</StyledScrollbar>
|
||||
</Aside>
|
||||
</StyledSessionsPanel>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ setup, dialogsStore, peopleStore }) => {
|
||||
export default inject(({ dialogsStore }) => {
|
||||
const { userSessionsPanelVisible, setUserSessionPanelVisible } = dialogsStore;
|
||||
const { setSessions, setAllSessions } = peopleStore.selectionStore;
|
||||
const { getUsersList } = peopleStore.usersStore;
|
||||
|
||||
const {
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
userModalData,
|
||||
sessionModalData,
|
||||
setSessionModalData,
|
||||
setDisplayName,
|
||||
sessionStatus,
|
||||
removeAllActiveSessionsById,
|
||||
getUserSessionsById,
|
||||
} = setup;
|
||||
|
||||
return {
|
||||
userData: userModalData,
|
||||
sessionData: sessionModalData,
|
||||
setSessionModalData: setSessionModalData,
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
visible: userSessionsPanelVisible,
|
||||
setVisible: setUserSessionPanelVisible,
|
||||
setDisplayName,
|
||||
sessionStatus,
|
||||
removeAllActiveSessionsById,
|
||||
getUsersList,
|
||||
getUserSessionsById,
|
||||
setSessions,
|
||||
setAllSessions,
|
||||
};
|
||||
})(
|
||||
withTranslation(["Settings", "Profile", "Common"])(
|
||||
|
@ -11,16 +11,11 @@ const StyledRow = styled(Row)`
|
||||
`;
|
||||
|
||||
const SessionsRow = (props) => {
|
||||
const { item, sectionWidth, setLogoutDialogVisible, setPlatformModalData } =
|
||||
props;
|
||||
const { item, sectionWidth, setLogoutDialogVisible, setPlatformData } = props;
|
||||
|
||||
const onClickDisable = () => {
|
||||
setLogoutDialogVisible(true);
|
||||
setPlatformModalData({
|
||||
id: item.id,
|
||||
platform: item.platform,
|
||||
browser: item.browser,
|
||||
});
|
||||
setPlatformData(item);
|
||||
};
|
||||
|
||||
const contentElement = (
|
||||
@ -44,11 +39,14 @@ const SessionsRow = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ setup }) => {
|
||||
export default inject(({ setup, peopleStore }) => {
|
||||
const { platformData, setPlatformData } = peopleStore.selectionStore;
|
||||
const { setLogoutDialogVisible, setPlatformModalData } = setup;
|
||||
|
||||
return {
|
||||
setLogoutDialogVisible,
|
||||
setPlatformModalData,
|
||||
platformData,
|
||||
setPlatformData,
|
||||
};
|
||||
})(observer(SessionsRow));
|
||||
|
@ -7,18 +7,18 @@ const StyledRowContainer = styled(RowContainer)`
|
||||
`;
|
||||
|
||||
const RowView = (props) => {
|
||||
const { t, sectionWidth, sessionsData } = props;
|
||||
const { t, sectionWidth, connections } = props;
|
||||
|
||||
return (
|
||||
<StyledRowContainer
|
||||
useReactWindow={false}
|
||||
hasMoreFiles={false}
|
||||
itemHeight={58}
|
||||
itemCount={sessionsData.length}
|
||||
filesLength={sessionsData.length}
|
||||
itemCount={connections.length}
|
||||
filesLength={connections.length}
|
||||
fetchMoreFiles={() => {}}
|
||||
>
|
||||
{sessionsData.map((item) => (
|
||||
{connections.map((item) => (
|
||||
<SessionsRow
|
||||
t={t}
|
||||
key={item.id}
|
||||
|
@ -1,14 +1,14 @@
|
||||
import { Consumer } from "@docspace/shared/utils";
|
||||
import RowView from "./RowView";
|
||||
|
||||
const RowWrapper = ({ t, sessionsData }) => {
|
||||
const RowWrapper = ({ t, connections }) => {
|
||||
return (
|
||||
<Consumer>
|
||||
{(context) => (
|
||||
<RowView
|
||||
t={t}
|
||||
sectionWidth={context.sectionWidth}
|
||||
sessionsData={sessionsData}
|
||||
connections={connections}
|
||||
/>
|
||||
)}
|
||||
</Consumer>
|
||||
|
@ -362,8 +362,8 @@ const SectionHeaderContent = (props) => {
|
||||
setLogoutAllDialogVisible,
|
||||
isSeveralSelection,
|
||||
peopleSelection,
|
||||
setSessionModalData,
|
||||
setUserModalData,
|
||||
setConnections,
|
||||
setUserLastSession,
|
||||
setUserSessionPanelVisible,
|
||||
setDisplayName,
|
||||
} = props;
|
||||
@ -404,8 +404,8 @@ const SectionHeaderContent = (props) => {
|
||||
);
|
||||
|
||||
const onClickSessions = () => {
|
||||
setUserModalData(peopleSelection[0]);
|
||||
setSessionModalData(peopleSelection[0].connections);
|
||||
setUserLastSession(peopleSelection[0]);
|
||||
setConnections(peopleSelection[0].connections);
|
||||
setUserSessionPanelVisible(true);
|
||||
};
|
||||
|
||||
@ -561,9 +561,6 @@ export default inject(
|
||||
setDisableDialogVisible,
|
||||
setLogoutDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
setSessionModalData,
|
||||
setUserModalData,
|
||||
setDisplayName,
|
||||
} = setup;
|
||||
const {
|
||||
selected,
|
||||
@ -583,6 +580,9 @@ export default inject(
|
||||
setSelected: peopleSetSelected,
|
||||
isSeveralSelection,
|
||||
selection: peopleSelection,
|
||||
setConnections,
|
||||
setUserLastSession,
|
||||
setDisplayName,
|
||||
} = peopleStore.selectionStore;
|
||||
|
||||
const { admins, selectorIsOpen } = setup.security.accessRight;
|
||||
@ -616,9 +616,9 @@ export default inject(
|
||||
setDisableDialogVisible,
|
||||
setLogoutDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
setSessionModalData,
|
||||
setConnections,
|
||||
setUserSessionPanelVisible,
|
||||
setUserModalData,
|
||||
setUserLastSession,
|
||||
setDisplayName,
|
||||
};
|
||||
},
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { useCallback } from "react";
|
||||
import { Base } from "@docspace/shared/themes";
|
||||
import styled, { css } from "styled-components";
|
||||
import withContent from "SRC_DIR/HOCs/withPeopleContent";
|
||||
import moment from "moment-timezone";
|
||||
import withContent from "SRC_DIR/HOCs/withPeopleContent";
|
||||
|
||||
import { Avatar } from "@docspace/shared/components/avatar";
|
||||
import { TableRow } from "@docspace/shared/components/table";
|
||||
@ -118,6 +117,9 @@ const StyledTableRow = styled(TableRow)`
|
||||
.session-info {
|
||||
font-weight: 600;
|
||||
color: ${(props) => props.theme.profile.activeSessions.tableCellColor};
|
||||
::first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
@ -144,8 +146,7 @@ const SessionsTableRow = (props) => {
|
||||
const {
|
||||
t,
|
||||
item,
|
||||
locale,
|
||||
checkedProps,
|
||||
element,
|
||||
onContentRowSelect,
|
||||
onContentRowClick,
|
||||
isActive,
|
||||
@ -154,20 +155,21 @@ const SessionsTableRow = (props) => {
|
||||
sessionStatus,
|
||||
connections,
|
||||
sessions,
|
||||
isOwner,
|
||||
isAdmin,
|
||||
locale,
|
||||
checkedProps,
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setUserModalData,
|
||||
setSessionModalData,
|
||||
setUserLastSession,
|
||||
setConnections,
|
||||
setUserSessionPanelVisible,
|
||||
setDisplayName,
|
||||
setSessionStatus,
|
||||
setStatus,
|
||||
} = props;
|
||||
|
||||
const [fromDateAgo, setFromDateAgo] = useState("");
|
||||
|
||||
const { platform, browser, ip, city, country, status, date } = sessions;
|
||||
const role = isOwner ? "owner" : isAdmin ? "admin" : null;
|
||||
|
||||
const isChecked = checkedProps?.checked;
|
||||
const isOnline = sessionStatus === "online";
|
||||
const isOffline = status === "offline";
|
||||
@ -198,9 +200,9 @@ const SessionsTableRow = (props) => {
|
||||
};
|
||||
|
||||
const onClickSessions = () => {
|
||||
setSessionStatus(fromDateAgo);
|
||||
setUserModalData(item);
|
||||
setSessionModalData(connections);
|
||||
setStatus(fromDateAgo);
|
||||
setUserLastSession(item);
|
||||
setConnections(connections);
|
||||
setUserSessionPanelVisible(true);
|
||||
};
|
||||
|
||||
@ -283,14 +285,7 @@ const SessionsTableRow = (props) => {
|
||||
className="table-container_row-checkbox-wrapper"
|
||||
checked={isChecked}
|
||||
>
|
||||
<div className="table-container_element">
|
||||
<Avatar
|
||||
className="avatar"
|
||||
role={role}
|
||||
size={"min"}
|
||||
userName={displayName}
|
||||
/>
|
||||
</div>
|
||||
<div className="table-container_element">{element}</div>
|
||||
<Checkbox
|
||||
className="table-container_row-checkbox"
|
||||
isChecked={isChecked}
|
||||
@ -335,29 +330,26 @@ const SessionsTableRow = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ setup, dialogsStore, settingsStore, userStore }) => {
|
||||
const { setUserSessionPanelVisible } = dialogsStore;
|
||||
const { culture } = settingsStore;
|
||||
const { user } = userStore;
|
||||
const locale = (user && user.cultureName) || culture || "en";
|
||||
export default inject(
|
||||
({ setup, dialogsStore, settingsStore, userStore, peopleStore }) => {
|
||||
const { setUserSessionPanelVisible } = dialogsStore;
|
||||
const { setLogoutAllDialogVisible, setDisableDialogVisible } = setup;
|
||||
const { culture } = settingsStore;
|
||||
const { user } = userStore;
|
||||
const locale = (user && user.cultureName) || culture || "en";
|
||||
|
||||
const {
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setUserModalData,
|
||||
setSessionModalData,
|
||||
setDisplayName,
|
||||
setSessionStatus,
|
||||
} = setup;
|
||||
const { setUserLastSession, setConnections, setDisplayName, setStatus } =
|
||||
peopleStore.selectionStore;
|
||||
|
||||
return {
|
||||
locale,
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setUserModalData,
|
||||
setSessionModalData,
|
||||
setUserSessionPanelVisible,
|
||||
setDisplayName,
|
||||
setSessionStatus,
|
||||
};
|
||||
})(withContent(observer(SessionsTableRow)));
|
||||
return {
|
||||
locale,
|
||||
setLogoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setUserLastSession,
|
||||
setConnections,
|
||||
setUserSessionPanelVisible,
|
||||
setDisplayName,
|
||||
setStatus,
|
||||
};
|
||||
},
|
||||
)(withContent(observer(SessionsTableRow)));
|
||||
|
@ -170,8 +170,6 @@ const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
|
||||
sessionStatus={item.status}
|
||||
connections={item.connections}
|
||||
sessions={item.sessions}
|
||||
isOwner={item.isOwner}
|
||||
isAdmin={item.isAdmin}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
|
@ -11,7 +11,6 @@ import { Button } from "@docspace/shared/components/button";
|
||||
|
||||
import useViewEffect from "SRC_DIR/Hooks/useViewEffect";
|
||||
import SessionsTable from "./SessionsTable";
|
||||
// import mockData from "./mockData";
|
||||
|
||||
import {
|
||||
LogoutSessionDialog,
|
||||
@ -76,25 +75,28 @@ const DownLoadWrapper = styled.div`
|
||||
|
||||
const Sessions = ({
|
||||
t,
|
||||
allSessions,
|
||||
sessionsData,
|
||||
dataFromSocket,
|
||||
displayName,
|
||||
clearSelection,
|
||||
setDataFromSocket,
|
||||
connections,
|
||||
setConnections,
|
||||
updateAllSessions,
|
||||
platformData,
|
||||
fetchData,
|
||||
viewAs,
|
||||
setViewAs,
|
||||
socketHelper,
|
||||
currentDeviceType,
|
||||
setSessions,
|
||||
clearSelection,
|
||||
disableDialogVisible,
|
||||
logoutDialogVisible,
|
||||
logoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setLogoutDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
platformModalData,
|
||||
getUsersList,
|
||||
socketHelper,
|
||||
getUserSessionsById,
|
||||
displayName,
|
||||
allSessions,
|
||||
setAllSessions,
|
||||
setSessionsFromSocket,
|
||||
removeSession,
|
||||
}) => {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
@ -109,39 +111,26 @@ const Sessions = ({
|
||||
});
|
||||
|
||||
socketHelper.on("statuses-in-portal", (data) => {
|
||||
setSessionsFromSocket(data);
|
||||
setDataFromSocket(data);
|
||||
});
|
||||
}, [socketHelper]);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const users = await getUsersList();
|
||||
const sessionsPromises = users.map((user) =>
|
||||
getUserSessionsById(user.id),
|
||||
);
|
||||
const sessions = await Promise.all(sessionsPromises);
|
||||
setSessions(sessions);
|
||||
setAllSessions();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
|
||||
return () => {
|
||||
clearSelection();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
updateAllSessions(sessionsData, dataFromSocket);
|
||||
}, [sessionsData, dataFromSocket]);
|
||||
|
||||
useViewEffect({
|
||||
view: viewAs,
|
||||
setView: setViewAs,
|
||||
currentDeviceType,
|
||||
});
|
||||
|
||||
console.log(JSON.parse(JSON.stringify(allSessions)));
|
||||
|
||||
const onClickRemoveAllSessions = () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
@ -166,10 +155,27 @@ const Sessions = ({
|
||||
}
|
||||
};
|
||||
|
||||
const onClickRemoveSession = () => {
|
||||
const onClickRemoveSession = async (id) => {
|
||||
const foundConnection = connections.find(
|
||||
(connection) => connection.id === id,
|
||||
);
|
||||
|
||||
if (!foundConnection) return;
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
console.log("onClickRemoveSession");
|
||||
await removeSession(foundConnection.id);
|
||||
const filteredConnections = connections.filter(
|
||||
(connection) => connection.id !== id,
|
||||
);
|
||||
setConnections(filteredConnections);
|
||||
fetchData();
|
||||
toastr.success(
|
||||
t("Profile:SuccessLogout", {
|
||||
platform: foundConnection.platform,
|
||||
browser: foundConnection.browser,
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
toastr.error(error);
|
||||
} finally {
|
||||
@ -178,6 +184,10 @@ const Sessions = ({
|
||||
}
|
||||
};
|
||||
|
||||
// console.log("allSessions", JSON.parse(JSON.stringify(allSessions)));
|
||||
// console.log("sessionsData", JSON.parse(JSON.stringify(sessionsData)));
|
||||
// console.log("connections", JSON.parse(JSON.stringify(connections)));
|
||||
|
||||
return (
|
||||
<MainContainer>
|
||||
<Text className="subtitle">{t("SessionsSubtitle")}</Text>
|
||||
@ -211,7 +221,7 @@ const Sessions = ({
|
||||
<LogoutSessionDialog
|
||||
t={t}
|
||||
visible={logoutDialogVisible}
|
||||
data={platformModalData}
|
||||
data={platformData}
|
||||
isLoading={isLoading}
|
||||
onClose={() => setLogoutDialogVisible(false)}
|
||||
onRemoveSession={onClickRemoveSession}
|
||||
@ -235,13 +245,18 @@ const Sessions = ({
|
||||
|
||||
export default inject(({ settingsStore, setup, peopleStore }) => {
|
||||
const { socketHelper, currentDeviceType } = settingsStore;
|
||||
const { getUsersList } = peopleStore.usersStore;
|
||||
const {
|
||||
clearSelection,
|
||||
allSessions,
|
||||
setSessions,
|
||||
setAllSessions,
|
||||
setSessionsFromSocket,
|
||||
sessionsData,
|
||||
dataFromSocket,
|
||||
displayName,
|
||||
clearSelection,
|
||||
setDataFromSocket,
|
||||
connections,
|
||||
setConnections,
|
||||
updateAllSessions,
|
||||
platformData,
|
||||
fetchData,
|
||||
} = peopleStore.selectionStore;
|
||||
|
||||
const {
|
||||
@ -253,31 +268,32 @@ export default inject(({ settingsStore, setup, peopleStore }) => {
|
||||
setDisableDialogVisible,
|
||||
setLogoutDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
platformModalData,
|
||||
getUserSessionsById,
|
||||
displayName,
|
||||
removeSession,
|
||||
} = setup;
|
||||
|
||||
return {
|
||||
currentDeviceType,
|
||||
allSessions,
|
||||
sessionsData,
|
||||
dataFromSocket,
|
||||
displayName,
|
||||
clearSelection,
|
||||
setDataFromSocket,
|
||||
connections,
|
||||
setConnections,
|
||||
updateAllSessions,
|
||||
platformData,
|
||||
fetchData,
|
||||
viewAs,
|
||||
setViewAs,
|
||||
allSessions,
|
||||
setSessions,
|
||||
clearSelection,
|
||||
socketHelper,
|
||||
currentDeviceType,
|
||||
disableDialogVisible,
|
||||
logoutDialogVisible,
|
||||
logoutAllDialogVisible,
|
||||
setDisableDialogVisible,
|
||||
setLogoutDialogVisible,
|
||||
setLogoutAllDialogVisible,
|
||||
platformModalData,
|
||||
socketHelper,
|
||||
getUsersList,
|
||||
getUserSessionsById,
|
||||
displayName,
|
||||
setAllSessions,
|
||||
setSessionsFromSocket,
|
||||
removeSession,
|
||||
};
|
||||
})(
|
||||
withTranslation(["Settings", "Profile", "Common", "ChangeUserStatusDialog"])(
|
||||
|
@ -24,15 +24,21 @@
|
||||
// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import { makeAutoObservable, runInAction } from "mobx";
|
||||
import api from "@docspace/shared/api";
|
||||
import { EmployeeStatus } from "@docspace/shared/enums";
|
||||
import { getUserStatus } from "../helpers/people-helpers";
|
||||
|
||||
class SelectionStore {
|
||||
peopleStore = null;
|
||||
allSessions = [];
|
||||
sessions = [];
|
||||
sessionsFromSocket = [];
|
||||
sessionsData = [];
|
||||
dataFromSocket = [];
|
||||
displayName = "";
|
||||
status = "";
|
||||
connections = [];
|
||||
platformData = [];
|
||||
userLastSession = [];
|
||||
selection = [];
|
||||
selectionUsersRights = {
|
||||
isVisitor: 0,
|
||||
@ -261,7 +267,7 @@ class SelectionStore {
|
||||
setSelected = (selected, isSessionsPage) => {
|
||||
this.bufferSelection = null;
|
||||
this.selected = selected;
|
||||
const sessions = this.sessions;
|
||||
const sessions = this.sessionsData;
|
||||
const list = this.peopleStore.usersStore.peopleList;
|
||||
|
||||
if (selected !== "none" && selected !== "close") {
|
||||
@ -426,45 +432,90 @@ class SelectionStore {
|
||||
|
||||
get isHeaderIndeterminate() {
|
||||
return (
|
||||
this.isHeaderVisible && this.selection.length !== this.sessions.length
|
||||
this.isHeaderVisible && this.selection.length !== this.sessionsData.length
|
||||
);
|
||||
}
|
||||
|
||||
get isHeaderChecked() {
|
||||
return (
|
||||
this.isHeaderVisible && this.selection.length === this.sessions.length
|
||||
this.isHeaderVisible && this.selection.length === this.sessionsData.length
|
||||
);
|
||||
}
|
||||
|
||||
setSessions = (sessions) => {
|
||||
this.sessions = sessions;
|
||||
setAllSessions = (allSessions) => {
|
||||
this.allSessions = allSessions;
|
||||
};
|
||||
|
||||
setSessionsFromSocket = (data) => {
|
||||
this.sessionsFromSocket = data;
|
||||
setSessionsData = (data) => {
|
||||
this.sessionsData = data;
|
||||
};
|
||||
|
||||
setAllSessions = () => {
|
||||
setDataFromSocket = (data) => {
|
||||
this.dataFromSocket = data;
|
||||
};
|
||||
|
||||
setDisplayName = (displayName) => {
|
||||
this.displayName = displayName;
|
||||
};
|
||||
|
||||
setStatus = (status) => {
|
||||
this.status = status;
|
||||
};
|
||||
|
||||
setConnections = (connections) => {
|
||||
this.connections = connections;
|
||||
};
|
||||
|
||||
setUserLastSession = (userLastSession) => {
|
||||
this.userLastSession = userLastSession;
|
||||
};
|
||||
|
||||
setPlatformData = (data) => {
|
||||
this.platformData = data;
|
||||
};
|
||||
|
||||
updateAllSessions = (sessions, dataFromSocket) => {
|
||||
const socketDataMap = new Map(
|
||||
this.sessionsFromSocket.map((user) => [user.id, user]),
|
||||
dataFromSocket.map((user) => [user.id, user]),
|
||||
);
|
||||
|
||||
const filteredSessions = this.sessions.filter((session) => {
|
||||
const filteredSessions = sessions.filter((session) => {
|
||||
const socketData = socketDataMap.get(session.id);
|
||||
return (
|
||||
socketData && socketData.sessions && socketData.sessions.length > 0
|
||||
);
|
||||
});
|
||||
|
||||
this.allSessions = filteredSessions.map((session) => {
|
||||
const newAllSessions = filteredSessions.map((session) => {
|
||||
const socketData = socketDataMap.get(session.id);
|
||||
console.log("allSessions", this.sessions);
|
||||
return {
|
||||
...session,
|
||||
status: socketData ? socketData.status : "offline",
|
||||
sessions: socketData ? socketData.sessions.slice(-1)[0] : [],
|
||||
};
|
||||
});
|
||||
|
||||
runInAction(() => {
|
||||
this.setAllSessions(newAllSessions);
|
||||
});
|
||||
};
|
||||
|
||||
getUserSessionsById = (userId) => {
|
||||
return api.settings.getUserSessionsById(userId);
|
||||
};
|
||||
|
||||
fetchData = async () => {
|
||||
const { getUsersList } = this.peopleStore.usersStore;
|
||||
try {
|
||||
const users = await getUsersList();
|
||||
const sessionsPromises = users.map((user) =>
|
||||
this.getUserSessionsById(user.id),
|
||||
);
|
||||
const sessions = await Promise.all(sessionsPromises);
|
||||
this.setSessionsData(sessions);
|
||||
this.updateAllSessions(sessions, this.dataFromSocket);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -107,13 +107,9 @@ class SettingsSetupStore {
|
||||
|
||||
securityLifetime = [];
|
||||
|
||||
sessionStatus = "";
|
||||
displayName = "";
|
||||
sessionsIsInit = false;
|
||||
sessions = [];
|
||||
currentSession = [];
|
||||
sessionModalData = [];
|
||||
userModalData = [];
|
||||
platformModalData = {};
|
||||
|
||||
constructor(tfaStore, authStore, settingsStore, thirdPartyStore) {
|
||||
@ -557,10 +553,6 @@ class SettingsSetupStore {
|
||||
return api.settings.getAllActiveSessions();
|
||||
};
|
||||
|
||||
getUserSessionsById = (userId) => {
|
||||
return api.settings.getUserSessionsById(userId);
|
||||
};
|
||||
|
||||
removeAllActiveSessionsById = (userId) => {
|
||||
return api.settings.removeAllActiveSessionsById(userId);
|
||||
};
|
||||
@ -602,14 +594,6 @@ class SettingsSetupStore {
|
||||
this.sessions = sessions;
|
||||
};
|
||||
|
||||
setSessionModalData = (data) => {
|
||||
this.sessionModalData = data;
|
||||
};
|
||||
|
||||
setUserModalData = (data) => {
|
||||
this.userModalData = data;
|
||||
};
|
||||
|
||||
setPlatformModalData = (data) => {
|
||||
this.platformModalData = {
|
||||
id: data.id,
|
||||
@ -617,14 +601,6 @@ class SettingsSetupStore {
|
||||
browser: data.browser,
|
||||
};
|
||||
};
|
||||
|
||||
setDisplayName = (name) => {
|
||||
this.displayName = name;
|
||||
};
|
||||
|
||||
setSessionStatus = (status) => {
|
||||
this.sessionStatus = status;
|
||||
};
|
||||
}
|
||||
|
||||
export default SettingsSetupStore;
|
||||
|
Loading…
Reference in New Issue
Block a user