Merge pull request #1133 from ONLYOFFICE/feature/fixed-files-table-cells-render

Feature/fixed files table cells render
This commit is contained in:
Alexey Safronov 2022-12-22 21:15:25 +03:00 committed by GitHub
commit 7bbffa90a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 925 additions and 595 deletions

View File

@ -0,0 +1,279 @@
import styled, { css } from "styled-components";
import Base from "@docspace/components/themes/base";
import TableRow from "@docspace/components/table-container/TableRow";
import DragAndDrop from "@docspace/components/drag-and-drop";
const hotkeyBorderStyle = css`
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: linear-gradient(to left, #2da7db 24px, #2da7db 24px);
`;
const rowCheckboxDraggingStyle = css`
margin-left: -20px;
padding-left: 20px;
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: ${(props) => `linear-gradient(to right,
${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
`;
const contextMenuWrapperDraggingStyle = css`
margin-right: -20px;
padding-right: 20px;
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: ${(props) => `linear-gradient(to left,
${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
`;
const StyledTableRow = styled(TableRow)`
${(props) =>
props.isRoom &&
css`
.table-container_cell {
height: 48px;
max-height: 48px;
}
.table-container_row-checkbox {
padding-left: 20px !important;
}
`}
${(props) =>
!props.isDragging &&
css`
:hover {
.table-container_cell {
cursor: pointer;
background: ${(props) =>
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
margin-top: ${(props) => (props.showHotkeyBorder ? "-2px" : "-1px")};
${(props) =>
!props.showHotkeyBorder &&
css`
border-top: ${(props) =>
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
`}
}
.table-container_file-name-cell {
margin-left: -24px;
padding-left: 24px;
}
.table-container_row-context-menu-wrapper {
margin-right: -20px;
padding-right: 18px;
}
}
`}
.table-container_cell {
background: ${(props) =>
(props.checked || props.isActive) &&
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
cursor: ${(props) =>
!props.isThirdPartyFolder &&
(props.checked || props.isActive) &&
"url(/static/images/cursor.palm.react.svg), auto !important"};
${(props) =>
props.inProgress &&
css`
pointer-events: none;
/* cursor: wait; */
`}
${(props) => props.showHotkeyBorder && "border-color: #2DA7DB"}
}
.table-container_element-wrapper,
.table-container_quick-buttons-wrapper {
padding-right: 0px;
}
.table-container_element-wrapper,
.table-container_row-loader {
min-width: ${(props) => (props.isRoom ? "40px" : "36px")};
}
.table-container_element-container {
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
}
.table-container_row-loader {
svg {
margin-left: 4px;
}
}
.table-container_row-checkbox {
padding-left: 20px;
width: 16px;
}
.table-container_file-name-cell {
${(props) =>
props.showHotkeyBorder &&
css`
margin-left: -24px;
padding-left: 24px;
${hotkeyBorderStyle}
`};
${(props) => props.dragging && rowCheckboxDraggingStyle};
}
.table-container_row-context-menu-wrapper {
padding-right: 0px;
${(props) => props.dragging && contextMenuWrapperDraggingStyle};
${(props) =>
props.showHotkeyBorder &&
css`
margin-right: -20px;
padding-right: 18px;
${hotkeyBorderStyle}
`};
}
.edit {
svg:not(:root) {
width: 12px;
height: 12px;
}
}
${(props) =>
props.showHotkeyBorder &&
css`
.table-container_cell {
margin-top: -2px;
border-top: 1px solid #2da7db !important;
border-right: 0;
border-left: 0;
}
.table-container_file-name-cell > .table-container_cell {
margin-top: 2px;
border-top: 0px !important;
}
.item-file-name,
.row_update-text,
.expandButton,
.badges,
.tag,
.author-cell,
.table-container_cell > p {
margin-top: 2px;
}
`}
`;
const StyledDragAndDrop = styled(DragAndDrop)`
display: contents;
`;
const StyledBadgesContainer = styled.div`
margin-left: 8px;
display: flex;
align-items: center;
${(props) =>
props.showHotkeyBorder &&
css`
margin-top: 1px;
`}
.badges {
display: flex;
align-items: center;
margin-right: 12px;
}
.badges:last-child {
margin-left: 0px;
}
.badge {
cursor: pointer;
margin-right: 8px;
}
.new-items {
min-width: 12px;
width: max-content;
margin: 0 -2px -2px -2px;
}
.badge-version {
width: max-content;
margin: 0 5px -2px -2px;
> div {
padding: 0 3.3px 0 4px;
p {
letter-spacing: 0.5px;
font-size: 8px;
font-weight: 800;
}
}
}
.badge-new-version {
width: max-content;
}
`;
const StyledQuickButtonsContainer = styled.div`
width: 100%;
.badges {
display: flex;
justify-content: flex-end;
align-items: center;
}
.badge {
margin-right: 14px;
}
.badge:last-child {
margin-right: 10px;
}
.lock-file {
svg {
height: 12px;
}
}
.favorite {
margin-top: 1px;
}
.share-button-icon:hover {
cursor: pointer;
path {
fill: ${(props) =>
props.theme.filesSection.tableView.row.shareHoverColor};
}
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
`;
StyledQuickButtonsContainer.defaultProps = { theme: Base };
export {
StyledBadgesContainer,
StyledQuickButtonsContainer,
StyledTableRow,
StyledDragAndDrop,
};

View File

@ -1,4 +1,4 @@
import React, { useEffect, useRef } from "react";
import React, { useEffect, useRef, useCallback } from "react";
import elementResizeDetectorMaker from "element-resize-detector";
import TableContainer from "@docspace/components/table-container";
import { inject, observer } from "mobx-react";
@ -8,7 +8,6 @@ import TableBody from "@docspace/components/table-container/TableBody";
import { isMobile } from "react-device-detect";
import styled, { css } from "styled-components";
import { Base } from "@docspace/components/themes";
import { TableVersions } from "SRC_DIR/helpers/constants";
const marginCss = css`
margin-top: -1px;
@ -99,14 +98,6 @@ const StyledTableContainer = styled(TableContainer)`
StyledTableContainer.defaultProps = { theme: Base };
const TABLE_COLUMNS = `filesTableColumns_ver-${TableVersions.Files}`;
const COLUMNS_SIZE = `filesColumnsSize_ver-${TableVersions.Files}`;
const COLUMNS_SIZE_INFO_PANEL = `filesColumnsSizeInfoPanel_ver-${TableVersions.Files}`;
const TABLE_ROOMS_COLUMNS = `roomsTableColumns_ver-${TableVersions.Rooms}`;
const COLUMNS_ROOMS_SIZE = `roomsColumnsSize_ver-${TableVersions.Rooms}`;
const COLUMNS_ROOMS_SIZE_INFO_PANEL = `roomsColumnsSizeInfoPanel_ver-${TableVersions.Rooms}`;
const elementResizeDetector = elementResizeDetectorMaker({
strategy: "scroll",
callOnAdd: false,
@ -121,12 +112,13 @@ const Table = ({
setHeaderBorder,
theme,
infoPanelVisible,
userId,
fetchMoreFiles,
hasMoreFiles,
filterTotal,
isRooms,
withPaging,
columnStorageName,
columnInfoPanelStorageName,
}) => {
const [tagCount, setTagCount] = React.useState(null);
const [hideColumns, setHideColumns] = React.useState(false);
@ -149,7 +141,7 @@ const Table = ({
}
}, [sectionWidth]);
React.useEffect(() => {
useEffect(() => {
return () => {
if (!tagRef?.current) return;
@ -157,7 +149,7 @@ const Table = ({
};
}, []);
const onResize = React.useCallback(
const onResize = useCallback(
(node) => {
const element = tagRef?.current ? tagRef?.current : node;
@ -172,7 +164,7 @@ const Table = ({
[tagCount]
);
const onSetTagRef = React.useCallback((node) => {
const onSetTagRef = useCallback((node) => {
if (node) {
tagRef.current = node;
onResize(node);
@ -181,28 +173,11 @@ const Table = ({
}
}, []);
const tableColumns = isRooms
? `${TABLE_ROOMS_COLUMNS}=${userId}`
: `${TABLE_COLUMNS}=${userId}`;
const columnStorageName = isRooms
? `${COLUMNS_ROOMS_SIZE}=${userId}`
: `${COLUMNS_SIZE}=${userId}`;
const columnInfoPanelStorageName = isRooms
? `${COLUMNS_ROOMS_SIZE_INFO_PANEL}=${userId}`
: `${COLUMNS_SIZE_INFO_PANEL}=${userId}`;
return (
<StyledTableContainer useReactWindow={!withPaging} forwardedRef={ref}>
<TableHeader
sectionWidth={sectionWidth}
containerRef={ref}
tableStorageName={tableColumns}
columnStorageName={columnStorageName}
filesColumnStorageName={`${COLUMNS_SIZE}=${userId}`}
roomsColumnStorageName={`${COLUMNS_ROOMS_SIZE}=${userId}`}
columnInfoPanelStorageName={columnInfoPanelStorageName}
filesColumnInfoPanelStorageName={`${COLUMNS_SIZE_INFO_PANEL}=${userId}`}
roomsColumnInfoPanelStorageName={`${COLUMNS_ROOMS_SIZE_INFO_PANEL}=${userId}`}
isRooms={isRooms}
tagRef={onSetTagRef}
setHideColumns={setHideColumns}
@ -228,9 +203,6 @@ const Table = ({
setFirsElemChecked={setFirsElemChecked}
setHeaderBorder={setHeaderBorder}
theme={theme}
tableColumns={tableColumns}
columnStorageName={columnStorageName}
columnInfoPanelStorageName={columnInfoPanelStorageName}
tagCount={tagCount}
isRooms={isRooms}
hideColumns={hideColumns}
@ -241,13 +213,14 @@ const Table = ({
);
};
export default inject(({ filesStore, treeFoldersStore, auth }) => {
export default inject(({ filesStore, treeFoldersStore, auth, tableStore }) => {
const { isVisible: infoPanelVisible } = auth.infoPanelStore;
const { isRoomsFolder, isArchiveFolder } = treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
const { columnStorageName, columnInfoPanelStorageName } = tableStore;
const {
filesList,
viewAs,
@ -276,5 +249,7 @@ export default inject(({ filesStore, treeFoldersStore, auth }) => {
filterTotal: isRooms ? roomsFilterTotal : filterTotal,
isRooms,
withPaging,
columnStorageName,
columnInfoPanelStorageName,
};
})(observer(Table));

View File

@ -4,8 +4,6 @@ import { inject, observer } from "mobx-react";
import { withTranslation } from "react-i18next";
import { Events } from "@docspace/common/constants";
const WITH_AUTHOR = "withAuthorColumn";
class FilesTableHeader extends React.Component {
constructor(props) {
super(props);
@ -16,13 +14,7 @@ class FilesTableHeader extends React.Component {
}
getTableColumns = (fromUpdate = false) => {
const {
t,
personal,
tableStorageName,
isRooms,
isPersonalRoom,
} = this.props;
const { t, isRooms, getColumns } = this.props;
const defaultColumns = [];
@ -32,7 +24,7 @@ class FilesTableHeader extends React.Component {
key: "Name",
title: t("Common:Name"),
resizable: true,
enable: true,
enable: this.props.roomColumnNameIsEnabled,
default: true,
sortBy: "AZ",
minWidth: 210,
@ -41,7 +33,7 @@ class FilesTableHeader extends React.Component {
{
key: "Type",
title: t("Common:Type"),
enable: false,
enable: this.props.roomColumnTypeIsEnabled,
resizable: true,
sortBy: "roomType",
onChange: this.onColumnChange,
@ -50,7 +42,7 @@ class FilesTableHeader extends React.Component {
{
key: "Tags",
title: t("Common:Tags"),
enable: true,
enable: this.props.roomColumnTagsIsEnabled,
resizable: true,
sortBy: "Tags",
withTagRef: true,
@ -60,7 +52,7 @@ class FilesTableHeader extends React.Component {
{
key: "Owner",
title: t("ByOwner"),
enable: false,
enable: this.props.roomColumnOwnerIsEnabled,
resizable: true,
sortBy: "Author",
onChange: this.onColumnChange,
@ -69,7 +61,7 @@ class FilesTableHeader extends React.Component {
{
key: "Activity",
title: t("ByLastModified"),
enable: true,
enable: this.props.roomColumnActivityIsEnabled,
resizable: true,
sortBy: "DateAndTime",
onChange: this.onColumnChange,
@ -79,38 +71,30 @@ class FilesTableHeader extends React.Component {
defaultColumns.push(...columns);
} else {
const authorOption = {
key: "Author",
title: t("ByAuthor"),
enable: false,
resizable: true,
sortBy: "Author",
// isDisabled: isPersonalRoom,
onClick: this.onFilter,
onChange: this.onColumnChange,
};
// if (isPersonalRoom) {
// authorOption.defaultSize = 0;
// }
const columns = [
{
key: "Name",
title: t("Common:Name"),
resizable: true,
enable: true,
enable: this.props.nameColumnIsEnabled,
default: true,
sortBy: "AZ",
minWidth: 210,
onClick: this.onFilter,
},
authorOption,
{
key: "Author",
title: t("ByAuthor"),
enable: this.props.authorColumnIsEnabled,
resizable: true,
sortBy: "Author",
onClick: this.onFilter,
onChange: this.onColumnChange,
},
{
key: "Created",
title: t("ByCreation"),
enable: true,
enable: this.props.createdColumnIsEnabled,
resizable: true,
sortBy: "DateAndTimeCreation",
onClick: this.onFilter,
@ -119,7 +103,7 @@ class FilesTableHeader extends React.Component {
{
key: "Modified",
title: t("ByLastModified"),
enable: true,
enable: this.props.modifiedColumnIsEnabled,
resizable: true,
sortBy: "DateAndTime",
onClick: this.onFilter,
@ -128,7 +112,7 @@ class FilesTableHeader extends React.Component {
{
key: "Size",
title: t("Common:Size"),
enable: true,
enable: this.props.sizeColumnIsEnabled,
resizable: true,
sortBy: "Size",
onClick: this.onFilter,
@ -137,7 +121,7 @@ class FilesTableHeader extends React.Component {
{
key: "Type",
title: t("Common:Type"),
enable: true,
enable: this.props.typeColumnIsEnabled,
resizable: true,
sortBy: "Type",
onClick: this.onFilter,
@ -146,20 +130,18 @@ class FilesTableHeader extends React.Component {
{
key: "QuickButtons",
title: "",
enable: true,
enable: this.props.quickButtonsColumnIsEnabled,
defaultSize: 75,
resizable: false,
},
];
personal && columns.splice(1, 1);
defaultColumns.push(...columns);
}
const storageColumns = localStorage.getItem(tableStorageName);
const columns = getColumns(defaultColumns);
const storageColumns = localStorage.getItem(this.tableStorageName);
const splitColumns = storageColumns && storageColumns.split(",");
const columns = this.getColumns(defaultColumns, splitColumns);
const resetColumnsSize =
(splitColumns && splitColumns.length !== columns.length) || !splitColumns;
@ -167,17 +149,15 @@ class FilesTableHeader extends React.Component {
this.setTableColumns(tableColumns);
if (fromUpdate) {
this.setState({
columns: columns,
resetColumnsSize: resetColumnsSize,
isRooms: isRooms,
isPersonalRoom: isPersonalRoom,
columns,
resetColumnsSize,
isRooms,
});
} else {
this.state = {
columns: columns,
resetColumnsSize: resetColumnsSize,
isRooms: isRooms,
isPersonalRoom: isPersonalRoom,
columns,
resetColumnsSize,
isRooms,
};
}
};
@ -214,15 +194,12 @@ class FilesTableHeader extends React.Component {
this.isBeginScrolling = true;
};
componentDidUpdate(prevProps) {
if (this.props.isRooms !== this.state.isRooms) {
return this.getTableColumns(true);
}
if (this.props.isPersonalRoom !== this.state.isPersonalRoom) {
return this.getTableColumns(true);
}
const { columns } = this.state;
if (this.props.withContent !== prevProps.withContent) {
const columnIndex = columns.findIndex((c) => c.key === "Share");
@ -244,56 +221,21 @@ class FilesTableHeader extends React.Component {
componentWillUnmount() {
this.customScrollElm.removeEventListener("scroll", this.onBeginScroll);
}
getColumns = (defaultColumns, splitColumns) => {
const { isPersonalRoom, isRooms } = this.props;
const columns = [];
if (splitColumns) {
for (let col of defaultColumns) {
const column = splitColumns.find((key) => key === col.key);
column ? (col.enable = true) : (col.enable = false);
if (!isRooms) {
if (column === "Author" && isPersonalRoom) {
col.enable = false;
}
if (col.key === "Author" && !isPersonalRoom) {
if (!col.enable) {
const withAuthor = localStorage.getItem(WITH_AUTHOR);
if (withAuthor === "true") {
col.enable = true;
}
}
}
}
columns.push(col);
}
return columns;
} else {
return defaultColumns;
}
};
onColumnChange = (key, e) => {
onColumnChange = (key) => {
const { columns } = this.state;
const columnIndex = columns.findIndex((c) => c.key === key);
if (columnIndex === -1) return;
this.props.setColumnEnable(key);
columns[columnIndex].enable = !columns[columnIndex].enable;
this.setState({ columns });
const tableColumns = columns.map((c) => c.enable && c.key);
this.setTableColumns(tableColumns);
if (key === "Author") {
localStorage.setItem(WITH_AUTHOR, columns[columnIndex].enable);
}
const event = new Event(Events.CHANGE_COLUMN);
window.dispatchEvent(event);
@ -356,7 +298,6 @@ class FilesTableHeader extends React.Component {
setHideColumns,
} = this.props;
// const { sortBy, sortOrder } = filter;
const { columns, resetColumnsSize } = this.state;
const sortBy = isRooms ? roomsFilter.sortBy : filter.sortBy;
@ -402,7 +343,7 @@ class FilesTableHeader extends React.Component {
}
export default inject(
({ auth, filesStore, selectedFolderStore, treeFoldersStore }) => {
({ auth, filesStore, selectedFolderStore, treeFoldersStore, tableStore }) => {
const { isVisible: infoPanelVisible } = auth.infoPanelStore;
const {
@ -416,17 +357,43 @@ export default inject(
roomsFilter,
fetchRooms,
} = filesStore;
const { isRecentFolder, isPersonalRoom } = treeFoldersStore;
const { isRecentFolder } = treeFoldersStore;
const withContent = canShare;
const sortingVisible = !isRecentFolder;
const { personal, withPaging } = auth.settingsStore;
const { withPaging } = auth.settingsStore;
const {
tableStorageName,
columnStorageName,
columnInfoPanelStorageName,
filesColumnStorageName,
roomsColumnStorageName,
filesColumnInfoPanelStorageName,
roomsColumnInfoPanelStorageName,
nameColumnIsEnabled,
authorColumnIsEnabled,
createdColumnIsEnabled,
modifiedColumnIsEnabled,
sizeColumnIsEnabled,
typeColumnIsEnabled,
quickButtonsColumnIsEnabled,
roomColumnNameIsEnabled,
roomColumnTypeIsEnabled,
roomColumnTagsIsEnabled,
roomColumnOwnerIsEnabled,
roomColumnActivityIsEnabled,
getColumns,
setColumnEnable,
} = tableStore;
return {
isHeaderChecked,
filter,
selectedFolderId: selectedFolderStore.id,
withContent,
personal,
sortingVisible,
setIsLoading,
@ -441,7 +408,30 @@ export default inject(
infoPanelVisible,
withPaging,
isPersonalRoom,
tableStorageName,
columnStorageName,
columnInfoPanelStorageName,
filesColumnStorageName,
roomsColumnStorageName,
filesColumnInfoPanelStorageName,
roomsColumnInfoPanelStorageName,
nameColumnIsEnabled,
authorColumnIsEnabled,
createdColumnIsEnabled,
modifiedColumnIsEnabled,
sizeColumnIsEnabled,
typeColumnIsEnabled,
quickButtonsColumnIsEnabled,
roomColumnNameIsEnabled,
roomColumnTypeIsEnabled,
roomColumnTagsIsEnabled,
roomColumnOwnerIsEnabled,
roomColumnActivityIsEnabled,
getColumns,
setColumnEnable,
};
}
)(

View File

@ -6,303 +6,24 @@ import withQuickButtons from "../../../../../HOCs/withQuickButtons";
import withFileActions from "../../../../../HOCs/withFileActions";
import ItemIcon from "../../../../../components/ItemIcon";
import { withTranslation } from "react-i18next";
import TableRow from "@docspace/components/table-container/TableRow";
import TableCell from "@docspace/components/table-container/TableCell";
import DragAndDrop from "@docspace/components/drag-and-drop";
import FileNameCell from "./sub-components/FileNameCell";
import SizeCell from "./sub-components/SizeCell";
import AuthorCell from "./sub-components/AuthorCell";
import DateCell from "./sub-components/DateCell";
import TypeCell from "./sub-components/TypeCell";
import TagsCell from "./sub-components/TagsCell";
import styled, { css } from "styled-components";
import Base from "@docspace/components/themes/base";
import { classNames } from "@docspace/components/utils/classNames";
const hotkeyBorderStyle = css`
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: linear-gradient(to left, #2da7db 24px, #2da7db 24px);
`;
const rowCheckboxDraggingStyle = css`
margin-left: -20px;
padding-left: 20px;
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: ${(props) => `linear-gradient(to right,
${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
`;
const contextMenuWrapperDraggingStyle = css`
margin-right: -20px;
padding-right: 20px;
border-bottom: 1px solid;
border-image-slice: 1;
border-image-source: ${(props) => `linear-gradient(to left,
${props.theme.filesSection.tableView.row.borderColorTransition} 17px, ${props.theme.filesSection.tableView.row.borderColor} 31px)`};
`;
const StyledTableRow = styled(TableRow)`
${(props) =>
props.isRoom &&
css`
.table-container_cell {
height: 48px;
max-height: 48px;
}
.table-container_row-checkbox {
padding-left: 20px !important;
}
`}
${(props) =>
!props.isDragging &&
css`
:hover {
.table-container_cell {
cursor: pointer;
background: ${(props) =>
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
margin-top: ${(props) => (props.showHotkeyBorder ? "-2px" : "-1px")};
${(props) =>
!props.showHotkeyBorder &&
css`
border-top: ${(props) =>
`1px solid ${props.theme.filesSection.tableView.row.borderColor}`};
`}
}
.table-container_file-name-cell {
margin-left: -24px;
padding-left: 24px;
}
.table-container_row-context-menu-wrapper {
margin-right: -20px;
padding-right: 18px;
}
}
`}
.table-container_cell {
background: ${(props) =>
(props.checked || props.isActive) &&
`${props.theme.filesSection.tableView.row.backgroundActive} !important`};
cursor: ${(props) =>
!props.isThirdPartyFolder &&
(props.checked || props.isActive) &&
"url(/static/images/cursor.palm.react.svg), auto !important"};
${(props) =>
props.inProgress &&
css`
pointer-events: none;
/* cursor: wait; */
`}
${(props) => props.showHotkeyBorder && "border-color: #2DA7DB"}
}
.table-container_element-wrapper,
.table-container_quick-buttons-wrapper {
padding-right: 0px;
}
.table-container_element-wrapper,
.table-container_row-loader {
min-width: ${(props) => (props.isRoom ? "40px" : "36px")};
}
.table-container_element-container {
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
}
.table-container_row-loader {
svg {
margin-left: 4px;
}
}
.table-container_row-checkbox {
padding-left: 20px;
width: 16px;
}
.table-container_file-name-cell {
${(props) =>
props.showHotkeyBorder &&
css`
margin-left: -24px;
padding-left: 24px;
${hotkeyBorderStyle}
`};
${(props) => props.dragging && rowCheckboxDraggingStyle};
}
.table-container_row-context-menu-wrapper {
padding-right: 0px;
${(props) => props.dragging && contextMenuWrapperDraggingStyle};
${(props) =>
props.showHotkeyBorder &&
css`
margin-right: -20px;
padding-right: 18px;
${hotkeyBorderStyle}
`};
}
.edit {
svg:not(:root) {
width: 12px;
height: 12px;
}
}
${(props) =>
props.showHotkeyBorder &&
css`
.table-container_cell {
margin-top: -2px;
border-top: 1px solid #2da7db !important;
border-right: 0;
border-left: 0;
}
.table-container_file-name-cell > .table-container_cell {
margin-top: 2px;
border-top: 0px !important;
}
.item-file-name,
.row_update-text,
.expandButton,
.badges,
.tag,
.author-cell,
.table-container_cell > p {
margin-top: 2px;
}
`}
`;
const StyledDragAndDrop = styled(DragAndDrop)`
display: contents;
`;
const StyledBadgesContainer = styled.div`
margin-left: 8px;
display: flex;
align-items: center;
${(props) =>
props.showHotkeyBorder &&
css`
margin-top: 1px;
`}
.badges {
display: flex;
align-items: center;
margin-right: 12px;
}
.badges:last-child {
margin-left: 0px;
}
.badge {
cursor: pointer;
margin-right: 8px;
}
.new-items {
min-width: 12px;
width: max-content;
margin: 0 -2px -2px -2px;
}
.badge-version {
width: max-content;
margin: 0 5px -2px -2px;
> div {
padding: 0 3.3px 0 4px;
p {
letter-spacing: 0.5px;
font-size: 8px;
font-weight: 800;
}
}
}
.badge-new-version {
width: max-content;
}
`;
const StyledQuickButtonsContainer = styled.div`
width: 100%;
.badges {
display: flex;
justify-content: flex-end;
align-items: center;
}
.badge {
margin-right: 14px;
}
.badge:last-child {
margin-right: 10px;
}
.lock-file {
svg {
height: 12px;
}
}
.favorite {
margin-top: 1px;
}
.share-button-icon:hover {
cursor: pointer;
path {
fill: ${(props) =>
props.theme.filesSection.tableView.row.shareHoverColor};
}
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
`;
StyledQuickButtonsContainer.defaultProps = { theme: Base };
import RoomsRowDataComponent from "./sub-components/RoomsRowData";
import RowDataComponent from "./sub-components/RowData";
import { StyledTableRow, StyledDragAndDrop } from "./StyledTable";
const FilesTableRow = (props) => {
const {
t,
fileContextClick,
item,
onContentFileSelect,
checkedProps,
className,
value,
onMouseClick,
badgesComponent,
dragging,
isDragging,
onDrop,
onMouseDown,
personal,
isActive,
onHideContextMenu,
onFilesClick,
@ -311,12 +32,9 @@ const FilesTableRow = (props) => {
setFirsElemChecked,
setHeaderBorder,
theme,
quickButtonsComponent,
getContextModel,
showHotkeyBorder,
tableColumns,
id,
hideColumns,
isRooms,
} = props;
const { acceptBackground, background } = theme.dragAndDrop;
@ -374,33 +92,6 @@ const FilesTableRow = (props) => {
}
}, [checkedProps, isActive, showHotkeyBorder]);
let availableColumns = [];
let authorAvailableDrag = true;
let createdAvailableDrag = true;
let modifiedAvailableDrag = true;
let sizeAvailableDrag = true;
let typeAvailableDrag = true;
let ownerAvailableDrag = true;
let tagsAvailableDrag = true;
let activityAvailableDrag = true;
let buttonsAvailableDrag = true;
if (dragging && isDragging) {
availableColumns = localStorage.getItem(tableColumns).split(",");
authorAvailableDrag = availableColumns.includes("Author") && !hideColumns;
createdAvailableDrag = availableColumns.includes("Created") && !hideColumns;
modifiedAvailableDrag =
availableColumns.includes("Modified") && !hideColumns;
sizeAvailableDrag = availableColumns.includes("Size") && !hideColumns;
typeAvailableDrag = availableColumns.includes("Type") && !hideColumns;
buttonsAvailableDrag = availableColumns.includes("QuickButtons");
ownerAvailableDrag = availableColumns.includes("Owner") && !hideColumns;
tagsAvailableDrag = availableColumns.includes("Tags") && !hideColumns;
activityAvailableDrag =
availableColumns.includes("Activity") && !hideColumns;
}
const idWithFileExst = item.fileExst
? `${item.id}_${item.fileExst}`
: item.id ?? "";
@ -446,161 +137,18 @@ const FilesTableRow = (props) => {
}
isRoom={item.isRoom}
>
<TableCell
{...dragStyles}
className={classNames(
selectionProp?.className,
"table-container_file-name-cell"
)}
value={value}
>
<FileNameCell
theme={theme}
onContentSelect={onContentFileSelect}
checked={checkedProps}
{isRooms ? (
<RoomsRowDataComponent
element={element}
inProgress={inProgress}
dragStyles={dragStyles}
{...props}
/>
<StyledBadgesContainer showHotkeyBorder={showHotkeyBorder}>
{badgesComponent}
</StyledBadgesContainer>
</TableCell>
{(item.isRoom || isRooms) && (
<TableCell
style={
!typeAvailableDrag
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TypeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
{!item.isRoom && isRooms && (
<TableCell
style={
!typeAvailableDrag
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
></TableCell>
)}
{item.isRoom && (
<TableCell
style={
!tagsAvailableDrag
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TagsCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
{!personal && (
<TableCell
style={
!authorAvailableDrag && !ownerAvailableDrag
? { background: "none" }
: dragStyles.style
}
{...selectionProp}
>
<AuthorCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
{!item.isRoom && !isRooms && (
<TableCell
style={
!createdAvailableDrag
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<DateCell
create
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
<TableCell
style={
!modifiedAvailableDrag && !activityAvailableDrag
? { background: "none" }
: dragStyles.style
}
{...selectionProp}
>
<DateCell
sideColor={theme.filesSection.tableView.row.sideColor}
) : (
<RowDataComponent
element={element}
dragStyles={dragStyles}
{...props}
/>
</TableCell>
{!item.isRoom && !isRooms && (
<TableCell
style={
!sizeAvailableDrag ? { background: "none" } : dragStyles.style
}
{...selectionProp}
>
<SizeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
{!item.isRoom && !isRooms && (
<TableCell
style={
!typeAvailableDrag
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TypeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
)}
{!item.isRoom && !isRooms && (
<TableCell
style={
!buttonsAvailableDrag ? { background: "none" } : dragStyles.style
}
{...selectionProp}
className={classNames(
selectionProp?.className,
"table-container_quick-buttons-wrapper"
)}
>
<StyledQuickButtonsContainer>
{quickButtonsComponent}
</StyledQuickButtonsContainer>
</TableCell>
)}
</StyledTableRow>
</StyledDragAndDrop>

View File

@ -0,0 +1,143 @@
import React from "react";
import { inject, observer } from "mobx-react";
import TableCell from "@docspace/components/table-container/TableCell";
import FileNameCell from "./FileNameCell";
import TypeCell from "./TypeCell";
import TagsCell from "./TagsCell";
import AuthorCell from "./AuthorCell";
import DateCell from "./DateCell";
import { classNames } from "@docspace/components/utils/classNames";
import { StyledBadgesContainer } from "../StyledTable";
const RoomsRowDataComponent = (props) => {
const {
roomColumnTypeIsEnabled,
roomColumnOwnerIsEnabled,
roomColumnTagsIsEnabled,
roomColumnActivityIsEnabled,
dragStyles,
selectionProp,
value,
theme,
onContentFileSelect,
checkedProps,
element,
inProgress,
showHotkeyBorder,
badgesComponent,
} = props;
return (
<>
<TableCell
{...dragStyles}
className={classNames(
selectionProp?.className,
"table-container_file-name-cell"
)}
value={value}
>
<FileNameCell
theme={theme}
onContentSelect={onContentFileSelect}
checked={checkedProps}
element={element}
inProgress={inProgress}
{...props}
/>
<StyledBadgesContainer showHotkeyBorder={showHotkeyBorder}>
{badgesComponent}
</StyledBadgesContainer>
</TableCell>
{roomColumnTypeIsEnabled ? (
<TableCell
style={
!roomColumnTypeIsEnabled
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TypeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{roomColumnTagsIsEnabled ? (
<TableCell
style={
!roomColumnTagsIsEnabled
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TagsCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{roomColumnOwnerIsEnabled ? (
<TableCell
style={
!roomColumnOwnerIsEnabled
? { background: "none" }
: dragStyles.style
}
{...selectionProp}
>
<AuthorCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{roomColumnActivityIsEnabled ? (
<TableCell
style={
!roomColumnActivityIsEnabled
? { background: "none" }
: dragStyles.style
}
{...selectionProp}
>
<DateCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
</>
);
};
export default inject(({ tableStore }) => {
const {
roomColumnTypeIsEnabled,
roomColumnOwnerIsEnabled,
roomColumnTagsIsEnabled,
roomColumnActivityIsEnabled,
} = tableStore;
return {
roomColumnTypeIsEnabled,
roomColumnOwnerIsEnabled,
roomColumnTagsIsEnabled,
roomColumnActivityIsEnabled,
};
})(observer(RoomsRowDataComponent));

View File

@ -0,0 +1,186 @@
import React from "react";
import { inject, observer } from "mobx-react";
import TableCell from "@docspace/components/table-container/TableCell";
import FileNameCell from "./FileNameCell";
import TypeCell from "./TypeCell";
import AuthorCell from "./AuthorCell";
import DateCell from "./DateCell";
import SizeCell from "./SizeCell";
import { classNames } from "@docspace/components/utils/classNames";
import {
StyledBadgesContainer,
StyledQuickButtonsContainer,
} from "../StyledTable";
const RowDataComponent = (props) => {
const {
authorColumnIsEnabled,
createdColumnIsEnabled,
modifiedColumnIsEnabled,
sizeColumnIsEnabled,
typeColumnIsEnabled,
quickButtonsColumnIsEnabled,
dragStyles,
selectionProp,
value,
theme,
onContentFileSelect,
checkedProps,
element,
inProgress,
showHotkeyBorder,
badgesComponent,
quickButtonsComponent,
} = props;
return (
<>
<TableCell
{...dragStyles}
className={classNames(
selectionProp?.className,
"table-container_file-name-cell"
)}
value={value}
>
<FileNameCell
theme={theme}
onContentSelect={onContentFileSelect}
checked={checkedProps}
element={element}
inProgress={inProgress}
{...props}
/>
<StyledBadgesContainer showHotkeyBorder={showHotkeyBorder}>
{badgesComponent}
</StyledBadgesContainer>
</TableCell>
{authorColumnIsEnabled ? (
<TableCell
style={
!authorColumnIsEnabled ? { background: "none" } : dragStyles.style
}
{...selectionProp}
>
<AuthorCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{createdColumnIsEnabled ? (
<TableCell
style={
!createdColumnIsEnabled
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<DateCell
create
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{modifiedColumnIsEnabled ? (
<TableCell
style={
!modifiedColumnIsEnabled ? { background: "none" } : dragStyles.style
}
{...selectionProp}
>
<DateCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{sizeColumnIsEnabled ? (
<TableCell
style={
!sizeColumnIsEnabled ? { background: "none" } : dragStyles.style
}
{...selectionProp}
>
<SizeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{typeColumnIsEnabled ? (
<TableCell
style={
!typeColumnIsEnabled
? { background: "none !important" }
: dragStyles.style
}
{...selectionProp}
>
<TypeCell
sideColor={theme.filesSection.tableView.row.sideColor}
{...props}
/>
</TableCell>
) : (
<div />
)}
{quickButtonsColumnIsEnabled ? (
<TableCell
style={
!quickButtonsColumnIsEnabled
? { background: "none" }
: dragStyles.style
}
{...selectionProp}
className={classNames(
selectionProp?.className,
"table-container_quick-buttons-wrapper"
)}
>
<StyledQuickButtonsContainer>
{quickButtonsComponent}
</StyledQuickButtonsContainer>
</TableCell>
) : (
<div />
)}
</>
);
};
export default inject(({ tableStore }) => {
const {
authorColumnIsEnabled,
createdColumnIsEnabled,
modifiedColumnIsEnabled,
sizeColumnIsEnabled,
typeColumnIsEnabled,
quickButtonsColumnIsEnabled,
} = tableStore;
return {
authorColumnIsEnabled,
createdColumnIsEnabled,
modifiedColumnIsEnabled,
sizeColumnIsEnabled,
typeColumnIsEnabled,
quickButtonsColumnIsEnabled,
};
})(observer(RowDataComponent));

View File

@ -0,0 +1,205 @@
import { makeAutoObservable } from "mobx";
import { TableVersions } from "SRC_DIR/helpers/constants";
const TABLE_COLUMNS = `filesTableColumns_ver-${TableVersions.Files}`;
const TABLE_ROOMS_COLUMNS = `roomsTableColumns_ver-${TableVersions.Rooms}`;
const COLUMNS_SIZE = `filesColumnsSize_ver-${TableVersions.Files}`;
const COLUMNS_ROOMS_SIZE = `roomsColumnsSize_ver-${TableVersions.Rooms}`;
const COLUMNS_SIZE_INFO_PANEL = `filesColumnsSizeInfoPanel_ver-${TableVersions.Files}`;
const COLUMNS_ROOMS_SIZE_INFO_PANEL = `roomsColumnsSizeInfoPanel_ver-${TableVersions.Rooms}`;
class TableStore {
authStore;
treeFoldersStore;
roomColumnNameIsEnabled = true; // always true
roomColumnTypeIsEnabled = false;
roomColumnTagsIsEnabled = true;
roomColumnOwnerIsEnabled = false;
roomColumnActivityIsEnabled = true;
nameColumnIsEnabled = true; // always true
authorColumnIsEnabled = false;
createdColumnIsEnabled = true;
modifiedColumnIsEnabled = true;
sizeColumnIsEnabled = true;
typeColumnIsEnabled = true;
quickButtonsColumnIsEnabled = true;
constructor(authStore, treeFoldersStore) {
makeAutoObservable(this);
this.authStore = authStore;
this.treeFoldersStore = treeFoldersStore;
}
setRoomColumnType = (enable) => {
this.roomColumnTypeIsEnabled = enable;
};
setRoomColumnTags = (enable) => {
this.roomColumnTagsIsEnabled = enable;
};
setRoomColumnOwner = (enable) => {
this.roomColumnOwnerIsEnabled = enable;
};
setRoomColumnActivity = (enable) => {
this.roomColumnActivityIsEnabled = enable;
};
setAuthorColumn = (enable) => {
this.authorColumnIsEnabled = enable;
};
setCreatedColumn = (enable) => {
this.createdColumnIsEnabled = enable;
};
setModifiedColumn = (enable) => {
this.modifiedColumnIsEnabled = enable;
};
setSizeColumn = (enable) => {
this.sizeColumnIsEnabled = enable;
};
setTypeColumn = (enable) => {
this.typeColumnIsEnabled = enable;
};
setQuickButtonsColumn = (enable) => {
this.quickButtonsColumnIsEnabled = enable;
};
setColumnsEnable = () => {
const storageColumns = localStorage.getItem(this.tableStorageName);
const splitColumns = storageColumns && storageColumns.split(",");
if (splitColumns) {
const { isRoomsFolder, isArchiveFolder } = this.treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
if (isRooms) {
this.setRoomColumnType(splitColumns.includes("Type"));
this.setRoomColumnTags(splitColumns.includes("Tags"));
this.setRoomColumnOwner(splitColumns.includes("Owner"));
this.setRoomColumnActivity(splitColumns.includes("Activity"));
} else {
this.setAuthorColumn(splitColumns.includes("Author"));
this.setCreatedColumn(splitColumns.includes("Created"));
this.setModifiedColumn(splitColumns.includes("Modified"));
this.setSizeColumn(splitColumns.includes("Size"));
this.setTypeColumn(splitColumns.includes("Type"));
this.setQuickButtonsColumn(splitColumns.includes("QuickButtons"));
}
}
};
setColumnEnable = (key) => {
const { isRoomsFolder, isArchiveFolder } = this.treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
switch (key) {
case "Author":
this.setAuthorColumn(!this.authorColumnIsEnabled);
return;
case "Created":
this.setCreatedColumn(!this.createdColumnIsEnabled);
return;
case "Modified":
this.setModifiedColumn(!this.modifiedColumnIsEnabled);
return;
case "Size":
this.setSizeColumn(!this.sizeColumnIsEnabled);
return;
case "Type":
isRooms
? this.setRoomColumnType(!this.roomColumnTypeIsEnabled)
: this.setTypeColumn(!this.typeColumnIsEnabled);
return;
case "QuickButtons":
this.setQuickButtonsColumn(!this.quickButtonsColumnIsEnabled);
return;
case "Owner":
this.setRoomColumnOwner(!this.roomColumnOwnerIsEnabled);
return;
case "Tags":
this.setRoomColumnTags(!this.roomColumnTagsIsEnabled);
return;
case "Activity":
this.setRoomColumnActivity(!this.roomColumnActivityIsEnabled);
return;
default:
return;
}
};
getColumns = (defaultColumns) => {
const storageColumns = localStorage.getItem(this.tableStorageName);
const splitColumns = storageColumns && storageColumns.split(",");
const columns = [];
if (splitColumns) {
this.setColumnsEnable();
for (let col of defaultColumns) {
const column = splitColumns.find((key) => key === col.key);
column ? (col.enable = true) : (col.enable = false);
columns.push(col);
}
return columns;
} else {
return defaultColumns;
}
};
get tableStorageName() {
const { isRoomsFolder, isArchiveFolder } = this.treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
const userId = this.authStore.userStore.user.id;
return isRooms
? `${TABLE_ROOMS_COLUMNS}=${userId}`
: `${TABLE_COLUMNS}=${userId}`;
}
get columnStorageName() {
const { isRoomsFolder, isArchiveFolder } = this.treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
const userId = this.authStore.userStore.user.id;
return isRooms
? `${COLUMNS_ROOMS_SIZE}=${userId}`
: `${COLUMNS_SIZE}=${userId}`;
}
get columnInfoPanelStorageName() {
const { isRoomsFolder, isArchiveFolder } = this.treeFoldersStore;
const isRooms = isRoomsFolder || isArchiveFolder;
const userId = this.authStore.userStore.user.id;
return isRooms
? `${COLUMNS_ROOMS_SIZE_INFO_PANEL}=${userId}`
: `${COLUMNS_SIZE_INFO_PANEL}=${userId}`;
}
get filesColumnStorageName() {
const userId = this.authStore.userStore.user.id;
return `${COLUMNS_SIZE}=${userId}`;
}
get roomsColumnStorageName() {
const userId = this.authStore.userStore.user.id;
return `${COLUMNS_ROOMS_SIZE}=${userId}`;
}
get filesColumnInfoPanelStorageName() {
const userId = this.authStore.userStore.user.id;
return `${COLUMNS_SIZE_INFO_PANEL}=${userId}`;
}
get roomsColumnInfoPanelStorageName() {
const userId = this.authStore.userStore.user.id;
return `${COLUMNS_ROOMS_SIZE_INFO_PANEL}=${userId}`;
}
}
export default TableStore;

View File

@ -31,6 +31,7 @@ import TagsStore from "./TagsStore";
import PeopleStore from "./PeopleStore";
import OformsStore from "./OformsStore";
import AccessRightsStore from "./AccessRightsStore";
import TableStore from "./TableStore";
const oformsStore = new OformsStore(authStore);
@ -136,6 +137,8 @@ const profileActionsStore = new ProfileActionsStore(
selectedFolderStore
);
const tableStore = new TableStore(authStore, treeFoldersStore);
authStore.infoPanelStore.authStore = authStore;
authStore.infoPanelStore.settingsStore = settingsStore;
authStore.infoPanelStore.filesStore = filesStore;
@ -170,6 +173,7 @@ const store = {
hotkeyStore,
selectFileDialogStore,
oformsStore,
tableStore,
tagsStore,