fix selection in table view
This commit is contained in:
parent
604087db5a
commit
6eda31a9a2
@ -1,5 +1,4 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { inject, observer } from "mobx-react";
|
||||
|
||||
import TableHeader from "@docspace/components/table-container/TableHeader";
|
||||
|
||||
@ -31,7 +30,7 @@ const SessionsTableHeader = (props) => {
|
||||
userId,
|
||||
sectionWidth,
|
||||
setHideColumns,
|
||||
tableRef,
|
||||
containerRef,
|
||||
columnStorageName,
|
||||
columnInfoPanelStorageName,
|
||||
} = props;
|
||||
@ -101,7 +100,7 @@ const SessionsTableHeader = (props) => {
|
||||
return (
|
||||
<TableHeader
|
||||
checkboxSize="48px"
|
||||
containerRef={tableRef}
|
||||
containerRef={containerRef}
|
||||
columns={columns}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
|
@ -1,33 +1,113 @@
|
||||
import { useRef } from "react";
|
||||
import { useCallback } from "react";
|
||||
import { Base } from "@docspace/components/themes";
|
||||
import styled, { css } from "styled-components";
|
||||
import withContent from "SRC_DIR/HOCs/withPeopleContent";
|
||||
|
||||
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";
|
||||
|
||||
const Wrapper = styled.div`
|
||||
display: contents;
|
||||
`;
|
||||
|
||||
const StyledTableRow = styled(TableRow)`
|
||||
:hover {
|
||||
.table-container_cell {
|
||||
cursor: pointer;
|
||||
background: ${(props) =>
|
||||
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
|
||||
border-top: ${(props) =>
|
||||
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.table-container_user-name-cell {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-right: -24px;
|
||||
padding-right: 24px;
|
||||
`
|
||||
: css`
|
||||
margin-left: -24px;
|
||||
padding-left: 24px;
|
||||
`}
|
||||
}
|
||||
.table-container_row-context-menu-wrapper {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: -20px;
|
||||
padding-left: 20px;
|
||||
`
|
||||
: css`
|
||||
margin-right: -20px;
|
||||
padding-right: 20px;
|
||||
`}
|
||||
}
|
||||
}
|
||||
|
||||
.table-container_cell {
|
||||
text-overflow: ellipsis;
|
||||
height: 48px;
|
||||
max-height: 48px;
|
||||
|
||||
background: ${(props) =>
|
||||
(props.checked || props.isActive) &&
|
||||
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
|
||||
}
|
||||
|
||||
.table-container_row-checkbox {
|
||||
padding: 16px 8px 16px 12px;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
.table-container_row-checkbox-wrapper {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 8px;
|
||||
padding-left: 0px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 8px;
|
||||
padding-right: 0px;
|
||||
`}
|
||||
min-width: 48px;
|
||||
|
||||
.table-container_row-checkbox {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-right: -4px;
|
||||
padding: 16px 12px 16px 8px;
|
||||
`
|
||||
: css`
|
||||
margin-left: -4px;
|
||||
padding: 16px 8px 16px 12px;
|
||||
`}
|
||||
}
|
||||
}
|
||||
|
||||
.table-cell_username {
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: 12px;
|
||||
`
|
||||
: css`
|
||||
margin-right: 12px;
|
||||
`}
|
||||
}
|
||||
|
||||
.table-container_row-context-menu-wrapper {
|
||||
justify-content: flex-end;
|
||||
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
padding-left: 0px;
|
||||
`
|
||||
: css`
|
||||
padding-right: 0px;
|
||||
`}
|
||||
}
|
||||
|
||||
@ -42,22 +122,26 @@ const StyledTableRow = styled(TableRow)`
|
||||
}
|
||||
`;
|
||||
|
||||
const SessionsTableRow = ({
|
||||
t,
|
||||
avatar,
|
||||
role,
|
||||
displayName,
|
||||
status,
|
||||
browser,
|
||||
platform,
|
||||
country,
|
||||
city,
|
||||
ip,
|
||||
hideColumns,
|
||||
isChecked,
|
||||
toggleSession,
|
||||
}) => {
|
||||
const tableRef = useRef();
|
||||
StyledTableRow.defaultProps = { theme: Base };
|
||||
|
||||
const SessionsTableRow = (props) => {
|
||||
const {
|
||||
t,
|
||||
item,
|
||||
element,
|
||||
checkedProps,
|
||||
onContentRowSelect,
|
||||
onContentRowClick,
|
||||
isActive,
|
||||
hideColumns,
|
||||
displayName,
|
||||
status,
|
||||
browser,
|
||||
platform,
|
||||
country,
|
||||
city,
|
||||
ip,
|
||||
} = props;
|
||||
|
||||
const contextOptions = [
|
||||
{
|
||||
@ -84,72 +168,101 @@ const SessionsTableRow = ({
|
||||
},
|
||||
];
|
||||
|
||||
const handleSessionToggle = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
tableRef.current?.contains(e.target) || toggleSession(e);
|
||||
};
|
||||
|
||||
const isChecked = checkedProps.checked;
|
||||
const isOnline = status === "Online";
|
||||
|
||||
const onChange = (e) => {
|
||||
onContentRowSelect && onContentRowSelect(e.target.checked, item);
|
||||
};
|
||||
|
||||
const onRowContextClick = useCallback(() => {
|
||||
onContentRowClick && onContentRowClick(!isChecked, item, false);
|
||||
}, [isChecked, item, onContentRowClick]);
|
||||
|
||||
const onRowClick = (e) => {
|
||||
if (
|
||||
e.target.closest(".checkbox") ||
|
||||
e.target.closest(".table-container_row-checkbox") ||
|
||||
e.target.closest(".paid-badge") ||
|
||||
e.target.closest(".pending-badge") ||
|
||||
e.target.closest(".disabled-badge") ||
|
||||
e.detail === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
onContentRowClick && onContentRowClick(!isChecked, item);
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledTableRow
|
||||
hideColumns={hideColumns}
|
||||
contextOptions={contextOptions}
|
||||
checked={isChecked}
|
||||
onClick={handleSessionToggle}
|
||||
<Wrapper
|
||||
className={`user-item ${
|
||||
isChecked || isActive ? "table-row-selected" : ""
|
||||
}`}
|
||||
>
|
||||
<TableCell hasAccess={true}>
|
||||
<div className="table-container_element">
|
||||
<Avatar
|
||||
className="avatar"
|
||||
userName={displayName}
|
||||
role={role}
|
||||
source={avatar}
|
||||
size={"small"}
|
||||
/>
|
||||
</div>
|
||||
<StyledTableRow
|
||||
key={item.id}
|
||||
className="table-row"
|
||||
checked={isChecked}
|
||||
isActive={isActive}
|
||||
onClick={onRowClick}
|
||||
fileContextClick={onRowContextClick}
|
||||
hideColumns={hideColumns}
|
||||
contextOptions={contextOptions}
|
||||
>
|
||||
<TableCell className="table-container_user-name-cell">
|
||||
<TableCell
|
||||
hasAccess={true}
|
||||
className="table-container_row-checkbox-wrapper"
|
||||
checked={isChecked}
|
||||
>
|
||||
<div className="table-container_element">{element}</div>
|
||||
<Checkbox
|
||||
className="table-container_row-checkbox"
|
||||
isChecked={isChecked}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</TableCell>
|
||||
<Text className="table-cell_username" fontWeight="600">
|
||||
{displayName}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<Checkbox
|
||||
className="table-container_row-checkbox"
|
||||
isChecked={isChecked}
|
||||
onChange={handleSessionToggle}
|
||||
/>
|
||||
<TableCell>
|
||||
<Text
|
||||
className={isOnline ? "session-online" : "session-info"}
|
||||
truncate
|
||||
>
|
||||
{status}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<Text fontWeight="600">{displayName}</Text>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{platform},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{browser}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text className={isOnline ? "session-online" : "session-info"} truncate>
|
||||
{status}
|
||||
</Text>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{country},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{city}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{platform},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{browser}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{country},
|
||||
</Text>
|
||||
<Text className="session-info" truncate>
|
||||
{city}
|
||||
</Text>
|
||||
</TableCell>
|
||||
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{ip}
|
||||
</Text>
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
<TableCell>
|
||||
<Text className="session-info" truncate>
|
||||
{ip}
|
||||
</Text>
|
||||
</TableCell>
|
||||
</StyledTableRow>
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default SessionsTableRow;
|
||||
export default withContent(SessionsTableRow);
|
||||
|
@ -14,6 +14,46 @@ 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 TABLE_VERSION = "5";
|
||||
const COLUMNS_SIZE = `sessionsColumnsSize_ver-${TABLE_VERSION}`;
|
||||
const INFO_PANEL_COLUMNS_SIZE = `infoPanelSessionsColumnsSize_ver-${TABLE_VERSION}`;
|
||||
|
||||
const marginCss = css`
|
||||
margin-top: -1px;
|
||||
border-top: ${(props) =>
|
||||
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
|
||||
`;
|
||||
|
||||
const userNameCss = css`
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-right: -24px;
|
||||
padding-right: 24px;
|
||||
`
|
||||
: css`
|
||||
margin-left: -24px;
|
||||
padding-left: 24px;
|
||||
`}
|
||||
|
||||
${marginCss}
|
||||
`;
|
||||
|
||||
const contextCss = css`
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
margin-left: -20px;
|
||||
padding-left: 20px;
|
||||
`
|
||||
: css`
|
||||
margin-right: -20px;
|
||||
padding-right: 20px;
|
||||
`}
|
||||
|
||||
${marginCss}
|
||||
`;
|
||||
|
||||
const StyledTableContainer = styled(TableContainer)`
|
||||
margin: 0 0 24px;
|
||||
|
||||
@ -21,7 +61,7 @@ const StyledTableContainer = styled(TableContainer)`
|
||||
height: 69px;
|
||||
position: absolute;
|
||||
z-index: 201;
|
||||
top: 0;
|
||||
top: -25px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
|
||||
@ -49,76 +89,91 @@ const StyledTableContainer = styled(TableContainer)`
|
||||
font-size: ${(props) => props.theme.getCorrectFontSize("12px")};
|
||||
}
|
||||
|
||||
.table-list-item {
|
||||
cursor: pointer;
|
||||
:has(
|
||||
.table-container_body
|
||||
.table-list-item:first-child:first-child
|
||||
> .table-row-selected
|
||||
) {
|
||||
.table-container_header {
|
||||
border-image-slice: 1;
|
||||
border-image-source: ${(props) =>
|
||||
props.theme.tableContainer.header.lengthenBorderImageSource};
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: ${(props) =>
|
||||
props.theme.filesSection.tableView.row.backgroundActive};
|
||||
.table-row-selected {
|
||||
.table-container_user-name-cell {
|
||||
${userNameCss}
|
||||
}
|
||||
|
||||
.table-container_cell {
|
||||
margin-top: -1px;
|
||||
border-top: ${(props) =>
|
||||
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
|
||||
|
||||
margin-left: -24px;
|
||||
padding-left: 24px;
|
||||
}
|
||||
.table-container_row-context-menu-wrapper {
|
||||
${contextCss}
|
||||
}
|
||||
}
|
||||
|
||||
.table-row-selected + .table-row-selected {
|
||||
.table-row {
|
||||
.table-container_user-name-cell,
|
||||
.table-container_row-context-menu-wrapper {
|
||||
margin-right: -20px;
|
||||
padding-right: 20px;
|
||||
margin-top: -1px;
|
||||
border-image-slice: 1;
|
||||
border-top: 1px solid;
|
||||
}
|
||||
.table-container_user-name-cell {
|
||||
${userNameCss}
|
||||
border-left: 0; //for Safari macOS
|
||||
border-right: 0; //for Safari macOS
|
||||
|
||||
border-image-source: ${(props) =>
|
||||
`linear-gradient(to right, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
|
||||
}
|
||||
.table-container_row-context-menu-wrapper {
|
||||
${contextCss}
|
||||
|
||||
border-image-source: ${(props) =>
|
||||
`linear-gradient(to left, ${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-list-item:has(.selected-table-row) {
|
||||
background-color: ${(props) =>
|
||||
props.theme.filesSection.tableView.row.backgroundActive};
|
||||
}
|
||||
.user-item:not(.table-row-selected) + .table-row-selected {
|
||||
.table-row {
|
||||
.table-container_user-name-cell {
|
||||
${userNameCss}
|
||||
}
|
||||
|
||||
.table-container_row-context-menu-wrapper {
|
||||
justify-content: flex-end;
|
||||
.table-container_row-context-menu-wrapper {
|
||||
${contextCss}
|
||||
}
|
||||
|
||||
${(props) =>
|
||||
props.theme.interfaceDirection === "rtl"
|
||||
? css`
|
||||
padding-left: 0px;
|
||||
`
|
||||
: css`
|
||||
padding-right: 0px;
|
||||
`}
|
||||
.table-container_user-name-cell,
|
||||
.table-container_row-context-menu-wrapper {
|
||||
border-bottom: ${(props) =>
|
||||
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
StyledTableContainer.defaultProps = { theme: Base };
|
||||
|
||||
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,
|
||||
allSessions,
|
||||
checkedSessions,
|
||||
toggleSession,
|
||||
toggleAllSessions,
|
||||
isSessionChecked,
|
||||
// allSessions,
|
||||
// checkedSessions,
|
||||
// toggleSession,
|
||||
// toggleAllSessions,
|
||||
// isSessionChecked,
|
||||
}) => {
|
||||
const [hideColumns, setHideColumns] = useState(false);
|
||||
const tableRef = useRef(null);
|
||||
const ref = useRef(null);
|
||||
|
||||
const handleToggle = (e, id) => {
|
||||
e.stopPropagation();
|
||||
toggleSession(id);
|
||||
};
|
||||
|
||||
const handleAllToggles = (checked) => {
|
||||
toggleAllSessions(checked, allSessions);
|
||||
};
|
||||
// const handleAllToggles = (checked) => {
|
||||
// toggleAllSessions(checked, allSessions);
|
||||
// };
|
||||
|
||||
const columnStorageName = `${COLUMNS_SIZE}=${userId}`;
|
||||
const columnInfoPanelStorageName = `${INFO_PANEL_COLUMNS_SIZE}=${userId}`;
|
||||
@ -147,14 +202,14 @@ const TableView = ({
|
||||
},
|
||||
];
|
||||
|
||||
const isChecked = checkedSessions.length === allSessions.length;
|
||||
// const isChecked = checkedSessions.length === allSessions.length;
|
||||
|
||||
const isIndeterminate =
|
||||
checkedSessions.length > 0 && checkedSessions.length !== allSessions.length;
|
||||
// const isIndeterminate =
|
||||
// checkedSessions.length > 0 && checkedSessions.length !== allSessions.length;
|
||||
|
||||
return (
|
||||
<StyledTableContainer forwardedRef={tableRef} useReactWindow>
|
||||
{checkedSessions.length > 0 && (
|
||||
<StyledTableContainer forwardedRef={ref} useReactWindow>
|
||||
{/* {checkedSessions.length > 0 && (
|
||||
<div className="table-group-menu">
|
||||
<TableGroupMenu
|
||||
sectionWidth={sectionWidth}
|
||||
@ -167,17 +222,15 @@ const TableView = ({
|
||||
onChange={handleAllToggles}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
)} */}
|
||||
<SessionsTableHeader
|
||||
t={t}
|
||||
userId={userId}
|
||||
sectionWidth={sectionWidth}
|
||||
setHideColumns={setHideColumns}
|
||||
userId={userId}
|
||||
tableRef={tableRef}
|
||||
containerRef={ref}
|
||||
columnStorageName={columnStorageName}
|
||||
columnInfoPanelStorageName={columnInfoPanelStorageName}
|
||||
isChecked={isChecked}
|
||||
isIndeterminate={isIndeterminate}
|
||||
/>
|
||||
<TableBody
|
||||
itemHeight={49}
|
||||
@ -190,21 +243,20 @@ const TableView = ({
|
||||
itemCount={sessionsData.length}
|
||||
fetchMoreFiles={() => {}}
|
||||
>
|
||||
{sessionsData.map((session) => (
|
||||
{sessionsData.map((item) => (
|
||||
<SessionsTableRow
|
||||
t={t}
|
||||
key={session.userId}
|
||||
avatar={session.avatar}
|
||||
displayName={session.displayName}
|
||||
status={session.status}
|
||||
platform={session.platform}
|
||||
browser={session.browser}
|
||||
country={session.country}
|
||||
city={session.city}
|
||||
ip={session.ip}
|
||||
key={item.userId}
|
||||
item={item}
|
||||
userId={userId}
|
||||
hideColumns={hideColumns}
|
||||
isChecked={isSessionChecked(session.userId)}
|
||||
toggleSession={(e) => handleToggle(e, session.userId)}
|
||||
displayName={item.displayName}
|
||||
status={item.status}
|
||||
browser={item.browser}
|
||||
platform={item.platform}
|
||||
country={item.country}
|
||||
city={item.city}
|
||||
ip={item.ip}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
|
Loading…
Reference in New Issue
Block a user