From 64f455eb59219bee506403b2bcfc50a1382b65ff Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 9 Jul 2021 11:59:20 +0300 Subject: [PATCH 01/74] Web: init table view --- packages/asc-web-components/index.js | 1 + .../table-container/Column.js | 111 ++++++++++++++++++ .../table-container/StyledTableContainer.js | 53 +++++++++ .../table-container/TableCell.js | 8 ++ .../table-container/TableContainer.js | 13 ++ .../table-container/index.js | 1 + .../Home/Section/Body/TableView/TableCell.js | 43 +++++++ .../Section/Body/TableView/TableContainer.js | 82 +++++++++++++ .../TableView/sub-components/FileNameCell.js | 36 ++++++ .../Body/TableView/sub-components/SizeCell.js | 36 ++++++ .../src/pages/Home/Section/Body/index.js | 6 +- 11 files changed, 389 insertions(+), 1 deletion(-) create mode 100644 packages/asc-web-components/table-container/Column.js create mode 100644 packages/asc-web-components/table-container/StyledTableContainer.js create mode 100644 packages/asc-web-components/table-container/TableCell.js create mode 100644 packages/asc-web-components/table-container/TableContainer.js create mode 100644 packages/asc-web-components/table-container/index.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js diff --git a/packages/asc-web-components/index.js b/packages/asc-web-components/index.js index 7ed002fd79..77b1e24f4a 100644 --- a/packages/asc-web-components/index.js +++ b/packages/asc-web-components/index.js @@ -62,3 +62,4 @@ export { default as DragAndDrop } from "./drag-and-drop"; export { default as ViewSelector } from "./view-selector"; export * as Themes from "./themes"; export { default as Portal } from "./portal"; +export { default as TableContainer } from "./TableContainer"; diff --git a/packages/asc-web-components/table-container/Column.js b/packages/asc-web-components/table-container/Column.js new file mode 100644 index 0000000000..5735db50c3 --- /dev/null +++ b/packages/asc-web-components/table-container/Column.js @@ -0,0 +1,111 @@ +import React, { useEffect, useState } from "react"; +import PropTypes from "prop-types"; + +const Column = ({ + id, + index, + title, + resizable, + children, + containerRef, + className, + ...rest +}) => { + const [columnIndex, setColumnIndex] = useState(null); + + const getSubstring = (str) => str.substring(0, str.length - 1); + + const onMouseMove = (e) => { + if (!columnIndex) return; + const column = document.getElementById("column_" + columnIndex); + + const columnSize = column.getBoundingClientRect(); + const newWidth = e.clientX - columnSize.left; + const percentWidth = (newWidth / containerRef.current.clientWidth) * 100; + + const { width, minWidth } = column.style; + + const clearPercent = getSubstring(width); + + if (percentWidth - 2 <= getSubstring(minWidth)) { + return; + } + + const offset = +percentWidth.toFixed(3) - clearPercent; + const column2 = document.getElementById("column_" + (+columnIndex + 1)); + const column2Width = column2 && getSubstring(column2.style.width); + + if (column2) { + if (+percentWidth.toFixed(3) < clearPercent) { + const width2 = column2Width - offset; + column2.style.width = width2 + "%"; + } else if (+percentWidth.toFixed(3) > clearPercent) { + const width2 = +column2Width - offset; + + if (width2 - 2 <= getSubstring(column2.style.minWidth)) { + return; + } + + column2.style.width = width2 + "%"; + } else return; + } + + column.style.width = percentWidth + "%"; + }; + + const onMouseUp = () => { + window.removeEventListener("mousemove", onMouseMove); + window.removeEventListener("mouseup", onMouseUp); + }; + + const onMouseDown = (event) => { + setColumnIndex(event.target.dataset.column); + }; + + useEffect(() => { + if (columnIndex !== null) { + window.addEventListener("mousemove", onMouseMove); + window.addEventListener("mouseup", onMouseUp); + } + + return () => { + window.removeEventListener("mousemove", onMouseMove); + window.removeEventListener("mouseup", onMouseUp); + }; + }, [columnIndex, onMouseMove, onMouseUp]); + + return ( +
+
+ {title} + {index} +
+
{children}
+ {resizable && ( +
+ )} +
+ ); +}; + +Column.propTypes = { + id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + className: PropTypes.string, + style: PropTypes.object, + children: PropTypes.any, + index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + title: PropTypes.string, + resizable: PropTypes.bool, + containerRef: PropTypes.shape({ current: PropTypes.any }), +}; + +export default Column; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js new file mode 100644 index 0000000000..a8c55849ab --- /dev/null +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -0,0 +1,53 @@ +import styled from "styled-components"; + +const StyledTableContainer = styled.div` + width: 100%; + display: flex; + + .table-column { + user-select: none; + position: relative; + min-width: 10%; + } + + .resize-handle { + display: block; + position: absolute; + cursor: ew-resize; + height: 10px; + width: 7px; + right: 4px; + top: 4px; + z-index: 1; + border-right: 2px solid transparent; + border-color: #d0d5da; + } + + .header-container { + border-bottom: 2px solid grey; + } + + .content-container { + overflow: hidden; + } + + .children-wrap { + display: flex; + flex-direction: column; + } + + .table-cell { + height: 47px; + border-bottom: 1px solid #eceef1; + } +`; + +const StyledTableCell = styled.div` + height: 47px; + max-height: 47px; + display: flex; + align-items: center; + border-bottom: 1px solid #eceef1; +`; + +export { StyledTableContainer, StyledTableCell }; diff --git a/packages/asc-web-components/table-container/TableCell.js b/packages/asc-web-components/table-container/TableCell.js new file mode 100644 index 0000000000..f1fffea5d2 --- /dev/null +++ b/packages/asc-web-components/table-container/TableCell.js @@ -0,0 +1,8 @@ +import React from "react"; +import { StyledTableCell } from "./StyledTableContainer"; + +const TableCell = (props) => { + return ; +}; + +export default TableCell; diff --git a/packages/asc-web-components/table-container/TableContainer.js b/packages/asc-web-components/table-container/TableContainer.js new file mode 100644 index 0000000000..bd110eacfb --- /dev/null +++ b/packages/asc-web-components/table-container/TableContainer.js @@ -0,0 +1,13 @@ +import React from "react"; +import { StyledTableContainer } from "./StyledTableContainer"; +import PropTypes from "prop-types"; + +const TableContainer = (props) => { + return ; +}; + +TableContainer.propTypes = { + forwardedRef: PropTypes.shape({ current: PropTypes.any }), +}; + +export default TableContainer; diff --git a/packages/asc-web-components/table-container/index.js b/packages/asc-web-components/table-container/index.js new file mode 100644 index 0000000000..13e6eba3bb --- /dev/null +++ b/packages/asc-web-components/table-container/index.js @@ -0,0 +1 @@ +export default from "./TableContainer"; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js new file mode 100644 index 0000000000..05024a78f8 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js @@ -0,0 +1,43 @@ +import React from "react"; +import { withRouter } from "react-router"; +import withContent from "../../../../../HOCs/withContent"; +import withBadges from "../../../../../HOCs/withBadges"; +import withFileActions from "../../../../../HOCs/withFileActions"; +import withContextOptions from "../../../../../HOCs/withContextOptions"; +import { withTranslation } from "react-i18next"; +import TableCell from "@appserver/components/table-container/TableCell"; +import FileNameCell from "./sub-components/FileNameCell"; +import SizeCell from "./sub-components/SizeCell"; + +const TableCellFiles = (props) => { + const { column } = props; + + const getElem = () => { + let field = null; + for (let inc of column.includes) { + if (field) { + field = field[inc]; + } else { + field = inc; + } + } + + switch (field) { + case "title": + return ; + case "contentLength": + return ; + + default: + return <>; + } + }; + + return {getElem()}; +}; + +export default withTranslation("Home")( + withFileActions( + withRouter(withContextOptions(withContent(withBadges(TableCellFiles)))) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js new file mode 100644 index 0000000000..3382707524 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -0,0 +1,82 @@ +import React, { useRef } from "react"; +import TableContainer from "@appserver/components/table-container"; +import { inject, observer } from "mobx-react"; +import Column from "@appserver/components/table-container/Column"; +import TableCell from "./TableCell"; + +const Table = ({ filesList }) => { + const columns = [ + { + key: -1, + title: "Checkbox", + includes: ["checked"], + resizable: false, + }, + { + key: 0, + title: "Name", + includes: ["title"], + resizable: true, + }, + { + key: 1, + title: "Author", + includes: ["createdBy", "displayName"], + resizable: true, + }, + { + key: 2, + title: "Created", + includes: ["created"], + resizable: true, + }, + // { + // key: 3, + // title: "Type", + // includes: [""], + // resizable: true, + // }, + { + key: 4, + title: "Size", + includes: ["contentLength"], + resizable: true, + }, + { + key: 5, + title: "Settings$#", + includes: [""], + resizable: false, + }, + ]; + + const ref = useRef(null); + + return ( + + {columns.map((column, index) => { + const { key, title, resizable } = column; + + return ( + + {filesList.map((item) => ( + + ))} + + ); + })} + + ); +}; + +export default inject(({ filesStore }) => { + const { filesList } = filesStore; + return { filesList }; +})(observer(Table)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js new file mode 100644 index 0000000000..5fa73ff4a3 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js @@ -0,0 +1,36 @@ +import React from "react"; +import Link from "@appserver/components/link"; +import Text from "@appserver/components/text"; + +const FileNameCell = (props) => { + const { item, titleWithoutExt, linkStyles } = props; + const { fileExst } = item; + return ( + + {titleWithoutExt} + {fileExst ? ( + + {fileExst} + + ) : null} + + ); +}; + +export default FileNameCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js new file mode 100644 index 0000000000..cc583acfb6 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js @@ -0,0 +1,36 @@ +import React from "react"; +import Text from "@appserver/components/text"; +import globalColors from "@appserver/components/utils/globalColors"; + +const sideColor = globalColors.gray; + +const SizeCell = (props) => { + const { t, item } = props; + const { + fileExst, + contentLength, + providerKey, + filesCount, + foldersCount, + } = item; + return ( + + {fileExst || contentLength + ? contentLength + : !providerKey + ? `${t("TitleDocuments")}: ${filesCount} | ${t( + "TitleSubfolders" + )}: ${foldersCount}` + : ""} + + ); +}; + +export default SizeCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js index 37c31007ba..ae0505a6af 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js @@ -8,6 +8,8 @@ import FilesTileContainer from "./TilesView/FilesTileContainer"; import EmptyContainer from "../../../../components/EmptyContainer"; import withLoader from "../../../../HOCs/withLoader"; +import TableView from "./TableView/TableContainer"; + let currentDroppable = null; const SectionBodyContent = (props) => { @@ -157,7 +159,9 @@ const SectionBodyContent = (props) => { return (!fileActionId && isEmptyFilesList) || null ? ( ) : viewAs === "tile" ? ( - + + ) : viewAs === "table" || viewAs === "row" ? ( + ) : ( ); From 1a06bd6a83e261b57cf4690d261f6d2d127d7f0b Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 9 Jul 2021 12:00:05 +0300 Subject: [PATCH 02/74] Web: Files: hid inLoad log --- products/ASC.Files/Client/src/HOCs/withLoader.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/products/ASC.Files/Client/src/HOCs/withLoader.js b/products/ASC.Files/Client/src/HOCs/withLoader.js index c9537ba1af..13a8006027 100644 --- a/products/ASC.Files/Client/src/HOCs/withLoader.js +++ b/products/ASC.Files/Client/src/HOCs/withLoader.js @@ -19,12 +19,12 @@ const withLoader = (WrappedComponent) => (Loader) => { if (isLoading) { cleanTimer(); loadTimeout = setTimeout(() => { - console.log("inLoad", true); + //console.log("inLoad", true); setInLoad(true); }, 500); } else { cleanTimer(); - console.log("inLoad", false); + //console.log("inLoad", false); setInLoad(false); } From 39b716326764ea000fd814e6fef853c15989de48 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 9 Jul 2021 13:39:09 +0300 Subject: [PATCH 03/74] Web: Files: added new table cells, fixed table styles --- .../table-container/Column.js | 11 +++++--- .../table-container/StyledTableContainer.js | 11 ++++---- .../table-container/TableContainer.js | 8 +++++- .../Home/Section/Body/TableView/TableCell.js | 27 ++++++++++++++----- .../TableView/sub-components/AuthorCell.js | 21 +++++++++++++++ .../TableView/sub-components/CreatedCell.js | 23 ++++++++++++++++ .../Body/TableView/sub-components/SizeCell.js | 5 +--- 7 files changed, 86 insertions(+), 20 deletions(-) create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js diff --git a/packages/asc-web-components/table-container/Column.js b/packages/asc-web-components/table-container/Column.js index 5735db50c3..b61c926fd4 100644 --- a/packages/asc-web-components/table-container/Column.js +++ b/packages/asc-web-components/table-container/Column.js @@ -1,5 +1,7 @@ import React, { useEffect, useState } from "react"; +import Text from "../text"; import PropTypes from "prop-types"; +import globalColors from "@appserver/components/utils/globalColors"; const Column = ({ id, @@ -81,10 +83,13 @@ const Column = ({ className={`${className} table-column`} {...rest} > -
+ {title} - {index} -
+
{children}
{resizable && (
{ - return ; + return ( + + ); }; TableContainer.propTypes = { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js index 05024a78f8..4941ce907f 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js @@ -8,25 +8,38 @@ import { withTranslation } from "react-i18next"; import TableCell from "@appserver/components/table-container/TableCell"; import FileNameCell from "./sub-components/FileNameCell"; import SizeCell from "./sub-components/SizeCell"; +import AuthorCell from "./sub-components/AuthorCell"; +import CreatedCell from "./sub-components/CreatedCell"; +import globalColors from "@appserver/components/utils/globalColors"; + +const sideColor = globalColors.gray; const TableCellFiles = (props) => { - const { column } = props; + const { column, item } = props; const getElem = () => { let field = null; for (let inc of column.includes) { - if (field) { - field = field[inc]; - } else { - field = inc; - } + field = inc; + // if (field) { + // console.log("123", field); + // console.log("inc", inc); + // field = field[inc]; + // console.log("234", field); + // } else { + // field = inc; + // } } switch (field) { case "title": return ; case "contentLength": - return ; + return ; + case "displayName": + return ; + case "created": + return ; default: return <>; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js new file mode 100644 index 0000000000..ffa06a8b33 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js @@ -0,0 +1,21 @@ +import React from "react"; +import Text from "@appserver/components/text"; + +const AuthorCell = (props) => { + const { fileOwner, sideColor } = props; + + return ( + + {fileOwner} + + ); +}; + +export default AuthorCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js new file mode 100644 index 0000000000..37ecafbf8c --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js @@ -0,0 +1,23 @@ +import React from "react"; +import Text from "@appserver/components/text"; + +const AuthorCell = (props) => { + const { updatedDate, sideColor, item } = props; + const { fileExst, contentLength, providerKey } = item; + + return ( + + {(fileExst || contentLength || !providerKey) && + updatedDate && + updatedDate} + + ); +}; + +export default AuthorCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js index cc583acfb6..452bc9a97e 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/SizeCell.js @@ -1,11 +1,8 @@ import React from "react"; import Text from "@appserver/components/text"; -import globalColors from "@appserver/components/utils/globalColors"; - -const sideColor = globalColors.gray; const SizeCell = (props) => { - const { t, item } = props; + const { t, item, sideColor } = props; const { fileExst, contentLength, From 08a380d5aa013d155d91600554d4737053557606 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 13 Jul 2021 11:07:50 +0300 Subject: [PATCH 04/74] Web: Table: changed the logic of work --- .../table-container/StyledTableContainer.js | 27 +++-- .../table-container/TableBody.js | 8 ++ .../table-container/TableContainer.js | 8 +- .../table-container/TableHeader.js | 105 ++++++++++++++++++ .../table-container/TableRow.js | 8 ++ .../table-container/TableTd.js | 8 ++ .../Section/Body/TableView/TableContainer.js | 29 ++--- .../TableView/sub-components/AuthorCell.js | 5 +- .../TableView/sub-components/CheckboxCell.js | 40 +++++++ .../TableView/sub-components/CreatedCell.js | 4 +- .../TableView/sub-components/FileNameCell.js | 4 +- .../Body/TableView/sub-components/SizeCell.js | 4 +- 12 files changed, 204 insertions(+), 46 deletions(-) create mode 100644 packages/asc-web-components/table-container/TableBody.js create mode 100644 packages/asc-web-components/table-container/TableHeader.js create mode 100644 packages/asc-web-components/table-container/TableRow.js create mode 100644 packages/asc-web-components/table-container/TableTd.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CheckboxCell.js diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 23e95734f7..edda2c968b 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -1,8 +1,10 @@ import styled from "styled-components"; -const StyledTableContainer = styled.div` +const StyledTableContainer = styled.table` width: 100%; - display: flex; + max-width: 100%; + margin-top: -18px; + border-collapse: collapse; .table-column { user-select: none; @@ -12,18 +14,15 @@ const StyledTableContainer = styled.div` .resize-handle { display: block; - position: absolute; cursor: ew-resize; height: 10px; - right: 4px; - top: 14px; + margin: 14px 4px 0 auto; z-index: 1; border-right: 2px solid #d0d5da; } .header-container { height: 38px; - border-bottom: 1px solid #eceef1; display: flex; align-items: center; } @@ -43,12 +42,20 @@ const StyledTableContainer = styled.div` } `; -const StyledTableCell = styled.div` +const StyledTableRow = styled.tr` height: 47px; max-height: 47px; - display: flex; - align-items: center; border-bottom: 1px solid #eceef1; `; -export { StyledTableContainer, StyledTableCell }; +const StyledTableHeader = styled.thead``; +const StyledTableBody = styled.tbody``; +const StyledTableCell = styled.td``; + +export { + StyledTableContainer, + StyledTableRow, + StyledTableBody, + StyledTableHeader, + StyledTableCell, +}; diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js new file mode 100644 index 0000000000..d9ff6647f0 --- /dev/null +++ b/packages/asc-web-components/table-container/TableBody.js @@ -0,0 +1,8 @@ +import React from "react"; +import { StyledTableBody } from "./StyledTableContainer"; + +const TableBody = (props) => { + return ; +}; + +export default TableBody; diff --git a/packages/asc-web-components/table-container/TableContainer.js b/packages/asc-web-components/table-container/TableContainer.js index 7324519122..bd110eacfb 100644 --- a/packages/asc-web-components/table-container/TableContainer.js +++ b/packages/asc-web-components/table-container/TableContainer.js @@ -3,13 +3,7 @@ import { StyledTableContainer } from "./StyledTableContainer"; import PropTypes from "prop-types"; const TableContainer = (props) => { - return ( - - ); + return ; }; TableContainer.propTypes = { diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js new file mode 100644 index 0000000000..8f2c350a05 --- /dev/null +++ b/packages/asc-web-components/table-container/TableHeader.js @@ -0,0 +1,105 @@ +import React, { useEffect, useState } from "react"; +import Text from "../text"; +import globalColors from "../utils/globalColors"; +import { StyledTableHeader } from "./StyledTableContainer"; +import TableRow from "./TableRow"; + +const TableHeader = ({ columns, containerRef, ...rest }) => { + const style = { minWidth: "10%", width: "16%" }; + + const [columnIndex, setColumnIndex] = useState(null); + + const getSubstring = (str) => str.substring(0, str.length - 1); + + const onMouseMove = (e) => { + if (!columnIndex) return; + const column = document.getElementById("column_" + columnIndex); + + const columnSize = column.getBoundingClientRect(); + const newWidth = e.clientX - columnSize.left; + const percentWidth = (newWidth / containerRef.current.clientWidth) * 100; + + const { width, minWidth } = column.style; + + const clearPercent = getSubstring(width); + + if (percentWidth - 2 <= getSubstring(minWidth)) { + return; + } + + const offset = +percentWidth.toFixed(3) - clearPercent; + const column2 = document.getElementById("column_" + (+columnIndex + 1)); + const column2Width = column2 && getSubstring(column2.style.width); + + if (column2) { + if (+percentWidth.toFixed(3) < clearPercent) { + const width2 = column2Width - offset; + column2.style.width = width2 + "%"; + } else if (+percentWidth.toFixed(3) > clearPercent) { + const width2 = +column2Width - offset; + + if (width2 - 2 <= getSubstring(column2.style.minWidth)) { + return; + } + + column2.style.width = width2 + "%"; + } else return; + } + + column.style.width = percentWidth + "%"; + }; + + const onMouseUp = () => { + window.removeEventListener("mousemove", onMouseMove); + window.removeEventListener("mouseup", onMouseUp); + }; + + const onMouseDown = (event) => { + setColumnIndex(event.target.dataset.column); + window.addEventListener("mousemove", onMouseMove); + window.addEventListener("mouseup", onMouseUp); + }; + + // useEffect(() => { + // if (columnIndex !== null) { + // window.addEventListener("mousemove", onMouseMove); + // window.addEventListener("mouseup", onMouseUp); + // } + + // return () => { + // window.removeEventListener("mousemove", onMouseMove); + // window.removeEventListener("mouseup", onMouseUp); + // }; + // }, [columnIndex, onMouseMove, onMouseUp]); + + return ( + + + {columns.map((column, index) => { + return ( + +
+ + {column.title} + + {column.resizable && ( +
+ )} +
+ + ); + })} + + + ); +}; + +export default TableHeader; diff --git a/packages/asc-web-components/table-container/TableRow.js b/packages/asc-web-components/table-container/TableRow.js new file mode 100644 index 0000000000..f24f1fec2d --- /dev/null +++ b/packages/asc-web-components/table-container/TableRow.js @@ -0,0 +1,8 @@ +import React from "react"; +import { StyledTableRow } from "./StyledTableContainer"; + +const TableRow = (props) => { + return ; +}; + +export default TableRow; diff --git a/packages/asc-web-components/table-container/TableTd.js b/packages/asc-web-components/table-container/TableTd.js new file mode 100644 index 0000000000..a2cde111fc --- /dev/null +++ b/packages/asc-web-components/table-container/TableTd.js @@ -0,0 +1,8 @@ +import React from "react"; +import { StyledTableTd } from "./StyledTableContainer"; + +const TableTd = (props) => { + return ; +}; + +export default TableTd; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js index 3382707524..3f63cf5361 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -1,8 +1,9 @@ import React, { useRef } from "react"; import TableContainer from "@appserver/components/table-container"; import { inject, observer } from "mobx-react"; -import Column from "@appserver/components/table-container/Column"; -import TableCell from "./TableCell"; +import TableRow from "./TableRow"; +import TableHeader from "@appserver/components/table-container/TableHeader"; +import TableBody from "@appserver/components/table-container/TableBody"; const Table = ({ filesList }) => { const columns = [ @@ -54,24 +55,12 @@ const Table = ({ filesList }) => { return ( - {columns.map((column, index) => { - const { key, title, resizable } = column; - - return ( - - {filesList.map((item) => ( - - ))} - - ); - })} + + + {filesList.map((item) => ( + + ))} + ); }; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js index ffa06a8b33..abb18ab7dd 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js @@ -1,11 +1,10 @@ import React from "react"; import Text from "@appserver/components/text"; -const AuthorCell = (props) => { - const { fileOwner, sideColor } = props; - +const AuthorCell = ({ fileOwner, sideColor }) => { return ( { + const { onContentFileSelect, element, checkedProps, item } = props; + const { checked } = checkedProps; + + const [iconVisible, setIconVisible] = useState(!checked); + + const onMouseEnter = () => { + if (checked) return; + setIconVisible(false); + }; + + const onMouseLeave = () => { + if (checked) return; + setIconVisible(true); + }; + + useEffect(() => { + setIconVisible(!checked); + }, [checked]); + + const onChange = (e) => { + onContentFileSelect && onContentFileSelect(e.target.checked, item); + }; + + return ( + + {iconVisible ? ( + element + ) : ( + + )} + + ); +}; + +export default CheckboxCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js index 37ecafbf8c..bc6c6c4327 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js @@ -1,12 +1,12 @@ import React from "react"; import Text from "@appserver/components/text"; -const AuthorCell = (props) => { - const { updatedDate, sideColor, item } = props; +const AuthorCell = ({ updatedDate, sideColor, item }) => { const { fileExst, contentLength, providerKey } = item; return ( { - const { item, titleWithoutExt, linkStyles } = props; +const FileNameCell = ({ item, titleWithoutExt, linkStyles }) => { const { fileExst } = item; return ( { - const { t, item, sideColor } = props; +const SizeCell = ({ t, item, sideColor }) => { const { fileExst, contentLength, @@ -12,6 +11,7 @@ const SizeCell = (props) => { } = item; return ( Date: Tue, 13 Jul 2021 11:12:22 +0300 Subject: [PATCH 05/74] Web: Table: changed the logic of work --- .../Home/Section/Body/TableView/TableCell.js | 56 ------------------- .../Home/Section/Body/TableView/TableRow.js | 45 +++++++++++++++ 2 files changed, 45 insertions(+), 56 deletions(-) delete mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js deleted file mode 100644 index 4941ce907f..0000000000 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableCell.js +++ /dev/null @@ -1,56 +0,0 @@ -import React from "react"; -import { withRouter } from "react-router"; -import withContent from "../../../../../HOCs/withContent"; -import withBadges from "../../../../../HOCs/withBadges"; -import withFileActions from "../../../../../HOCs/withFileActions"; -import withContextOptions from "../../../../../HOCs/withContextOptions"; -import { withTranslation } from "react-i18next"; -import TableCell from "@appserver/components/table-container/TableCell"; -import FileNameCell from "./sub-components/FileNameCell"; -import SizeCell from "./sub-components/SizeCell"; -import AuthorCell from "./sub-components/AuthorCell"; -import CreatedCell from "./sub-components/CreatedCell"; -import globalColors from "@appserver/components/utils/globalColors"; - -const sideColor = globalColors.gray; - -const TableCellFiles = (props) => { - const { column, item } = props; - - const getElem = () => { - let field = null; - for (let inc of column.includes) { - field = inc; - // if (field) { - // console.log("123", field); - // console.log("inc", inc); - // field = field[inc]; - // console.log("234", field); - // } else { - // field = inc; - // } - } - - switch (field) { - case "title": - return ; - case "contentLength": - return ; - case "displayName": - return ; - case "created": - return ; - - default: - return <>; - } - }; - - return {getElem()}; -}; - -export default withTranslation("Home")( - withFileActions( - withRouter(withContextOptions(withContent(withBadges(TableCellFiles)))) - ) -); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js new file mode 100644 index 0000000000..4fde85e705 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js @@ -0,0 +1,45 @@ +import React from "react"; +import { withRouter } from "react-router"; +import withContent from "../../../../../HOCs/withContent"; +import withBadges from "../../../../../HOCs/withBadges"; +import withFileActions from "../../../../../HOCs/withFileActions"; +import withContextOptions from "../../../../../HOCs/withContextOptions"; +import { withTranslation } from "react-i18next"; +import TableRow from "@appserver/components/table-container/TableRow"; +import TableCell from "@appserver/components/table-container/TableCell"; +import CheckboxCell from "./sub-components/CheckboxCell"; +import FileNameCell from "./sub-components/FileNameCell"; +import SizeCell from "./sub-components/SizeCell"; +import AuthorCell from "./sub-components/AuthorCell"; +import CreatedCell from "./sub-components/CreatedCell"; +import globalColors from "@appserver/components/utils/globalColors"; + +const sideColor = globalColors.gray; + +const FilesTableRow = (props) => { + return ( + + + + + + + + + + + + + + + + + + ); +}; + +export default withTranslation("Home")( + withFileActions( + withRouter(withContextOptions(withContent(withBadges(FilesTableRow)))) + ) +); From 245928b14eab31759a41425685bdb93f82c861f4 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 13 Jul 2021 11:52:34 +0300 Subject: [PATCH 06/74] Web: Components: removed unused table files --- .../table-container/Column.js | 116 ------------------ .../table-container/TableTd.js | 8 -- 2 files changed, 124 deletions(-) delete mode 100644 packages/asc-web-components/table-container/Column.js delete mode 100644 packages/asc-web-components/table-container/TableTd.js diff --git a/packages/asc-web-components/table-container/Column.js b/packages/asc-web-components/table-container/Column.js deleted file mode 100644 index b61c926fd4..0000000000 --- a/packages/asc-web-components/table-container/Column.js +++ /dev/null @@ -1,116 +0,0 @@ -import React, { useEffect, useState } from "react"; -import Text from "../text"; -import PropTypes from "prop-types"; -import globalColors from "@appserver/components/utils/globalColors"; - -const Column = ({ - id, - index, - title, - resizable, - children, - containerRef, - className, - ...rest -}) => { - const [columnIndex, setColumnIndex] = useState(null); - - const getSubstring = (str) => str.substring(0, str.length - 1); - - const onMouseMove = (e) => { - if (!columnIndex) return; - const column = document.getElementById("column_" + columnIndex); - - const columnSize = column.getBoundingClientRect(); - const newWidth = e.clientX - columnSize.left; - const percentWidth = (newWidth / containerRef.current.clientWidth) * 100; - - const { width, minWidth } = column.style; - - const clearPercent = getSubstring(width); - - if (percentWidth - 2 <= getSubstring(minWidth)) { - return; - } - - const offset = +percentWidth.toFixed(3) - clearPercent; - const column2 = document.getElementById("column_" + (+columnIndex + 1)); - const column2Width = column2 && getSubstring(column2.style.width); - - if (column2) { - if (+percentWidth.toFixed(3) < clearPercent) { - const width2 = column2Width - offset; - column2.style.width = width2 + "%"; - } else if (+percentWidth.toFixed(3) > clearPercent) { - const width2 = +column2Width - offset; - - if (width2 - 2 <= getSubstring(column2.style.minWidth)) { - return; - } - - column2.style.width = width2 + "%"; - } else return; - } - - column.style.width = percentWidth + "%"; - }; - - const onMouseUp = () => { - window.removeEventListener("mousemove", onMouseMove); - window.removeEventListener("mouseup", onMouseUp); - }; - - const onMouseDown = (event) => { - setColumnIndex(event.target.dataset.column); - }; - - useEffect(() => { - if (columnIndex !== null) { - window.addEventListener("mousemove", onMouseMove); - window.addEventListener("mouseup", onMouseUp); - } - - return () => { - window.removeEventListener("mousemove", onMouseMove); - window.removeEventListener("mouseup", onMouseUp); - }; - }, [columnIndex, onMouseMove, onMouseUp]); - - return ( -
- - {title} - -
{children}
- {resizable && ( -
- )} -
- ); -}; - -Column.propTypes = { - id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - className: PropTypes.string, - style: PropTypes.object, - children: PropTypes.any, - index: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), - title: PropTypes.string, - resizable: PropTypes.bool, - containerRef: PropTypes.shape({ current: PropTypes.any }), -}; - -export default Column; diff --git a/packages/asc-web-components/table-container/TableTd.js b/packages/asc-web-components/table-container/TableTd.js deleted file mode 100644 index a2cde111fc..0000000000 --- a/packages/asc-web-components/table-container/TableTd.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from "react"; -import { StyledTableTd } from "./StyledTableContainer"; - -const TableTd = (props) => { - return ; -}; - -export default TableTd; From 568aa610710e9e60a0deff0f34dcdecc31d68219 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 15 Jul 2021 10:57:06 +0300 Subject: [PATCH 07/74] Web: Table: refactoring --- .../table-container/StyledTableContainer.js | 53 +++- .../table-container/TableBody.js | 2 +- .../table-container/TableCell.js | 8 +- .../table-container/TableContainer.js | 8 +- .../table-container/TableHeader.js | 238 ++++++++++++------ .../table-container/TableRow.js | 2 +- .../table-container/svg/settings.react.svg | 3 + .../table-container/svg/sort-arrow.react.svg | 3 + .../Section/Body/TableView/TableContainer.js | 48 +++- .../Home/Section/Body/TableView/TableRow.js | 101 ++++++-- .../TableView/sub-components/AuthorCell.js | 1 - .../TableView/sub-components/CheckboxCell.js | 8 +- .../TableView/sub-components/CreatedCell.js | 5 +- .../TableView/sub-components/FileNameCell.js | 1 - .../Body/TableView/sub-components/SizeCell.js | 1 - 15 files changed, 365 insertions(+), 117 deletions(-) create mode 100644 packages/asc-web-components/table-container/svg/settings.react.svg create mode 100644 packages/asc-web-components/table-container/svg/sort-arrow.react.svg diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index edda2c968b..eca48eabff 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -1,10 +1,20 @@ import styled from "styled-components"; +import SettingsIcon from "./svg/settings.react.svg"; -const StyledTableContainer = styled.table` +const StyledTableContainer = styled.div` width: 100%; max-width: 100%; margin-top: -18px; - border-collapse: collapse; + + display: grid; + grid-template-columns: + 32px + minmax(180px, 2fr) + minmax(150px, 1fr) + minmax(150px, 1fr) + minmax(150px, 1fr) + 80px + 24px; .table-column { user-select: none; @@ -42,15 +52,39 @@ const StyledTableContainer = styled.table` } `; -const StyledTableRow = styled.tr` - height: 47px; - max-height: 47px; - border-bottom: 1px solid #eceef1; +const StyledTableRow = styled.div` + display: contents; `; -const StyledTableHeader = styled.thead``; -const StyledTableBody = styled.tbody``; -const StyledTableCell = styled.td``; +const StyledTableHeader = styled.div` + display: grid; + position: fixed; + background: #fff; + z-index: 1; + + .table-container_header-cell { + border-bottom: 1px solid #eceef1; + } +`; +const StyledTableBody = styled.div` + display: contents; +`; +const StyledTableCell = styled.div` + height: 40px; + max-height: 40px; + border-bottom: 1px solid #eceef1; + + display: flex; + align-items: center; + + .react-svg-icon svg { + margin-top: 2px; + } +`; + +const StyledSettingsIcon = styled(SettingsIcon)` + margin-top: 12px; +`; export { StyledTableContainer, @@ -58,4 +92,5 @@ export { StyledTableBody, StyledTableHeader, StyledTableCell, + StyledSettingsIcon, }; diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js index d9ff6647f0..5f03dc1f65 100644 --- a/packages/asc-web-components/table-container/TableBody.js +++ b/packages/asc-web-components/table-container/TableBody.js @@ -2,7 +2,7 @@ import React from "react"; import { StyledTableBody } from "./StyledTableContainer"; const TableBody = (props) => { - return ; + return ; }; export default TableBody; diff --git a/packages/asc-web-components/table-container/TableCell.js b/packages/asc-web-components/table-container/TableCell.js index f1fffea5d2..07c2fb0197 100644 --- a/packages/asc-web-components/table-container/TableCell.js +++ b/packages/asc-web-components/table-container/TableCell.js @@ -2,7 +2,13 @@ import React from "react"; import { StyledTableCell } from "./StyledTableContainer"; const TableCell = (props) => { - return ; + return ( + + ); }; export default TableCell; diff --git a/packages/asc-web-components/table-container/TableContainer.js b/packages/asc-web-components/table-container/TableContainer.js index bd110eacfb..daac555615 100644 --- a/packages/asc-web-components/table-container/TableContainer.js +++ b/packages/asc-web-components/table-container/TableContainer.js @@ -3,7 +3,13 @@ import { StyledTableContainer } from "./StyledTableContainer"; import PropTypes from "prop-types"; const TableContainer = (props) => { - return ; + return ( + + ); }; TableContainer.propTypes = { diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js index 8f2c350a05..2cea47bb71 100644 --- a/packages/asc-web-components/table-container/TableHeader.js +++ b/packages/asc-web-components/table-container/TableHeader.js @@ -1,105 +1,195 @@ -import React, { useEffect, useState } from "react"; +import React from "react"; +import PropTypes from "prop-types"; +import throttle from "lodash.throttle"; import Text from "../text"; import globalColors from "../utils/globalColors"; -import { StyledTableHeader } from "./StyledTableContainer"; +import { StyledSettingsIcon, StyledTableHeader } from "./StyledTableContainer"; import TableRow from "./TableRow"; -const TableHeader = ({ columns, containerRef, ...rest }) => { - const style = { minWidth: "10%", width: "16%" }; +const TABLE_SIZE = "tableSize"; - const [columnIndex, setColumnIndex] = useState(null); +class TableHeader extends React.Component { + constructor(props) { + super(props); - const getSubstring = (str) => str.substring(0, str.length - 1); + this.state = { columnIndex: null }; - const onMouseMove = (e) => { + this.headerRef = React.createRef(); + this.throttledResize = throttle(this.onResize, 0); + } + + componentDidMount() { + //this.onResize(); + window.addEventListener("resize", this.throttledResize); + } + + componentWillUnmount() { + window.removeEventListener("resize", this.throttledResize); + } + + getSubstring = (str) => str.substring(0, str.length - 2); + + onMouseMove = (e) => { + const { columnIndex } = this.state; + const { containerRef } = this.props; if (!columnIndex) return; const column = document.getElementById("column_" + columnIndex); - const columnSize = column.getBoundingClientRect(); const newWidth = e.clientX - columnSize.left; - const percentWidth = (newWidth / containerRef.current.clientWidth) * 100; - const { width, minWidth } = column.style; + const tableContainer = containerRef.current.style.gridTemplateColumns; + const widths = tableContainer.split(" "); - const clearPercent = getSubstring(width); + //getSubstring(widths[+columnIndex]) + if (newWidth <= 150) { + widths[+columnIndex] = widths[+columnIndex]; + } else { + const offset = +this.getSubstring(widths[+columnIndex]) - newWidth; + const column2Width = +this.getSubstring(widths[+columnIndex + 1]); - if (percentWidth - 2 <= getSubstring(minWidth)) { - return; + //getSubstring(widths[+columnIndex]) + if (column2Width + offset >= 150) { + widths[+columnIndex] = newWidth + "px"; + widths[+columnIndex + 1] = column2Width + offset + "px"; + } } - const offset = +percentWidth.toFixed(3) - clearPercent; - const column2 = document.getElementById("column_" + (+columnIndex + 1)); - const column2Width = column2 && getSubstring(column2.style.width); + containerRef.current.style.gridTemplateColumns = widths.join(" "); + this.headerRef.current.style.gridTemplateColumns = widths.join(" "); + }; - if (column2) { - if (+percentWidth.toFixed(3) < clearPercent) { - const width2 = column2Width - offset; - column2.style.width = width2 + "%"; - } else if (+percentWidth.toFixed(3) > clearPercent) { - const width2 = +column2Width - offset; + onMouseUp = () => { + localStorage.setItem( + TABLE_SIZE, + this.props.containerRef.current.style.gridTemplateColumns + ); - if (width2 - 2 <= getSubstring(column2.style.minWidth)) { - return; + window.removeEventListener("mousemove", this.onMouseMove); + window.removeEventListener("mouseup", this.onMouseUp); + }; + + onMouseDown = (event) => { + this.setState({ columnIndex: event.target.dataset.column }); + + window.addEventListener("mousemove", this.onMouseMove); + window.addEventListener("mouseup", this.onMouseUp); + }; + + onResize = () => { + const { containerRef } = this.props; + + const storageSize = localStorage.getItem(TABLE_SIZE); + const tableContainer = storageSize + ? storageSize.split(" ") + : containerRef.current.style.gridTemplateColumns.split(" "); + + const containerWidth = +containerRef.current.clientWidth; + const newContainerWidth = containerWidth - 32 - 80 - 24; + + let str = ""; + + if (tableContainer.length > 1) { + const gridTemplateColumns = []; + + const oldWidth = tableContainer + .map((column) => +this.getSubstring(column)) + .reduce((x, y) => x + y); + + for (let index in tableContainer) { + const item = tableContainer[index]; + + if (item !== "24px" && item !== "32px" && item !== "80px") { + const percent = (+this.getSubstring(item) / oldWidth) * 100; + const newItemWidth = (containerWidth * percent) / 100 + "px"; + + gridTemplateColumns.push(newItemWidth); + } else { + gridTemplateColumns.push(item); } - column2.style.width = width2 + "%"; - } else return; + str = gridTemplateColumns.join(" "); + } + } else { + const column = (newContainerWidth * 40) / 100 + "px"; + const otherColumns = (newContainerWidth * 20) / 100 + "px"; + + str = `32px ${column} ${otherColumns} ${otherColumns} ${otherColumns} 80px 24px`; } + containerRef.current.style.gridTemplateColumns = str; + this.headerRef.current.style.gridTemplateColumns = str; - column.style.width = percentWidth + "%"; + localStorage.setItem(TABLE_SIZE, str); }; - const onMouseUp = () => { - window.removeEventListener("mousemove", onMouseMove); - window.removeEventListener("mouseup", onMouseUp); + renderFakeHeader = () => { + const style = { padding: "0 4px 0 4px" }; + return ( + + + + + + + + + ); }; - const onMouseDown = (event) => { - setColumnIndex(event.target.dataset.column); - window.addEventListener("mousemove", onMouseMove); - window.addEventListener("mouseup", onMouseUp); - }; + render() { + const { columns, isHeaderVisible, ...rest } = this.props; - // useEffect(() => { - // if (columnIndex !== null) { - // window.addEventListener("mousemove", onMouseMove); - // window.addEventListener("mouseup", onMouseUp); - // } - - // return () => { - // window.removeEventListener("mousemove", onMouseMove); - // window.removeEventListener("mouseup", onMouseUp); - // }; - // }, [columnIndex, onMouseMove, onMouseUp]); - - return ( - - - {columns.map((column, index) => { - return ( - -
- - {column.title} - - {column.resizable && ( -
- )} + return isHeaderVisible ? ( + this.renderFakeHeader() + ) : ( + + + {columns.map((column, index) => { + return ( +
+
+ + {column.title} + + {column.resizable && ( +
+ )} +
- - ); - })} - - - ); + ); + })} + +
+ +
+ + + ); + } +} + +TableHeader.propTypes = { + containerRef: PropTypes.shape({ current: PropTypes.any }), + columns: PropTypes.array, + isHeaderVisible: PropTypes.bool, }; export default TableHeader; diff --git a/packages/asc-web-components/table-container/TableRow.js b/packages/asc-web-components/table-container/TableRow.js index f24f1fec2d..b7421cec2c 100644 --- a/packages/asc-web-components/table-container/TableRow.js +++ b/packages/asc-web-components/table-container/TableRow.js @@ -2,7 +2,7 @@ import React from "react"; import { StyledTableRow } from "./StyledTableContainer"; const TableRow = (props) => { - return ; + return ; }; export default TableRow; diff --git a/packages/asc-web-components/table-container/svg/settings.react.svg b/packages/asc-web-components/table-container/svg/settings.react.svg new file mode 100644 index 0000000000..ced590105e --- /dev/null +++ b/packages/asc-web-components/table-container/svg/settings.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/asc-web-components/table-container/svg/sort-arrow.react.svg b/packages/asc-web-components/table-container/svg/sort-arrow.react.svg new file mode 100644 index 0000000000..7e25a0e54a --- /dev/null +++ b/packages/asc-web-components/table-container/svg/sort-arrow.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js index 3f63cf5361..2ba0e8c40c 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -4,12 +4,25 @@ import { inject, observer } from "mobx-react"; import TableRow from "./TableRow"; import TableHeader from "@appserver/components/table-container/TableHeader"; import TableBody from "@appserver/components/table-container/TableBody"; +import Checkbox from "@appserver/components/checkbox"; + +const Table = ({ filesList, isHeaderVisible, setSelected }) => { + const onChange = (checked) => { + setSelected(checked ? "all" : "none"); + }; -const Table = ({ filesList }) => { const columns = [ { key: -1, - title: "Checkbox", + //title: "Checkbox", + //title: "", + title: ( + + ), includes: ["checked"], resizable: false, }, @@ -41,11 +54,11 @@ const Table = ({ filesList }) => { key: 4, title: "Size", includes: ["contentLength"], - resizable: true, + resizable: false, }, { key: 5, - title: "Settings$#", + title: "", includes: [""], resizable: false, }, @@ -55,10 +68,14 @@ const Table = ({ filesList }) => { return ( - + - {filesList.map((item) => ( - + {filesList.map((item, index) => ( + ))} @@ -66,6 +83,19 @@ const Table = ({ filesList }) => { }; export default inject(({ filesStore }) => { - const { filesList } = filesStore; - return { filesList }; + const { + filesList, + setSelected, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + } = filesStore; + + return { + filesList, + setSelected, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + }; })(observer(Table)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js index 4fde85e705..fab28eec32 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableRow.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useRef } from "react"; import { withRouter } from "react-router"; import withContent from "../../../../../HOCs/withContent"; import withBadges from "../../../../../HOCs/withBadges"; @@ -13,27 +13,100 @@ import SizeCell from "./sub-components/SizeCell"; import AuthorCell from "./sub-components/AuthorCell"; import CreatedCell from "./sub-components/CreatedCell"; import globalColors from "@appserver/components/utils/globalColors"; +import styled from "styled-components"; + +import ContextMenu from "@appserver/components/context-menu"; +import ContextMenuButton from "@appserver/components/context-menu-button"; const sideColor = globalColors.gray; -const FilesTableRow = (props) => { - return ( - - +const StyledShare = styled.div` + cursor: pointer; - - + .share-button { + padding: 4px; + border: 1px solid transparent; + border-radius: 3px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + + :hover { + border: 1px solid #a3a9ae; + svg { + cursor: pointer; + } + } + + .share-button-icon { + margin-right: 7px; + } + } +`; + +const FilesTableRow = (props) => { + const { contextOptionsProps, fileContextClick } = props; + + const cm = useRef(); + const row = useRef(); + + const onContextMenu = (e) => { + props.rowContextClick && props.rowContextClick(); + if (cm.current && !cm.current.menuRef.current) { + row.current.click(e); //TODO: need fix context menu to global + } + cm.current.show(e); + }; + + const renderContext = + Object.prototype.hasOwnProperty.call(props, "contextOptionsProps") && + props.contextOptionsProps.contextOptions.length > 0; + + const getOptions = () => { + props.rowContextClick && props.rowContextClick(); + return props.contextOptionsProps.contextOptions; + }; + + const style = props.index === 0 ? { style: { marginTop: 40 } } : {}; + + return ( + + + + + - - + + - - + + - - + + + + + {props.sharedButton} + + +
+ + {renderContext ? ( + + ) : ( +
+ )} +
-
); }; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js index abb18ab7dd..1634925532 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/AuthorCell.js @@ -4,7 +4,6 @@ import Text from "@appserver/components/text"; const AuthorCell = ({ fileOwner, sideColor }) => { return ( { onContentFileSelect && onContentFileSelect(e.target.checked, item); }; + const style = props.index === 0 ? { style: { marginTop: 40 } } : {}; + return ( - + {iconVisible ? ( element ) : ( diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js index bc6c6c4327..b7e7474eb0 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/CreatedCell.js @@ -1,12 +1,11 @@ import React from "react"; import Text from "@appserver/components/text"; -const AuthorCell = ({ updatedDate, sideColor, item }) => { +const CreatedCell = ({ updatedDate, sideColor, item }) => { const { fileExst, contentLength, providerKey } = item; return ( { ); }; -export default AuthorCell; +export default CreatedCell; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js index d282f1d7ba..0c582816e9 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/sub-components/FileNameCell.js @@ -6,7 +6,6 @@ const FileNameCell = ({ item, titleWithoutExt, linkStyles }) => { const { fileExst } = item; return ( { } = item; return ( Date: Thu, 15 Jul 2021 13:45:04 +0300 Subject: [PATCH 08/74] Web: Files: added table-view to files module --- .../Client/public/locales/en/Home.json | 5 +- .../Client/public/locales/ru/Home.json | 5 +- .../src/pages/Home/Section/Body/index.js | 4 +- .../src/pages/Home/Section/Filter/index.js | 86 +++++++++++-------- 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/products/ASC.Files/Client/public/locales/en/Home.json b/products/ASC.Files/Client/public/locales/en/Home.json index 2faef33299..84d4b2e4c7 100644 --- a/products/ASC.Files/Client/public/locales/en/Home.json +++ b/products/ASC.Files/Client/public/locales/en/Home.json @@ -81,5 +81,6 @@ "UnblockVersion": "Unblock/Check-in", "UploadToFolder": "Upload to folder", "ViewList": "List", - "ViewTiles": "Tiles" -} \ No newline at end of file + "ViewTiles": "Tiles", + "ViewTables": "Tables" +} diff --git a/products/ASC.Files/Client/public/locales/ru/Home.json b/products/ASC.Files/Client/public/locales/ru/Home.json index 0d2ee2c2cc..ea32d18914 100644 --- a/products/ASC.Files/Client/public/locales/ru/Home.json +++ b/products/ASC.Files/Client/public/locales/ru/Home.json @@ -81,5 +81,6 @@ "UnblockVersion": "Заблокировать/Разблокировать", "UploadToFolder": "Загрузить в папку", "ViewList": "Список", - "ViewTiles": "Плитки" -} \ No newline at end of file + "ViewTiles": "Плитки", + "ViewTables": "Таблицы" +} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js index ae0505a6af..afbeaa8093 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/index.js @@ -159,8 +159,8 @@ const SectionBodyContent = (props) => { return (!fileActionId && isEmptyFilesList) || null ? ( ) : viewAs === "tile" ? ( - - ) : viewAs === "table" || viewAs === "row" ? ( + + ) : viewAs === "table" ? ( ) : ( diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Filter/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Filter/index.js index 1d54bd9f69..683d7fe65c 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Filter/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Filter/index.js @@ -212,12 +212,12 @@ class SectionFilterContent extends React.Component { { key: "Size", label: t("Common:Size"), default: true }, ]; - if (!personal) - commonOptions.push({ - key: "Author", - label: t("ByAuthor"), - default: true, - }); + if (!personal) + commonOptions.push({ + key: "Author", + label: t("ByAuthor"), + default: true, + }); return commonOptions; }; @@ -229,20 +229,23 @@ class SectionFilterContent extends React.Component { { value: "row", label: t("ViewList"), - isSetting: isMobileOnly, - default: true, icon: "/static/images/view-rows.react.svg", }, { value: "tile", label: t("ViewTiles"), - isSetting: isMobileOnly, - default: true, icon: "/static/images/view-tiles.react.svg", callback: createThumbnails, }, ]; + !isMobile && + viewSettings.push({ + value: "table", + label: t("ViewTables"), + icon: "/static/images/view-tiles.react.svg", + }); + return viewSettings; }; @@ -290,7 +293,14 @@ class SectionFilterContent extends React.Component { render() { //console.log("Filter render"); const selectedFilterData = this.getSelectedFilterData(); - const { t, sectionWidth, tReady, isFiltered, viewAs, personal } = this.props; + const { + t, + sectionWidth, + tReady, + isFiltered, + viewAs, + personal, + } = this.props; const filterColumnCount = window.innerWidth < 500 ? {} : { filterColumnCount: personal ? 2 : 3 }; @@ -320,22 +330,22 @@ class SectionFilterContent extends React.Component { export default inject( ({ auth, filesStore, treeFoldersStore, selectedFolderStore }) => { - const { - fetchFiles, - filter, - setIsLoading, - setViewAs, - viewAs, - files, - folders, + const { + fetchFiles, + filter, + setIsLoading, + setViewAs, + viewAs, + files, + folders, createThumbnails, - } = filesStore; + } = filesStore; - const { user } = auth.userStore; - const { customNames, culture, personal } = auth.settingsStore; + const { user } = auth.userStore; + const { customNames, culture, personal } = auth.settingsStore; - const { search, filterType, authorType } = filter; - const isFiltered = + const { search, filterType, authorType } = filter; + const isFiltered = (!!files.length || !!folders.length || search || @@ -343,22 +353,22 @@ export default inject( authorType) && !(treeFoldersStore.isPrivacyFolder && isMobile); - return { - customNames, - user, - selectedFolderId: selectedFolderStore.id, - selectedItem: filter.selectedItem, - filter, - viewAs, - isFiltered, + return { + customNames, + user, + selectedFolderId: selectedFolderStore.id, + selectedItem: filter.selectedItem, + filter, + viewAs, + isFiltered, - setIsLoading, - fetchFiles, - setViewAs, - createThumbnails, + setIsLoading, + fetchFiles, + setViewAs, + createThumbnails, - personal, - }; + personal, + }; } )( withRouter( From d1ec4a262b33d1ea8e6f4d393ec3fd3c4c3f0fe2 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 15 Jul 2021 16:55:24 +0300 Subject: [PATCH 09/74] Web: Components: added TableGroupMenu --- .../table-container/TableGroupMenu.js | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/asc-web-components/table-container/TableGroupMenu.js diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js new file mode 100644 index 0000000000..4fa4b08a55 --- /dev/null +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -0,0 +1,45 @@ +import React from "react"; +import PropTypes from "prop-types"; +import Checkbox from "../checkbox"; +import { StyledTableGroupMenu } from "./StyledTableContainer"; +import Button from "../button"; + +const TableGroupMenu = (props) => { + const { isChecked, isIndeterminate, headerMenu, onChange } = props; + + const onCheckboxChange = (e) => { + onChange && onChange(e.target && e.target.checked); + }; + + return ( + + + {headerMenu.map((item, index) => { + const { label, disabled, onClick } = item; + return ( + - - - - - - - ); + onChange = (checked) => { + this.props.setSelected(checked ? "all" : "none"); }; render() { - const { columns, isHeaderVisible, ...rest } = this.props; + const { columns, ...rest } = this.props; - return isHeaderVisible ? ( - this.renderFakeHeader() - ) : ( + return ( + + {columns.map((column, index) => { return (
@@ -170,7 +158,7 @@ class TableHeader extends React.Component { {column.resizable && (
@@ -192,7 +180,7 @@ class TableHeader extends React.Component { TableHeader.propTypes = { containerRef: PropTypes.shape({ current: PropTypes.any }), columns: PropTypes.array, - isHeaderVisible: PropTypes.bool, + setSelected: PropTypes.func, }; export default TableHeader; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js index a08f0f0a57..6b6faad915 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -4,71 +4,13 @@ import { inject, observer } from "mobx-react"; import TableRow from "./TableRow"; import TableHeader from "./TableHeader"; import TableBody from "@appserver/components/table-container/TableBody"; -import Checkbox from "@appserver/components/checkbox"; - -const Table = ({ filesList, setSelected }) => { - const onChange = (checked) => { - setSelected(checked ? "all" : "none"); - }; - - const columns = [ - { - key: -1, - //title: "Checkbox", - //title: "", - title: ( - - ), - includes: ["checked"], - resizable: false, - }, - { - key: 0, - title: "Name", - includes: ["title"], - resizable: true, - }, - { - key: 1, - title: "Author", - includes: ["createdBy", "displayName"], - resizable: true, - }, - { - key: 2, - title: "Created", - includes: ["created"], - resizable: true, - }, - // { - // key: 3, - // title: "Type", - // includes: [""], - // resizable: true, - // }, - { - key: 4, - title: "Size", - includes: ["contentLength"], - resizable: false, - }, - { - key: 5, - title: "", - includes: [""], - resizable: false, - }, - ]; +const Table = ({ filesList }) => { const ref = useRef(null); return ( - + {filesList.map((item, index) => ( @@ -79,10 +21,9 @@ const Table = ({ filesList, setSelected }) => { }; export default inject(({ filesStore }) => { - const { filesList, setSelected } = filesStore; + const { filesList } = filesStore; return { filesList, - setSelected, }; })(observer(Table)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js index 53c2612e19..5f0323f908 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -7,7 +7,6 @@ import { withTranslation } from "react-i18next"; const FilesTableHeader = (props) => { const { t, - columns, containerRef, isHeaderVisible, isHeaderChecked, @@ -16,6 +15,39 @@ const FilesTableHeader = (props) => { setSelected, } = props; + const columns = [ + { + key: 0, + title: t("Common:Name"), + resizable: true, + }, + { + key: 1, + title: t("ByAuthor"), + resizable: true, + }, + { + key: 2, + title: t("ByCreationDate"), + resizable: true, + }, + // { + // key: 3, + // title: t("Common:Type"), + // resizable: true, + // }, + { + key: 4, + title: t("Common:Size"), + resizable: false, + }, + { + key: 5, + title: "", + resizable: false, + }, + ]; + const onChange = (checked) => { setSelected(checked ? "all" : "none"); }; @@ -28,7 +60,11 @@ const FilesTableHeader = (props) => { headerMenu={getHeaderMenu(t)} /> ) : ( - + ); }; From b957b48c4e0b59c5b372023362c9e8803046f7ce Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 16 Jul 2021 15:32:46 +0300 Subject: [PATCH 18/74] Web: Components: Table: fixed header styles --- .../table-container/StyledTableContainer.js | 2 +- .../asc-web-components/table-container/TableCell.js | 8 ++++---- .../table-container/TableContainer.js | 1 + .../table-container/TableHeader.js | 13 +++++++++---- .../asc-web-components/table-container/TableRow.js | 4 ++-- 5 files changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index f1043eb62f..0ec3f78d16 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -6,7 +6,6 @@ const HeaderStyles = css` position: fixed; background: #fff; z-index: 1; - width: 79%; border-bottom: 1px solid #eceef1; `; @@ -96,6 +95,7 @@ const StyledTableRow = styled.div` `; const StyledTableCell = styled.div` + padding-right: 8px; height: 40px; max-height: 40px; border-bottom: 1px solid #eceef1; diff --git a/packages/asc-web-components/table-container/TableCell.js b/packages/asc-web-components/table-container/TableCell.js index 07c2fb0197..224b645658 100644 --- a/packages/asc-web-components/table-container/TableCell.js +++ b/packages/asc-web-components/table-container/TableCell.js @@ -1,12 +1,12 @@ import React from "react"; import { StyledTableCell } from "./StyledTableContainer"; -const TableCell = (props) => { +const TableCell = ({ className, forwardedRef, ...rest }) => { return ( ); }; diff --git a/packages/asc-web-components/table-container/TableContainer.js b/packages/asc-web-components/table-container/TableContainer.js index daac555615..75e115b0f2 100644 --- a/packages/asc-web-components/table-container/TableContainer.js +++ b/packages/asc-web-components/table-container/TableContainer.js @@ -5,6 +5,7 @@ import PropTypes from "prop-types"; const TableContainer = (props) => { return ( { const { containerRef } = this.props; + const container = containerRef.current + ? containerRef.current + : document.getElementById("table-container"); + const storageSize = localStorage.getItem(TABLE_SIZE); const tableContainer = storageSize ? storageSize.split(" ") - : containerRef.current.style.gridTemplateColumns.split(" "); + : container.style.gridTemplateColumns.split(" "); - const containerWidth = +containerRef.current.clientWidth; + const containerWidth = +container.clientWidth; const newContainerWidth = containerWidth - 32 - 80 - 24; let str = ""; @@ -119,8 +123,9 @@ class TableHeader extends React.Component { str = `32px ${column} ${otherColumns} ${otherColumns} ${otherColumns} 80px 24px`; } - containerRef.current.style.gridTemplateColumns = str; + container.style.gridTemplateColumns = str; this.headerRef.current.style.gridTemplateColumns = str; + this.headerRef.current.style.width = containerWidth + "px"; localStorage.setItem(TABLE_SIZE, str); }; diff --git a/packages/asc-web-components/table-container/TableRow.js b/packages/asc-web-components/table-container/TableRow.js index 5c7b2c08e5..d85a1ae853 100644 --- a/packages/asc-web-components/table-container/TableRow.js +++ b/packages/asc-web-components/table-container/TableRow.js @@ -42,7 +42,7 @@ const TableRow = (props) => { const [iconVisible, setIconVisible] = useState(!checked); - const onMouseEnter = () => { + const onMouseOver = () => { if (checked) return; setIconVisible(false); }; @@ -70,7 +70,7 @@ const TableRow = (props) => { {...selectionProp} {...props.style} onMouseLeave={onMouseLeave} - onMouseEnter={onMouseEnter} + onMouseOver={onMouseOver} > {iconVisible ? ( element From 5ed5adbb9ba38e0a482c7fae73bf5694c60b778c Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 19 Jul 2021 14:09:09 +0300 Subject: [PATCH 19/74] Web: Components: Table: added settings, fixed table group menu header --- .../components/FilterInput/FilterInput.js | 2 +- packages/asc-web-components/checkbox/index.js | 2 + .../table-container/StyledTableContainer.js | 16 +++-- .../table-container/TableGroupMenu.js | 15 ++++- .../table-container/TableHeader.js | 11 ++-- .../table-container/TableSettings.js | 64 +++++++++++++++++++ .../Client/public/images}/settings.react.svg | 0 .../public/images}/sort-arrow.react.svg | 0 .../Client/src/HOCs/withFileActions.js | 19 ++---- .../Section/Body/RowsView/SimpleFilesRow.js | 4 +- .../Section/Body/TableView/TableHeader.js | 47 ++++++++++++-- .../Home/Section/Body/TableView/TableRow.js | 24 +++++++ .../Home/Section/Body/TilesView/FileTile.js | 4 +- 13 files changed, 168 insertions(+), 40 deletions(-) create mode 100644 packages/asc-web-components/table-container/TableSettings.js rename {packages/asc-web-components/table-container/svg => products/ASC.Files/Client/public/images}/settings.react.svg (100%) rename {packages/asc-web-components/table-container/svg => products/ASC.Files/Client/public/images}/sort-arrow.react.svg (100%) diff --git a/packages/asc-web-common/components/FilterInput/FilterInput.js b/packages/asc-web-common/components/FilterInput/FilterInput.js index b6ac75babb..b5f2e3fce1 100644 --- a/packages/asc-web-common/components/FilterInput/FilterInput.js +++ b/packages/asc-web-common/components/FilterInput/FilterInput.js @@ -932,7 +932,7 @@ class FilterInput extends React.Component {
{viewAs && !isMobileOnly && ( props.width}; ${HeaderStyles} @@ -108,8 +108,16 @@ const StyledTableCell = styled.div` } `; -const StyledSettingsIcon = styled(SettingsIcon)` - margin-top: 12px; +const StyledTableSettings = styled.div` + margin: 14px 0 0px 8px; + display: inline-block; + position: relative; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + + .table-container_settings-checkbox { + padding: 8px 16px; + } `; export { @@ -118,6 +126,6 @@ export { StyledTableBody, StyledTableHeader, StyledTableCell, - StyledSettingsIcon, + StyledTableSettings, StyledTableGroupMenu, }; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 4fa4b08a55..6bd2bc42b2 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -5,14 +5,24 @@ import { StyledTableGroupMenu } from "./StyledTableContainer"; import Button from "../button"; const TableGroupMenu = (props) => { - const { isChecked, isIndeterminate, headerMenu, onChange } = props; + const { + isChecked, + isIndeterminate, + headerMenu, + containerRef, + onChange, + } = props; const onCheckboxChange = (e) => { onChange && onChange(e.target && e.target.checked); }; + const width = containerRef.current + ? containerRef.current.clientWidth + "px" + : "100%"; + return ( - + - +
@@ -184,7 +181,7 @@ class TableHeader extends React.Component { TableHeader.propTypes = { containerRef: PropTypes.shape({ current: PropTypes.any }), - columns: PropTypes.array, + columns: PropTypes.array.isRequired, setSelected: PropTypes.func, }; diff --git a/packages/asc-web-components/table-container/TableSettings.js b/packages/asc-web-components/table-container/TableSettings.js new file mode 100644 index 0000000000..c64b579b26 --- /dev/null +++ b/packages/asc-web-components/table-container/TableSettings.js @@ -0,0 +1,64 @@ +import React, { useRef, useState } from "react"; +import PropTypes from "prop-types"; +import IconButton from "../icon-button"; +import DropDown from "../drop-down"; +import { StyledTableSettings } from "./StyledTableContainer"; +import Checkbox from "../checkbox"; + +const TableSettings = ({ columns }) => { + const [isOpen, setIsOpen] = useState(false); + + const ref = useRef(); + + const onClick = () => { + setIsOpen(!isOpen); + }; + + const clickOutsideAction = (e) => { + const path = e.path || (e.composedPath && e.composedPath()); + const dropDownItem = path ? path.find((x) => x === ref.current) : null; + if (dropDownItem) return; + + setIsOpen(false); + }; + + return ( + + + + {columns.map((column) => ( + + ))} + + + ); +}; + +TableSettings.propTypes = { + columns: PropTypes.array.isRequired, +}; + +export default TableSettings; diff --git a/packages/asc-web-components/table-container/svg/settings.react.svg b/products/ASC.Files/Client/public/images/settings.react.svg similarity index 100% rename from packages/asc-web-components/table-container/svg/settings.react.svg rename to products/ASC.Files/Client/public/images/settings.react.svg diff --git a/packages/asc-web-components/table-container/svg/sort-arrow.react.svg b/products/ASC.Files/Client/public/images/sort-arrow.react.svg similarity index 100% rename from packages/asc-web-components/table-container/svg/sort-arrow.react.svg rename to products/ASC.Files/Client/public/images/sort-arrow.react.svg diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 5a1d74a875..77ffc9e3e3 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -14,11 +14,8 @@ export default function withFileActions(WrappedFileItem) { class WithFileActions extends React.Component { constructor(props) { super(props); - - this.state = { - isMouseDown: false, - }; } + onContentFileSelect = (checked, file) => { const { selectRowAction } = this.props; if (!file || file.id === -1) return; @@ -106,8 +103,6 @@ export default function withFileActions(WrappedFileItem) { } = this.props; const notSelectable = e.target.classList.contains("not-selectable"); - this.setState({ isMouseDown: true }); - if (!draggable || isPrivacy) return; if (window.innerWidth < 1025 || notSelectable) { @@ -130,8 +125,7 @@ export default function withFileActions(WrappedFileItem) { onMarkAsRead = (id) => this.props.markAsRead([], [`${id}`], this.props.item); - onMouseUpHandler = (e) => { - const { isMouseDown } = this.state; + onMouseClick = (e) => { const { viewAs, checked, item } = this.props; if ( @@ -146,18 +140,13 @@ export default function withFileActions(WrappedFileItem) { return; if (viewAs === "tile") { - if ( - !isMouseDown || - e.target.closest(".edit-button") || - e.target.tagName === "IMG" - ) + if (e.target.closest(".edit-button") || e.target.tagName === "IMG") return; this.onFilesClick(); } else { this.fileContextClick(); } - this.setState({ isMouseDown: false }); }; onFilesClick = (e) => { const { @@ -297,7 +286,7 @@ export default function withFileActions(WrappedFileItem) { onDrop={this.onDrop} onMouseDown={this.onMouseDown} onFilesClick={this.onFilesClick} - onMouseUp={this.onMouseUpHandler} + onMouseClick={this.onMouseClick} getClassName={this.getClassName} className={className} isDragging={isDragging} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js index 4b02ac0c1b..5aa91dd484 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js @@ -66,7 +66,7 @@ const SimpleFilesRow = (props) => { checkedProps, element, onFilesClick, - onMouseUp, + onMouseClick, isEdit, } = props; @@ -90,7 +90,7 @@ const SimpleFilesRow = (props) => { onSelect={onContentFileSelect} rowContextClick={fileContextClick} isPrivacy={isPrivacy} - onMouseUp={onMouseUp} + onClick={onMouseClick} onDoubleClick={onFilesClick} {...checkedProps} {...contextOptionsProps} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js index 5f0323f908..b1860fba53 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useState } from "react"; import TableHeader from "@appserver/components/table-container/TableHeader"; import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu"; import { inject, observer } from "mobx-react"; @@ -15,45 +15,78 @@ const FilesTableHeader = (props) => { setSelected, } = props; - const columns = [ + const onColumnChange = (e) => { + const key = e.currentTarget.dataset.key; + const columnIndex = columns.findIndex((c) => c.key === key); + + if (columnIndex === -1) return; + + columns[columnIndex].enable = !columns[columnIndex].enable; + setColumns([...columns]); + }; + + const defaultColumns = [ { - key: 0, + key: "Name", title: t("Common:Name"), resizable: true, + enable: true, + default: true, + onChange: onColumnChange, }, { - key: 1, + key: "Author", title: t("ByAuthor"), + enable: true, resizable: true, + onChange: onColumnChange, }, { - key: 2, + key: "Created", title: t("ByCreationDate"), + enable: true, resizable: true, + onChange: onColumnChange, }, // { - // key: 3, + // key: "Modified", // title: t("Common:Type"), + // enable: true, // resizable: true, + // onChange: onColumnChange, // }, { - key: 4, + key: "Size", title: t("Common:Size"), + enable: true, resizable: false, + onChange: onColumnChange, }, + // { + // key: "Type", + // title: t("Common:Type"), + // enable: true, + // resizable: true, + // onChange: onColumnChange, + // }, { key: 5, title: "", + enable: true, resizable: false, + onChange: onColumnChange, }, ]; + const [columns, setColumns] = useState(defaultColumns); + const onChange = (checked) => { setSelected(checked ? "all" : "none"); }; return isHeaderVisible ? ( { const { contextOptionsProps, @@ -48,6 +68,8 @@ const FilesTableRow = (props) => { checkedProps, className, value, + onMouseClick, + badgesComponent, } = props; const style = props.index === 0 ? { style: { marginTop: 40 } } : {}; @@ -66,11 +88,13 @@ const FilesTableRow = (props) => { element={element} fileContextClick={fileContextClick} onContentFileSelect={onContentFileSelect} + onClick={onMouseClick} {...contextOptionsProps} {...checkedProps} > + {badgesComponent} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js index 8130a11f04..552b5f0eca 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FileTile.js @@ -30,7 +30,7 @@ const FilesTile = (props) => { element, getIcon, onFilesClick, - onMouseUp, + onMouseClick, } = props; const temporaryIcon = getIcon( 96, @@ -64,7 +64,7 @@ const FilesTile = (props) => { tileContextClick={fileContextClick} isPrivacy={isPrivacy} dragging={dragging && isDragging} - onMouseUp={onMouseUp} + onClick={onMouseClick} thumbnailClick={onFilesClick} onDoubleClick={onFilesClick} {...checkedProps} From 4d389cab9144197424d31be7b3046cad1a1edb0c Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 19 Jul 2021 14:37:54 +0300 Subject: [PATCH 20/74] Web: Files: fixed SimpleFilesRow click --- .../src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js | 1 + 1 file changed, 1 insertion(+) diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js index 5aa91dd484..f2ddbff1bf 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js @@ -83,6 +83,7 @@ const SimpleFilesRow = (props) => { > Date: Tue, 20 Jul 2021 13:29:39 +0300 Subject: [PATCH 21/74] Web: Components: Table: added header filtering, refactoring --- .../table-container/StyledTableContainer.js | 71 ++++++++- .../table-container/TableGroupMenu.js | 11 ++ .../table-container/TableHeader.js | 35 ++--- .../table-container/TableHeaderCell.js | 66 +++++++++ .../table-container/TableSettings.js | 23 +-- .../Section/Body/TableView/TableHeader.js | 139 ++++++++++++++---- public/images/folder arrow.react.svg | 3 + 7 files changed, 277 insertions(+), 71 deletions(-) create mode 100644 packages/asc-web-components/table-container/TableHeaderCell.js create mode 100644 public/images/folder arrow.react.svg diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index adc5bf7c98..d875c38b6b 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -38,12 +38,6 @@ const StyledTableContainer = styled.div` border-right: 2px solid #d0d5da; } - .header-container { - height: 38px; - display: flex; - align-items: center; - } - .content-container { overflow: hidden; } @@ -57,6 +51,41 @@ const StyledTableContainer = styled.div` height: 47px; border-bottom: 1px solid #eceef1; } + + .table-container_group-menu { + .table-container_group-menu-checkbox { + width: 22px; + } + + .table-container_group-menu-combobox { + height: 24px; + width: 16px; + margin-bottom: 16px; + + .combo-button { + height: 24px; + margin-top: 8px; + width: 16px; + + .combo-buttons_arrow-icon { + margin: 8px 16px 0 0; + + /* svg { + path { + fill: #333; + } + } */ + } + } + } + + .table-container_group-menu-separator { + border-right: 1px solid #eceef1; + width: 2px; + height: 10px; + margin: 0 8px; + } + } `; const StyledTableGroupMenu = styled.div` @@ -86,6 +115,35 @@ const StyledTableHeader = styled.div` ${HeaderStyles} `; +const StyledTableHeaderCell = styled.div` + .table-container_header-item { + display: flex; + user-select: none; + } + + .header-container-text-wrapper { + display: flex; + cursor: pointer; + + .header-container-text-icon { + padding: 2px 0 0 4px; + + ${(props) => + props.sorted && + css` + transform: scale(1, -1); + padding: 0 0 0 4px; + `} + } + } + + .header-container-text { + height: 38px; + display: flex; + align-items: center; + } +`; + const StyledTableBody = styled.div` display: contents; `; @@ -125,6 +183,7 @@ export { StyledTableRow, StyledTableBody, StyledTableHeader, + StyledTableHeaderCell, StyledTableCell, StyledTableSettings, StyledTableGroupMenu, diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 6bd2bc42b2..19753eba7b 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -3,6 +3,7 @@ import PropTypes from "prop-types"; import Checkbox from "../checkbox"; import { StyledTableGroupMenu } from "./StyledTableContainer"; import Button from "../button"; +import ComboBox from "../combobox"; const TableGroupMenu = (props) => { const { @@ -11,6 +12,7 @@ const TableGroupMenu = (props) => { headerMenu, containerRef, onChange, + checkboxOptions, } = props; const onCheckboxChange = (e) => { @@ -24,10 +26,18 @@ const TableGroupMenu = (props) => { return ( + +
{headerMenu.map((item, index) => { const { label, disabled, onClick } = item; return ( @@ -48,6 +58,7 @@ TableGroupMenu.propTypes = { isChecked: PropTypes.bool, isIndeterminate: PropTypes.bool, headerMenu: PropTypes.arrayOf(PropTypes.object), + checkboxOptions: PropTypes.any, onClick: PropTypes.func, onChange: PropTypes.func, containerRef: PropTypes.shape({ current: PropTypes.any }), diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js index 094b48ac06..fd13df2b38 100644 --- a/packages/asc-web-components/table-container/TableHeader.js +++ b/packages/asc-web-components/table-container/TableHeader.js @@ -1,11 +1,10 @@ import React from "react"; import PropTypes from "prop-types"; import throttle from "lodash.throttle"; -import Text from "../text"; -import globalColors from "../utils/globalColors"; import { StyledTableHeader, StyledTableRow } from "./StyledTableContainer"; import Checkbox from "../checkbox"; import TableSettings from "./TableSettings"; +import TableHeaderCell from "./TableHeaderCell"; const TABLE_SIZE = "tableSize"; @@ -141,32 +140,18 @@ class TableHeader extends React.Component { {...rest} > - + {columns.map((column, index) => { return ( -
-
- - {column.title} - - {column.resizable && ( -
- )} -
-
+ column.enable && ( + + ) ); })} diff --git a/packages/asc-web-components/table-container/TableHeaderCell.js b/packages/asc-web-components/table-container/TableHeaderCell.js new file mode 100644 index 0000000000..9b6ad18a5f --- /dev/null +++ b/packages/asc-web-components/table-container/TableHeaderCell.js @@ -0,0 +1,66 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import Text from "../text"; +import Link from "../link"; +import globalColors from "../utils/globalColors"; +import { StyledTableHeaderCell } from "./StyledTableContainer"; + +const TableHeaderCell = ({ column, index, onMouseDown }) => { + const [sorted, setSorted] = useState(false); + + const onClick = (e) => { + column.onClick(sorted, e); + setSorted(!sorted); + }; + + return ( + +
+ {column.onClick ? ( +
+ + {column.title} + + +
+ ) : ( + + {column.title} + + )} + {column.resizable && ( +
+ )} +
+ + ); +}; + +TableHeaderCell.propTypes = { + column: PropTypes.object, + index: PropTypes.number, + onMouseDown: PropTypes.func, +}; + +export default TableHeaderCell; diff --git a/packages/asc-web-components/table-container/TableSettings.js b/packages/asc-web-components/table-container/TableSettings.js index c64b579b26..1d3d459a95 100644 --- a/packages/asc-web-components/table-container/TableSettings.js +++ b/packages/asc-web-components/table-container/TableSettings.js @@ -42,16 +42,19 @@ const TableSettings = ({ columns }) => { clickOutsideAction={clickOutsideAction} withBackdrop={false} > - {columns.map((column) => ( - - ))} + {columns.map( + (column) => + !column.default && ( + + ) + )} ); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js index b1860fba53..a96c627997 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -3,16 +3,22 @@ import TableHeader from "@appserver/components/table-container/TableHeader"; import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; +import { FilterType } from "@appserver/common/constants"; +import DropDownItem from "@appserver/components/drop-down-item"; const FilesTableHeader = (props) => { const { t, + filter, + selectedFolderId, containerRef, isHeaderVisible, isHeaderChecked, isHeaderIndeterminate, getHeaderMenu, setSelected, + setIsLoading, + fetchFiles, } = props; const onColumnChange = (e) => { @@ -25,6 +31,14 @@ const FilesTableHeader = (props) => { setColumns([...columns]); }; + const onNameClick = (val) => { + const newFilter = filter.clone(); + newFilter.sortOrder = val ? "ascending" : "descending"; + + setIsLoading(true); + fetchFiles(selectedFolderId, newFilter).finally(() => setIsLoading(false)); + }; + const defaultColumns = [ { key: "Name", @@ -32,6 +46,7 @@ const FilesTableHeader = (props) => { resizable: true, enable: true, default: true, + onClick: onNameClick, onChange: onColumnChange, }, { @@ -48,13 +63,13 @@ const FilesTableHeader = (props) => { resizable: true, onChange: onColumnChange, }, - // { - // key: "Modified", - // title: t("Common:Type"), - // enable: true, - // resizable: true, - // onChange: onColumnChange, - // }, + { + key: "Modified", + title: t("Common:Type"), + enable: false, + resizable: true, + onChange: onColumnChange, + }, { key: "Size", title: t("Common:Size"), @@ -62,13 +77,13 @@ const FilesTableHeader = (props) => { resizable: false, onChange: onColumnChange, }, - // { - // key: "Type", - // title: t("Common:Type"), - // enable: true, - // resizable: true, - // onChange: onColumnChange, - // }, + { + key: "Type", + title: t("Common:Type"), + enable: false, + resizable: true, + onChange: onColumnChange, + }, { key: 5, title: "", @@ -84,9 +99,62 @@ const FilesTableHeader = (props) => { setSelected(checked ? "all" : "none"); }; + const onSelect = (e) => { + const key = e.currentTarget.dataset.key; + setSelected(key); + }; + + const checkboxOptions = ( + <> + + + + + + + + + + + ); + return isHeaderVisible ? ( { ); }; -export default inject(({ filesStore, filesActionsStore }) => { - const { - setSelected, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, - } = filesStore; - const { getHeaderMenu } = filesActionsStore; +export default inject( + ({ filesStore, filesActionsStore, selectedFolderStore }) => { + const { + setSelected, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + setIsLoading, + filter, + fetchFiles, + } = filesStore; + const { getHeaderMenu } = filesActionsStore; - return { - setSelected, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, + console.log("filter", filter); - getHeaderMenu, - }; -})( + return { + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + filter, + selectedFolderId: selectedFolderStore.id, + + setSelected, + setIsLoading, + fetchFiles, + getHeaderMenu, + }; + } +)( withTranslation(["Home", "Common", "Translations"])( observer(FilesTableHeader) ) diff --git a/public/images/folder arrow.react.svg b/public/images/folder arrow.react.svg new file mode 100644 index 0000000000..25d9c9c20e --- /dev/null +++ b/public/images/folder arrow.react.svg @@ -0,0 +1,3 @@ + + + From 044168c6dbac13f4e3ca30a0a6fd006666f0b626 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 20 Jul 2021 16:01:54 +0300 Subject: [PATCH 22/74] Web: Components: fixed header styles --- .../table-container/StyledTableContainer.js | 7 ++ .../table-container/TableGroupMenu.js | 65 +++++++++++-------- .../table-container/TableHeader.js | 57 +++++++++------- 3 files changed, 76 insertions(+), 53 deletions(-) diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index d875c38b6b..3f69bc5c2f 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -178,6 +178,12 @@ const StyledTableSettings = styled.div` } `; +const StyledEmptyTableContainer = styled.div` + grid-column-start: 1; + grid-column-end: -1; + height: 40px; +`; + export { StyledTableContainer, StyledTableRow, @@ -187,4 +193,5 @@ export { StyledTableCell, StyledTableSettings, StyledTableGroupMenu, + StyledEmptyTableContainer, }; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 19753eba7b..a5da7490cf 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -1,7 +1,10 @@ import React from "react"; import PropTypes from "prop-types"; import Checkbox from "../checkbox"; -import { StyledTableGroupMenu } from "./StyledTableContainer"; +import { + StyledTableGroupMenu, + StyledEmptyTableContainer, +} from "./StyledTableContainer"; import Button from "../button"; import ComboBox from "../combobox"; @@ -24,33 +27,39 @@ const TableGroupMenu = (props) => { : "100%"; return ( - - - -
- {headerMenu.map((item, index) => { - const { label, disabled, onClick } = item; - return ( -