added table group menu for tablet view
This commit is contained in:
parent
5204c566cd
commit
9f4f4e08ab
@ -4,7 +4,7 @@ import { inject, observer } from "mobx-react";
|
||||
import TableHeader from "@docspace/components/table-container/TableHeader";
|
||||
|
||||
const TABLE_VERSION = "5";
|
||||
const TABLE_COLUMNS = `GoogleWorkspaceColumns_ver-${TABLE_VERSION}`;
|
||||
const TABLE_COLUMNS = `SessionsColumns_ver-${TABLE_VERSION}`;
|
||||
|
||||
const getColumns = (defaultColumns, userId) => {
|
||||
const storageColumns = localStorage.getItem(`${TABLE_COLUMNS}=${userId}`);
|
||||
@ -30,10 +30,10 @@ const SessionsTableHeader = (props) => {
|
||||
t,
|
||||
userId,
|
||||
sectionWidth,
|
||||
setHideColumns,
|
||||
tableRef,
|
||||
columnStorageName,
|
||||
columnInfoPanelStorageName,
|
||||
setHideColumns,
|
||||
} = props;
|
||||
|
||||
const defaultColumns = [
|
||||
@ -45,11 +45,6 @@ const SessionsTableHeader = (props) => {
|
||||
default: true,
|
||||
active: true,
|
||||
minWidth: 180,
|
||||
// checkbox: {
|
||||
// value: isChecked,
|
||||
// isIndeterminate,
|
||||
// onChange: toggleAll,
|
||||
// },
|
||||
onChange: onColumnChange,
|
||||
},
|
||||
{
|
||||
@ -76,7 +71,7 @@ const SessionsTableHeader = (props) => {
|
||||
{
|
||||
key: "IpAddress",
|
||||
title: t("Common:IpAddress"),
|
||||
enable: true,
|
||||
enable: false,
|
||||
resizable: true,
|
||||
onChange: onColumnChange,
|
||||
},
|
||||
@ -84,6 +79,10 @@ const SessionsTableHeader = (props) => {
|
||||
|
||||
const [columns, setColumns] = useState(getColumns(defaultColumns, userId));
|
||||
|
||||
useEffect(() => {
|
||||
setColumns(getColumns(defaultColumns));
|
||||
}, []);
|
||||
|
||||
function onColumnChange(key, e) {
|
||||
const columnIndex = columns.findIndex((c) => c.key === key);
|
||||
|
||||
@ -99,10 +98,6 @@ const SessionsTableHeader = (props) => {
|
||||
localStorage.setItem(`${TABLE_COLUMNS}=${userId}`, tableColumns);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setColumns(getColumns(defaultColumns));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<TableHeader
|
||||
checkboxSize="48px"
|
||||
@ -120,8 +115,4 @@ const SessionsTableHeader = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
return {
|
||||
userId: auth.userStore.user.id,
|
||||
};
|
||||
})(observer(SessionsTableHeader));
|
||||
export default SessionsTableHeader;
|
||||
|
@ -1,25 +1,45 @@
|
||||
import { useRef } from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
import TableRow from "@docspace/components/table-container/TableRow";
|
||||
import TableCell from "@docspace/components/table-container/TableCell";
|
||||
import Text from "@docspace/components/text";
|
||||
import Avatar from "@docspace/components/avatar";
|
||||
import Checkbox from "@docspace/components/checkbox";
|
||||
|
||||
import HistoryFinalizedReactSvgUrl from "PUBLIC_DIR/images/history-finalized.react.svg?url";
|
||||
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
|
||||
import TrashReactSvgUrl from "PUBLIC_DIR/images/trash.react.svg?url";
|
||||
|
||||
import styled, { css } from "styled-components";
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
.table-container_cell {
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.table-container_row-checkbox {
|
||||
padding: 16px 8px 16px 12px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 6px;
|
||||
margin-left: 8px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 6px;
|
||||
margin-right: 8px;
|
||||
`}
|
||||
}
|
||||
|
||||
.session-info {
|
||||
font-weight: 600;
|
||||
color: #a3a9ae;
|
||||
}
|
||||
|
||||
.session-online {
|
||||
font-weight: 600;
|
||||
color: #35ad17;
|
||||
}
|
||||
`;
|
||||
|
||||
const SessionsTableRow = ({
|
||||
@ -33,9 +53,12 @@ const SessionsTableRow = ({
|
||||
country,
|
||||
city,
|
||||
ip,
|
||||
userId,
|
||||
hideColumns,
|
||||
isChecked,
|
||||
toggleSession,
|
||||
}) => {
|
||||
const tableRef = useRef();
|
||||
|
||||
const contextOptions = [
|
||||
{
|
||||
key: "ViewSessions",
|
||||
@ -61,13 +84,23 @@ const SessionsTableRow = ({
|
||||
},
|
||||
];
|
||||
|
||||
const handleSessionToggle = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
tableRef.current?.contains(e.target) || toggleSession(e);
|
||||
};
|
||||
|
||||
const isOnline = status === "Online";
|
||||
|
||||
return (
|
||||
<StyledTableRow
|
||||
onClick={() => console.log("selected row")}
|
||||
contextOptions={contextOptions}
|
||||
hideColumns={hideColumns}
|
||||
contextOptions={contextOptions}
|
||||
checked={isChecked}
|
||||
onClick={handleSessionToggle}
|
||||
>
|
||||
<TableCell>
|
||||
<TableCell hasAccess={true}>
|
||||
<div className="table-container_element">
|
||||
<Avatar
|
||||
className="avatar"
|
||||
userName={displayName}
|
||||
@ -75,25 +108,45 @@ const SessionsTableRow = ({
|
||||
source={avatar}
|
||||
size={"small"}
|
||||
/>
|
||||
<Text>{displayName}</Text>
|
||||
</div>
|
||||
|
||||
<Checkbox
|
||||
className="table-container_row-checkbox"
|
||||
isChecked={isChecked}
|
||||
onChange={handleSessionToggle}
|
||||
/>
|
||||
|
||||
<Text fontWeight="600">{displayName}</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text>{status}</Text>
|
||||
<Text className={isOnline ? "session-online" : "session-info"} truncate>
|
||||
{status}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text>{platform}, </Text>
|
||||
<Text>{browser}</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{platform},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{browser}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text>{country}, </Text>
|
||||
<Text>{city}</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{country},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{city}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text>{ip}</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{ip}
|
||||
</Text>
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
);
|
||||
|
@ -5,13 +5,47 @@ import styled, { css } from "styled-components";
|
||||
|
||||
import SessionsTableHeader from "./SessionsTableHeader";
|
||||
import SessionsTableRow from "./SessionsTableRow";
|
||||
|
||||
import HistoryFinalizedReactSvgUrl from "PUBLIC_DIR/images/history-finalized.react.svg?url";
|
||||
import RemoveSvgUrl from "PUBLIC_DIR/images/remove.session.svg?url";
|
||||
import TrashReactSvgUrl from "PUBLIC_DIR/images/trash.react.svg?url";
|
||||
|
||||
import TableContainer from "@docspace/components/table-container/TableContainer";
|
||||
import TableGroupMenu from "@docspace/components/table-container/TableGroupMenu";
|
||||
import TableBody from "@docspace/components/table-container/TableBody";
|
||||
|
||||
const StyledTableContainer = styled(TableContainer)`
|
||||
margin: 0 0 24px;
|
||||
|
||||
.table-group-menu {
|
||||
height: 69px;
|
||||
position: absolute;
|
||||
z-index: 201;
|
||||
top: 0;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
|
||||
.table-container_group-menu {
|
||||
border-image-slice: 0;
|
||||
border-image-source: none;
|
||||
border-bottom: ${(props) =>
|
||||
props.theme.filesSection.tableView.row.borderColor};
|
||||
box-shadow: rgba(4, 15, 27, 0.07) 0px 15px 20px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.table-container_group-menu-separator {
|
||||
margin: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-container_header {
|
||||
position: absolute;
|
||||
padding: 0px 20px;
|
||||
}
|
||||
|
||||
.header-container-text {
|
||||
color: #a3a9ae;
|
||||
font-size: ${(props) => props.theme.getCorrectFontSize("12px")};
|
||||
}
|
||||
|
||||
@ -59,30 +93,91 @@ const StyledTableContainer = styled(TableContainer)`
|
||||
|
||||
StyledTableContainer.defaultProps = { theme: Base };
|
||||
|
||||
const TABLE_VERSION = "6";
|
||||
const TABLE_VERSION = "5";
|
||||
const COLUMNS_SIZE = `sessionsColumnsSize_ver-${TABLE_VERSION}`;
|
||||
const INFO_PANEL_COLUMNS_SIZE = `infoPanelSessionsColumnsSize_ver-${TABLE_VERSION}`;
|
||||
|
||||
const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
|
||||
const TableView = ({
|
||||
t,
|
||||
sectionWidth,
|
||||
userId,
|
||||
sessionsData,
|
||||
allSessions,
|
||||
checkedSessions,
|
||||
toggleSession,
|
||||
toggleAllSessions,
|
||||
isSessionChecked,
|
||||
}) => {
|
||||
const [hideColumns, setHideColumns] = useState(false);
|
||||
const tableRef = useRef(null);
|
||||
|
||||
const handleToggle = (e, id) => {
|
||||
e.stopPropagation();
|
||||
toggleSession(id);
|
||||
};
|
||||
|
||||
const handleAllToggles = (checked) => {
|
||||
toggleAllSessions(checked, allSessions);
|
||||
};
|
||||
|
||||
const columnStorageName = `${COLUMNS_SIZE}=${userId}`;
|
||||
const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`;
|
||||
|
||||
const headerMenu = [
|
||||
{
|
||||
id: "sessions",
|
||||
key: "Sessions",
|
||||
label: t("Common:Sessions"),
|
||||
onClick: () => console.log("Sessions"),
|
||||
iconUrl: HistoryFinalizedReactSvgUrl,
|
||||
},
|
||||
{
|
||||
id: "logout",
|
||||
key: "Logout",
|
||||
label: t("Common:Logout"),
|
||||
onClick: () => console.log("Logout"),
|
||||
iconUrl: RemoveSvgUrl,
|
||||
},
|
||||
{
|
||||
id: "Disable",
|
||||
key: "Disable",
|
||||
label: t("Common:DisableUserButton"),
|
||||
onClick: () => console.log("Disable"),
|
||||
iconUrl: TrashReactSvgUrl,
|
||||
},
|
||||
];
|
||||
|
||||
const isChecked = checkedSessions.length === allSessions.length;
|
||||
|
||||
const isIndeterminate =
|
||||
checkedSessions.length > 0 && checkedSessions.length !== allSessions.length;
|
||||
|
||||
return (
|
||||
<StyledTableContainer forwardedRef={tableRef} useReactWindow>
|
||||
{checkedSessions.length > 0 && (
|
||||
<div className="table-group-menu">
|
||||
<TableGroupMenu
|
||||
sectionWidth={sectionWidth}
|
||||
headerMenu={headerMenu}
|
||||
withoutInfoPanelToggler
|
||||
withComboBox={false}
|
||||
checkboxOptions={[]}
|
||||
isChecked={isChecked}
|
||||
isIndeterminate={isIndeterminate}
|
||||
onChange={handleAllToggles}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<SessionsTableHeader
|
||||
t={t}
|
||||
sectionWidth={sectionWidth}
|
||||
tableRef={tableRef}
|
||||
setHideColumns={setHideColumns}
|
||||
userId={userId}
|
||||
tableRef={tableRef}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
setHideColumns={setHideColumns}
|
||||
// isIndeterminate={isIndeterminate}
|
||||
// isChecked={checkedUsers.withEmail.length === withEmailUsers.length}
|
||||
// toggleAll={toggleAll}
|
||||
isChecked={isChecked}
|
||||
isIndeterminate={isIndeterminate}
|
||||
/>
|
||||
<TableBody
|
||||
itemHeight={49}
|
||||
@ -98,7 +193,7 @@ const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
|
||||
{sessionsData.map((session) => (
|
||||
<SessionsTableRow
|
||||
t={t}
|
||||
key={session.id}
|
||||
key={session.userId}
|
||||
avatar={session.avatar}
|
||||
displayName={session.displayName}
|
||||
status={session.status}
|
||||
@ -107,10 +202,9 @@ const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
|
||||
country={session.country}
|
||||
city={session.city}
|
||||
ip={session.ip}
|
||||
userId={session.userId}
|
||||
hideColumns={hideColumns}
|
||||
// isChecked={isAccountChecked(data.key, checkedAccountType)}
|
||||
// toggleAccount={(e) => handleToggle(e, data)}
|
||||
isChecked={isSessionChecked(session.userId)}
|
||||
toggleSession={(e) => handleToggle(e, session.userId)}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
@ -118,10 +212,22 @@ const TableView = ({ t, sectionWidth, userId, sessionsData }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
export default inject(({ auth, setup }) => {
|
||||
const { id: userId } = auth.userStore.user;
|
||||
const {
|
||||
allSessions,
|
||||
checkedSessions,
|
||||
toggleSession,
|
||||
toggleAllSessions,
|
||||
isSessionChecked,
|
||||
} = setup;
|
||||
|
||||
return {
|
||||
userId,
|
||||
allSessions,
|
||||
checkedSessions,
|
||||
toggleSession,
|
||||
toggleAllSessions,
|
||||
isSessionChecked,
|
||||
};
|
||||
})(observer(TableView));
|
||||
|
@ -1,82 +0,0 @@
|
||||
const allSessionsData = [
|
||||
{
|
||||
id: 1,
|
||||
avatar: "",
|
||||
displayName: "Ilya Genkin",
|
||||
status: "Online",
|
||||
platform: "Windows 10",
|
||||
browser: "Chrome 120",
|
||||
country: "Russia",
|
||||
city: "Kstovo",
|
||||
date: "2023-12-26T17:13:28+00:00",
|
||||
ip: "172.18.0.1",
|
||||
mobile: false,
|
||||
page: "http://192.168.0.239/wizard",
|
||||
tenantId: 1,
|
||||
userId: "66faa6e4-f133-11ea-b126-00ffeec8b4ef",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
avatar: "",
|
||||
displayName: "Timur Aliev",
|
||||
status: "Online",
|
||||
platform: "Mac OS 14.1.2",
|
||||
browser: "Safari 17",
|
||||
country: "Uzbekistan",
|
||||
city: "Tashkent",
|
||||
date: "2023-12-26T17:13:28+00:00",
|
||||
ip: "172.19.0.1",
|
||||
mobile: false,
|
||||
page: "http://192.168.0.239/wizard",
|
||||
tenantId: 1,
|
||||
userId: "66faa6e4-f133-11ea-b126-00ffeec8b4ea",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
avatar: "",
|
||||
displayName: "Aleksei Safronov",
|
||||
status: "8 minutes ago",
|
||||
platform: "Windows 10",
|
||||
browser: "Chrome 119",
|
||||
country: "Armenia",
|
||||
city: "Yerevan",
|
||||
date: "2023-12-26T17:13:28+00:00",
|
||||
ip: "172.20.0.1",
|
||||
mobile: false,
|
||||
page: "http://192.168.0.239/wizard",
|
||||
tenantId: 1,
|
||||
userId: "66faa6e4-f133-11ea-b126-00ffeec8b4eb",
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
displayName: "Dmitry Vanyukov",
|
||||
status: "3 hours ago",
|
||||
platform: "Mac OS 14.1.2",
|
||||
browser: "Safari 15",
|
||||
country: "Russia",
|
||||
city: "Kuznechikha",
|
||||
date: "2023-12-26T17:13:28+00:00",
|
||||
ip: "172.21.0.1",
|
||||
mobile: false,
|
||||
page: "http://192.168.0.239/wizard",
|
||||
tenantId: 1,
|
||||
userId: "66faa6e4-f133-11ea-b126-00ffeec8b4ec",
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
displayName: "Elizabeth Rayen",
|
||||
status: "Yesterday, 5:12 PM",
|
||||
platform: "Mac OS X 10",
|
||||
browser: "Chrome 119",
|
||||
country: "Germany",
|
||||
city: " Frankfurt",
|
||||
date: "2023-12-26T17:13:28+00:00",
|
||||
ip: "172.22.0.1",
|
||||
mobile: false,
|
||||
page: "http://192.168.0.239/wizard",
|
||||
tenantId: 1,
|
||||
userId: "66faa6e4-f133-11ea-b126-00ffeec8b4ed",
|
||||
},
|
||||
];
|
||||
|
||||
export default allSessionsData;
|
@ -1,11 +1,13 @@
|
||||
import { useEffect } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { mobile, tablet } from "@docspace/components/utils/device";
|
||||
import styled from "styled-components";
|
||||
|
||||
import { MainContainer } from "../StyledSecurity";
|
||||
import useViewEffect from "SRC_DIR/Hooks/useViewEffect";
|
||||
import SessionsTable from "./SessionsTable";
|
||||
import allSessionsData from "./allSessionsData";
|
||||
import styled from "styled-components";
|
||||
import mockData from "./mockData";
|
||||
|
||||
import Text from "@docspace/components/text";
|
||||
import Button from "@docspace/components/button";
|
||||
@ -69,8 +71,14 @@ const Sessions = ({
|
||||
viewAs,
|
||||
setViewAs,
|
||||
currentDeviceType,
|
||||
allSessions,
|
||||
setAllSessions,
|
||||
isLoadingDownloadReport,
|
||||
}) => {
|
||||
useEffect(() => {
|
||||
setAllSessions(mockData);
|
||||
}, []);
|
||||
|
||||
useViewEffect({
|
||||
view: viewAs,
|
||||
setView: setViewAs,
|
||||
@ -81,7 +89,7 @@ const Sessions = ({
|
||||
<MainContainer>
|
||||
<Text className="subtitle">{t("SessionsSubtitle")}</Text>
|
||||
|
||||
<SessionsTable t={t} sessionsData={allSessionsData} />
|
||||
<SessionsTable t={t} sessionsData={allSessions} />
|
||||
|
||||
<DownLoadWrapper>
|
||||
<Button
|
||||
@ -104,14 +112,22 @@ const Sessions = ({
|
||||
export default inject(({ auth, setup }) => {
|
||||
const { culture, currentDeviceType } = auth.settingsStore;
|
||||
const { user } = auth.userStore;
|
||||
const { viewAs, setViewAs, isLoadingDownloadReport } = setup;
|
||||
const locale = (user && user.cultureName) || culture || "en";
|
||||
const {
|
||||
viewAs,
|
||||
setViewAs,
|
||||
allSessions,
|
||||
setAllSessions,
|
||||
isLoadingDownloadReport,
|
||||
} = setup;
|
||||
|
||||
return {
|
||||
locale,
|
||||
viewAs,
|
||||
setViewAs,
|
||||
currentDeviceType,
|
||||
allSessions,
|
||||
setAllSessions,
|
||||
isLoadingDownloadReport,
|
||||
};
|
||||
})(withTranslation(["Settings", "Common"])(observer(Sessions)));
|
||||
|
@ -78,6 +78,8 @@ class SettingsSetupStore {
|
||||
securityLifetime = [];
|
||||
|
||||
sessionsIsInit = false;
|
||||
allSessions = [];
|
||||
checkedSessions = [];
|
||||
sessions = [];
|
||||
currentSession = [];
|
||||
|
||||
@ -182,6 +184,22 @@ class SettingsSetupStore {
|
||||
this.integration.consumers = consumers;
|
||||
};
|
||||
|
||||
setAllSessions = (sessions) => {
|
||||
this.allSessions = sessions;
|
||||
};
|
||||
|
||||
toggleSession = (id) => {
|
||||
this.checkedSessions = this.checkedSessions.includes(id)
|
||||
? this.checkedSessions.filter((itemId) => itemId !== id)
|
||||
: [...this.checkedSessions, id];
|
||||
};
|
||||
|
||||
toggleAllSessions = (checked, sessions) => {
|
||||
this.checkedSessions = checked ? sessions.map((data) => data.userId) : [];
|
||||
};
|
||||
|
||||
isSessionChecked = (userId) => this.checkedSessions.includes(userId);
|
||||
|
||||
get isSMTPInitialSettings() {
|
||||
const settings = this.integration.smtpSettings.settings;
|
||||
const initialSettings = this.integration.smtpSettings.initialSettings;
|
||||
|
Loading…
Reference in New Issue
Block a user