From d2f1927d31c832dfbf4ae9903c1c38d64f701ad4 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 7 Jun 2022 16:31:13 +0300 Subject: [PATCH 01/78] Web: Files: added infinite scroll --- .../Section/sub-components/section-body.js | 6 +- .../Body/RowsView/FilesRowContainer.js | 15 ++++- .../Section/Body/TableView/TableContainer.js | 17 +++++- .../TilesView/sub-components/TileContainer.js | 57 ++++++++++++++++++- .../src/pages/Home/Section/Body/index.js | 13 +++++ .../ASC.Files/Client/src/pages/Home/index.js | 5 -- .../ASC.Files/Client/src/store/FilesStore.js | 47 ++++++++++++++- 7 files changed, 148 insertions(+), 12 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/section-body.js b/packages/asc-web-common/components/Section/sub-components/section-body.js index 99770aba84..dbcde290b8 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-body.js +++ b/packages/asc-web-common/components/Section/sub-components/section-body.js @@ -221,7 +221,11 @@ class SectionBody extends React.Component { > {withScroll ? ( !isMobileOnly ? ( - +
{children} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index 2ac612c471..92c27c92fe 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -5,8 +5,12 @@ import SimpleFilesRow from "./SimpleFilesRow"; import { isMobile } from "react-device-detect"; import styled from "styled-components"; import marginStyles from "./CommonStyles"; -import { isTablet } from "@appserver/components/utils/device"; import { Base } from "@appserver/components/themes"; +import Loaders from "@appserver/common/components/Loaders"; + +const StyledLoader = styled.div` + padding-top: 16px; +`; const StyledRowContainer = styled(RowContainer)` .row-selected + .row-wrapper:not(.row-selected) { @@ -64,6 +68,7 @@ const FilesRowContainer = ({ viewAs, setViewAs, infoPanelVisible, + filesIsLoading, }) => { useEffect(() => { if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return; @@ -93,17 +98,23 @@ const FilesRowContainer = ({ sectionWidth={sectionWidth} /> ))} + {filesIsLoading && ( + + + + )} ); }; export default inject(({ filesStore, auth }) => { - const { filesList, viewAs, setViewAs } = filesStore; + const { filesList, viewAs, setViewAs, filesIsLoading } = filesStore; const { isVisible: infoPanelVisible } = auth.infoPanelStore; return { filesList, viewAs, setViewAs, infoPanelVisible, + filesIsLoading, }; })(observer(FilesRowContainer)); 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 a22870eb2b..4c16abd3ec 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 @@ -6,8 +6,15 @@ import TableHeader from "./TableHeader"; import TableBody from "@appserver/components/table-container/TableBody"; import { isMobile } from "react-device-detect"; import styled, { css } from "styled-components"; -import { isTablet } from "@appserver/components/utils/device"; import { Base } from "@appserver/components/themes"; +import Loaders from "@appserver/common/components/Loaders"; + +const StyledLoader = styled.div` + grid-column-start: 1; + grid-column-end: -1; + display: grid; + padding-top: 16px; +`; const marginCss = css` margin-top: -1px; @@ -113,6 +120,7 @@ const Table = ({ theme, infoPanelVisible, userId, + filesIsLoading, }) => { const ref = useRef(null); @@ -158,6 +166,11 @@ const Table = ({ columnInfoPanelStorageName={columnInfoPanelStorageName} /> ))} + {filesIsLoading && ( + + + + )} ); @@ -172,6 +185,7 @@ export default inject(({ filesStore, auth }) => { setViewAs, setFirsElemChecked, setHeaderBorder, + filesIsLoading, } = filesStore; return { @@ -183,5 +197,6 @@ export default inject(({ filesStore, auth }) => { theme: auth.settingsStore.theme, userId: auth.userStore.user.id, infoPanelVisible, + filesIsLoading, }; })(observer(Table)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 7ec665ee07..2c6ce0249d 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -21,6 +21,7 @@ import Text from "@appserver/components/text"; import IconButton from "@appserver/components/icon-button"; import ComboBox from "@appserver/components/combobox"; import { Base } from "@appserver/components/themes"; +import Loaders from "@appserver/common/components/Loaders"; import SortDesc from "../../../../../../../../../../public/images/sort.desc.react.svg"; @@ -48,6 +49,10 @@ const StyledGridWrapper = styled.div` @media ${tablet} { grid-gap: 14px; } + + .folders-loader { + padding-top: 14px; + } `; const StyledTileContainer = styled.div` @@ -322,6 +327,41 @@ class TileContainer extends React.PureComponent { ); }; + getTilesLoaders = (folders, files) => { + const { getCountTilesInRow } = this.props; + + const countTilesInRow = getCountTilesInRow(); + const loaders = []; + + if (files.length === 0) { + let count = countTilesInRow - (folders.length % countTilesInRow); + while (count !== 0) { + loaders.push( + + ); + count--; + } + } else { + let count = countTilesInRow - (files.length % countTilesInRow); + while (count !== 0) { + loaders.push( + + ); + count--; + } + } + + return loaders; + }; + render() { const { t, @@ -335,6 +375,7 @@ class TileContainer extends React.PureComponent { headingFiles, isRecentFolder, isFavoritesFolder, + filesIsLoading, } = this.props; const Folders = []; @@ -425,6 +466,8 @@ class TileContainer extends React.PureComponent { ); }; + const loaders = filesIsLoading ? this.getTilesLoaders(Folders, Files) : []; + return ( {renderList} ) : ( - {Folders} + + {Folders} + {Files.length === 0 && filesIsLoading && loaders} + )} )} @@ -462,7 +508,10 @@ class TileContainer extends React.PureComponent { {useReactWindow ? ( {renderList} ) : ( - {Files} + + {Files} + {filesIsLoading && loaders} + )} )} @@ -500,6 +549,8 @@ export default inject( files, folders, createThumbnails, + filesIsLoading, + getCountTilesInRow, } = filesStore; const { user } = auth.userStore; @@ -530,6 +581,8 @@ export default inject( fetchFiles, setViewAs, createThumbnails, + filesIsLoading, + getCountTilesInRow, personal, }; 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 92a09e3417..a16837c1b2 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 @@ -40,6 +40,7 @@ const SectionBodyContent = (props) => { scrollToFolderId, setScrollToFolderId, filesList, + fetchMoreFiles, } = props; useEffect(() => { @@ -59,6 +60,9 @@ const SectionBodyContent = (props) => { document.addEventListener("dragleave", onDragLeaveDoc); document.addEventListener("drop", onDropEvent); + const scroll = document.getElementsByClassName("section-scroll")[0]; + scroll.addEventListener("scroll", onScroll); + return () => { window.removeEventListener("mousedown", onMouseDown); window.removeEventListener("mouseup", onMouseUp); @@ -67,6 +71,7 @@ const SectionBodyContent = (props) => { document.removeEventListener("dragover", onDragOver); document.removeEventListener("dragleave", onDragLeaveDoc); document.removeEventListener("drop", onDropEvent); + scroll.removeEventListener("scroll", onScroll); }; }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); @@ -95,6 +100,12 @@ const SectionBodyContent = (props) => { } }, [scrollToFolderId]); + const onScroll = (e) => { + if (window.innerHeight + e.target.scrollTop + 1 > e.target.scrollHeight) { + fetchMoreFiles(); + } + }; + const onMouseDown = (e) => { if ( (e.target.closest(".scroll-body") && @@ -283,6 +294,7 @@ export default inject( scrollToFolderId, setScrollToFolderId, filesList, + fetchMoreFiles, } = filesStore; return { @@ -306,6 +318,7 @@ export default inject( scrollToFolderId, setScrollToFolderId, filesList, + fetchMoreFiles, }; } )( diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 0bfa841106..fdf6f010a8 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -317,7 +317,6 @@ class PureHome extends React.Component { secondaryProgressDataStoreAlert, dragging, - tReady, personal, checkedMaintenance, setMaintenanceExist, @@ -390,10 +389,6 @@ class PureHome extends React.Component { - - - - ); diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 7f0825c2ea..756c0adcf3 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -18,6 +18,7 @@ import config from "../../package.json"; import { thumbnailStatuses } from "../helpers/constants"; import { loopTreeFolders } from "../helpers/files-helpers"; import { openDocEditor as openEditor } from "../helpers/utils"; +import { isDesktop } from "@appserver/components/utils/device"; const { FilesFilter } = api; const storageViewAs = localStorage.getItem("viewAs"); @@ -73,6 +74,7 @@ class FilesStore { isLoadingFilesFind = false; pageItemsLength = null; isHidePagination = false; + filesIsLoading = false; constructor( authStore, @@ -268,7 +270,12 @@ class FilesStore { this.isLoaded = isLoaded; }; - setViewAs = (viewAs) => { + setViewAs = async (viewAs) => { + // this.setIsLoading(true); + // await this.fetchFiles(this.selectedFolderStore.id, null, true); + + // this.setIsLoading(false); + this.viewAs = viewAs; localStorage.setItem("viewAs", viewAs); }; @@ -2084,6 +2091,44 @@ class FilesStore { setScrollToFolderId = (folderId) => { this.scrollToFolderId = folderId; }; + + get hasMoreFiles() { + return this.filesList.length < this.filter.total; + } + + setFilesIsLoading = (filesIsLoading) => { + this.filesIsLoading = filesIsLoading; + }; + + fetchMoreFiles = async () => { + if (!this.hasMoreFiles || this.filesIsLoading || this.isLoading) return; + + this.setFilesIsLoading(true); + console.log("fetchMoreFiles"); + + const newFilter = this.filter; + newFilter.page += 1; + const newFiles = await api.files.getFolder(newFilter.folder, newFilter); + + runInAction(() => { + this.setFiles([...this.files, ...newFiles.files]); + this.setFolders([...this.folders, ...newFiles.folders]); + this.setFilesIsLoading(false); + }); + }; + + //Duplicate of countTilesInRow, used to update the number of tiles in a row after the window is resized. + getCountTilesInRow = () => { + const isDesktopView = isDesktop(); + const tileGap = isDesktopView ? 16 : 14; + const minTileWidth = 216 + tileGap; + const sectionPadding = isDesktopView ? 24 : 16; + + const body = document.getElementById("section"); + const sectionWidth = body ? body.offsetWidth - sectionPadding : 0; + + return Math.floor(sectionWidth / minTileWidth); + }; } export default FilesStore; From f08a58f329ab2733e2da055d72142d7418cd22fc Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 7 Jun 2022 17:00:25 +0300 Subject: [PATCH 02/78] Web: Files: fixed loaders for mobile devices --- .../components/Section/sub-components/section-body.js | 6 +----- .../Body/TilesView/sub-components/TileContainer.js | 10 +++++++--- .../Client/src/pages/Home/Section/Body/index.js | 5 ++++- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/section-body.js b/packages/asc-web-common/components/Section/sub-components/section-body.js index dbcde290b8..99770aba84 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-body.js +++ b/packages/asc-web-common/components/Section/sub-components/section-body.js @@ -221,11 +221,7 @@ class SectionBody extends React.Component { > {withScroll ? ( !isMobileOnly ? ( - +
{children} diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 2c6ce0249d..4b6ba77026 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -50,8 +50,12 @@ const StyledGridWrapper = styled.div` grid-gap: 14px; } - .folders-loader { + .tiles-loader { padding-top: 14px; + + &:nth-of-type(n + 3) { + display: block; + } } `; @@ -339,7 +343,7 @@ class TileContainer extends React.PureComponent { loaders.push( ); @@ -351,7 +355,7 @@ class TileContainer extends React.PureComponent { loaders.push( ); 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 a16837c1b2..bf21577450 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 @@ -60,7 +60,10 @@ const SectionBodyContent = (props) => { document.addEventListener("dragleave", onDragLeaveDoc); document.addEventListener("drop", onDropEvent); - const scroll = document.getElementsByClassName("section-scroll")[0]; + const scroll = + isMobile && customScrollElm + ? customScrollElm + : document.getElementsByClassName("section-scroll")[0]; scroll.addEventListener("scroll", onScroll); return () => { From f7583badec05330e984c01f4f194fe707444c0e8 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 7 Jun 2022 17:16:47 +0300 Subject: [PATCH 03/78] Web: Files: fixed scroll for IOS --- .../components/Section/sub-components/section-body.js | 8 ++++++-- .../ASC.Files/Client/src/pages/Home/Section/Body/index.js | 6 ++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/section-body.js b/packages/asc-web-common/components/Section/sub-components/section-body.js index 99770aba84..62426dc50b 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-body.js +++ b/packages/asc-web-common/components/Section/sub-components/section-body.js @@ -221,7 +221,11 @@ class SectionBody extends React.Component { > {withScroll ? ( !isMobileOnly ? ( - +
{children} @@ -255,7 +259,7 @@ class SectionBody extends React.Component { > {withScroll ? ( !isMobileOnly ? ( - +
{children} 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 bf21577450..c462cf8365 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 @@ -60,10 +60,8 @@ const SectionBodyContent = (props) => { document.addEventListener("dragleave", onDragLeaveDoc); document.addEventListener("drop", onDropEvent); - const scroll = - isMobile && customScrollElm - ? customScrollElm - : document.getElementsByClassName("section-scroll")[0]; + const scroll = document.getElementById("sectionScroll").childNodes[0]; + scroll.addEventListener("scroll", onScroll); return () => { From 3a1c380c2cd93c3c405b0ce607547c3ec9f86fd6 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 7 Jun 2022 17:28:49 +0300 Subject: [PATCH 04/78] Web: Files: fixed getting sectionScroll --- .../ASC.Files/Client/src/pages/Home/Section/Body/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 c462cf8365..086d6b6f37 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 @@ -60,7 +60,9 @@ const SectionBodyContent = (props) => { document.addEventListener("dragleave", onDragLeaveDoc); document.addEventListener("drop", onDropEvent); - const scroll = document.getElementById("sectionScroll").childNodes[0]; + const scrollElem = document.getElementById("sectionScroll"); + + const scroll = scrollElem ? scrollElem.childNodes[0] : customScrollElm; scroll.addEventListener("scroll", onScroll); @@ -72,7 +74,7 @@ const SectionBodyContent = (props) => { document.removeEventListener("dragover", onDragOver); document.removeEventListener("dragleave", onDragLeaveDoc); document.removeEventListener("drop", onDropEvent); - scroll.removeEventListener("scroll", onScroll); + scroll && scroll.removeEventListener("scroll", onScroll); }; }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); From 4abfe32f282abbc414ba1e63ebefb5cea2ec2095 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 8 Jun 2022 15:49:58 +0300 Subject: [PATCH 05/78] Web: Files: fixed reset filesList after delete operation --- .../Client/src/store/FilesActionsStore.js | 28 +++++++++++++++---- .../ASC.Files/Client/src/store/FilesStore.js | 7 +++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/products/ASC.Files/Client/src/store/FilesActionsStore.js b/products/ASC.Files/Client/src/store/FilesActionsStore.js index 6536ea36a3..b943f9e755 100644 --- a/products/ASC.Files/Client/src/store/FilesActionsStore.js +++ b/products/ASC.Files/Client/src/store/FilesActionsStore.js @@ -176,6 +176,22 @@ class FilesActionStore { setTimeout(() => clearSecondaryProgressData(), TIMEOUT); }; + updateFilesAfterDelete = (folderIds) => { + const { folders, setFolders, filter } = this.filesStore; + const { + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + if (folderIds) { + const newFolders = folders.filter((f) => !folderIds.includes(f.id)); + setFolders(newFolders); + filter.total -= 1; + } + + this.dialogsStore.setIsFolderActions(false); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + }; + deleteAction = async ( translations, newSelection = null, @@ -245,7 +261,9 @@ class FilesActionStore { label: translations.deleteOperation, }; await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder(fileIds, folderIds); + + //this.updateCurrentFolder(fileIds, folderIds); + this.updateFilesAfterDelete(folderIds); if (currentFolderId) { const { socketHelper } = this.authStore.settingsStore; @@ -557,8 +575,6 @@ class FilesActionStore { label: translations.deleteOperation, }; - const selectionFilesLength = 1; - if (isFile) { addActiveItems([itemId]); this.isMediaOpen(); @@ -567,7 +583,8 @@ class FilesActionStore { if (res[0]?.error) return Promise.reject(res[0].error); const data = res[0] ? res[0] : null; await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder([itemId]); + //this.updateCurrentFolder([itemId]); + this.updateFilesAfterDelete(); }) .then(() => toastr.success(translations.successRemoveFile)); } else { @@ -577,7 +594,8 @@ class FilesActionStore { if (res[0]?.error) return Promise.reject(res[0].error); const data = res[0] ? res[0] : null; await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder(null, [itemId]); + //this.updateCurrentFolder(null, [itemId]); + this.updateFilesAfterDelete([itemId]); }) .then(() => toastr.success(translations.successRemoveFolder)); } diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 756c0adcf3..6b185624fd 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -100,7 +100,7 @@ class FilesStore { const { socketHelper } = authStore.settingsStore; socketHelper.on("s:modify-folder", async (opt) => { - //console.log("Call s:modify-folder", opt); + console.log("Call s:modify-folder", opt); if (this.isLoading) return; @@ -162,6 +162,7 @@ class FilesStore { return index !== foundIndex; }) ); + this.filter.total -= 1; // Hide pagination when deleting files runInAction(() => { @@ -604,6 +605,8 @@ class FilesStore { filterData.sortOrder = splitFilter[2]; } + filterData.page = 0; + setSelectedNode([folderId + ""]); //TODO: fix @my @@ -2106,7 +2109,7 @@ class FilesStore { this.setFilesIsLoading(true); console.log("fetchMoreFiles"); - const newFilter = this.filter; + const newFilter = this.filter.clone(); newFilter.page += 1; const newFiles = await api.files.getFolder(newFilter.folder, newFilter); From 1f69e46128daa9ce4b34618aa063344653729b8c Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 8 Jun 2022 16:57:39 +0300 Subject: [PATCH 06/78] Web: Files: fixed upload files --- .../ASC.Files/Client/src/store/FilesStore.js | 8 +-- .../Client/src/store/UploadDataStore.js | 59 ++++++++++--------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 6b185624fd..a6b0b1912b 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -100,7 +100,7 @@ class FilesStore { const { socketHelper } = authStore.settingsStore; socketHelper.on("s:modify-folder", async (opt) => { - console.log("Call s:modify-folder", opt); + //console.log("Call s:modify-folder", opt); if (this.isLoading) return; @@ -114,9 +114,9 @@ class FilesStore { const newFiles = [file, ...this.files]; - if (newFiles.length > this.filter.pageCount) { - newFiles.pop(); // Remove last - } + // if (newFiles.length > this.filter.pageCount) { + // newFiles.pop(); // Remove last + // } this.setFiles(newFiles); } diff --git a/products/ASC.Files/Client/src/store/UploadDataStore.js b/products/ASC.Files/Client/src/store/UploadDataStore.js index 7b4d477c62..25d4b8385d 100644 --- a/products/ASC.Files/Client/src/store/UploadDataStore.js +++ b/products/ASC.Files/Client/src/store/UploadDataStore.js @@ -585,9 +585,9 @@ class UploadDataStore { const newFiles = files; const newFolders = folders; const path = currentFile.path ? currentFile.path.slice() : []; - const fileIndex = newFiles.findIndex( - (x) => x.id === currentFile.fileInfo.id - ); + // const fileIndex = newFiles.findIndex( + // (x) => x.id === currentFile.fileInfo.id + // ); let folderInfo = null; const index = path.findIndex((x) => x === this.selectedFolderStore.id); @@ -617,22 +617,23 @@ class UploadDataStore { newFolders.unshift(folderInfo); setFolders(newFolders); const newFilter = filter; - newFilter.total = newFilter.total += 1; + newFilter.total += 1; setFilter(newFilter); } } else { - if (currentFile && currentFile.fileInfo) { - if (fileIndex === -1) { - newFiles.unshift(currentFile.fileInfo); - setFiles(newFiles); - const newFilter = filter; - newFilter.total = newFilter.total += 1; - setFilter(newFilter); - } else if (!this.settingsStore.storeOriginalFiles) { - newFiles[fileIndex] = currentFile.fileInfo; - setFiles(newFiles); - } - } + // if (currentFile && currentFile.fileInfo) { + // console.log("addNewFile", fileIndex); + // if (fileIndex === -1) { + // newFiles.unshift(currentFile.fileInfo); + // setFiles(newFiles); + // const newFilter = filter; + // newFilter.total += 1; + // setFilter(newFilter); + // } else if (!this.settingsStore.storeOriginalFiles) { + // newFiles[fileIndex] = currentFile.fileInfo; + // setFiles(newFiles); + // } + // } } }; @@ -653,17 +654,17 @@ class UploadDataStore { } } - if (filter.total >= filter.pageCount) { - if (files.length) { - fileIndex === -1 && newFiles.pop(); - addNewFile(); - } else { - newFolders.pop(); - addNewFile(); - } - } else { - addNewFile(); - } + // if (filter.total >= filter.pageCount) { + // if (files.length) { + // fileIndex === -1 && newFiles.pop(); + // addNewFile(); + // } else { + // newFolders.pop(); + // addNewFile(); + // } + // } else { + addNewFile(); + // } if (!!folderInfo) { const { @@ -926,7 +927,7 @@ class UploadDataStore { }; finishUploadFiles = () => { - const { fetchFiles, filter } = this.filesStore; + //const { fetchFiles, filter } = this.filesStore; const totalErrorsCount = sumBy(this.files, (f) => (f.error ? 1 : 0)); @@ -947,7 +948,7 @@ class UploadDataStore { if (this.files.length > 0) { const toFolderId = this.files[0]?.toFolderId; - fetchFiles(toFolderId, filter); + //fetchFiles(toFolderId, filter); if (toFolderId) { const { socketHelper } = this.filesStore.settingsStore; From 25c13a39b2a6340bd9ab28d1105d64147c2a64d0 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 9 Jun 2022 12:56:11 +0300 Subject: [PATCH 07/78] Web: Files: fixed selection after remove action --- products/ASC.Files/Client/src/store/FilesActionsStore.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/products/ASC.Files/Client/src/store/FilesActionsStore.js b/products/ASC.Files/Client/src/store/FilesActionsStore.js index b943f9e755..743bed4e5d 100644 --- a/products/ASC.Files/Client/src/store/FilesActionsStore.js +++ b/products/ASC.Files/Client/src/store/FilesActionsStore.js @@ -177,11 +177,13 @@ class FilesActionStore { }; updateFilesAfterDelete = (folderIds) => { - const { folders, setFolders, filter } = this.filesStore; + const { folders, setFolders, filter, setSelected } = this.filesStore; const { clearSecondaryProgressData, } = this.uploadDataStore.secondaryProgressDataStore; + setSelected("close"); + if (folderIds) { const newFolders = folders.filter((f) => !folderIds.includes(f.id)); setFolders(newFolders); From 3bd4714eb80a12529f492dee844a90ce0760651d Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 9 Jun 2022 14:43:48 +0300 Subject: [PATCH 08/78] Web: Files: Scroll: fixed loading files after changing directory --- .../src/components/Article/Body/index.js | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/products/ASC.Files/Client/src/components/Article/Body/index.js b/products/ASC.Files/Client/src/components/Article/Body/index.js index 2c595801ec..07747d9470 100644 --- a/products/ASC.Files/Client/src/components/Article/Body/index.js +++ b/products/ASC.Files/Client/src/components/Article/Body/index.js @@ -37,56 +37,62 @@ const ArticleBodyContent = (props) => { isVisitor, FirebaseHelper, theme, + filesIsLoading, } = props; const campaigns = (localStorage.getItem("campaigns") || "") .split(",") .filter((campaign) => campaign.length > 0); - const onClick = React.useCallback((data) => { - const { - toggleArticleOpen, - setIsLoading, - fetchFiles, - homepage, - history, - } = props; + const onClick = React.useCallback( + (data) => { + const { + toggleArticleOpen, + setIsLoading, + fetchFiles, + homepage, + history, + } = props; - const filesSection = window.location.pathname.indexOf("/filter") > 0; + if (filesIsLoading) return; - if (filesSection) { - setIsLoading(true); - } else { - showLoader(); - } + const filesSection = window.location.pathname.indexOf("/filter") > 0; - fetchFiles(data, null, true, false) - .then(() => { - if (!filesSection) { - const filter = FilesFilter.getDefault(); + if (filesSection) { + setIsLoading(true); + } else { + showLoader(); + } - filter.folder = data; + fetchFiles(data, null, true, false) + .then(() => { + if (!filesSection) { + const filter = FilesFilter.getDefault(); - const urlFilter = filter.toUrlParams(); + filter.folder = data; - history.push( - combineUrl( - AppServerConfig.proxyURL, - homepage, - `/filter?${urlFilter}` - ) - ); - } - }) - .catch((err) => toastr.error(err)) - .finally(() => { - if (isMobileOnly || isMobile()) { - toggleArticleOpen(); - } - if (filesSection) setIsLoading(false); - else hideLoader(); - }); - }, []); + const urlFilter = filter.toUrlParams(); + + history.push( + combineUrl( + AppServerConfig.proxyURL, + homepage, + `/filter?${urlFilter}` + ) + ); + } + }) + .catch((err) => toastr.error(err)) + .finally(() => { + if (isMobileOnly || isMobile()) { + toggleArticleOpen(); + } + if (filesSection) setIsLoading(false); + else hideLoader(); + }); + }, + [filesIsLoading] + ); const onShowNewFilesPanel = React.useCallback((folderId) => { props.setNewFilesPanelVisible(true, [`${folderId}`]); @@ -130,6 +136,7 @@ export default inject( firstLoad, isLoading, isLoaded, + filesIsLoading, } = filesStore; const { treeFolders, setTreeFolders } = treeFoldersStore; @@ -173,6 +180,7 @@ export default inject( isDesktopClient, FirebaseHelper, theme, + filesIsLoading, }; } )( From ce067cfdaf8c10e3c933eea3710e4c55cd779829 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 14 Jun 2022 12:56:20 +0300 Subject: [PATCH 09/78] Web: Files: added setFilter on scroll --- products/ASC.Files/Client/src/store/FilesStore.js | 1 + 1 file changed, 1 insertion(+) diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 3cae89fdb9..e280c801b9 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -2117,6 +2117,7 @@ class FilesStore { const newFilter = this.filter.clone(); newFilter.page += 1; + this.setFilter(newFilter); const newFiles = await api.files.getFolder(newFilter.folder, newFilter); runInAction(() => { From 9169e4733a1d9c7f65f938a20205d7c1020f37d8 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 11 Jul 2022 11:36:34 +0300 Subject: [PATCH 10/78] Web: Files: fixed hasMoreFiles --- products/ASC.Files/Client/src/store/FilesStore.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 2058690f58..bb0279d500 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -2139,8 +2139,12 @@ class FilesStore { this.trashIsEmpty = isEmpty; }; + get filterTotal() { + return this.filter.total; + } + get hasMoreFiles() { - return this.filesList.length < this.filter.total; + return this.filesList.length < this.filterTotal; } setFilesIsLoading = (filesIsLoading) => { From 3f3e612245c972bf7e23fe9959d30a0ce5320dbc Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 11 Jul 2022 11:44:15 +0300 Subject: [PATCH 11/78] Web: Files: removed onScroll listener from SectionBodyContent --- .../Client/src/pages/Home/Section/Body/index.js | 16 ---------------- 1 file changed, 16 deletions(-) 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 c02f76e191..f3e38405a5 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 @@ -41,7 +41,6 @@ const SectionBodyContent = (props) => { setScrollToItem, filesList, uploaded, - fetchMoreFiles, } = props; useEffect(() => { @@ -62,12 +61,6 @@ const SectionBodyContent = (props) => { document.addEventListener("dragleave", onDragLeaveDoc); document.addEventListener("drop", onDropEvent); - const scrollElem = document.getElementById("sectionScroll"); - - const scroll = scrollElem ? scrollElem.childNodes[0] : customScrollElm; - - scroll.addEventListener("scroll", onScroll); - return () => { window.removeEventListener("beforeunload", onBeforeunload); window.removeEventListener("mousedown", onMouseDown); @@ -77,7 +70,6 @@ const SectionBodyContent = (props) => { document.removeEventListener("dragover", onDragOver); document.removeEventListener("dragleave", onDragLeaveDoc); document.removeEventListener("drop", onDropEvent); - scroll && scroll.removeEventListener("scroll", onScroll); }; }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs, uploaded]); @@ -106,12 +98,6 @@ const SectionBodyContent = (props) => { } }, [scrollToItem]); - const onScroll = (e) => { - if (window.innerHeight + e.target.scrollTop + 1 > e.target.scrollHeight) { - fetchMoreFiles(); - } - }; - const onBeforeunload = (e) => { if (!uploaded) { e.preventDefault(); @@ -308,7 +294,6 @@ export default inject( scrollToItem, setScrollToItem, filesList, - fetchMoreFiles, } = filesStore; return { dragging, @@ -332,7 +317,6 @@ export default inject( setScrollToItem, filesList, uploaded: uploadDataStore.uploaded, - fetchMoreFiles, }; } )( From f69a87a7a70d69d5c63b272bc97f99ff8f22316d Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 11 Jul 2022 15:25:00 +0300 Subject: [PATCH 12/78] Web: Files: added InfiniteLoader to table view --- .../Section/sub-components/section-body.js | 5 ++ .../table-container/StyledTableContainer.js | 25 ++++++ .../table-container/TableBody.js | 87 ++++++++++++++++++- .../table-container/TableContainer.js | 8 +- .../table-container/TableHeader.js | 24 ++++- .../Section/Body/TableView/TableContainer.js | 37 ++++---- .../Section/Body/TableView/TableHeader.js | 48 +++++----- .../Home/Section/Body/TableView/TableRow.js | 1 + .../ASC.Files/Client/src/pages/Home/index.js | 2 +- 9 files changed, 188 insertions(+), 49 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/section-body.js b/packages/asc-web-common/components/Section/sub-components/section-body.js index 8c958607c1..d379a99286 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-body.js +++ b/packages/asc-web-common/components/Section/sub-components/section-body.js @@ -23,6 +23,8 @@ const paddingStyles = css` ? "19px 3px 16px 16px" : "19px 3px 16px 20px"}; + ${({ withScroll }) => !withScroll && "padding: 0"}; //TODO: inf-scroll + @media ${tablet} { padding: ${(props) => props.settingsStudio ? "0 0 16px 24px" : "19px 0 16px 24px"}; @@ -60,6 +62,7 @@ const commonStyles = css` border-top: none; .section-wrapper { + height: 100%; ${(props) => !props.withScroll && `display: flex; flex-direction: column; height: 100%; box-sizing:border-box`}; @@ -134,6 +137,8 @@ const StyledSectionBody = styled.div` const StyledDropZoneBody = styled(DragAndDrop)` max-width: 100vw !important; + /* padding-right: 20px; */ //TODO: inf-scroll + ${commonStyles} .drag-and-drop { user-select: none; height: 100%; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 176b9b7386..c324c25371 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -4,6 +4,19 @@ import { mobile, tablet, hugeMobile } from "../utils/device"; import Scrollbar from "../scrollbar"; import { isMobile } from "react-device-detect"; +const reactWindowContainerStyles = css` + height: 100%; + overflow: hidden; + display: block; + margin-top: 0; +`; + +const reactWindowBodyStyles = css` + display: block; + height: 100%; + height: 95%; //TODO: inf-scroll +`; + const StyledTableContainer = styled.div` -moz-user-select: none; @@ -75,6 +88,8 @@ const StyledTableContainer = styled.div` width: 22px; } } + + ${({ useReactWindow }) => useReactWindow && reactWindowContainerStyles} `; StyledTableContainer.defaultProps = { theme: Base }; @@ -278,6 +293,8 @@ StyledTableHeaderCell.defaultProps = { theme: Base }; const StyledTableBody = styled.div` display: contents; + + ${({ useReactWindow }) => useReactWindow && reactWindowBodyStyles} `; const StyledTableRow = styled.div` @@ -372,6 +389,13 @@ const StyledScrollbar = styled(Scrollbar)` } `; +const StyledLoader = styled.div` + grid-column-start: 1; + grid-column-end: -1; + display: grid; + padding-top: 16px; +`; + StyledTableRow.defaultProps = { theme: Base }; export { @@ -386,4 +410,5 @@ export { StyledInfoPanelToggleWrapper, StyledEmptyTableContainer, StyledScrollbar, + StyledLoader, }; diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js index 5f03dc1f65..baa931bb30 100644 --- a/packages/asc-web-components/table-container/TableBody.js +++ b/packages/asc-web-components/table-container/TableBody.js @@ -1,8 +1,89 @@ -import React from "react"; -import { StyledTableBody } from "./StyledTableContainer"; +import React, { useCallback, memo } from "react"; +import AutoSizer from "react-virtualized-auto-sizer"; +import { FixedSizeList as List, areEqual } from "react-window"; +import InfiniteLoader from "react-window-infinite-loader"; +import Loaders from "@appserver/common/components/Loaders"; + +import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import { StyledTableBody, StyledLoader } from "./StyledTableContainer"; const TableBody = (props) => { - return ; + const { + columnStorageName, + fetchMoreFiles, + children, + filesListLength, + hasMoreFiles, + itemCount, + useReactWindow, + } = props; + + const renderTable = memo(({ data, index, style }) => { + const storageSize = localStorage.getItem(columnStorageName); + + const isLoaded = isItemLoaded(index + 1); + + if (!isLoaded) { + return ( + + + + ); + } + + return ( +
+ {data[index]} +
+ ); + }, areEqual); + + const isItemLoaded = useCallback( + (index) => !hasMoreFiles || index < filesListLength, + [filesListLength, hasMoreFiles] + ); + + const renderList = ({ height, width }) => ( + + {({ onItemsRendered, ref }) => ( + + {renderTable} + + )} + + ); + + return useReactWindow ? ( + + {renderList} + + ) : ( + + ); }; export default TableBody; diff --git a/packages/asc-web-components/table-container/TableContainer.js b/packages/asc-web-components/table-container/TableContainer.js index 75e115b0f2..f569c7a4e7 100644 --- a/packages/asc-web-components/table-container/TableContainer.js +++ b/packages/asc-web-components/table-container/TableContainer.js @@ -3,18 +3,22 @@ import { StyledTableContainer } from "./StyledTableContainer"; import PropTypes from "prop-types"; const TableContainer = (props) => { + const { forwardedRef, useReactWindow, ...rest } = props; + return ( ); }; TableContainer.propTypes = { forwardedRef: PropTypes.shape({ current: PropTypes.any }), + useReactWindow: PropTypes.bool, }; export default TableContainer; diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js index 27024a5f6f..a8d8255b5d 100644 --- a/packages/asc-web-components/table-container/TableHeader.js +++ b/packages/asc-web-components/table-container/TableHeader.js @@ -190,8 +190,12 @@ class TableHeader extends React.Component { this.moveToRight(widths, newWidth); } - containerRef.current.style.gridTemplateColumns = widths.join(" "); - this.headerRef.current.style.gridTemplateColumns = widths.join(" "); + const str = widths.join(" "); + + containerRef.current.style.gridTemplateColumns = str; + this.headerRef.current.style.gridTemplateColumns = str; + + this.updateTableRows(str); }; onMouseUp = () => { @@ -537,6 +541,9 @@ class TableHeader extends React.Component { if (str) { container.style.gridTemplateColumns = str; + + this.updateTableRows(str); + if (this.headerRef.current) { this.headerRef.current.style.gridTemplateColumns = str; this.headerRef.current.style.width = containerWidth + "px"; @@ -552,6 +559,18 @@ class TableHeader extends React.Component { } }; + updateTableRows = (str) => { + if (!this.props.useReactWindow) return; + + const rows = document.getElementsByClassName("table-row"); + + if (rows?.length) { + for (let i = 0; i < rows.length; i++) { + rows[i].style.gridTemplateColumns = str; + } + } + }; + resetColumns = (resetToDefault = false) => { const { containerRef, @@ -702,6 +721,7 @@ TableHeader.propTypes = { isLengthenHeader: PropTypes.bool, sortingVisible: PropTypes.bool, infoPanelVisible: PropTypes.bool, + useReactWindow: PropTypes.bool, }; 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 549f9568b4..60fb5ec88d 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 @@ -7,14 +7,6 @@ import TableBody from "@appserver/components/table-container/TableBody"; import { isMobile } from "react-device-detect"; import styled, { css } from "styled-components"; import { Base } from "@appserver/components/themes"; -import Loaders from "@appserver/common/components/Loaders"; - -const StyledLoader = styled.div` - grid-column-start: 1; - grid-column-end: -1; - display: grid; - padding-top: 16px; -`; const marginCss = css` margin-top: -1px; @@ -120,7 +112,9 @@ const Table = ({ theme, infoPanelVisible, userId, - filesIsLoading, + fetchMoreFiles, + hasMoreFiles, + filterTotal, }) => { const ref = useRef(null); @@ -144,7 +138,7 @@ const Table = ({ const columnInfoPanelStorageName = `${COLUMNS_SIZE_INFO_PANEL}=${userId}`; return ( - + - + + {filesList.map((item, index) => ( ))} - {filesIsLoading && ( - - - - )} ); @@ -186,7 +183,9 @@ export default inject(({ filesStore, auth }) => { setViewAs, setFirsElemChecked, setHeaderBorder, - filesIsLoading, + fetchMoreFiles, + hasMoreFiles, + filterTotal, } = filesStore; return { @@ -198,6 +197,8 @@ export default inject(({ filesStore, auth }) => { theme: auth.settingsStore.theme, userId: auth.userStore.user.id, infoPanelVisible, - filesIsLoading, + fetchMoreFiles, + hasMoreFiles, + filterTotal, }; })(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 1a77b31c46..100b5458b9 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 @@ -96,35 +96,35 @@ class FilesTableHeader extends React.Component { localStorage.setItem(this.props.tableStorageName, tableColumns); }; +//TODO: inf-scroll componentDidMount() { - this.customScrollElm = document.getElementsByClassName("section-scroll")[0]; - - this.customScrollElm.addEventListener("scroll", this.onBeginScroll); + //this.customScrollElm = document.getElementsByClassName("section-scroll")[0]; + //this.customScrollElm.addEventListener("scroll", this.onBeginScroll); } - onBeginScroll = () => { - const { firstElemChecked } = this.props; + // onBeginScroll = () => { + // const { firstElemChecked } = this.props; - const currentScrollPosition = this.customScrollElm.scrollTop; - const elem = document.getElementById("table-container_caption-header"); + // const currentScrollPosition = this.customScrollElm.scrollTop; + // const elem = document.getElementById("table-container_caption-header"); - if (currentScrollPosition === 0) { - this.isBeginScrolling = false; + // if (currentScrollPosition === 0) { + // this.isBeginScrolling = false; - this.props.headerBorder && - elem?.classList?.add("hotkeys-lengthen-header"); + // this.props.headerBorder && + // elem?.classList?.add("hotkeys-lengthen-header"); - !firstElemChecked && elem?.classList?.remove("lengthen-header"); - return; - } + // !firstElemChecked && elem?.classList?.remove("lengthen-header"); + // return; + // } - if (!this.isBeginScrolling) { - elem?.classList?.remove("hotkeys-lengthen-header"); - elem?.classList?.add("lengthen-header"); - } + // if (!this.isBeginScrolling) { + // elem?.classList?.remove("hotkeys-lengthen-header"); + // elem?.classList?.add("lengthen-header"); + // } - this.isBeginScrolling = true; - }; + // this.isBeginScrolling = true; + // }; componentDidUpdate(prevProps) { const { columns } = this.state; if (this.props.withContent !== prevProps.withContent) { @@ -144,9 +144,10 @@ class FilesTableHeader extends React.Component { } } - componentWillUnmount() { - this.customScrollElm.removeEventListener("scroll", this.onBeginScroll); - } +//TODO: inf-scroll + // componentWillUnmount() { + // this.customScrollElm.removeEventListener("scroll", this.onBeginScroll); + // } getColumns = (defaultColumns, splitColumns) => { const columns = []; @@ -221,6 +222,7 @@ class FilesTableHeader extends React.Component { resetColumnsSize={resetColumnsSize} sortingVisible={sortingVisible} infoPanelVisible={infoPanelVisible} + useReactWindow /> ); } 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 8b590a911e..6b0fbf6430 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 @@ -273,6 +273,7 @@ const FilesTableRow = (props) => { showHotkeyBorder, tableColumns, id, + style: tableStyles,//TODO: inf-scroll } = props; const { acceptBackground, background } = theme.dragAndDrop; diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 8bc0857b41..5746752d56 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -320,7 +320,7 @@ class PureHome extends React.Component {
Date: Mon, 11 Jul 2022 17:06:21 +0300 Subject: [PATCH 13/78] Web: Components: created InfiniteLoader component --- .../infinite-loader/InfiniteLoader.js | 128 ++++++++++++++++++ .../infinite-loader/StyledInfiniteLoader.js | 14 ++ .../infinite-loader/index.js | 1 + .../asc-web-components/row-container/index.js | 41 +++--- .../table-container/StyledTableContainer.js | 8 -- .../table-container/TableBody.js | 89 ++++-------- .../Body/RowsView/FilesRowContainer.js | 33 +++-- .../Section/Body/TableView/TableContainer.js | 2 +- 8 files changed, 211 insertions(+), 105 deletions(-) create mode 100644 packages/asc-web-components/infinite-loader/InfiniteLoader.js create mode 100644 packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js create mode 100644 packages/asc-web-components/infinite-loader/index.js diff --git a/packages/asc-web-components/infinite-loader/InfiniteLoader.js b/packages/asc-web-components/infinite-loader/InfiniteLoader.js new file mode 100644 index 0000000000..cbf5b0bea6 --- /dev/null +++ b/packages/asc-web-components/infinite-loader/InfiniteLoader.js @@ -0,0 +1,128 @@ +import React, { memo, useCallback } from "react"; +import PropTypes from "prop-types"; +import AutoSizer from "react-virtualized-auto-sizer"; +import InfiniteLoader from "react-window-infinite-loader"; +import { FixedSizeList as List, areEqual } from "react-window"; +import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import Loaders from "@appserver/common/components/Loaders"; +import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; + +const InfiniteLoaderComponent = ({ + viewAs, + hasMoreFiles, + filesLength, + itemCount, + loadMoreItems, + itemSize, + onScroll, + columnStorageName, + children, + className, +}) => { + const renderRow = memo(({ data, index, style }) => { + const isLoaded = isItemLoaded(index + 1); + if (!isLoaded) return getLoader(style); + + return
{data[index]}
; + }, areEqual); + + const renderTile = memo(({ data, index, style }) => { + //TODO: + return
{data[index]}
; + }, areEqual); + + const isItemLoaded = useCallback( + (index) => !hasMoreFiles || index < filesLength, + [filesLength, hasMoreFiles] + ); + + const renderTable = memo(({ data, index, style }) => { + const storageSize = localStorage.getItem(columnStorageName); + + const isLoaded = isItemLoaded(index + 1); + if (!isLoaded) return getLoader(style); + + return ( +
+ {data[index]} +
+ ); + }, areEqual); + + const getLoader = (style) => { + switch (viewAs) { + case "table": + return ( + + + + ); + case "row": + return ( + + + + ); + case "tile": + return <>; + return; + default: + return; + } + }; + + const renderList = ({ height, width }) => ( + + {({ onItemsRendered, ref }) => ( + + {viewAs === "table" + ? renderTable + : viewAs === "row" + ? renderRow + : renderTile} + + )} + + ); + + return {renderList}; +}; + +InfiniteLoaderComponent.propTypes = { + viewAs: PropTypes.string.isRequired, + hasMoreFiles: PropTypes.bool.isRequired, + filesLength: PropTypes.number.isRequired, + itemCount: PropTypes.number.isRequired, + loadMoreItems: PropTypes.func.isRequired, + itemSize: PropTypes.number.isRequired, + children: PropTypes.any.isRequired, + /** Called when the list scroll positions changes */ + onScroll: PropTypes.func, +}; + +export default InfiniteLoaderComponent; diff --git a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js new file mode 100644 index 0000000000..bea5428a5d --- /dev/null +++ b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js @@ -0,0 +1,14 @@ +import styled from "styled-components"; + +const StyledTableLoader = styled.div` + grid-column-start: 1; + grid-column-end: -1; + display: grid; + padding-top: 16px; +`; + +const StyledRowLoader = styled.div` + padding-top: 16px; +`; + +export { StyledTableLoader, StyledRowLoader }; diff --git a/packages/asc-web-components/infinite-loader/index.js b/packages/asc-web-components/infinite-loader/index.js new file mode 100644 index 0000000000..b50b5bc43a --- /dev/null +++ b/packages/asc-web-components/infinite-loader/index.js @@ -0,0 +1 @@ +export default from "./InfiniteLoader"; diff --git a/packages/asc-web-components/row-container/index.js b/packages/asc-web-components/row-container/index.js index d3220b1394..a784544a42 100644 --- a/packages/asc-web-components/row-container/index.js +++ b/packages/asc-web-components/row-container/index.js @@ -5,6 +5,7 @@ import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual- import { FixedSizeList as List, areEqual } from "react-window"; import AutoSizer from "react-virtualized-auto-sizer"; import StyledRowContainer from "./styled-row-container"; +import InfiniteLoaderComponent from "../infinite-loader"; class RowContainer extends React.PureComponent { renderRow = memo(({ data, index, style }) => { @@ -21,23 +22,12 @@ class RowContainer extends React.PureComponent { className, style, onScroll, + filesLength, + itemCount, + fetchMoreFiles, + hasMoreFiles, } = this.props; - const renderList = ({ height, width }) => ( - - {this.renderRow} - - ); - return ( - {useReactWindow ? {renderList} : children} + {useReactWindow ? ( + + {children} + + ) : ( + children + )} ); } @@ -69,6 +74,10 @@ RowContainer.propTypes = { style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), /** Called when the list scroll positions changes */ onScroll: PropTypes.func, + filesLength: PropTypes.number, + itemCount: PropTypes.number, + loadMoreItems: PropTypes.func, + hasMoreFiles: PropTypes.bool, }; RowContainer.defaultProps = { diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index c324c25371..3578417427 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -389,13 +389,6 @@ const StyledScrollbar = styled(Scrollbar)` } `; -const StyledLoader = styled.div` - grid-column-start: 1; - grid-column-end: -1; - display: grid; - padding-top: 16px; -`; - StyledTableRow.defaultProps = { theme: Base }; export { @@ -410,5 +403,4 @@ export { StyledInfoPanelToggleWrapper, StyledEmptyTableContainer, StyledScrollbar, - StyledLoader, }; diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js index baa931bb30..43ab0f5cf6 100644 --- a/packages/asc-web-components/table-container/TableBody.js +++ b/packages/asc-web-components/table-container/TableBody.js @@ -1,89 +1,46 @@ -import React, { useCallback, memo } from "react"; -import AutoSizer from "react-virtualized-auto-sizer"; -import { FixedSizeList as List, areEqual } from "react-window"; -import InfiniteLoader from "react-window-infinite-loader"; -import Loaders from "@appserver/common/components/Loaders"; - -import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; -import { StyledTableBody, StyledLoader } from "./StyledTableContainer"; +import React from "react"; +import { StyledTableBody } from "./StyledTableContainer"; +import InfiniteLoaderComponent from "../infinite-loader"; const TableBody = (props) => { const { columnStorageName, fetchMoreFiles, children, - filesListLength, + filesLength, hasMoreFiles, itemCount, + itemHeight, useReactWindow, + onScroll, } = props; - const renderTable = memo(({ data, index, style }) => { - const storageSize = localStorage.getItem(columnStorageName); - - const isLoaded = isItemLoaded(index + 1); - - if (!isLoaded) { - return ( - - - - ); - } - - return ( -
- {data[index]} -
- ); - }, areEqual); - - const isItemLoaded = useCallback( - (index) => !hasMoreFiles || index < filesListLength, - [filesListLength, hasMoreFiles] - ); - - const renderList = ({ height, width }) => ( - - {({ onItemsRendered, ref }) => ( - - {renderTable} - - )} - - ); - return useReactWindow ? ( - {renderList} + + {children} + ) : ( ); }; +TableBody.defaultProps = { + itemHeight: 40, +}; + export default TableBody; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index 53e1d5e5e1..2b3dad30f9 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -6,11 +6,6 @@ import { isMobile } from "react-device-detect"; import styled from "styled-components"; import marginStyles from "./CommonStyles"; import { Base } from "@appserver/components/themes"; -import Loaders from "@appserver/common/components/Loaders"; - -const StyledLoader = styled.div` - padding-top: 16px; -`; const StyledRowContainer = styled(RowContainer)` .row-selected + .row-wrapper:not(.row-selected) { @@ -68,7 +63,9 @@ const FilesRowContainer = ({ viewAs, setViewAs, infoPanelVisible, - filesIsLoading, + filterTotal, + fetchMoreFiles, + hasMoreFiles, }) => { useEffect(() => { if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return; @@ -88,8 +85,12 @@ const FilesRowContainer = ({ return ( {filesList.map((item, index) => ( ))} - {filesIsLoading && ( - - - - )} ); }; export default inject(({ filesStore, auth }) => { - const { filesList, viewAs, setViewAs, filesIsLoading } = filesStore; + const { + filesList, + viewAs, + setViewAs, + filterTotal, + fetchMoreFiles, + hasMoreFiles, + } = filesStore; const { isVisible: infoPanelVisible } = auth.infoPanelStore; return { filesList, viewAs, setViewAs, infoPanelVisible, - filesIsLoading, + filterTotal, + fetchMoreFiles, + hasMoreFiles, }; })(observer(FilesRowContainer)); 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 60fb5ec88d..95a9ebec6b 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 @@ -150,7 +150,7 @@ const Table = ({ Date: Mon, 11 Jul 2022 17:29:18 +0300 Subject: [PATCH 14/78] Web: Components: fixed updateTableRows --- packages/asc-web-components/infinite-loader/InfiniteLoader.js | 2 +- packages/asc-web-components/table-container/TableHeader.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/asc-web-components/infinite-loader/InfiniteLoader.js b/packages/asc-web-components/infinite-loader/InfiniteLoader.js index cbf5b0bea6..c8c64df13c 100644 --- a/packages/asc-web-components/infinite-loader/InfiniteLoader.js +++ b/packages/asc-web-components/infinite-loader/InfiniteLoader.js @@ -44,7 +44,7 @@ const InfiniteLoaderComponent = ({ return (
{ if (!this.props.useReactWindow) return; - const rows = document.getElementsByClassName("table-row"); + const rows = document.querySelectorAll(".table-row, .table-row-list-item"); if (rows?.length) { for (let i = 0; i < rows.length; i++) { From 5d712ea8b1f2a49c79a00fab820769dcc3f42f87 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 15 Jul 2022 11:58:58 +0300 Subject: [PATCH 15/78] Web: Components: moved ListComponent to another file, added GridComponent --- .../infinite-loader/Grid.js | 134 ++++++++++++++++++ .../infinite-loader/InfiniteLoader.js | 121 ++-------------- .../infinite-loader/List.js | 102 +++++++++++++ .../infinite-loader/StyledInfiniteLoader.js | 15 +- .../ASC.Files/Client/src/store/FilesStore.js | 1 - 5 files changed, 259 insertions(+), 114 deletions(-) create mode 100644 packages/asc-web-components/infinite-loader/Grid.js create mode 100644 packages/asc-web-components/infinite-loader/List.js diff --git a/packages/asc-web-components/infinite-loader/Grid.js b/packages/asc-web-components/infinite-loader/Grid.js new file mode 100644 index 0000000000..ea5c2e1955 --- /dev/null +++ b/packages/asc-web-components/infinite-loader/Grid.js @@ -0,0 +1,134 @@ +import React, { memo, useCallback } from "react"; +import AutoSizer from "react-virtualized-auto-sizer"; +import InfiniteLoader from "react-window-infinite-loader"; +import { VariableSizeList as List, areEqual } from "react-window"; +import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import Loaders from "@appserver/common/components/Loaders"; +import { StyledCard, StyledItem } from "./StyledInfiniteLoader"; + +const GridComponent = ({ + hasMoreFiles, + filesLength, + itemCount, + loadMoreItems, + onScroll, + countTilesInRow, + children, + className, +}) => { + const isItemLoaded = useCallback( + (index) => { + return !hasMoreFiles || index * countTilesInRow < filesLength; + }, + [filesLength, hasMoreFiles, countTilesInRow] + ); + + const renderTile = memo(({ data, index, style }) => { + const { itemCount } = data; + + // This is the range of cards visible on this row, given the current width: + const startIndex = index * countTilesInRow; + const stopIndex = Math.min(itemCount - 1, startIndex + countTilesInRow - 1); + let countLoaders = (stopIndex + 1) % countTilesInRow; + + const cards = []; + // Header(Files) + for (let i = startIndex; i <= stopIndex; i++) { + if (children[i].props.className === "tile-items-heading") { + cards.push( +
+ {children[i]} +
+ ); + + break; + } + + //Cards + cards.push( + + {children[i]} + + ); + } + + //Loaders + if (hasMoreFiles && cards.length) { + while (countLoaders !== 0) { + cards.push( + + ); + countLoaders--; + } + } + + return ( + + {cards} + + ); + }, areEqual); + + const getItemSize = (index) => { + const newIndex = index * countTilesInRow; + + if (!children[newIndex]) return 0; + + const itemProps = children[newIndex].props; + const isFile = itemProps?.className?.includes("file"); + const isFolder = itemProps?.className?.includes("folder"); + + const horizontalGap = 16; + const verticalGap = 14; + + const folderHeight = 64 + verticalGap; + const fileHeight = 220 + horizontalGap; + const titleHeight = 20 + horizontalGap; + + return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; + }; + + const renderGrid = ({ height, width }) => { + const itemsCount = children.length; + + const rowCount = Math.ceil(itemsCount / countTilesInRow) + 1; + + return ( + + {({ onItemsRendered, ref }) => ( + + {renderTile} + + )} + + ); + }; + + return {renderGrid}; +}; + +export default GridComponent; diff --git a/packages/asc-web-components/infinite-loader/InfiniteLoader.js b/packages/asc-web-components/infinite-loader/InfiniteLoader.js index c8c64df13c..c54cbe97db 100644 --- a/packages/asc-web-components/infinite-loader/InfiniteLoader.js +++ b/packages/asc-web-components/infinite-loader/InfiniteLoader.js @@ -1,125 +1,22 @@ -import React, { memo, useCallback } from "react"; +import React from "react"; import PropTypes from "prop-types"; -import AutoSizer from "react-virtualized-auto-sizer"; -import InfiniteLoader from "react-window-infinite-loader"; -import { FixedSizeList as List, areEqual } from "react-window"; -import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; -import Loaders from "@appserver/common/components/Loaders"; -import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; +import ListComponent from "./List"; +import GridComponent from "./Grid"; -const InfiniteLoaderComponent = ({ - viewAs, - hasMoreFiles, - filesLength, - itemCount, - loadMoreItems, - itemSize, - onScroll, - columnStorageName, - children, - className, -}) => { - const renderRow = memo(({ data, index, style }) => { - const isLoaded = isItemLoaded(index + 1); - if (!isLoaded) return getLoader(style); - - return
{data[index]}
; - }, areEqual); - - const renderTile = memo(({ data, index, style }) => { - //TODO: - return
{data[index]}
; - }, areEqual); - - const isItemLoaded = useCallback( - (index) => !hasMoreFiles || index < filesLength, - [filesLength, hasMoreFiles] +const InfiniteLoaderComponent = (props) => + props.viewAs === "tile" ? ( + + ) : ( + ); - const renderTable = memo(({ data, index, style }) => { - const storageSize = localStorage.getItem(columnStorageName); - - const isLoaded = isItemLoaded(index + 1); - if (!isLoaded) return getLoader(style); - - return ( -
- {data[index]} -
- ); - }, areEqual); - - const getLoader = (style) => { - switch (viewAs) { - case "table": - return ( - - - - ); - case "row": - return ( - - - - ); - case "tile": - return <>; - return; - default: - return; - } - }; - - const renderList = ({ height, width }) => ( - - {({ onItemsRendered, ref }) => ( - - {viewAs === "table" - ? renderTable - : viewAs === "row" - ? renderRow - : renderTile} - - )} - - ); - - return {renderList}; -}; - InfiniteLoaderComponent.propTypes = { viewAs: PropTypes.string.isRequired, hasMoreFiles: PropTypes.bool.isRequired, filesLength: PropTypes.number.isRequired, itemCount: PropTypes.number.isRequired, loadMoreItems: PropTypes.func.isRequired, - itemSize: PropTypes.number.isRequired, + itemSize: PropTypes.number, children: PropTypes.any.isRequired, /** Called when the list scroll positions changes */ onScroll: PropTypes.func, diff --git a/packages/asc-web-components/infinite-loader/List.js b/packages/asc-web-components/infinite-loader/List.js new file mode 100644 index 0000000000..7b52c4eef8 --- /dev/null +++ b/packages/asc-web-components/infinite-loader/List.js @@ -0,0 +1,102 @@ +import React, { memo, useCallback } from "react"; +import AutoSizer from "react-virtualized-auto-sizer"; +import InfiniteLoader from "react-window-infinite-loader"; +import { FixedSizeList as List, areEqual } from "react-window"; +import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import Loaders from "@appserver/common/components/Loaders"; +import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; + +const ListComponent = ({ + viewAs, + hasMoreFiles, + filesLength, + itemCount, + loadMoreItems, + itemSize, + onScroll, + columnStorageName, + children, + className, +}) => { + const renderRow = memo(({ index, style }) => { + const isLoaded = isItemLoaded(index + 1); + if (!isLoaded) return getLoader(style); + + return
{children[index]}
; + }, areEqual); + + const isItemLoaded = useCallback( + (index) => !hasMoreFiles || index < filesLength, + [filesLength, hasMoreFiles] + ); + + const renderTable = memo(({ index, style }) => { + const storageSize = localStorage.getItem(columnStorageName); + + const isLoaded = isItemLoaded(index + 1); + if (!isLoaded) return getLoader(style); + + return ( +
+ {children[index]} +
+ ); + }, areEqual); + + const getLoader = (style) => { + switch (viewAs) { + case "table": + return ( + + + + ); + case "row": + return ( + + + + ); + default: + return <>; + } + }; + + const renderList = ({ height, width }) => ( + + {({ onItemsRendered, ref }) => ( + + {viewAs === "table" ? renderTable : renderRow} + + )} + + ); + + return {renderList}; +}; + +export default ListComponent; diff --git a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js index bea5428a5d..6ffd862047 100644 --- a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js @@ -11,4 +11,17 @@ const StyledRowLoader = styled.div` padding-top: 16px; `; -export { StyledTableLoader, StyledRowLoader }; +const StyledCard = styled.div` + display: grid; + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); + + //gap: 14px 16px; +`; + +const StyledItem = styled.div` + display: grid; + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); + gap: 14px 16px; +`; + +export { StyledTableLoader, StyledRowLoader, StyledCard, StyledItem }; diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 7ddd8fd0a8..33683cdbda 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -2,7 +2,6 @@ import { makeAutoObservable, runInAction } from "mobx"; import api from "@appserver/common/api"; import { AppServerConfig, - FileAction, FileType, FilterType, FolderType, From 49bf1e0fa16410d894ab1567863ade8f276d3a46 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 15 Jul 2022 12:48:24 +0300 Subject: [PATCH 16/78] Web: Files: Tile: refactoring TileContainer --- .../TilesView/sub-components/TileContainer.js | 221 +++--------------- 1 file changed, 27 insertions(+), 194 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 4b6ba77026..7c4310ba09 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -1,14 +1,9 @@ -/* eslint-disable react/display-name */ -import React, { memo } from "react"; +import React from "react"; import { inject, observer } from "mobx-react"; import { withTranslation } from "react-i18next"; import styled, { css } from "styled-components"; import PropTypes from "prop-types"; -import { FixedSizeList as List, areEqual } from "react-window"; -import AutoSizer from "react-virtualized-auto-sizer"; import Heading from "@appserver/components/heading"; -import ContextMenu from "@appserver/components/context-menu"; -import CustomScrollbarsVirtualList from "@appserver/components/scrollbar"; import { isMobile } from "react-device-detect"; import { tablet, @@ -21,7 +16,6 @@ import Text from "@appserver/components/text"; import IconButton from "@appserver/components/icon-button"; import ComboBox from "@appserver/components/combobox"; import { Base } from "@appserver/components/themes"; -import Loaders from "@appserver/common/components/Loaders"; import SortDesc from "../../../../../../../../../../public/images/sort.desc.react.svg"; @@ -176,7 +170,6 @@ class TileContainer extends React.PureComponent { super(props); this.state = { - contextOptions: [], isOpen: false, selectedFilterData: { sortId: props.filter.sortBy, @@ -185,51 +178,12 @@ class TileContainer extends React.PureComponent { }; } - onRowContextClick = (options) => { - if (Array.isArray(options)) { - this.setState({ - contextOptions: options, - }); - } - }; - toggleDropdown = () => { this.setState((prev) => ({ isOpen: !prev.isOpen, })); }; - componentDidMount() { - window.addEventListener("contextmenu", this.onRowContextClick); - } - - componentWillUnmount() { - window.removeEventListener("contextmenu", this.onRowContextClick); - } - - renderFolders = () => { - return
; - }; - - renderFiles = () => { - return
; - }; - - // eslint-disable-next-line react/prop-types - renderTile = memo(({ data, index, style }) => { - // eslint-disable-next-line react/prop-types - const options = data[index].props.contextOptions; - - return ( -
- {data[index]} -
- ); - }, areEqual); - getSortData = () => { const { t, personal } = this.props; @@ -331,45 +285,9 @@ class TileContainer extends React.PureComponent { ); }; - getTilesLoaders = (folders, files) => { - const { getCountTilesInRow } = this.props; - - const countTilesInRow = getCountTilesInRow(); - const loaders = []; - - if (files.length === 0) { - let count = countTilesInRow - (folders.length % countTilesInRow); - while (count !== 0) { - loaders.push( - - ); - count--; - } - } else { - let count = countTilesInRow - (files.length % countTilesInRow); - while (count !== 0) { - loaders.push( - - ); - count--; - } - } - - return loaders; - }; - render() { const { t, - itemHeight, children, useReactWindow, id, @@ -379,9 +297,10 @@ class TileContainer extends React.PureComponent { headingFiles, isRecentFolder, isFavoritesFolder, - filesIsLoading, } = this.props; + const { isOpen, selectedFilterData } = this.state; + const Folders = []; const Files = []; @@ -389,47 +308,19 @@ class TileContainer extends React.PureComponent { const { isFolder, fileExst, id } = item.props.item; if ((isFolder || id === -1) && !fileExst) { Folders.push( -
+
{item}
); } else { Files.push( -
+
{item}
); } }); - const renderList = ({ height, width }) => ( - - {this.renderTile} - - ); - const advancedOptions = this.getAdvancedOptions(); const renderSorting = () => { @@ -442,7 +333,7 @@ class TileContainer extends React.PureComponent { !isMobileUtils() && (
- <> + {Folders.length > 0 && ( - {Folders.length > 0 && headingFolders} - {Folders.length > 0 && renderSorting()} + {headingFolders} + {renderSorting()} - {Folders.length > 0 && ( - <> - {useReactWindow ? ( - {renderList} - ) : ( - - {Folders} - {Files.length === 0 && filesIsLoading && loaders} - - )} - - )} - - - {Files.length > 0 && ( - <> - - {headingFiles} - {Folders.length === 0 && renderSorting()} - - {useReactWindow ? ( - {renderList} - ) : ( - - {Files} - {filesIsLoading && loaders} - - )} - + )} + {Folders.length > 0 && ( + {Folders} )} - + {Files.length > 0 && ( + + {headingFiles} + {Folders.length === 0 && renderSorting()} + + )} + {Files.length > 0 && {Files}} ); } } TileContainer.propTypes = { - itemHeight: PropTypes.number, - manualHeight: PropTypes.string, children: PropTypes.any.isRequired, useReactWindow: PropTypes.bool, className: PropTypes.string, @@ -537,58 +404,24 @@ TileContainer.propTypes = { }; TileContainer.defaultProps = { - itemHeight: 50, useReactWindow: true, - id: "rowContainer", + id: "tileContainer", }; export default inject( ({ auth, filesStore, treeFoldersStore, selectedFolderStore }) => { - const { - fetchFiles, - filter, - setIsLoading, - setViewAs, - viewAs, - files, - folders, - createThumbnails, - filesIsLoading, - getCountTilesInRow, - } = filesStore; - - const { user } = auth.userStore; - const { customNames, personal } = auth.settingsStore; + const { personal } = auth.settingsStore; + const { fetchFiles, filter, setIsLoading } = filesStore; const { isFavoritesFolder, isRecentFolder } = treeFoldersStore; - const { search, filterType, authorType } = filter; - const isFiltered = - (!!files.length || - !!folders.length || - search || - filterType || - authorType) && - !(treeFoldersStore.isPrivacyFolder && isMobile); - return { - customNames, - user, - selectedFolderId: selectedFolderStore.id, - selectedItem: filter.selectedItem, + personal, + fetchFiles, filter, - viewAs, - isFiltered, + setIsLoading, isFavoritesFolder, isRecentFolder, - - setIsLoading, - fetchFiles, - setViewAs, - createThumbnails, - filesIsLoading, - getCountTilesInRow, - - personal, + selectedFolderId: selectedFolderStore.id, }; } )(observer(withTranslation(["Home", "Common"])(TileContainer))); From 08aefad8691aa57ef2f26926c33d69be58fad4b1 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 15 Jul 2022 15:18:11 +0300 Subject: [PATCH 17/78] Web: Files: added InfiniteGrid component --- .../Body/TilesView/FilesTileContainer.js | 2 +- .../TilesView/sub-components/InfiniteGrid.js | 60 +++++++++++++++++++ .../TilesView/sub-components/TileContainer.js | 39 ++++++++---- 3 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js index 893ed32f5a..24c716953d 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js @@ -70,7 +70,7 @@ const FilesTileContainer = ({ filesList, t, sectionWidth }) => { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js new file mode 100644 index 0000000000..fa4d1e6aab --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js @@ -0,0 +1,60 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import InfiniteLoaderComponent from "@appserver/components/infinite-loader"; + +const InfiniteGrid = (props) => { + const { + children, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + className, + getCountTilesInRow, + ...rest + } = props; + + const list = []; + React.Children.map( + children.props.children, + (item) => item && list.push(item) + ); + + const countTilesInRow = getCountTilesInRow(); + + return ( + + {list} + + ); +}; + +export default inject(({ filesStore }) => { + const { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + getCountTilesInRow, + } = filesStore; + + const filesLength = filesList.length; + + return { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + getCountTilesInRow, + }; +})(observer(InfiniteGrid)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 7c4310ba09..972f50f52d 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -16,8 +16,8 @@ import Text from "@appserver/components/text"; import IconButton from "@appserver/components/icon-button"; import ComboBox from "@appserver/components/combobox"; import { Base } from "@appserver/components/themes"; - import SortDesc from "../../../../../../../../../../public/images/sort.desc.react.svg"; +import InfiniteGrid from "./InfiniteGrid"; const paddingCss = css` @media ${desktop} { @@ -55,6 +55,7 @@ const StyledGridWrapper = styled.div` const StyledTileContainer = styled.div` position: relative; + height: 100%; .tile-item-wrapper { position: relative; @@ -361,14 +362,8 @@ class TileContainer extends React.PureComponent { ); }; - return ( - + const renderTile = ( + <> {Folders.length > 0 && ( )} - {Folders.length > 0 && ( + {Folders.length > 0 && useReactWindow ? ( + Folders + ) : ( {Folders} )} @@ -389,7 +386,27 @@ class TileContainer extends React.PureComponent { {Folders.length === 0 && renderSorting()} )} - {Files.length > 0 && {Files}} + {Files.length > 0 && useReactWindow ? ( + Files + ) : ( + {Files} + )} + + ); + + return ( + + {useReactWindow ? ( + {renderTile} + ) : ( + renderTile + )} ); } From ab3b5a2dec482b5f90a590e0534e0e0effc84ad0 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 20 Jul 2022 12:31:57 +0300 Subject: [PATCH 18/78] Web: Files: moved InfiniteGrid to components --- .../infinite-loader/Grid.js | 84 ++------ .../infinite-loader/InfiniteGrid.js | 185 ++++++++++++++++++ .../infinite-loader/index.js | 5 +- .../asc-web-components/row-container/index.js | 2 +- .../table-container/TableBody.js | 2 +- .../Home/Section/Body/TableView/TableRow.js | 1 - .../TilesView/sub-components/InfiniteGrid.js | 60 ------ .../TilesView/sub-components/TileContainer.js | 39 ++-- 8 files changed, 229 insertions(+), 149 deletions(-) create mode 100644 packages/asc-web-components/infinite-loader/InfiniteGrid.js delete mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js diff --git a/packages/asc-web-components/infinite-loader/Grid.js b/packages/asc-web-components/infinite-loader/Grid.js index ea5c2e1955..03e96b8926 100644 --- a/packages/asc-web-components/infinite-loader/Grid.js +++ b/packages/asc-web-components/infinite-loader/Grid.js @@ -3,8 +3,6 @@ import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { VariableSizeList as List, areEqual } from "react-window"; import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; -import Loaders from "@appserver/common/components/Loaders"; -import { StyledCard, StyledItem } from "./StyledInfiniteLoader"; const GridComponent = ({ hasMoreFiles, @@ -23,84 +21,29 @@ const GridComponent = ({ [filesLength, hasMoreFiles, countTilesInRow] ); - const renderTile = memo(({ data, index, style }) => { - const { itemCount } = data; - - // This is the range of cards visible on this row, given the current width: - const startIndex = index * countTilesInRow; - const stopIndex = Math.min(itemCount - 1, startIndex + countTilesInRow - 1); - let countLoaders = (stopIndex + 1) % countTilesInRow; - - const cards = []; - // Header(Files) - for (let i = startIndex; i <= stopIndex; i++) { - if (children[i].props.className === "tile-items-heading") { - cards.push( -
- {children[i]} -
- ); - - break; - } - - //Cards - cards.push( - - {children[i]} - - ); - } - - //Loaders - if (hasMoreFiles && cards.length) { - while (countLoaders !== 0) { - cards.push( - - ); - countLoaders--; - } - } - - return ( - - {cards} - - ); + const renderTile = memo(({ index, style }) => { + // console.log("renderTile children[index]", children[index]); + // console.log("renderTile style", style); + return
{children[index]}
; }, areEqual); const getItemSize = (index) => { - const newIndex = index * countTilesInRow; - - if (!children[newIndex]) return 0; - - const itemProps = children[newIndex].props; - const isFile = itemProps?.className?.includes("file"); - const isFolder = itemProps?.className?.includes("folder"); + const itemClassNames = children[index]?.props?.className; + const isFile = itemClassNames?.includes("isFile"); + const isFolder = itemClassNames?.includes("isFolder"); const horizontalGap = 16; const verticalGap = 14; + const headerMargin = 15; const folderHeight = 64 + verticalGap; const fileHeight = 220 + horizontalGap; - const titleHeight = 20 + horizontalGap; + const titleHeight = 20 + headerMargin; return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; }; const renderGrid = ({ height, width }) => { - const itemsCount = children.length; - - const rowCount = Math.ceil(itemsCount / countTilesInRow) + 1; - return ( {renderTile} @@ -128,6 +70,8 @@ const GridComponent = ({ ); }; + //console.log("GridComponent render"); + return {renderGrid}; }; diff --git a/packages/asc-web-components/infinite-loader/InfiniteGrid.js b/packages/asc-web-components/infinite-loader/InfiniteGrid.js new file mode 100644 index 0000000000..ecf07a029f --- /dev/null +++ b/packages/asc-web-components/infinite-loader/InfiniteGrid.js @@ -0,0 +1,185 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import InfiniteLoaderComponent from "./InfiniteLoader"; +import { StyledCard, StyledItem } from "./StyledInfiniteLoader"; +import Loaders from "@appserver/common/components/Loaders"; + +const InfiniteGrid = (props) => { + const { + children, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + className, + getCountTilesInRow, + ...rest + } = props; + + const countTilesInRow = getCountTilesInRow(); + + let temp = []; + const list = []; + + const getItemSize = (child) => { + const isFile = child?.props?.className?.includes("file"); + const isFolder = child?.props?.className?.includes("folder"); + + const horizontalGap = 16; + const verticalGap = 14; + const headerMargin = 15; + + const folderHeight = 64 + verticalGap; + const fileHeight = 220 + horizontalGap; + const titleHeight = 20 + headerMargin; + + return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; + }; + + React.Children.map(children.props.children, (child, index) => { + if (child) { + //debugger; + //console.log("child.key", child.key); + + if (child.props.className === "tile-items-heading") { + //if after folder files title, push item to list + if (temp.length) { + const isFolder = temp + .at(-1) + .props.children.props.className.includes("folder"); + const otherClassName2 = isFolder ? "Item isFolder" : "Item isFile"; + + // console.log("temp", temp); + // console.log("temp", `item_${temp.at(-1).key}`); + + list.push( + + {temp} + + ); + temp = []; + } + + list.push( +
+ {child} +
+ ); + } else { + const isFile = child?.props?.className?.includes("file"); + const className = isFile ? "Item isFile" : "Item isFolder"; + + const item = ( + + {child} + + ); + + if (temp.length && temp.length === countTilesInRow) { + list.push( + + {temp} + + ); + temp = []; + } + temp.push(item); + } + } + }); + + // TODO: inf-scroll loaders + // refactoring + + const isFolder = temp.length + ? temp.at(-1).props.children.props.className.includes("folder") + : list.at(-1).props.className.includes("isFolder"); + + const otherClassName = isFolder ? "isFolder" : "isFile"; + + if (hasMoreFiles) { + if (temp.length === countTilesInRow) { + list.push( + + {temp} + + ); + temp = []; + } + + while (temp.length !== countTilesInRow) { + temp.push( + + ); + } + + list.push( + + {temp} + + ); + } else if (temp.length) { + const key = temp.at(-1).key; + list.push( + + {temp} + + ); + } + + //console.log("InfiniteGrid render", list); + + return ( + + {list} + + ); +}; + +export default inject(({ filesStore }) => { + const { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + getCountTilesInRow, + } = filesStore; + + const filesLength = filesList.length; + + return { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + getCountTilesInRow, + }; +})(observer(InfiniteGrid)); diff --git a/packages/asc-web-components/infinite-loader/index.js b/packages/asc-web-components/infinite-loader/index.js index b50b5bc43a..abb26b39b0 100644 --- a/packages/asc-web-components/infinite-loader/index.js +++ b/packages/asc-web-components/infinite-loader/index.js @@ -1 +1,4 @@ -export default from "./InfiniteLoader"; +import InfiniteGrid from "./InfiniteGrid"; +import InfiniteLoaderComponent from "./InfiniteLoader"; + +export { InfiniteGrid, InfiniteLoaderComponent }; diff --git a/packages/asc-web-components/row-container/index.js b/packages/asc-web-components/row-container/index.js index a784544a42..574ade4658 100644 --- a/packages/asc-web-components/row-container/index.js +++ b/packages/asc-web-components/row-container/index.js @@ -5,7 +5,7 @@ import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual- import { FixedSizeList as List, areEqual } from "react-window"; import AutoSizer from "react-virtualized-auto-sizer"; import StyledRowContainer from "./styled-row-container"; -import InfiniteLoaderComponent from "../infinite-loader"; +import { InfiniteLoaderComponent } from "../infinite-loader"; class RowContainer extends React.PureComponent { renderRow = memo(({ data, index, style }) => { diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js index 43ab0f5cf6..3da15ef577 100644 --- a/packages/asc-web-components/table-container/TableBody.js +++ b/packages/asc-web-components/table-container/TableBody.js @@ -1,6 +1,6 @@ import React from "react"; import { StyledTableBody } from "./StyledTableContainer"; -import InfiniteLoaderComponent from "../infinite-loader"; +import { InfiniteLoaderComponent } from "../infinite-loader"; const TableBody = (props) => { const { 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 6b0fbf6430..8b590a911e 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 @@ -273,7 +273,6 @@ const FilesTableRow = (props) => { showHotkeyBorder, tableColumns, id, - style: tableStyles,//TODO: inf-scroll } = props; const { acceptBackground, background } = theme.dragAndDrop; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js deleted file mode 100644 index fa4d1e6aab..0000000000 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import { inject, observer } from "mobx-react"; -import InfiniteLoaderComponent from "@appserver/components/infinite-loader"; - -const InfiniteGrid = (props) => { - const { - children, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - filesLength, - className, - getCountTilesInRow, - ...rest - } = props; - - const list = []; - React.Children.map( - children.props.children, - (item) => item && list.push(item) - ); - - const countTilesInRow = getCountTilesInRow(); - - return ( - - {list} - - ); -}; - -export default inject(({ filesStore }) => { - const { - filesList, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - getCountTilesInRow, - } = filesStore; - - const filesLength = filesList.length; - - return { - filesList, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - filesLength, - getCountTilesInRow, - }; -})(observer(InfiniteGrid)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 972f50f52d..d7b9cf90fc 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -17,7 +17,7 @@ import IconButton from "@appserver/components/icon-button"; import ComboBox from "@appserver/components/combobox"; import { Base } from "@appserver/components/themes"; import SortDesc from "../../../../../../../../../../public/images/sort.desc.react.svg"; -import InfiniteGrid from "./InfiniteGrid"; +import { InfiniteGrid } from "@appserver/components/infinite-loader"; const paddingCss = css` @media ${desktop} { @@ -305,17 +305,17 @@ class TileContainer extends React.PureComponent { const Folders = []; const Files = []; - React.Children.map(children, (item, index) => { + React.Children.map(children, (item) => { const { isFolder, fileExst, id } = item.props.item; if ((isFolder || id === -1) && !fileExst) { Folders.push( -
+
{item}
); } else { Files.push( -
+
{item}
); @@ -366,6 +366,7 @@ class TileContainer extends React.PureComponent { <> {Folders.length > 0 && ( )} - {Folders.length > 0 && useReactWindow ? ( - Folders - ) : ( - {Folders} - )} + {Folders.length > 0 ? ( + useReactWindow ? ( + Folders + ) : ( + {Folders} + ) + ) : null} {Files.length > 0 && ( - + {headingFiles} {Folders.length === 0 && renderSorting()} )} - {Files.length > 0 && useReactWindow ? ( - Files - ) : ( - {Files} - )} + {Files.length > 0 ? ( + useReactWindow ? ( + Files + ) : ( + {Files} + ) + ) : null} ); From 310c774cfb39fdd108fa30a7d7082562d1ba3c02 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 20 Jul 2022 13:25:33 +0300 Subject: [PATCH 19/78] Web: Components: added custom scroll, changed outerElementType for VariableSizeList --- .../infinite-loader/Grid.js | 4 +- .../infinite-loader/List.js | 4 +- .../infinite-loader/Scroll.js | 8 ++++ .../infinite-loader/StyledInfiniteLoader.js | 41 +++++++++++++++++-- 4 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 packages/asc-web-components/infinite-loader/Scroll.js diff --git a/packages/asc-web-components/infinite-loader/Grid.js b/packages/asc-web-components/infinite-loader/Grid.js index 03e96b8926..239e11da37 100644 --- a/packages/asc-web-components/infinite-loader/Grid.js +++ b/packages/asc-web-components/infinite-loader/Grid.js @@ -2,7 +2,7 @@ import React, { memo, useCallback } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { VariableSizeList as List, areEqual } from "react-window"; -import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import Scroll from "./Scroll"; const GridComponent = ({ hasMoreFiles, @@ -60,7 +60,7 @@ const GridComponent = ({ width={width} onItemsRendered={onItemsRendered} ref={ref} - //outerElementType={CustomScrollbarsVirtualList} + outerElementType={Scroll} overscanCount={5} //TODO: inf-scroll > {renderTile} diff --git a/packages/asc-web-components/infinite-loader/List.js b/packages/asc-web-components/infinite-loader/List.js index 7b52c4eef8..6f23908d9a 100644 --- a/packages/asc-web-components/infinite-loader/List.js +++ b/packages/asc-web-components/infinite-loader/List.js @@ -2,7 +2,7 @@ import React, { memo, useCallback } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { FixedSizeList as List, areEqual } from "react-window"; -import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; +import Scroll from "./Scroll"; import Loaders from "@appserver/common/components/Loaders"; import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; @@ -88,7 +88,7 @@ const ListComponent = ({ itemCount={children.length} onItemsRendered={onItemsRendered} ref={ref} - outerElementType={CustomScrollbarsVirtualList} + outerElementType={Scroll} > {viewAs === "table" ? renderTable : renderRow} diff --git a/packages/asc-web-components/infinite-loader/Scroll.js b/packages/asc-web-components/infinite-loader/Scroll.js new file mode 100644 index 0000000000..4ca05c099e --- /dev/null +++ b/packages/asc-web-components/infinite-loader/Scroll.js @@ -0,0 +1,8 @@ +import React, { forwardRef } from "react"; +import { StyledScroll } from "./StyledInfiniteLoader"; + +const Scroll = forwardRef((props, ref) => { + return ; +}); + +export default Scroll; diff --git a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js index 6ffd862047..737dc13499 100644 --- a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js @@ -1,4 +1,5 @@ import styled from "styled-components"; +import Base from "../themes/base"; const StyledTableLoader = styled.div` grid-column-start: 1; @@ -14,8 +15,6 @@ const StyledRowLoader = styled.div` const StyledCard = styled.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); - - //gap: 14px 16px; `; const StyledItem = styled.div` @@ -24,4 +23,40 @@ const StyledItem = styled.div` gap: 14px 16px; `; -export { StyledTableLoader, StyledRowLoader, StyledCard, StyledItem }; +const StyledScroll = styled.div` + overflow: scroll; + + /* Chrome, Edge и Safari */ + + ::-webkit-scrollbar { + width: 8px; + height: 8px; + } + + ::-webkit-scrollbar-thumb { + background-color: ${({ theme }) => theme.scrollbar.backgroundColorVertical}; + border-radius: 3px; + + :hover { + background-color: ${({ theme }) => + theme.scrollbar.hoverBackgroundColorVertical}; + } + } + + /* Firefox */ + + scrollbar-width: thin; + scrollbar-color: ${({ theme }) => theme.scrollbar.backgroundColorVertical}; +`; + +StyledScroll.defaultProps = { + theme: Base, +}; + +export { + StyledTableLoader, + StyledRowLoader, + StyledCard, + StyledItem, + StyledScroll, +}; From bdc07bd48da9919815776f2a49725f2514bfdf8a Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 20 Jul 2022 16:13:50 +0300 Subject: [PATCH 20/78] Web: Components: added resetAfterIndex after folder change --- .../asc-web-components/infinite-loader/Grid.js | 18 ++++++++++++++---- .../infinite-loader/InfiniteGrid.js | 12 +++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/asc-web-components/infinite-loader/Grid.js b/packages/asc-web-components/infinite-loader/Grid.js index 239e11da37..7acd2c307d 100644 --- a/packages/asc-web-components/infinite-loader/Grid.js +++ b/packages/asc-web-components/infinite-loader/Grid.js @@ -1,4 +1,4 @@ -import React, { memo, useCallback } from "react"; +import React, { memo, useCallback, useEffect, useRef } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { VariableSizeList as List, areEqual } from "react-window"; @@ -11,9 +11,18 @@ const GridComponent = ({ loadMoreItems, onScroll, countTilesInRow, + selectedFolderId, children, className, }) => { + const gridRef = useRef(null); + + useEffect(() => { + //console.log("resetAfterIndex"); + + gridRef?.current?.resetAfterIndex(0); + }, [selectedFolderId]); + const isItemLoaded = useCallback( (index) => { return !hasMoreFiles || index * countTilesInRow < filesLength; @@ -22,8 +31,6 @@ const GridComponent = ({ ); const renderTile = memo(({ index, style }) => { - // console.log("renderTile children[index]", children[index]); - // console.log("renderTile style", style); return
{children[index]}
; }, areEqual); @@ -59,7 +66,10 @@ const GridComponent = ({ itemSize={getItemSize} width={width} onItemsRendered={onItemsRendered} - ref={ref} + ref={(listRef) => { + ref(listRef); + gridRef.current = listRef; + }} outerElementType={Scroll} overscanCount={5} //TODO: inf-scroll > diff --git a/packages/asc-web-components/infinite-loader/InfiniteGrid.js b/packages/asc-web-components/infinite-loader/InfiniteGrid.js index ecf07a029f..31afec0eed 100644 --- a/packages/asc-web-components/infinite-loader/InfiniteGrid.js +++ b/packages/asc-web-components/infinite-loader/InfiniteGrid.js @@ -13,6 +13,7 @@ const InfiniteGrid = (props) => { filesLength, className, getCountTilesInRow, + selectedFolderId, ...rest } = props; @@ -38,9 +39,6 @@ const InfiniteGrid = (props) => { React.Children.map(children.props.children, (child, index) => { if (child) { - //debugger; - //console.log("child.key", child.key); - if (child.props.className === "tile-items-heading") { //if after folder files title, push item to list if (temp.length) { @@ -49,9 +47,6 @@ const InfiniteGrid = (props) => { .props.children.props.className.includes("folder"); const otherClassName2 = isFolder ? "Item isFolder" : "Item isFile"; - // console.log("temp", temp); - // console.log("temp", `item_${temp.at(-1).key}`); - list.push( { itemCount={filterTotal / countTilesInRow} //TODO: - count headers loadMoreItems={fetchMoreFiles} className={`TileList ${className}`} + selectedFolderId={selectedFolderId} {...rest} > {list} @@ -163,7 +159,8 @@ const InfiniteGrid = (props) => { ); }; -export default inject(({ filesStore }) => { +//TODO: remove store +export default inject(({ filesStore, selectedFolderStore }) => { const { filesList, hasMoreFiles, @@ -181,5 +178,6 @@ export default inject(({ filesStore }) => { fetchMoreFiles, filesLength, getCountTilesInRow, + selectedFolderId: selectedFolderStore.id, }; })(observer(InfiniteGrid)); From a9d23c4d1958d703d3c7a3e6f237fa677683104e Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 21 Jul 2022 11:27:29 +0300 Subject: [PATCH 21/78] Web: Files: InfiniteLoader: refactoring --- .../infinite-loader/Grid.js | 1 + .../infinite-loader/InfiniteGrid.js | 183 ----------------- .../infinite-loader/StyledInfiniteLoader.js | 19 +- .../infinite-loader/index.js | 5 +- .../asc-web-components/row-container/index.js | 11 +- .../table-container/TableBody.js | 2 +- .../TilesView/sub-components/InfiniteGrid.js | 184 ++++++++++++++++++ .../sub-components/StyledInfiniteGrid.js | 20 ++ .../TilesView/sub-components/TileContainer.js | 9 +- 9 files changed, 212 insertions(+), 222 deletions(-) delete mode 100644 packages/asc-web-components/infinite-loader/InfiniteGrid.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js diff --git a/packages/asc-web-components/infinite-loader/Grid.js b/packages/asc-web-components/infinite-loader/Grid.js index 7acd2c307d..97ed974665 100644 --- a/packages/asc-web-components/infinite-loader/Grid.js +++ b/packages/asc-web-components/infinite-loader/Grid.js @@ -18,6 +18,7 @@ const GridComponent = ({ const gridRef = useRef(null); useEffect(() => { + //TODO:it is slow //console.log("resetAfterIndex"); gridRef?.current?.resetAfterIndex(0); diff --git a/packages/asc-web-components/infinite-loader/InfiniteGrid.js b/packages/asc-web-components/infinite-loader/InfiniteGrid.js deleted file mode 100644 index 31afec0eed..0000000000 --- a/packages/asc-web-components/infinite-loader/InfiniteGrid.js +++ /dev/null @@ -1,183 +0,0 @@ -import React from "react"; -import { inject, observer } from "mobx-react"; -import InfiniteLoaderComponent from "./InfiniteLoader"; -import { StyledCard, StyledItem } from "./StyledInfiniteLoader"; -import Loaders from "@appserver/common/components/Loaders"; - -const InfiniteGrid = (props) => { - const { - children, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - filesLength, - className, - getCountTilesInRow, - selectedFolderId, - ...rest - } = props; - - const countTilesInRow = getCountTilesInRow(); - - let temp = []; - const list = []; - - const getItemSize = (child) => { - const isFile = child?.props?.className?.includes("file"); - const isFolder = child?.props?.className?.includes("folder"); - - const horizontalGap = 16; - const verticalGap = 14; - const headerMargin = 15; - - const folderHeight = 64 + verticalGap; - const fileHeight = 220 + horizontalGap; - const titleHeight = 20 + headerMargin; - - return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; - }; - - React.Children.map(children.props.children, (child, index) => { - if (child) { - if (child.props.className === "tile-items-heading") { - //if after folder files title, push item to list - if (temp.length) { - const isFolder = temp - .at(-1) - .props.children.props.className.includes("folder"); - const otherClassName2 = isFolder ? "Item isFolder" : "Item isFile"; - - list.push( - - {temp} - - ); - temp = []; - } - - list.push( -
- {child} -
- ); - } else { - const isFile = child?.props?.className?.includes("file"); - const className = isFile ? "Item isFile" : "Item isFolder"; - - const item = ( - - {child} - - ); - - if (temp.length && temp.length === countTilesInRow) { - list.push( - - {temp} - - ); - temp = []; - } - temp.push(item); - } - } - }); - - // TODO: inf-scroll loaders - // refactoring - - const isFolder = temp.length - ? temp.at(-1).props.children.props.className.includes("folder") - : list.at(-1).props.className.includes("isFolder"); - - const otherClassName = isFolder ? "isFolder" : "isFile"; - - if (hasMoreFiles) { - if (temp.length === countTilesInRow) { - list.push( - - {temp} - - ); - temp = []; - } - - while (temp.length !== countTilesInRow) { - temp.push( - - ); - } - - list.push( - - {temp} - - ); - } else if (temp.length) { - const key = temp.at(-1).key; - list.push( - - {temp} - - ); - } - - //console.log("InfiniteGrid render", list); - - return ( - - {list} - - ); -}; - -//TODO: remove store -export default inject(({ filesStore, selectedFolderStore }) => { - const { - filesList, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - getCountTilesInRow, - } = filesStore; - - const filesLength = filesList.length; - - return { - filesList, - hasMoreFiles, - filterTotal, - fetchMoreFiles, - filesLength, - getCountTilesInRow, - selectedFolderId: selectedFolderStore.id, - }; -})(observer(InfiniteGrid)); diff --git a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js index 737dc13499..8ed1d2b8d3 100644 --- a/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/asc-web-components/infinite-loader/StyledInfiniteLoader.js @@ -12,17 +12,6 @@ const StyledRowLoader = styled.div` padding-top: 16px; `; -const StyledCard = styled.div` - display: grid; - grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); -`; - -const StyledItem = styled.div` - display: grid; - grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); - gap: 14px 16px; -`; - const StyledScroll = styled.div` overflow: scroll; @@ -53,10 +42,4 @@ StyledScroll.defaultProps = { theme: Base, }; -export { - StyledTableLoader, - StyledRowLoader, - StyledCard, - StyledItem, - StyledScroll, -}; +export { StyledTableLoader, StyledRowLoader, StyledScroll }; diff --git a/packages/asc-web-components/infinite-loader/index.js b/packages/asc-web-components/infinite-loader/index.js index abb26b39b0..b50b5bc43a 100644 --- a/packages/asc-web-components/infinite-loader/index.js +++ b/packages/asc-web-components/infinite-loader/index.js @@ -1,4 +1 @@ -import InfiniteGrid from "./InfiniteGrid"; -import InfiniteLoaderComponent from "./InfiniteLoader"; - -export { InfiniteGrid, InfiniteLoaderComponent }; +export default from "./InfiniteLoader"; diff --git a/packages/asc-web-components/row-container/index.js b/packages/asc-web-components/row-container/index.js index 574ade4658..34cc2cf707 100644 --- a/packages/asc-web-components/row-container/index.js +++ b/packages/asc-web-components/row-container/index.js @@ -1,17 +1,10 @@ /* eslint-disable react/display-name */ -import React, { memo } from "react"; +import React from "react"; import PropTypes from "prop-types"; -import CustomScrollbarsVirtualList from "../scrollbar/custom-scrollbars-virtual-list"; -import { FixedSizeList as List, areEqual } from "react-window"; -import AutoSizer from "react-virtualized-auto-sizer"; import StyledRowContainer from "./styled-row-container"; -import { InfiniteLoaderComponent } from "../infinite-loader"; +import InfiniteLoaderComponent from "../infinite-loader"; class RowContainer extends React.PureComponent { - renderRow = memo(({ data, index, style }) => { - return
{data[index]}
; - }, areEqual); - render() { const { manualHeight, diff --git a/packages/asc-web-components/table-container/TableBody.js b/packages/asc-web-components/table-container/TableBody.js index 3da15ef577..43ab0f5cf6 100644 --- a/packages/asc-web-components/table-container/TableBody.js +++ b/packages/asc-web-components/table-container/TableBody.js @@ -1,6 +1,6 @@ import React from "react"; import { StyledTableBody } from "./StyledTableContainer"; -import { InfiniteLoaderComponent } from "../infinite-loader"; +import InfiniteLoaderComponent from "../infinite-loader"; const TableBody = (props) => { const { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js new file mode 100644 index 0000000000..d6bb76f7f9 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js @@ -0,0 +1,184 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import InfiniteLoaderComponent from "@appserver/components/infinite-loader"; +import { StyledCard, StyledItem, StyledHeaderItem } from "./StyledInfiniteGrid"; +import Loaders from "@appserver/common/components/Loaders"; +import uniqueid from "lodash/uniqueId"; + +const HeaderItem = ({ children, ...rest }) => { + return ( + + {children} + + ); +}; + +const Card = ({ children, ...rest }) => { + const getItemSize = (child) => { + const isFile = child?.props?.className?.includes("file"); + const isFolder = child?.props?.className?.includes("folder"); + + const horizontalGap = 16; + const verticalGap = 14; + const headerMargin = 15; + + const folderHeight = 64 + verticalGap; + const fileHeight = 220 + horizontalGap; + const titleHeight = 20 + headerMargin; + + return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; + }; + + const cardHeight = getItemSize(children); + + return ( + + {children} + + ); +}; + +const Item = ({ children, className, ...rest }) => { + return ( + + {children} + + ); +}; + +const InfiniteGrid = (props) => { + const { + children, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + className, + getCountTilesInRow, + selectedFolderId, + ...rest + } = props; + + const countTilesInRow = getCountTilesInRow(); + + let cards = []; + const list = []; + + const addItemToList = (key, className, clear) => { + list.push( + + {cards} + + ); + if (clear) cards = []; + }; + + const checkIsFolder = (useTempList = true) => { + const isFolder = useTempList + ? cards.at(-1).props.children.props.className.includes("folder") + : list.at(-1).props.className.includes("isFolder"); + return isFolder; + }; + + React.Children.map(children.props.children, (child) => { + if (child) { + if (child.props.className === "tile-items-heading") { + // If cards is not empty then put the cards into the list + if (cards.length) { + const isFolder = checkIsFolder(); + + addItemToList( + `last-item-of_${isFolder ? "folders" : "files"}`, + isFolder ? "isFolder" : "isFile", + true + ); + } + + list.push( + + {child} + + ); + } else { + const isFile = child?.props?.className?.includes("file"); + const className = isFile ? "isFile" : "isFolder"; + + if (cards.length && cards.length === countTilesInRow) { + const listKey = uniqueid("list-item_"); + addItemToList(listKey, className, true); + } + + const cardKey = uniqueid("card-item_"); + cards.push({child}); + } + } + }); + + const isFolder = checkIsFolder(!!cards.length); + const otherClassName = isFolder ? "isFolder" : "isFile"; + + if (hasMoreFiles) { + // If cards elements are full, it will add the full line of loaders + if (cards.length === countTilesInRow) { + addItemToList("loaded-row", otherClassName, true); + } + + // Added line of loaders + while (cards.length !== countTilesInRow) { + const key = `tiles-loader_${countTilesInRow - cards.length}`; + cards.push( + + ); + } + + addItemToList("loaded-row", otherClassName); + } else if (cards.length) { + // Adds loaders until the row is full + const listKey = uniqueid("list-item_"); + addItemToList(listKey, otherClassName); + } + + //console.log("InfiniteGrid render", list); + + return ( + + {list} + + ); +}; + +export default inject(({ filesStore, selectedFolderStore }) => { + const { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + getCountTilesInRow, + } = filesStore; + + const filesLength = filesList.length; + + return { + filesList, + hasMoreFiles, + filterTotal, + fetchMoreFiles, + filesLength, + getCountTilesInRow, + selectedFolderId: selectedFolderStore.id, + }; +})(observer(InfiniteGrid)); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js new file mode 100644 index 0000000000..77ad4e1855 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js @@ -0,0 +1,20 @@ +import styled from "styled-components"; + +const StyledCard = styled.div` + display: grid; + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); + height: ${({ cardHeight }) => `${cardHeight}px`}; +`; + +const StyledItem = styled.div` + display: grid; + grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); + gap: 14px 16px; +`; + +const StyledHeaderItem = styled.div` + height: 20px; + grid-column: -1 / 1; +`; + +export { StyledCard, StyledItem, StyledHeaderItem }; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index d7b9cf90fc..f3bc1fbe22 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -17,7 +17,7 @@ import IconButton from "@appserver/components/icon-button"; import ComboBox from "@appserver/components/combobox"; import { Base } from "@appserver/components/themes"; import SortDesc from "../../../../../../../../../../public/images/sort.desc.react.svg"; -import { InfiniteGrid } from "@appserver/components/infinite-loader"; +import InfiniteGrid from "./InfiniteGrid"; const paddingCss = css` @media ${desktop} { @@ -366,7 +366,6 @@ class TileContainer extends React.PureComponent { <> {Folders.length > 0 && ( 0 && ( - + {headingFiles} {Folders.length === 0 && renderSorting()} From 0de5d36ce4965fe3b7ab855e34a53849071ca746 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 9 Aug 2022 13:43:24 +0300 Subject: [PATCH 22/78] Web: Files: Scroll: added WindowScroller --- .../Section/Body/TableView/TableHeader.js | 46 ++++++------- packages/client/src/pages/Home/index.js | 2 +- .../Section/sub-components/section-body.js | 5 +- packages/components/infinite-loader/Grid.js | 15 +++-- .../infinite-loader/InfiniteLoader.js | 31 +++++++-- packages/components/infinite-loader/List.js | 67 ++++++++++++------- packages/components/package.json | 1 + .../table-container/StyledTableContainer.js | 3 - yarn.lock | 22 +++++- 9 files changed, 121 insertions(+), 71 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js index 37aa8507ea..26f4e7e97f 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableHeader.js @@ -299,35 +299,34 @@ class FilesTableHeader extends React.Component { localStorage.setItem(this.props.tableStorageName, tableColumns); }; -//TODO: inf-scroll componentDidMount() { - //this.customScrollElm = document.getElementsByClassName("section-scroll")[0]; - //this.customScrollElm.addEventListener("scroll", this.onBeginScroll); + this.customScrollElm = document.getElementsByClassName("section-scroll")[0]; + this.customScrollElm.addEventListener("scroll", this.onBeginScroll); } - // onBeginScroll = () => { - // const { firstElemChecked } = this.props; + onBeginScroll = () => { + const { firstElemChecked } = this.props; - // const currentScrollPosition = this.customScrollElm.scrollTop; - // const elem = document.getElementById("table-container_caption-header"); + const currentScrollPosition = this.customScrollElm.scrollTop; + const elem = document.getElementById("table-container_caption-header"); - // if (currentScrollPosition === 0) { - // this.isBeginScrolling = false; + if (currentScrollPosition === 0) { + this.isBeginScrolling = false; - // this.props.headerBorder && - // elem?.classList?.add("hotkeys-lengthen-header"); + this.props.headerBorder && + elem?.classList?.add("hotkeys-lengthen-header"); - // !firstElemChecked && elem?.classList?.remove("lengthen-header"); - // return; - // } + !firstElemChecked && elem?.classList?.remove("lengthen-header"); + return; + } - // if (!this.isBeginScrolling) { - // elem?.classList?.remove("hotkeys-lengthen-header"); - // elem?.classList?.add("lengthen-header"); - // } + if (!this.isBeginScrolling) { + elem?.classList?.remove("hotkeys-lengthen-header"); + elem?.classList?.add("lengthen-header"); + } - // this.isBeginScrolling = true; - // }; + this.isBeginScrolling = true; + }; componentDidUpdate(prevProps) { if (this.props.isRooms !== this.state.isRooms) { return this.getTableColumns(true); @@ -351,10 +350,9 @@ class FilesTableHeader extends React.Component { } } -//TODO: inf-scroll - // componentWillUnmount() { - // this.customScrollElm.removeEventListener("scroll", this.onBeginScroll); - // } + componentWillUnmount() { + this.customScrollElm.removeEventListener("scroll", this.onBeginScroll); + } getColumns = (defaultColumns, splitColumns) => { const columns = []; diff --git a/packages/client/src/pages/Home/index.js b/packages/client/src/pages/Home/index.js index 76905470ce..f17d639a96 100644 --- a/packages/client/src/pages/Home/index.js +++ b/packages/client/src/pages/Home/index.js @@ -513,7 +513,7 @@ class PureHome extends React.Component {
!withScroll && "padding: 0"}; //TODO: inf-scroll - @media ${tablet} { padding: ${(props) => props.settingsStudio ? "0 0 16px 24px" : "19px 0 16px 24px"}; @@ -70,6 +68,8 @@ const commonStyles = css` } .section-wrapper-content { + height: 100%; + ${paddingStyles} flex: 1 0 auto; outline: none; @@ -137,7 +137,6 @@ const StyledSectionBody = styled.div` const StyledDropZoneBody = styled(DragAndDrop)` max-width: 100vw !important; - /* padding-right: 20px; */ //TODO: inf-scroll ${commonStyles} .drag-and-drop { user-select: none; diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 97ed974665..ac72dc5886 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -2,7 +2,7 @@ import React, { memo, useCallback, useEffect, useRef } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { VariableSizeList as List, areEqual } from "react-window"; -import Scroll from "./Scroll"; +//import Scroll from "./Scroll"; const GridComponent = ({ hasMoreFiles, @@ -14,11 +14,12 @@ const GridComponent = ({ selectedFolderId, children, className, + listRef, }) => { const gridRef = useRef(null); useEffect(() => { - //TODO:it is slow + //TODO: inf-scroll it is slow //console.log("resetAfterIndex"); gridRef?.current?.resetAfterIndex(0); @@ -63,16 +64,18 @@ const GridComponent = ({ onScroll={onScroll} className={className} height={height} + width={width} itemCount={children.length} itemSize={getItemSize} - width={width} onItemsRendered={onItemsRendered} - ref={(listRef) => { + ref={(refList) => { ref(listRef); - gridRef.current = listRef; + gridRef.current = refList; + listRef.current = refList; }} - outerElementType={Scroll} + //outerElementType={Scroll} overscanCount={5} //TODO: inf-scroll + style={{ height: "100% !important" }} > {renderTile} diff --git a/packages/components/infinite-loader/InfiniteLoader.js b/packages/components/infinite-loader/InfiniteLoader.js index c54cbe97db..9e5344a11d 100644 --- a/packages/components/infinite-loader/InfiniteLoader.js +++ b/packages/components/infinite-loader/InfiniteLoader.js @@ -1,15 +1,32 @@ -import React from "react"; +import React, { useRef } from "react"; import PropTypes from "prop-types"; +import { WindowScroller } from "react-virtualized"; import ListComponent from "./List"; import GridComponent from "./Grid"; -const InfiniteLoaderComponent = (props) => - props.viewAs === "tile" ? ( - - ) : ( - - ); +const InfiniteLoaderComponent = (props) => { + const ref = useRef(null); + const scroll = document.getElementsByClassName("section-scroll")[0]; + + const onScroll = ({ scrollTop }) => { + ref.current.scrollTo(scrollTop); + }; + + return ( + <> + + {() =>
} + + + {props.viewAs === "tile" ? ( + + ) : ( + + )} + + ); +}; InfiniteLoaderComponent.propTypes = { viewAs: PropTypes.string.isRequired, hasMoreFiles: PropTypes.bool.isRequired, diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 07621a20bd..c1ded2bca2 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -1,8 +1,8 @@ -import React, { memo, useCallback } from "react"; +import React, { memo, useCallback, useEffect, useRef } from "react"; import AutoSizer from "react-virtualized-auto-sizer"; import InfiniteLoader from "react-window-infinite-loader"; import { FixedSizeList as List, areEqual } from "react-window"; -import Scroll from "./Scroll"; +//import Scroll from "./Scroll"; import Loaders from "@docspace/common/components/Loaders"; import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; @@ -15,9 +15,19 @@ const ListComponent = ({ itemSize, onScroll, columnStorageName, + selectedFolderId, children, className, + listRef, }) => { + const listComponentRef = useRef(null); + + useEffect(() => { + //TODO: inf-scroll it is slow + + listComponentRef?.current?.resetAfterIndex(0); + }, [selectedFolderId]); + const renderRow = memo(({ index, style }) => { const isLoaded = isItemLoaded(index + 1); if (!isLoaded) return getLoader(style); @@ -72,29 +82,36 @@ const ListComponent = ({ } }; - const renderList = ({ height, width }) => ( - - {({ onItemsRendered, ref }) => ( - - {viewAs === "table" ? renderTable : renderRow} - - )} - - ); + const renderList = ({ height, width }) => { + return ( + + {({ onItemsRendered, ref }) => ( + { + ref(listRef); + listComponentRef.current = refList; + listRef.current = refList; + }} + style={{ height: "100% !important" }} + //outerElementType={Scroll} + > + {viewAs === "table" ? renderTable : renderRow} + + )} + + ); + }; return {renderList}; }; diff --git a/packages/components/package.json b/packages/components/package.json index 4ca9f87c7d..97e7861118 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -38,6 +38,7 @@ "react-toastify": "^7.0.0", "react-tooltip": "^4.2.21", "react-transition-group": "^4.4.1", + "react-virtualized": "^9.22.3", "react-window": "^1.8.6", "resize-image": "^0.1.0" }, diff --git a/packages/components/table-container/StyledTableContainer.js b/packages/components/table-container/StyledTableContainer.js index 3578417427..c77a35e6d2 100644 --- a/packages/components/table-container/StyledTableContainer.js +++ b/packages/components/table-container/StyledTableContainer.js @@ -6,15 +6,12 @@ import { isMobile } from "react-device-detect"; const reactWindowContainerStyles = css` height: 100%; - overflow: hidden; display: block; - margin-top: 0; `; const reactWindowBodyStyles = css` display: block; height: 100%; - height: 95%; //TODO: inf-scroll `; const StyledTableContainer = styled.div` diff --git a/yarn.lock b/yarn.lock index a0090dbf12..d9a6763a4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2155,6 +2155,7 @@ __metadata: react-tooltip: ^4.2.21 react-transition-group: ^4.4.1 react-values: ^0.3.3 + react-virtualized: ^9.22.3 react-window: ^1.8.6 resize-image: ^0.1.0 styled-components: ^5.3.1 @@ -8883,7 +8884,7 @@ __metadata: languageName: node linkType: hard -"clsx@npm:^1.1.1": +"clsx@npm:^1.0.4, clsx@npm:^1.1.1": version: 1.2.1 resolution: "clsx@npm:1.2.1" checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12 @@ -10534,7 +10535,7 @@ __metadata: languageName: node linkType: hard -"dom-helpers@npm:^5.0.1": +"dom-helpers@npm:^5.0.1, dom-helpers@npm:^5.1.3": version: 5.2.1 resolution: "dom-helpers@npm:5.2.1" dependencies: @@ -20692,6 +20693,23 @@ __metadata: languageName: node linkType: hard +"react-virtualized@npm:^9.22.3": + version: 9.22.3 + resolution: "react-virtualized@npm:9.22.3" + dependencies: + "@babel/runtime": ^7.7.2 + clsx: ^1.0.4 + dom-helpers: ^5.1.3 + loose-envify: ^1.4.0 + prop-types: ^15.7.2 + react-lifecycles-compat: ^3.0.4 + peerDependencies: + react: ^15.3.0 || ^16.0.0-alpha + react-dom: ^15.3.0 || ^16.0.0-alpha + checksum: 5e3b566592293bc0057bc6be4f6ee29c58c8931421d2882a3ef45ca9b24c6f3ea78bbc5a182c2916af6520845e5a90f569b3a63c9b5e89428720913e6d6239cc + languageName: node + linkType: hard + "react-window-infinite-loader@npm:^1.0.7": version: 1.0.8 resolution: "react-window-infinite-loader@npm:1.0.8" From b1d70eaeb054f390b3c6765492025ec37cda2d79 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 9 Aug 2022 14:13:42 +0300 Subject: [PATCH 23/78] Web: Files: fixed Tile styles --- .../sub-components/StyledInfiniteGrid.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js index 77ad4e1855..8d9b8b3897 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js @@ -1,4 +1,16 @@ -import styled from "styled-components"; +import styled, { css } from "styled-components"; +import { desktop, tablet } from "@docspace/components/utils/device"; + +const paddingCss = css` + @media ${desktop} { + margin-left: 1px; + padding-right: 0px; + } + + @media ${tablet} { + margin-left: -1px; + } +`; const StyledCard = styled.div` display: grid; @@ -10,6 +22,9 @@ const StyledItem = styled.div` display: grid; grid-template-columns: repeat(auto-fill, minmax(216px, 1fr)); gap: 14px 16px; + width: 100%; + + ${paddingCss}; `; const StyledHeaderItem = styled.div` From deffed2d14d8cf58a0f0d41af32a7c95ce749c8e Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 9 Aug 2022 16:19:52 +0300 Subject: [PATCH 24/78] Web: Files: fixed scroll for mobile devices --- packages/client/src/components/Layout/MobileLayout.js | 7 ++++++- packages/components/infinite-loader/InfiniteLoader.js | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/Layout/MobileLayout.js b/packages/client/src/components/Layout/MobileLayout.js index 55ab85cf79..87d54f0a16 100644 --- a/packages/client/src/components/Layout/MobileLayout.js +++ b/packages/client/src/components/Layout/MobileLayout.js @@ -132,7 +132,12 @@ class MobileLayout extends Component { const { children } = this.props; return ( - + { const ref = useRef(null); - const scroll = document.getElementsByClassName("section-scroll")[0]; + const scroll = isMobile + ? document.getElementsByClassName("mobile-scroll")[0] + : document.getElementsByClassName("section-scroll")[0]; const onScroll = ({ scrollTop }) => { ref.current.scrollTo(scrollTop); From 08c41f5121e2591d5118ddaf9a6a53d9121ba1c0 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 10 Aug 2022 11:28:57 +0300 Subject: [PATCH 25/78] Web: Files: FormGallery: removed useless code --- packages/client/src/pages/FormGallery/Body.js | 2 +- .../TilesView/sub-components/TileContainer.js | 54 ++----------------- 2 files changed, 5 insertions(+), 51 deletions(-) diff --git a/packages/client/src/pages/FormGallery/Body.js b/packages/client/src/pages/FormGallery/Body.js index a15a1413a3..ea07cfe58a 100644 --- a/packages/client/src/pages/FormGallery/Body.js +++ b/packages/client/src/pages/FormGallery/Body.js @@ -43,7 +43,7 @@ const SectionBodyContent = ({ descriptionText={t("EmptyScreenDescription")} /> ) : ( - + {oformFiles.map((item, index) => ( ))} diff --git a/packages/client/src/pages/FormGallery/TilesView/sub-components/TileContainer.js b/packages/client/src/pages/FormGallery/TilesView/sub-components/TileContainer.js index 0cf19ec0b6..b249b5e98c 100644 --- a/packages/client/src/pages/FormGallery/TilesView/sub-components/TileContainer.js +++ b/packages/client/src/pages/FormGallery/TilesView/sub-components/TileContainer.js @@ -1,71 +1,25 @@ -import React, { memo } from "react"; +import React from "react"; import { withTranslation } from "react-i18next"; import PropTypes from "prop-types"; -import { FixedSizeList as List, areEqual } from "react-window"; -import AutoSizer from "react-virtualized-auto-sizer"; -import CustomScrollbarsVirtualList from "@docspace/components/scrollbar"; import { StyledGridWrapper, StyledTileContainer } from "../StyledTileView"; class TileContainer extends React.PureComponent { - renderTile = memo(({ data, index, style }) => { - return
{data[index]}
; - }, areEqual); - render() { - const { - itemHeight, - children, - useReactWindow, - id, - className, - style, - } = this.props; - - const renderList = ({ height, width }) => ( - - {this.renderTile} - - ); + const { children, id, className, style } = this.props; return ( - - {useReactWindow ? ( - {renderList} - ) : ( - {children} - )} + + {children} ); } } TileContainer.propTypes = { - itemHeight: PropTypes.number, - manualHeight: PropTypes.string, children: PropTypes.any.isRequired, - useReactWindow: PropTypes.bool, className: PropTypes.string, id: PropTypes.string, style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), }; -TileContainer.defaultProps = { - itemHeight: 50, - useReactWindow: true, - id: "rowContainer", -}; - export default withTranslation(["Files", "Common"])(TileContainer); From 2c2251d33e20715f1c17b7d14a3a8802654e9fb3 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 10 Aug 2022 11:37:14 +0300 Subject: [PATCH 26/78] Web: Files: added default useReactWindow prop --- .../pages/Home/Section/Body/TableView/TableContainer.js | 1 - packages/components/infinite-loader/Grid.js | 6 +++++- packages/components/infinite-loader/List.js | 8 ++++++-- packages/components/table-container/TableBody.js | 1 + packages/components/table-container/TableContainer.js | 4 ++++ packages/components/table-container/TableHeader.js | 3 ++- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index 5658dd7d93..75b5896562 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -7,7 +7,6 @@ import TableHeader from "./TableHeader"; import TableBody from "@docspace/components/table-container/TableBody"; import { isMobile } from "react-device-detect"; import styled, { css } from "styled-components"; -import { isTablet } from "@docspace/components/utils/device"; import { Base } from "@docspace/components/themes"; const marginCss = css` diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index ac72dc5886..95d9002594 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -33,7 +33,11 @@ const GridComponent = ({ ); const renderTile = memo(({ index, style }) => { - return
{children[index]}
; + return ( +
+ {children[index]} +
+ ); }, areEqual); const getItemSize = (index) => { diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index c1ded2bca2..5c4b92d601 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -32,7 +32,11 @@ const ListComponent = ({ const isLoaded = isItemLoaded(index + 1); if (!isLoaded) return getLoader(style); - return
{children[index]}
; + return ( +
+ {children[index]} +
+ ); }, areEqual); const isItemLoaded = useCallback( @@ -48,7 +52,7 @@ const ListComponent = ({ return (
{ TableBody.defaultProps = { itemHeight: 40, + useReactWindow: false, }; export default TableBody; diff --git a/packages/components/table-container/TableContainer.js b/packages/components/table-container/TableContainer.js index f569c7a4e7..f4dae10cf0 100644 --- a/packages/components/table-container/TableContainer.js +++ b/packages/components/table-container/TableContainer.js @@ -16,6 +16,10 @@ const TableContainer = (props) => { ); }; +TableContainer.defaultProps = { + useReactWindow: false, +}; + TableContainer.propTypes = { forwardedRef: PropTypes.shape({ current: PropTypes.any }), useReactWindow: PropTypes.bool, diff --git a/packages/components/table-container/TableHeader.js b/packages/components/table-container/TableHeader.js index 06324db6ef..5d627bc5cf 100644 --- a/packages/components/table-container/TableHeader.js +++ b/packages/components/table-container/TableHeader.js @@ -563,7 +563,7 @@ class TableHeader extends React.Component { updateTableRows = (str) => { if (!this.props.useReactWindow) return; - const rows = document.querySelectorAll(".table-row, .table-row-list-item"); + const rows = document.querySelectorAll(".table-row, .table-list-item"); if (rows?.length) { for (let i = 0; i < rows.length; i++) { @@ -708,6 +708,7 @@ class TableHeader extends React.Component { TableHeader.defaultProps = { sortingVisible: true, infoPanelVisible: false, + useReactWindow: false, }; TableHeader.propTypes = { From 966e1e293e2cbe265ba336270ca17293765417ea Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 10 Aug 2022 11:38:04 +0300 Subject: [PATCH 27/78] Web: Files: fixed hotkeys --- packages/client/src/HOCs/withHotkeys.js | 11 ++++++++--- packages/client/src/store/HotkeyStore.js | 9 ++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/client/src/HOCs/withHotkeys.js b/packages/client/src/HOCs/withHotkeys.js index 2b815e689f..d121b78691 100644 --- a/packages/client/src/HOCs/withHotkeys.js +++ b/packages/client/src/HOCs/withHotkeys.js @@ -1,7 +1,6 @@ import React, { useEffect } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import { observer, inject } from "mobx-react"; -import { FileAction } from "@docspace/common/constants"; import { Events } from "@docspace/client/src/helpers/filesConstants"; import toastr from "client/toastr"; @@ -51,6 +50,7 @@ const withHotkeys = (Component) => { selection, setFavoriteAction, + filesIsLoading, } = props; const hotkeysFilter = { @@ -58,7 +58,11 @@ const withHotkeys = (Component) => { ev.target?.type === "checkbox" || ev.target?.tagName !== "INPUT", filterPreventDefault: false, enableOnTags: ["INPUT"], - enabled: !someDialogIsOpen && enabledHotkeys && !mediaViewerIsVisible, + enabled: + !someDialogIsOpen && + enabledHotkeys && + !mediaViewerIsVisible && + !filesIsLoading, // keyup: true, // keydown: false, }; @@ -322,9 +326,9 @@ const withHotkeys = (Component) => { setSelected, viewAs, setViewAs, - fileActionStore, enabledHotkeys, selection, + filesIsLoading, } = filesStore; const { @@ -413,6 +417,7 @@ const withHotkeys = (Component) => { selection, setFavoriteAction, + filesIsLoading, }; } )(observer(WithHotkeys)); diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index 0f6333785c..0d8c4ad878 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -85,7 +85,14 @@ class HotkeyStore { ) { //console.log("element is visible"); } else { - scroll.scrollTo(0, el.offsetTop - scrollRect.height / 2); + const offset = el.closest(".window-item")?.offsetTop; + const offsetTop = offset + ? offset + : viewAs === "tile" + ? el.parentElement.parentElement.offsetTop + : el.offsetTop; + + scroll.scrollTo(0, offsetTop - scrollRect.height / 2); //console.log("element is not visible"); } } From 8f4ee05948c848be7c1e40240f5146e84de064d3 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 10 Aug 2022 13:27:52 +0300 Subject: [PATCH 28/78] Web: Files: fixed mobile scroll --- packages/client/src/components/Layout/MobileLayout.js | 7 +------ packages/components/infinite-loader/InfiniteLoader.js | 8 ++++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/client/src/components/Layout/MobileLayout.js b/packages/client/src/components/Layout/MobileLayout.js index 87d54f0a16..55ab85cf79 100644 --- a/packages/client/src/components/Layout/MobileLayout.js +++ b/packages/client/src/components/Layout/MobileLayout.js @@ -132,12 +132,7 @@ class MobileLayout extends Component { const { children } = this.props; return ( - + { const ref = useRef(null); - const scroll = isMobile - ? document.getElementsByClassName("mobile-scroll")[0] - : document.getElementsByClassName("section-scroll")[0]; + const scroll = isMobileOnly + ? document.querySelector("#customScrollBar > .scroll-body") + : document.querySelector("#sectionScroll > .scroll-body"); const onScroll = ({ scrollTop }) => { ref.current.scrollTo(scrollTop); From 492ed8667480725869439c1e3d128c13cc8d69bc Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 10 Aug 2022 13:32:17 +0300 Subject: [PATCH 29/78] Web: Files: fixed double scroll --- packages/components/infinite-loader/Grid.js | 2 +- packages/components/infinite-loader/List.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 95d9002594..c9d1cfe05f 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -79,7 +79,7 @@ const GridComponent = ({ }} //outerElementType={Scroll} overscanCount={5} //TODO: inf-scroll - style={{ height: "100% !important" }} + style={{ height: "100% !important", overflow: "hidden" }} > {renderTile} diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 5c4b92d601..527290b245 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -107,7 +107,7 @@ const ListComponent = ({ listComponentRef.current = refList; listRef.current = refList; }} - style={{ height: "100% !important" }} + style={{ height: "100% !important", overflow: "hidden" }} //outerElementType={Scroll} > {viewAs === "table" ? renderTable : renderRow} From 28c73a4a7c7357150c24ec31033ad9665b1e818b Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 10:35:32 +0300 Subject: [PATCH 30/78] Web: Components: moved to react-virtualized, fixed blue screen --- packages/components/infinite-loader/Grid.js | 99 ++++++------- .../infinite-loader/InfiniteLoader.js | 25 +--- packages/components/infinite-loader/List.js | 132 +++++++++--------- .../infinite-loader/StyledInfiniteLoader.js | 18 +-- 4 files changed, 120 insertions(+), 154 deletions(-) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index c9d1cfe05f..dae8fd52f0 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -1,8 +1,6 @@ -import React, { memo, useCallback, useEffect, useRef } from "react"; -import AutoSizer from "react-virtualized-auto-sizer"; -import InfiniteLoader from "react-window-infinite-loader"; -import { VariableSizeList as List, areEqual } from "react-window"; -//import Scroll from "./Scroll"; +import React, { useCallback } from "react"; +import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized"; +import { StyledList } from "./StyledInfiniteLoader"; const GridComponent = ({ hasMoreFiles, @@ -11,36 +9,26 @@ const GridComponent = ({ loadMoreItems, onScroll, countTilesInRow, - selectedFolderId, children, className, - listRef, + scroll, }) => { - const gridRef = useRef(null); - - useEffect(() => { - //TODO: inf-scroll it is slow - //console.log("resetAfterIndex"); - - gridRef?.current?.resetAfterIndex(0); - }, [selectedFolderId]); - const isItemLoaded = useCallback( - (index) => { + ({ index }) => { return !hasMoreFiles || index * countTilesInRow < filesLength; }, [filesLength, hasMoreFiles, countTilesInRow] ); - const renderTile = memo(({ index, style }) => { + const renderTile = ({ index, style, key }) => { return ( -
+
{children[index]}
); - }, areEqual); + }; - const getItemSize = (index) => { + const getItemSize = ({ index }) => { const itemClassNames = children[index]?.props?.className; const isFile = itemClassNames?.includes("isFile"); const isFolder = itemClassNames?.includes("isFolder"); @@ -56,41 +44,40 @@ const GridComponent = ({ return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; }; - const renderGrid = ({ height, width }) => { - return ( - - {({ onItemsRendered, ref }) => ( - { - ref(listRef); - gridRef.current = refList; - listRef.current = refList; - }} - //outerElementType={Scroll} - overscanCount={5} //TODO: inf-scroll - style={{ height: "100% !important", overflow: "hidden" }} - > - {renderTile} - - )} - - ); - }; - - //console.log("GridComponent render"); - - return {renderGrid}; + return ( + + {({ onRowsRendered, registerChild }) => ( + + {({ height, isScrolling, onChildScroll, scrollTop }) => ( + + {({ width }) => ( + + )} + + )} + + )} + + ); }; export default GridComponent; diff --git a/packages/components/infinite-loader/InfiniteLoader.js b/packages/components/infinite-loader/InfiniteLoader.js index f47b469f6c..da422afe9f 100644 --- a/packages/components/infinite-loader/InfiniteLoader.js +++ b/packages/components/infinite-loader/InfiniteLoader.js @@ -1,33 +1,18 @@ -import React, { useRef } from "react"; +import React from "react"; import PropTypes from "prop-types"; -import { WindowScroller } from "react-virtualized"; import { isMobileOnly } from "react-device-detect"; import ListComponent from "./List"; import GridComponent from "./Grid"; const InfiniteLoaderComponent = (props) => { - const ref = useRef(null); - const scroll = isMobileOnly ? document.querySelector("#customScrollBar > .scroll-body") : document.querySelector("#sectionScroll > .scroll-body"); - const onScroll = ({ scrollTop }) => { - ref.current.scrollTo(scrollTop); - }; - - return ( - <> - - {() =>
} - - - {props.viewAs === "tile" ? ( - - ) : ( - - )} - + return props.viewAs === "tile" ? ( + + ) : ( + ); }; InfiniteLoaderComponent.propTypes = { diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 527290b245..12314fa42c 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -1,54 +1,42 @@ -import React, { memo, useCallback, useEffect, useRef } from "react"; -import AutoSizer from "react-virtualized-auto-sizer"; -import InfiniteLoader from "react-window-infinite-loader"; -import { FixedSizeList as List, areEqual } from "react-window"; -//import Scroll from "./Scroll"; +import React, { useCallback } from "react"; +import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized"; import Loaders from "@docspace/common/components/Loaders"; -import { StyledTableLoader, StyledRowLoader } from "./StyledInfiniteLoader"; +import { StyledList } from "./StyledInfiniteLoader"; const ListComponent = ({ viewAs, hasMoreFiles, filesLength, itemCount, + onScroll, loadMoreItems, itemSize, - onScroll, columnStorageName, - selectedFolderId, children, className, - listRef, + scroll, }) => { - const listComponentRef = useRef(null); - - useEffect(() => { - //TODO: inf-scroll it is slow - - listComponentRef?.current?.resetAfterIndex(0); - }, [selectedFolderId]); - - const renderRow = memo(({ index, style }) => { - const isLoaded = isItemLoaded(index + 1); - if (!isLoaded) return getLoader(style); + const renderRow = ({ key, index, style }) => { + const isLoaded = isItemLoaded({ index: index + 2 }); + if (!isLoaded) return getLoader(style, key); return ( -
+
{children[index]}
); - }, areEqual); + }; const isItemLoaded = useCallback( - (index) => !hasMoreFiles || index < filesLength, + ({ index }) => !hasMoreFiles || index < filesLength, [filesLength, hasMoreFiles] ); - const renderTable = memo(({ index, style }) => { + const renderTable = ({ index, style, key }) => { const storageSize = localStorage.getItem(columnStorageName); - const isLoaded = isItemLoaded(index + 1); - if (!isLoaded) return getLoader(style); + const isLoaded = isItemLoaded({ index: index + 2 }); + if (!isLoaded) return getLoader(style, key); return (
{children[index]}
); - }, areEqual); + }; - const getLoader = (style) => { + const getLoader = (style, key) => { switch (viewAs) { case "table": return ( - - - + count={1} + /> ); case "row": return ( - - - + ); default: return <>; } }; - const renderList = ({ height, width }) => { - return ( - - {({ onItemsRendered, ref }) => ( - { - ref(listRef); - listComponentRef.current = refList; - listRef.current = refList; - }} - style={{ height: "100% !important", overflow: "hidden" }} - //outerElementType={Scroll} - > - {viewAs === "table" ? renderTable : renderRow} - - )} - - ); - }; + return ( + + {({ onRowsRendered, registerChild }) => ( + + {({ height, isScrolling, onChildScroll, scrollTop }) => { + if (height === undefined) { + height = scroll.getBoundingClientRect().height; + } - return {renderList}; + return ( + + {({ width }) => ( + + )} + + ); + }} + + )} + + ); }; export default ListComponent; diff --git a/packages/components/infinite-loader/StyledInfiniteLoader.js b/packages/components/infinite-loader/StyledInfiniteLoader.js index 8ed1d2b8d3..5f961dd865 100644 --- a/packages/components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/components/infinite-loader/StyledInfiniteLoader.js @@ -1,17 +1,7 @@ +import { List } from "react-virtualized"; import styled from "styled-components"; import Base from "../themes/base"; -const StyledTableLoader = styled.div` - grid-column-start: 1; - grid-column-end: -1; - display: grid; - padding-top: 16px; -`; - -const StyledRowLoader = styled.div` - padding-top: 16px; -`; - const StyledScroll = styled.div` overflow: scroll; @@ -38,8 +28,12 @@ const StyledScroll = styled.div` scrollbar-color: ${({ theme }) => theme.scrollbar.backgroundColorVertical}; `; +const StyledList = styled(List)` + outline: none; +`; + StyledScroll.defaultProps = { theme: Base, }; -export { StyledTableLoader, StyledRowLoader, StyledScroll }; +export { StyledScroll, StyledList }; From 7d691f6dcbe50e01a1c9d53d7f680059ff361e46 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 11:00:42 +0300 Subject: [PATCH 31/78] Web: Common: fixed scroll --- .../common/components/Section/sub-components/section-body.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/common/components/Section/sub-components/section-body.js b/packages/common/components/Section/sub-components/section-body.js index ac0a876a0f..596fb7273d 100644 --- a/packages/common/components/Section/sub-components/section-body.js +++ b/packages/common/components/Section/sub-components/section-body.js @@ -68,8 +68,6 @@ const commonStyles = css` } .section-wrapper-content { - height: 100%; - ${paddingStyles} flex: 1 0 auto; outline: none; From 1853175976a20ec9102385577e917e58c6a1dad5 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 12:56:57 +0300 Subject: [PATCH 32/78] Web: Files: fixed create/rename events --- packages/client/src/HOCs/withContent.js | 2 -- .../components/GlobalEvents/CreateEvent.js | 8 ++--- .../components/GlobalEvents/RenameEvent.js | 10 +++--- .../dialogs/ConvertPasswordDialog/index.js | 2 +- .../client/src/store/FilesActionsStore.js | 31 +++---------------- packages/client/src/store/FilesStore.js | 15 +++++++-- 6 files changed, 26 insertions(+), 42 deletions(-) diff --git a/packages/client/src/HOCs/withContent.js b/packages/client/src/HOCs/withContent.js index 64062d934b..87ff930f1b 100644 --- a/packages/client/src/HOCs/withContent.js +++ b/packages/client/src/HOCs/withContent.js @@ -120,7 +120,6 @@ export default function withContent(WrappedContent) { }, { item } ) => { - const { editCompleteAction } = filesActionsStore; const { createFile, createFolder, @@ -164,7 +163,6 @@ export default function withContent(WrappedContent) { createFile, createFolder, culture, - editCompleteAction, folderFormValidation, homepage: config.homepage, diff --git a/packages/client/src/components/GlobalEvents/CreateEvent.js b/packages/client/src/components/GlobalEvents/CreateEvent.js index 2b6acf0c9a..e5d6376ccc 100644 --- a/packages/client/src/components/GlobalEvents/CreateEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateEvent.js @@ -103,7 +103,7 @@ const CreateEvent = ({ addActiveItems(null, [folder.id]); setCreatedItem({ id: createdFolderId, type: "folder" }); }) - .then(() => editCompleteAction(id, item, false, type)) + .then(() => editCompleteAction(item, type)) .catch((e) => toastr.error(e)) .finally(() => { const folderIds = [+id]; @@ -123,7 +123,7 @@ const CreateEvent = ({ open && openDocEditor(file.id, file.providerKey, tab); }) - .then(() => editCompleteAction(id, item, false, type)) + .then(() => editCompleteAction(item, type)) .catch((err) => { if (err.indexOf("password") == -1) { toastr.error(err, t("Common:Warning")); @@ -173,7 +173,7 @@ const CreateEvent = ({ return open && openDocEditor(file.id, file.providerKey, tab); }) - .then(() => editCompleteAction(id, item, false, type)) + .then(() => editCompleteAction(item, type)) .catch((e) => toastr.error(e)) .finally(() => { const fileIds = [+id]; @@ -209,7 +209,7 @@ const CreateEvent = ({ return open && openDocEditor(file.id, file.providerKey, tab); }) - .then(() => editCompleteAction(id, item, false, type)) + .then(() => editCompleteAction(item, type)) .catch((e) => toastr.error(e)) .finally(() => { const fileIds = [+id]; diff --git a/packages/client/src/components/GlobalEvents/RenameEvent.js b/packages/client/src/components/GlobalEvents/RenameEvent.js index 5b46519269..96a5f20a45 100644 --- a/packages/client/src/components/GlobalEvents/RenameEvent.js +++ b/packages/client/src/components/GlobalEvents/RenameEvent.js @@ -48,7 +48,7 @@ const RenameEvent = ({ if (isSameTitle) { setStartValue(originalTitle); - return editCompleteAction(item.id, item, isSameTitle, type); + return editCompleteAction(item, type); } else { timerId = setTimeout(() => { isFile ? addActiveItems([item.id]) : addActiveItems(null, [item.id]); @@ -57,7 +57,7 @@ const RenameEvent = ({ isFile ? updateFile(item.id, value) - .then(() => editCompleteAction(item.id, item, false, type)) + .then(() => editCompleteAction(item, type)) .then(() => toastr.success( t("FileRenamed", { @@ -68,7 +68,7 @@ const RenameEvent = ({ ) .catch((err) => { toastr.error(err); - editCompleteAction(item.id, item, false, type); + editCompleteAction(item, type); }) .finally(() => { clearTimeout(timerId); @@ -79,7 +79,7 @@ const RenameEvent = ({ onClose(); }) : renameFolder(item.id, value) - .then(() => editCompleteAction(item.id, item, false, type)) + .then(() => editCompleteAction(item, type)) .then(() => toastr.success( t("FolderRenamed", { @@ -90,7 +90,7 @@ const RenameEvent = ({ ) .catch((err) => { toastr.error(err); - editCompleteAction(item.id, item, false, type); + editCompleteAction(item, type); }) .finally(() => { clearTimeout(timerId); diff --git a/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js b/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js index b3f60de943..30ad712393 100644 --- a/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js +++ b/packages/client/src/components/dialogs/ConvertPasswordDialog/index.js @@ -114,7 +114,7 @@ const ConvertPasswordDialogComponent = (props) => { open && openDocEditor(file.id, file.providerKey, tab); }) .then(() => { - editCompleteAction(actionId, fileInfo, false); + editCompleteAction(fileInfo); }) .catch((err) => { if (err.indexOf("password") == -1) { diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 82634a7ac0..5bf1fcb764 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -489,35 +489,12 @@ class FilesActionStore { return this.downloadFiles(fileIds, folderIds, label); }; - editCompleteAction = async (id, selectedItem, isCancelled = false, type) => { - const { - filter, - folders, - files, + editCompleteAction = async (selectedItem, type) => { + if (type === FileAction.Create) { + this.filesStore.addFile(selectedItem); + } - fetchFiles, - setIsLoading, - } = this.filesStore; - - const { treeFolders, setTreeFolders } = this.treeFoldersStore; - - const items = [...folders, ...files]; - const item = items.find((o) => o.id === id && !o.fileExst); //TODO: maybe need files find and folders find, not at one function? if (type === FileAction.Create || type === FileAction.Rename) { - setIsLoading(true); - - if (!isCancelled) { - const data = await fetchFiles(this.selectedFolderStore.id, filter); - const newItem = (item && item.id) === -1 ? null : item; //TODO: not add new folders? - if (!selectedItem.fileExst && !selectedItem.contentLength) { - const path = data.selectedFolder.pathParts; - const folders = await getSubfolders(this.selectedFolderStore.id); - loopTreeFolders(path, treeFolders, folders, null, newItem); - setTreeFolders(treeFolders); - } - } - - setIsLoading(false); type === FileAction.Rename && this.onSelectItem( { diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index c5bbe41867..9e83cdb9d2 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -12,7 +12,7 @@ import { import history from "@docspace/common/history"; import { combineUrl } from "@docspace/common/utils"; import { updateTempContent } from "@docspace/common/utils"; -import { isMobile } from "react-device-detect"; +import { isMobile, isMobileOnly } from "react-device-detect"; import toastr from "client/toastr"; import config from "PACKAGE_FILE"; @@ -671,9 +671,7 @@ class FilesStore { treeFolders, setSelectedNode, getSubfolders, - selectedTreeNode, } = this.treeFoldersStore; - const { id } = this.selectedFolderStore; const filterData = filter ? filter.clone() : FilesFilter.getDefault(); filterData.folder = folderId; @@ -1631,6 +1629,17 @@ class FilesStore { this.folders[idx].pinned = !this.folders[idx].pinned; }; + addFile = (item) => { + this.filter.total += 1; + this.files.unshift(item); + + const scrollElm = isMobileOnly + ? document.querySelector("#customScrollBar > .scroll-body") + : document.querySelector("#sectionScroll > .scroll-body"); + + scrollElm && scrollElm.scrollTo(0, 0); + }; + updateFile = (fileId, title) => { return api.files .updateFile(fileId, title) From 87d351a3049180ededf5533a29eb01ff4b773e90 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 14:45:14 +0300 Subject: [PATCH 33/78] Web: Components: fixed List width, fixed fetch --- packages/client/src/store/FilesStore.js | 14 ++++-- packages/components/infinite-loader/Grid.js | 48 ++++++++++--------- packages/components/infinite-loader/List.js | 45 +++++++++-------- .../components/table-container/TableBody.js | 2 +- 4 files changed, 60 insertions(+), 49 deletions(-) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 983d7abcd4..08f3f281f3 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -666,6 +666,8 @@ class FilesStore { getSubfolders, } = this.treeFoldersStore; + this.scrollToTop(); + const filterData = filter ? filter.clone() : FilesFilter.getDefault(); filterData.folder = folderId; @@ -1622,10 +1624,7 @@ class FilesStore { this.folders[idx].pinned = !this.folders[idx].pinned; }; - addFile = (item) => { - this.filter.total += 1; - this.files.unshift(item); - + scrollToTop = () => { const scrollElm = isMobileOnly ? document.querySelector("#customScrollBar > .scroll-body") : document.querySelector("#sectionScroll > .scroll-body"); @@ -1633,6 +1632,13 @@ class FilesStore { scrollElm && scrollElm.scrollTo(0, 0); }; + addFile = (item) => { + this.filter.total += 1; + this.files.unshift(item); + + this.scrollToTop(); + }; + updateFile = (fileId, title) => { return api.files .updateFile(fileId, title) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index dae8fd52f0..2b9ffd7284 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized"; +import { InfiniteLoader, WindowScroller } from "react-virtualized"; import { StyledList } from "./StyledInfiniteLoader"; const GridComponent = ({ @@ -52,28 +52,30 @@ const GridComponent = ({ > {({ onRowsRendered, registerChild }) => ( - {({ height, isScrolling, onChildScroll, scrollTop }) => ( - - {({ width }) => ( - - )} - - )} + {({ height, isScrolling, onChildScroll, scrollTop }) => { + const width = + document.getElementById("tileContainer")?.getBoundingClientRect() + .width ?? 0; + + return ( + + ); + }} )} diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 12314fa42c..5017b0088a 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -1,5 +1,5 @@ import React, { useCallback } from "react"; -import { InfiniteLoader, WindowScroller, AutoSizer } from "react-virtualized"; +import { InfiniteLoader, WindowScroller } from "react-virtualized"; import Loaders from "@docspace/common/components/Loaders"; import { StyledList } from "./StyledInfiniteLoader"; @@ -91,27 +91,30 @@ const ListComponent = ({ height = scroll.getBoundingClientRect().height; } + const viewId = + viewAs === "table" ? "table-container" : "rowContainer"; + + const width = + document.getElementById(viewId)?.getBoundingClientRect().width ?? + 0; + return ( - - {({ width }) => ( - - )} - + ); }} diff --git a/packages/components/table-container/TableBody.js b/packages/components/table-container/TableBody.js index 642bd96a96..576702c0a0 100644 --- a/packages/components/table-container/TableBody.js +++ b/packages/components/table-container/TableBody.js @@ -40,7 +40,7 @@ const TableBody = (props) => { }; TableBody.defaultProps = { - itemHeight: 40, + itemHeight: 41, useReactWindow: false, }; From 645c771b3b09f980666f95f47dd829857c9fb503 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 15:28:57 +0300 Subject: [PATCH 34/78] Web: Components: fixed table columns --- .../src/pages/Home/Section/Body/TableView/TableContainer.js | 2 ++ packages/components/infinite-loader/List.js | 6 +++++- packages/components/table-container/TableBody.js | 5 +++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index 75b5896562..ab51837173 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -204,6 +204,8 @@ const Table = ({ hasMoreFiles={hasMoreFiles} itemCount={filterTotal} useReactWindow + infoPanelVisible={infoPanelVisible} + columnInfoPanelStorageName={columnInfoPanelStorageName} > {filesList.map((item, index) => { return index === 0 && item.isRoom ? ( diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 5017b0088a..7d7bc0e3f3 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -12,9 +12,11 @@ const ListComponent = ({ loadMoreItems, itemSize, columnStorageName, + columnInfoPanelStorageName, children, className, scroll, + infoPanelVisible, }) => { const renderRow = ({ key, index, style }) => { const isLoaded = isItemLoaded({ index: index + 2 }); @@ -33,7 +35,9 @@ const ListComponent = ({ ); const renderTable = ({ index, style, key }) => { - const storageSize = localStorage.getItem(columnStorageName); + const storageSize = infoPanelVisible + ? localStorage.getItem(columnInfoPanelStorageName) + : localStorage.getItem(columnStorageName); const isLoaded = isItemLoaded({ index: index + 2 }); if (!isLoaded) return getLoader(style, key); diff --git a/packages/components/table-container/TableBody.js b/packages/components/table-container/TableBody.js index 576702c0a0..630a4d3eab 100644 --- a/packages/components/table-container/TableBody.js +++ b/packages/components/table-container/TableBody.js @@ -5,6 +5,7 @@ import InfiniteLoaderComponent from "../infinite-loader"; const TableBody = (props) => { const { columnStorageName, + columnInfoPanelStorageName, fetchMoreFiles, children, filesLength, @@ -13,6 +14,7 @@ const TableBody = (props) => { itemHeight, useReactWindow, onScroll, + infoPanelVisible, } = props; return useReactWindow ? ( @@ -28,8 +30,10 @@ const TableBody = (props) => { itemCount={itemCount} loadMoreItems={fetchMoreFiles} columnStorageName={columnStorageName} + columnInfoPanelStorageName={columnInfoPanelStorageName} itemSize={itemHeight} onScroll={onScroll} + infoPanelVisible={infoPanelVisible} > {children} @@ -42,6 +46,7 @@ const TableBody = (props) => { TableBody.defaultProps = { itemHeight: 41, useReactWindow: false, + infoPanelVisible: false, }; export default TableBody; From 2ec456f07077680ca1a7da5bd949461c13d1e91a Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 15:31:21 +0300 Subject: [PATCH 35/78] Web: Components: fixed height error --- packages/components/infinite-loader/Grid.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 2b9ffd7284..d35948c6c0 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -53,6 +53,10 @@ const GridComponent = ({ {({ onRowsRendered, registerChild }) => ( {({ height, isScrolling, onChildScroll, scrollTop }) => { + if (height === undefined) { + height = scroll.getBoundingClientRect().height; + } + const width = document.getElementById("tileContainer")?.getBoundingClientRect() .width ?? 0; From a35aa2d306414c60bc8a909ca3f173ed80291f93 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 15:56:18 +0300 Subject: [PATCH 36/78] Web: Files: fixed create folders --- .../client/src/components/GlobalEvents/CreateEvent.js | 2 +- .../Body/TilesView/sub-components/TileContainer.js | 9 +-------- packages/client/src/store/FilesActionsStore.js | 4 ++-- packages/client/src/store/FilesStore.js | 4 ++-- 4 files changed, 6 insertions(+), 13 deletions(-) diff --git a/packages/client/src/components/GlobalEvents/CreateEvent.js b/packages/client/src/components/GlobalEvents/CreateEvent.js index e5d6376ccc..2b9a226cca 100644 --- a/packages/client/src/components/GlobalEvents/CreateEvent.js +++ b/packages/client/src/components/GlobalEvents/CreateEvent.js @@ -103,7 +103,7 @@ const CreateEvent = ({ addActiveItems(null, [folder.id]); setCreatedItem({ id: createdFolderId, type: "folder" }); }) - .then(() => editCompleteAction(item, type)) + .then(() => editCompleteAction(item, type, true)) .catch((e) => toastr.error(e)) .finally(() => { const folderIds = [+id]; diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index fc90d2cb16..9d11da6e7f 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -172,7 +172,6 @@ class TileContainer extends React.PureComponent { super(props); this.state = { - isOpen: false, selectedFilterData: { sortId: props.filter.sortBy, sortDirection: props.filter.sortOrder, @@ -180,12 +179,6 @@ class TileContainer extends React.PureComponent { }; } - toggleDropdown = () => { - this.setState((prev) => ({ - isOpen: !prev.isOpen, - })); - }; - render() { const { children, @@ -197,7 +190,7 @@ class TileContainer extends React.PureComponent { headingFiles, } = this.props; - const { isOpen, selectedFilterData } = this.state; + const { selectedFilterData } = this.state; const Rooms = []; const Folders = []; diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 2c0d942a36..5bf34216d2 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -489,9 +489,9 @@ class FilesActionStore { return this.downloadFiles(fileIds, folderIds, label); }; - editCompleteAction = async (selectedItem, type) => { + editCompleteAction = async (selectedItem, type, isFolder = false) => { if (type === FileAction.Create) { - this.filesStore.addFile(selectedItem); + this.filesStore.addFile(selectedItem, isFolder); } if (type === FileAction.Create || type === FileAction.Rename) { diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 08f3f281f3..7b5ed07256 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -1632,9 +1632,9 @@ class FilesStore { scrollElm && scrollElm.scrollTo(0, 0); }; - addFile = (item) => { + addFile = (item, isFolder) => { this.filter.total += 1; - this.files.unshift(item); + isFolder ? this.folders.unshift(item) : this.files.unshift(item); this.scrollToTop(); }; From 22c45015c33913c2c8342fb450cf928ac54acb1d Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 17:01:53 +0300 Subject: [PATCH 37/78] Web: Components: fixed scroll --- packages/components/infinite-loader/StyledInfiniteLoader.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/components/infinite-loader/StyledInfiniteLoader.js b/packages/components/infinite-loader/StyledInfiniteLoader.js index 5f961dd865..eb73c729bb 100644 --- a/packages/components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/components/infinite-loader/StyledInfiniteLoader.js @@ -30,6 +30,7 @@ const StyledScroll = styled.div` const StyledList = styled(List)` outline: none; + overflow: hidden !important; `; StyledScroll.defaultProps = { From 5fcb32c16e7589e40d8b3ece3248f269a2849c4e Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 17:35:30 +0300 Subject: [PATCH 38/78] Web: Files: fixed remove files --- packages/client/src/store/FilesActionsStore.js | 3 +++ packages/client/src/store/FilesStore.js | 11 ++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 5bf34216d2..4c02c17c9d 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -289,6 +289,7 @@ class FilesActionStore { //this.updateCurrentFolder(fileIds, folderIds, false); this.updateFilesAfterDelete(folderIds); + this.filesStore.removeFiles(fileIds, folderIds); if (currentFolderId) { const { socketHelper } = this.authStore.settingsStore; @@ -623,6 +624,7 @@ class FilesActionStore { await this.uploadDataStore.loopFilesOperations(data, pbData); //this.updateCurrentFolder([itemId]); this.updateFilesAfterDelete(); + this.filesStore.removeFiles([itemId]); }) .then(() => toastr.success(translations.successRemoveFile)); } else if (isRoom) { @@ -648,6 +650,7 @@ class FilesActionStore { await this.uploadDataStore.loopFilesOperations(data, pbData); //this.updateCurrentFolder(null, [itemId]); this.updateFilesAfterDelete([itemId]); + this.filesStore.removeFiles([itemId]); getIsEmptyTrash(); }) .then(() => toastr.success(translations.successRemoveFolder)); diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 7b5ed07256..f3169f0c9d 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -1639,6 +1639,14 @@ class FilesStore { this.scrollToTop(); }; + removeFiles = (fileIds, folderIds) => { + this.filter.total -= fileIds.length + folderIds.length; + + if (fileIds) this.files = this.files.filter((x) => !fileIds.includes(x.id)); + if (folderIds) + this.folders = this.folders.filter((x) => !folderIds.includes(x.id)); + }; + updateFile = (fileId, title) => { return api.files .updateFile(fileId, title) @@ -2482,12 +2490,13 @@ class FilesStore { this.trashIsEmpty = isEmpty; }; + //TODO: filter.total is not updated, need move filter to new filterStore get filterTotal() { return this.filter.total; } get hasMoreFiles() { - return this.filesList.length < this.filterTotal; + return this.filesList.length < this.filter.total; } setFilesIsLoading = (filesIsLoading) => { From 160bc3a1a736cea8bb1c7083aab6a558774b47f1 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 12 Aug 2022 17:52:21 +0300 Subject: [PATCH 39/78] Web: Components: fixed grid loaders --- packages/components/infinite-loader/Grid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index d35948c6c0..5369095601 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -15,7 +15,7 @@ const GridComponent = ({ }) => { const isItemLoaded = useCallback( ({ index }) => { - return !hasMoreFiles || index * countTilesInRow < filesLength; + return !hasMoreFiles || (index + 1) * countTilesInRow < filesLength; }, [filesLength, hasMoreFiles, countTilesInRow] ); From 769f70db182eea40d77daf963ffdf9bd96e7e1cf Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 15 Aug 2022 12:06:19 +0300 Subject: [PATCH 40/78] Web: Files: fixed hotkeys scroll --- packages/client/src/store/FilesStore.js | 4 +- packages/client/src/store/HotkeyStore.js | 116 ++++++++++++++--------- 2 files changed, 71 insertions(+), 49 deletions(-) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index f3169f0c9d..0e48e45610 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -529,9 +529,7 @@ class FilesStore { }; setHotkeyCaret = (hotkeyCaret) => { - if (hotkeyCaret) { - this.hotkeyCaret = hotkeyCaret; - } else if (this.hotkeyCaret) { + if (hotkeyCaret || this.hotkeyCaret) { this.hotkeyCaret = hotkeyCaret; } }; diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index 0d8c4ad878..a34833bcf5 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -14,6 +14,8 @@ class HotkeyStore { treeFoldersStore; uploadDataStore; + elemOffset = 0; + constructor( filesStore, dialogsStore, @@ -50,7 +52,7 @@ class HotkeyStore { e.preventDefault(); } - const { selection: s, hotkeyCaret, viewAs, filesList } = this.filesStore; + const { selection: s, hotkeyCaret, filesList } = this.filesStore; const selection = s.length ? s : filesList; if (!hotkeyCaret) { @@ -59,12 +61,44 @@ class HotkeyStore { } if (!hotkeyCaret && selection.length) { - this.filesStore.setHotkeyCaret(selection[0]); + this.setCaret(selection[0]); this.filesStore.setHotkeyCaretStart(selection[0]); } if (!hotkeyCaret || isDefaultKeys) return; + const { offsetTop, item } = this.getItemOffset(); + const scroll = document.getElementsByClassName("section-scroll")[0]; + const scrollRect = scroll.getBoundingClientRect(); + + if (item && item[0]) { + const el = item[0]; + const rect = el.getBoundingClientRect(); + + if ( + scrollRect.top + scrollRect.height - rect.height > rect.top && + scrollRect.top < rect.top + el.offsetHeight + ) { + //console.log("element is visible"); + } else { + scroll.scrollTo(0, offsetTop - scrollRect.height / 2); + //console.log("element is not visible"); + } + } else { + scroll.scrollTo(0, this.elemOffset - scrollRect.height / 2); + } + }; + + setCaret = (caret) => { + this.filesStore.setHotkeyCaret(caret); + const { offsetTop } = this.getItemOffset(); + + if (offsetTop) this.elemOffset = offsetTop; + }; + + getItemOffset = () => { + const { hotkeyCaret, viewAs } = this.filesStore; + let item = document.getElementsByClassName( `${hotkeyCaret.id}_${hotkeyCaret.fileExst}` ); @@ -75,42 +109,38 @@ class HotkeyStore { if (item && item[0]) { const el = item[0]; - const rect = el.getBoundingClientRect(); - const scroll = document.getElementsByClassName("section-scroll")[0]; - const scrollRect = scroll.getBoundingClientRect(); - if ( - scrollRect.top + scrollRect.height - rect.height > rect.top && - scrollRect.top < rect.top + el.offsetHeight - ) { - //console.log("element is visible"); - } else { - const offset = el.closest(".window-item")?.offsetTop; - const offsetTop = offset - ? offset - : viewAs === "tile" - ? el.parentElement.parentElement.offsetTop - : el.offsetTop; + const offset = el.closest(".window-item")?.offsetTop; - scroll.scrollTo(0, offsetTop - scrollRect.height / 2); - //console.log("element is not visible"); - } + const offsetTop = offset + ? offset + : viewAs === "tile" + ? el.parentElement.parentElement.offsetTop + : el.offsetTop; + + return { offsetTop, item }; } + + return { offsetTop: null, item: null }; }; selectFirstFile = () => { const { filesList } = this.filesStore; if (filesList.length) { + // scroll to first element + const scroll = document.querySelector("#sectionScroll > .scroll-body"); + scroll.scrollTo(0, 0); + this.filesStore.setSelection([filesList[0]]); - this.filesStore.setHotkeyCaret(filesList[0]); + this.setCaret(filesList[0]); this.filesStore.setHotkeyCaretStart(filesList[0]); } }; setSelectionWithCaret = (selection) => { this.filesStore.setSelection(selection); - this.filesStore.setHotkeyCaret(selection[0]); + this.setCaret(selection[0]); this.filesStore.setHotkeyCaretStart(selection[0]); }; @@ -119,7 +149,6 @@ class HotkeyStore { selection, setSelection, hotkeyCaret, - setHotkeyCaret, setHotkeyCaretStart, } = this.filesStore; @@ -135,7 +164,7 @@ class HotkeyStore { setHotkeyCaretStart(hotkeyCaret); } else { if (selection.length) { - setHotkeyCaret(selection[0]); + this.setCaret(selection[0]); setHotkeyCaretStart(selection[0]); } else this.selectFirstFile(); } @@ -204,7 +233,6 @@ class HotkeyStore { setHotkeyCaretStart, hotkeyCaret, viewAs, - setHotkeyCaret, deselectFile, } = this.filesStore; @@ -220,14 +248,14 @@ class HotkeyStore { ...this.selectionsDown, ...[hotkeyCaretStart ? hotkeyCaretStart : hotkeyCaret], ]); - setHotkeyCaret(this.nextForTileDown); + this.setCaret(this.nextForTileDown); } else if (this.nextFile) { if (selection.findIndex((f) => f.id === this.nextFile.id) !== -1) { deselectFile(hotkeyCaret); } else { setSelection([...selection, ...[this.nextFile]]); } - setHotkeyCaret(this.nextFile); + this.setCaret(this.nextFile); } }; @@ -239,7 +267,6 @@ class HotkeyStore { setHotkeyCaretStart, hotkeyCaret, viewAs, - setHotkeyCaret, deselectFile, } = this.filesStore; @@ -255,7 +282,7 @@ class HotkeyStore { ...this.selectionsUp, ...[hotkeyCaretStart ? hotkeyCaretStart : hotkeyCaret], ]); - setHotkeyCaret(this.prevForTileUp); + this.setCaret(this.prevForTileUp); } else if (this.prevFile) { if (selection.findIndex((f) => f.id === this.prevFile.id) !== -1) { deselectFile(hotkeyCaret); @@ -263,7 +290,7 @@ class HotkeyStore { setSelection([...[this.prevFile], ...selection]); } - setHotkeyCaret(this.prevFile); + this.setCaret(this.prevFile); } }; @@ -273,7 +300,6 @@ class HotkeyStore { setSelection, hotkeyCaret, viewAs, - setHotkeyCaret, deselectFile, hotkeyCaretStart, filesList, @@ -314,7 +340,7 @@ class HotkeyStore { if (viewAs === "tile") { setSelection(nextForTileRight); - setHotkeyCaret(nextFile); + this.setCaret(nextFile); } else if (nextFile) { if (selection.findIndex((f) => f.id === nextFile.id) !== -1) { deselectFile(hotkeyCaret); @@ -322,7 +348,7 @@ class HotkeyStore { setSelection([...selection, ...[nextFile]]); } - setHotkeyCaret(nextFile); + this.setCaret(nextFile); } }; @@ -332,7 +358,6 @@ class HotkeyStore { setSelection, hotkeyCaret, viewAs, - setHotkeyCaret, deselectFile, filesList, hotkeyCaretStart, @@ -373,7 +398,7 @@ class HotkeyStore { if (viewAs === "tile") { setSelection(prevForTileLeft); - setHotkeyCaret(prevFile); + this.setCaret(prevFile); } else if (prevFile) { if (selection.findIndex((f) => f.id === prevFile.id) !== -1) { deselectFile(hotkeyCaret); @@ -381,30 +406,30 @@ class HotkeyStore { setSelection([...[prevFile], ...selection]); } - setHotkeyCaret(prevFile); + this.setCaret(prevFile); } }; moveCaretBottom = () => { - const { viewAs, setHotkeyCaret } = this.filesStore; + const { viewAs } = this.filesStore; - if (viewAs === "tile") setHotkeyCaret(this.nextForTileDown); - else if (this.nextFile) setHotkeyCaret(this.nextFile); + if (viewAs === "tile") this.setCaret(this.nextForTileDown); + else if (this.nextFile) this.setCaret(this.nextFile); }; moveCaretUpper = () => { - const { viewAs, setHotkeyCaret } = this.filesStore; + const { viewAs } = this.filesStore; - if (viewAs === "tile") setHotkeyCaret(this.prevForTileUp); - else if (this.prevFile) setHotkeyCaret(this.prevFile); + if (viewAs === "tile") this.setCaret(this.prevForTileUp); + else if (this.prevFile) this.setCaret(this.prevFile); }; moveCaretLeft = () => { - if (this.prevFile) this.filesStore.setHotkeyCaret(this.prevFile); + if (this.prevFile) this.setCaret(this.prevFile); }; moveCaretRight = () => { - if (this.nextFile) this.filesStore.setHotkeyCaret(this.nextFile); + if (this.nextFile) this.setCaret(this.nextFile); }; openItem = () => { @@ -418,14 +443,13 @@ class HotkeyStore { const { filesList, hotkeyCaret, - setHotkeyCaret, setHotkeyCaretStart, setSelected, } = this.filesStore; setSelected("all"); if (!hotkeyCaret) { - setHotkeyCaret(filesList[0]); + this.setCaret(filesList[0]); setHotkeyCaretStart(filesList[0]); } }; From c65e01a988cf5500589f021c9acdb8d76b74c112 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 15 Aug 2022 17:22:50 +0300 Subject: [PATCH 41/78] Web: Files: fixed fetch files --- .../Body/TilesView/sub-components/InfiniteGrid.js | 4 ++-- packages/components/infinite-loader/Grid.js | 9 ++++++++- packages/components/infinite-loader/List.js | 9 ++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js index fcd092fba7..4aeecbb3ae 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js @@ -142,7 +142,7 @@ const InfiniteGrid = (props) => { addItemToList(listKey, otherClassName); } - //console.log("InfiniteGrid render", list); + // console.log("InfiniteGrid render", list); return ( { countTilesInRow={countTilesInRow} filesLength={filesLength} hasMoreFiles={hasMoreFiles} - itemCount={filterTotal / countTilesInRow} //TODO: - count headers + itemCount={hasMoreFiles ? list.length + 1 : list.length} loadMoreItems={fetchMoreFiles} className={`TileList ${className}`} selectedFolderId={selectedFolderId} diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 5369095601..c5186856a3 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import React, { useCallback, useEffect } from "react"; import { InfiniteLoader, WindowScroller } from "react-virtualized"; import { StyledList } from "./StyledInfiniteLoader"; @@ -13,6 +13,12 @@ const GridComponent = ({ className, scroll, }) => { + const loaderRef = React.createRef(); + + useEffect(() => { + setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); + }, [loaderRef]); + const isItemLoaded = useCallback( ({ index }) => { return !hasMoreFiles || (index + 1) * countTilesInRow < filesLength; @@ -49,6 +55,7 @@ const GridComponent = ({ isRowLoaded={isItemLoaded} rowCount={itemCount} loadMoreRows={loadMoreItems} + ref={loaderRef} > {({ onRowsRendered, registerChild }) => ( diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 7d7bc0e3f3..f7c68f7082 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -1,4 +1,4 @@ -import React, { useCallback } from "react"; +import React, { useCallback, useEffect } from "react"; import { InfiniteLoader, WindowScroller } from "react-virtualized"; import Loaders from "@docspace/common/components/Loaders"; import { StyledList } from "./StyledInfiniteLoader"; @@ -18,6 +18,12 @@ const ListComponent = ({ scroll, infoPanelVisible, }) => { + const loaderRef = React.createRef(); + + useEffect(() => { + setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); + }, [loaderRef]); + const renderRow = ({ key, index, style }) => { const isLoaded = isItemLoaded({ index: index + 2 }); if (!isLoaded) return getLoader(style, key); @@ -87,6 +93,7 @@ const ListComponent = ({ isRowLoaded={isItemLoaded} rowCount={itemCount} loadMoreRows={loadMoreItems} + ref={loaderRef} > {({ onRowsRendered, registerChild }) => ( From 5d3c98ea91ece22cb2a2cdefd5012a96297d4a40 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 15 Aug 2022 17:41:39 +0300 Subject: [PATCH 42/78] Web: Files: fixed fetch files --- .../Body/RowsView/FilesRowContainer.js | 51 +++++++------- .../Section/Body/TableView/TableContainer.js | 69 ++++++++++--------- packages/components/infinite-loader/Grid.js | 7 +- packages/components/infinite-loader/List.js | 7 +- packages/components/row-container/index.js | 2 + .../components/table-container/TableBody.js | 2 + 6 files changed, 77 insertions(+), 61 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index 8d0b1ab26e..aae1dd5726 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -68,6 +68,7 @@ const FilesRowContainer = ({ fetchMoreFiles, hasMoreFiles, isRooms, + selectedFolderId, }) => { useEffect(() => { if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return; @@ -93,6 +94,7 @@ const FilesRowContainer = ({ hasMoreFiles={hasMoreFiles} draggable useReactWindow + selectedFolderId={selectedFolderId} > {filesList.map((item, index) => ( { - const { - filesList, - viewAs, - setViewAs, - filterTotal, - fetchMoreFiles, - hasMoreFiles, - } = filesStore; - const { isVisible: infoPanelVisible } = auth.infoPanelStore; - const { isRoomsFolder, isArchiveFolder } = treeFoldersStore; +export default inject( + ({ filesStore, auth, treeFoldersStore, selectedFolderStore }) => { + const { + filesList, + viewAs, + setViewAs, + filterTotal, + fetchMoreFiles, + hasMoreFiles, + } = filesStore; + const { isVisible: infoPanelVisible } = auth.infoPanelStore; + const { isRoomsFolder, isArchiveFolder } = treeFoldersStore; - const isRooms = isRoomsFolder || isArchiveFolder; + const isRooms = isRoomsFolder || isArchiveFolder; - return { - filesList, - viewAs, - setViewAs, - infoPanelVisible, - filterTotal, - fetchMoreFiles, - hasMoreFiles, - isRooms, - }; -})(observer(FilesRowContainer)); + return { + filesList, + viewAs, + setViewAs, + infoPanelVisible, + filterTotal, + fetchMoreFiles, + hasMoreFiles, + isRooms, + selectedFolderId: selectedFolderStore.id, + }; + } +)(observer(FilesRowContainer)); diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index ab51837173..38a93a044f 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -122,6 +122,7 @@ const Table = ({ hasMoreFiles, filterTotal, isRooms, + selectedFolderId, }) => { const [tagCount, setTagCount] = React.useState(null); @@ -206,6 +207,7 @@ const Table = ({ useReactWindow infoPanelVisible={infoPanelVisible} columnInfoPanelStorageName={columnInfoPanelStorageName} + selectedFolderId={selectedFolderId} > {filesList.map((item, index) => { return index === 0 && item.isRoom ? ( @@ -246,39 +248,42 @@ const Table = ({ ); }; -export default inject(({ filesStore, treeFoldersStore, auth }) => { - const { isVisible: infoPanelVisible } = auth.infoPanelStore; +export default inject( + ({ filesStore, treeFoldersStore, auth, selectedFolderStore }) => { + const { isVisible: infoPanelVisible } = auth.infoPanelStore; - const { isRoomsFolder, isArchiveFolder } = treeFoldersStore; + const { isRoomsFolder, isArchiveFolder } = treeFoldersStore; - const isRooms = - isRoomsFolder || - isArchiveFolder || - window.location.href.includes("/rooms?"); + const isRooms = + isRoomsFolder || + isArchiveFolder || + window.location.href.includes("/rooms?"); - const { - filesList, - viewAs, - setViewAs, - setFirsElemChecked, - setHeaderBorder, - fetchMoreFiles, - hasMoreFiles, - filterTotal, - } = filesStore; + const { + filesList, + viewAs, + setViewAs, + setFirsElemChecked, + setHeaderBorder, + fetchMoreFiles, + hasMoreFiles, + filterTotal, + } = filesStore; - return { - filesList, - viewAs, - setViewAs, - setFirsElemChecked, - setHeaderBorder, - theme: auth.settingsStore.theme, - userId: auth.userStore.user.id, - infoPanelVisible, - fetchMoreFiles, - hasMoreFiles, - filterTotal, - isRooms, - }; -})(observer(Table)); + return { + filesList, + viewAs, + setViewAs, + setFirsElemChecked, + setHeaderBorder, + theme: auth.settingsStore.theme, + userId: auth.userStore.user.id, + infoPanelVisible, + fetchMoreFiles, + hasMoreFiles, + filterTotal, + isRooms, + selectedFolderId: selectedFolderStore.id, + }; + } +)(observer(Table)); diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index c5186856a3..7695332c53 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useCallback, useEffect, createRef } from "react"; import { InfiniteLoader, WindowScroller } from "react-virtualized"; import { StyledList } from "./StyledInfiniteLoader"; @@ -12,12 +12,13 @@ const GridComponent = ({ children, className, scroll, + selectedFolderId, }) => { - const loaderRef = React.createRef(); + const loaderRef = createRef(); useEffect(() => { setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); - }, [loaderRef]); + }, [loaderRef, selectedFolderId]); const isItemLoaded = useCallback( ({ index }) => { diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index f7c68f7082..81b78f7f75 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect } from "react"; +import React, { useCallback, useEffect, createRef } from "react"; import { InfiniteLoader, WindowScroller } from "react-virtualized"; import Loaders from "@docspace/common/components/Loaders"; import { StyledList } from "./StyledInfiniteLoader"; @@ -17,12 +17,13 @@ const ListComponent = ({ className, scroll, infoPanelVisible, + selectedFolderId, }) => { - const loaderRef = React.createRef(); + const loaderRef = createRef(); useEffect(() => { setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); - }, [loaderRef]); + }, [loaderRef, selectedFolderId]); const renderRow = ({ key, index, style }) => { const isLoaded = isItemLoaded({ index: index + 2 }); diff --git a/packages/components/row-container/index.js b/packages/components/row-container/index.js index 34cc2cf707..54e504fe67 100644 --- a/packages/components/row-container/index.js +++ b/packages/components/row-container/index.js @@ -19,6 +19,7 @@ class RowContainer extends React.PureComponent { itemCount, fetchMoreFiles, hasMoreFiles, + selectedFolderId, } = this.props; return ( @@ -39,6 +40,7 @@ class RowContainer extends React.PureComponent { loadMoreItems={fetchMoreFiles} itemSize={itemHeight} onScroll={onScroll} + selectedFolderId={selectedFolderId} > {children} diff --git a/packages/components/table-container/TableBody.js b/packages/components/table-container/TableBody.js index 630a4d3eab..a88fd17f1b 100644 --- a/packages/components/table-container/TableBody.js +++ b/packages/components/table-container/TableBody.js @@ -15,6 +15,7 @@ const TableBody = (props) => { useReactWindow, onScroll, infoPanelVisible, + selectedFolderId, } = props; return useReactWindow ? ( @@ -34,6 +35,7 @@ const TableBody = (props) => { itemSize={itemHeight} onScroll={onScroll} infoPanelVisible={infoPanelVisible} + selectedFolderId={selectedFolderId} > {children} From fe37848cdc52510829542f7c4eb31a56df04f338 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 16 Aug 2022 16:15:05 +0300 Subject: [PATCH 43/78] Web: Files: Row: fixed itemHeight --- .../src/pages/Home/Section/Body/RowsView/FilesRowContainer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index aae1dd5726..002222c7b4 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -95,6 +95,7 @@ const FilesRowContainer = ({ draggable useReactWindow selectedFolderId={selectedFolderId} + itemHeight={58} > {filesList.map((item, index) => ( Date: Tue, 16 Aug 2022 16:16:33 +0300 Subject: [PATCH 44/78] Web: Files: fixed removeFiles, fixed filterTotal --- .../client/src/store/FilesActionsStore.js | 10 +---- packages/client/src/store/FilesStore.js | 43 ++++++++++++++++--- packages/common/api/files/filter.js | 3 +- 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 4c02c17c9d..50c1d8c02e 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -199,20 +199,14 @@ class FilesActionStore { setTimeout(() => clearSecondaryProgressData(), TIMEOUT); }; - updateFilesAfterDelete = (folderIds) => { - const { folders, setFolders, filter, setSelected } = this.filesStore; + updateFilesAfterDelete = () => { + const { setSelected } = this.filesStore; const { clearSecondaryProgressData, } = this.uploadDataStore.secondaryProgressDataStore; setSelected("close"); - if (folderIds) { - const newFolders = folders.filter((f) => !folderIds.includes(f.id)); - setFolders(newFolders); - filter.total -= 1; - } - this.dialogsStore.setIsFolderActions(false); setTimeout(() => clearSecondaryProgressData(), TIMEOUT); }; diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 0e48e45610..2b4dd36067 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -1631,18 +1631,48 @@ class FilesStore { }; addFile = (item, isFolder) => { - this.filter.total += 1; + const filter = this.filter.clone(); + filter.total += 1; + this.setFilter(filter); + isFolder ? this.folders.unshift(item) : this.files.unshift(item); this.scrollToTop(); }; removeFiles = (fileIds, folderIds) => { - this.filter.total -= fileIds.length + folderIds.length; + const newFilter = this.filter.clone(); + const deleteCount = fileIds.length + folderIds.length; + newFilter.startIndex = + (newFilter.page + 1) * newFilter.pageCount - deleteCount; + newFilter.pageCount = deleteCount; - if (fileIds) this.files = this.files.filter((x) => !fileIds.includes(x.id)); - if (folderIds) - this.folders = this.folders.filter((x) => !folderIds.includes(x.id)); + api.files + .getFolder(newFilter.folder, newFilter) + .then((res) => { + const files = fileIds + ? this.files.filter((x) => !fileIds.includes(x.id)) + : []; + const folders = folderIds + ? this.folders.filter((x) => !folderIds.includes(x.id)) + : []; + + const newFiles = [...files, ...res.files]; + const newFolders = [...folders, ...res.folders]; + + const filter = this.filter.clone(); + filter.total = res.total; + + runInAction(() => { + this.setFilter(filter); + this.setFiles(newFiles); + this.setFolders(newFolders); + }); + }) + .catch(() => { + toastr.error(err); + console.log("Need page reload"); + }); }; updateFile = (fileId, title) => { @@ -2488,13 +2518,12 @@ class FilesStore { this.trashIsEmpty = isEmpty; }; - //TODO: filter.total is not updated, need move filter to new filterStore get filterTotal() { return this.filter.total; } get hasMoreFiles() { - return this.filesList.length < this.filter.total; + return this.filesList.length < this.filterTotal; } setFilesIsLoading = (filesIsLoading) => { diff --git a/packages/common/api/files/filter.js b/packages/common/api/files/filter.js index b545b667b2..c178b8ed81 100644 --- a/packages/common/api/files/filter.js +++ b/packages/common/api/files/filter.js @@ -135,6 +135,7 @@ class FilesFilter { sortBy, sortOrder, withSubfolders, + startIndex, } = this; const isFilterSet = @@ -148,7 +149,7 @@ class FilesFilter { const dtoFilter = { count: pageCount, - startIndex: this.getStartIndex(), + startIndex: startIndex ? startIndex : this.getStartIndex(), page: page, sortby: sortBy, sortOrder: sortOrder, From 0b1a8bf3687b83361639a53475c15a323ea76e1f Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 15:11:48 +0300 Subject: [PATCH 45/78] Web: Files: fixed infinite-scroll styles --- .../TilesView/sub-components/InfiniteGrid.js | 9 ++-- .../sub-components/StyledInfiniteGrid.js | 4 ++ .../Section/sub-components/section-body.js | 46 +++++++++-------- packages/components/infinite-loader/Grid.js | 3 +- .../infinite-loader/InfiniteLoader.js | 8 ++- packages/components/infinite-loader/List.js | 1 + .../infinite-loader/StyledInfiniteLoader.js | 49 ++++++++++++++++++- 7 files changed, 93 insertions(+), 27 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js index 4aeecbb3ae..1596aebd5f 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js @@ -5,9 +5,9 @@ import { StyledCard, StyledItem, StyledHeaderItem } from "./StyledInfiniteGrid"; import Loaders from "@docspace/common/components/Loaders"; import uniqueid from "lodash/uniqueId"; -const HeaderItem = ({ children, ...rest }) => { +const HeaderItem = ({ children, className, ...rest }) => { return ( - + {children} ); @@ -95,7 +95,10 @@ const InfiniteGrid = (props) => { } list.push( - + {child} ); diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js index 8d9b8b3897..2976567cd4 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/StyledInfiniteGrid.js @@ -24,6 +24,10 @@ const StyledItem = styled.div` gap: 14px 16px; width: 100%; + @media ${tablet} { + gap: 14px; + } + ${paddingCss}; `; diff --git a/packages/common/components/Section/sub-components/section-body.js b/packages/common/components/Section/sub-components/section-body.js index e28369ebef..7a88972cb2 100644 --- a/packages/common/components/Section/sub-components/section-body.js +++ b/packages/common/components/Section/sub-components/section-body.js @@ -10,33 +10,37 @@ import Scrollbar from "@docspace/components/scrollbar"; import DragAndDrop from "@docspace/components/drag-and-drop"; import { tablet, - mobile, desktop, smallTablet, } from "@docspace/components/utils/device"; +const settingsStudioStyles = css` + ${({ settingsStudio }) => + settingsStudio + ? css` + padding: 0 7px 16px 20px; + + @media ${tablet} { + padding: 0 0 16px 24px; + } + + @media ${smallTablet} { + padding: 8px 0 16px 24px; + } + ` + : css` + @media ${tablet} { + padding: ${({ viewAs }) => + viewAs === "tile" ? "19px 0 16px 24px" : "19px 0 16px 8px"}; + } + `} +`; + const paddingStyles = css` - padding: ${(props) => - props.settingsStudio - ? "0 7px 16px 20px" - : props.viewAs === "row" - ? "19px 3px 16px 16px" - : "19px 3px 16px 20px"}; + padding: ${({ viewAs }) => + viewAs === "row" ? "19px 3px 16px 0px" : "19px 3px 16px 20px"}; - @media ${tablet} { - padding: ${(props) => - props.settingsStudio ? "0 0 16px 24px" : "19px 0 16px 24px"}; - } - - @media ${smallTablet} { - padding: ${(props) => - props.settingsStudio ? "8px 0 16px 24px" : "19px 0 16px 24px"}; - } - - @media ${mobile} { - padding: ${(props) => - props.settingsStudio ? "8px 0 16px 24px" : "19px 0 16px 24px"}; - } + ${settingsStudioStyles}; ${isMobile && css` diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 7695332c53..4697d25b05 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -39,6 +39,7 @@ const GridComponent = ({ const itemClassNames = children[index]?.props?.className; const isFile = itemClassNames?.includes("isFile"); const isFolder = itemClassNames?.includes("isFolder"); + const isFolderHeader = itemClassNames?.includes("folder_header"); const horizontalGap = 16; const verticalGap = 14; @@ -46,7 +47,7 @@ const GridComponent = ({ const folderHeight = 64 + verticalGap; const fileHeight = 220 + horizontalGap; - const titleHeight = 20 + headerMargin; + const titleHeight = 20 + headerMargin + (isFolderHeader ? 0 : 11); return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; }; diff --git a/packages/components/infinite-loader/InfiniteLoader.js b/packages/components/infinite-loader/InfiniteLoader.js index da422afe9f..6f44dd94f5 100644 --- a/packages/components/infinite-loader/InfiniteLoader.js +++ b/packages/components/infinite-loader/InfiniteLoader.js @@ -3,13 +3,19 @@ import PropTypes from "prop-types"; import { isMobileOnly } from "react-device-detect"; import ListComponent from "./List"; import GridComponent from "./Grid"; +import { isMobile } from "../utils/device"; const InfiniteLoaderComponent = (props) => { + const { viewAs } = props; + const scroll = isMobileOnly ? document.querySelector("#customScrollBar > .scroll-body") : document.querySelector("#sectionScroll > .scroll-body"); - return props.viewAs === "tile" ? ( + if (viewAs === "row") scroll.style.paddingRight = 0; + else scroll.style.paddingRight = isMobile() ? "8px" : "17px"; + + return viewAs === "tile" ? ( ) : ( diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 81b78f7f75..3881edb504 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -126,6 +126,7 @@ const ListComponent = ({ scrollTop={scrollTop} overscanRowCount={3} onScroll={onScroll} + viewAs={viewAs} /> ); }} diff --git a/packages/components/infinite-loader/StyledInfiniteLoader.js b/packages/components/infinite-loader/StyledInfiniteLoader.js index eb73c729bb..cc676535eb 100644 --- a/packages/components/infinite-loader/StyledInfiniteLoader.js +++ b/packages/components/infinite-loader/StyledInfiniteLoader.js @@ -1,6 +1,7 @@ import { List } from "react-virtualized"; -import styled from "styled-components"; +import styled, { css } from "styled-components"; import Base from "../themes/base"; +import { desktop, mobile, tablet } from "../utils/device"; const StyledScroll = styled.div` overflow: scroll; @@ -28,9 +29,55 @@ const StyledScroll = styled.div` scrollbar-color: ${({ theme }) => theme.scrollbar.backgroundColorVertical}; `; +const rowStyles = css` + .row-list-item, + .row-loader { + padding-left: 16px; + width: calc(100% - 33px) !important; + + @media ${mobile} { + width: calc(100% - 24px) !important; + } + } + + .row-loader { + padding-left: 22px; + } +`; + +const tableStyles = css` + margin-left: -20px; + width: ${({ width }) => width + 40 + "px !important"}; + + .ReactVirtualized__Grid__innerScrollContainer { + max-width: ${({ width }) => width + 40 + "px !important"}; + } + .table-container_body-loader { + width: calc(100% - 48px) !important; + } + + .table-list-item, + .table-container_body-loader { + padding-left: 20px; + } +`; + +const tileStyles = css` + .files_header { + padding-top: 11px; + } +`; + const StyledList = styled(List)` outline: none; overflow: hidden !important; + + ${({ viewAs }) => + viewAs === "row" + ? rowStyles + : viewAs === "table" + ? tableStyles + : tileStyles} `; StyledScroll.defaultProps = { From 2afade9016dcb68ca82d66189277efd4c508e246 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 17:16:49 +0300 Subject: [PATCH 46/78] Web: Files: Hotkeys: added throttle to keydown event --- packages/client/src/HOCs/withHotkeys.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/client/src/HOCs/withHotkeys.js b/packages/client/src/HOCs/withHotkeys.js index 481dc2ccd6..cd9f046e19 100644 --- a/packages/client/src/HOCs/withHotkeys.js +++ b/packages/client/src/HOCs/withHotkeys.js @@ -3,6 +3,7 @@ import { useHotkeys } from "react-hotkeys-hook"; import { observer, inject } from "mobx-react"; import { Events } from "@docspace/client/src/helpers/filesConstants"; import toastr from "client/toastr"; +import throttle from "lodash/throttle"; const withHotkeys = (Component) => { const WithHotkeys = (props) => { @@ -91,9 +92,12 @@ const withHotkeys = (Component) => { }; useEffect(() => { - window.addEventListener("keydown", onKeyDown); + const throttledKeyDownEvent = throttle(onKeyDown, 300); - return () => window.removeEventListener("keypress", onKeyDown); + window.addEventListener("keydown", throttledKeyDownEvent); + + return () => + window.removeEventListener("keypress", throttledKeyDownEvent); }); //Select/deselect item From 896f86fde41870a6b21984615acf7a3e949dd53e Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 17:30:55 +0300 Subject: [PATCH 47/78] Web: Files: fixed hotkeys scroll --- packages/client/src/store/HotkeyStore.js | 55 +++++++++++++----------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index a34833bcf5..c93e784cf5 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -33,6 +33,29 @@ class HotkeyStore { this.uploadDataStore = uploadDataStore; } + scrollToCaret = () => { + const { offsetTop, item } = this.getItemOffset(); + const scroll = document.getElementsByClassName("section-scroll")[0]; + const scrollRect = scroll.getBoundingClientRect(); + + if (item && item[0]) { + const el = item[0]; + const rect = el.getBoundingClientRect(); + + if ( + scrollRect.top + scrollRect.height - rect.height > rect.top && + scrollRect.top < rect.top + el.offsetHeight + ) { + //console.log("element is visible"); + } else { + scroll.scrollTo(0, offsetTop - scrollRect.height / 2); + //console.log("element is not visible"); + } + } else { + scroll.scrollTo(0, this.elemOffset - scrollRect.height / 2); + } + }; + activateHotkeys = (e) => { if ( this.dialogsStore.someDialogIsOpen || @@ -65,34 +88,18 @@ class HotkeyStore { this.filesStore.setHotkeyCaretStart(selection[0]); } - if (!hotkeyCaret || isDefaultKeys) return; - - const { offsetTop, item } = this.getItemOffset(); - const scroll = document.getElementsByClassName("section-scroll")[0]; - const scrollRect = scroll.getBoundingClientRect(); - - if (item && item[0]) { - const el = item[0]; - const rect = el.getBoundingClientRect(); - - if ( - scrollRect.top + scrollRect.height - rect.height > rect.top && - scrollRect.top < rect.top + el.offsetHeight - ) { - //console.log("element is visible"); - } else { - scroll.scrollTo(0, offsetTop - scrollRect.height / 2); - //console.log("element is not visible"); - } - } else { - scroll.scrollTo(0, this.elemOffset - scrollRect.height / 2); - } + if (!hotkeyCaret || isDefaultKeys) return e; }; setCaret = (caret) => { - this.filesStore.setHotkeyCaret(caret); - const { offsetTop } = this.getItemOffset(); + const id = caret.isFolder ? `folder_${caret.id}` : `file_${caret.id}`; + const elem = document.getElementById(id); + if (!elem) return; + this.filesStore.setHotkeyCaret(caret); + this.scrollToCaret(); + + const { offsetTop } = this.getItemOffset(); if (offsetTop) this.elemOffset = offsetTop; }; From 2e2b701df03430591240187d97c67d0fd53b92ab Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 17:54:35 +0300 Subject: [PATCH 48/78] Web: Common: changed DEFAULT_PAGE_COUNT --- packages/common/api/files/filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/common/api/files/filter.js b/packages/common/api/files/filter.js index c178b8ed81..eabf6b2fc8 100644 --- a/packages/common/api/files/filter.js +++ b/packages/common/api/files/filter.js @@ -2,7 +2,7 @@ import { getObjectByLocation, toUrlParams } from "../../utils"; import queryString from "query-string"; const DEFAULT_PAGE = 0; -const DEFAULT_PAGE_COUNT = 25; +const DEFAULT_PAGE_COUNT = 100; const DEFAULT_TOTAL = 0; const DEFAULT_SORT_BY = "DateAndTime"; const DEFAULT_SORT_ORDER = "descending"; From c8676289a6b1aace4d7a7195b32e631c5631e651 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 17:55:05 +0300 Subject: [PATCH 49/78] Web: Files: Hotkeys: fixed scrollToCaret --- packages/client/src/store/HotkeyStore.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index c93e784cf5..9fe02d46c2 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -92,9 +92,10 @@ class HotkeyStore { }; setCaret = (caret) => { - const id = caret.isFolder ? `folder_${caret.id}` : `file_${caret.id}`; - const elem = document.getElementById(id); - if (!elem) return; + //TODO: inf-scroll + // const id = caret.isFolder ? `folder_${caret.id}` : `file_${caret.id}`; + // const elem = document.getElementById(id); + // if (!elem) return; this.filesStore.setHotkeyCaret(caret); this.scrollToCaret(); From 6df825670de22173d3ac1576974191e131a97f82 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 17 Aug 2022 17:55:59 +0300 Subject: [PATCH 50/78] Web: Components: fixed scroll z-index --- packages/components/scrollbar/styled-scrollbar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/scrollbar/styled-scrollbar.js b/packages/components/scrollbar/styled-scrollbar.js index 287aaed1fb..b264ac564b 100644 --- a/packages/components/scrollbar/styled-scrollbar.js +++ b/packages/components/scrollbar/styled-scrollbar.js @@ -8,7 +8,7 @@ const StyledScrollbar = styled(Scrollbars)` props.color ? props.color : props.theme.scrollbar.backgroundColorVertical}; - z-index: 1; + z-index: 201; } .nav-thumb-horizontal { background-color: ${(props) => From 09fbafed03200a1f83cfe1e0a5d10bb15eae28a6 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 18 Aug 2022 10:20:12 +0300 Subject: [PATCH 51/78] Web: Components: fixed loadMoreItems --- packages/components/infinite-loader/Grid.js | 4 ++-- packages/components/infinite-loader/List.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 4697d25b05..5ecbb3ae7f 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -17,8 +17,8 @@ const GridComponent = ({ const loaderRef = createRef(); useEffect(() => { - setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); - }, [loaderRef, selectedFolderId]); + setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 1000); + }, [loaderRef, selectedFolderId, filesLength]); const isItemLoaded = useCallback( ({ index }) => { diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 3881edb504..1dab53c80a 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -22,8 +22,8 @@ const ListComponent = ({ const loaderRef = createRef(); useEffect(() => { - setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 0); - }, [loaderRef, selectedFolderId]); + setTimeout(() => loaderRef?.current?.resetLoadMoreRowsCache(true), 1000); + }, [loaderRef, selectedFolderId, filesLength]); const renderRow = ({ key, index, style }) => { const isLoaded = isItemLoaded({ index: index + 2 }); From a6ddc6937c73e1bed5fb69fb68b4a4c391c5ca26 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 18 Aug 2022 10:46:22 +0300 Subject: [PATCH 52/78] Web: Files: fixed deleteAction toast --- .../client/src/store/FilesActionsStore.js | 72 ++++++++++--------- packages/client/src/store/FilesStore.js | 4 +- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index 50c1d8c02e..ebad96eb6f 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -283,7 +283,22 @@ class FilesActionStore { //this.updateCurrentFolder(fileIds, folderIds, false); this.updateFilesAfterDelete(folderIds); - this.filesStore.removeFiles(fileIds, folderIds); + + const showToast = () => { + if (isRecycleBinFolder) { + return toastr.success(translations.deleteFromTrash); + } + + if (selection.length > 1 || isThirdPartyFile) { + return toastr.success(translations.deleteSelectedElem); + } + if (selection[0].fileExst) { + return toastr.success(translations.FileRemoved); + } + return toastr.success(translations.FolderRemoved); + }; + + this.filesStore.removeFiles(fileIds, folderIds, showToast); if (currentFolderId) { const { socketHelper } = this.authStore.settingsStore; @@ -293,18 +308,6 @@ class FilesActionStore { data: currentFolderId, }); } - - if (isRecycleBinFolder) { - return toastr.success(translations.deleteFromTrash); - } - - if (selection.length > 1 || isThirdPartyFile) { - return toastr.success(translations.deleteSelectedElem); - } - if (selection[0].fileExst) { - return toastr.success(translations.FileRemoved); - } - return toastr.success(translations.FolderRemoved); }) .finally(() => { clearActiveOperations(fileIds, folderIds); @@ -611,16 +614,17 @@ class FilesActionStore { if (isFile) { addActiveItems([itemId]); this.isMediaOpen(); - return deleteFile(itemId) - .then(async (res) => { - if (res[0]?.error) return Promise.reject(res[0].error); - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations(data, pbData); - //this.updateCurrentFolder([itemId]); - this.updateFilesAfterDelete(); - this.filesStore.removeFiles([itemId]); - }) - .then(() => toastr.success(translations.successRemoveFile)); + return deleteFile(itemId).then(async (res) => { + if (res[0]?.error) return Promise.reject(res[0].error); + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations(data, pbData); + //this.updateCurrentFolder([itemId]); + this.updateFilesAfterDelete(); + + this.filesStore.removeFiles([itemId], null, () => + toastr.success(translations.successRemoveFile) + ); + }); } else if (isRoom) { const items = Array.isArray(itemId) ? itemId : [itemId]; addActiveItems(null, items); @@ -637,17 +641,17 @@ class FilesActionStore { .then(() => toastr.success(translations?.successRemoveRoom)); } else { addActiveItems(null, [itemId]); - return deleteFolder(itemId) - .then(async (res) => { - if (res[0]?.error) return Promise.reject(res[0].error); - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations(data, pbData); - //this.updateCurrentFolder(null, [itemId]); - this.updateFilesAfterDelete([itemId]); - this.filesStore.removeFiles([itemId]); - getIsEmptyTrash(); - }) - .then(() => toastr.success(translations.successRemoveFolder)); + return deleteFolder(itemId).then(async (res) => { + if (res[0]?.error) return Promise.reject(res[0].error); + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations(data, pbData); + //this.updateCurrentFolder(null, [itemId]); + this.updateFilesAfterDelete([itemId]); + this.filesStore.removeFiles([itemId], null, () => + toastr.success(translations.successRemoveFolder) + ); + getIsEmptyTrash(); + }); } }; diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 2b4dd36067..05f0186c2e 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -1640,7 +1640,7 @@ class FilesStore { this.scrollToTop(); }; - removeFiles = (fileIds, folderIds) => { + removeFiles = (fileIds, folderIds, showToast) => { const newFilter = this.filter.clone(); const deleteCount = fileIds.length + folderIds.length; newFilter.startIndex = @@ -1668,6 +1668,8 @@ class FilesStore { this.setFiles(newFiles); this.setFolders(newFolders); }); + + showToast && showToast(); }) .catch(() => { toastr.error(err); From e5e1d966d1929533a3d7a26855adb68a1ea6b573 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 19 Aug 2022 12:37:30 +0300 Subject: [PATCH 53/78] Web: Files: restored paging, added withPaging parameter --- .../Body/RowsView/FilesRowContainer.js | 5 +- .../Section/Body/TableView/TableContainer.js | 7 ++- .../Section/Body/TableView/TableHeader.js | 6 +- .../Body/TilesView/FilesTileContainer.js | 7 ++- .../TilesView/sub-components/TileContainer.js | 1 - packages/client/src/pages/Home/index.js | 11 ++++ .../client/src/store/FilesActionsStore.js | 41 ++++++++----- packages/client/src/store/FilesStore.js | 22 +++---- packages/client/src/store/UploadDataStore.js | 60 +++++++++---------- packages/common/api/files/filter.js | 2 +- packages/common/components/Section/index.js | 4 ++ .../Section/sub-components/section-body.js | 18 ++++-- 12 files changed, 116 insertions(+), 68 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js index 002222c7b4..a621f14a68 100644 --- a/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js +++ b/packages/client/src/pages/Home/Section/Body/RowsView/FilesRowContainer.js @@ -69,6 +69,7 @@ const FilesRowContainer = ({ hasMoreFiles, isRooms, selectedFolderId, + withPaging, }) => { useEffect(() => { if ((viewAs !== "table" && viewAs !== "row") || !sectionWidth) return; @@ -93,7 +94,7 @@ const FilesRowContainer = ({ fetchMoreFiles={fetchMoreFiles} hasMoreFiles={hasMoreFiles} draggable - useReactWindow + useReactWindow={!withPaging} selectedFolderId={selectedFolderId} itemHeight={58} > @@ -119,6 +120,7 @@ export default inject( filterTotal, fetchMoreFiles, hasMoreFiles, + withPaging, } = filesStore; const { isVisible: infoPanelVisible } = auth.infoPanelStore; const { isRoomsFolder, isArchiveFolder } = treeFoldersStore; @@ -135,6 +137,7 @@ export default inject( hasMoreFiles, isRooms, selectedFolderId: selectedFolderStore.id, + withPaging, }; } )(observer(FilesRowContainer)); diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index 38a93a044f..f7eba972bf 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -123,6 +123,7 @@ const Table = ({ filterTotal, isRooms, selectedFolderId, + withPaging, }) => { const [tagCount, setTagCount] = React.useState(null); @@ -184,7 +185,7 @@ const Table = ({ : `${COLUMNS_SIZE_INFO_PANEL}=${userId}`; return ( - + ); } @@ -357,7 +358,7 @@ export default inject( canShare, firstElemChecked, headerBorder, - + withPaging, roomsFilter, fetchRooms, } = filesStore; @@ -385,6 +386,7 @@ export default inject( headerBorder, infoPanelVisible, + withPaging, }; } )( diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js index 90fcc8aded..9f6c756c12 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/FilesTileContainer.js @@ -28,7 +28,7 @@ const getThumbSize = (width) => { return `${imgWidth}x300`; }; -const FilesTileContainer = ({ filesList, t, sectionWidth }) => { +const FilesTileContainer = ({ filesList, t, sectionWidth, withPaging }) => { const firstRef = useRef(); const [thumbSize, setThumbSize] = useState(""); const [columnCount, setColumnCount] = useState(null); @@ -77,7 +77,7 @@ const FilesTileContainer = ({ filesList, t, sectionWidth }) => { @@ -108,9 +108,10 @@ const FilesTileContainer = ({ filesList, t, sectionWidth }) => { }; export default inject(({ filesStore }) => { - const { filesList } = filesStore; + const { filesList, withPaging } = filesStore; return { filesList, + withPaging, }; })(observer(FilesTileContainer)); diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 9d11da6e7f..391b2e1c8d 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -305,7 +305,6 @@ TileContainer.propTypes = { }; TileContainer.defaultProps = { - useReactWindow: true, id: "tileContainer", }; diff --git a/packages/client/src/pages/Home/index.js b/packages/client/src/pages/Home/index.js index f17d639a96..dcf991ec6d 100644 --- a/packages/client/src/pages/Home/index.js +++ b/packages/client/src/pages/Home/index.js @@ -493,6 +493,7 @@ class PureHome extends React.Component { secondaryProgressDataStoreAlert, dragging, + tReady, personal, checkedMaintenance, setMaintenanceExist, @@ -501,6 +502,7 @@ class PureHome extends React.Component { showTitle, showFilter, frameConfig, + withPaging, } = this.props; if (window.parent && !frameConfig) { @@ -512,6 +514,7 @@ class PureHome extends React.Component {
+ + {withPaging && ( + + + + )}
); @@ -629,6 +638,7 @@ export default inject( createRoom, refreshFiles, setViewAs, + withPaging, } = filesStore; const { @@ -765,6 +775,7 @@ export default inject( createRoom, refreshFiles, setViewAs, + withPaging, }; } )(withRouter(observer(Home))); diff --git a/packages/client/src/store/FilesActionsStore.js b/packages/client/src/store/FilesActionsStore.js index ebad96eb6f..658ebbf862 100644 --- a/packages/client/src/store/FilesActionsStore.js +++ b/packages/client/src/store/FilesActionsStore.js @@ -281,9 +281,6 @@ class FilesActionStore { }; await this.uploadDataStore.loopFilesOperations(data, pbData); - //this.updateCurrentFolder(fileIds, folderIds, false); - this.updateFilesAfterDelete(folderIds); - const showToast = () => { if (isRecycleBinFolder) { return toastr.success(translations.deleteFromTrash); @@ -298,7 +295,13 @@ class FilesActionStore { return toastr.success(translations.FolderRemoved); }; - this.filesStore.removeFiles(fileIds, folderIds, showToast); + if (this.filesStore.withPaging) { + this.updateCurrentFolder(fileIds, folderIds, false); + showToast(); + } else { + this.updateFilesAfterDelete(folderIds); + this.filesStore.removeFiles(fileIds, folderIds, showToast); + } if (currentFolderId) { const { socketHelper } = this.authStore.settingsStore; @@ -618,12 +621,16 @@ class FilesActionStore { if (res[0]?.error) return Promise.reject(res[0].error); const data = res[0] ? res[0] : null; await this.uploadDataStore.loopFilesOperations(data, pbData); - //this.updateCurrentFolder([itemId]); - this.updateFilesAfterDelete(); - this.filesStore.removeFiles([itemId], null, () => - toastr.success(translations.successRemoveFile) - ); + if (this.filesStore.withPaging) { + this.updateCurrentFolder([itemId]); + toastr.success(translations.successRemoveFile); + } else { + this.updateFilesAfterDelete(); + this.filesStore.removeFiles([itemId], null, () => + toastr.success(translations.successRemoveFile) + ); + } }); } else if (isRoom) { const items = Array.isArray(itemId) ? itemId : [itemId]; @@ -645,11 +652,17 @@ class FilesActionStore { if (res[0]?.error) return Promise.reject(res[0].error); const data = res[0] ? res[0] : null; await this.uploadDataStore.loopFilesOperations(data, pbData); - //this.updateCurrentFolder(null, [itemId]); - this.updateFilesAfterDelete([itemId]); - this.filesStore.removeFiles([itemId], null, () => - toastr.success(translations.successRemoveFolder) - ); + + if (this.filesStore.withPaging) { + this.updateCurrentFolder(null, [itemId]); + toastr.success(translations.successRemoveFolder); + } else { + this.updateFilesAfterDelete([itemId]); + this.filesStore.removeFiles([itemId], null, () => + toastr.success(translations.successRemoveFolder) + ); + } + getIsEmptyTrash(); }); } diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 05f0186c2e..42e60fb4a1 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -92,6 +92,7 @@ class FilesStore { isHidePagination = false; trashIsEmpty = false; filesIsLoading = false; + withPaging = false; constructor( authStore, @@ -131,9 +132,9 @@ class FilesStore { const newFiles = [file, ...this.files]; - // if (newFiles.length > this.filter.pageCount) { - // newFiles.pop(); // Remove last - // } + if (newFiles.length > this.filter.pageCount && this.withPaging) { + newFiles.pop(); // Remove last + } this.setFiles(newFiles); } @@ -179,7 +180,10 @@ class FilesStore { return index !== foundIndex; }) ); - this.filter.total -= 1; + + const newFilter = this.filter.clone(); + newFilter.total -= 1; + this.setFilter(newFilter); // Hide pagination when deleting files runInAction(() => { @@ -294,11 +298,6 @@ class FilesStore { }; setViewAs = async (viewAs) => { - // this.setIsLoading(true); - // await this.fetchFiles(this.selectedFolderStore.id, null, true); - - // this.setIsLoading(false); - this.viewAs = viewAs; localStorage.setItem("viewAs", viewAs); }; @@ -590,6 +589,7 @@ class FilesStore { }; setFilter = (filter) => { + if (!this.withPaging) filter.pageCount = 100; this.filter = filter; }; @@ -681,7 +681,7 @@ class FilesStore { filterData.sortOrder = splitFilter[2]; } - filterData.page = 0; + if (!this.withPaging) filterData.page = 0; setSelectedNode([folderId + ""]); @@ -1623,6 +1623,8 @@ class FilesStore { }; scrollToTop = () => { + if (this.withPaging) return; + const scrollElm = isMobileOnly ? document.querySelector("#customScrollBar > .scroll-body") : document.querySelector("#sectionScroll > .scroll-body"); diff --git a/packages/client/src/store/UploadDataStore.js b/packages/client/src/store/UploadDataStore.js index 1f2f1e92ce..249fc5b398 100644 --- a/packages/client/src/store/UploadDataStore.js +++ b/packages/client/src/store/UploadDataStore.js @@ -581,13 +581,14 @@ class UploadDataStore { filter, setFilter, } = this.filesStore; + if (window.location.pathname.indexOf("/history") === -1) { const newFiles = files; const newFolders = folders; const path = currentFile.path ? currentFile.path.slice() : []; - // const fileIndex = newFiles.findIndex( - // (x) => x.id === currentFile.fileInfo.id - // ); + const fileIndex = newFiles.findIndex( + (x) => x.id === currentFile.fileInfo.id + ); let folderInfo = null; const index = path.findIndex((x) => x === this.selectedFolderStore.id); @@ -621,19 +622,18 @@ class UploadDataStore { setFilter(newFilter); } } else { - // if (currentFile && currentFile.fileInfo) { - // console.log("addNewFile", fileIndex); - // if (fileIndex === -1) { - // newFiles.unshift(currentFile.fileInfo); - // setFiles(newFiles); - // const newFilter = filter; - // newFilter.total += 1; - // setFilter(newFilter); - // } else if (!this.settingsStore.storeOriginalFiles) { - // newFiles[fileIndex] = currentFile.fileInfo; - // setFiles(newFiles); - // } - // } + if (currentFile && currentFile.fileInfo) { + if (fileIndex === -1) { + newFiles.unshift(currentFile.fileInfo); + setFiles(newFiles); + const newFilter = filter; + newFilter.total += 1; + setFilter(newFilter); + } else if (!this.settingsStore.storeOriginalFiles) { + newFiles[fileIndex] = currentFile.fileInfo; + setFiles(newFiles); + } + } } }; @@ -641,7 +641,7 @@ class UploadDataStore { filter.filterType || filter.authorType || filter.search || - filter.page !== 0; + (this.filesStore.withPaging && filter.page !== 0); if ((!currentFile && !folderInfo) || isFiltered) return; if (folderInfo && this.selectedFolderStore.id === folderInfo.id) return; @@ -654,17 +654,17 @@ class UploadDataStore { } } - // if (filter.total >= filter.pageCount) { - // if (files.length) { - // fileIndex === -1 && newFiles.pop(); - // addNewFile(); - // } else { - // newFolders.pop(); - // addNewFile(); - // } - // } else { - addNewFile(); - // } + if (filter.total >= filter.pageCount && this.filesStore.withPaging) { + if (files.length) { + fileIndex === -1 && newFiles.pop(); + addNewFile(); + } else { + newFolders.pop(); + addNewFile(); + } + } else { + addNewFile(); + } if (!!folderInfo) { const { @@ -927,7 +927,7 @@ class UploadDataStore { }; finishUploadFiles = () => { - //const { fetchFiles, filter } = this.filesStore; + const { fetchFiles, filter, withPaging } = this.filesStore; const totalErrorsCount = sumBy(this.files, (f) => (f.error ? 1 : 0)); @@ -948,7 +948,7 @@ class UploadDataStore { if (this.files.length > 0) { const toFolderId = this.files[0]?.toFolderId; - //fetchFiles(toFolderId, filter); + withPaging && fetchFiles(toFolderId, filter); if (toFolderId) { const { socketHelper } = this.filesStore.settingsStore; diff --git a/packages/common/api/files/filter.js b/packages/common/api/files/filter.js index eabf6b2fc8..c178b8ed81 100644 --- a/packages/common/api/files/filter.js +++ b/packages/common/api/files/filter.js @@ -2,7 +2,7 @@ import { getObjectByLocation, toUrlParams } from "../../utils"; import queryString from "query-string"; const DEFAULT_PAGE = 0; -const DEFAULT_PAGE_COUNT = 100; +const DEFAULT_PAGE_COUNT = 25; const DEFAULT_TOTAL = 0; const DEFAULT_SORT_BY = "DateAndTime"; const DEFAULT_SORT_ORDER = "descending"; diff --git a/packages/common/components/Section/index.js b/packages/common/components/Section/index.js index 4b419d74ac..aa1fac1978 100644 --- a/packages/common/components/Section/index.js +++ b/packages/common/components/Section/index.js @@ -224,6 +224,7 @@ class Section extends React.Component { isInfoPanelAvailable, settingsStudio, clearUploadedFilesHistory, + withPaging, } = this.props; let sectionHeaderContent = null; @@ -362,6 +363,7 @@ class Section extends React.Component { viewAs={viewAs} isHomepage={isHomepage} settingsStudio={settingsStudio} + withPaging={withPaging} > {isMobile && ( - viewAs === "tile" ? "19px 0 16px 24px" : "19px 0 16px 8px"}; + padding: ${({ viewAs, withPaging }) => + viewAs === "tile" + ? "19px 0 16px 24px" + : withPaging + ? "19px 0 16px 24px" + : "19px 0 16px 8px"}; } `} `; const paddingStyles = css` - padding: ${({ viewAs }) => - viewAs === "row" ? "19px 3px 16px 0px" : "19px 3px 16px 20px"}; + padding: ${({ viewAs, withPaging }) => + viewAs === "row" + ? withPaging + ? "19px 3px 16px 16px" + : "19px 3px 16px 0px" + : "19px 3px 16px 20px"}; ${settingsStudioStyles}; @@ -208,6 +216,7 @@ class SectionBody extends React.Component { isDesktop, isHomepage, settingsStudio, + withPaging, } = this.props; const focusProps = autoFocus @@ -227,6 +236,7 @@ class SectionBody extends React.Component { isLoaded={isLoaded} isDesktop={isDesktop} settingsStudio={settingsStudio} + withPaging={withPaging} className="section-body" > {withScroll ? ( From 76425d413491d13dec7a275d2a4ff6a0d622c11c Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Fri, 19 Aug 2022 14:11:58 +0300 Subject: [PATCH 54/78] Web: Files: fixed setViewAs --- packages/client/src/store/FilesStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 42e60fb4a1..622402c3b4 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -297,7 +297,7 @@ class FilesStore { this.isLoaded = isLoaded; }; - setViewAs = async (viewAs) => { + setViewAs = (viewAs) => { this.viewAs = viewAs; localStorage.setItem("viewAs", viewAs); }; From 8e9d2c6d933f2994231d11576fe9f2570ecbd7d8 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 22 Aug 2022 14:30:42 +0300 Subject: [PATCH 55/78] Web: Common: upgraded react-selecto --- packages/common/components/Section/index.js | 7 +++- .../Section/sub-components/section-body.js | 6 +++ packages/common/package.json | 2 +- yarn.lock | 40 +++++++++---------- 4 files changed, 32 insertions(+), 23 deletions(-) diff --git a/packages/common/components/Section/index.js b/packages/common/components/Section/index.js index aa1fac1978..a2dfa27a6c 100644 --- a/packages/common/components/Section/index.js +++ b/packages/common/components/Section/index.js @@ -150,6 +150,7 @@ class Section extends React.Component { this.intervalHandler = null; this.scroll = null; + this.selectoRef = React.createRef(null); } componentDidUpdate(prevProps) { @@ -364,6 +365,7 @@ class Section extends React.Component { isHomepage={isHomepage} settingsStudio={settingsStudio} withPaging={withPaging} + selectoRef={this.selectoRef} > {isMobile && ( { + this.props.selectoRef.current.checkScroll(); + return e; + }; + render() { //console.log(" SectionBody render" ); const { @@ -245,6 +250,7 @@ class SectionBody extends React.Component { id="sectionScroll" scrollclass="section-scroll" stype="mediumBlack" + onScroll={this.onScroll} >
diff --git a/packages/common/package.json b/packages/common/package.json index 4210e56374..ec17ecdf14 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -32,7 +32,7 @@ "react-resize-detector": "^6.7.6", "react-router": "^5.2.1", "react-router-dom": "^5.3.0", - "react-selecto": "^1.12.0", + "react-selecto": "^1.18.2", "react-tooltip": "^4.2.21", "react-viewer": "^3.2.2", "react-virtualized-auto-sizer": "^1.0.6", diff --git a/yarn.lock b/yarn.lock index d9a6763a4a..fc5f8eabdf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2067,7 +2067,7 @@ __metadata: react-resize-detector: ^6.7.6 react-router: ^5.2.1 react-router-dom: ^5.3.0 - react-selecto: ^1.12.0 + react-selecto: ^1.18.2 react-tooltip: ^4.2.21 react-viewer: ^3.2.2 react-virtualized-auto-sizer: ^1.0.6 @@ -3591,13 +3591,13 @@ __metadata: languageName: node linkType: hard -"@scena/dragscroll@npm:^1.1.1": - version: 1.2.0 - resolution: "@scena/dragscroll@npm:1.2.0" +"@scena/dragscroll@npm:^1.2.1": + version: 1.2.1 + resolution: "@scena/dragscroll@npm:1.2.1" dependencies: "@daybrush/utils": 1.6.0 "@scena/event-emitter": ^1.0.2 - checksum: cac9db269d865a0acacf836327d26966d8acf10764bdeb52c4be5953797a805169dbcd6df15d090864046c6a2ed6bc49a0e22309b20e36dda8e73844e6833fa1 + checksum: 217b0612b0b5d2e721cd41b7534cc1b831aca236a4256b30bdeb965b3b0b7cf9f3934801a7158cb38483242e2568f8b734eeccfaee43b5df4e5df9ead7653dd5 languageName: node linkType: hard @@ -12711,13 +12711,13 @@ __metadata: languageName: node linkType: hard -"gesto@npm:^1.9.0": - version: 1.11.1 - resolution: "gesto@npm:1.11.1" +"gesto@npm:^1.11.1": + version: 1.12.1 + resolution: "gesto@npm:1.12.1" dependencies: "@daybrush/utils": ^1.7.1 "@scena/event-emitter": ^1.0.2 - checksum: cfd0c17bc84865f062b8ae03a99fe21373239a5e0a593d185a0d0713d3dc0ebf21738859b7473c7949ae9b79f40e02188d5c384656bab6932e439c380ed04a91 + checksum: e9b3f461e3ac05cc77187052660dbd0efa0aa7922bc650ced2d1d24ee77633046a92b8093eb584475bed1e3e82236999c86aef7007f949d55b4cce45c1d2bc5b languageName: node linkType: hard @@ -20475,12 +20475,12 @@ __metadata: languageName: node linkType: hard -"react-selecto@npm:^1.12.0": - version: 1.17.0 - resolution: "react-selecto@npm:1.17.0" +"react-selecto@npm:^1.18.2": + version: 1.18.2 + resolution: "react-selecto@npm:1.18.2" dependencies: - selecto: ~1.17.0 - checksum: 135bc3f9100a6631232b408ecb4ce008219ccce5b106ccc1cf03c7a0aba62cbe8bdf0427d88db5323988f181affc1635adb448f149eed93b7aa72d24c1a41e35 + selecto: ~1.18.2 + checksum: f1207f66b0a806e0129e9e611b720c160f5362a28cc9c381f8428fca0c4dc1df92a0a03c31f3b61a6c3de02f615eabbcf43cb785d908103548cc5ef3d1acda27 languageName: node linkType: hard @@ -21842,21 +21842,21 @@ __metadata: languageName: node linkType: hard -"selecto@npm:~1.17.0": - version: 1.17.0 - resolution: "selecto@npm:1.17.0" +"selecto@npm:~1.18.2": + version: 1.18.2 + resolution: "selecto@npm:1.18.2" dependencies: "@daybrush/utils": ^1.7.1 "@egjs/children-differ": ^1.0.1 - "@scena/dragscroll": ^1.1.1 + "@scena/dragscroll": ^1.2.1 "@scena/event-emitter": ^1.0.5 css-styled: ^1.0.0 css-to-mat: ^1.0.3 framework-utils: ^1.1.0 - gesto: ^1.9.0 + gesto: ^1.11.1 keycon: ^1.2.0 overlap-area: ^1.1.0 - checksum: ad288ee4be3bc2610925010a5a215370e0664f2075d7157ef2c020d08ac7244e9d6818fccb67998dbd655be8c5b9f2912cac329b8a9961787c9e86873adba47d + checksum: 192221746c8688c11e20ea1fc5918de8674e5eeba2b6d3a15324fb6befec3005abfaa42625eda36095f79df5bc76036576e8aa9a29a0a05476e1528666809b1e languageName: node linkType: hard From 1f2cceda94708bd5b0b9f70e17fe55364e05f180 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 22 Aug 2022 14:38:00 +0300 Subject: [PATCH 56/78] Web: Common: hidden Selecto for infinite scroll --- packages/common/components/Section/index.js | 2 +- .../common/components/Section/sub-components/section-body.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/common/components/Section/index.js b/packages/common/components/Section/index.js index a2dfa27a6c..f358d0e12e 100644 --- a/packages/common/components/Section/index.js +++ b/packages/common/components/Section/index.js @@ -502,7 +502,7 @@ class Section extends React.Component { return ( <> {renderSection()} - {!isMobile && uploadFiles && !dragging && ( + {!isMobile && uploadFiles && !dragging && withPaging && ( { - this.props.selectoRef.current.checkScroll(); + this.props.selectoRef.current && + this.props.selectoRef.current.checkScroll(); return e; }; From a748a372bbade335fe674c59efef86059b5d8e87 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 22 Aug 2022 17:21:01 +0300 Subject: [PATCH 57/78] Web: Files: fixed InfiniteLoaderComponent --- packages/components/infinite-loader/InfiniteLoader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/infinite-loader/InfiniteLoader.js b/packages/components/infinite-loader/InfiniteLoader.js index 6f44dd94f5..9d57698587 100644 --- a/packages/components/infinite-loader/InfiniteLoader.js +++ b/packages/components/infinite-loader/InfiniteLoader.js @@ -12,7 +12,7 @@ const InfiniteLoaderComponent = (props) => { ? document.querySelector("#customScrollBar > .scroll-body") : document.querySelector("#sectionScroll > .scroll-body"); - if (viewAs === "row") scroll.style.paddingRight = 0; + if (viewAs === "row" && scroll) scroll.style.paddingRight = 0; else scroll.style.paddingRight = isMobile() ? "8px" : "17px"; return viewAs === "tile" ? ( From d2035f16c358885b5a81b7dd4b196dc34ef5c7fc Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Mon, 22 Aug 2022 18:22:54 +0300 Subject: [PATCH 58/78] Web: Files: fixed hotkeys border, fixed caretIndex --- packages/client/src/HOCs/withFileActions.js | 3 ++- packages/client/src/store/HotkeyStore.js | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/client/src/HOCs/withFileActions.js b/packages/client/src/HOCs/withFileActions.js index 53fc855980..fd8605d678 100644 --- a/packages/client/src/HOCs/withFileActions.js +++ b/packages/client/src/HOCs/withFileActions.js @@ -331,7 +331,8 @@ export default function withFileActions(WrappedFileItem) { ) isActive = true; - const showHotkeyBorder = hotkeyCaret?.id === item.id; + const showHotkeyBorder = + hotkeyCaret?.id === item.id && hotkeyCaret?.isFolder === item.isFolder; return { t, diff --git a/packages/client/src/store/HotkeyStore.js b/packages/client/src/store/HotkeyStore.js index 9fe02d46c2..d225a22381 100644 --- a/packages/client/src/store/HotkeyStore.js +++ b/packages/client/src/store/HotkeyStore.js @@ -528,11 +528,14 @@ class HotkeyStore { get caretIndex() { const { filesList, hotkeyCaret, selection } = this.filesStore; - const id = + const item = selection.length && selection.length === 1 && !hotkeyCaret - ? selection[0].id - : hotkeyCaret?.id; - const caretIndex = filesList.findIndex((f) => f.id === id); + ? selection[0] + : hotkeyCaret; + + const caretIndex = filesList.findIndex( + (f) => f.id === item?.id && f.isFolder === item?.isFolder + ); if (caretIndex !== -1) return caretIndex; else return null; From c5171c01aa49c5b453c57d1c638d5ca946ecf452 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Tue, 23 Aug 2022 14:25:34 +0300 Subject: [PATCH 59/78] Web: Files: fixed filter pageCount --- packages/client/src/store/FilesStore.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index 622402c3b4..fd1e035f5b 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -681,7 +681,10 @@ class FilesStore { filterData.sortOrder = splitFilter[2]; } - if (!this.withPaging) filterData.page = 0; + if (!this.withPaging) { + filterData.page = 0; + filterData.pageCount = 100; + } setSelectedNode([folderId + ""]); From f37f355a41737d0b451dec96afa7777d06fcb0ea Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 24 Aug 2022 11:28:13 +0300 Subject: [PATCH 60/78] Web: Components: fixed renderRow --- packages/components/infinite-loader/List.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/infinite-loader/List.js b/packages/components/infinite-loader/List.js index 1dab53c80a..a153152938 100644 --- a/packages/components/infinite-loader/List.js +++ b/packages/components/infinite-loader/List.js @@ -26,7 +26,7 @@ const ListComponent = ({ }, [loaderRef, selectedFolderId, filesLength]); const renderRow = ({ key, index, style }) => { - const isLoaded = isItemLoaded({ index: index + 2 }); + const isLoaded = isItemLoaded({ index }); if (!isLoaded) return getLoader(style, key); return ( @@ -46,7 +46,7 @@ const ListComponent = ({ ? localStorage.getItem(columnInfoPanelStorageName) : localStorage.getItem(columnStorageName); - const isLoaded = isItemLoaded({ index: index + 2 }); + const isLoaded = isItemLoaded({ index }); if (!isLoaded) return getLoader(style, key); return ( @@ -116,7 +116,7 @@ const ListComponent = ({ height={height} onRowsRendered={onRowsRendered} ref={registerChild} - rowCount={children.length} + rowCount={hasMoreFiles ? children.length + 2 : children.length} rowHeight={itemSize} rowRenderer={viewAs === "table" ? renderTable : renderRow} width={width} From f8684c2cb4646da8ffc26699502fd860ae37b386 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 24 Aug 2022 14:05:40 +0300 Subject: [PATCH 61/78] Web: Files: Tiles: fixed Rooms --- .../Body/TilesView/sub-components/TileContainer.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js index 391b2e1c8d..c7c8340552 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/TileContainer.js @@ -206,14 +206,7 @@ class TileContainer extends React.PureComponent { ); } else if (isRoom) { Rooms.push( -
+
{item}
); @@ -238,7 +231,7 @@ class TileContainer extends React.PureComponent { )} - {Folders.length > 0 ? ( + {Rooms.length > 0 ? ( useReactWindow ? ( Rooms ) : ( From 814cb2c515bc5315eca34569bb557a5a1caa1c5f Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 24 Aug 2022 14:09:58 +0300 Subject: [PATCH 62/78] Web: Files: Tiles: fixed rooms styles --- .../TilesView/sub-components/InfiniteGrid.js | 37 ++++++++++++------- packages/components/infinite-loader/Grid.js | 7 +++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js index 1596aebd5f..4975aa3cac 100644 --- a/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js +++ b/packages/client/src/pages/Home/Section/Body/TilesView/sub-components/InfiniteGrid.js @@ -17,16 +17,21 @@ const Card = ({ children, ...rest }) => { const getItemSize = (child) => { const isFile = child?.props?.className?.includes("file"); const isFolder = child?.props?.className?.includes("folder"); + const isRoom = child?.props?.className?.includes("room"); const horizontalGap = 16; const verticalGap = 14; const headerMargin = 15; const folderHeight = 64 + verticalGap; + const roomHeight = 122 + verticalGap; const fileHeight = 220 + horizontalGap; const titleHeight = 20 + headerMargin; - return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; + if (isRoom) return roomHeight; + if (isFolder) return folderHeight; + if (isFile) return fileHeight; + return titleHeight; }; const cardHeight = getItemSize(children); @@ -73,11 +78,20 @@ const InfiniteGrid = (props) => { if (clear) cards = []; }; - const checkIsFolder = (useTempList = true) => { + const checkType = (useTempList = true) => { + const isFile = useTempList + ? cards.at(-1).props.children.props.className.includes("file") + : list.at(-1).props.className.includes("isFile"); + + if (isFile) return "isFile"; + const isFolder = useTempList ? cards.at(-1).props.children.props.className.includes("folder") : list.at(-1).props.className.includes("isFolder"); - return isFolder; + + if (isFolder) return "isFolder"; + + return "isRoom"; }; React.Children.map(children.props.children, (child) => { @@ -85,13 +99,9 @@ const InfiniteGrid = (props) => { if (child.props.className === "tile-items-heading") { // If cards is not empty then put the cards into the list if (cards.length) { - const isFolder = checkIsFolder(); + const type = checkType(); - addItemToList( - `last-item-of_${isFolder ? "folders" : "files"}`, - isFolder ? "isFolder" : "isFile", - true - ); + addItemToList(`last-item-of_${type}`, type, true); } list.push( @@ -104,7 +114,8 @@ const InfiniteGrid = (props) => { ); } else { const isFile = child?.props?.className?.includes("file"); - const className = isFile ? "isFile" : "isFolder"; + const isRoom = child?.props?.className?.includes("room"); + const className = isFile ? "isFile" : isRoom ? "isRoom" : "isFolder"; if (cards.length && cards.length === countTilesInRow) { const listKey = uniqueid("list-item_"); @@ -117,8 +128,8 @@ const InfiniteGrid = (props) => { } }); - const isFolder = checkIsFolder(!!cards.length); - const otherClassName = isFolder ? "isFolder" : "isFile"; + const type = checkType(!!cards.length); + const otherClassName = type; if (hasMoreFiles) { // If cards elements are full, it will add the full line of loaders @@ -133,7 +144,7 @@ const InfiniteGrid = (props) => { ); } diff --git a/packages/components/infinite-loader/Grid.js b/packages/components/infinite-loader/Grid.js index 5ecbb3ae7f..e610176ea0 100644 --- a/packages/components/infinite-loader/Grid.js +++ b/packages/components/infinite-loader/Grid.js @@ -39,6 +39,7 @@ const GridComponent = ({ const itemClassNames = children[index]?.props?.className; const isFile = itemClassNames?.includes("isFile"); const isFolder = itemClassNames?.includes("isFolder"); + const isRoom = itemClassNames?.includes("isRoom"); const isFolderHeader = itemClassNames?.includes("folder_header"); const horizontalGap = 16; @@ -46,10 +47,14 @@ const GridComponent = ({ const headerMargin = 15; const folderHeight = 64 + verticalGap; + const roomHeight = 122 + verticalGap; const fileHeight = 220 + horizontalGap; const titleHeight = 20 + headerMargin + (isFolderHeader ? 0 : 11); - return isFolder ? folderHeight : isFile ? fileHeight : titleHeight; + if (isRoom) return roomHeight; + if (isFolder) return folderHeight; + if (isFile) return fileHeight; + return titleHeight; }; return ( From b238de7746dae0d045b04d529810f1384d823524 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 24 Aug 2022 15:30:30 +0300 Subject: [PATCH 63/78] Web: Files: Scroll: fixed shared folder --- packages/client/src/store/FilesStore.js | 35 ++++++++++++++++++++----- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/client/src/store/FilesStore.js b/packages/client/src/store/FilesStore.js index fd1e035f5b..ad754c648f 100644 --- a/packages/client/src/store/FilesStore.js +++ b/packages/client/src/store/FilesStore.js @@ -572,6 +572,8 @@ class FilesStore { const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; localStorage.setItem(key, value); + if (!this.withPaging) filter.pageCount = 100; + this.setFilterUrl(filter, true); this.roomsFilter = filter; @@ -849,6 +851,11 @@ class FilesStore { filterData.sortOrder = splitFilter[2]; } + if (!this.withPaging) { + filterData.page = 0; + filterData.pageCount = 100; + } + if (folderId) setSelectedNode([folderId + ""]); const searchArea = folderId @@ -2525,12 +2532,21 @@ class FilesStore { this.trashIsEmpty = isEmpty; }; + get roomsFilterTotal() { + return this.roomsFilter.total; + } + get filterTotal() { return this.filter.total; } get hasMoreFiles() { - return this.filesList.length < this.filterTotal; + const { Shared, Archive } = CategoryType; + const isRoom = this.categoryType == Shared || this.categoryType == Archive; + + const filterTotal = isRoom ? this.roomsFilterTotal : this.filterTotal; + + return this.filesList.length < filterTotal; } setFilesIsLoading = (filesIsLoading) => { @@ -2540,13 +2556,20 @@ class FilesStore { fetchMoreFiles = async () => { if (!this.hasMoreFiles || this.filesIsLoading || this.isLoading) return; - this.setFilesIsLoading(true); - console.log("fetchMoreFiles"); + const { Shared, Archive } = CategoryType; + const isRoom = this.categoryType == Shared || this.categoryType == Archive; - const newFilter = this.filter.clone(); + this.setFilesIsLoading(true); + // console.log("fetchMoreFiles"); + + const newFilter = isRoom ? this.roomsFilter.clone() : this.filter.clone(); newFilter.page += 1; - this.setFilter(newFilter); - const newFiles = await api.files.getFolder(newFilter.folder, newFilter); + if (isRoom) this.setRoomsFilter(newFilter); + else this.setFilter(newFilter); + + const newFiles = isRoom + ? await api.rooms.getRooms(newFilter) + : await api.files.getFolder(newFilter.folder, newFilter); runInAction(() => { this.setFiles([...this.files, ...newFiles.files]); From 4d38717656a0a26d85fd248f6ed1225f560e82d6 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 24 Aug 2022 17:29:28 +0300 Subject: [PATCH 64/78] Web: Files: Table: fixed rooms itemHeight --- .../src/pages/Home/Section/Body/TableView/TableContainer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js index f7eba972bf..84738b5391 100644 --- a/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js +++ b/packages/client/src/pages/Home/Section/Body/TableView/TableContainer.js @@ -209,6 +209,7 @@ const Table = ({ infoPanelVisible={infoPanelVisible} columnInfoPanelStorageName={columnInfoPanelStorageName} selectedFolderId={selectedFolderId} + itemHeight={isRooms ? 49 : 41} > {filesList.map((item, index) => { return index === 0 && item.isRoom ? ( From 04fb7ade63199fe4ae0601ac826562e83d4ab735 Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Thu, 25 Aug 2022 10:54:04 +0300 Subject: [PATCH 65/78] Web: People: fixed row styles --- .../common/components/Section/sub-components/section-body.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/common/components/Section/sub-components/section-body.js b/packages/common/components/Section/sub-components/section-body.js index f42832e5cc..31be2548be 100644 --- a/packages/common/components/Section/sub-components/section-body.js +++ b/packages/common/components/Section/sub-components/section-body.js @@ -283,6 +283,7 @@ class SectionBody extends React.Component { isLoaded={isLoaded} isDesktop={isDesktop} settingsStudio={settingsStudio} + withPaging={withPaging} > {withScroll ? ( !isMobileOnly ? ( From 1be967fe3f53545dfd19b2ef885390be60a3a401 Mon Sep 17 00:00:00 2001 From: MaksimChegulov Date: Fri, 26 Aug 2022 13:07:27 +0300 Subject: [PATCH 66/78] Files: added id conversion in base64 string --- .../Core/Thirdparty/Sharpbox/SharpBoxDaoBase.cs | 13 +++++++++++-- products/ASC.Files/Core/GlobalUsings.cs | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxDaoBase.cs b/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxDaoBase.cs index 9c83a7310b..0b4b48e037 100644 --- a/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxDaoBase.cs +++ b/products/ASC.Files/Core/Core/Thirdparty/Sharpbox/SharpBoxDaoBase.cs @@ -219,7 +219,16 @@ internal abstract class SharpBoxDaoBase : ThirdPartyProviderDao Date: Fri, 26 Aug 2022 13:08:03 +0300 Subject: [PATCH 67/78] Files: fix rename for SharpBox, SharePoint providers --- .../ASC.Files/Server/Helpers/FilesControllerHelper.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/products/ASC.Files/Server/Helpers/FilesControllerHelper.cs b/products/ASC.Files/Server/Helpers/FilesControllerHelper.cs index d74614ae8f..8dcdefd9b6 100644 --- a/products/ASC.Files/Server/Helpers/FilesControllerHelper.cs +++ b/products/ASC.Files/Server/Helpers/FilesControllerHelper.cs @@ -235,17 +235,20 @@ public class FilesControllerHelper : FilesHelperBase public async Task> UpdateFileAsync(T fileId, string title, int lastVersion) { + File file = null; + if (!string.IsNullOrEmpty(title)) { - await _fileStorageService.FileRenameAsync(fileId, title); + file = await _fileStorageService.FileRenameAsync(fileId, title); } if (lastVersion > 0) { - await _fileStorageService.UpdateToVersionAsync(fileId, lastVersion); + var result = await _fileStorageService.UpdateToVersionAsync(fileId, lastVersion); + file = result.Key; } - return await GetFileInfoAsync(fileId); + return await GetFileInfoAsync(file.Id); } public async Task> UpdateFileStreamAsync(Stream file, T fileId, string fileExtension, bool encrypted = false, bool forcesave = false) From 4797576a0c4910a16d5edf157f06f1636bf98a5b Mon Sep 17 00:00:00 2001 From: MaksimChegulov Date: Fri, 26 Aug 2022 13:54:22 +0300 Subject: [PATCH 68/78] Files: fix open in editor --- products/ASC.Files/Core/Utils/FileShareLink.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/products/ASC.Files/Core/Utils/FileShareLink.cs b/products/ASC.Files/Core/Utils/FileShareLink.cs index 76fe7640fd..b349e7bb61 100644 --- a/products/ASC.Files/Core/Utils/FileShareLink.cs +++ b/products/ASC.Files/Core/Utils/FileShareLink.cs @@ -111,7 +111,14 @@ public class FileShareLink } var fileId = Parse(doc); - var file = await fileDao.GetFileAsync(fileId); + + File file = null; + + if (!EqualityComparer.Default.Equals(fileId, default(T))) + { + file = await fileDao.GetFileAsync(fileId); + } + if (file == null) { return (FileShare.Restrict, file); From a8972c7cba6246da377e763ce24eb532494f0a9d Mon Sep 17 00:00:00 2001 From: MaksimChegulov Date: Mon, 29 Aug 2022 10:47:54 +0300 Subject: [PATCH 69/78] Files: fix rooms sorting --- products/ASC.Files/Core/Utils/EntryManager.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/products/ASC.Files/Core/Utils/EntryManager.cs b/products/ASC.Files/Core/Utils/EntryManager.cs index a624510822..08fbd0ea57 100644 --- a/products/ASC.Files/Core/Utils/EntryManager.cs +++ b/products/ASC.Files/Core/Utils/EntryManager.cs @@ -955,6 +955,7 @@ public class EntryManager var folders = entries.Where(r => r.FileEntryType == FileEntryType.Folder).Except(pinnedRooms).Except(rooms); var files = entries.Where(r => r.FileEntryType == FileEntryType.File); pinnedRooms = pinnedRooms.OrderBy(r => r, comparer); + rooms = rooms.OrderBy(r => r, comparer); folders = folders.OrderBy(r => r, comparer); files = files.OrderBy(r => r, comparer); From ab654bc8896fd19eb879b18b9d1e03f6336e32ec Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Mon, 29 Aug 2022 11:33:52 +0300 Subject: [PATCH 70/78] Web: Fix same key duplication warning --- .../client/src/components/GlobalEvents/sub-components/Dialog.js | 2 +- .../client/src/components/dialogs/ChangeEmailDialog/index.js | 2 +- .../client/src/components/dialogs/ChangePasswordDialog/index.js | 2 +- .../client/src/components/dialogs/ChangePhoneDialog/index.js | 2 +- .../src/components/dialogs/DeleteSelfProfileDialog/index.js | 2 +- .../src/components/dialogs/ResetApplicationDialog/index.js | 2 +- .../login/src/sub-components/forgot-password-modal-dialog.js | 2 +- .../login/src/sub-components/recover-access-modal-dialog.js | 2 +- packages/login/src/sub-components/register-modal-dialog.js | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/client/src/components/GlobalEvents/sub-components/Dialog.js b/packages/client/src/components/GlobalEvents/sub-components/Dialog.js index 8be0dddbd5..ee4a0b4bdd 100644 --- a/packages/client/src/components/GlobalEvents/sub-components/Dialog.js +++ b/packages/client/src/components/GlobalEvents/sub-components/Dialog.js @@ -86,7 +86,7 @@ const Dialog = ({