From be1277d8b4dc597dcd1b75642158d7aaaf7e7ed7 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 8 Feb 2022 15:11:31 +0300 Subject: [PATCH 01/81] addoed structure --- .../components/PageLayout/index.js | 1047 +++++++------- .../sub-components/notifications-body.js | 11 + .../sub-components/notifications.js | 16 + .../sub-components/section-header.js | 271 ++-- .../public/static/images/panel.react.svg | 3 + .../pages/Home/Notifications/Body/index.js | 12 + .../src/pages/Home/Notifications/index.js | 1 + .../src/pages/Home/Section/Header/index.js | 1213 +++++++++-------- .../ASC.Files/Client/src/pages/Home/index.js | 816 +++++------ .../Client/src/store/NotificationsStore.js | 15 + products/ASC.Files/Client/src/store/index.js | 126 +- 11 files changed, 1866 insertions(+), 1665 deletions(-) create mode 100644 packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js create mode 100644 packages/asc-web-common/components/PageLayout/sub-components/notifications.js create mode 100644 packages/asc-web-components/public/static/images/panel.react.svg create mode 100644 products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js create mode 100644 products/ASC.Files/Client/src/pages/Home/Notifications/index.js create mode 100644 products/ASC.Files/Client/src/store/NotificationsStore.js diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 1ae88c04ef..694c42534d 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -1,532 +1,597 @@ -import React from "react"; -import PropTypes from "prop-types"; import Backdrop from "@appserver/components/backdrop"; -import { desktop, size, tablet } from "@appserver/components/utils/device"; import { Provider } from "@appserver/components/utils/context"; -import { isMobile, isFirefox, isMobileOnly } from "react-device-detect"; -import Article from "./sub-components/article"; -import SubArticleHeader from "./sub-components/article-header"; -import SubArticleMainButton from "./sub-components/article-main-button"; -import SubArticleBody from "./sub-components/article-body"; -import ArticlePinPanel from "./sub-components/article-pin-panel"; -import Section from "./sub-components/section"; -import SubSectionHeader from "./sub-components/section-header"; -import SubSectionFilter from "./sub-components/section-filter"; -import SubSectionBody from "./sub-components/section-body"; -import SubSectionBodyContent from "./sub-components/section-body-content"; -import SubSectionPaging from "./sub-components/section-paging"; -import SectionToggler from "./sub-components/section-toggler"; -import ReactResizeDetector from "react-resize-detector"; -import FloatingButton from "../FloatingButton"; +import { desktop, size, tablet } from "@appserver/components/utils/device"; import { inject, observer } from "mobx-react"; +import PropTypes from "prop-types"; +import React from "react"; +import { isFirefox, isMobile, isMobileOnly } from "react-device-detect"; +import ReactResizeDetector from "react-resize-detector"; import Selecto from "react-selecto"; import styled, { css } from "styled-components"; +import FloatingButton from "../FloatingButton"; +import Article from "./sub-components/article"; +import SubArticleBody from "./sub-components/article-body"; +import SubArticleHeader from "./sub-components/article-header"; +import SubArticleMainButton from "./sub-components/article-main-button"; +import ArticlePinPanel from "./sub-components/article-pin-panel"; +import Notifications from "./sub-components/notifications"; +import SubNotificationsBody from "./sub-components/notifications-body"; +import Section from "./sub-components/section"; +import SubSectionBody from "./sub-components/section-body"; +import SubSectionBodyContent from "./sub-components/section-body-content"; +import SubSectionFilter from "./sub-components/section-filter"; +import SubSectionHeader from "./sub-components/section-header"; +import SubSectionPaging from "./sub-components/section-paging"; +import SectionToggler from "./sub-components/section-toggler"; + const StyledSelectoWrapper = styled.div` - .selecto-selection { - z-index: 200; - } + .selecto-selection { + z-index: 200; + } `; const StyledMainBar = styled.div` - box-sizing: border-box; + box-sizing: border-box; - ${!isMobile - ? css` - padding-right: 24px; - @media ${tablet} { - padding-right: 16px; - } - ` - : css` - margin-top: 10px; - padding-right: 0px; + ${!isMobile + ? css` + padding-right: 24px; + @media ${tablet} { + padding-right: 16px; + } + ` + : css` + margin-top: 10px; + padding-right: 0px; - @media ${desktop} { - padding-right: 10px; - } - `} + @media ${desktop} { + padding-right: 10px; + } + `} `; function ArticleHeader() { - return null; + return null; } ArticleHeader.displayName = "ArticleHeader"; function ArticleMainButton() { - return null; + return null; } ArticleMainButton.displayName = "ArticleMainButton"; function ArticleBody() { - return null; + return null; } ArticleBody.displayName = "ArticleBody"; function SectionHeader() { - return null; + return null; } SectionHeader.displayName = "SectionHeader"; function SectionFilter() { - return null; + return null; } SectionFilter.displayName = "SectionFilter"; function SectionBody() { - return null; + return null; } SectionBody.displayName = "SectionBody"; function SectionPaging() { - return null; + return null; } SectionPaging.displayName = "SectionPaging"; +function NotificationsBody() { + return null; +} +NotificationsBody.displayName = "NotificationsBody"; + class PageLayout extends React.Component { - static ArticleHeader = ArticleHeader; - static ArticleMainButton = ArticleMainButton; - static ArticleBody = ArticleBody; - static SectionHeader = SectionHeader; - static SectionFilter = SectionFilter; - static SectionBody = SectionBody; - static SectionPaging = SectionPaging; + static ArticleHeader = ArticleHeader; + static ArticleMainButton = ArticleMainButton; + static ArticleBody = ArticleBody; + static SectionHeader = SectionHeader; + static SectionFilter = SectionFilter; + static SectionBody = SectionBody; + static SectionPaging = SectionPaging; + static NotificationsBody = NotificationsBody; - constructor(props) { - super(props); + constructor(props) { + super(props); - this.timeoutHandler = null; - this.intervalHandler = null; + this.timeoutHandler = null; + this.intervalHandler = null; - this.scroll = null; - } - - componentDidUpdate(prevProps) { - if (!this.scroll) { - this.scroll = document.getElementsByClassName("section-scroll")[0]; + this.scroll = null; } - if ( - this.props.hideAside && - !this.props.isArticlePinned && - this.props.hideAside !== prevProps.hideAside - ) { - this.backdropClick(); + componentDidUpdate(prevProps) { + if (!this.scroll) { + this.scroll = document.getElementsByClassName("section-scroll")[0]; + } + + if ( + this.props.hideAside && + !this.props.isArticlePinned && + this.props.hideAside !== prevProps.hideAside + ) { + this.backdropClick(); + } } - } - componentDidMount() { - window.addEventListener("orientationchange", this.orientationChangeHandler); + componentDidMount() { + window.addEventListener( + "orientationchange", + this.orientationChangeHandler + ); - this.orientationChangeHandler(); - } - - componentWillUnmount() { - window.removeEventListener( - "orientationchange", - this.orientationChangeHandler - ); - - if (this.intervalHandler) clearInterval(this.intervalHandler); - if (this.timeoutHandler) clearTimeout(this.timeoutHandler); - } - - orientationChangeHandler = () => { - const isValueExist = !!this.props.isArticlePinned; - const isEnoughWidth = screen.availWidth > size.smallTablet; - const isPortrait = - isFirefox && - isMobileOnly && - screen.orientation.type === "portrait-primary"; - - if ((!isEnoughWidth && isValueExist) || isPortrait) { - this.backdropClick(); - return; + this.orientationChangeHandler(); } - if (isEnoughWidth && isValueExist) { - this.pinArticle(); + + componentWillUnmount() { + window.removeEventListener( + "orientationchange", + this.orientationChangeHandler + ); + + if (this.intervalHandler) clearInterval(this.intervalHandler); + if (this.timeoutHandler) clearTimeout(this.timeoutHandler); } - }; - backdropClick = () => { - this.props.setArticlePinned(false); - this.props.setIsBackdropVisible(false); - this.props.setIsArticleVisible(false); - isMobile && this.props.setArticleVisibleOnUnpin(false); - }; + orientationChangeHandler = () => { + const isValueExist = !!this.props.isArticlePinned; + const isEnoughWidth = screen.availWidth > size.smallTablet; + const isPortrait = + isFirefox && + isMobileOnly && + screen.orientation.type === "portrait-primary"; - pinArticle = () => { - this.props.setIsBackdropVisible(false); - this.props.setIsArticleVisible(true); - this.props.setArticlePinned(true); - isMobile && this.props.setArticleVisibleOnUnpin(false); - }; - - unpinArticle = () => { - this.props.setIsBackdropVisible(true); - this.props.setIsArticleVisible(true); - this.props.setArticlePinned(false); - isMobile && this.props.setArticleVisibleOnUnpin(true); - }; - - showArticle = () => { - this.props.setArticlePinned(false); - this.props.setIsBackdropVisible(true); - this.props.setIsArticleVisible(true); - isMobile && this.props.setArticleVisibleOnUnpin(true); - }; - - onSelect = (e) => { - if (this.props.dragging) return; - const items = e.selected; - this.props.setSelections(items); - }; - - dragCondition = (e) => { - const path = e.inputEvent.composedPath(); - const isBackdrop = path.some( - (x) => x.classList && x.classList.contains("backdrop-active") - ); - const notSelectablePath = path.some( - (x) => x.classList && x.classList.contains("not-selectable") - ); - - const isDraggable = path.some( - (x) => x.classList && x.classList.contains("draggable") - ); - - if (notSelectablePath || isBackdrop || isDraggable) { - return false; - } else return true; - }; - - onScroll = (e) => { - this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10); - }; - - render() { - const { - onDrop, - showPrimaryProgressBar, - primaryProgressBarIcon, - primaryProgressBarValue, - showPrimaryButtonAlert, - showSecondaryProgressBar, - secondaryProgressBarValue, - secondaryProgressBarIcon, - showSecondaryButtonAlert, - uploadFiles, - viewAs, - //withBodyAutoFocus, - withBodyScroll, - children, - isHeaderVisible, - //headerBorderBottom, - onOpenUploadPanel, - isTabletView, - firstLoad, - dragging, - isArticleVisible, - isBackdropVisible, - isArticlePinned, - isDesktop, - } = this.props; - let articleHeaderContent = null; - let articleMainButtonContent = null; - let articleBodyContent = null; - let sectionHeaderContent = null; - let sectionFilterContent = null; - let sectionPagingContent = null; - let sectionBodyContent = null; - - React.Children.forEach(children, (child) => { - const childType = - child && child.type && (child.type.displayName || child.type.name); - - switch (childType) { - case ArticleHeader.displayName: - articleHeaderContent = child; - break; - case ArticleMainButton.displayName: - articleMainButtonContent = child; - break; - case ArticleBody.displayName: - articleBodyContent = child; - break; - case SectionHeader.displayName: - sectionHeaderContent = child; - break; - case SectionFilter.displayName: - sectionFilterContent = child; - break; - case SectionPaging.displayName: - sectionPagingContent = child; - break; - case SectionBody.displayName: - sectionBodyContent = child; - break; - default: - break; - } - }); - - const isArticleHeaderAvailable = !!articleHeaderContent, - isArticleMainButtonAvailable = !!articleMainButtonContent, - isArticleBodyAvailable = !!articleBodyContent, - isArticleAvailable = - isArticleHeaderAvailable || - isArticleMainButtonAvailable || - isArticleBodyAvailable, - isSectionHeaderAvailable = !!sectionHeaderContent, - isSectionFilterAvailable = !!sectionFilterContent, - isSectionPagingAvailable = !!sectionPagingContent, - isSectionBodyAvailable = - !!sectionBodyContent || - isSectionFilterAvailable || - isSectionPagingAvailable, - isSectionAvailable = - isSectionHeaderAvailable || - isSectionFilterAvailable || - isSectionBodyAvailable || - isSectionPagingAvailable || - isArticleAvailable, - isBackdropAvailable = isArticleAvailable; - - const renderPageLayout = () => { - return ( - <> - {isBackdropAvailable && ( - - )} - {isArticleAvailable && ( -
- {isArticleHeaderAvailable && ( - - {articleHeaderContent - ? articleHeaderContent.props.children - : null} - - )} - {isArticleMainButtonAvailable && ( - - {articleMainButtonContent - ? articleMainButtonContent.props.children - : null} - - )} - {isArticleBodyAvailable && ( - - {articleBodyContent - ? articleBodyContent.props.children - : null} - - )} - {isArticleBodyAvailable && ( - - )} -
- )} - {isSectionAvailable && ( - - {({ width, height }) => ( - -
- {isSectionHeaderAvailable && ( - - {sectionHeaderContent - ? sectionHeaderContent.props.children - : null} - - )} - - {isSectionFilterAvailable && ( - <> - - - {sectionFilterContent - ? sectionFilterContent.props.children - : null} - - - )} - {isSectionBodyAvailable && ( - <> - - {isSectionFilterAvailable && ( - - {sectionFilterContent - ? sectionFilterContent.props.children - : null} - - )} - - {sectionBodyContent - ? sectionBodyContent.props.children - : null} - - {isSectionPagingAvailable && ( - - {sectionPagingContent - ? sectionPagingContent.props.children - : null} - - )} - - - )} - - {showPrimaryProgressBar && showSecondaryProgressBar ? ( - <> - - - - ) : showPrimaryProgressBar && !showSecondaryProgressBar ? ( - - ) : !showPrimaryProgressBar && showSecondaryProgressBar ? ( - - ) : ( - <> - )} - - {isArticleAvailable && ( - - )} -
-
- )} -
- )} - - ); + if ((!isEnoughWidth && isValueExist) || isPortrait) { + this.backdropClick(); + return; + } + if (isEnoughWidth && isValueExist) { + this.pinArticle(); + } }; - const scrollOptions = this.scroll - ? { - container: this.scroll, - throttleTime: 0, - threshold: 100, - } - : {}; + backdropClick = () => { + this.props.setArticlePinned(false); + this.props.setIsBackdropVisible(false); + this.props.setIsArticleVisible(false); + isMobile && this.props.setArticleVisibleOnUnpin(false); + }; - return ( - <> - {renderPageLayout()} - {!isMobile && uploadFiles && !dragging && ( - - - - )} - - ); - } + pinArticle = () => { + this.props.setIsBackdropVisible(false); + this.props.setIsArticleVisible(true); + this.props.setArticlePinned(true); + isMobile && this.props.setArticleVisibleOnUnpin(false); + }; + + unpinArticle = () => { + this.props.setIsBackdropVisible(true); + this.props.setIsArticleVisible(true); + this.props.setArticlePinned(false); + isMobile && this.props.setArticleVisibleOnUnpin(true); + }; + + showArticle = () => { + this.props.setArticlePinned(false); + this.props.setIsBackdropVisible(true); + this.props.setIsArticleVisible(true); + isMobile && this.props.setArticleVisibleOnUnpin(true); + }; + + onSelect = (e) => { + if (this.props.dragging) return; + const items = e.selected; + this.props.setSelections(items); + }; + + dragCondition = (e) => { + const path = e.inputEvent.composedPath(); + const isBackdrop = path.some( + (x) => x.classList && x.classList.contains("backdrop-active") + ); + const notSelectablePath = path.some( + (x) => x.classList && x.classList.contains("not-selectable") + ); + + const isDraggable = path.some( + (x) => x.classList && x.classList.contains("draggable") + ); + + if (notSelectablePath || isBackdrop || isDraggable) { + return false; + } else return true; + }; + + onScroll = (e) => { + this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10); + }; + + render() { + const { + onDrop, + showPrimaryProgressBar, + primaryProgressBarIcon, + primaryProgressBarValue, + showPrimaryButtonAlert, + showSecondaryProgressBar, + secondaryProgressBarValue, + secondaryProgressBarIcon, + showSecondaryButtonAlert, + uploadFiles, + viewAs, + //withBodyAutoFocus, + withBodyScroll, + children, + isHeaderVisible, + //headerBorderBottom, + onOpenUploadPanel, + isTabletView, + firstLoad, + dragging, + isArticleVisible, + isBackdropVisible, + isArticlePinned, + isDesktop, + } = this.props; + let articleHeaderContent = null; + let articleMainButtonContent = null; + let articleBodyContent = null; + let sectionHeaderContent = null; + let sectionFilterContent = null; + let sectionPagingContent = null; + let sectionBodyContent = null; + let notificationsBodyContent = null; + + React.Children.forEach(children, (child) => { + const childType = + child && + child.type && + (child.type.displayName || child.type.name); + + switch (childType) { + case ArticleHeader.displayName: + articleHeaderContent = child; + break; + case ArticleMainButton.displayName: + articleMainButtonContent = child; + break; + case ArticleBody.displayName: + articleBodyContent = child; + break; + case SectionHeader.displayName: + sectionHeaderContent = child; + break; + case SectionFilter.displayName: + sectionFilterContent = child; + break; + case SectionPaging.displayName: + sectionPagingContent = child; + break; + case SectionBody.displayName: + sectionBodyContent = child; + break; + case NotificationsBody.displayName: + notificationsBodyContent = child; + console.log(notificationsBodyContent); + break; + default: + break; + } + }); + + const isArticleHeaderAvailable = !!articleHeaderContent, + isArticleMainButtonAvailable = !!articleMainButtonContent, + isArticleBodyAvailable = !!articleBodyContent, + isArticleAvailable = + isArticleHeaderAvailable || + isArticleMainButtonAvailable || + isArticleBodyAvailable, + isSectionHeaderAvailable = !!sectionHeaderContent, + isSectionFilterAvailable = !!sectionFilterContent, + isSectionPagingAvailable = !!sectionPagingContent, + isSectionBodyAvailable = + !!sectionBodyContent || + isSectionFilterAvailable || + isSectionPagingAvailable, + isSectionAvailable = + isSectionHeaderAvailable || + isSectionFilterAvailable || + isSectionBodyAvailable || + isSectionPagingAvailable || + isArticleAvailable, + isBackdropAvailable = isArticleAvailable; + + const renderPageLayout = () => { + return ( + <> + {isBackdropAvailable && ( + + )} + {isArticleAvailable && ( +
+ {isArticleHeaderAvailable && ( + + {articleHeaderContent + ? articleHeaderContent.props.children + : null} + + )} + {isArticleMainButtonAvailable && ( + + {articleMainButtonContent + ? articleMainButtonContent.props + .children + : null} + + )} + {isArticleBodyAvailable && ( + + {articleBodyContent + ? articleBodyContent.props.children + : null} + + )} + {isArticleBodyAvailable && ( + + )} +
+ )} + {isSectionAvailable && ( + + {({ width, height }) => ( + +
+ {isSectionHeaderAvailable && ( + + {sectionHeaderContent + ? sectionHeaderContent.props + .children + : null} + + )} + {isSectionFilterAvailable && ( + <> + + + {sectionFilterContent + ? sectionFilterContent + .props.children + : null} + + + )} + + {isSectionBodyAvailable && ( + <> + + {isSectionFilterAvailable && ( + + {sectionFilterContent + ? sectionFilterContent + .props + .children + : null} + + )} + + {sectionBodyContent + ? sectionBodyContent + .props + .children + : null} + + {isSectionPagingAvailable && ( + + {sectionPagingContent + ? sectionPagingContent + .props + .children + : null} + + )} + + + )} + {showPrimaryProgressBar && + showSecondaryProgressBar ? ( + <> + + + + ) : showPrimaryProgressBar && + !showSecondaryProgressBar ? ( + + ) : !showPrimaryProgressBar && + showSecondaryProgressBar ? ( + + ) : ( + <> + )} + + {isArticleAvailable && ( + + )} +
+ + + {notificationsBodyContent} + + +
+ )} +
+ )} + + ); + }; + + const scrollOptions = this.scroll + ? { + container: this.scroll, + throttleTime: 0, + threshold: 100, + } + : {}; + + return ( + <> + {renderPageLayout()} + {!isMobile && uploadFiles && !dragging && ( + + + + )} + + ); + } } PageLayout.propTypes = { - children: PropTypes.any, - withBodyScroll: PropTypes.bool, - withBodyAutoFocus: PropTypes.bool, - showPrimaryProgressBar: PropTypes.bool, - primaryProgressBarValue: PropTypes.number, - showPrimaryButtonAlert: PropTypes.bool, - progressBarDropDownContent: PropTypes.any, - primaryProgressBarIcon: PropTypes.string, - showSecondaryProgressBar: PropTypes.bool, - secondaryProgressBarValue: PropTypes.number, - secondaryProgressBarIcon: PropTypes.string, - showSecondaryButtonAlert: PropTypes.bool, - onDrop: PropTypes.func, - setSelections: PropTypes.func, - uploadFiles: PropTypes.bool, - hideAside: PropTypes.bool, - viewAs: PropTypes.string, - uploadPanelVisible: PropTypes.bool, - onOpenUploadPanel: PropTypes.func, - isTabletView: PropTypes.bool, - isHeaderVisible: PropTypes.bool, - firstLoad: PropTypes.bool, + children: PropTypes.any, + withBodyScroll: PropTypes.bool, + withBodyAutoFocus: PropTypes.bool, + showPrimaryProgressBar: PropTypes.bool, + primaryProgressBarValue: PropTypes.number, + showPrimaryButtonAlert: PropTypes.bool, + progressBarDropDownContent: PropTypes.any, + primaryProgressBarIcon: PropTypes.string, + showSecondaryProgressBar: PropTypes.bool, + secondaryProgressBarValue: PropTypes.number, + secondaryProgressBarIcon: PropTypes.string, + showSecondaryButtonAlert: PropTypes.bool, + onDrop: PropTypes.func, + setSelections: PropTypes.func, + uploadFiles: PropTypes.bool, + hideAside: PropTypes.bool, + viewAs: PropTypes.string, + uploadPanelVisible: PropTypes.bool, + onOpenUploadPanel: PropTypes.func, + isTabletView: PropTypes.bool, + isHeaderVisible: PropTypes.bool, + firstLoad: PropTypes.bool, }; PageLayout.defaultProps = { - withBodyScroll: true, - withBodyAutoFocus: false, + withBodyScroll: true, + withBodyAutoFocus: false, }; PageLayout.ArticleHeader = ArticleHeader; @@ -538,31 +603,31 @@ PageLayout.SectionBody = SectionBody; PageLayout.SectionPaging = SectionPaging; export default inject(({ auth }) => { - const { isLoaded, settingsStore } = auth; - const { - isHeaderVisible, - isTabletView, - isArticlePinned, - isArticleVisible, - isBackdropVisible, - setArticlePinned, - setArticleVisibleOnUnpin, - setIsArticleVisible, - setIsBackdropVisible, - isDesktopClient, - } = settingsStore; + const { isLoaded, settingsStore } = auth; + const { + isHeaderVisible, + isTabletView, + isArticlePinned, + isArticleVisible, + isBackdropVisible, + setArticlePinned, + setArticleVisibleOnUnpin, + setIsArticleVisible, + setIsBackdropVisible, + isDesktopClient, + } = settingsStore; - return { - isLoaded, - isTabletView, - isHeaderVisible, - isArticlePinned, - isArticleVisible, - setArticlePinned, - setArticleVisibleOnUnpin, - setIsArticleVisible, - isBackdropVisible, - setIsBackdropVisible, - isDesktop: isDesktopClient, - }; + return { + isLoaded, + isTabletView, + isHeaderVisible, + isArticlePinned, + isArticleVisible, + setArticlePinned, + setArticleVisibleOnUnpin, + setIsArticleVisible, + isBackdropVisible, + setIsBackdropVisible, + isDesktop: isDesktopClient, + }; })(observer(PageLayout)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js b/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js new file mode 100644 index 0000000000..5f36cb884a --- /dev/null +++ b/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js @@ -0,0 +1,11 @@ +import { inject, observer } from "mobx-react"; +import React from "react"; + +const SubNotificationsBody = ({ children }) => { + console.log("SNB - ", children); + return {children}; +}; + +export default inject(() => { + return {}; +})(observer(SubNotificationsBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/notifications.js b/packages/asc-web-common/components/PageLayout/sub-components/notifications.js new file mode 100644 index 0000000000..03487ff8b3 --- /dev/null +++ b/packages/asc-web-common/components/PageLayout/sub-components/notifications.js @@ -0,0 +1,16 @@ +import React from "react"; +import styled from "styled-components"; + +const Notifications = ({ children }) => { + const StyledNotifications = styled.div` + height: 100%; + width: 400px; + background-color: red; + `; + + console.log("N - ", children); + + return {children}; +}; + +export default Notifications; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/section-header.js b/packages/asc-web-common/components/PageLayout/sub-components/section-header.js index e35e1ea3ae..fcf3ea9ae8 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/section-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/section-header.js @@ -1,152 +1,165 @@ -import React from "react"; -import styled, { css } from "styled-components"; -import equal from "fast-deep-equal/react"; -import classnames from "classnames"; -import PropTypes from "prop-types"; -import { LayoutContextConsumer } from "studio/Layout/context"; -import { isMobile } from "react-device-detect"; -import { tablet, desktop } from "@appserver/components/utils/device"; import NoUserSelect from "@appserver/components/utils/commonStyles"; -const StyledSectionHeader = styled.div` - height: 42px; - margin-right: 24px; - ${NoUserSelect} - ${isMobile && - css` - height: 20px; - width: ${(props) => !props.isLoaded && "100%"}; +import { desktop, tablet } from "@appserver/components/utils/device"; +import classnames from "classnames"; +import equal from "fast-deep-equal/react"; +import PropTypes from "prop-types"; +import React from "react"; +import { isMobile } from "react-device-detect"; +import { LayoutContextConsumer } from "studio/Layout/context"; +import styled, { css } from "styled-components"; - margin-top: 62px; - @media ${tablet} { - margin-top: 48px; - } - `} +const StyledSectionHeader = styled.div` + height: 42px; + margin-right: 24px; + ${NoUserSelect} + ${isMobile && + css` + height: 20px; + width: ${(props) => !props.isLoaded && "100%"}; + + margin-top: 62px; + @media ${tablet} { + margin-top: 48px; + } + `} @media ${desktop} { - ${(props) => - (props.viewAs === "table" || props.viewAs === "tile") && - "margin-left: -4px"}; - } - - @media ${tablet} { - ${(props) => - props.viewAs !== "tablet" && - css` - height: 49px; - - .arrow-button { - svg { - width: 14px !important; - } - margin-right: 10px !important; - } - `} - } - - @media ${tablet} { - margin-right: 16px; - } - - .section-header { - height: 50px; - ${isMobile && - css` - max-width: calc(100vw - 32px); - width: 100%; - `} - - ${isMobile && - css` - position: fixed; - top: 48px; - - width: ${(props) => - props.isArticlePinned ? `calc(100% - 272px)` : "100%"}; - - background-color: #fff; - z-index: 149; - padding-right: 16px; - `} - } - ${isMobile && - css` - .section-header, - .section-header--hidden { - &, - .group-button-menu-container > div:first-child { - transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - } - .group-button-menu-container { - padding-bottom: 0 !important; - > div:first-child { - top: ${(props) => - !props.isSectionHeaderVisible ? "56px" : "0px"} !important; - - @media ${desktop} { - ${isMobile && - css` - position: absolute; - `} - } - } - } + ${(props) => + (props.viewAs === "table" || props.viewAs === "tile") && + "margin-left: -4px"}; + } + + @media ${tablet} { + ${(props) => + props.viewAs !== "tablet" && + css` + height: 49px; + + .arrow-button { + svg { + width: 14px !important; + } + margin-right: 10px !important; + } + `} + } + + @media ${tablet} { + margin-right: 16px; + } + + .section-header { + height: 50px; + ${isMobile && + css` + max-width: calc(100vw - 32px); + width: 100%; + `} + + ${isMobile && + css` + position: fixed; + top: 48px; + + width: ${(props) => + props.isArticlePinned ? `calc(100% - 272px)` : "100%"}; + + background-color: #fff; + z-index: 149; + padding-right: 16px; + `} } - `} - .section-header--hidden { ${isMobile && css` - top: -61px; + .section-header, + .section-header--hidden { + &, + .group-button-menu-container > div:first-child { + transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + } + .group-button-menu-container { + padding-bottom: 0 !important; + > div:first-child { + top: ${(props) => + !props.isSectionHeaderVisible + ? "56px" + : "0px"} !important; + + @media ${desktop} { + ${isMobile && + css` + position: absolute; + `} + } + } + } + } `} - } + .section-header--hidden { + ${isMobile && + css` + top: -61px; + `} + } `; class SectionHeader extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); - this.focusRef = React.createRef(); - } + this.focusRef = React.createRef(); + } - shouldComponentUpdate(nextProps) { - return !equal(this.props, nextProps); - } + shouldComponentUpdate(nextProps) { + return !equal(this.props, nextProps); + } - render() { - //console.log("PageLayout SectionHeader render"); - // eslint-disable-next-line react/prop-types + render() { + //console.log("PageLayout SectionHeader render"); + // eslint-disable-next-line react/prop-types - const { isArticlePinned, isHeaderVisible, viewAs, ...rest } = this.props; + const { + isArticlePinned, + isHeaderVisible, + viewAs, + ...rest + } = this.props; - return ( - - {(value) => ( - -
- - )} - - ); - } + return ( + + {(value) => ( + +
+ + )} + + ); + } } SectionHeader.displayName = "SectionHeader"; SectionHeader.propTypes = { - isArticlePinned: PropTypes.bool, - isHeaderVisible: PropTypes.bool, + isArticlePinned: PropTypes.bool, + isHeaderVisible: PropTypes.bool, }; export default SectionHeader; diff --git a/packages/asc-web-components/public/static/images/panel.react.svg b/packages/asc-web-components/public/static/images/panel.react.svg new file mode 100644 index 0000000000..8da7c48595 --- /dev/null +++ b/packages/asc-web-components/public/static/images/panel.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js b/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js new file mode 100644 index 0000000000..22c04db2c1 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js @@ -0,0 +1,12 @@ +import { inject, observer } from "mobx-react"; +import React from "react"; +import { withTranslation } from "react-i18next"; +import { withRouter } from "react-router"; + +const NotificationsBodyContent = () => { + return
NOTIFICATION BODY CONTENT
; +}; + +export default inject(({}) => { + return {}; +})(withTranslation()(withRouter(observer(NotificationsBodyContent)))); diff --git a/products/ASC.Files/Client/src/pages/Home/Notifications/index.js b/products/ASC.Files/Client/src/pages/Home/Notifications/index.js new file mode 100644 index 0000000000..69b89df7df --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/Notifications/index.js @@ -0,0 +1 @@ +export { default as NotificationsBodyContent } from "./Body"; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 98da366667..fed080d42c 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -1,634 +1,673 @@ -import React from "react"; -import copy from "copy-to-clipboard"; -import styled, { css } from "styled-components"; -import { withRouter } from "react-router"; -import toastr from "studio/toastr"; -import Loaders from "@appserver/common/components/Loaders"; import Headline from "@appserver/common/components/Headline"; -import { FilterType, FileAction } from "@appserver/common/constants"; -import { withTranslation } from "react-i18next"; -import { isMobile } from "react-device-detect"; +import Loaders from "@appserver/common/components/Loaders"; +import { FileAction, FilterType } from "@appserver/common/constants"; import ContextMenuButton from "@appserver/components/context-menu-button"; import DropDownItem from "@appserver/components/drop-down-item"; import IconButton from "@appserver/components/icon-button"; -import { tablet, desktop } from "@appserver/components/utils/device"; -import { Consumer } from "@appserver/components/utils/context"; -import { inject, observer } from "mobx-react"; import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu"; +import { Consumer } from "@appserver/components/utils/context"; +import { desktop, tablet } from "@appserver/components/utils/device"; +import copy from "copy-to-clipboard"; +import { inject, observer } from "mobx-react"; +import React from "react"; +import { isMobile } from "react-device-detect"; +import { withTranslation } from "react-i18next"; +import { withRouter } from "react-router"; +import toastr from "studio/toastr"; +import styled, { css } from "styled-components"; const StyledContainer = styled.div` - .table-container_group-menu { - ${(props) => - props.viewAs === "table" - ? css` - margin: 0px -20px; - width: calc(100% + 44px); - ` - : css` - margin: 0px -24px; - width: calc(100% + 48px); - `} - - @media ${tablet} { - margin: 0 -16px; - width: calc(100% + 32px); - } - } - - .header-container { - position: relative; - ${(props) => - props.title && - css` - display: grid; - grid-template-columns: ${(props) => - props.isRootFolder - ? "auto auto 1fr" - : props.canCreate - ? "auto auto auto auto 1fr" - : "auto auto auto 1fr"}; + .table-container_group-menu { + ${(props) => + props.viewAs === "table" + ? css` + margin: 0px -20px; + width: calc(100% + 44px); + ` + : css` + margin: 0px -24px; + width: calc(100% + 48px); + `} @media ${tablet} { - grid-template-columns: ${(props) => - props.isRootFolder - ? "1fr auto" - : props.canCreate - ? "auto 1fr auto auto" - : "auto 1fr auto"}; - ${(props) => !props.isLoading && "top: 7px;"} + margin: 0 -16px; + width: calc(100% + 32px); } - `} - align-items: center; - max-width: calc(100vw - 32px); + } + + .header-container { + position: relative; + ${(props) => + props.title && + css` + display: grid; + grid-template-columns: ${(props) => + props.isRootFolder + ? "auto auto 1fr" + : props.canCreate + ? "auto auto auto auto 1fr" + : "auto auto auto 1fr"}; + + @media ${tablet} { + grid-template-columns: ${(props) => + props.isRootFolder + ? "1fr auto" + : props.canCreate + ? "auto 1fr auto auto" + : "auto 1fr auto"}; + ${(props) => !props.isLoading && "top: 7px;"} + } + `} + align-items: center; + max-width: calc(100vw - 32px); + + @media ${tablet} { + .headline-header { + margin-left: -1px; + } + } + .arrow-button { + margin-right: 15px; + min-width: 17px; + + @media ${tablet} { + padding: 8px 0 8px 8px; + margin-left: -8px; + margin-right: 16px; + } + } + + .add-button { + margin-bottom: -1px; + margin-left: 16px; + + @media ${tablet} { + margin-left: auto; + + & > div:first-child { + padding: 8px 8px 8px 8px; + margin-right: -8px; + } + } + } + + .option-button { + margin-bottom: -1px; + + @media (min-width: 1024px) { + margin-left: 8px; + } + + @media ${tablet} { + & > div:first-child { + padding: 8px 8px 8px 8px; + margin-right: -8px; + } + } + } + + .trash-button { + margin-bottom: -1px; + + @media (min-width: 1024px) { + margin-left: 8px; + } + + @media ${tablet} { + & > div:first-child { + margin-right: -8px; + } + } + } + } + + .group-button-menu-container { + margin: 0 -16px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + + ${isMobile && + css` + position: sticky; + `} + + ${(props) => + !props.isTabletView + ? props.width && + isMobile && + css` + width: ${props.width + 40 + "px"}; + ` + : props.width && + isMobile && + css` + width: ${props.width + 32 + "px"}; + `} @media ${tablet} { - .headline-header { - margin-left: -1px; - } - } - .arrow-button { - margin-right: 15px; - min-width: 17px; + padding-bottom: 0; + ${!isMobile && + css` + height: 56px; + `} + & > div:first-child { + ${(props) => + !isMobile && + props.width && + css` + width: ${props.width + 16 + "px"}; + `} - @media ${tablet} { - padding: 8px 0 8px 8px; - margin-left: -8px; - margin-right: 16px; - } - } - - .add-button { - margin-bottom: -1px; - margin-left: 16px; - - @media ${tablet} { - margin-left: auto; - - & > div:first-child { - padding: 8px 8px 8px 8px; - margin-right: -8px; + position: absolute; + ${(props) => + !props.isDesktop && + css` + top: 48px; + `} + z-index: 180; + } } - } - } - .option-button { - margin-bottom: -1px; - - @media (min-width: 1024px) { - margin-left: 8px; - } - - @media ${tablet} { - & > div:first-child { - padding: 8px 8px 8px 8px; - margin-right: -8px; + @media ${desktop} { + margin: 0 -24px; } - } } - - .trash-button { - margin-bottom: -1px; - - @media (min-width: 1024px) { - margin-left: 8px; - } - - @media ${tablet} { - & > div:first-child { - margin-right: -8px; - } - } - } - } - - .group-button-menu-container { - margin: 0 -16px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - - ${isMobile && - css` - position: sticky; - `} - - ${(props) => - !props.isTabletView - ? props.width && - isMobile && - css` - width: ${props.width + 40 + "px"}; - ` - : props.width && - isMobile && - css` - width: ${props.width + 32 + "px"}; - `} - - @media ${tablet} { - padding-bottom: 0; - ${!isMobile && - css` - height: 56px; - `} - & > div:first-child { - ${(props) => - !isMobile && - props.width && - css` - width: ${props.width + 16 + "px"}; - `} - - position: absolute; - ${(props) => - !props.isDesktop && - css` - top: 48px; - `} - z-index: 180; - } - } - - @media ${desktop} { - margin: 0 -24px; - } - } `; class SectionHeaderContent extends React.Component { - constructor(props) { - super(props); - } - - onCreate = (format) => { - this.props.setAction({ - type: FileAction.Create, - extension: format, - id: -1, - }); - }; - - createDocument = () => this.onCreate("docx"); - - createSpreadsheet = () => this.onCreate("xlsx"); - - createPresentation = () => this.onCreate("pptx"); - - createForm = () => this.onCreate("docxf"); - - createFormFromFile = () => { - const { setSelectFileDialogVisible } = this.props; - setSelectFileDialogVisible(true); - }; - - createFolder = () => this.onCreate(); - - uploadToFolder = () => console.log("Upload To Folder click"); - - getContextOptionsPlus = () => { - const { t, isPrivacyFolder } = this.props; - - return [ - { - key: "new-document", - label: t("NewDocument"), - onClick: this.createDocument, - }, - { - key: "new-spreadsheet", - label: t("NewSpreadsheet"), - onClick: this.createSpreadsheet, - }, - { - key: "new-presentation", - label: t("NewPresentation"), - onClick: this.createPresentation, - }, - { - label: t("Translations:NewForm"), - onClick: this.createForm, - }, - { - label: t("Translations:NewFormFile"), - onClick: this.createFormFromFile, - disabled: isPrivacyFolder, - }, - { - key: "new-folder", - label: t("NewFolder"), - onClick: this.createFolder, - }, - { key: "separator", isSeparator: true }, - { - key: "make-invitation-link", - label: t("UploadToFolder"), - onClick: this.uploadToFolder, - disabled: true, - }, - ]; - }; - - createLinkForPortalUsers = () => { - const { currentFolderId } = this.props; - const { t } = this.props; - - copy( - `${window.location.origin}/products/files/filter?folder=${currentFolderId}` - ); - - toastr.success(t("Translations:LinkCopySuccess")); - }; - - onMoveAction = () => { - this.props.setIsFolderActions(true); - this.props.setBufferSelection(this.props.currentFolderId); - return this.props.setMoveToPanelVisible(true); - }; - onCopyAction = () => { - this.props.setIsFolderActions(true); - this.props.setBufferSelection(this.props.currentFolderId); - return this.props.setCopyPanelVisible(true); - }; - downloadAction = () => { - this.props.setBufferSelection(this.props.currentFolderId); - this.props.setIsFolderActions(true); - this.props - .downloadAction(this.props.t("Translations:ArchivingData"), [ - this.props.currentFolderId, - ]) - .catch((err) => toastr.error(err)); - }; - - renameAction = () => console.log("renameAction click"); - onOpenSharingPanel = () => { - this.props.setBufferSelection(this.props.currentFolderId); - this.props.setIsFolderActions(true); - return this.props.setSharingPanelVisible(true); - }; - - onDeleteAction = () => { - const { - t, - deleteAction, - confirmDelete, - setDeleteDialogVisible, - isThirdPartySelection, - currentFolderId, - getFolderInfo, - setBufferSelection, - } = this.props; - - this.props.setIsFolderActions(true); - - if (confirmDelete || isThirdPartySelection) { - getFolderInfo(currentFolderId).then((data) => { - setBufferSelection(data); - setDeleteDialogVisible(true); - }); - } else { - const translations = { - deleteOperation: t("Translations:DeleteOperation"), - deleteFromTrash: t("Translations:DeleteFromTrash"), - deleteSelectedElem: t("Translations:DeleteSelectedElem"), - }; - - deleteAction(translations, [currentFolderId], true).catch((err) => - toastr.error(err) - ); + constructor(props) { + super(props); } - }; - onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); + onCreate = (format) => { + this.props.setAction({ + type: FileAction.Create, + extension: format, + id: -1, + }); + }; - getContextOptionsFolder = () => { - const { t, personal } = this.props; + createDocument = () => this.onCreate("docx"); - return [ - { - key: "sharing-settings", - label: t("SharingSettings"), - onClick: this.onOpenSharingPanel, - disabled: personal ? true : false, - }, - { - key: "link-portal-users", - label: t("LinkForPortalUsers"), - onClick: this.createLinkForPortalUsers, - disabled: personal ? true : false, - }, - { key: "separator-2", isSeparator: true }, - { - key: "move-to", - label: t("MoveTo"), - onClick: this.onMoveAction, - disabled: false, - }, - { - key: "copy", - label: t("Translations:Copy"), - onClick: this.onCopyAction, - disabled: false, - }, - { - key: "download", - label: t("Common:Download"), - onClick: this.downloadAction, - disabled: false, - }, - { - key: "rename", - label: t("Rename"), - onClick: this.renameAction, - disabled: true, - }, - { - key: "delete", - label: t("Common:Delete"), - onClick: this.onDeleteAction, - disabled: false, - }, - ]; - }; + createSpreadsheet = () => this.onCreate("xlsx"); - onBackToParentFolder = () => { - const { setIsLoading, parentId, filter, fetchFiles } = this.props; - setIsLoading(true); - fetchFiles(parentId, null, true, false).finally(() => setIsLoading(false)); - }; + createPresentation = () => this.onCreate("pptx"); - onSelect = (e) => { - const key = e.currentTarget.dataset.key; - this.props.setSelected(key); - }; + createForm = () => this.onCreate("docxf"); - onClose = () => { - this.props.setSelected("close"); - }; + createFormFromFile = () => { + const { setSelectFileDialogVisible } = this.props; + setSelectFileDialogVisible(true); + }; - getMenuItems = () => { - const { t, cbMenuItems, getCheckboxItemLabel } = this.props; + createFolder = () => this.onCreate(); - const checkboxOptions = ( - <> - {cbMenuItems.map((key) => { - const label = getCheckboxItemLabel(t, key); - return ( - - ); - })} - - ); + uploadToFolder = () => console.log("Upload To Folder click"); - return checkboxOptions; - }; + getContextOptionsPlus = () => { + const { t, isPrivacyFolder } = this.props; - onChange = (checked) => { - this.props.setSelected(checked ? "all" : "none"); - }; + return [ + { + key: "new-document", + label: t("NewDocument"), + onClick: this.createDocument, + }, + { + key: "new-spreadsheet", + label: t("NewSpreadsheet"), + onClick: this.createSpreadsheet, + }, + { + key: "new-presentation", + label: t("NewPresentation"), + onClick: this.createPresentation, + }, + { + label: t("Translations:NewForm"), + onClick: this.createForm, + }, + { + label: t("Translations:NewFormFile"), + onClick: this.createFormFromFile, + disabled: isPrivacyFolder, + }, + { + key: "new-folder", + label: t("NewFolder"), + onClick: this.createFolder, + }, + { key: "separator", isSeparator: true }, + { + key: "make-invitation-link", + label: t("UploadToFolder"), + onClick: this.uploadToFolder, + disabled: true, + }, + ]; + }; - render() { - //console.log("Body header render"); + createLinkForPortalUsers = () => { + const { currentFolderId } = this.props; + const { t } = this.props; - const { - t, - tReady, - isHeaderVisible, - isHeaderChecked, - isHeaderIndeterminate, - isRootFolder, - title, - canCreate, - isDesktop, - isTabletView, - personal, - getHeaderMenu, - viewAs, - isRecycleBinFolder, - isEmptyFilesList, - } = this.props; + copy( + `${window.location.origin}/products/files/filter?folder=${currentFolderId}` + ); - const menuItems = this.getMenuItems(); - const isLoading = !title || !tReady; - const headerMenu = getHeaderMenu(t); + toastr.success(t("Translations:LinkCopySuccess")); + }; - return ( - - {(context) => ( - - {isHeaderVisible ? ( - - ) : ( -
- {isLoading ? ( - - ) : ( - <> - {!isRootFolder && ( - - )} - { + this.props.setIsFolderActions(true); + this.props.setBufferSelection(this.props.currentFolderId); + return this.props.setMoveToPanelVisible(true); + }; + onCopyAction = () => { + this.props.setIsFolderActions(true); + this.props.setBufferSelection(this.props.currentFolderId); + return this.props.setCopyPanelVisible(true); + }; + downloadAction = () => { + this.props.setBufferSelection(this.props.currentFolderId); + this.props.setIsFolderActions(true); + this.props + .downloadAction(this.props.t("Translations:ArchivingData"), [ + this.props.currentFolderId, + ]) + .catch((err) => toastr.error(err)); + }; + + renameAction = () => console.log("renameAction click"); + onOpenSharingPanel = () => { + this.props.setBufferSelection(this.props.currentFolderId); + this.props.setIsFolderActions(true); + return this.props.setSharingPanelVisible(true); + }; + + onDeleteAction = () => { + const { + t, + deleteAction, + confirmDelete, + setDeleteDialogVisible, + isThirdPartySelection, + currentFolderId, + getFolderInfo, + setBufferSelection, + } = this.props; + + this.props.setIsFolderActions(true); + + if (confirmDelete || isThirdPartySelection) { + getFolderInfo(currentFolderId).then((data) => { + setBufferSelection(data); + setDeleteDialogVisible(true); + }); + } else { + const translations = { + deleteOperation: t("Translations:DeleteOperation"), + deleteFromTrash: t("Translations:DeleteFromTrash"), + deleteSelectedElem: t("Translations:DeleteSelectedElem"), + }; + + deleteAction(translations, [currentFolderId], true).catch((err) => + toastr.error(err) + ); + } + }; + + onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); + onToggleNotifications = () => this.props.toggleNotifications(); + + getContextOptionsFolder = () => { + const { t, personal } = this.props; + + return [ + { + key: "sharing-settings", + label: t("SharingSettings"), + onClick: this.onOpenSharingPanel, + disabled: personal ? true : false, + }, + { + key: "link-portal-users", + label: t("LinkForPortalUsers"), + onClick: this.createLinkForPortalUsers, + disabled: personal ? true : false, + }, + { key: "separator-2", isSeparator: true }, + { + key: "move-to", + label: t("MoveTo"), + onClick: this.onMoveAction, + disabled: false, + }, + { + key: "copy", + label: t("Translations:Copy"), + onClick: this.onCopyAction, + disabled: false, + }, + { + key: "download", + label: t("Common:Download"), + onClick: this.downloadAction, + disabled: false, + }, + { + key: "rename", + label: t("Rename"), + onClick: this.renameAction, + disabled: true, + }, + { + key: "delete", + label: t("Common:Delete"), + onClick: this.onDeleteAction, + disabled: false, + }, + ]; + }; + + onBackToParentFolder = () => { + const { setIsLoading, parentId, filter, fetchFiles } = this.props; + setIsLoading(true); + fetchFiles(parentId, null, true, false).finally(() => + setIsLoading(false) + ); + }; + + onSelect = (e) => { + const key = e.currentTarget.dataset.key; + this.props.setSelected(key); + }; + + onClose = () => { + this.props.setSelected("close"); + }; + + getMenuItems = () => { + const { t, cbMenuItems, getCheckboxItemLabel } = this.props; + + const checkboxOptions = ( + <> + {cbMenuItems.map((key) => { + const label = getCheckboxItemLabel(t, key); + return ( + + ); + })} + + ); + + return checkboxOptions; + }; + + onChange = (checked) => { + this.props.setSelected(checked ? "all" : "none"); + }; + + render() { + //console.log("Body header render"); + + const { + t, + tReady, + isHeaderVisible, + isHeaderChecked, + isHeaderIndeterminate, + isRootFolder, + title, + canCreate, + isDesktop, + isTabletView, + personal, + getHeaderMenu, + viewAs, + isRecycleBinFolder, + isEmptyFilesList, + } = this.props; + + const menuItems = this.getMenuItems(); + const isLoading = !title || !tReady; + const headerMenu = getHeaderMenu(t); + + return ( + + {(context) => ( + - {title} - - {!isRootFolder && canCreate ? ( - <> - + {isHeaderVisible ? ( + + ) : ( +
+ {isLoading ? ( + + ) : ( + <> + {!isRootFolder && ( + + )} + + {title} + + {!isRootFolder && canCreate ? ( + <> + - - - ) : ( - canCreate && ( - - ) - )} - {isRecycleBinFolder && !isEmptyFilesList && ( - - - - )} - + + + ) : ( + canCreate && ( + + ) + )} + {isRecycleBinFolder && + !isEmptyFilesList && ( + + + + )} + + + + + )} +
+ )} + )} -
- )} -
- )} -
- ); - } + + ); + } } export default inject( - ({ - auth, - filesStore, - dialogsStore, - selectedFolderStore, - filesActionsStore, - settingsStore, - treeFoldersStore, - }) => { - const { - setSelected, - setSelection, - fileActionStore, - fetchFiles, - filter, - canCreate, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, - isThirdPartySelection, - setIsLoading, - cbMenuItems, - getCheckboxItemLabel, - isEmptyFilesList, getFolderInfo, - setBufferSelection, - viewAs, - } = filesStore; - const { setAction } = fileActionStore; - const { - setSharingPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - setEmptyTrashDialogVisible, - setSelectFileDialogVisible, - setIsFolderActions, - } = dialogsStore; + ({ + auth, + filesStore, + dialogsStore, + selectedFolderStore, + filesActionsStore, + settingsStore, + treeFoldersStore, + }) => { + const { + setSelected, + setSelection, + fileActionStore, + fetchFiles, + filter, + canCreate, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + isThirdPartySelection, + setIsLoading, + cbMenuItems, + getCheckboxItemLabel, + isEmptyFilesList, + getFolderInfo, + setBufferSelection, + viewAs, + } = filesStore; + const { setAction } = fileActionStore; + const { + setSharingPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + setEmptyTrashDialogVisible, + setSelectFileDialogVisible, + setIsFolderActions, + } = dialogsStore; - const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore; - const { deleteAction, downloadAction, getHeaderMenu } = filesActionsStore; + const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore; + const { + deleteAction, + downloadAction, + getHeaderMenu, + } = filesActionsStore; - return { - isDesktop: auth.settingsStore.isDesktopClient, - isRootFolder: selectedFolderStore.parentId === 0, - title: selectedFolderStore.title, - parentId: selectedFolderStore.parentId, - currentFolderId: selectedFolderStore.id, - filter, - canCreate, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, - isThirdPartySelection, - isTabletView: auth.settingsStore.isTabletView, - confirmDelete: settingsStore.confirmDelete, - personal: auth.settingsStore.personal, - cbMenuItems, - getFolderInfo, + return { + isDesktop: auth.settingsStore.isDesktopClient, + isRootFolder: selectedFolderStore.parentId === 0, + title: selectedFolderStore.title, + parentId: selectedFolderStore.parentId, + currentFolderId: selectedFolderStore.id, + filter, + canCreate, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + isThirdPartySelection, + isTabletView: auth.settingsStore.isTabletView, + confirmDelete: settingsStore.confirmDelete, + personal: auth.settingsStore.personal, + cbMenuItems, + getFolderInfo, - setSelected, - setSelection, - setAction, - setIsLoading, - fetchFiles, - setSharingPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setBufferSelection, - setIsFolderActions, - deleteAction, - setDeleteDialogVisible, - downloadAction, - getHeaderMenu, - getCheckboxItemLabel, - setSelectFileDialogVisible, + setSelected, + setSelection, + setAction, + setIsLoading, + fetchFiles, + setSharingPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setBufferSelection, + setIsFolderActions, + deleteAction, + setDeleteDialogVisible, + downloadAction, + getHeaderMenu, + getCheckboxItemLabel, + setSelectFileDialogVisible, - isRecycleBinFolder, - setEmptyTrashDialogVisible, - isEmptyFilesList, - isPrivacyFolder, - viewAs, }; - } + isRecycleBinFolder, + setEmptyTrashDialogVisible, + isEmptyFilesList, + isPrivacyFolder, + viewAs, + }; + } )( - withTranslation(["Home", "Common", "Translations"])( - withRouter(observer(SectionHeaderContent)) - ) + withTranslation(["Home", "Common", "Translations"])( + withRouter(observer(SectionHeaderContent)) + ) ); diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index a7d4b36c4a..98e8e853cc 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -1,447 +1,469 @@ -import React from "react"; -//import PropTypes from "prop-types"; -import { withRouter } from "react-router"; -import { isMobile } from "react-device-detect"; -import axios from "axios"; -import toastr from "@appserver/components/toast/toastr"; -import PageLayout from "@appserver/common/components/PageLayout"; -import { showLoader, hideLoader } from "@appserver/common/utils"; import FilesFilter from "@appserver/common/api/files/filter"; import { getGroup } from "@appserver/common/api/groups"; import { getUserById } from "@appserver/common/api/people"; -import { withTranslation, Trans } from "react-i18next"; -import { - ArticleBodyContent, - ArticleHeaderContent, - ArticleMainButtonContent, -} from "../../components/Article"; -import { - SectionBodyContent, - SectionFilterContent, - SectionHeaderContent, - SectionPagingContent, -} from "./Section"; +import PageLayout from "@appserver/common/components/PageLayout"; +import { hideLoader, showLoader } from "@appserver/common/utils"; +import toastr from "@appserver/components/toast/toastr"; +import axios from "axios"; +import { inject, observer } from "mobx-react"; +import React from "react"; +import { isMobile } from "react-device-detect"; +import { Trans, withTranslation } from "react-i18next"; +//import PropTypes from "prop-types"; +import { withRouter } from "react-router"; +import config from "../../../package.json"; +import { + ArticleBodyContent, + ArticleHeaderContent, + ArticleMainButtonContent, +} from "../../components/Article"; +import DragTooltip from "../../components/DragTooltip"; import { createTreeFolders } from "../../helpers/files-helpers"; import MediaViewer from "./MediaViewer"; -import DragTooltip from "../../components/DragTooltip"; -import { observer, inject } from "mobx-react"; -import config from "../../../package.json"; +import { NotificationsBodyContent } from "./Notifications"; +import { + SectionBodyContent, + SectionFilterContent, + SectionHeaderContent, + SectionPagingContent, +} from "./Section"; class PureHome extends React.Component { - componentDidMount() { - const { - fetchFiles, - homepage, - setIsLoading, - setFirstLoad, - expandedKeys, - setExpandedKeys, - setToPreviewFile, - mediaViewersFormatsStore, - getFileInfo, - } = this.props; + componentDidMount() { + const { + fetchFiles, + homepage, + setIsLoading, + setFirstLoad, + expandedKeys, + setExpandedKeys, + setToPreviewFile, + mediaViewersFormatsStore, + getFileInfo, + } = this.props; - const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gmi"); //TODO: Always find? - const match = window.location.pathname.match(reg); - let filterObj = null; + const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gmi"); //TODO: Always find? + const match = window.location.pathname.match(reg); + let filterObj = null; - if (window.location.href.indexOf("/files/#preview") > 1) { - const pathname = window.location.href; - const fileId = pathname.slice(pathname.indexOf("#preview") + 9); + if (window.location.href.indexOf("/files/#preview") > 1) { + const pathname = window.location.href; + const fileId = pathname.slice(pathname.indexOf("#preview") + 9); - getFileInfo(fileId) - .then((data) => { - const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( - data.fileExst - ); - const file = { ...data, canOpenPlayer }; - setToPreviewFile(file, true); - }) - .catch((err) => { - toastr.error(err); - this.fetchDefaultFiles(); - }); + getFileInfo(fileId) + .then((data) => { + const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( + data.fileExst + ); + const file = { ...data, canOpenPlayer }; + setToPreviewFile(file, true); + }) + .catch((err) => { + toastr.error(err); + this.fetchDefaultFiles(); + }); - return; - } + return; + } - if (match && match.length > 0) { - filterObj = FilesFilter.getFilter(window.location); + if (match && match.length > 0) { + filterObj = FilesFilter.getFilter(window.location); + + if (!filterObj) { + setIsLoading(true); + this.fetchDefaultFiles(); + + return; + } + } + + if (!filterObj) return; + + let dataObj = { filter: filterObj }; + + if (filterObj && filterObj.authorType) { + const authorType = filterObj.authorType; + const indexOfUnderscore = authorType.indexOf("_"); + const type = authorType.slice(0, indexOfUnderscore); + const itemId = authorType.slice(indexOfUnderscore + 1); + + if (itemId) { + dataObj = { + type, + itemId, + filter: filterObj, + }; + } else { + filterObj.authorType = null; + dataObj = { filter: filterObj }; + } + } + + if (!dataObj) return; + + const { filter, itemId, type } = dataObj; + const newFilter = filter ? filter.clone() : FilesFilter.getDefault(); + const requests = [Promise.resolve(newFilter)]; + + if (type === "group") { + requests.push(getGroup(itemId)); + } else if (type === "user") { + requests.push(getUserById(itemId)); + } - if (!filterObj) { setIsLoading(true); - this.fetchDefaultFiles(); - return; - } + axios + .all(requests) + .catch((err) => { + Promise.resolve(FilesFilter.getDefault()); + console.warn("Filter restored by default", err); + }) + .then((data) => { + const filter = data[0]; + const result = data[1]; + if (result) { + const type = result.displayName ? "user" : "group"; + const selectedItem = { + key: result.id, + label: + type === "user" ? result.displayName : result.name, + type, + }; + filter.selectedItem = selectedItem; + } + + if (filter) { + const folderId = filter.folder; + //console.log("filter", filter); + + return fetchFiles(folderId, filter).then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createTreeFolders( + pathParts, + expandedKeys + ); + setExpandedKeys(newExpandedKeys); + }); + } + + return Promise.resolve(); + }) + .finally(() => { + setIsLoading(false); + setFirstLoad(false); + }); } - if (!filterObj) return; + fetchDefaultFiles = () => { + const { + isVisitor, + fetchFiles, + setIsLoading, + setFirstLoad, + } = this.props; + const filterObj = FilesFilter.getDefault(); + const folderId = isVisitor ? "@common" : filterObj.folder; - let dataObj = { filter: filterObj }; + fetchFiles(folderId).finally(() => { + setIsLoading(false); + setFirstLoad(false); + }); + }; - if (filterObj && filterObj.authorType) { - const authorType = filterObj.authorType; - const indexOfUnderscore = authorType.indexOf("_"); - const type = authorType.slice(0, indexOfUnderscore); - const itemId = authorType.slice(indexOfUnderscore + 1); + onDrop = (files, uploadToFolder) => { + const { t, startUpload, setDragging, dragging } = this.props; + dragging && setDragging(false); + startUpload(files, uploadToFolder, t); + }; - if (itemId) { - dataObj = { - type, - itemId, - filter: filterObj, - }; - } else { - filterObj.authorType = null; - dataObj = { filter: filterObj }; - } + showOperationToast = (type, qty, title) => { + const { t } = this.props; + switch (type) { + case "move": + if (qty > 1) { + return toastr.success( + + {{ qty }} elements has been moved + + ); + } + return toastr.success( + + {{ title }} moved + + ); + case "duplicate": + if (qty > 1) { + return toastr.success( + + {{ qty }} elements copied + + ); + } + return toastr.success( + + {{ title }} copied + + ); + default: + break; + } + }; + + showUploadPanel = () => { + const { + uploaded, + converted, + uploadPanelVisible, + setUploadPanelVisible, + clearPrimaryProgressData, + primaryProgressDataVisible, + } = this.props; + setUploadPanelVisible(!uploadPanelVisible); + + if (primaryProgressDataVisible && uploaded && converted) + clearPrimaryProgressData(); + }; + componentDidUpdate(prevProps) { + const { + isProgressFinished, + secondaryProgressDataStoreIcon, + selectionLength, + selectionTitle, + } = this.props; + + if (this.props.isHeaderVisible !== prevProps.isHeaderVisible) { + this.props.setHeaderVisible(this.props.isHeaderVisible); + } + if ( + isProgressFinished && + isProgressFinished !== prevProps.isProgressFinished + ) { + this.showOperationToast( + secondaryProgressDataStoreIcon, + selectionLength, + selectionTitle + ); + } } - if (!dataObj) return; + render() { + //console.log("Home render"); + const { + viewAs, + fileActionId, + firstLoad, + isHeaderVisible, + isPrivacyFolder, + isRecycleBinFolder, - const { filter, itemId, type } = dataObj; - const newFilter = filter ? filter.clone() : FilesFilter.getDefault(); - const requests = [Promise.resolve(newFilter)]; + primaryProgressDataVisible, + primaryProgressDataPercent, + primaryProgressDataIcon, + primaryProgressDataAlert, - if (type === "group") { - requests.push(getGroup(itemId)); - } else if (type === "user") { - requests.push(getUserById(itemId)); - } + secondaryProgressDataStoreVisible, + secondaryProgressDataStorePercent, + secondaryProgressDataStoreIcon, + secondaryProgressDataStoreAlert, - setIsLoading(true); + dragging, + tReady, + } = this.props; - axios - .all(requests) - .catch((err) => { - Promise.resolve(FilesFilter.getDefault()); - console.warn("Filter restored by default", err); - }) - .then((data) => { - const filter = data[0]; - const result = data[1]; - if (result) { - const type = result.displayName ? "user" : "group"; - const selectedItem = { - key: result.id, - label: type === "user" ? result.displayName : result.name, - type, - }; - filter.selectedItem = selectedItem; - } + return ( + <> + + + + + + - if (filter) { - const folderId = filter.folder; - //console.log("filter", filter); + + + - return fetchFiles(folderId, filter).then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createTreeFolders(pathParts, expandedKeys); - setExpandedKeys(newExpandedKeys); - }); - } + + + - return Promise.resolve(); - }) - .finally(() => { - setIsLoading(false); - setFirstLoad(false); - }); - } + + + - fetchDefaultFiles = () => { - const { isVisitor, fetchFiles, setIsLoading, setFirstLoad } = this.props; - const filterObj = FilesFilter.getDefault(); - const folderId = isVisitor ? "@common" : filterObj.folder; + + + - fetchFiles(folderId).finally(() => { - setIsLoading(false); - setFirstLoad(false); - }); - }; + + + - onDrop = (files, uploadToFolder) => { - const { t, startUpload, setDragging, dragging } = this.props; - dragging && setDragging(false); - startUpload(files, uploadToFolder, t); - }; + + + - showOperationToast = (type, qty, title) => { - const { t } = this.props; - switch (type) { - case "move": - if (qty > 1) { - return toastr.success( - - {{ qty }} elements has been moved - - ); - } - return toastr.success( - - {{ title }} moved - + + + + + ); - case "duplicate": - if (qty > 1) { - return toastr.success( - - {{ qty }} elements copied - - ); - } - return toastr.success( - - {{ title }} copied - - ); - default: - break; } - }; - - showUploadPanel = () => { - const { - uploaded, - converted, - uploadPanelVisible, - setUploadPanelVisible, - clearPrimaryProgressData, - primaryProgressDataVisible, - } = this.props; - setUploadPanelVisible(!uploadPanelVisible); - - if (primaryProgressDataVisible && uploaded && converted) - clearPrimaryProgressData(); - }; - componentDidUpdate(prevProps) { - const { - isProgressFinished, - secondaryProgressDataStoreIcon, - selectionLength, - selectionTitle, - } = this.props; - - if (this.props.isHeaderVisible !== prevProps.isHeaderVisible) { - this.props.setHeaderVisible(this.props.isHeaderVisible); - } - if ( - isProgressFinished && - isProgressFinished !== prevProps.isProgressFinished - ) { - this.showOperationToast( - secondaryProgressDataStoreIcon, - selectionLength, - selectionTitle - ); - } - } - - render() { - //console.log("Home render"); - const { - viewAs, - fileActionId, - firstLoad, - isHeaderVisible, - isPrivacyFolder, - isRecycleBinFolder, - - primaryProgressDataVisible, - primaryProgressDataPercent, - primaryProgressDataIcon, - primaryProgressDataAlert, - - secondaryProgressDataStoreVisible, - secondaryProgressDataStorePercent, - secondaryProgressDataStoreIcon, - secondaryProgressDataStoreAlert, - - dragging, - tReady, - } = this.props; - return ( - <> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); - } } const Home = withTranslation("Home")(PureHome); export default inject( - ({ - auth, - filesStore, - uploadDataStore, - treeFoldersStore, - mediaViewerDataStore, - formatsStore, - }) => { - const { - secondaryProgressDataStore, - primaryProgressDataStore, - } = uploadDataStore; - const { - firstLoad, - setFirstLoad, - fetchFiles, - fileActionStore, - selection, - setSelections, - dragging, - setDragging, - setIsLoading, - isLoading, - viewAs, - getFileInfo, - } = filesStore; + ({ + auth, + filesStore, + uploadDataStore, + treeFoldersStore, + mediaViewerDataStore, + formatsStore, + }) => { + const { + secondaryProgressDataStore, + primaryProgressDataStore, + } = uploadDataStore; + const { + firstLoad, + setFirstLoad, + fetchFiles, + fileActionStore, + selection, + setSelections, + dragging, + setDragging, + setIsLoading, + isLoading, + viewAs, + getFileInfo, + } = filesStore; - const { mediaViewersFormatsStore } = formatsStore; + const { mediaViewersFormatsStore } = formatsStore; - const { id } = fileActionStore; - const { - isRecycleBinFolder, - isPrivacyFolder, - expandedKeys, - setExpandedKeys, - } = treeFoldersStore; + const { id } = fileActionStore; + const { + isRecycleBinFolder, + isPrivacyFolder, + expandedKeys, + setExpandedKeys, + } = treeFoldersStore; - const { - visible: primaryProgressDataVisible, - percent: primaryProgressDataPercent, - icon: primaryProgressDataIcon, - alert: primaryProgressDataAlert, - clearPrimaryProgressData, - } = primaryProgressDataStore; + const { + visible: primaryProgressDataVisible, + percent: primaryProgressDataPercent, + icon: primaryProgressDataIcon, + alert: primaryProgressDataAlert, + clearPrimaryProgressData, + } = primaryProgressDataStore; - const { - visible: secondaryProgressDataStoreVisible, - percent: secondaryProgressDataStorePercent, - icon: secondaryProgressDataStoreIcon, - alert: secondaryProgressDataStoreAlert, - isSecondaryProgressFinished: isProgressFinished, - } = secondaryProgressDataStore; + const { + visible: secondaryProgressDataStoreVisible, + percent: secondaryProgressDataStorePercent, + icon: secondaryProgressDataStoreIcon, + alert: secondaryProgressDataStoreAlert, + isSecondaryProgressFinished: isProgressFinished, + } = secondaryProgressDataStore; - const { - setUploadPanelVisible, - startUpload, - uploaded, - converted, - } = uploadDataStore; + const { + setUploadPanelVisible, + startUpload, + uploaded, + converted, + } = uploadDataStore; - const selectionLength = isProgressFinished ? selection.length : null; - const selectionTitle = isProgressFinished - ? filesStore.selectionTitle - : null; + const selectionLength = isProgressFinished ? selection.length : null; + const selectionTitle = isProgressFinished + ? filesStore.selectionTitle + : null; - const { setToPreviewFile } = mediaViewerDataStore; - if (!firstLoad) { - if (isLoading) { - showLoader(); - } else { - hideLoader(); - } + const { setToPreviewFile } = mediaViewerDataStore; + if (!firstLoad) { + if (isLoading) { + showLoader(); + } else { + hideLoader(); + } + } + + return { + homepage: config.homepage, + firstLoad, + dragging, + fileActionId: id, + viewAs, + uploaded, + converted, + isRecycleBinFolder, + isPrivacyFolder, + isVisitor: auth.userStore.user.isVisitor, + expandedKeys, + + primaryProgressDataVisible, + primaryProgressDataPercent, + primaryProgressDataIcon, + primaryProgressDataAlert, + clearPrimaryProgressData, + + secondaryProgressDataStoreVisible, + secondaryProgressDataStorePercent, + secondaryProgressDataStoreIcon, + secondaryProgressDataStoreAlert, + + selectionLength, + isProgressFinished, + selectionTitle, + + setExpandedKeys, + setFirstLoad, + setDragging, + setIsLoading, + fetchFiles, + setUploadPanelVisible, + setSelections, + startUpload, + isHeaderVisible: auth.settingsStore.isHeaderVisible, + setHeaderVisible: auth.settingsStore.setHeaderVisible, + setToPreviewFile, + mediaViewersFormatsStore, + getFileInfo, + }; } - - return { - homepage: config.homepage, - firstLoad, - dragging, - fileActionId: id, - viewAs, - uploaded, - converted, - isRecycleBinFolder, - isPrivacyFolder, - isVisitor: auth.userStore.user.isVisitor, - expandedKeys, - - primaryProgressDataVisible, - primaryProgressDataPercent, - primaryProgressDataIcon, - primaryProgressDataAlert, - clearPrimaryProgressData, - - secondaryProgressDataStoreVisible, - secondaryProgressDataStorePercent, - secondaryProgressDataStoreIcon, - secondaryProgressDataStoreAlert, - - selectionLength, - isProgressFinished, - selectionTitle, - - setExpandedKeys, - setFirstLoad, - setDragging, - setIsLoading, - fetchFiles, - setUploadPanelVisible, - setSelections, - startUpload, - isHeaderVisible: auth.settingsStore.isHeaderVisible, - setHeaderVisible: auth.settingsStore.setHeaderVisible, - setToPreviewFile, - mediaViewersFormatsStore, - getFileInfo, - }; - } )(withRouter(observer(Home))); diff --git a/products/ASC.Files/Client/src/store/NotificationsStore.js b/products/ASC.Files/Client/src/store/NotificationsStore.js new file mode 100644 index 0000000000..2331eaa628 --- /dev/null +++ b/products/ASC.Files/Client/src/store/NotificationsStore.js @@ -0,0 +1,15 @@ +import { makeAutoObservable } from "mobx"; + +class NotificationsStore { + isVisible = false; + + constructor() { + makeAutoObservable(this); + } + + toggleIsVisible = () => { + isVisible = !this.isVisible; + }; +} + +export default NotificationsStore; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index f3306d4853..0e6e631c7f 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -1,43 +1,44 @@ -import FilesStore from "./FilesStore"; -import fileActionStore from "./FileActionStore"; -import selectedFolderStore from "./SelectedFolderStore"; -import TreeFoldersStore from "./TreeFoldersStore"; -import thirdPartyStore from "./ThirdPartyStore"; -import SettingsStore from "./SettingsStore"; -import FilesActionsStore from "./FilesActionsStore"; -import FormatsStore from "./FormatsStore"; -import iconFormatsStore from "./IconFormatsStore"; -import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; -import docserviceStore from "./DocserviceStore"; -import MediaViewerDataStore from "./MediaViewerDataStore"; -import UploadDataStore from "./UploadDataStore"; -import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; -import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; - -import VersionHistoryStore from "./VersionHistoryStore"; -import DialogsStore from "./DialogsStore"; -import selectedFilesStore from "./SelectedFilesStore"; import store from "studio/store"; +import DialogsStore from "./DialogsStore"; +import docserviceStore from "./DocserviceStore"; +import fileActionStore from "./FileActionStore"; +import FilesActionsStore from "./FilesActionsStore"; +import FilesStore from "./FilesStore"; +import FormatsStore from "./FormatsStore"; +import iconFormatsStore from "./IconFormatsStore"; +import MediaViewerDataStore from "./MediaViewerDataStore"; +import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; +import NotificationsStore from "./NotificationsStore"; +import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; +import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; +import selectedFilesStore from "./SelectedFilesStore"; +import selectedFolderStore from "./SelectedFolderStore"; +import SettingsStore from "./SettingsStore"; +import thirdPartyStore from "./ThirdPartyStore"; +import TreeFoldersStore from "./TreeFoldersStore"; +import UploadDataStore from "./UploadDataStore"; +import VersionHistoryStore from "./VersionHistoryStore"; + const formatsStore = new FormatsStore( - iconFormatsStore, - mediaViewersFormatsStore, - docserviceStore + iconFormatsStore, + mediaViewersFormatsStore, + docserviceStore ); const treeFoldersStore = new TreeFoldersStore(selectedFolderStore); const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore); const filesStore = new FilesStore( - store.auth, - store.auth.settingsStore, - store.auth.userStore, - fileActionStore, - selectedFolderStore, - treeFoldersStore, - formatsStore, - settingsStore, - selectedFilesStore + store.auth, + store.auth.settingsStore, + store.auth.userStore, + fileActionStore, + selectedFolderStore, + treeFoldersStore, + formatsStore, + settingsStore, + selectedFilesStore ); const mediaViewerDataStore = new MediaViewerDataStore(filesStore, formatsStore); @@ -45,46 +46,49 @@ const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); const dialogsStore = new DialogsStore( - treeFoldersStore, - filesStore, - selectedFolderStore + treeFoldersStore, + filesStore, + selectedFolderStore ); const uploadDataStore = new UploadDataStore( - formatsStore, - treeFoldersStore, - selectedFolderStore, - filesStore, - secondaryProgressDataStore, - primaryProgressDataStore, - dialogsStore, - settingsStore + formatsStore, + treeFoldersStore, + selectedFolderStore, + filesStore, + secondaryProgressDataStore, + primaryProgressDataStore, + dialogsStore, + settingsStore ); const filesActionsStore = new FilesActionsStore( - store.auth, - uploadDataStore, - treeFoldersStore, - filesStore, - selectedFolderStore, - settingsStore, - dialogsStore, - mediaViewerDataStore + store.auth, + uploadDataStore, + treeFoldersStore, + filesStore, + selectedFolderStore, + settingsStore, + dialogsStore, + mediaViewerDataStore ); const versionHistoryStore = new VersionHistoryStore(filesStore); +const notificationsStore = new NotificationsStore(); + //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { - filesStore, - settingsStore, - mediaViewerDataStore, - formatsStore, - versionHistoryStore, - uploadDataStore, - dialogsStore, - treeFoldersStore, - selectedFolderStore, - filesActionsStore, - selectedFilesStore, + filesStore, + settingsStore, + mediaViewerDataStore, + formatsStore, + versionHistoryStore, + uploadDataStore, + dialogsStore, + treeFoldersStore, + selectedFolderStore, + filesActionsStore, + selectedFilesStore, + notificationsStore, }; export default stores; From b5aba234d9580fdd2011d95e45edd5956e637426 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 8 Feb 2022 17:04:27 +0300 Subject: [PATCH 02/81] for review --- .../components/PageLayout/sub-components/notifications.js | 5 +++-- .../Client/src/pages/Home/Notifications/Body/index.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/asc-web-common/components/PageLayout/sub-components/notifications.js b/packages/asc-web-common/components/PageLayout/sub-components/notifications.js index 03487ff8b3..88b61ff5e0 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/notifications.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/notifications.js @@ -1,3 +1,4 @@ +import { observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; @@ -10,7 +11,7 @@ const Notifications = ({ children }) => { console.log("N - ", children); - return {children}; + return {children}1213; }; -export default Notifications; +export default observer(Notifications); diff --git a/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js b/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js index 22c04db2c1..ab30cb010b 100644 --- a/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js @@ -9,4 +9,4 @@ const NotificationsBodyContent = () => { export default inject(({}) => { return {}; -})(withTranslation()(withRouter(observer(NotificationsBodyContent)))); +})(observer(NotificationsBodyContent)); From ff3c55e89235f5d2101002c8cb3cee2e33b0fd98 Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 9 Feb 2022 12:13:16 +0300 Subject: [PATCH 03/81] add header --- .../components/PageLayout/index.js | 44 ++++++++++++------- .../sub-components/notifications-body.js | 11 ----- .../sub-components/notifications.js | 17 ------- .../sub-components/room-info-body.js | 16 +++++++ .../sub-components/room-info-header.js | 16 +++++++ .../PageLayout/sub-components/room-info.js | 17 +++++++ .../src/pages/Home/Notifications/index.js | 1 - .../{Notifications => RoomInfo}/Body/index.js | 4 +- .../src/pages/Home/RoomInfo/Header/index.js | 12 +++++ .../Client/src/pages/Home/RoomInfo/index.js | 2 + .../src/pages/Home/Section/Header/index.js | 6 +-- .../ASC.Files/Client/src/pages/Home/index.js | 13 ++++-- ...NotificationsStore.js => RoomInfoStore.js} | 4 +- products/ASC.Files/Client/src/store/index.js | 6 +-- 14 files changed, 108 insertions(+), 61 deletions(-) delete mode 100644 packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js delete mode 100644 packages/asc-web-common/components/PageLayout/sub-components/notifications.js create mode 100644 packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js create mode 100644 packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js create mode 100644 packages/asc-web-common/components/PageLayout/sub-components/room-info.js delete mode 100644 products/ASC.Files/Client/src/pages/Home/Notifications/index.js rename products/ASC.Files/Client/src/pages/Home/{Notifications => RoomInfo}/Body/index.js (76%) create mode 100644 products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js create mode 100644 products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js rename products/ASC.Files/Client/src/store/{NotificationsStore.js => RoomInfoStore.js} (76%) diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 694c42534d..395eeede95 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -15,8 +15,9 @@ import SubArticleBody from "./sub-components/article-body"; import SubArticleHeader from "./sub-components/article-header"; import SubArticleMainButton from "./sub-components/article-main-button"; import ArticlePinPanel from "./sub-components/article-pin-panel"; -import Notifications from "./sub-components/notifications"; -import SubNotificationsBody from "./sub-components/notifications-body"; +import RoomInfo from "./sub-components/room-info"; +import SubRoomInfoBody from "./sub-components/room-info-body"; +import SubRoomInfoHeader from "./sub-components/room-info-header"; import Section from "./sub-components/section"; import SubSectionBody from "./sub-components/section-body"; import SubSectionBodyContent from "./sub-components/section-body-content"; @@ -86,10 +87,15 @@ function SectionPaging() { } SectionPaging.displayName = "SectionPaging"; -function NotificationsBody() { +function RoomInfoBody() { return null; } -NotificationsBody.displayName = "NotificationsBody"; +RoomInfoBody.displayName = "RoomInfoBody"; + +function RoomInfoHeader() { + return null; +} +RoomInfoHeader.displayName = "RoomInfoHeader"; class PageLayout extends React.Component { static ArticleHeader = ArticleHeader; @@ -99,7 +105,8 @@ class PageLayout extends React.Component { static SectionFilter = SectionFilter; static SectionBody = SectionBody; static SectionPaging = SectionPaging; - static NotificationsBody = NotificationsBody; + static RoomInfoBody = RoomInfoBody; + static RoomInfoHeader = RoomInfoHeader; constructor(props) { super(props); @@ -250,7 +257,8 @@ class PageLayout extends React.Component { let sectionFilterContent = null; let sectionPagingContent = null; let sectionBodyContent = null; - let notificationsBodyContent = null; + let roomInfoBodyContent = null; + let roomInfoHeaderContent = null; React.Children.forEach(children, (child) => { const childType = @@ -280,9 +288,11 @@ class PageLayout extends React.Component { case SectionBody.displayName: sectionBodyContent = child; break; - case NotificationsBody.displayName: - notificationsBodyContent = child; - console.log(notificationsBodyContent); + case RoomInfoBody.displayName: + roomInfoBodyContent = child; + break; + case RoomInfoHeader.displayName: + roomInfoHeaderContent = child; break; default: break; @@ -514,14 +524,14 @@ class PageLayout extends React.Component { /> )} - - - {notificationsBodyContent} - - + + + {roomInfoHeaderContent} + + + {roomInfoBodyContent} + + )} diff --git a/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js b/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js deleted file mode 100644 index 5f36cb884a..0000000000 --- a/packages/asc-web-common/components/PageLayout/sub-components/notifications-body.js +++ /dev/null @@ -1,11 +0,0 @@ -import { inject, observer } from "mobx-react"; -import React from "react"; - -const SubNotificationsBody = ({ children }) => { - console.log("SNB - ", children); - return {children}; -}; - -export default inject(() => { - return {}; -})(observer(SubNotificationsBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/notifications.js b/packages/asc-web-common/components/PageLayout/sub-components/notifications.js deleted file mode 100644 index 88b61ff5e0..0000000000 --- a/packages/asc-web-common/components/PageLayout/sub-components/notifications.js +++ /dev/null @@ -1,17 +0,0 @@ -import { observer } from "mobx-react"; -import React from "react"; -import styled from "styled-components"; - -const Notifications = ({ children }) => { - const StyledNotifications = styled.div` - height: 100%; - width: 400px; - background-color: red; - `; - - console.log("N - ", children); - - return {children}1213; -}; - -export default observer(Notifications); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js new file mode 100644 index 0000000000..3c5d08e0fa --- /dev/null +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js @@ -0,0 +1,16 @@ +import { inject, observer } from "mobx-react"; +import React from "react"; + +const SubRoomInfoBody = ({ children }) => { + console.log("SRIB children - ", children); + return ( +
+
ROOM INFO BODY
+
Children - {children}
+
+ ); +}; + +export default inject(() => { + return {}; +})(observer(SubRoomInfoBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js new file mode 100644 index 0000000000..b6fd95a636 --- /dev/null +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js @@ -0,0 +1,16 @@ +import { inject, observer } from "mobx-react"; +import React from "react"; + +const SubRoomInfoHeader = ({ children }) => { + console.log("SRIH children - ", { children }); + return ( +
+
ROOM INFO HEADER
+
Children - {children}
+
+ ); +}; + +export default inject(() => { + return {}; +})(observer(SubRoomInfoHeader)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js new file mode 100644 index 0000000000..fb8a6ec29f --- /dev/null +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js @@ -0,0 +1,17 @@ +import { observer } from "mobx-react"; +import React from "react"; +import styled from "styled-components"; + +const RoomInfo = ({ children }) => { + const StyledRoomInfo = styled.div` + height: 100%; + width: 400px; + background-color: #ffffff; + border-left: 1px solid #eceef1; + padding: 12px 16px; + `; + + return {children}; +}; + +export default observer(RoomInfo); diff --git a/products/ASC.Files/Client/src/pages/Home/Notifications/index.js b/products/ASC.Files/Client/src/pages/Home/Notifications/index.js deleted file mode 100644 index 69b89df7df..0000000000 --- a/products/ASC.Files/Client/src/pages/Home/Notifications/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default as NotificationsBodyContent } from "./Body"; diff --git a/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js similarity index 76% rename from products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js rename to products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js index ab30cb010b..e6e0248201 100644 --- a/products/ASC.Files/Client/src/pages/Home/Notifications/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js @@ -3,10 +3,10 @@ import React from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; -const NotificationsBodyContent = () => { +const RoomInfoBodyContent = () => { return
NOTIFICATION BODY CONTENT
; }; export default inject(({}) => { return {}; -})(observer(NotificationsBodyContent)); +})(observer(RoomInfoBodyContent)); diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js new file mode 100644 index 0000000000..ea0ac5a6d2 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js @@ -0,0 +1,12 @@ +import { inject, observer } from "mobx-react"; +import React from "react"; +import { withTranslation } from "react-i18next"; +import { withRouter } from "react-router"; + +const RoomInfoHeaderContent = () => { + return
NOTIFICATION HEADER CONTENT
; +}; + +export default inject(({}) => { + return {}; +})(observer(RoomInfoHeaderContent)); diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js new file mode 100644 index 0000000000..f9edfc6327 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js @@ -0,0 +1,2 @@ +export { default as RoomInfoHeaderContent } from "./Header"; +export { default as RoomInfoBodyContent } from "./Body"; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index fed080d42c..4c86bd4764 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -317,7 +317,7 @@ class SectionHeaderContent extends React.Component { }; onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); - onToggleNotifications = () => this.props.toggleNotifications(); + onToggleRoomInfo = () => this.props.toggleRoomInfo(); getContextOptionsFolder = () => { const { t, personal } = this.props; @@ -560,9 +560,7 @@ class SectionHeaderContent extends React.Component { color="#A3A9AE" hoverColor="#657077" isFill={true} - onClick={ - this.onToggleNotifications - } + onClick={this.onToggleRoomInfo} className="trash-button" /> diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 98e8e853cc..462550ac2e 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -21,7 +21,8 @@ import { import DragTooltip from "../../components/DragTooltip"; import { createTreeFolders } from "../../helpers/files-helpers"; import MediaViewer from "./MediaViewer"; -import { NotificationsBodyContent } from "./Notifications"; +import { RoomInfoBodyContent } from "./RoomInfo"; +import { RoomInfoHeaderContent } from "./RoomInfo"; import { SectionBodyContent, SectionFilterContent, @@ -333,9 +334,13 @@ class PureHome extends React.Component { - - - + + + + + + + diff --git a/products/ASC.Files/Client/src/store/NotificationsStore.js b/products/ASC.Files/Client/src/store/RoomInfoStore.js similarity index 76% rename from products/ASC.Files/Client/src/store/NotificationsStore.js rename to products/ASC.Files/Client/src/store/RoomInfoStore.js index 2331eaa628..1f66cd094c 100644 --- a/products/ASC.Files/Client/src/store/NotificationsStore.js +++ b/products/ASC.Files/Client/src/store/RoomInfoStore.js @@ -1,6 +1,6 @@ import { makeAutoObservable } from "mobx"; -class NotificationsStore { +class RoomInfoStore { isVisible = false; constructor() { @@ -12,4 +12,4 @@ class NotificationsStore { }; } -export default NotificationsStore; +export default RoomInfoStore; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index 0e6e631c7f..ffb8135706 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -1,3 +1,4 @@ +import RoomInfoStore from "./RoomInfoStore"; import store from "studio/store"; import DialogsStore from "./DialogsStore"; @@ -9,7 +10,6 @@ import FormatsStore from "./FormatsStore"; import iconFormatsStore from "./IconFormatsStore"; import MediaViewerDataStore from "./MediaViewerDataStore"; import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; -import NotificationsStore from "./NotificationsStore"; import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; import selectedFilesStore from "./SelectedFilesStore"; @@ -73,7 +73,7 @@ const filesActionsStore = new FilesActionsStore( const versionHistoryStore = new VersionHistoryStore(filesStore); -const notificationsStore = new NotificationsStore(); +const roomInfoStore = new RoomInfoStore(); //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { @@ -88,7 +88,7 @@ const stores = { selectedFolderStore, filesActionsStore, selectedFilesStore, - notificationsStore, + roomInfoStore, }; export default stores; From 82c1c47be6efd7da828349905681cfca5e274782 Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 9 Feb 2022 21:08:22 +0300 Subject: [PATCH 04/81] working RoomInfoStore --- frontend.code-workspace | 114 +-- .../components/PageLayout/index.js | 2 + .../sub-components/room-info-body.js | 14 +- .../sub-components/room-info-header.js | 2 +- .../PageLayout/sub-components/room-info.js | 14 +- packages/asc-web-common/constants/index.js | 168 ++--- .../asc-web-common/store/SettingsStore.js | 661 +++++++++--------- .../src/pages/Home/RoomInfo/Body/index.js | 7 +- .../src/pages/Home/RoomInfo/Header/index.js | 2 - .../src/pages/Home/Section/Header/index.js | 14 +- .../Client/src/store/RoomInfoStore.js | 6 +- .../Client/src/store/SettingsStore.js | 344 ++++----- products/ASC.Files/Client/src/store/index.js | 2 +- 13 files changed, 696 insertions(+), 654 deletions(-) diff --git a/frontend.code-workspace b/frontend.code-workspace index ecd0bea263..1278b51607 100644 --- a/frontend.code-workspace +++ b/frontend.code-workspace @@ -1,61 +1,61 @@ { - "folders": [ - { - "name": "✨ appserver", - "path": "." + "folders": [ + { + "name": "✨ appserver", + "path": "." + }, + { + "name": "📦 @appserver/common", + "path": "packages\\asc-web-common" + }, + { + "name": "🚀 @appserver/files", + "path": "products\\ASC.Files\\Client" + }, + { + "name": "📦 @appserver/components", + "path": "packages\\asc-web-components" + }, + { + "name": "🚀 @appserver/people", + "path": "products\\ASC.People\\Client" + }, + { + "name": "🚀 @appserver/crm", + "path": "products\\ASC.Crm\\Client" + }, + { + "name": "🚀 @appserver/projects", + "path": "products\\ASC.Projects\\Client" + }, + { + "name": "🚀 @appserver/mail", + "path": "products\\ASC.Mail\\Client" + }, + { + "name": "🚀 @appserver/calendar", + "path": "products\\ASC.Calendar\\Client" + }, + { + "name": "🚀 @appserver/studio", + "path": "web\\ASC.Web.Client" + }, + { + "name": "🚀 @appserver/login", + "path": "web\\ASC.Web.Login" + }, + { + "name": "🚀 @appserver/editor", + "path": "web\\ASC.Web.Editor" + } + ], + "settings": { + "window.zoomLevel": 0, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "liveServer.settings.multiRootWorkspaceName": "✨ appserver" }, - { - "name": "📦 @appserver/common", - "path": "packages\\asc-web-common" - }, - { - "name": "📦 @appserver/components", - "path": "packages\\asc-web-components" - }, - { - "name": "🚀 @appserver/files", - "path": "products\\ASC.Files\\Client" - }, - { - "name": "🚀 @appserver/people", - "path": "products\\ASC.People\\Client" - }, - { - "name": "🚀 @appserver/crm", - "path": "products\\ASC.Crm\\Client" - }, - { - "name": "🚀 @appserver/projects", - "path": "products\\ASC.Projects\\Client" - }, - { - "name": "🚀 @appserver/mail", - "path": "products\\ASC.Mail\\Client" - }, - { - "name": "🚀 @appserver/calendar", - "path": "products\\ASC.Calendar\\Client" - }, - { - "name": "🚀 @appserver/studio", - "path": "web\\ASC.Web.Client" - }, - { - "name": "🚀 @appserver/login", - "path": "web\\ASC.Web.Login" - }, - { - "name": "🚀 @appserver/editor", - "path": "web\\ASC.Web.Editor" + "extensions": { + "recommendations": ["folke.vscode-monorepo-workspace"] } - ], - "settings": { - "window.zoomLevel": 0, - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "liveServer.settings.multiRootWorkspaceName": "✨ appserver" - }, - "extensions": { - "recommendations": ["folke.vscode-monorepo-workspace"] - } } diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 395eeede95..459875dc63 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -611,6 +611,8 @@ PageLayout.SectionHeader = SectionHeader; PageLayout.SectionFilter = SectionFilter; PageLayout.SectionBody = SectionBody; PageLayout.SectionPaging = SectionPaging; +PageLayout.RoomInfoHeader = RoomInfoHeader; +PageLayout.RoomInfoBody = RoomInfoBody; export default inject(({ auth }) => { const { isLoaded, settingsStore } = auth; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js index 3c5d08e0fa..8d16bdb10a 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js @@ -1,16 +1,22 @@ import { inject, observer } from "mobx-react"; import React from "react"; -const SubRoomInfoBody = ({ children }) => { - console.log("SRIB children - ", children); +const SubRoomInfoBody = ({ children, isVisible }) => { + console.log("Body children - ", children); + return (
+

Room Info Is {isVisible ? "Visible" : "Hidden"}

ROOM INFO BODY
Children - {children}
); }; -export default inject(() => { - return {}; +export default inject(({ roomInfoStore }) => { + let isVisible = false; + if (roomInfoStore) isVisible = roomInfoStore.isVisible; + return { + isVisible, + }; })(observer(SubRoomInfoBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js index b6fd95a636..e54db8f8d9 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js @@ -2,7 +2,7 @@ import { inject, observer } from "mobx-react"; import React from "react"; const SubRoomInfoHeader = ({ children }) => { - console.log("SRIH children - ", { children }); + console.log("Header children - ", { children }); return (
ROOM INFO HEADER
diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js index fb8a6ec29f..3c45560dea 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js @@ -1,8 +1,10 @@ -import { observer } from "mobx-react"; +import { inject, observer } from "mobx-react"; import React from "react"; import styled from "styled-components"; -const RoomInfo = ({ children }) => { +const RoomInfo = ({ children, isVisible }) => { + if (!isVisible) return null; + const StyledRoomInfo = styled.div` height: 100%; width: 400px; @@ -14,4 +16,10 @@ const RoomInfo = ({ children }) => { return {children}; }; -export default observer(RoomInfo); +export default inject(({ roomInfoStore }) => { + let isVisible = false; + if (roomInfoStore) isVisible = roomInfoStore.isVisible; + return { + isVisible, + }; +})(RoomInfo); diff --git a/packages/asc-web-common/constants/index.js b/packages/asc-web-common/constants/index.js index ac7e2d24e6..df648b133b 100644 --- a/packages/asc-web-common/constants/index.js +++ b/packages/asc-web-common/constants/index.js @@ -6,10 +6,10 @@ export const ARTICLE_PINNED_KEY = "asc_article_pinned_key"; * @readonly */ export const EmployeeActivationStatus = Object.freeze({ - NotActivated: 0, - Activated: 1, - Pending: 2, - AutoGenerated: 4, + NotActivated: 0, + Activated: 1, + Pending: 2, + AutoGenerated: 4, }); /** @@ -17,8 +17,8 @@ export const EmployeeActivationStatus = Object.freeze({ * @readonly */ export const EmployeeStatus = Object.freeze({ - Active: 1, - Disabled: 2, + Active: 1, + Disabled: 2, }); /** @@ -26,8 +26,8 @@ export const EmployeeStatus = Object.freeze({ * @readonly */ export const EmployeeType = Object.freeze({ - User: 1, - Guest: 2, + User: 1, + Guest: 2, }); /** @@ -35,18 +35,18 @@ export const EmployeeType = Object.freeze({ * @readonly */ export const FilterType = Object.freeze({ - None: 0, - FilesOnly: 1, - FoldersOnly: 2, - DocumentsOnly: 3, - PresentationsOnly: 4, - SpreadsheetsOnly: 5, - ImagesOnly: 7, - ByUser: 8, - ByDepartment: 9, - ArchiveOnly: 10, - ByExtension: 11, - MediaOnly: 12, + None: 0, + FilesOnly: 1, + FoldersOnly: 2, + DocumentsOnly: 3, + PresentationsOnly: 4, + SpreadsheetsOnly: 5, + ImagesOnly: 7, + ByUser: 8, + ByDepartment: 9, + ArchiveOnly: 10, + ByExtension: 11, + MediaOnly: 12, }); /** @@ -54,14 +54,14 @@ export const FilterType = Object.freeze({ * @readonly */ export const FileType = Object.freeze({ - Unknown: 0, - Archive: 1, - Video: 2, - Audio: 3, - Image: 4, - Spreadsheet: 5, - Presentation: 6, - Document: 7, + Unknown: 0, + Archive: 1, + Video: 2, + Audio: 3, + Image: 4, + Spreadsheet: 5, + Presentation: 6, + Document: 7, }); /** @@ -69,8 +69,8 @@ export const FileType = Object.freeze({ * @readonly */ export const FileAction = Object.freeze({ - Create: 0, - Rename: 1, + Create: 0, + Rename: 1, }); /** @@ -78,68 +78,68 @@ export const FileAction = Object.freeze({ * @readonly */ export const FolderType = Object.freeze({ - DEFAULT: 0, - COMMON: 1, - BUNCH: 2, - TRASH: 3, - USER: 5, - SHARE: 6, - Projects: 8, - Favorites: 10, - Recent: 11, - Templates: 12, - Privacy: 13, + DEFAULT: 0, + COMMON: 1, + BUNCH: 2, + TRASH: 3, + USER: 5, + SHARE: 6, + Projects: 8, + Favorites: 10, + Recent: 11, + Templates: 12, + Privacy: 13, }); export const ShareAccessRights = Object.freeze({ - None: 0, - FullAccess: 1, - ReadOnly: 2, - DenyAccess: 3, - Varies: 4, - Review: 5, - Comment: 6, - FormFilling: 7, - CustomFilter: 8, + None: 0, + FullAccess: 1, + ReadOnly: 2, + DenyAccess: 3, + Varies: 4, + Review: 5, + Comment: 6, + FormFilling: 7, + CustomFilter: 8, }); export const ConflictResolveType = Object.freeze({ - Skip: 0, - Overwrite: 1, - Duplicate: 2, + Skip: 0, + Overwrite: 1, + Duplicate: 2, }); export const providersData = Object.freeze({ - google: { - label: "google", - icon: "/static/images/share.google.react.svg", - }, - facebook: { - label: "facebook", - icon: "/static/images/share.facebook.react.svg", - }, - twitter: { - label: "twitter", - icon: "/static/images/share.twitter.react.svg", - iconOptions: { color: "#2AA3EF" }, - }, - linkedin: { - label: "linkedin", - icon: "/static/images/share.linkedin.react.svg", - }, + google: { + label: "google", + icon: "/static/images/share.google.react.svg", + }, + facebook: { + label: "facebook", + icon: "/static/images/share.facebook.react.svg", + }, + twitter: { + label: "twitter", + icon: "/static/images/share.twitter.react.svg", + iconOptions: { color: "#2AA3EF" }, + }, + linkedin: { + label: "linkedin", + icon: "/static/images/share.linkedin.react.svg", + }, }); export const LoaderStyle = { - title: "", - width: "100%", - height: "32", - backgroundColor: "#000000", - foregroundColor: "#000000", - backgroundOpacity: 0.1, - foregroundOpacity: 0.15, - borderRadius: "3", - radius: "3", - speed: 2, - animate: true, + title: "", + width: "100%", + height: "32", + backgroundColor: "#000000", + foregroundColor: "#000000", + backgroundOpacity: 0.1, + foregroundOpacity: 0.15, + borderRadius: "3", + radius: "3", + speed: 2, + animate: true, }; import config from "./AppServerConfig"; @@ -151,9 +151,9 @@ export const AppServerConfig = config; * @readonly */ export const TenantTrustedDomainsType = Object.freeze({ - None: 0, - Custom: 1, - All: 2, + None: 0, + Custom: 1, + All: 2, }); export const PasswordLimitSpecialCharacters = "!@#$%^&*"; diff --git a/packages/asc-web-common/store/SettingsStore.js b/packages/asc-web-common/store/SettingsStore.js index ae97b55929..ffa584c2f0 100644 --- a/packages/asc-web-common/store/SettingsStore.js +++ b/packages/asc-web-common/store/SettingsStore.js @@ -8,352 +8,357 @@ import { version } from "../package.json"; const { proxyURL } = AppServerConfig; class SettingsStore { - isLoading = false; - isLoaded = false; + isLoading = false; + isLoaded = false; - currentProductId = ""; - culture = "en-US"; - cultures = []; - trustedDomains = []; - trustedDomainsType = 0; - trustedDomains = []; - timezone = "UTC"; - timezones = []; - utcOffset = "00:00:00"; - utcHoursOffset = 0; - defaultPage = "/"; - homepage = ""; - datePattern = "M/d/yyyy"; - datePatternJQ = "00/00/0000"; - dateTimePattern = "dddd, MMMM d, yyyy h:mm:ss tt"; - datepicker = { - datePattern: "mm/dd/yy", - dateTimePattern: "DD, mm dd, yy h:mm:ss tt", - timePattern: "h:mm tt", - }; - organizationName = "ONLYOFFICE"; - greetingSettings = "Web Office Applications"; - enableAdmMess = false; - enabledJoin = false; - urlLicense = "https://gnu.org/licenses/gpl-3.0.html"; - urlSupport = "https://helpdesk.onlyoffice.com/"; - logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg"); - customNames = { - id: "Common", - userCaption: "User", - usersCaption: "Users", - groupCaption: "Group", - groupsCaption: "Groups", - userPostCaption: "Title", - regDateCaption: "Registration Date", - groupHeadCaption: "Head", - guestCaption: "Guest", - guestsCaption: "Guests", - }; - isDesktopClient = window["AscDesktopEditor"] !== undefined; - //isDesktopEncryption: desktopEncryption; - isEncryptionSupport = false; - encryptionKeys = null; + currentProductId = ""; + culture = "en-US"; + cultures = []; + trustedDomains = []; + trustedDomainsType = 0; + trustedDomains = []; + timezone = "UTC"; + timezones = []; + utcOffset = "00:00:00"; + utcHoursOffset = 0; + defaultPage = "/"; + homepage = ""; + datePattern = "M/d/yyyy"; + datePatternJQ = "00/00/0000"; + dateTimePattern = "dddd, MMMM d, yyyy h:mm:ss tt"; + datepicker = { + datePattern: "mm/dd/yy", + dateTimePattern: "DD, mm dd, yy h:mm:ss tt", + timePattern: "h:mm tt", + }; + organizationName = "ONLYOFFICE"; + greetingSettings = "Web Office Applications"; + enableAdmMess = false; + enabledJoin = false; + urlLicense = "https://gnu.org/licenses/gpl-3.0.html"; + urlSupport = "https://helpdesk.onlyoffice.com/"; + logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg"); + customNames = { + id: "Common", + userCaption: "User", + usersCaption: "Users", + groupCaption: "Group", + groupsCaption: "Groups", + userPostCaption: "Title", + regDateCaption: "Registration Date", + groupHeadCaption: "Head", + guestCaption: "Guest", + guestsCaption: "Guests", + }; + isDesktopClient = window["AscDesktopEditor"] !== undefined; + //isDesktopEncryption: desktopEncryption; + isEncryptionSupport = false; + encryptionKeys = null; - personal = false; + personal = false; - isHeaderVisible = false; - isTabletView = false; - isArticlePinned = - localStorage.getItem(ARTICLE_PINNED_KEY) === "true" || false; - isArticleVisible = false; - isBackdropVisible = false; + isHeaderVisible = false; + isTabletView = false; + isArticlePinned = + localStorage.getItem(ARTICLE_PINNED_KEY) === "true" || false; + isArticleVisible = false; + isBackdropVisible = false; - isArticleVisibleOnUnpin = false; + isArticleVisibleOnUnpin = false; - hashSettings = null; - title = ""; - ownerId = null; - nameSchemaId = null; - owner = {}; - wizardToken = null; - passwordSettings = null; - hasShortenService = false; + hashSettings = null; + title = ""; + ownerId = null; + nameSchemaId = null; + owner = {}; + wizardToken = null; + passwordSettings = null; + hasShortenService = false; - customSchemaList = []; - firebase = { - apiKey: "", - authDomain: "", - projectId: "", - storageBucket: "", - messagingSenderId: "", - appId: "", - measurementId: "", - }; - version = ""; - buildVersionInfo = { - appServer: version, - documentServer: "6.4.1", - }; - debugInfo = false; + customSchemaList = []; + firebase = { + apiKey: "", + authDomain: "", + projectId: "", + storageBucket: "", + messagingSenderId: "", + appId: "", + measurementId: "", + }; + version = ""; + buildVersionInfo = { + appServer: version, + documentServer: "6.4.1", + }; + debugInfo = false; - userFormValidation = /^[\p{L}\p{M}'\-]+$/gu; - folderFormValidation = new RegExp('[*+:"<>?|\\\\/]', "gim"); + userFormValidation = /^[\p{L}\p{M}'\-]+$/gu; + folderFormValidation = new RegExp('[*+:"<>?|\\\\/]', "gim"); - constructor() { - makeAutoObservable(this); - } - - get urlAuthKeys() { - const splitted = this.culture.split("-"); - const lang = splitted.length > 0 ? splitted[0] : "en"; - return `https://helpcenter.onlyoffice.com/${lang}/installation/groups-authorization-keys.aspx`; - } - - get wizardCompleted() { - return this.isLoaded && !this.wizardToken; - } - - get helpUrlCommonSettings() { - const substring = this.culture.substring(0, this.culture.indexOf("-")); - const lang = substring.length > 0 ? substring : "en"; - - return `https://helpcenter.onlyoffice.com/${lang}/administration/configuration.aspx#CustomizingPortal_block`; - } - - setIsArticleVisible = (visible) => { - this.isArticleVisible = this.isArticlePinned ? true : visible; - }; - - setIsBackdropVisible = (visible) => { - this.isBackdropVisible = visible; - }; - - hideArticle = () => { - this.setIsArticleVisible(false); - this.setIsBackdropVisible(false); - }; - - setValue = (key, value) => { - this[key] = value; - }; - - setDefaultPage = (defaultPage) => { - this.defaultPage = defaultPage; - }; - - getSettings = async () => { - const newSettings = await api.settings.getSettings(); - - if (window["AscDesktopEditor"] !== undefined || this.personal) { - const dp = combineUrl(proxyURL, "/products/files/"); - this.setDefaultPage(dp); + constructor() { + makeAutoObservable(this); } - Object.keys(newSettings).map((key) => { - if (key in this) { - this.setValue( - key, - key === "defaultPage" - ? combineUrl(proxyURL, newSettings[key]) - : newSettings[key] - ); - if (key === "culture") { - const language = localStorage.getItem(LANGUAGE); - if (!language || language == "undefined") { - localStorage.setItem(LANGUAGE, newSettings[key]); - } - } - if (key === "personal") { - window.AppServer = { - ...window.AppServer, - personal: newSettings[key], - }; - } - } else if (key === "passwordHash") { - this.setValue("hashSettings", newSettings[key]); - } - }); - - return newSettings; - }; - - getCurrentCustomSchema = async (id) => { - this.customNames = await api.settings.getCurrentCustomSchema(id); - }; - - getCustomSchemaList = async () => { - this.customSchemaList = await api.settings.getCustomSchemaList(); - }; - - getPortalSettings = async () => { - const origSettings = await this.getSettings(); - - if (origSettings.nameSchemaId) { - this.getCurrentCustomSchema(origSettings.nameSchemaId); + get urlAuthKeys() { + const splitted = this.culture.split("-"); + const lang = splitted.length > 0 ? splitted[0] : "en"; + return `https://helpcenter.onlyoffice.com/${lang}/installation/groups-authorization-keys.aspx`; } - }; - init = async () => { - this.setIsLoading(true); - - await Promise.all([this.getPortalSettings(), this.getBuildVersionInfo()]); - - this.setIsLoading(false); - this.setIsLoaded(true); - }; - - setIsLoading = (isLoading) => { - this.isLoading = isLoading; - }; - - setIsLoaded = (isLoaded) => { - this.isLoaded = isLoaded; - }; - - getPortalCultures = async () => { - this.cultures = await api.settings.getPortalCultures(); - }; - - setIsEncryptionSupport = (isEncryptionSupport) => { - this.isEncryptionSupport = isEncryptionSupport; - }; - - getIsEncryptionSupport = async () => { - const isEncryptionSupport = await api.files.getIsEncryptionSupport(); - this.setIsEncryptionSupport(isEncryptionSupport); - }; - - updateEncryptionKeys = (encryptionKeys) => { - this.encryptionKeys = encryptionKeys ?? {}; - }; - - setEncryptionKeys = async (keys) => { - await api.files.setEncryptionKeys(keys); - this.updateEncryptionKeys(keys); - }; - - getEncryptionKeys = async () => { - const encryptionKeys = await api.files.getEncryptionKeys(); - this.updateEncryptionKeys(encryptionKeys); - }; - - getOAuthToken = (tokenGetterWin) => { - return new Promise((resolve, reject) => { - localStorage.removeItem("code"); - let interval = null; - interval = setInterval(() => { - try { - const code = localStorage.getItem("code"); - - if (code) { - localStorage.removeItem("code"); - clearInterval(interval); - resolve(code); - } else if (tokenGetterWin && tokenGetterWin.closed) { - clearInterval(interval); - reject(); - } - } catch { - return; - } - }, 500); - }); - }; - - getLoginLink = (token, code) => { - return combineUrl(proxyURL, `/login.ashx?p=${token}&code=${code}`); - }; - - setModuleInfo = (homepage, productId) => { - if (this.homepage === homepage || this.currentProductId === productId) - return; - - console.log(`setModuleInfo('${homepage}', '${productId}')`); - - this.homepage = homepage; - this.setCurrentProductId(productId); - - const baseElm = document.getElementsByTagName("base"); - if (baseElm && baseElm.length === 1) { - const baseUrl = homepage - ? homepage[homepage.length - 1] === "/" - ? homepage - : `${homepage}/` - : "/"; - - console.log("SET base URL", baseUrl); - - baseElm[0].setAttribute("href", baseUrl); + get wizardCompleted() { + return this.isLoaded && !this.wizardToken; } - }; - setCurrentProductId = (currentProductId) => { - this.currentProductId = currentProductId; - }; + get helpUrlCommonSettings() { + const substring = this.culture.substring(0, this.culture.indexOf("-")); + const lang = substring.length > 0 ? substring : "en"; - getPortalOwner = async () => { - const owner = await api.people.getUserById(this.ownerId); - this.owner = owner; - return owner; - }; + return `https://helpcenter.onlyoffice.com/${lang}/administration/configuration.aspx#CustomizingPortal_block`; + } - setWizardComplete = () => { - this.wizardToken = null; - }; - - setPasswordSettings = (passwordSettings) => { - this.passwordSettings = passwordSettings; - }; - - getPortalPasswordSettings = async (confirmKey = null) => { - const settings = await api.settings.getPortalPasswordSettings(confirmKey); - this.setPasswordSettings(settings); - }; - - setTimezones = (timezones) => { - this.timezones = timezones; - }; - - getPortalTimezones = async (token = undefined) => { - const timezones = await api.settings.getPortalTimezones(token); - this.setTimezones(timezones); - }; - - setHeaderVisible = (isHeaderVisible) => { - this.isHeaderVisible = isHeaderVisible; - }; - - setIsTabletView = (isTabletView) => { - this.isTabletView = isTabletView; - }; - - setArticlePinned = (isPinned) => { - isPinned - ? localStorage.setItem(ARTICLE_PINNED_KEY, isPinned) - : localStorage.removeItem(ARTICLE_PINNED_KEY); - this.isArticlePinned = isPinned; - }; - - setArticleVisibleOnUnpin = (visible) => { - this.isArticleVisibleOnUnpin = visible; - }; - - get firebaseHelper() { - window.firebaseHelper = new FirebaseHelper(this.firebase); - return window.firebaseHelper; - } - - getBuildVersionInfo = async () => { - const versionInfo = await api.settings.getBuildVersion(); - this.setBuildVersionInfo(versionInfo); - }; - - setBuildVersionInfo = (versionInfo) => { - this.buildVersionInfo = { - ...this.buildVersionInfo, - appServer: version, - ...versionInfo, + setIsArticleVisible = (visible) => { + this.isArticleVisible = this.isArticlePinned ? true : visible; }; - if (!this.buildVersionInfo.documentServer) - this.buildVersionInfo.documentServer = "6.4.1"; - }; + setIsBackdropVisible = (visible) => { + this.isBackdropVisible = visible; + }; + + hideArticle = () => { + this.setIsArticleVisible(false); + this.setIsBackdropVisible(false); + }; + + setValue = (key, value) => { + this[key] = value; + }; + + setDefaultPage = (defaultPage) => { + this.defaultPage = defaultPage; + }; + + getSettings = async () => { + const newSettings = await api.settings.getSettings(); + + if (window["AscDesktopEditor"] !== undefined || this.personal) { + const dp = combineUrl(proxyURL, "/products/files/"); + this.setDefaultPage(dp); + } + + Object.keys(newSettings).map((key) => { + if (key in this) { + this.setValue( + key, + key === "defaultPage" + ? combineUrl(proxyURL, newSettings[key]) + : newSettings[key] + ); + if (key === "culture") { + const language = localStorage.getItem(LANGUAGE); + if (!language || language == "undefined") { + localStorage.setItem(LANGUAGE, newSettings[key]); + } + } + if (key === "personal") { + window.AppServer = { + ...window.AppServer, + personal: newSettings[key], + }; + } + } else if (key === "passwordHash") { + this.setValue("hashSettings", newSettings[key]); + } + }); + + return newSettings; + }; + + getCurrentCustomSchema = async (id) => { + this.customNames = await api.settings.getCurrentCustomSchema(id); + }; + + getCustomSchemaList = async () => { + this.customSchemaList = await api.settings.getCustomSchemaList(); + }; + + getPortalSettings = async () => { + const origSettings = await this.getSettings(); + + if (origSettings.nameSchemaId) { + this.getCurrentCustomSchema(origSettings.nameSchemaId); + } + }; + + init = async () => { + this.setIsLoading(true); + + await Promise.all([ + this.getPortalSettings(), + this.getBuildVersionInfo(), + ]); + + this.setIsLoading(false); + this.setIsLoaded(true); + }; + + setIsLoading = (isLoading) => { + this.isLoading = isLoading; + }; + + setIsLoaded = (isLoaded) => { + this.isLoaded = isLoaded; + }; + + getPortalCultures = async () => { + this.cultures = await api.settings.getPortalCultures(); + }; + + setIsEncryptionSupport = (isEncryptionSupport) => { + this.isEncryptionSupport = isEncryptionSupport; + }; + + getIsEncryptionSupport = async () => { + const isEncryptionSupport = await api.files.getIsEncryptionSupport(); + this.setIsEncryptionSupport(isEncryptionSupport); + }; + + updateEncryptionKeys = (encryptionKeys) => { + this.encryptionKeys = encryptionKeys ?? {}; + }; + + setEncryptionKeys = async (keys) => { + await api.files.setEncryptionKeys(keys); + this.updateEncryptionKeys(keys); + }; + + getEncryptionKeys = async () => { + const encryptionKeys = await api.files.getEncryptionKeys(); + this.updateEncryptionKeys(encryptionKeys); + }; + + getOAuthToken = (tokenGetterWin) => { + return new Promise((resolve, reject) => { + localStorage.removeItem("code"); + let interval = null; + interval = setInterval(() => { + try { + const code = localStorage.getItem("code"); + + if (code) { + localStorage.removeItem("code"); + clearInterval(interval); + resolve(code); + } else if (tokenGetterWin && tokenGetterWin.closed) { + clearInterval(interval); + reject(); + } + } catch { + return; + } + }, 500); + }); + }; + + getLoginLink = (token, code) => { + return combineUrl(proxyURL, `/login.ashx?p=${token}&code=${code}`); + }; + + setModuleInfo = (homepage, productId) => { + if (this.homepage === homepage || this.currentProductId === productId) + return; + + console.log(`setModuleInfo('${homepage}', '${productId}')`); + + this.homepage = homepage; + this.setCurrentProductId(productId); + + const baseElm = document.getElementsByTagName("base"); + if (baseElm && baseElm.length === 1) { + const baseUrl = homepage + ? homepage[homepage.length - 1] === "/" + ? homepage + : `${homepage}/` + : "/"; + + console.log("SET base URL", baseUrl); + + baseElm[0].setAttribute("href", baseUrl); + } + }; + + setCurrentProductId = (currentProductId) => { + this.currentProductId = currentProductId; + }; + + getPortalOwner = async () => { + const owner = await api.people.getUserById(this.ownerId); + this.owner = owner; + return owner; + }; + + setWizardComplete = () => { + this.wizardToken = null; + }; + + setPasswordSettings = (passwordSettings) => { + this.passwordSettings = passwordSettings; + }; + + getPortalPasswordSettings = async (confirmKey = null) => { + const settings = await api.settings.getPortalPasswordSettings( + confirmKey + ); + this.setPasswordSettings(settings); + }; + + setTimezones = (timezones) => { + this.timezones = timezones; + }; + + getPortalTimezones = async (token = undefined) => { + const timezones = await api.settings.getPortalTimezones(token); + this.setTimezones(timezones); + }; + + setHeaderVisible = (isHeaderVisible) => { + this.isHeaderVisible = isHeaderVisible; + }; + + setIsTabletView = (isTabletView) => { + this.isTabletView = isTabletView; + }; + + setArticlePinned = (isPinned) => { + isPinned + ? localStorage.setItem(ARTICLE_PINNED_KEY, isPinned) + : localStorage.removeItem(ARTICLE_PINNED_KEY); + this.isArticlePinned = isPinned; + }; + + setArticleVisibleOnUnpin = (visible) => { + this.isArticleVisibleOnUnpin = visible; + }; + + get firebaseHelper() { + window.firebaseHelper = new FirebaseHelper(this.firebase); + return window.firebaseHelper; + } + + getBuildVersionInfo = async () => { + const versionInfo = await api.settings.getBuildVersion(); + this.setBuildVersionInfo(versionInfo); + }; + + setBuildVersionInfo = (versionInfo) => { + this.buildVersionInfo = { + ...this.buildVersionInfo, + appServer: version, + ...versionInfo, + }; + + if (!this.buildVersionInfo.documentServer) + this.buildVersionInfo.documentServer = "6.4.1"; + }; } export default SettingsStore; diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js index e6e0248201..8ef1c68542 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js @@ -1,12 +1,7 @@ -import { inject, observer } from "mobx-react"; import React from "react"; -import { withTranslation } from "react-i18next"; -import { withRouter } from "react-router"; const RoomInfoBodyContent = () => { return
NOTIFICATION BODY CONTENT
; }; -export default inject(({}) => { - return {}; -})(observer(RoomInfoBodyContent)); +export default RoomInfoBodyContent; diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js index ea0ac5a6d2..188e9458a4 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js @@ -1,7 +1,5 @@ import { inject, observer } from "mobx-react"; import React from "react"; -import { withTranslation } from "react-i18next"; -import { withRouter } from "react-router"; const RoomInfoHeaderContent = () => { return
NOTIFICATION HEADER CONTENT
; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 4c86bd4764..e897f6b618 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -119,6 +119,11 @@ const StyledContainer = styled.div` } } } + + .room-info-button { + position: absolute; + right: 0; + } } .group-button-menu-container { @@ -553,7 +558,7 @@ class SectionHeaderContent extends React.Component { /> )} - + <> - + )}
@@ -584,6 +589,7 @@ export default inject( filesActionsStore, settingsStore, treeFoldersStore, + roomInfoStore, }) => { const { setSelected, @@ -621,6 +627,7 @@ export default inject( downloadAction, getHeaderMenu, } = filesActionsStore; + const toggleRoomInfo = roomInfoStore.toggleIsVisible; return { isDesktop: auth.settingsStore.isDesktopClient, @@ -630,6 +637,7 @@ export default inject( currentFolderId: selectedFolderStore.id, filter, canCreate, + toggleRoomInfo, isHeaderVisible, isHeaderIndeterminate, isHeaderChecked, diff --git a/products/ASC.Files/Client/src/store/RoomInfoStore.js b/products/ASC.Files/Client/src/store/RoomInfoStore.js index 1f66cd094c..ef4171cf70 100644 --- a/products/ASC.Files/Client/src/store/RoomInfoStore.js +++ b/products/ASC.Files/Client/src/store/RoomInfoStore.js @@ -8,8 +8,12 @@ class RoomInfoStore { } toggleIsVisible = () => { - isVisible = !this.isVisible; + this.isVisible = !this.isVisible; }; + + get isVisible() { + return this.isVisible; + } } export default RoomInfoStore; diff --git a/products/ASC.Files/Client/src/store/SettingsStore.js b/products/ASC.Files/Client/src/store/SettingsStore.js index ca73b1e763..52c375fbdd 100644 --- a/products/ASC.Files/Client/src/store/SettingsStore.js +++ b/products/ASC.Files/Client/src/store/SettingsStore.js @@ -1,188 +1,204 @@ -import { makeAutoObservable } from "mobx"; import api from "@appserver/common/api"; -import axios from "axios"; import { - setFavoritesSetting, - setRecentSetting, + setFavoritesSetting, + setRecentSetting, } from "@appserver/common/api/files"; import { FolderType } from "@appserver/common/constants"; +import axios from "axios"; +import { makeAutoObservable } from "mobx"; class SettingsStore { - thirdPartyStore; - treeFoldersStore; + thirdPartyStore; + treeFoldersStore; - isErrorSettings = null; - expandedSetting = null; + isErrorSettings = null; + expandedSetting = null; - confirmDelete = null; - enableThirdParty = null; - forcesave = null; - storeForcesave = null; - storeOriginalFiles = null; - updateIfExist = null; - favoritesSection = null; - recentSection = null; - hideConfirmConvertSave = null; - chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb + confirmDelete = null; + enableThirdParty = null; + forcesave = null; + storeForcesave = null; + storeOriginalFiles = null; + updateIfExist = null; + favoritesSection = null; + recentSection = null; + hideConfirmConvertSave = null; + chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb - settingsIsLoaded = false; + roomInfoIsVisible = false; - constructor(thirdPartyStore, treeFoldersStore) { - makeAutoObservable(this); + settingsIsLoaded = false; - this.thirdPartyStore = thirdPartyStore; - this.treeFoldersStore = treeFoldersStore; - } + constructor(thirdPartyStore, treeFoldersStore) { + makeAutoObservable(this); - setIsLoaded = (isLoaded) => { - this.settingsIsLoaded = isLoaded; - }; - - get isLoadedSettingsTree() { - return ( - this.confirmDelete !== null && - this.enableThirdParty !== null && - this.forcesave !== null && - this.storeForcesave !== null && - this.storeOriginalFiles !== null && - this.updateIfExist !== null - ); - } - - setFilesSettings = (settings) => { - const settingsItems = Object.keys(settings); - for (let key of settingsItems) { - this[key] = settings[key]; + this.thirdPartyStore = thirdPartyStore; + this.treeFoldersStore = treeFoldersStore; } - }; - setIsErrorSettings = (isError) => { - this.isErrorSettings = isError; - }; - - setExpandSettingsTree = (expandedSetting) => { - this.expandedSetting = expandedSetting; - }; - - getFilesSettings = () => { - if (!this.isLoadedSettingsTree) { - return api.files - .getSettingsFiles() - .then((settings) => { - this.setFilesSettings(settings); - if (settings.enableThirdParty) { - this.setIsLoaded(true); - return axios - .all([ - api.files.getThirdPartyCapabilities(), - api.files.getThirdPartyList(), - ]) - .then(([capabilities, providers]) => { - for (let item of capabilities) { - item.splice(1, 1); - } - this.thirdPartyStore.setThirdPartyCapabilities(capabilities); //TODO: Out of bounds read: 1 - this.thirdPartyStore.setThirdPartyProviders(providers); - }); - } - return this.setIsLoaded(true); - }) - .catch(() => this.setIsErrorSettings(true)); - } else { - return Promise.resolve(); + get roomInfoIsVisible() { + return this.roomInfoIsVisible; } - }; - setFilesSetting = (setting, val) => { - this[setting] = val; - }; + setIsLoaded = (isLoaded) => { + this.settingsIsLoaded = isLoaded; + }; - setUpdateIfExist = (data, setting) => - api.files - .updateIfExist(data) - .then((res) => this.setFilesSetting(setting, res)); - - setStoreOriginal = (data, setting) => - api.files - .storeOriginal(data) - .then((res) => this.setFilesSetting(setting, res)); - - setConfirmDelete = (data, setting) => - api.files - .changeDeleteConfirm(data) - .then((res) => this.setFilesSetting(setting, res)); - - setStoreForceSave = (data, setting) => - api.files - .storeForceSave(data) - .then((res) => this.setFilesSetting(setting, res)); - - setEnableThirdParty = async (data, setting) => { - const res = await api.files.thirdParty(data); - this.setFilesSetting(setting, res); - - if (data) { - return axios - .all([ - api.files.getThirdPartyCapabilities(), - api.files.getThirdPartyList(), - ]) - .then(([capabilities, providers]) => { - for (let item of capabilities) { - item.splice(1, 1); - } - this.thirdPartyStore.setThirdPartyCapabilities(capabilities); //TODO: Out of bounds read: 1 - this.thirdPartyStore.setThirdPartyProviders(providers); - }); - } else { - return Promise.resolve(); - } - }; - - setForceSave = (data, setting) => - api.files.forceSave(data).then((res) => this.setFilesSetting(setting, res)); - - updateRootTreeFolders = (set, rootFolderIndex, folderType) => { - const { - getFoldersTree, - treeFolders, - setTreeFolders, - } = this.treeFoldersStore; - - getFoldersTree().then((root) => { - if (set) { - const rootFolder = root.find((x) => x.rootFolderType === folderType); - const newTreeFolders = treeFolders; - newTreeFolders.splice(rootFolderIndex, 0, rootFolder); - setTreeFolders(newTreeFolders); - } else { - const newTreeFolders = treeFolders.filter( - (x) => x.rootFolderType !== folderType + get isLoadedSettingsTree() { + return ( + this.confirmDelete !== null && + this.enableThirdParty !== null && + this.forcesave !== null && + this.storeForcesave !== null && + this.storeOriginalFiles !== null && + this.updateIfExist !== null ); - setTreeFolders(newTreeFolders); - } - }); - }; + } - setFavoritesSetting = (set, setting) => { - return setFavoritesSetting(set).then((res) => { - this.setFilesSetting(setting, res); - this.updateRootTreeFolders(set, 2, FolderType.Favorites); - }); - }; + setFilesSettings = (settings) => { + const settingsItems = Object.keys(settings); + for (let key of settingsItems) { + this[key] = settings[key]; + } + }; - setRecentSetting = (set, setting) => { - return setRecentSetting(set).then((res) => { - this.setFilesSetting(setting, res); - const index = this.treeFoldersStore.favoritesFolder ? 3 : 2; - this.updateRootTreeFolders(set, index, FolderType.Recent); - }); - }; + setIsErrorSettings = (isError) => { + this.isErrorSettings = isError; + }; - hideConfirmConvert = async (save = true) => { - const hideConfirmConvertSave = await api.files.hideConfirmConvert(save); - this.hideConfirmConvertSave = hideConfirmConvertSave; - }; + setExpandSettingsTree = (expandedSetting) => { + this.expandedSetting = expandedSetting; + }; + + getFilesSettings = () => { + if (!this.isLoadedSettingsTree) { + return api.files + .getSettingsFiles() + .then((settings) => { + this.setFilesSettings(settings); + if (settings.enableThirdParty) { + this.setIsLoaded(true); + return axios + .all([ + api.files.getThirdPartyCapabilities(), + api.files.getThirdPartyList(), + ]) + .then(([capabilities, providers]) => { + for (let item of capabilities) { + item.splice(1, 1); + } + this.thirdPartyStore.setThirdPartyCapabilities( + capabilities + ); //TODO: Out of bounds read: 1 + this.thirdPartyStore.setThirdPartyProviders( + providers + ); + }); + } + return this.setIsLoaded(true); + }) + .catch(() => this.setIsErrorSettings(true)); + } else { + return Promise.resolve(); + } + }; + + setFilesSetting = (setting, val) => { + this[setting] = val; + }; + + setUpdateIfExist = (data, setting) => + api.files + .updateIfExist(data) + .then((res) => this.setFilesSetting(setting, res)); + + setStoreOriginal = (data, setting) => + api.files + .storeOriginal(data) + .then((res) => this.setFilesSetting(setting, res)); + + setConfirmDelete = (data, setting) => + api.files + .changeDeleteConfirm(data) + .then((res) => this.setFilesSetting(setting, res)); + + setStoreForceSave = (data, setting) => + api.files + .storeForceSave(data) + .then((res) => this.setFilesSetting(setting, res)); + + setEnableThirdParty = async (data, setting) => { + const res = await api.files.thirdParty(data); + this.setFilesSetting(setting, res); + + if (data) { + return axios + .all([ + api.files.getThirdPartyCapabilities(), + api.files.getThirdPartyList(), + ]) + .then(([capabilities, providers]) => { + for (let item of capabilities) { + item.splice(1, 1); + } + this.thirdPartyStore.setThirdPartyCapabilities( + capabilities + ); //TODO: Out of bounds read: 1 + this.thirdPartyStore.setThirdPartyProviders(providers); + }); + } else { + return Promise.resolve(); + } + }; + + setForceSave = (data, setting) => + api.files + .forceSave(data) + .then((res) => this.setFilesSetting(setting, res)); + + updateRootTreeFolders = (set, rootFolderIndex, folderType) => { + const { + getFoldersTree, + treeFolders, + setTreeFolders, + } = this.treeFoldersStore; + + getFoldersTree().then((root) => { + if (set) { + const rootFolder = root.find( + (x) => x.rootFolderType === folderType + ); + const newTreeFolders = treeFolders; + newTreeFolders.splice(rootFolderIndex, 0, rootFolder); + setTreeFolders(newTreeFolders); + } else { + const newTreeFolders = treeFolders.filter( + (x) => x.rootFolderType !== folderType + ); + setTreeFolders(newTreeFolders); + } + }); + }; + + setFavoritesSetting = (set, setting) => { + return setFavoritesSetting(set).then((res) => { + this.setFilesSetting(setting, res); + this.updateRootTreeFolders(set, 2, FolderType.Favorites); + }); + }; + + setRecentSetting = (set, setting) => { + return setRecentSetting(set).then((res) => { + this.setFilesSetting(setting, res); + const index = this.treeFoldersStore.favoritesFolder ? 3 : 2; + this.updateRootTreeFolders(set, index, FolderType.Recent); + }); + }; + + hideConfirmConvert = async (save = true) => { + const hideConfirmConvertSave = await api.files.hideConfirmConvert(save); + this.hideConfirmConvertSave = hideConfirmConvertSave; + }; } export default SettingsStore; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index ffb8135706..7e31bac994 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -1,4 +1,3 @@ -import RoomInfoStore from "./RoomInfoStore"; import store from "studio/store"; import DialogsStore from "./DialogsStore"; @@ -11,6 +10,7 @@ import iconFormatsStore from "./IconFormatsStore"; import MediaViewerDataStore from "./MediaViewerDataStore"; import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; +import RoomInfoStore from "./RoomInfoStore"; import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; import selectedFilesStore from "./SelectedFilesStore"; import selectedFolderStore from "./SelectedFolderStore"; From 830d56007785e37cc84d61ac0639f32de99c8762 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 10 Feb 2022 16:18:16 +0300 Subject: [PATCH 05/81] added responsiveness --- .../sub-components/room-info-body.js | 12 +-- .../sub-components/room-info-header.js | 3 +- .../PageLayout/sub-components/room-info.js | 87 +++++++++++++++++-- packages/asc-web-common/custom.scss | 50 +++++------ .../ASC.Files/Client/public/images/panel.svg | 3 + .../src/pages/Home/RoomInfo/Header/index.js | 25 +++++- .../src/pages/Home/Section/Header/index.js | 21 ++++- .../Client/src/store/RoomInfoStore.js | 4 + 8 files changed, 160 insertions(+), 45 deletions(-) create mode 100644 products/ASC.Files/Client/public/images/panel.svg diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js index 8d16bdb10a..dfc665530f 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js @@ -1,22 +1,18 @@ import { inject, observer } from "mobx-react"; import React from "react"; -const SubRoomInfoBody = ({ children, isVisible }) => { +const SubRoomInfoBody = ({ children }) => { console.log("Body children - ", children); return (
-

Room Info Is {isVisible ? "Visible" : "Hidden"}

ROOM INFO BODY
-
Children - {children}
+
Children:
+ {children}
); }; export default inject(({ roomInfoStore }) => { - let isVisible = false; - if (roomInfoStore) isVisible = roomInfoStore.isVisible; - return { - isVisible, - }; + return {}; })(observer(SubRoomInfoBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js index e54db8f8d9..8086f33200 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js @@ -6,7 +6,8 @@ const SubRoomInfoHeader = ({ children }) => { return (
ROOM INFO HEADER
-
Children - {children}
+
Children:
+ {children}
); }; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js index 3c45560dea..5791088dcc 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js @@ -1,25 +1,100 @@ -import { inject, observer } from "mobx-react"; +import IconButton from "@appserver/components/icon-button"; +import { mobile, tablet } from "@appserver/components/utils/device"; +import { inject } from "mobx-react"; import React from "react"; import styled from "styled-components"; -const RoomInfo = ({ children, isVisible }) => { +const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { if (!isVisible) return null; + const StyledRoomInfoWrapper = styled.div` + height: auto; + width: auto; + background: rgba(6, 22, 38, 0.2); + backdrop-filter: blur(18px); + + @media ${tablet} { + z-index: 191; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + `; + const StyledRoomInfo = styled.div` height: 100%; - width: 400px; + width: 368px; background-color: #ffffff; border-left: 1px solid #eceef1; - padding: 12px 16px; + display: flex; + flex-direction: column; + align-items: center; + + @media ${tablet} { + position: absolute; + border: none; + right: 0; + width: 480px; + max-width: calc(100vw - 37px); + } + + @media ${mobile} { + bottom: 0; + height: 80%; + max-width: none; + width: 100%; + } `; - return {children}; + const StyledCloseButtonWrapper = styled.div` + position: absolute; + display: none; + @media ${tablet} { + display: block; + top: 0; + left: 0; + margin-top: 18px; + margin-left: -27px; + } + @media ${mobile} { + right: 0; + left: auto; + margin-top: -27px; + margin-right: 10px; + } + `; + + return ( + + + + + + {children} + + + ); }; export default inject(({ roomInfoStore }) => { let isVisible = false; - if (roomInfoStore) isVisible = roomInfoStore.isVisible; + let toggleIsVisible = () => {}; + if (roomInfoStore) { + isVisible = roomInfoStore.isVisible; + toggleIsVisible = roomInfoStore.toggleIsVisible; + } return { isVisible, + toggleIsVisible, }; })(RoomInfo); diff --git a/packages/asc-web-common/custom.scss b/packages/asc-web-common/custom.scss index 414f373b0c..37887bc202 100644 --- a/packages/asc-web-common/custom.scss +++ b/packages/asc-web-common/custom.scss @@ -5,48 +5,48 @@ $font-family-base: "Open Sans", sans-serif; html, body { - height: 100%; + height: 100%; } #root { - min-height: 100%; - position: relative; + min-height: 100%; + position: relative; - .pageLoader { - position: fixed; - left: calc(50% - 20px); - top: 35%; - } + .pageLoader { + position: fixed; + left: calc(50% - 20px); + top: 35%; + } } body { - margin: 0; + margin: 0; } body.loading * { - cursor: wait !important; + cursor: wait !important; } body.drag-cursor * { - cursor: url('data:image/svg+xml;utf8,') - 6 6, - auto !important; + cursor: url('data:image/svg+xml;utf8,') + 6 6, + auto !important; } body.desktop { - user-select: none; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; - mozuserselect: none; + user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + mozuserselect: none; } #snackbar { - display: flex; - justify-content: center; - position: fixed; - width: calc(100vw - 60px); - padding: 30px; - bottom: 15px; + display: flex; + justify-content: center; + position: fixed; + width: calc(100vw - 60px); + padding: 30px; + bottom: 15px; } diff --git a/products/ASC.Files/Client/public/images/panel.svg b/products/ASC.Files/Client/public/images/panel.svg new file mode 100644 index 0000000000..8da7c48595 --- /dev/null +++ b/products/ASC.Files/Client/public/images/panel.svg @@ -0,0 +1,3 @@ + + + diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js index 188e9458a4..6efe87a745 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js @@ -1,8 +1,31 @@ import { inject, observer } from "mobx-react"; import React from "react"; +import { styled } from "styled-components"; const RoomInfoHeaderContent = () => { - return
NOTIFICATION HEADER CONTENT
; + const StyledRoomInfoHeader = styled.div` + width: 100%; + height: 53px; + display: flex; + justify-content: space-between; + align-item: center; + padding: 8px 16px; + + //styleName: H2 21-28 - Bold; + font-family: Open Sans; + font-size: 21px; + font-style: normal; + font-weight: 700; + line-height: 28px; + letter-spacing: 0px; + text-align: left; + `; + + return ( + + Room + + ); }; export default inject(({}) => { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index e897f6b618..95b4be11fa 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -31,7 +31,7 @@ const StyledContainer = styled.div` @media ${tablet} { margin: 0 -16px; - width: calc(100% + 32px); + //width: calc(100% + 32px); } } @@ -83,6 +83,7 @@ const StyledContainer = styled.div` @media ${tablet} { margin-left: auto; + margin-right: 32px; & > div:first-child { padding: 8px 8px 8px 8px; @@ -99,6 +100,8 @@ const StyledContainer = styled.div` } @media ${tablet} { + margin-left: auto; + margin-right: 32px; & > div:first-child { padding: 8px 8px 8px 8px; margin-right: -8px; @@ -114,13 +117,17 @@ const StyledContainer = styled.div` } @media ${tablet} { + margin-left: auto; + margin-right: 32px; & > div:first-child { + padding: 3px; margin-right: -8px; } } } .room-info-button { + margin-bottom: -1px; position: absolute; right: 0; } @@ -560,10 +567,13 @@ class SectionHeaderContent extends React.Component { )} <> { + this.isVisible = bool; + }; + get isVisible() { return this.isVisible; } From b2fb153042bd72a6ed6e8a837dc8dc11e9f02a43 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 10 Feb 2022 18:52:27 +0300 Subject: [PATCH 06/81] fixed child rendering; styled header --- .../sub-components/room-info-body.js | 14 +- .../sub-components/room-info-header.js | 72 ++- .../PageLayout/sub-components/room-info.js | 22 +- .../src/pages/Home/RoomInfo/Body/index.js | 15 +- .../src/pages/Home/RoomInfo/Header/index.js | 27 +- .../src/pages/Home/Section/Body/index.js | 422 +++++++++--------- .../Client/src/store/SettingsStore.js | 2 - 7 files changed, 315 insertions(+), 259 deletions(-) diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js index dfc665530f..bf1cbab478 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js @@ -2,17 +2,13 @@ import { inject, observer } from "mobx-react"; import React from "react"; const SubRoomInfoBody = ({ children }) => { - console.log("Body children - ", children); + const content = children.props.children; - return ( -
-
ROOM INFO BODY
-
Children:
- {children} -
- ); + return <>{content}; }; -export default inject(({ roomInfoStore }) => { +SubRoomInfoBody.displayName = "SubRoomInfoBody"; + +export default inject(() => { return {}; })(observer(SubRoomInfoBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js index 8086f33200..880f2ae588 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js @@ -1,17 +1,67 @@ -import { inject, observer } from "mobx-react"; -import React from "react"; +import IconButton from "@appserver/components/icon-button"; +import Text from "@appserver/components/text"; + +import { inject, observer } from "mobx-react"; +import PropTypes from "prop-types"; + +import React from "react"; +import { tablet } from "@appserver/components/utils/device"; + +import styled from "styled-components"; + +const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { + const content = children.props.children; + + console.log(toggleIsVisible); + + const StyledRoomInfoHeader = styled.div` + width: 100%; + height: 53px; + display: flex; + justify-content: space-between; + align-items: center; + margin: 8px 0; + + /* .close-btn { + @media ${tablet} { + display: none; + } + } */ + `; -const SubRoomInfoHeader = ({ children }) => { - console.log("Header children - ", { children }); return ( -
-
ROOM INFO HEADER
-
Children:
- {children} -
+ + + {content} + + + ); }; -export default inject(() => { - return {}; +SubRoomInfoHeader.displayName = "SubRoomInfoHeader"; + +SubRoomInfoHeader.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + PropTypes.any, + ]), + toggleIsVisible: PropTypes.func, +}; + +export default inject(({ roomInfoStore }) => { + let toggleIsVisible = () => {}; + if (roomInfoStore) { + toggleIsVisible = roomInfoStore.toggleIsVisible; + } + return { toggleIsVisible }; })(observer(SubRoomInfoHeader)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js index 5791088dcc..5805fdab64 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js @@ -1,5 +1,7 @@ import IconButton from "@appserver/components/icon-button"; import { mobile, tablet } from "@appserver/components/utils/device"; +import PropTypes from "prop-types"; + import { inject } from "mobx-react"; import React from "react"; import styled from "styled-components"; @@ -31,20 +33,20 @@ const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { display: flex; flex-direction: column; align-items: center; + padding: 0 16px; @media ${tablet} { position: absolute; border: none; right: 0; - width: 480px; - max-width: calc(100vw - 37px); + width: 448px; + max-width: calc(100vw - 69px); } @media ${mobile} { bottom: 0; height: 80%; - max-width: none; - width: 100%; + max-width: calc(100vw - 32px); } `; @@ -72,7 +74,7 @@ const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { { ); }; +RoomInfo.propTypes = { + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + PropTypes.any, + ]), + isVisible: PropTypes.bool, + toggleIsVisible: PropTypes.func, +}; + export default inject(({ roomInfoStore }) => { let isVisible = false; let toggleIsVisible = () => {}; diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js index 8ef1c68542..6098e01118 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js @@ -1,7 +1,18 @@ import React from "react"; +import { withRouter } from "react-router"; +import { withTranslation } from "react-i18next"; +import { observer, inject } from "mobx-react"; const RoomInfoBodyContent = () => { - return
NOTIFICATION BODY CONTENT
; + return
ROOM INFO BODY CONTENT
; }; -export default RoomInfoBodyContent; +export default inject(({}) => { + return {}; +})( + withRouter( + withTranslation(["Home", "Common", "Translations"])( + observer(RoomInfoBodyContent) + ) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js index 6efe87a745..538449d98e 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js @@ -1,31 +1,10 @@ import { inject, observer } from "mobx-react"; import React from "react"; -import { styled } from "styled-components"; +import { withRouter } from "react-router"; +import { withTranslation } from "react-i18next"; const RoomInfoHeaderContent = () => { - const StyledRoomInfoHeader = styled.div` - width: 100%; - height: 53px; - display: flex; - justify-content: space-between; - align-item: center; - padding: 8px 16px; - - //styleName: H2 21-28 - Bold; - font-family: Open Sans; - font-size: 21px; - font-style: normal; - font-weight: 700; - line-height: 28px; - letter-spacing: 0px; - text-align: left; - `; - - return ( - - Room - - ); + return <>Room; }; export default inject(({}) => { 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 4efa962c00..0dd5988669 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 @@ -13,238 +13,248 @@ import { Consumer } from "@appserver/components/utils/context"; let currentDroppable = null; const SectionBodyContent = (props) => { - const { - t, - tReady, - fileActionId, - isEmptyFilesList, - folderId, - dragging, - setDragging, - startDrag, - setStartDrag, - setTooltipPosition, - isRecycleBinFolder, - moveDragItems, - viewAs, - setSelection, - setBufferSelection, - tooltipPageX, - tooltipPageY, - } = props; + const { + t, + tReady, + fileActionId, + isEmptyFilesList, + folderId, + dragging, + setDragging, + startDrag, + setStartDrag, + setTooltipPosition, + isRecycleBinFolder, + moveDragItems, + viewAs, + setSelection, + setBufferSelection, + tooltipPageX, + tooltipPageY, + } = props; - useEffect(() => { - const customScrollElm = document.querySelector( - "#customScrollBar > .scroll-body" - ); + useEffect(() => { + const customScrollElm = document.querySelector( + "#customScrollBar > .scroll-body" + ); - if (isMobile) { - customScrollElm && customScrollElm.scrollTo(0, 0); - } + if (isMobile) { + customScrollElm && customScrollElm.scrollTo(0, 0); + } - !isMobile && window.addEventListener("mousedown", onMouseDown); - startDrag && window.addEventListener("mouseup", onMouseUp); - startDrag && document.addEventListener("mousemove", onMouseMove); + !isMobile && window.addEventListener("mousedown", onMouseDown); + startDrag && window.addEventListener("mouseup", onMouseUp); + startDrag && document.addEventListener("mousemove", onMouseMove); - document.addEventListener("dragover", onDragOver); - document.addEventListener("dragleave", onDragLeaveDoc); - document.addEventListener("drop", onDropEvent); + document.addEventListener("dragover", onDragOver); + document.addEventListener("dragleave", onDragLeaveDoc); + document.addEventListener("drop", onDropEvent); - return () => { - window.removeEventListener("mousedown", onMouseDown); - window.removeEventListener("mouseup", onMouseUp); - document.removeEventListener("mousemove", onMouseMove); + return () => { + window.removeEventListener("mousedown", onMouseDown); + window.removeEventListener("mouseup", onMouseUp); + document.removeEventListener("mousemove", onMouseMove); - document.removeEventListener("dragover", onDragOver); - document.removeEventListener("dragleave", onDragLeaveDoc); - document.removeEventListener("drop", onDropEvent); + document.removeEventListener("dragover", onDragOver); + document.removeEventListener("dragleave", onDragLeaveDoc); + document.removeEventListener("drop", onDropEvent); + }; + }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); + + const onMouseDown = (e) => { + if ( + e.target.closest(".scroll-body") && + !e.target.closest(".files-item") && + !e.target.closest(".not-selectable") && + !e.target.closest(".table-container_group-menu") + ) { + setSelection([]); + setBufferSelection(null); + } }; - }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); - const onMouseDown = (e) => { - if ( - e.target.closest(".scroll-body") && - !e.target.closest(".files-item") && - !e.target.closest(".not-selectable") && - !e.target.closest(".table-container_group-menu") - ) { - setSelection([]); - setBufferSelection(null); - } - }; - - const onMouseMove = (e) => { - if ( - Math.abs(e.pageX - tooltipPageX) < 5 && - Math.abs(e.pageY - tooltipPageY) < 5 - ) { - return false; - } - - if (!dragging) { - document.body.classList.add("drag-cursor"); - setDragging(true); - } - - setTooltipPosition(e.pageX, e.pageY); - const wrapperElement = document.elementFromPoint(e.clientX, e.clientY); - if (!wrapperElement) { - return; - } - - const droppable = wrapperElement.closest(".droppable"); - if (currentDroppable !== droppable) { - if (currentDroppable) { - if (viewAs === "table") { - const value = currentDroppable.getAttribute("value"); - const classElements = document.getElementsByClassName(value); - - for (let cl of classElements) { - cl.classList.remove("droppable-hover"); - } - } else { - currentDroppable.classList.remove("droppable-hover"); + const onMouseMove = (e) => { + if ( + Math.abs(e.pageX - tooltipPageX) < 5 && + Math.abs(e.pageY - tooltipPageY) < 5 + ) { + return false; } - } - currentDroppable = droppable; - if (currentDroppable) { - if (viewAs === "table") { - const value = currentDroppable.getAttribute("value"); - const classElements = document.getElementsByClassName(value); - - for (let cl of classElements) { - cl.classList.add("droppable-hover"); - } - } else { - currentDroppable.classList.add("droppable-hover"); - currentDroppable = droppable; + if (!dragging) { + document.body.classList.add("drag-cursor"); + setDragging(true); } - } - } - }; - const onMouseUp = (e) => { - document.body.classList.remove("drag-cursor"); + setTooltipPosition(e.pageX, e.pageY); + const wrapperElement = document.elementFromPoint(e.clientX, e.clientY); + if (!wrapperElement) { + return; + } - const treeElem = e.target.closest(".tree-drag"); - const treeDataValue = treeElem?.dataset?.value; - const splitValue = treeDataValue && treeDataValue.split(" "); - const isDragging = splitValue && splitValue.includes("dragging"); - const treeValue = isDragging ? splitValue[0] : null; + const droppable = wrapperElement.closest(".droppable"); + if (currentDroppable !== droppable) { + if (currentDroppable) { + if (viewAs === "table") { + const value = currentDroppable.getAttribute("value"); + const classElements = document.getElementsByClassName( + value + ); - const elem = e.target.closest(".droppable"); - const title = elem && elem.dataset.title; - const value = elem && elem.getAttribute("value"); - if ((!value && !treeValue) || isRecycleBinFolder) { - setDragging(false); - setStartDrag(false); - return; - } + for (let cl of classElements) { + cl.classList.remove("droppable-hover"); + } + } else { + currentDroppable.classList.remove("droppable-hover"); + } + } + currentDroppable = droppable; - const folderId = value ? value.split("_")[1] : treeValue; + if (currentDroppable) { + if (viewAs === "table") { + const value = currentDroppable.getAttribute("value"); + const classElements = document.getElementsByClassName( + value + ); - setStartDrag(false); - setDragging(false); - onMoveTo(folderId, title); - return; - }; + for (let cl of classElements) { + cl.classList.add("droppable-hover"); + } + } else { + currentDroppable.classList.add("droppable-hover"); + currentDroppable = droppable; + } + } + } + }; - const onMoveTo = (destFolderId, title) => { - const id = isNaN(+destFolderId) ? destFolderId : +destFolderId; - moveDragItems(id, title, { - copy: t("Translations:CopyOperation"), - move: t("Translations:MoveToOperation"), - }); //TODO: then catch - }; + const onMouseUp = (e) => { + document.body.classList.remove("drag-cursor"); - const onDropEvent = () => { - setDragging(false); - }; + const treeElem = e.target.closest(".tree-drag"); + const treeDataValue = treeElem?.dataset?.value; + const splitValue = treeDataValue && treeDataValue.split(" "); + const isDragging = splitValue && splitValue.includes("dragging"); + const treeValue = isDragging ? splitValue[0] : null; - const onDragOver = (e) => { - e.preventDefault(); - if ( - e.dataTransfer.items.length > 0 && - e.dataTransfer.dropEffect !== "none" - ) { - setDragging(true); - } - }; + const elem = e.target.closest(".droppable"); + const title = elem && elem.dataset.title; + const value = elem && elem.getAttribute("value"); + if ((!value && !treeValue) || isRecycleBinFolder) { + setDragging(false); + setStartDrag(false); + return; + } - const onDragLeaveDoc = (e) => { - e.preventDefault(); - if (!e.relatedTarget || !e.dataTransfer.items.length) { - setDragging(false); - } - }; + const folderId = value ? value.split("_")[1] : treeValue; - //console.log("Files Home SectionBodyContent render", props); + setStartDrag(false); + setDragging(false); + onMoveTo(folderId, title); + return; + }; - return ( - - {(context) => - (!fileActionId && isEmptyFilesList) || null ? ( - - ) : viewAs === "tile" ? ( - - ) : viewAs === "table" ? ( - - ) : ( - - ) - } - - ); + const onMoveTo = (destFolderId, title) => { + const id = isNaN(+destFolderId) ? destFolderId : +destFolderId; + moveDragItems(id, title, { + copy: t("Translations:CopyOperation"), + move: t("Translations:MoveToOperation"), + }); //TODO: then catch + }; + + const onDropEvent = () => { + setDragging(false); + }; + + const onDragOver = (e) => { + e.preventDefault(); + if ( + e.dataTransfer.items.length > 0 && + e.dataTransfer.dropEffect !== "none" + ) { + setDragging(true); + } + }; + + const onDragLeaveDoc = (e) => { + e.preventDefault(); + if (!e.relatedTarget || !e.dataTransfer.items.length) { + setDragging(false); + } + }; + + //console.log("Files Home SectionBodyContent render", props); + + return ( + + {(context) => + (!fileActionId && isEmptyFilesList) || null ? ( + + ) : viewAs === "tile" ? ( + + ) : viewAs === "table" ? ( + + ) : ( + + ) + } + + ); }; export default inject( - ({ - filesStore, - selectedFolderStore, - treeFoldersStore, - filesActionsStore, - }) => { - const { - fileActionStore, - isEmptyFilesList, - dragging, - setDragging, - viewAs, - setTooltipPosition, - startDrag, - setStartDrag, - setSelection, - tooltipPageX, - tooltipPageY, - setBufferSelection, - } = filesStore; + ({ + filesStore, + selectedFolderStore, + treeFoldersStore, + filesActionsStore, + }) => { + const { + fileActionStore, + isEmptyFilesList, + dragging, + setDragging, + viewAs, + setTooltipPosition, + startDrag, + setStartDrag, + setSelection, + tooltipPageX, + tooltipPageY, + setBufferSelection, + } = filesStore; - return { - dragging, - startDrag, - setStartDrag, - fileActionId: fileActionStore.id, - isEmptyFilesList, - setDragging, - folderId: selectedFolderStore.id, - setTooltipPosition, - isRecycleBinFolder: treeFoldersStore.isRecycleBinFolder, - moveDragItems: filesActionsStore.moveDragItems, - viewAs, - setSelection, - setBufferSelection, - tooltipPageX, - tooltipPageY, - }; - } + return { + dragging, + startDrag, + setStartDrag, + fileActionId: fileActionStore.id, + isEmptyFilesList, + setDragging, + folderId: selectedFolderStore.id, + setTooltipPosition, + isRecycleBinFolder: treeFoldersStore.isRecycleBinFolder, + moveDragItems: filesActionsStore.moveDragItems, + viewAs, + setSelection, + setBufferSelection, + tooltipPageX, + tooltipPageY, + }; + } )( - withRouter( - withTranslation(["Home", "Common", "Translations"])( - withLoader(observer(SectionBodyContent))() + withRouter( + withTranslation(["Home", "Common", "Translations"])( + withLoader(observer(SectionBodyContent))() + ) ) - ) ); diff --git a/products/ASC.Files/Client/src/store/SettingsStore.js b/products/ASC.Files/Client/src/store/SettingsStore.js index 52c375fbdd..c9d5806f5f 100644 --- a/products/ASC.Files/Client/src/store/SettingsStore.js +++ b/products/ASC.Files/Client/src/store/SettingsStore.js @@ -25,8 +25,6 @@ class SettingsStore { hideConfirmConvertSave = null; chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb - roomInfoIsVisible = false; - settingsIsLoaded = false; constructor(thirdPartyStore, treeFoldersStore) { From 46fd2f0f7591557df93669c37b23d904e9c2bae4 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 11 Feb 2022 17:30:07 +0300 Subject: [PATCH 07/81] added isVisible toogle to GroupMenu --- .../sub-components/room-info-header.js | 9 +- .../PageLayout/sub-components/room-info.js | 2 +- .../table-container/StyledTableContainer.js | 5 +- .../table-container/TableGroupMenu.js | 10 ++- .../src/pages/Home/RoomInfo/Body/index.js | 14 ++-- .../src/pages/Home/Section/Header/index.js | 83 ++++++++++++------- .../Client/src/store/SelectedFilesStore.js | 36 ++++---- 7 files changed, 97 insertions(+), 62 deletions(-) diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js index 880f2ae588..5968f7f325 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js @@ -1,12 +1,9 @@ import IconButton from "@appserver/components/icon-button"; import Text from "@appserver/components/text"; - +import { tablet } from "@appserver/components/utils/device"; import { inject, observer } from "mobx-react"; import PropTypes from "prop-types"; - import React from "react"; -import { tablet } from "@appserver/components/utils/device"; - import styled from "styled-components"; const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { @@ -22,11 +19,11 @@ const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { align-items: center; margin: 8px 0; - /* .close-btn { + .close-btn { @media ${tablet} { display: none; } - } */ + } `; return ( diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js index 5805fdab64..8efb75b41d 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/room-info.js @@ -16,7 +16,7 @@ const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { backdrop-filter: blur(18px); @media ${tablet} { - z-index: 191; + z-index: 200; position: absolute; top: 0; bottom: 0; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 7e3d63d192..befb0778d0 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -1,8 +1,9 @@ +import { isMobile } from "react-device-detect"; import styled, { css } from "styled-components"; + +import Scrollbar from "../scrollbar"; import Base from "../themes/base"; import { mobile, tablet } from "../utils/device"; -import Scrollbar from "../scrollbar"; -import { isMobile } from "react-device-detect"; const StyledTableContainer = styled.div` -moz-user-select: none; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index dd42f3b419..c8e00ff77b 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -1,16 +1,18 @@ -import React from "react"; import PropTypes from "prop-types"; +import React from "react"; +import { useTranslation } from "react-i18next"; + import Checkbox from "../checkbox"; -import { StyledTableGroupMenu, StyledScrollbar } from "./StyledTableContainer"; import ComboBox from "../combobox"; import GroupMenuItem from "./GroupMenuItem"; -import { useTranslation } from "react-i18next"; +import { StyledScrollbar, StyledTableGroupMenu } from "./StyledTableContainer"; const TableGroupMenu = (props) => { const { isChecked, isIndeterminate, headerMenu, + infoPanelToggle, onChange, checkboxOptions, checkboxMargin, @@ -53,6 +55,7 @@ const TableGroupMenu = (props) => { {headerMenu.map((item, index) => ( ))} + {infoPanelToggle} @@ -63,6 +66,7 @@ TableGroupMenu.propTypes = { isChecked: PropTypes.bool, isIndeterminate: PropTypes.bool, headerMenu: PropTypes.arrayOf(PropTypes.object).isRequired, + infoPanelToggle: PropTypes.node, checkboxOptions: PropTypes.any.isRequired, onClick: PropTypes.func, onChange: PropTypes.func, diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js index 6098e01118..1aedefc54c 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js @@ -1,14 +1,16 @@ +import { inject, observer } from "mobx-react"; import React from "react"; -import { withRouter } from "react-router"; import { withTranslation } from "react-i18next"; -import { observer, inject } from "mobx-react"; +import { withRouter } from "react-router"; -const RoomInfoBodyContent = () => { - return
ROOM INFO BODY CONTENT
; +const RoomInfoBodyContent = (selectedFilesStore) => { + return
{selectedFilesStore.fileInfo}
; }; -export default inject(({}) => { - return {}; +export default inject(({ selectedFilesStore }) => { + //const { selectedFilesStore } = filesStore; + console.log(selectedFilesStore); + return { selectedFilesStore }; })( withRouter( withTranslation(["Home", "Common", "Translations"])( diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 95b4be11fa..3ceb8b9245 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -22,16 +22,15 @@ const StyledContainer = styled.div` props.viewAs === "table" ? css` margin: 0px -20px; - width: calc(100% + 44px); + width: calc(100% + 40px); ` : css` margin: 0px -24px; width: calc(100% + 48px); `} - @media ${tablet} { margin: 0 -16px; - //width: calc(100% + 32px); + width: calc(100% + 32px); } } @@ -45,16 +44,16 @@ const StyledContainer = styled.div` props.isRootFolder ? "auto auto 1fr" : props.canCreate - ? "auto auto auto auto 1fr" - : "auto auto auto 1fr"}; + ? "auto auto auto auto auto 1fr" + : "auto auto auto auto 1fr"}; @media ${tablet} { grid-template-columns: ${(props) => props.isRootFolder - ? "1fr auto" + ? "auto auto 1fr" : props.canCreate - ? "auto 1fr auto auto" - : "auto 1fr auto"}; + ? "auto auto auto auto 1fr" + : "auto auto auto 1fr"}; ${(props) => !props.isLoading && "top: 7px;"} } `} @@ -125,12 +124,6 @@ const StyledContainer = styled.div` } } } - - .room-info-button { - margin-bottom: -1px; - position: absolute; - right: 0; - } } .group-button-menu-container { @@ -185,6 +178,32 @@ const StyledContainer = styled.div` } `; +const StyledInfoPanelToggleWrapper = styled.div` + display: flex; + margin-left: auto; + align-items: center; + align-self: center; + justify-content: center; + + .info-panel-toggle-bg { + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: ${(props) => + props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; + } + + ${(props) => + props.isHeaderVisible && + css` + margin-right: 24px; + padding-left: 12px; + `} +`; + class SectionHeaderContent extends React.Component { constructor(props) { super(props); @@ -433,6 +452,7 @@ class SectionHeaderContent extends React.Component { isHeaderVisible, isHeaderChecked, isHeaderIndeterminate, + isRoomInfoVisible, isRootFolder, title, canCreate, @@ -449,6 +469,24 @@ class SectionHeaderContent extends React.Component { const isLoading = !title || !tReady; const headerMenu = getHeaderMenu(t); + const infoPanelToggle = ( + +
+ +
+
+ ); + return ( {(context) => ( @@ -469,6 +507,7 @@ class SectionHeaderContent extends React.Component { isChecked={isHeaderChecked} isIndeterminate={isHeaderIndeterminate} headerMenu={headerMenu} + infoPanelToggle={infoPanelToggle} /> ) : (
@@ -565,20 +604,7 @@ class SectionHeaderContent extends React.Component { /> )} - <> - - + {infoPanelToggle} )}
@@ -638,6 +664,7 @@ export default inject( getHeaderMenu, } = filesActionsStore; + //const { toggleRoomInfo, isRoomInfoVisible } = roomInfoStore; const toggleRoomInfo = roomInfoStore.toggleIsVisible; const isRoomInfoVisible = roomInfoStore.isVisible; diff --git a/products/ASC.Files/Client/src/store/SelectedFilesStore.js b/products/ASC.Files/Client/src/store/SelectedFilesStore.js index cf7681320d..9cf072a5ed 100644 --- a/products/ASC.Files/Client/src/store/SelectedFilesStore.js +++ b/products/ASC.Files/Client/src/store/SelectedFilesStore.js @@ -1,25 +1,29 @@ import { makeObservable, action, observable } from "mobx"; class SelectedFilesStore { - folderId = null; - fileInfo = null; + folderId = null; + fileInfo = null; - constructor() { - makeObservable(this, { - fileInfo: observable, - folderId: observable, + constructor() { + makeObservable(this, { + fileInfo: observable, + folderId: observable, - setFolderId: action, - setFile: action, - }); - } + setFolderId: action, + setFile: action, + }); + } - setFolderId = (id) => { - this.folderId = id; - }; - setFile = (obj) => { - this.fileInfo = obj; - }; + setFolderId = (id) => { + this.folderId = id; + }; + setFile = (obj) => { + this.fileInfo = obj; + }; + + get fileInfo() { + return this.fileInfo; + } } export default new SelectedFilesStore(); From 6c22190b289374d0f8f02c8b412082937ccde916 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 11 Feb 2022 17:35:18 +0300 Subject: [PATCH 08/81] rename to info-panel --- .../components/PageLayout/index.js | 50 +++++++++---------- .../{room-info-body.js => info-panel-body.js} | 6 +-- ...om-info-header.js => info-panel-header.js} | 20 ++++---- .../{room-info.js => info-panel.js} | 31 ++++++------ .../{RoomInfo => InfoPanel}/Body/index.js | 4 +- .../{RoomInfo => InfoPanel}/Header/index.js | 4 +- .../Client/src/pages/Home/InfoPanel/index.js | 2 + .../Client/src/pages/Home/RoomInfo/index.js | 2 - .../src/pages/Home/Section/Header/index.js | 22 ++++---- .../ASC.Files/Client/src/pages/Home/index.js | 16 +++--- .../{RoomInfoStore.js => InfoPanelStore.js} | 4 +- .../Client/src/store/SettingsStore.js | 4 +- products/ASC.Files/Client/src/store/index.js | 6 +-- 13 files changed, 85 insertions(+), 86 deletions(-) rename packages/asc-web-common/components/PageLayout/sub-components/{room-info-body.js => info-panel-body.js} (60%) rename packages/asc-web-common/components/PageLayout/sub-components/{room-info-header.js => info-panel-header.js} (75%) rename packages/asc-web-common/components/PageLayout/sub-components/{room-info.js => info-panel.js} (81%) rename products/ASC.Files/Client/src/pages/Home/{RoomInfo => InfoPanel}/Body/index.js (83%) rename products/ASC.Files/Client/src/pages/Home/{RoomInfo => InfoPanel}/Header/index.js (75%) create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/index.js delete mode 100644 products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js rename products/ASC.Files/Client/src/store/{RoomInfoStore.js => InfoPanelStore.js} (86%) diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 459875dc63..16c3455f74 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -15,9 +15,9 @@ import SubArticleBody from "./sub-components/article-body"; import SubArticleHeader from "./sub-components/article-header"; import SubArticleMainButton from "./sub-components/article-main-button"; import ArticlePinPanel from "./sub-components/article-pin-panel"; -import RoomInfo from "./sub-components/room-info"; -import SubRoomInfoBody from "./sub-components/room-info-body"; -import SubRoomInfoHeader from "./sub-components/room-info-header"; +import InfoPanel from "./sub-components/info-panel"; +import SubInfoPanelBody from "./sub-components/info-panel-body"; +import SubInfoPanelHeader from "./sub-components/info-panel-header"; import Section from "./sub-components/section"; import SubSectionBody from "./sub-components/section-body"; import SubSectionBodyContent from "./sub-components/section-body-content"; @@ -87,15 +87,15 @@ function SectionPaging() { } SectionPaging.displayName = "SectionPaging"; -function RoomInfoBody() { +function InfoPanelBody() { return null; } -RoomInfoBody.displayName = "RoomInfoBody"; +InfoPanelBody.displayName = "InfoPanelBody"; -function RoomInfoHeader() { +function InfoPanelHeader() { return null; } -RoomInfoHeader.displayName = "RoomInfoHeader"; +InfoPanelHeader.displayName = "InfoPanelHeader"; class PageLayout extends React.Component { static ArticleHeader = ArticleHeader; @@ -105,8 +105,8 @@ class PageLayout extends React.Component { static SectionFilter = SectionFilter; static SectionBody = SectionBody; static SectionPaging = SectionPaging; - static RoomInfoBody = RoomInfoBody; - static RoomInfoHeader = RoomInfoHeader; + static InfoPanelBody = InfoPanelBody; + static InfoPanelHeader = InfoPanelHeader; constructor(props) { super(props); @@ -257,8 +257,8 @@ class PageLayout extends React.Component { let sectionFilterContent = null; let sectionPagingContent = null; let sectionBodyContent = null; - let roomInfoBodyContent = null; - let roomInfoHeaderContent = null; + let infoPanelBodyContent = null; + let infoPanelHeaderContent = null; React.Children.forEach(children, (child) => { const childType = @@ -288,11 +288,11 @@ class PageLayout extends React.Component { case SectionBody.displayName: sectionBodyContent = child; break; - case RoomInfoBody.displayName: - roomInfoBodyContent = child; + case InfoPanelBody.displayName: + infoPanelBodyContent = child; break; - case RoomInfoHeader.displayName: - roomInfoHeaderContent = child; + case InfoPanelHeader.displayName: + infoPanelHeaderContent = child; break; default: break; @@ -524,14 +524,14 @@ class PageLayout extends React.Component { /> )} - - - {roomInfoHeaderContent} - - - {roomInfoBodyContent} - - + + + {infoPanelHeaderContent} + + + {infoPanelBodyContent} + + )} @@ -611,8 +611,8 @@ PageLayout.SectionHeader = SectionHeader; PageLayout.SectionFilter = SectionFilter; PageLayout.SectionBody = SectionBody; PageLayout.SectionPaging = SectionPaging; -PageLayout.RoomInfoHeader = RoomInfoHeader; -PageLayout.RoomInfoBody = RoomInfoBody; +PageLayout.InfoPanelHeader = InfoPanelHeader; +PageLayout.InfoPanelBody = InfoPanelBody; export default inject(({ auth }) => { const { isLoaded, settingsStore } = auth; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js similarity index 60% rename from packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js rename to packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js index bf1cbab478..aedc82aa61 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-body.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js @@ -1,14 +1,14 @@ import { inject, observer } from "mobx-react"; import React from "react"; -const SubRoomInfoBody = ({ children }) => { +const SubInfoPanelBody = ({ children }) => { const content = children.props.children; return <>{content}; }; -SubRoomInfoBody.displayName = "SubRoomInfoBody"; +SubInfoPanelBody.displayName = "SubInfoPanelBody"; export default inject(() => { return {}; -})(observer(SubRoomInfoBody)); +})(observer(SubInfoPanelBody)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js similarity index 75% rename from packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js rename to packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js index 5968f7f325..85a987c081 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js @@ -6,12 +6,12 @@ import PropTypes from "prop-types"; import React from "react"; import styled from "styled-components"; -const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { +const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { const content = children.props.children; console.log(toggleIsVisible); - const StyledRoomInfoHeader = styled.div` + const StyledInfoPanelHeader = styled.div` width: 100%; height: 53px; display: flex; @@ -27,7 +27,7 @@ const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { `; return ( - + {content} @@ -40,13 +40,13 @@ const SubRoomInfoHeader = ({ children, toggleIsVisible }) => { hoverColor="#657077" isFill={true} /> - + ); }; -SubRoomInfoHeader.displayName = "SubRoomInfoHeader"; +SubInfoPanelHeader.displayName = "SubInfoPanelHeader"; -SubRoomInfoHeader.propTypes = { +SubInfoPanelHeader.propTypes = { children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), PropTypes.node, @@ -55,10 +55,10 @@ SubRoomInfoHeader.propTypes = { toggleIsVisible: PropTypes.func, }; -export default inject(({ roomInfoStore }) => { +export default inject(({ infoPanelStore }) => { let toggleIsVisible = () => {}; - if (roomInfoStore) { - toggleIsVisible = roomInfoStore.toggleIsVisible; + if (infoPanelStore) { + toggleIsVisible = infoPanelStore.toggleIsVisible; } return { toggleIsVisible }; -})(observer(SubRoomInfoHeader)); +})(observer(SubInfoPanelHeader)); diff --git a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js similarity index 81% rename from packages/asc-web-common/components/PageLayout/sub-components/room-info.js rename to packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index 8efb75b41d..23f2599865 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/room-info.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -1,15 +1,14 @@ import IconButton from "@appserver/components/icon-button"; import { mobile, tablet } from "@appserver/components/utils/device"; -import PropTypes from "prop-types"; - import { inject } from "mobx-react"; +import PropTypes from "prop-types"; import React from "react"; import styled from "styled-components"; -const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { +const InfoPanel = ({ children, isVisible, toggleIsVisible }) => { if (!isVisible) return null; - const StyledRoomInfoWrapper = styled.div` + const StyledInfoPanelWrapper = styled.div` height: auto; width: auto; background: rgba(6, 22, 38, 0.2); @@ -25,7 +24,7 @@ const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { } `; - const StyledRoomInfo = styled.div` + const StyledInfoPanel = styled.div` height: 100%; width: 368px; background-color: #ffffff; @@ -69,8 +68,8 @@ const RoomInfo = ({ children, isVisible, toggleIsVisible }) => { `; return ( - - + + { color="#ffffff" hoverColor="#657077" isFill={true} - className="room-info-button" + className="info-panel-button" /> {children} - - + + ); }; -RoomInfo.propTypes = { +InfoPanel.propTypes = { children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), PropTypes.node, @@ -98,15 +97,15 @@ RoomInfo.propTypes = { toggleIsVisible: PropTypes.func, }; -export default inject(({ roomInfoStore }) => { +export default inject(({ infoPanelStore }) => { let isVisible = false; let toggleIsVisible = () => {}; - if (roomInfoStore) { - isVisible = roomInfoStore.isVisible; - toggleIsVisible = roomInfoStore.toggleIsVisible; + if (infoPanelStore) { + isVisible = infoPanelStore.isVisible; + toggleIsVisible = infoPanelStore.toggleIsVisible; } return { isVisible, toggleIsVisible, }; -})(RoomInfo); +})(InfoPanel); diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js similarity index 83% rename from products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js rename to products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 1aedefc54c..7f5c170c9c 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -3,7 +3,7 @@ import React from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; -const RoomInfoBodyContent = (selectedFilesStore) => { +const InfoPanelBodyContent = (selectedFilesStore) => { return
{selectedFilesStore.fileInfo}
; }; @@ -14,7 +14,7 @@ export default inject(({ selectedFilesStore }) => { })( withRouter( withTranslation(["Home", "Common", "Translations"])( - observer(RoomInfoBodyContent) + observer(InfoPanelBodyContent) ) ) ); diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js similarity index 75% rename from products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js rename to products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js index 538449d98e..389d6bba53 100644 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js @@ -3,10 +3,10 @@ import React from "react"; import { withRouter } from "react-router"; import { withTranslation } from "react-i18next"; -const RoomInfoHeaderContent = () => { +const InfoPanelHeaderContent = () => { return <>Room; }; export default inject(({}) => { return {}; -})(observer(RoomInfoHeaderContent)); +})(observer(InfoPanelHeaderContent)); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/index.js new file mode 100644 index 0000000000..ea39524769 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/index.js @@ -0,0 +1,2 @@ +export { default as InfoPanelHeaderContent } from "./Header"; +export { default as InfoPanelBodyContent } from "./Body"; diff --git a/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js b/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js deleted file mode 100644 index f9edfc6327..0000000000 --- a/products/ASC.Files/Client/src/pages/Home/RoomInfo/index.js +++ /dev/null @@ -1,2 +0,0 @@ -export { default as RoomInfoHeaderContent } from "./Header"; -export { default as RoomInfoBodyContent } from "./Body"; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 3ceb8b9245..44fddd7237 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -348,7 +348,7 @@ class SectionHeaderContent extends React.Component { }; onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); - onToggleRoomInfo = () => this.props.toggleRoomInfo(); + onToggleInfoPanel = () => this.props.toggleInfoPanel(); getContextOptionsFolder = () => { const { t, personal } = this.props; @@ -452,7 +452,7 @@ class SectionHeaderContent extends React.Component { isHeaderVisible, isHeaderChecked, isHeaderIndeterminate, - isRoomInfoVisible, + isInfoPanelVisible, isRootFolder, title, canCreate, @@ -471,7 +471,7 @@ class SectionHeaderContent extends React.Component { const infoPanelToggle = (
@@ -479,9 +479,9 @@ class SectionHeaderContent extends React.Component { className="info-panel-toggle" iconName="images/panel.svg" size="16" - color={isRoomInfoVisible ? "#3B72A7" : "#A3A9AE"} + color={isInfoPanelVisible ? "#3B72A7" : "#A3A9AE"} isFill={true} - onClick={this.onToggleRoomInfo} + onClick={this.onToggleInfoPanel} />
@@ -625,7 +625,7 @@ export default inject( filesActionsStore, settingsStore, treeFoldersStore, - roomInfoStore, + infoPanelStore, }) => { const { setSelected, @@ -664,9 +664,9 @@ export default inject( getHeaderMenu, } = filesActionsStore; - //const { toggleRoomInfo, isRoomInfoVisible } = roomInfoStore; - const toggleRoomInfo = roomInfoStore.toggleIsVisible; - const isRoomInfoVisible = roomInfoStore.isVisible; + //const { toggleInfoPanel, isInfoPanelVisible } = infoPanelStore; + const toggleInfoPanel = infoPanelStore.toggleIsVisible; + const isInfoPanelVisible = infoPanelStore.isVisible; return { isDesktop: auth.settingsStore.isDesktopClient, @@ -676,8 +676,8 @@ export default inject( currentFolderId: selectedFolderStore.id, filter, canCreate, - toggleRoomInfo, - isRoomInfoVisible, + toggleInfoPanel, + isInfoPanelVisible, isHeaderVisible, isHeaderIndeterminate, isHeaderChecked, diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 462550ac2e..a8f26c3f4d 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -21,8 +21,8 @@ import { import DragTooltip from "../../components/DragTooltip"; import { createTreeFolders } from "../../helpers/files-helpers"; import MediaViewer from "./MediaViewer"; -import { RoomInfoBodyContent } from "./RoomInfo"; -import { RoomInfoHeaderContent } from "./RoomInfo"; +import { InfoPanelBodyContent } from "./InfoPanel"; +import { InfoPanelHeaderContent } from "./InfoPanel"; import { SectionBodyContent, SectionFilterContent, @@ -334,13 +334,13 @@ class PureHome extends React.Component { - - - + + + - - - + + + diff --git a/products/ASC.Files/Client/src/store/RoomInfoStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js similarity index 86% rename from products/ASC.Files/Client/src/store/RoomInfoStore.js rename to products/ASC.Files/Client/src/store/InfoPanelStore.js index 0b896ac599..df9247f1f7 100644 --- a/products/ASC.Files/Client/src/store/RoomInfoStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -1,6 +1,6 @@ import { makeAutoObservable } from "mobx"; -class RoomInfoStore { +class InfoPanelStore { isVisible = false; constructor() { @@ -20,4 +20,4 @@ class RoomInfoStore { } } -export default RoomInfoStore; +export default InfoPanelStore; diff --git a/products/ASC.Files/Client/src/store/SettingsStore.js b/products/ASC.Files/Client/src/store/SettingsStore.js index c9d5806f5f..32c35e6f8e 100644 --- a/products/ASC.Files/Client/src/store/SettingsStore.js +++ b/products/ASC.Files/Client/src/store/SettingsStore.js @@ -34,8 +34,8 @@ class SettingsStore { this.treeFoldersStore = treeFoldersStore; } - get roomInfoIsVisible() { - return this.roomInfoIsVisible; + get infoPanelIsVisible() { + return this.infoPanelIsVisible; } setIsLoaded = (isLoaded) => { diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index 7e31bac994..249e69c2e0 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -10,7 +10,7 @@ import iconFormatsStore from "./IconFormatsStore"; import MediaViewerDataStore from "./MediaViewerDataStore"; import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; -import RoomInfoStore from "./RoomInfoStore"; +import InfoPanelStore from "./InfoPanelStore"; import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; import selectedFilesStore from "./SelectedFilesStore"; import selectedFolderStore from "./SelectedFolderStore"; @@ -73,7 +73,7 @@ const filesActionsStore = new FilesActionsStore( const versionHistoryStore = new VersionHistoryStore(filesStore); -const roomInfoStore = new RoomInfoStore(); +const infoPanelStore = new InfoPanelStore(); //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { @@ -88,7 +88,7 @@ const stores = { selectedFolderStore, filesActionsStore, selectedFilesStore, - roomInfoStore, + infoPanelStore, }; export default stores; From 9c815a76af22c55e0f6572aceb7d356d97ceb3c3 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 11 Feb 2022 18:19:15 +0300 Subject: [PATCH 09/81] added items-panel header divider --- .../sub-components/info-panel-header.js | 42 ++++++++++++------- .../src/pages/Home/Section/Header/index.js | 8 ++-- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js index 85a987c081..508c585b03 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js @@ -13,11 +13,11 @@ const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { const StyledInfoPanelHeader = styled.div` width: 100%; - height: 53px; + height: 52px; display: flex; justify-content: space-between; align-items: center; - margin: 8px 0; + margin: 8px -16px; .close-btn { @media ${tablet} { @@ -26,21 +26,31 @@ const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { } `; + const StyledDivider = styled.div` + margin: 0 -16px; + width: calc(100% + 32px); + height: 1px; + background: #eceef1; + `; + return ( - - - {content} - - - + <> + + + {content} + + + + + ); }; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 44fddd7237..bdafad4be8 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -21,12 +21,12 @@ const StyledContainer = styled.div` ${(props) => props.viewAs === "table" ? css` - margin: 0px -20px; - width: calc(100% + 40px); + margin: 0px -22px; + width: calc(100% + 44px); ` : css` - margin: 0px -24px; - width: calc(100% + 48px); + margin: 0px -20px; + width: calc(100% + 40px); `} @media ${tablet} { margin: 0 -16px; From 125796a11232e1ed74c80750ce4a24ee6803d166 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 15 Feb 2022 14:57:36 +0300 Subject: [PATCH 10/81] body content --- config/kafka.json | 4 - .../sub-components/info-panel-body.js | 7 +- .../sub-components/info-panel-header.js | 6 +- .../PageLayout/sub-components/info-panel.js | 1 - .../src/pages/Home/InfoPanel/Body/index.js | 342 +++++++++++++++++- .../src/pages/Home/InfoPanel/Header/index.js | 4 +- .../src/pages/Home/Section/Header/index.js | 25 +- 7 files changed, 360 insertions(+), 29 deletions(-) delete mode 100644 config/kafka.json diff --git a/config/kafka.json b/config/kafka.json deleted file mode 100644 index cf73d7b851..0000000000 --- a/config/kafka.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "kafka": { - } -} \ No newline at end of file diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js index aedc82aa61..9be491efd7 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-body.js @@ -1,10 +1,15 @@ +import Scrollbar from "@appserver/components/scrollbar"; import { inject, observer } from "mobx-react"; import React from "react"; const SubInfoPanelBody = ({ children }) => { const content = children.props.children; - return <>{content}; + return ( + + {content} + + ); }; SubInfoPanelBody.displayName = "SubInfoPanelBody"; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js index 508c585b03..c28ce43544 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js @@ -9,8 +9,6 @@ import styled from "styled-components"; const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { const content = children.props.children; - console.log(toggleIsVisible); - const StyledInfoPanelHeader = styled.div` width: 100%; height: 52px; @@ -19,6 +17,10 @@ const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { align-items: center; margin: 8px -16px; + .header-text { + margin-left: 16px; + } + .close-btn { @media ${tablet} { display: none; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index 23f2599865..7fed227368 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -31,7 +31,6 @@ const InfoPanel = ({ children, isVisible, toggleIsVisible }) => { border-left: 1px solid #eceef1; display: flex; flex-direction: column; - align-items: center; padding: 0 16px; @media ${tablet} { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 7f5c170c9c..14254bdd0c 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -1,16 +1,344 @@ +import { FileType } from "@appserver/common/constants"; +import IconButton from "@appserver/components/icon-button"; +import Link from "@appserver/components/link"; +import Text from "@appserver/components/text"; import { inject, observer } from "mobx-react"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; +import styled from "styled-components"; -const InfoPanelBodyContent = (selectedFilesStore) => { - return
{selectedFilesStore.fileInfo}
; +const StyledInfoRoomBody = styled.div` + .item { + padding: 8px 0; + } +`; + +const StyledItemTitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 80px; + + .icon { + width: 32px; + height: 32px; + margin: 0px 8px; + display: inline-block; + } + + .text { + font-family: Open Sans; + line-height: 22px; + margin: 0px 8px; + } +`; + +const StyledItemSubtitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + padding: 24px 0; +`; + +const StyledItemProperties = styled.div` + .property { + width: 100%; + display: grid; + grid-template-columns: 110px 1fr; + .property-title { + font-size: 13px; + color: #333333; + margin: 8px 0px; + } + + .property-content { + font-weight: 600; + font-size: 13px; + color: #333333; + margin: 8px 0px; + } + } +`; + +const StyledItemAccess = styled.div` + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } +`; + +const StyleditemAccessUser = styled.div` + width: 32px; + height: 32px; + border-radius: 50%; + + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } + } +`; + +const InfoPanelBodyContent = ({ selection, getFolderInfo }) => { + const selectedItems = selection; + console.log(selectedItems); + const [items, setItems] = useState([ + { + title: "", + icon: "", + properties: [], + access: { + owner: { + img: "", + link: "", + }, + others: [], + }, + }, + ]); + + const updateItemsInfo = async () => { + const res = await Promise.all( + selectedItems.map(async (s) => { + const existingItem = items.find((i) => i.id === s.id); + if (existingItem) return existingItem; + + const properties = await getItemProperties(s); + const access = getItemAccess(s); + + console.log(access); + return { + id: s.id, + title: s.title, + icon: s.icon, + properties: properties, + access: access, + }; + }) + ); + + setItems(res); + }; + + const getItemProperties = async (item) => { + const styledLink = (text, href) => ( + + {text} + + ); + + const styledText = (text) => ( + {text} + ); + + const parseAndFormatDate = (date) => { + date = new Date(date); + + const normalize = (num) => { + if (num > 9) return num; + return `0${num}`; + }; + + let hours = date.getHours(), + month = normalize(date.getMonth()), + day = normalize(date.getDate()), + a_p = hours > 12 ? "AM" : "PM"; + + if (hours === 0) hours = 12; + else if (hours > 12) hours = hours - 12; + + return `${day}.${month}.${date.getFullYear()} ${hours}:${date.getMinutes()} ${a_p}`; + }; + + const getItemType = (fileType) => { + switch (fileType) { + case FileType.Unknown: + return "Unknown"; + case FileType.Archive: + return "Archive"; + case FileType.Video: + return "Video"; + case FileType.Audio: + return "Audio"; + case FileType.Image: + return "Image"; + case FileType.Spreadsheet: + return "Spreadsheet"; + case FileType.Presentation: + return "Presentation"; + case FileType.Document: + return "Document"; + + default: + return "Folder"; + } + }; + + console.log(item); + + const parentFolderId = item.isFolder ? item.parentId : item.folderId; + const folderInfo = await getFolderInfo(parentFolderId); + console.log(folderInfo); + + const itemSize = item.isFolder + ? `${item.foldersCount} Folders | ${item.filesCount} Files` + : item.contentLength; + + const itemType = getItemType(item.fileType); + + let result = [ + { + title: "Owner", + content: styledLink( + item.createdBy.displayName, + item.createdBy.profileUrl + ), + }, + { + title: "Location", + content: styledLink( + folderInfo.title, + `/products/files/filter?folder=${parentFolderId}` + ), + }, + { + title: "Type", + content: styledText(itemType), + }, + { + title: "Size", + content: styledText(itemSize), + }, + { + title: "Date modified", + content: styledText(parseAndFormatDate(item.updated)), + }, + { + title: "Last modified by", + content: styledLink( + item.updatedBy.displayName, + item.updatedBy.profileUrl + ), + }, + { + title: "Date creation", + content: styledText(parseAndFormatDate(item.created)), + }, + ]; + + if (itemType === "Folder") return result; + + result.splice(3, 0, { + title: "File extension", + content: styledText(item.fileExst.split(".")[1].toUpperCase()), + }); + + result.push( + { + title: "Versions", + content: styledText(item.version), + }, + { + title: "Comments", + content: styledText(item.comment), + } + ); + + return result; + }; + + const getItemAccess = (item) => { + let result = { + owner: { + img: item.createdBy.avatarSmall, + link: item.createdBy.profileUrl, + }, + others: [], + }; + + return result; + + if (item.access === 0) return result; + }; + + useEffect(() => { + updateItemsInfo(); + }, [selectedItems]); + + return ( + + {items.map((i) => ( +
+ + + + {i.title} + + + + {/* < THUMBNAIL /> */} + + + + System Properties + + + + + {i.properties.map((p) => ( +
+ + {p.title} + + {p.content} +
+ ))} +
+ + + + Who has access + + + + + + + + + + {!i.access.others &&
} +
+
+ ))} +
+ ); }; -export default inject(({ selectedFilesStore }) => { - //const { selectedFilesStore } = filesStore; - console.log(selectedFilesStore); - return { selectedFilesStore }; +export default inject(({ filesStore }) => { + const selection = JSON.parse(JSON.stringify(filesStore.selection)); + const { getFolderInfo } = filesStore; + + return { selection, getFolderInfo }; })( withRouter( withTranslation(["Home", "Common", "Translations"])( diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js index 389d6bba53..5283394fab 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js @@ -1,10 +1,10 @@ import { inject, observer } from "mobx-react"; import React from "react"; -import { withRouter } from "react-router"; import { withTranslation } from "react-i18next"; +import { withRouter } from "react-router"; const InfoPanelHeaderContent = () => { - return <>Room; + return <>Info; }; export default inject(({}) => { diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index bdafad4be8..26fe4bd207 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -21,13 +21,14 @@ const StyledContainer = styled.div` ${(props) => props.viewAs === "table" ? css` - margin: 0px -22px; + margin: 0px -20px; width: calc(100% + 44px); ` : css` - margin: 0px -20px; - width: calc(100% + 40px); + margin: 0px -24px; + width: calc(100% + 48px); `} + @media ${tablet} { margin: 0 -16px; width: calc(100% + 32px); @@ -44,18 +45,18 @@ const StyledContainer = styled.div` props.isRootFolder ? "auto auto 1fr" : props.canCreate - ? "auto auto auto auto auto 1fr" - : "auto auto auto auto 1fr"}; + ? "auto auto auto 1fr 32px" + : "auto auto 1fr 32px"}; - @media ${tablet} { + /* @media ${tablet} { grid-template-columns: ${(props) => - props.isRootFolder - ? "auto auto 1fr" - : props.canCreate - ? "auto auto auto auto 1fr" - : "auto auto auto 1fr"}; + props.isRootFolder + ? "auto auto 1fr" + : props.canCreate + ? "auto auto auto 1fr" + : "auto auto 1fr"}; ${(props) => !props.isLoading && "top: 7px;"} - } + } */ `} align-items: center; max-width: calc(100vw - 32px); From f2ba9680c2decea074e0d5e82f0cd1c06960a838 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 15 Feb 2022 15:01:23 +0300 Subject: [PATCH 11/81] fix kafka --- config/kafka.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 config/kafka.json diff --git a/config/kafka.json b/config/kafka.json new file mode 100644 index 0000000000..4ffde92112 --- /dev/null +++ b/config/kafka.json @@ -0,0 +1,5 @@ +{ + "kafka": { + "BootstrapServers": "" + } +} From 4039499a1f61f0acd636f4a881c6fc316fc691a3 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 17 Feb 2022 11:46:20 +0300 Subject: [PATCH 12/81] added loader and shared-to users --- .../InfoPanelLoader/InfoPanelLoader.js | 111 + .../InfoPanelLoader/StyledInfoPanelLoader.js | 114 + .../Loaders/InfoPanelLoader/index.js | 1 + .../components/Loaders/index.js | 70 +- .../sub-components/info-panel-header.js | 44 +- .../PageLayout/sub-components/info-panel.js | 1 - .../src/pages/Home/InfoPanel/Body/index.js | 396 +- .../src/pages/Home/Section/Header/index.js | 36 +- .../ASC.Files/Client/src/store/FilesStore.js | 3228 +++++++++-------- 9 files changed, 2223 insertions(+), 1778 deletions(-) create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js new file mode 100644 index 0000000000..2c0ace2138 --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js @@ -0,0 +1,111 @@ +import PropTypes from "prop-types"; +import React from "react"; + +import RectangleLoader from "../RectangleLoader"; +import { + StyledAccessRow, + StyledInfoRoomBody, + StyledPropertiesTable, + StyledPropertyRow, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./StyledInfoPanelLoader"; + +const InfoPanelLoader = ({ + id, + className, + style, + isFolder, + hasThumbnail, + ...rest +}) => { + const {} = rest; + + const randomNumber = (min, max) => Math.random() * (max - min) + min; + + const customRectangleLoader = (width, height, rounded) => ( + + ); + + const properties = isFolder + ? [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + ] + : [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { "File Extension": 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + { Versions: 17.6 }, + { Comments: 17.6 }, + ]; + + return ( + + + {customRectangleLoader(32, 32)} + {customRectangleLoader(250, 22)} + + + System Properties + + {hasThumbnail && ( + + {customRectangleLoader(320.2, 200)} + + )} + + + {properties.map((property) => ( + +
+ {Object.keys(property)[0]} +
+ {customRectangleLoader( + randomNumber(125, 150), + Object.values(property)[0] + )} +
+ ))} +
+ + Who has access + + + {customRectangleLoader(32, 32, 16)} +
+ {customRectangleLoader(32, 32, 16)} + {customRectangleLoader(32, 32, 16)} +
+
+ ); +}; + +InfoPanelLoader.propTypes = { + id: PropTypes.string, + className: PropTypes.string, + style: PropTypes.object, +}; + +InfoPanelLoader.defaultProps = { + id: undefined, + className: undefined, + style: undefined, +}; + +export default InfoPanelLoader; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js new file mode 100644 index 0000000000..59543d61bf --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js @@ -0,0 +1,114 @@ +import styled from "styled-components"; + +const StyledInfoRoomBody = styled.div``; + +const StyledTitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 80px; + gap: 8px; +`; + +const StyledThumbnail = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; +`; + +const StyledSubtitle = styled.div` + margin-bottom: 24px; + height: 19.2px; + font-weight: 600; + font-size: 14px; + color: #000000; +`; + +const StyledPropertiesTable = styled.div` + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; +`; + +const StyledPropertyRow = styled.div` + width: 100%; + display: grid; + grid-template-columns: 110px 1fr; + grid-column-gap: 24px; + + .property-title { + font-size: 13px; + color: #333333; + } +`; + +const StyledAccessRow = styled.div` + width: 100%; + height: 32px; + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } +`; + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +export { + StyledInfoRoomBody, + StyledSubtitle, + StyledTitle, + StyledThumbnail, + StyledPropertiesTable, + StyledPropertyRow, + StyledAccessRow, +}; + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +const StyledItemAccess = styled.div` + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } +`; + +const StyleditemAccessUser = styled.div` + width: 32px; + height: 32px; + border-radius: 50%; + + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } + } +`; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js new file mode 100644 index 0000000000..ed427373f5 --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js @@ -0,0 +1 @@ +export default from "./InfoPanelLoader"; diff --git a/packages/asc-web-common/components/Loaders/index.js b/packages/asc-web-common/components/Loaders/index.js index 53a13fe12f..d9900ad7db 100644 --- a/packages/asc-web-common/components/Loaders/index.js +++ b/packages/asc-web-common/components/Loaders/index.js @@ -1,43 +1,45 @@ -import Rectangle from "./RectangleLoader"; -import Circle from "./CircleLoader"; -import Header from "./HeaderLoader"; -import SectionHeader from "./SectionHeaderLoader"; import ArticleHeader from "./ArticleHeaderLoader"; -import TreeFolders from "./TreeFolderLoader"; -import TreeSettingsLoader from "./TreeSettingsLoader"; +import Circle from "./CircleLoader"; +import DialogAsideLoader from "./DialogAsideLoader"; +import DialogLoader from "./DialogLoader"; +import Filter from "./FilterLoader"; +import Group from "./GroupLoader"; +import Header from "./HeaderLoader"; +import HistoryRows from "./HistoryRowsLoader"; +import InfoPanelLoader from "./InfoPanelLoader"; +import MainButton from "./MainButtonLoader"; +import ProfileView from "./ProfileViewLoader"; +import Rectangle from "./RectangleLoader"; import Row from "./RowLoader"; import Rows from "./RowsLoader"; -import Text from "./TextLoader"; -import Filter from "./FilterLoader"; -import ProfileView from "./ProfileViewLoader"; +import SectionHeader from "./SectionHeaderLoader"; import SettingsFiles from "./SettingsFilesLoader"; -import Group from "./GroupLoader"; -import HistoryRows from "./HistoryRowsLoader"; +import Text from "./TextLoader"; import Tile from "./TileLoader"; import Tiles from "./TilesLoader"; -import DialogLoader from "./DialogLoader"; -import DialogAsideLoader from "./DialogAsideLoader"; -import MainButton from "./MainButtonLoader"; +import TreeFolders from "./TreeFolderLoader"; +import TreeSettingsLoader from "./TreeSettingsLoader"; export default { - Rectangle, - Circle, - Header, - SectionHeader, - ArticleHeader, - TreeFolders, - TreeSettingsLoader, - Row, - Rows, - Text, - Filter, - ProfileView, - SettingsFiles, - Group, - HistoryRows, - Tile, - Tiles, - DialogLoader, - DialogAsideLoader, - MainButton, + Rectangle, + Circle, + Header, + SectionHeader, + ArticleHeader, + TreeFolders, + TreeSettingsLoader, + Row, + Rows, + Text, + Filter, + ProfileView, + SettingsFiles, + Group, + HistoryRows, + Tile, + Tiles, + DialogLoader, + DialogAsideLoader, + MainButton, + InfoPanelLoader, }; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js index c28ce43544..1ea90623c5 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel-header.js @@ -11,48 +11,40 @@ const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { const StyledInfoPanelHeader = styled.div` width: 100%; + max-width: 100%; height: 52px; display: flex; justify-content: space-between; align-items: center; - margin: 8px -16px; + padding: 8px 0; + border-bottom: 1px solid #eceef1; .header-text { margin-left: 16px; } .close-btn { + margin-right: 16px; @media ${tablet} { display: none; } } `; - - const StyledDivider = styled.div` - margin: 0 -16px; - width: calc(100% + 32px); - height: 1px; - background: #eceef1; - `; - return ( - <> - - - {content} - - - - - + + + {content} + + + ); }; diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index 7fed227368..8141aa695f 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -31,7 +31,6 @@ const InfoPanel = ({ children, isVisible, toggleIsVisible }) => { border-left: 1px solid #eceef1; display: flex; flex-direction: column; - padding: 0 16px; @media ${tablet} { position: absolute; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 14254bdd0c..7568c3a9da 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -1,16 +1,20 @@ +import Loaders from "@appserver/common/components/Loaders"; +import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; import { FileType } from "@appserver/common/constants"; -import IconButton from "@appserver/components/icon-button"; import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; +import Tooltip from "@appserver/components/tooltip"; import { inject, observer } from "mobx-react"; import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; +import { ReactSVG } from "react-svg"; import styled from "styled-components"; const StyledInfoRoomBody = styled.div` - .item { - padding: 8px 0; + padding: 0px 16px 16px; + .no-item { + text-align: center; } `; @@ -22,10 +26,10 @@ const StyledItemTitle = styled.div` height: 80px; .icon { - width: 32px; - height: 32px; - margin: 0px 8px; - display: inline-block; + svg { + height: 32px; + width: 32px; + } } .text { @@ -35,30 +39,54 @@ const StyledItemTitle = styled.div` } `; +const StyledItemThumbnail = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; + img { + max-height: 200px; + max-width: 100%; + width: auto; + height: auto; + } +`; + const StyledItemSubtitle = styled.div` display: flex; flex-direction: row; align-items: center; width: 100%; - padding: 24px 0; + margin-bottom: 24px; `; const StyledItemProperties = styled.div` + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; + .property { width: 100%; display: grid; grid-template-columns: 110px 1fr; + grid-column-gap: 24px; + .property-title { font-size: 13px; color: #333333; - margin: 8px 0px; } .property-content { font-weight: 600; font-size: 13px; color: #333333; - margin: 8px 0px; } } `; @@ -90,48 +118,131 @@ const StyleditemAccessUser = styled.div` } `; -const InfoPanelBodyContent = ({ selection, getFolderInfo }) => { - const selectedItems = selection; - console.log(selectedItems); - const [items, setItems] = useState([ - { - title: "", - icon: "", - properties: [], +const InfoPanelBodyContent = ({ + selectedItem, + getFolderInfo, + getIcon, + getFolderIcon, + + getShareUsers, +}) => { + const [item, setItem] = useState({}); + // title: "", + // iconUrl: "", + // thumbnailUrl: "", + // properties: [{ title: "", content: {} }], + // access: { + // owner: { + // img: "", + // link: "", + // }, + // others: [ + // { + // img: "", + // link: "", + // }, + // ], + // }, + + const updateItemsInfo = async (selectedItem) => { + const displayedItem = { + id: selectedItem.id, + title: selectedItem.title, + iconUrl: getItemIcon(selectedItem), + thumbnailUrl: selectedItem.thumbnailUrl, + properties: getItemProperties(selectedItem), access: { owner: { - img: "", - link: "", + img: selectedItem.createdBy.avatarSmall, + link: selectedItem.createdBy.profileUrl, }, others: [], }, - }, - ]); + }; - const updateItemsInfo = async () => { - const res = await Promise.all( - selectedItems.map(async (s) => { - const existingItem = items.find((i) => i.id === s.id); - if (existingItem) return existingItem; - - const properties = await getItemProperties(s); - const access = getItemAccess(s); - - console.log(access); - return { - id: s.id, - title: s.title, - icon: s.icon, - properties: properties, - access: access, - }; - }) - ); - - setItems(res); + setItem(displayedItem); + loadAsyncData(displayedItem, selectedItem); }; - const getItemProperties = async (item) => { + const loadAsyncData = async (displayedItem, selectedItem) => { + const updateLoadedItemProperties = async ( + displayedItem, + selectedItem + ) => { + const parentFolderId = selectedItem.isFolder + ? selectedItem.parentId + : selectedItem.folderId; + const folderInfo = await getFolderInfo(parentFolderId); + + return [...displayedItem.properties].map((op) => + op.title === "Location" + ? { + title: "Location", + content: ( + + {folderInfo.title} + + ), + } + : op + ); + }; + + const updateLoadedItemAccess = async (item) => { + const accesses = await getShareUsers([item.folderId], [item.id]); + console.log(accesses); + + const result = { + owner: {}, + others: [], + }; + + accesses.forEach((access) => { + const user = access.sharedTo; + const userData = { + key: user.id, + img: user.avatarSmall, + link: user.profileUrl, + name: user.displayName, + email: user.email, + }; + + if (access.isOwner) result.owner = userData; + else result.others.push(userData); + }); + + return result; + }; + + const properties = await updateLoadedItemProperties( + displayedItem, + selectedItem + ); + const access = await updateLoadedItemAccess(selectedItem); + + setItem({ + ...displayedItem, + properties: properties, + access: access, + }); + }; + + const getItemIcon = (item) => { + const extension = item.fileExst; + const iconUrl = extension + ? getIcon(24, extension) + : getFolderIcon(item.providerKey, 24); + + return iconUrl; + }; + + const getItemProperties = (item) => { + console.log(item); + const styledLink = (text, href) => ( {text} @@ -185,12 +296,6 @@ const InfoPanelBodyContent = ({ selection, getFolderInfo }) => { } }; - console.log(item); - - const parentFolderId = item.isFolder ? item.parentId : item.folderId; - const folderInfo = await getFolderInfo(parentFolderId); - console.log(folderInfo); - const itemSize = item.isFolder ? `${item.foldersCount} Folders | ${item.filesCount} Files` : item.contentLength; @@ -207,10 +312,7 @@ const InfoPanelBodyContent = ({ selection, getFolderInfo }) => { }, { title: "Location", - content: styledLink( - folderInfo.title, - `/products/files/filter?folder=${parentFolderId}` - ), + content: , }, { title: "Type", @@ -258,87 +360,131 @@ const InfoPanelBodyContent = ({ selection, getFolderInfo }) => { return result; }; - const getItemAccess = (item) => { - let result = { - owner: { - img: item.createdBy.avatarSmall, - link: item.createdBy.profileUrl, - }, - others: [], - }; - - return result; - - if (item.access === 0) return result; - }; - useEffect(() => { - updateItemsInfo(); - }, [selectedItems]); + if (selectedItem !== null) updateItemsInfo(selectedItem); + }, [selectedItem]); return ( - {items.map((i) => ( -
- - - - {i.title} - - - - {/* < THUMBNAIL /> */} - - - - System Properties - - - - - {i.properties.map((p) => ( -
- - {p.title} - - {p.content} -
- ))} -
- - - - Who has access - - - - - - - - - - {!i.access.others &&
} -
+ {!selectedItem ? ( +
+

Select an item to display it's info

- ))} + ) : ( + <> + {item.title && ( + <> + + + + {item.title} + + + + {"thumbnailUrl" in selectedItem && ( + + + + )} + + + + System Properties + + + + + {item.properties.map((p) => ( +
+ + {p.title} + + {p.content} +
+ ))} +
+ + + + Who has access + + + + + +
+ + + +
+
+ + {item.access.others.length ? ( +
+ ) : null} + + {item.access.others.map((user) => ( +
+ +
+ + + +
+
+
+ ))} +
+ + + dataTip ? ( + {dataTip} + ) : null + } + /> + + )} + + )} ); }; -export default inject(({ filesStore }) => { - const selection = JSON.parse(JSON.stringify(filesStore.selection)); - const { getFolderInfo } = filesStore; +export default inject(({ filesStore, formatsStore }) => { + console.log(filesStore); + const selectedItem = JSON.parse(JSON.stringify(filesStore.bufferSelection)); + const { getFolderInfo, getShareUsers } = filesStore; - return { selection, getFolderInfo }; + const { getIcon, getFolderIcon } = formatsStore.iconFormatsStore; + + return { + selectedItem, + getFolderInfo, + getShareUsers, + + getIcon, + getFolderIcon, + }; })( withRouter( withTranslation(["Home", "Common", "Translations"])( diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 26fe4bd207..24a550a03a 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -41,22 +41,14 @@ const StyledContainer = styled.div` props.title && css` display: grid; - grid-template-columns: ${(props) => - props.isRootFolder - ? "auto auto 1fr" - : props.canCreate - ? "auto auto auto 1fr 32px" - : "auto auto 1fr 32px"}; - - /* @media ${tablet} { - grid-template-columns: ${(props) => - props.isRootFolder - ? "auto auto 1fr" - : props.canCreate - ? "auto auto auto 1fr" - : "auto auto 1fr"}; - ${(props) => !props.isLoading && "top: 7px;"} - } */ + grid-template-columns: ${({ isRootFolder, canCreate }) => { + if (isRootFolder) { + if (canCreate) return "auto auto 1fr"; + return "auto 1fr"; + } + if (canCreate) return "auto auto auto 1fr 32px"; + return "auto auto 1fr 32px"; + }}; `} align-items: center; max-width: calc(100vw - 32px); @@ -95,13 +87,16 @@ const StyledContainer = styled.div` .option-button { margin-bottom: -1px; - @media (min-width: 1024px) { + margin-left: auto; + margin-right: 16px; + + /* @media (min-width: 1024px) { margin-left: 8px; - } + } */ @media ${tablet} { - margin-left: auto; - margin-right: 32px; + /* margin-left: auto; + margin-right: 32px; */ & > div:first-child { padding: 8px 8px 8px 8px; margin-right: -8px; @@ -200,6 +195,7 @@ const StyledInfoPanelToggleWrapper = styled.div` ${(props) => props.isHeaderVisible && css` + margin-bottom: 2px; margin-right: 24px; padding-left: 12px; `} diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index d1cfd45ef2..dcb8c1e3ce 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -1,1670 +1,1754 @@ -import { makeAutoObservable } from "mobx"; import api from "@appserver/common/api"; import { - FolderType, - FilterType, - FileType, - FileAction, - AppServerConfig, + AppServerConfig, + FileAction, + FileType, + FilterType, + FolderType, } from "@appserver/common/constants"; import history from "@appserver/common/history"; -import { loopTreeFolders } from "../helpers/files-helpers"; -import config from "../../package.json"; import { combineUrl } from "@appserver/common/utils"; import { updateTempContent } from "@appserver/common/utils"; -import { thumbnailStatuses } from "../helpers/constants"; +import { makeAutoObservable } from "mobx"; import { isMobile } from "react-device-detect"; -import { openDocEditor as openEditor } from "../helpers/utils"; import toastr from "studio/toastr"; +import config from "../../package.json"; +import { thumbnailStatuses } from "../helpers/constants"; +import { loopTreeFolders } from "../helpers/files-helpers"; +import { openDocEditor as openEditor } from "../helpers/utils"; + const { FilesFilter } = api; const storageViewAs = localStorage.getItem("viewAs"); class FilesStore { - authStore; - settingsStore; - userStore; - fileActionStore; - selectedFolderStore; - treeFoldersStore; - formatsStore; - filesSettingsStore; + authStore; + settingsStore; + userStore; + fileActionStore; + selectedFolderStore; + treeFoldersStore; + formatsStore; + filesSettingsStore; - isLoaded = false; - isLoading = false; - viewAs = - isMobile && storageViewAs !== "tile" ? "row" : storageViewAs || "table"; - dragging = false; - privacyInstructions = "https://www.onlyoffice.com/private-rooms.aspx"; - isInit = false; + isLoaded = false; + isLoading = false; + viewAs = + isMobile && storageViewAs !== "tile" ? "row" : storageViewAs || "table"; + dragging = false; + privacyInstructions = "https://www.onlyoffice.com/private-rooms.aspx"; + isInit = false; - tooltipPageX = 0; - tooltipPageY = 0; - startDrag = false; + tooltipPageX = 0; + tooltipPageY = 0; + startDrag = false; - firstLoad = true; - files = []; - folders = []; - selection = []; - bufferSelection = null; - selected = "close"; - filter = FilesFilter.getDefault(); //TODO: FILTER - loadTimeout = null; + firstLoad = true; + files = []; + folders = []; + selection = []; + bufferSelection = null; + selected = "close"; + filter = FilesFilter.getDefault(); //TODO: FILTER + loadTimeout = null; - constructor( - authStore, - settingsStore, - userStore, - fileActionStore, - selectedFolderStore, - treeFoldersStore, - formatsStore, - filesSettingsStore - ) { - const pathname = window.location.pathname.toLowerCase(); - this.isEditor = pathname.indexOf("doceditor") !== -1; + constructor( + authStore, + settingsStore, + userStore, + fileActionStore, + selectedFolderStore, + treeFoldersStore, + formatsStore, + filesSettingsStore + ) { + const pathname = window.location.pathname.toLowerCase(); + this.isEditor = pathname.indexOf("doceditor") !== -1; - makeAutoObservable(this); - this.authStore = authStore; - this.settingsStore = settingsStore; - this.userStore = userStore; - this.fileActionStore = fileActionStore; - this.selectedFolderStore = selectedFolderStore; - this.treeFoldersStore = treeFoldersStore; - this.formatsStore = formatsStore; - this.filesSettingsStore = filesSettingsStore; - } - - setIsLoaded = (isLoaded) => { - this.isLoaded = isLoaded; - }; - - setViewAs = (viewAs) => { - this.viewAs = viewAs; - localStorage.setItem("viewAs", viewAs); - }; - - setDragging = (dragging) => { - this.dragging = dragging; - }; - - setIsLoading = (isLoading) => { - this.isLoading = isLoading; - }; - - setTooltipPosition = (tooltipPageX, tooltipPageY) => { - this.tooltipPageX = tooltipPageX; - this.tooltipPageY = tooltipPageY; - }; - - setStartDrag = (startDrag) => { - this.selection = this.selection.filter((x) => !x.providerKey); // removed root thirdparty folders - this.startDrag = startDrag; - }; - - get tooltipOptions() { - if (!this.dragging) return null; - - const selectionLength = this.selection.length; - const elementTitle = selectionLength && this.selection[0].title; - const singleElement = selectionLength === 1; - const filesCount = singleElement ? elementTitle : selectionLength; - const { isShareFolder, isCommonFolder } = this.treeFoldersStore; - - let operationName; - - if (this.authStore.isAdmin && isShareFolder) { - operationName = "copy"; - } else if (!this.authStore.isAdmin && (isShareFolder || isCommonFolder)) { - operationName = "copy"; - } else { - operationName = "move"; + makeAutoObservable(this); + this.authStore = authStore; + this.settingsStore = settingsStore; + this.userStore = userStore; + this.fileActionStore = fileActionStore; + this.selectedFolderStore = selectedFolderStore; + this.treeFoldersStore = treeFoldersStore; + this.formatsStore = formatsStore; + this.filesSettingsStore = filesSettingsStore; } - return { - filesCount, - operationName, + setIsLoaded = (isLoaded) => { + this.isLoaded = isLoaded; }; - } - initFiles = () => { - if (this.isInit) return; + setViewAs = (viewAs) => { + this.viewAs = viewAs; + localStorage.setItem("viewAs", viewAs); + }; - const { isAuthenticated, settingsStore } = this.authStore; - const { getFilesSettings } = this.filesSettingsStore; + setDragging = (dragging) => { + this.dragging = dragging; + }; - const { - getPortalCultures, - getIsEncryptionSupport, - getEncryptionKeys, - setModuleInfo, - } = this.settingsStore; - const { isDesktopClient } = settingsStore; + setIsLoading = (isLoading) => { + this.isLoading = isLoading; + }; - setModuleInfo(config.homepage, config.id); + setTooltipPosition = (tooltipPageX, tooltipPageY) => { + this.tooltipPageX = tooltipPageX; + this.tooltipPageY = tooltipPageY; + }; - const requests = []; + setStartDrag = (startDrag) => { + this.selection = this.selection.filter((x) => !x.providerKey); // removed root thirdparty folders + this.startDrag = startDrag; + }; - updateTempContent(); - if (!isAuthenticated) { - return this.setIsLoaded(true); - } else { - updateTempContent(isAuthenticated); + get tooltipOptions() { + if (!this.dragging) return null; + + const selectionLength = this.selection.length; + const elementTitle = selectionLength && this.selection[0].title; + const singleElement = selectionLength === 1; + const filesCount = singleElement ? elementTitle : selectionLength; + const { isShareFolder, isCommonFolder } = this.treeFoldersStore; + + let operationName; + + if (this.authStore.isAdmin && isShareFolder) { + operationName = "copy"; + } else if ( + !this.authStore.isAdmin && + (isShareFolder || isCommonFolder) + ) { + operationName = "copy"; + } else { + operationName = "move"; + } + + return { + filesCount, + operationName, + }; } - if (!this.isEditor) { - requests.push( - getPortalCultures(), - this.treeFoldersStore.fetchTreeFolders() - ); + initFiles = () => { + if (this.isInit) return; - if (isDesktopClient) { - requests.push(getIsEncryptionSupport(), getEncryptionKeys()); - } - } - requests.push(getFilesSettings()); + const { isAuthenticated, settingsStore } = this.authStore; + const { getFilesSettings } = this.filesSettingsStore; - return Promise.all(requests).then(() => (this.isInit = true)); - }; + const { + getPortalCultures, + getIsEncryptionSupport, + getEncryptionKeys, + setModuleInfo, + } = this.settingsStore; + const { isDesktopClient } = settingsStore; - setFirstLoad = (firstLoad) => { - this.firstLoad = firstLoad; - }; + setModuleInfo(config.homepage, config.id); - setFiles = (files) => { - this.files = files; - }; + const requests = []; - setFolders = (folders) => { - this.folders = folders; - }; + updateTempContent(); + if (!isAuthenticated) { + return this.setIsLoaded(true); + } else { + updateTempContent(isAuthenticated); + } - setFile = (file) => { - const index = this.files.findIndex((x) => x.id === file.id); - if (index !== -1) this.files[index] = file; - }; - - setFolder = (folder) => { - const index = this.folders.findIndex((x) => x.id === folder.id); - if (index !== -1) this.folders[index] = folder; - }; - - getFilesChecked = (file, selected) => { - const type = file.fileType; - switch (selected) { - case "all": - return true; - case FilterType.FoldersOnly.toString(): - return file.parentId; - case FilterType.DocumentsOnly.toString(): - return type === FileType.Document; - case FilterType.PresentationsOnly.toString(): - return type === FileType.Presentation; - case FilterType.SpreadsheetsOnly.toString(): - return type === FileType.Spreadsheet; - case FilterType.ImagesOnly.toString(): - return type === FileType.Image; - case FilterType.MediaOnly.toString(): - return type === FileType.Video || type === FileType.Audio; - case FilterType.ArchiveOnly.toString(): - return type === FileType.Archive; - case FilterType.FilesOnly.toString(): - return type || !file.parentId; - default: - return false; - } - }; - - getFilesBySelected = (files, selected) => { - let newSelection = []; - files.forEach((file) => { - const checked = this.getFilesChecked(file, selected); - - if (checked) newSelection.push(file); - }); - - return newSelection; - }; - - setSelected = (selected) => { - if (selected === "close" || selected === "none") - this.setBufferSelection(null); - - this.selected = selected; - const files = this.files.concat(this.folders); - this.selection = this.getFilesBySelected(files, selected); - }; - - setSelection = (selection) => { - this.selection = selection; - }; - - setBufferSelection = (bufferSelection) => { - this.bufferSelection = bufferSelection; - }; - - //TODO: FILTER - setFilesFilter = (filter) => { - const key = `UserFilter=${this.userStore.user.id}`; - const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; - localStorage.setItem(key, value); - - this.setFilterUrl(filter); - this.filter = filter; - }; - - setFilter = (filter) => { - this.filter = filter; - }; - - setFilesOwner = (folderIds, fileIds, ownerId) => { - return api.files.setFileOwner(folderIds, fileIds, ownerId); - }; - - setFilterUrl = (filter) => { - const urlFilter = filter.toUrlParams(); - history.push( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/filter?${urlFilter}` - ) - ); - }; - - isEmptyLastPageAfterOperation = (newSelection) => { - const selection = - newSelection || this.selection?.length || [this.bufferSelection].length; - - return ( - selection && - this.filter.page > 0 && - !this.filter.hasNext() && - selection === this.files.length + this.folders.length - ); - }; - - resetFilterPage = () => { - let newFilter; - newFilter = this.filter.clone(); - newFilter.page--; - - return newFilter; - }; - - fetchFiles = ( - folderId, - filter, - clearFilter = true, - withSubfolders = false - ) => { - const { - treeFolders, - setSelectedNode, - getSubfolders, - } = this.treeFoldersStore; - - const filterData = filter ? filter.clone() : FilesFilter.getDefault(); - filterData.folder = folderId; - - const filterStorageItem = localStorage.getItem( - `UserFilter=${this.userStore.user.id}` - ); - - if (filterStorageItem && !filter) { - const splitFilter = filterStorageItem.split(","); - - filterData.sortBy = splitFilter[0]; - filterData.pageCount = splitFilter[1]; - filterData.sortOrder = splitFilter[2]; - } - - setSelectedNode([folderId + ""]); - - //TODO: fix @my - let requestCounter = 1; - const request = () => - api.files - .getFolder(folderId, filterData) - .then(async (data) => { - const isRecycleBinFolder = - data.current.rootFolderType === FolderType.TRASH; - - !isRecycleBinFolder && this.checkUpdateNode(data, folderId); - - if (!isRecycleBinFolder && withSubfolders) { - const path = data.pathParts.slice(0); - const foldersCount = data.current.foldersCount; - const subfolders = await getSubfolders(folderId); - loopTreeFolders(path, treeFolders, subfolders, foldersCount); - } - - const isPrivacyFolder = - data.current.rootFolderType === FolderType.Privacy; - - filterData.total = data.total; - this.setFilesFilter(filterData); //TODO: FILTER - this.setFolders(isPrivacyFolder && isMobile ? [] : data.folders); - this.setFiles(isPrivacyFolder && isMobile ? [] : data.files); - - if (clearFilter) { - this.fileActionStore.setAction({ type: null }); - this.setSelected("close"); - } - - this.selectedFolderStore.setSelectedFolder({ - folders: data.folders, - ...data.current, - pathParts: data.pathParts, - ...{ new: data.new }, - }); - - const selectedFolder = { - selectedFolder: { ...this.selectedFolderStore }, - }; - this.viewAs === "tile" && this.createThumbnails(); - return Promise.resolve(selectedFolder); - }) - .catch((err) => { - toastr.error(err); - if (!requestCounter) return; - requestCounter--; - - if (folderId === "@my" /* && !this.isInit */) { - setTimeout(() => { - return request(); - }, 5000); - } else { - this.treeFoldersStore.fetchTreeFolders(); - return this.fetchFiles( - this.userStore.user.isVisitor ? "@common" : "@my" + if (!this.isEditor) { + requests.push( + getPortalCultures(), + this.treeFoldersStore.fetchTreeFolders() ); - } + + if (isDesktopClient) { + requests.push(getIsEncryptionSupport(), getEncryptionKeys()); + } + } + requests.push(getFilesSettings()); + + return Promise.all(requests).then(() => (this.isInit = true)); + }; + + setFirstLoad = (firstLoad) => { + this.firstLoad = firstLoad; + }; + + setFiles = (files) => { + this.files = files; + }; + + setFolders = (folders) => { + this.folders = folders; + }; + + setFile = (file) => { + const index = this.files.findIndex((x) => x.id === file.id); + if (index !== -1) this.files[index] = file; + }; + + setFolder = (folder) => { + const index = this.folders.findIndex((x) => x.id === folder.id); + if (index !== -1) this.folders[index] = folder; + }; + + getFilesChecked = (file, selected) => { + const type = file.fileType; + switch (selected) { + case "all": + return true; + case FilterType.FoldersOnly.toString(): + return file.parentId; + case FilterType.DocumentsOnly.toString(): + return type === FileType.Document; + case FilterType.PresentationsOnly.toString(): + return type === FileType.Presentation; + case FilterType.SpreadsheetsOnly.toString(): + return type === FileType.Spreadsheet; + case FilterType.ImagesOnly.toString(): + return type === FileType.Image; + case FilterType.MediaOnly.toString(): + return type === FileType.Video || type === FileType.Audio; + case FilterType.ArchiveOnly.toString(): + return type === FileType.Archive; + case FilterType.FilesOnly.toString(): + return type || !file.parentId; + default: + return false; + } + }; + + getFilesBySelected = (files, selected) => { + let newSelection = []; + files.forEach((file) => { + const checked = this.getFilesChecked(file, selected); + + if (checked) newSelection.push(file); }); - return request(); - }; - - checkUpdateNode = async (data, folderId) => { - const { treeFolders, getSubfolders } = this.treeFoldersStore; - const { pathParts, current } = data; - - if (current.parentId === 0) return; - - const somePath = pathParts.slice(0); - const path = pathParts.slice(0); - let newItems = treeFolders; - - while (somePath.length !== 1) { - const folderItem = newItems.find((x) => x.id === somePath[0]); - newItems = folderItem?.folders - ? folderItem.folders - : somePath.length > 1 - ? [] - : null; - if (!newItems) { - return; - } - - somePath.shift(); - } - - if (!newItems.find((x) => x.id == folderId)) { - path.splice(pathParts.length - 1, 1); - const subfolders = await getSubfolders(current.parentId); - loopTreeFolders(path, treeFolders, subfolders, 0); - } - }; - - isFileSelected = (fileId, parentId) => { - const item = this.selection.find( - (x) => x.id === fileId && x.parentId === parentId - ); - - return item !== undefined; - }; - - selectFile = (file) => { - const { id, parentId } = file; - const isFileSelected = this.isFileSelected(id, parentId); - if (!isFileSelected) this.selection.push(file); - }; - - deselectFile = (file) => { - const { id, parentId } = file; - const isFileSelected = this.isFileSelected(id, parentId); - if (isFileSelected) - this.selection = this.selection.filter((x) => x.id !== id); - }; - - removeOptions = (options, toRemoveArray) => - options.filter((o) => !toRemoveArray.includes(o)); - - getFilesContextOptions = (item, canOpenPlayer) => { - const isVisitor = - (this.userStore.user && this.userStore.user.isVisitor) || false; - const isFile = !!item.fileExst || item.contentLength; - const isFavorite = - item.fileStatus === 32 || - item.fileStatus === 33 || - item.fileStatus === 34; - const isFullAccess = item.access < 2; - const withoutShare = false; //TODO: need this prop - const isThirdPartyItem = !!item.providerKey; - const hasNew = - item.new > 0 || item.fileStatus === 2 || item.fileStatus === 34; - const canConvert = false; //TODO: fix of added convert check; - const isEncrypted = item.encrypted; - const isDocuSign = false; //TODO: need this prop; - const isEditing = false; //TODO: need this prop; - const isFileOwner = item.createdBy.id === this.userStore.user.id; - - const { - isRecycleBinFolder, - isPrivacyFolder, - isRecentFolder, - isCommon, - isShare, - isFavoritesFolder, - isShareFolder, - isMy, - } = this.treeFoldersStore; - - const { - canWebEdit, - canViewedDocs, - canFormFillingDocs, - } = this.formatsStore.docserviceStore; - - const isThirdPartyFolder = - item.providerKey && item.id === item.rootFolderId; - const isShareItem = isShare(item.rootFolderType); - const isCommonFolder = isCommon(item.rootFolderType); - const isMyFolder = isMy(item.rootFolderType); - - const { personal } = this.settingsStore; - const { isDesktopClient } = this.authStore.settingsStore; - - if (isFile) { - const shouldFillForm = canFormFillingDocs(item.fileExst); - const shouldEdit = !shouldFillForm && canWebEdit(item.fileExst); - const shouldView = canViewedDocs(item.fileExst); - const isMasterForm = item.fileExst === ".docxf"; - - let fileOptions = [ - //"open", - "fill-form", - "edit", - "preview", - "view", - "make-form", - "separator0", - "sharing-settings", - "external-link", - "owner-change", - "link-for-portal-users", - "send-by-email", - "docu-sign", - "version", //category - "finalize-version", - "show-version-history", - "block-unblock-version", //need split - "separator1", - "open-location", - "mark-read", - "mark-as-favorite", - "remove-from-favorites", - "download", - "download-as", - "convert", - "move", //category - "move-to", - "copy-to", - "copy", - "restore", - "rename", - "separator2", - "unsubscribe", - "delete", - ]; - - if (!isMasterForm) - fileOptions = this.removeOptions(fileOptions, ["make-form"]); - - if (!shouldFillForm) - fileOptions = this.removeOptions(fileOptions, ["fill-form"]); - - if (personal) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "link-for-portal-users", - "docu-sign", - "mark-read", - "unsubscribe", - ]); - - if (!shouldEdit && !shouldView) { - fileOptions = this.removeOptions(fileOptions, ["sharing-settings"]); - } - } - - if (!this.canConvertSelected) { - fileOptions = this.removeOptions(fileOptions, ["download-as"]); - } - - if (!canConvert || isEncrypted) { - fileOptions = this.removeOptions(fileOptions, ["convert"]); - } - - if (!canOpenPlayer) { - fileOptions = this.removeOptions(fileOptions, ["view"]); - } else { - fileOptions = this.removeOptions(fileOptions, ["edit", "preview"]); - } - - if (!isDocuSign) { - fileOptions = this.removeOptions(fileOptions, ["docu-sign"]); - } - - if (isEditing) { - fileOptions = this.removeOptions(fileOptions, [ - "finalize-version", - "move-to", - "delete", - ]); - if (isThirdPartyFolder) { - fileOptions = this.removeOptions(fileOptions, ["rename"]); - } - } - - if (isFavorite) { - fileOptions = this.removeOptions(fileOptions, ["mark-as-favorite"]); - } else { - fileOptions = this.removeOptions(fileOptions, [ - "remove-from-favorites", - ]); - - if (isFavoritesFolder) { - fileOptions = this.removeOptions(fileOptions, ["mark-as-favorite"]); - } - } - - if (isFavoritesFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "move-to", - "delete", - "copy", - ]); - - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, ["separator2"]); - } - } - - if (isEncrypted) { - fileOptions = this.removeOptions(fileOptions, [ - "open", - "edit", - "make-form", - "link-for-portal-users", - "external-link", - "send-by-email", - "block-unblock-version", //need split - "version", //category - "finalize-version", - "copy-to", - "copy", - "mark-as-favorite", - ]); - } - - if (isRecentFolder) { - fileOptions = this.removeOptions(fileOptions, ["delete"]); - - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, ["separator2"]); - } - } - - if (isFavoritesFolder || isRecentFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "make-form", - "copy", - "move-to", - //"sharing-settings", - "unsubscribe", - "separator2", - ]); - } - - if (isRecycleBinFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "fill-form", - "open", - "open-location", - "view", - "preview", - "edit", - "make-form", - "link-for-portal-users", - "sharing-settings", - "external-link", - "send-by-email", - "block-unblock-version", //need split - "version", //category - "finalize-version", - "show-version-history", - "move", //category - "move-to", - "copy-to", - "copy", - "mark-read", - "mark-as-favorite", - "remove-from-favorites", - "rename", - "separator0", - "separator1", - ]); - } else { - fileOptions = this.removeOptions(fileOptions, ["restore"]); - } - - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, [ - "finalize-version", - "rename", - "block-unblock-version", - "copy", - "sharing-settings", - ]); - } - - if (isVisitor) { - fileOptions = this.removeOptions(fileOptions, [ - "block-unblock-version", - "finalize-version", - "mark-as-favorite", - "remove-from-favorites", - ]); - - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, ["rename"]); - } - } - - if (!this.canShareOwnerChange(item)) { - fileOptions = this.removeOptions(fileOptions, ["owner-change"]); - } - - if (isThirdPartyItem) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "finalize-version", - "copy", - ]); - } - - if (isCommonFolder) { - if (!this.userAccess) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "move-to", - "delete", - "copy", - "separator2", - ]); - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, ["separator2"]); - } - } - } - - if (withoutShare) { - fileOptions = this.removeOptions(fileOptions, [ - "sharing-settings", - "external-link", - ]); - } - - if (!hasNew) { - fileOptions = this.removeOptions(fileOptions, ["mark-read"]); - } - - if ( - !( - isRecentFolder || - isFavoritesFolder || - (isMyFolder && (this.filter.filterType || this.filter.search)) - ) - ) { - fileOptions = this.removeOptions(fileOptions, ["open-location"]); - } - - if (isShareItem) { - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, ["edit"]); - } - - if (isShareFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "copy", - "move-to", - "delete", - ]); - } - } else if (!isEncrypted) { - fileOptions = this.removeOptions(fileOptions, ["unsubscribe"]); - } - - if (isPrivacyFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "preview", - "view", - "separator0", - "copy", - "download-as", - ]); - - if (!isDesktopClient) { - fileOptions = this.removeOptions(fileOptions, ["sharing-settings"]); - } - - fileOptions = this.removeOptions( - fileOptions, - isFileOwner ? ["unsubscribe"] : ["move-to", "delete"] - ); - } - - if (!shouldEdit && !shouldView && !fileOptions.includes("view")) { - fileOptions = this.removeOptions(fileOptions, [ - "edit", - "preview", - "separator0", - ]); - } - - if (!shouldEdit && shouldView) { - fileOptions = this.removeOptions(fileOptions, ["edit"]); - } - - return fileOptions; - } else { - let folderOptions = [ - "open", - "separator0", - "sharing-settings", - "owner-change", - "link-for-portal-users", - "separator1", - "open-location", - "download", - "move", //category - "move-to", - "copy-to", - "mark-read", - "restore", - "rename", - "change-thirdparty-info", - "separator2", - "unsubscribe", - "delete", - ]; - - if (personal) { - folderOptions = this.removeOptions(folderOptions, [ - "sharing-settings", - "owner-change", - "link-for-portal-users", - "separator1", - "docu-sign", - "mark-read", - "unsubscribe", - ]); - } - - if (isPrivacyFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "sharing-settings", - "copy", - "copy-to", - ]); - - if (!isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, ["rename"]); - } - } - - if (isShareItem) { - if (isShareFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "move-to", - "delete", - ]); - } - } else { - folderOptions = this.removeOptions(folderOptions, ["unsubscribe"]); - } - - if (isRecycleBinFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "open", - "link-for-portal-users", - "sharing-settings", - "move", - "move-to", - "copy-to", - "mark-read", - "rename", - "separator0", - "separator1", - ]); - } else { - folderOptions = this.removeOptions(folderOptions, ["restore"]); - } - - if (!isFullAccess) { - //TODO: if added Projects, add project folder check - folderOptions = this.removeOptions(folderOptions, [ - "rename", - "change-thirdparty-info", - ]); - } - - if (!this.canShareOwnerChange(item)) { - folderOptions = this.removeOptions(folderOptions, ["owner-change"]); - } - - if (!isFullAccess) { - folderOptions = this.removeOptions(folderOptions, [ - "owner-change", - "move-to", - "delete", - "change-thirdparty-info", - ]); - - if (!isShareItem) { - folderOptions = this.removeOptions(folderOptions, ["separator2"]); - } - - if (isVisitor) { - folderOptions = this.removeOptions(folderOptions, ["rename"]); - } - } - - if (withoutShare) { - folderOptions = this.removeOptions(folderOptions, ["sharing-settings"]); - } - - if (!hasNew) { - folderOptions = this.removeOptions(folderOptions, ["mark-read"]); - } - - if (isThirdPartyFolder) { - folderOptions = this.removeOptions(folderOptions, ["move-to"]); - - if (isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, [ - "separator2", - "delete", - ]); - } - } else { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - if (isThirdPartyItem) { - folderOptions = this.removeOptions(folderOptions, ["owner-change"]); - - if (isShareFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } else { - if (isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - folderOptions = this.removeOptions(folderOptions, ["remove"]); - - if (!item) { - //For damaged items - folderOptions = this.removeOptions(folderOptions, [ - "open", - "download", - "copy-to", - "rename", - ]); - } - } - } else { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - if (!(isMyFolder && (this.filter.filterType || this.filter.search))) { - folderOptions = this.removeOptions(folderOptions, ["open-location"]); - } - - return folderOptions; - } - }; - - addFileToRecentlyViewed = (fileId) => { - if (this.treeFoldersStore.isPrivacyFolder) return Promise.resolve(); - return api.files.addFileToRecentlyViewed(fileId); - }; - - createFile = (folderId, title, templateId) => { - return api.files.createFile(folderId, title, templateId).then((file) => { - return Promise.resolve(file); - }); - }; - - createFolder(parentFolderId, title) { - return api.files.createFolder(parentFolderId, title); - } - - setFile = (file) => { - const fileIndex = this.files.findIndex((f) => f.id === file.id); - if (fileIndex !== -1) this.files[fileIndex] = file; - }; - - setFolder = (folder) => { - const folderIndex = this.folders.findIndex((f) => f.id === folder.id); - if (folderIndex !== -1) this.folders[folderIndex] = folder; - }; - - updateFolderBadge = (id, count) => { - const folder = this.folders.find((x) => x.id === id); - if (folder) folder.new -= count; - }; - - updateFileBadge = (id) => { - const file = this.files.find((x) => x.id === id); - if (file) file.fileStatus = 0; - }; - - updateFilesBadge = () => { - for (let file of this.files) { - file.fileStatus = 0; - } - }; - - updateFoldersBadge = () => { - for (let folder of this.folders) { - folder.new = 0; - } - }; - - updateFile = (fileId, title) => { - return api.files - .updateFile(fileId, title) - .then((file) => this.setFile(file)); - }; - - renameFolder = (folderId, title) => { - return api.files.renameFolder(folderId, title).then((folder) => { - this.setFolder(folder); - }); - }; - - getFilesCount = () => { - const { filesCount, foldersCount } = this.selectedFolderStore; - return filesCount + this.folders ? this.folders.length : foldersCount; - }; - - getServiceFilesCount = () => { - const filesLength = this.files ? this.files.length : 0; - const foldersLength = this.folders ? this.folders.length : 0; - return filesLength + foldersLength; - }; - - canShareOwnerChange = (item) => { - const userId = this.userStore.user && this.userStore.user.id; - const isCommonFolder = - this.treeFoldersStore.commonFolder && - this.selectedFolderStore.pathParts && - this.treeFoldersStore.commonFolder.id === - this.selectedFolderStore.pathParts[0]; - - if (item.providerKey || !isCommonFolder) { - return false; - } else if (this.authStore.isAdmin) { - return true; - } else if (item.createdBy.id === userId) { - return true; - } else { - return false; - } - }; - - get canShare() { - const folderType = this.selectedFolderStore.rootFolderType; - const isVisitor = - (this.userStore.user && this.userStore.user.isVisitor) || false; - - if (isVisitor) { - return false; - } - - switch (folderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - return true; - case FolderType.COMMON: - return this.authStore.isAdmin; - case FolderType.TRASH: - return false; - case FolderType.Favorites: - return true; // false; - case FolderType.Recent: - return true; //false; - case FolderType.Privacy: - return true; - default: - return false; - } - } - - get currentFilesCount() { - const serviceFilesCount = this.getServiceFilesCount(); - const filesCount = this.getFilesCount(); - return this.selectedFolderStore.providerItem - ? serviceFilesCount - : filesCount; - } - - get iconOfDraggedFile() { - const { getIcon } = this.formatsStore.iconFormatsStore; - - if (this.selection.length === 1) { - return getIcon( - 24, - this.selection[0].fileExst, - this.selection[0].providerKey - ); - } - return null; - } - - get isHeaderVisible() { - return this.selection.length > 0; - } - - get isHeaderIndeterminate() { - const items = [...this.files, ...this.folders]; - return this.isHeaderVisible && this.selection.length - ? this.selection.length < items.length - : false; - } - - get isHeaderChecked() { - const items = [...this.files, ...this.folders]; - return this.isHeaderVisible && this.selection.length === items.length; - } - - get canCreate() { - switch (this.selectedFolderStore.rootFolderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - const canCreateInSharedFolder = this.selectedFolderStore.access === 1; - return ( - !this.selectedFolderStore.isRootFolder && canCreateInSharedFolder - ); - case FolderType.Privacy: - return ( - this.authStore.settingsStore.isDesktopClient && - this.settingsStore.isEncryptionSupport - ); - case FolderType.COMMON: - return this.authStore.isAdmin; - case FolderType.TRASH: - default: - return false; - } - } - - onCreateAddTempItem = (items) => { - const { getFileIcon, getFolderIcon } = this.formatsStore.iconFormatsStore; - const { extension, title } = this.fileActionStore; - - if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this; - - const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24; - const icon = extension - ? getFileIcon(`.${extension}`, iconSize) - : getFolderIcon(null, iconSize); - - items.unshift({ - id: -1, - title: title, - parentId: this.selectedFolderStore.id, - fileExst: extension, - icon, - }); - }; - - get filesList() { - const { mediaViewersFormatsStore, iconFormatsStore } = this.formatsStore; - const { getIcon } = iconFormatsStore; - //return [...this.folders, ...this.files]; - - const items = [...this.folders, ...this.files]; - const newItem = items.map((item) => { - const { - access, - comment, - contentLength, - created, - createdBy, - encrypted, - fileExst, - filesCount, - fileStatus, - fileType, - folderId, - foldersCount, - id, - locked, - parentId, - pureContentLength, - rootFolderType, - rootFolderId, - shared, - title, - updated, - updatedBy, - version, - versionGroup, - viewUrl, - webUrl, - providerKey, - thumbnailUrl, - thumbnailStatus, - canShare, - canEdit, - } = item; - - const { canConvert } = this.formatsStore.docserviceStore; - - const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( - item.fileExst - ); - - const previewUrl = canOpenPlayer - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/#preview/${id}` - ) - : null; - const contextOptions = this.getFilesContextOptions(item, canOpenPlayer); - const isThirdPartyFolder = providerKey && id === rootFolderId; - - const iconSize = this.viewAs === "table" ? 24 : 32; - const icon = getIcon(iconSize, fileExst, providerKey, contentLength); - - let isFolder = false; - this.folders.map((x) => { - if (x.id === item.id) isFolder = true; - }); - - const { isRecycleBinFolder } = this.treeFoldersStore; - - const folderUrl = isFolder - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/filter?folder=${id}` - ) - : null; - - const needConvert = canConvert(fileExst); - - const docUrl = combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/doceditor?fileId=${id}${needConvert ? "&action=view" : ""}` - ); - - const href = isRecycleBinFolder - ? null - : previewUrl - ? previewUrl - : !isFolder - ? docUrl - : folderUrl; - - return { - access, - //checked, - comment, - contentLength, - contextOptions, - created, - createdBy, - encrypted, - fileExst, - filesCount, - fileStatus, - fileType, - folderId, - foldersCount, - icon, - id, - isFolder, - locked, - new: item.new, - parentId, - pureContentLength, - rootFolderType, - rootFolderId, - //selectedItem, - shared, - title, - updated, - updatedBy, - version, - versionGroup, - viewUrl, - webUrl, - providerKey, - canOpenPlayer, - //canShare, - canShare, - canEdit, - thumbnailUrl, - thumbnailStatus, - previewUrl, - folderUrl, - href, - isThirdPartyFolder, - }; - }); - - if (this.fileActionStore.type === FileAction.Create) { - this.onCreateAddTempItem(newItem); - } - - return newItem; - } - - get cbMenuItems() { - const { mediaViewersFormatsStore, iconFormatsStore } = this.formatsStore; - const { - isDocument, - isPresentation, - isSpreadsheet, - isArchive, - } = iconFormatsStore; - const { isImage, isVideo } = mediaViewersFormatsStore; - - let cbMenu = ["all"]; - const filesItems = [...this.files, ...this.folders]; - - if (this.folders.length) cbMenu.push(FilterType.FoldersOnly); - for (let item of filesItems) { - if (isDocument(item.fileExst)) cbMenu.push(FilterType.DocumentsOnly); - else if (isPresentation(item.fileExst)) - cbMenu.push(FilterType.PresentationsOnly); - else if (isSpreadsheet(item.fileExst)) - cbMenu.push(FilterType.SpreadsheetsOnly); - else if (isImage(item.fileExst)) cbMenu.push(FilterType.ImagesOnly); - else if (isVideo(item.fileExst)) cbMenu.push(FilterType.MediaOnly); - else if (isArchive(item.fileExst)) cbMenu.push(FilterType.ArchiveOnly); - } - - const hasFiles = cbMenu.some( - (elem) => elem !== "all" && elem !== FilterType.FoldersOnly - ); - - if (hasFiles) cbMenu.push(FilterType.FilesOnly); - - cbMenu = cbMenu.filter((item, index) => cbMenu.indexOf(item) === index); - - return cbMenu; - } - - getCheckboxItemLabel = (t, key) => { - switch (key) { - case "all": - return t("All"); - case FilterType.FoldersOnly: - return t("Translations:Folders"); - case FilterType.DocumentsOnly: - return t("Common:Documents"); - case FilterType.PresentationsOnly: - return t("Translations:Presentations"); - case FilterType.SpreadsheetsOnly: - return t("Translations:Spreadsheets"); - case FilterType.ImagesOnly: - return t("Images"); - case FilterType.MediaOnly: - return t("Media"); - case FilterType.ArchiveOnly: - return t("Archives"); - case FilterType.FilesOnly: - return t("AllFiles"); - - default: - return ""; - } - }; - - get sortedFiles() { - const { - isSpreadsheet, - isPresentation, - isDocument, - } = this.formatsStore.iconFormatsStore; - const { filesConverts } = this.formatsStore.docserviceStore; - - let sortedFiles = { - documents: [], - spreadsheets: [], - presentations: [], - other: [], + return newSelection; }; - const selection = this.selection.length - ? this.selection - : this.bufferSelection - ? [this.bufferSelection] - : []; + setSelected = (selected) => { + if (selected === "close" || selected === "none") + this.setBufferSelection(null); - for (let item of selection) { - item.checked = true; - item.format = null; + this.selected = selected; + const files = this.files.concat(this.folders); + this.selection = this.getFilesBySelected(files, selected); + }; - const canConvert = filesConverts.find((f) => f[item.fileExst]); + setSelection = (selection) => { + this.selection = selection; + }; - if (item.fileExst && canConvert) { - if (isSpreadsheet(item.fileExst)) { - sortedFiles.spreadsheets.push(item); - } else if (isPresentation(item.fileExst)) { - sortedFiles.presentations.push(item); - } else if (isDocument(item.fileExst)) { - sortedFiles.documents.push(item); - } else { - sortedFiles.other.push(item); - } - } else { - sortedFiles.other.push(item); - } - } + setBufferSelection = (bufferSelection) => { + this.bufferSelection = bufferSelection; + }; - return sortedFiles; - } + //TODO: FILTER + setFilesFilter = (filter) => { + const key = `UserFilter=${this.userStore.user.id}`; + const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; + localStorage.setItem(key, value); - get userAccess() { - switch (this.selectedFolderStore.rootFolderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - return false; - case FolderType.COMMON: - return ( - this.authStore.isAdmin || - this.selection.some((x) => x.access === 0 || x.access === 1) + this.setFilterUrl(filter); + this.filter = filter; + }; + + setFilter = (filter) => { + this.filter = filter; + }; + + setFilesOwner = (folderIds, fileIds, ownerId) => { + return api.files.setFileOwner(folderIds, fileIds, ownerId); + }; + + setFilterUrl = (filter) => { + const urlFilter = filter.toUrlParams(); + history.push( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/filter?${urlFilter}` + ) ); - case FolderType.Privacy: - return true; - case FolderType.TRASH: - return true; - default: - return false; - } - } + }; - get isAccessedSelected() { - return ( - this.selection.length && - this.selection.every((x) => x.access === 1 || x.access === 0) - ); - } + isEmptyLastPageAfterOperation = (newSelection) => { + const selection = + newSelection || + this.selection?.length || + [this.bufferSelection].length; - get isThirdPartyRootSelection() { - const withProvider = this.selection.find((x) => x.providerKey); - return withProvider && withProvider.rootFolderId === withProvider.id; - } + return ( + selection && + this.filter.page > 0 && + !this.filter.hasNext() && + selection === this.files.length + this.folders.length + ); + }; - get isThirdPartySelection() { - const withProvider = this.selection.find((x) => x.providerKey); - return !!withProvider; - } + resetFilterPage = () => { + let newFilter; + newFilter = this.filter.clone(); + newFilter.page--; - get canConvertSelected() { - const { filesConverts } = this.formatsStore.docserviceStore; + return newFilter; + }; - const selection = this.selection.length - ? this.selection - : this.bufferSelection - ? [this.bufferSelection] - : []; + fetchFiles = ( + folderId, + filter, + clearFilter = true, + withSubfolders = false + ) => { + const { + treeFolders, + setSelectedNode, + getSubfolders, + } = this.treeFoldersStore; - return selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - const index = filesConverts.findIndex((f) => f[selected.fileExst]); - return index !== -1; - }); - } + const filterData = filter ? filter.clone() : FilesFilter.getDefault(); + filterData.folder = folderId; - get isViewedSelected() { - const { canViewedDocs } = this.formatsStore.docserviceStore; + const filterStorageItem = localStorage.getItem( + `UserFilter=${this.userStore.user.id}` + ); - return this.selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - return canViewedDocs(selected.fileExst); - }); - } + if (filterStorageItem && !filter) { + const splitFilter = filterStorageItem.split(","); - get isMediaSelected() { - const { isMediaOrImage } = this.formatsStore.mediaViewersFormatsStore; + filterData.sortBy = splitFilter[0]; + filterData.pageCount = splitFilter[1]; + filterData.sortOrder = splitFilter[2]; + } - return this.selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - return isMediaOrImage(selected.fileExst); - }); - } + setSelectedNode([folderId + ""]); - get selectionTitle() { - if (this.selection.length === 0) { - if (this.bufferSelection) { - return this.bufferSelection.title; - } - return null; - } - return this.selection.find((el) => el.title).title; - } + //TODO: fix @my + let requestCounter = 1; + const request = () => + api.files + .getFolder(folderId, filterData) + .then(async (data) => { + const isRecycleBinFolder = + data.current.rootFolderType === FolderType.TRASH; - get hasSelection() { - return !!this.selection.length; - } + !isRecycleBinFolder && this.checkUpdateNode(data, folderId); - get isEmptyFilesList() { - const filesList = [...this.files, ...this.folders]; - return filesList.length <= 0; - } + if (!isRecycleBinFolder && withSubfolders) { + const path = data.pathParts.slice(0); + const foldersCount = data.current.foldersCount; + const subfolders = await getSubfolders(folderId); + loopTreeFolders( + path, + treeFolders, + subfolders, + foldersCount + ); + } - getOptions = (selection, externalAccess = false) => { - const { - canWebEdit, - canWebComment, - canWebReview, - canFormFillingDocs, - canWebFilterEditing, - } = this.formatsStore.docserviceStore; + const isPrivacyFolder = + data.current.rootFolderType === FolderType.Privacy; - if (selection[0].encrypted) { - return ["FullAccess", "DenyAccess"]; + filterData.total = data.total; + this.setFilesFilter(filterData); //TODO: FILTER + this.setFolders( + isPrivacyFolder && isMobile ? [] : data.folders + ); + this.setFiles( + isPrivacyFolder && isMobile ? [] : data.files + ); + + if (clearFilter) { + this.fileActionStore.setAction({ type: null }); + this.setSelected("close"); + } + + this.selectedFolderStore.setSelectedFolder({ + folders: data.folders, + ...data.current, + pathParts: data.pathParts, + ...{ new: data.new }, + }); + + const selectedFolder = { + selectedFolder: { ...this.selectedFolderStore }, + }; + this.viewAs === "tile" && this.createThumbnails(); + return Promise.resolve(selectedFolder); + }) + .catch((err) => { + toastr.error(err); + if (!requestCounter) return; + requestCounter--; + + if (folderId === "@my" /* && !this.isInit */) { + setTimeout(() => { + return request(); + }, 5000); + } else { + this.treeFoldersStore.fetchTreeFolders(); + return this.fetchFiles( + this.userStore.user.isVisitor ? "@common" : "@my" + ); + } + }); + + return request(); + }; + + checkUpdateNode = async (data, folderId) => { + const { treeFolders, getSubfolders } = this.treeFoldersStore; + const { pathParts, current } = data; + + if (current.parentId === 0) return; + + const somePath = pathParts.slice(0); + const path = pathParts.slice(0); + let newItems = treeFolders; + + while (somePath.length !== 1) { + const folderItem = newItems.find((x) => x.id === somePath[0]); + newItems = folderItem?.folders + ? folderItem.folders + : somePath.length > 1 + ? [] + : null; + if (!newItems) { + return; + } + + somePath.shift(); + } + + if (!newItems.find((x) => x.id == folderId)) { + path.splice(pathParts.length - 1, 1); + const subfolders = await getSubfolders(current.parentId); + loopTreeFolders(path, treeFolders, subfolders, 0); + } + }; + + isFileSelected = (fileId, parentId) => { + const item = this.selection.find( + (x) => x.id === fileId && x.parentId === parentId + ); + + return item !== undefined; + }; + + selectFile = (file) => { + const { id, parentId } = file; + const isFileSelected = this.isFileSelected(id, parentId); + if (!isFileSelected) this.selection.push(file); + }; + + deselectFile = (file) => { + const { id, parentId } = file; + const isFileSelected = this.isFileSelected(id, parentId); + if (isFileSelected) + this.selection = this.selection.filter((x) => x.id !== id); + }; + + removeOptions = (options, toRemoveArray) => + options.filter((o) => !toRemoveArray.includes(o)); + + getFilesContextOptions = (item, canOpenPlayer) => { + const isVisitor = + (this.userStore.user && this.userStore.user.isVisitor) || false; + const isFile = !!item.fileExst || item.contentLength; + const isFavorite = + item.fileStatus === 32 || + item.fileStatus === 33 || + item.fileStatus === 34; + const isFullAccess = item.access < 2; + const withoutShare = false; //TODO: need this prop + const isThirdPartyItem = !!item.providerKey; + const hasNew = + item.new > 0 || item.fileStatus === 2 || item.fileStatus === 34; + const canConvert = false; //TODO: fix of added convert check; + const isEncrypted = item.encrypted; + const isDocuSign = false; //TODO: need this prop; + const isEditing = false; //TODO: need this prop; + const isFileOwner = item.createdBy.id === this.userStore.user.id; + + const { + isRecycleBinFolder, + isPrivacyFolder, + isRecentFolder, + isCommon, + isShare, + isFavoritesFolder, + isShareFolder, + isMy, + } = this.treeFoldersStore; + + const { + canWebEdit, + canViewedDocs, + canFormFillingDocs, + } = this.formatsStore.docserviceStore; + + const isThirdPartyFolder = + item.providerKey && item.id === item.rootFolderId; + const isShareItem = isShare(item.rootFolderType); + const isCommonFolder = isCommon(item.rootFolderType); + const isMyFolder = isMy(item.rootFolderType); + + const { personal } = this.settingsStore; + const { isDesktopClient } = this.authStore.settingsStore; + + if (isFile) { + const shouldFillForm = canFormFillingDocs(item.fileExst); + const shouldEdit = !shouldFillForm && canWebEdit(item.fileExst); + const shouldView = canViewedDocs(item.fileExst); + const isMasterForm = item.fileExst === ".docxf"; + + let fileOptions = [ + //"open", + "fill-form", + "edit", + "preview", + "view", + "make-form", + "separator0", + "sharing-settings", + "external-link", + "owner-change", + "link-for-portal-users", + "send-by-email", + "docu-sign", + "version", //category + "finalize-version", + "show-version-history", + "block-unblock-version", //need split + "separator1", + "open-location", + "mark-read", + "mark-as-favorite", + "remove-from-favorites", + "download", + "download-as", + "convert", + "move", //category + "move-to", + "copy-to", + "copy", + "restore", + "rename", + "separator2", + "unsubscribe", + "delete", + ]; + + if (!isMasterForm) + fileOptions = this.removeOptions(fileOptions, ["make-form"]); + + if (!shouldFillForm) + fileOptions = this.removeOptions(fileOptions, ["fill-form"]); + + if (personal) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "link-for-portal-users", + "docu-sign", + "mark-read", + "unsubscribe", + ]); + + if (!shouldEdit && !shouldView) { + fileOptions = this.removeOptions(fileOptions, [ + "sharing-settings", + ]); + } + } + + if (!this.canConvertSelected) { + fileOptions = this.removeOptions(fileOptions, ["download-as"]); + } + + if (!canConvert || isEncrypted) { + fileOptions = this.removeOptions(fileOptions, ["convert"]); + } + + if (!canOpenPlayer) { + fileOptions = this.removeOptions(fileOptions, ["view"]); + } else { + fileOptions = this.removeOptions(fileOptions, [ + "edit", + "preview", + ]); + } + + if (!isDocuSign) { + fileOptions = this.removeOptions(fileOptions, ["docu-sign"]); + } + + if (isEditing) { + fileOptions = this.removeOptions(fileOptions, [ + "finalize-version", + "move-to", + "delete", + ]); + if (isThirdPartyFolder) { + fileOptions = this.removeOptions(fileOptions, ["rename"]); + } + } + + if (isFavorite) { + fileOptions = this.removeOptions(fileOptions, [ + "mark-as-favorite", + ]); + } else { + fileOptions = this.removeOptions(fileOptions, [ + "remove-from-favorites", + ]); + + if (isFavoritesFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "mark-as-favorite", + ]); + } + } + + if (isFavoritesFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "move-to", + "delete", + "copy", + ]); + + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, [ + "separator2", + ]); + } + } + + if (isEncrypted) { + fileOptions = this.removeOptions(fileOptions, [ + "open", + "edit", + "make-form", + "link-for-portal-users", + "external-link", + "send-by-email", + "block-unblock-version", //need split + "version", //category + "finalize-version", + "copy-to", + "copy", + "mark-as-favorite", + ]); + } + + if (isRecentFolder) { + fileOptions = this.removeOptions(fileOptions, ["delete"]); + + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, [ + "separator2", + ]); + } + } + + if (isFavoritesFolder || isRecentFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "make-form", + "copy", + "move-to", + //"sharing-settings", + "unsubscribe", + "separator2", + ]); + } + + if (isRecycleBinFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "fill-form", + "open", + "open-location", + "view", + "preview", + "edit", + "make-form", + "link-for-portal-users", + "sharing-settings", + "external-link", + "send-by-email", + "block-unblock-version", //need split + "version", //category + "finalize-version", + "show-version-history", + "move", //category + "move-to", + "copy-to", + "copy", + "mark-read", + "mark-as-favorite", + "remove-from-favorites", + "rename", + "separator0", + "separator1", + ]); + } else { + fileOptions = this.removeOptions(fileOptions, ["restore"]); + } + + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, [ + "finalize-version", + "rename", + "block-unblock-version", + "copy", + "sharing-settings", + ]); + } + + if (isVisitor) { + fileOptions = this.removeOptions(fileOptions, [ + "block-unblock-version", + "finalize-version", + "mark-as-favorite", + "remove-from-favorites", + ]); + + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, ["rename"]); + } + } + + if (!this.canShareOwnerChange(item)) { + fileOptions = this.removeOptions(fileOptions, ["owner-change"]); + } + + if (isThirdPartyItem) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "finalize-version", + "copy", + ]); + } + + if (isCommonFolder) { + if (!this.userAccess) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "move-to", + "delete", + "copy", + "separator2", + ]); + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, [ + "separator2", + ]); + } + } + } + + if (withoutShare) { + fileOptions = this.removeOptions(fileOptions, [ + "sharing-settings", + "external-link", + ]); + } + + if (!hasNew) { + fileOptions = this.removeOptions(fileOptions, ["mark-read"]); + } + + if ( + !( + isRecentFolder || + isFavoritesFolder || + (isMyFolder && + (this.filter.filterType || this.filter.search)) + ) + ) { + fileOptions = this.removeOptions(fileOptions, [ + "open-location", + ]); + } + + if (isShareItem) { + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, ["edit"]); + } + + if (isShareFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "copy", + "move-to", + "delete", + ]); + } + } else if (!isEncrypted) { + fileOptions = this.removeOptions(fileOptions, ["unsubscribe"]); + } + + if (isPrivacyFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "preview", + "view", + "separator0", + "copy", + "download-as", + ]); + + if (!isDesktopClient) { + fileOptions = this.removeOptions(fileOptions, [ + "sharing-settings", + ]); + } + + fileOptions = this.removeOptions( + fileOptions, + isFileOwner ? ["unsubscribe"] : ["move-to", "delete"] + ); + } + + if (!shouldEdit && !shouldView && !fileOptions.includes("view")) { + fileOptions = this.removeOptions(fileOptions, [ + "edit", + "preview", + "separator0", + ]); + } + + if (!shouldEdit && shouldView) { + fileOptions = this.removeOptions(fileOptions, ["edit"]); + } + + return fileOptions; + } else { + let folderOptions = [ + "open", + "separator0", + "sharing-settings", + "owner-change", + "link-for-portal-users", + "separator1", + "open-location", + "download", + "move", //category + "move-to", + "copy-to", + "mark-read", + "restore", + "rename", + "change-thirdparty-info", + "separator2", + "unsubscribe", + "delete", + ]; + + if (personal) { + folderOptions = this.removeOptions(folderOptions, [ + "sharing-settings", + "owner-change", + "link-for-portal-users", + "separator1", + "docu-sign", + "mark-read", + "unsubscribe", + ]); + } + + if (isPrivacyFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "sharing-settings", + "copy", + "copy-to", + ]); + + if (!isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, [ + "rename", + ]); + } + } + + if (isShareItem) { + if (isShareFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "move-to", + "delete", + ]); + } + } else { + folderOptions = this.removeOptions(folderOptions, [ + "unsubscribe", + ]); + } + + if (isRecycleBinFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "open", + "link-for-portal-users", + "sharing-settings", + "move", + "move-to", + "copy-to", + "mark-read", + "rename", + "separator0", + "separator1", + ]); + } else { + folderOptions = this.removeOptions(folderOptions, ["restore"]); + } + + if (!isFullAccess) { + //TODO: if added Projects, add project folder check + folderOptions = this.removeOptions(folderOptions, [ + "rename", + "change-thirdparty-info", + ]); + } + + if (!this.canShareOwnerChange(item)) { + folderOptions = this.removeOptions(folderOptions, [ + "owner-change", + ]); + } + + if (!isFullAccess) { + folderOptions = this.removeOptions(folderOptions, [ + "owner-change", + "move-to", + "delete", + "change-thirdparty-info", + ]); + + if (!isShareItem) { + folderOptions = this.removeOptions(folderOptions, [ + "separator2", + ]); + } + + if (isVisitor) { + folderOptions = this.removeOptions(folderOptions, [ + "rename", + ]); + } + } + + if (withoutShare) { + folderOptions = this.removeOptions(folderOptions, [ + "sharing-settings", + ]); + } + + if (!hasNew) { + folderOptions = this.removeOptions(folderOptions, [ + "mark-read", + ]); + } + + if (isThirdPartyFolder) { + folderOptions = this.removeOptions(folderOptions, ["move-to"]); + + if (isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, [ + "separator2", + "delete", + ]); + } + } else { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } + + if (isThirdPartyItem) { + folderOptions = this.removeOptions(folderOptions, [ + "owner-change", + ]); + + if (isShareFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } else { + if (isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } + + folderOptions = this.removeOptions(folderOptions, [ + "remove", + ]); + + if (!item) { + //For damaged items + folderOptions = this.removeOptions(folderOptions, [ + "open", + "download", + "copy-to", + "rename", + ]); + } + } + } else { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } + + if ( + !(isMyFolder && (this.filter.filterType || this.filter.search)) + ) { + folderOptions = this.removeOptions(folderOptions, [ + "open-location", + ]); + } + + return folderOptions; + } + }; + + addFileToRecentlyViewed = (fileId) => { + if (this.treeFoldersStore.isPrivacyFolder) return Promise.resolve(); + return api.files.addFileToRecentlyViewed(fileId); + }; + + createFile = (folderId, title, templateId) => { + return api.files + .createFile(folderId, title, templateId) + .then((file) => { + return Promise.resolve(file); + }); + }; + + createFolder(parentFolderId, title) { + return api.files.createFolder(parentFolderId, title); } - let AccessOptions = []; + setFile = (file) => { + const fileIndex = this.files.findIndex((f) => f.id === file.id); + if (fileIndex !== -1) this.files[fileIndex] = file; + }; - AccessOptions.push("ReadOnly", "DenyAccess"); + setFolder = (folder) => { + const folderIndex = this.folders.findIndex((f) => f.id === folder.id); + if (folderIndex !== -1) this.folders[folderIndex] = folder; + }; - const webEdit = selection.find((x) => canWebEdit(x.fileExst)); + updateFolderBadge = (id, count) => { + const folder = this.folders.find((x) => x.id === id); + if (folder) folder.new -= count; + }; - const webComment = selection.find((x) => canWebComment(x.fileExst)); + updateFileBadge = (id) => { + const file = this.files.find((x) => x.id === id); + if (file) file.fileStatus = 0; + }; - const webReview = selection.find((x) => canWebReview(x.fileExst)); + updateFilesBadge = () => { + for (let file of this.files) { + file.fileStatus = 0; + } + }; - const formFillingDocs = selection.find((x) => - canFormFillingDocs(x.fileExst) - ); + updateFoldersBadge = () => { + for (let folder of this.folders) { + folder.new = 0; + } + }; - const webFilter = selection.find((x) => canWebFilterEditing(x.fileExst)); + updateFile = (fileId, title) => { + return api.files + .updateFile(fileId, title) + .then((file) => this.setFile(file)); + }; - if (webEdit || !externalAccess) AccessOptions.push("FullAccess"); + renameFolder = (folderId, title) => { + return api.files.renameFolder(folderId, title).then((folder) => { + this.setFolder(folder); + }); + }; - if (webComment) AccessOptions.push("Comment"); - if (webReview) AccessOptions.push("Review"); - if (formFillingDocs && !externalAccess) AccessOptions.push("FormFilling"); - if (webFilter) AccessOptions.push("FilterEditing"); + getFilesCount = () => { + const { filesCount, foldersCount } = this.selectedFolderStore; + return filesCount + this.folders ? this.folders.length : foldersCount; + }; - return AccessOptions; - }; + getServiceFilesCount = () => { + const filesLength = this.files ? this.files.length : 0; + const foldersLength = this.folders ? this.folders.length : 0; + return filesLength + foldersLength; + }; - getAccessOption = (selection) => { - return this.getOptions(selection); - }; + canShareOwnerChange = (item) => { + const userId = this.userStore.user && this.userStore.user.id; + const isCommonFolder = + this.treeFoldersStore.commonFolder && + this.selectedFolderStore.pathParts && + this.treeFoldersStore.commonFolder.id === + this.selectedFolderStore.pathParts[0]; - getExternalAccessOption = (selection) => { - return this.getOptions(selection, true); - }; + if (item.providerKey || !isCommonFolder) { + return false; + } else if (this.authStore.isAdmin) { + return true; + } else if (item.createdBy.id === userId) { + return true; + } else { + return false; + } + }; - setSelections = (items) => { - if (!items.length && !this.selection.length) return; + get canShare() { + const folderType = this.selectedFolderStore.rootFolderType; + const isVisitor = + (this.userStore.user && this.userStore.user.isVisitor) || false; - //if (items.length !== this.selection.length) { - const newSelection = []; + if (isVisitor) { + return false; + } - for (let item of items) { - const value = item.getAttribute("value"); - const splitValue = value && value.split("_"); - - const fileType = splitValue[0]; - const id = - splitValue[splitValue.length - 1] === "draggable" - ? splitValue.slice(1, -1).join("_") - : splitValue.slice(1).join("_"); - - if (fileType === "file") { - newSelection.push(this.files.find((f) => f.id == id)); - } else { - const selectableFolder = this.folders.find((f) => f.id == id); - selectableFolder.isFolder = true; - newSelection.push(selectableFolder); - } + switch (folderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + return true; + case FolderType.COMMON: + return this.authStore.isAdmin; + case FolderType.TRASH: + return false; + case FolderType.Favorites: + return true; // false; + case FolderType.Recent: + return true; //false; + case FolderType.Privacy: + return true; + default: + return false; + } } - //this.selected === "close" && this.setSelected("none"); - - //need fo table view - const clearSelection = Object.values( - newSelection.reduce((item, n) => ((item[n.id] = n), item), {}) - ); - - this.setSelection(clearSelection); - //} - }; - - getShareUsers(folderIds, fileIds) { - return api.files.getShareFiles(fileIds, folderIds); - } - - setShareFiles = ( - folderIds, - fileIds, - share, - notify, - sharingMessage, - externalAccess, - ownerId - ) => { - let externalAccessRequest = []; - if (fileIds.length === 1 && externalAccess !== null) { - externalAccessRequest = fileIds.map((id) => - api.files.setExternalAccess(id, externalAccess) - ); + get currentFilesCount() { + const serviceFilesCount = this.getServiceFilesCount(); + const filesCount = this.getFilesCount(); + return this.selectedFolderStore.providerItem + ? serviceFilesCount + : filesCount; } - const ownerChangeRequest = ownerId - ? [this.setFilesOwner(folderIds, fileIds, ownerId)] - : []; + get iconOfDraggedFile() { + const { getIcon } = this.formatsStore.iconFormatsStore; - const shareRequest = !!share.length - ? [ - api.files.setShareFiles( - fileIds, - folderIds, - share, - notify, - sharingMessage - ), - ] - : []; + if (this.selection.length === 1) { + return getIcon( + 24, + this.selection[0].fileExst, + this.selection[0].providerKey + ); + } + return null; + } - const requests = [ - ...ownerChangeRequest, - ...shareRequest, - ...externalAccessRequest, - ]; + get isHeaderVisible() { + return this.selection.length > 0; + } - return Promise.all(requests); - }; + get isHeaderIndeterminate() { + const items = [...this.files, ...this.folders]; + return this.isHeaderVisible && this.selection.length + ? this.selection.length < items.length + : false; + } - markItemAsFavorite = (id) => api.files.markAsFavorite(id); + get isHeaderChecked() { + const items = [...this.files, ...this.folders]; + return this.isHeaderVisible && this.selection.length === items.length; + } - removeItemFromFavorite = (id) => api.files.removeFromFavorite(id); + get canCreate() { + switch (this.selectedFolderStore.rootFolderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + const canCreateInSharedFolder = + this.selectedFolderStore.access === 1; + return ( + !this.selectedFolderStore.isRootFolder && + canCreateInSharedFolder + ); + case FolderType.Privacy: + return ( + this.authStore.settingsStore.isDesktopClient && + this.settingsStore.isEncryptionSupport + ); + case FolderType.COMMON: + return this.authStore.isAdmin; + case FolderType.TRASH: + default: + return false; + } + } - fetchFavoritesFolder = async (folderId) => { - const favoritesFolder = await api.files.getFolder(folderId); - this.setFolders(favoritesFolder.folders); - this.setFiles(favoritesFolder.files); + onCreateAddTempItem = (items) => { + const { + getFileIcon, + getFolderIcon, + } = this.formatsStore.iconFormatsStore; + const { extension, title } = this.fileActionStore; - this.selectedFolderStore.setSelectedFolder({ - folders: favoritesFolder.folders, - ...favoritesFolder.current, - pathParts: favoritesFolder.pathParts, - }); - }; + if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this; - getFileInfo = async (id) => { - const fileInfo = await api.files.getFileInfo(id); - this.setFile(fileInfo); - return fileInfo; - }; + const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24; + const icon = extension + ? getFileIcon(`.${extension}`, iconSize) + : getFolderIcon(null, iconSize); - getFolderInfo = async (id) => { - const folderInfo = await api.files.getFolderInfo(id); - this.setFolder(folderInfo); - return folderInfo; - }; + items.unshift({ + id: -1, + title: title, + parentId: this.selectedFolderStore.id, + fileExst: extension, + icon, + }); + }; - openDocEditor = (id, providerKey = null, tab = null, url = null) => { - return openEditor(id, providerKey, tab, url); - }; + get filesList() { + const { + mediaViewersFormatsStore, + iconFormatsStore, + } = this.formatsStore; + const { getIcon } = iconFormatsStore; + //return [...this.folders, ...this.files]; - createThumbnails = () => { - const filesList = [...this.files, this.folders]; - const fileIds = []; + const items = [...this.folders, ...this.files]; + const newItem = items.map((item) => { + const { + access, + comment, + contentLength, + created, + createdBy, + encrypted, + fileExst, + filesCount, + fileStatus, + fileType, + folderId, + foldersCount, + id, + locked, + parentId, + pureContentLength, + rootFolderType, + rootFolderId, + shared, + title, + updated, + updatedBy, + version, + versionGroup, + viewUrl, + webUrl, + providerKey, + thumbnailUrl, + thumbnailStatus, + canShare, + canEdit, + } = item; - filesList.map((file) => { - const { thumbnailStatus } = file; + const { canConvert } = this.formatsStore.docserviceStore; - if (thumbnailStatus === thumbnailStatuses.WAITING) fileIds.push(file.id); - }); + const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( + item.fileExst + ); - if (fileIds.length) return api.files.createThumbnails(fileIds); - }; + const previewUrl = canOpenPlayer + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/#preview/${id}` + ) + : null; + const contextOptions = this.getFilesContextOptions( + item, + canOpenPlayer + ); + const isThirdPartyFolder = providerKey && id === rootFolderId; + + const iconSize = this.viewAs === "table" ? 24 : 32; + const icon = getIcon( + iconSize, + fileExst, + providerKey, + contentLength + ); + + let isFolder = false; + this.folders.map((x) => { + if (x.id === item.id) isFolder = true; + }); + + const { isRecycleBinFolder } = this.treeFoldersStore; + + const folderUrl = isFolder + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/filter?folder=${id}` + ) + : null; + + const needConvert = canConvert(fileExst); + + const docUrl = combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/doceditor?fileId=${id}${needConvert ? "&action=view" : ""}` + ); + + const href = isRecycleBinFolder + ? null + : previewUrl + ? previewUrl + : !isFolder + ? docUrl + : folderUrl; + + return { + access, + //checked, + comment, + contentLength, + contextOptions, + created, + createdBy, + encrypted, + fileExst, + filesCount, + fileStatus, + fileType, + folderId, + foldersCount, + icon, + id, + isFolder, + locked, + new: item.new, + parentId, + pureContentLength, + rootFolderType, + rootFolderId, + //selectedItem, + shared, + title, + updated, + updatedBy, + version, + versionGroup, + viewUrl, + webUrl, + providerKey, + canOpenPlayer, + //canShare, + canShare, + canEdit, + thumbnailUrl, + thumbnailStatus, + previewUrl, + folderUrl, + href, + isThirdPartyFolder, + }; + }); + + if (this.fileActionStore.type === FileAction.Create) { + this.onCreateAddTempItem(newItem); + } + + return newItem; + } + + get cbMenuItems() { + const { + mediaViewersFormatsStore, + iconFormatsStore, + } = this.formatsStore; + const { + isDocument, + isPresentation, + isSpreadsheet, + isArchive, + } = iconFormatsStore; + const { isImage, isVideo } = mediaViewersFormatsStore; + + let cbMenu = ["all"]; + const filesItems = [...this.files, ...this.folders]; + + if (this.folders.length) cbMenu.push(FilterType.FoldersOnly); + for (let item of filesItems) { + if (isDocument(item.fileExst)) + cbMenu.push(FilterType.DocumentsOnly); + else if (isPresentation(item.fileExst)) + cbMenu.push(FilterType.PresentationsOnly); + else if (isSpreadsheet(item.fileExst)) + cbMenu.push(FilterType.SpreadsheetsOnly); + else if (isImage(item.fileExst)) cbMenu.push(FilterType.ImagesOnly); + else if (isVideo(item.fileExst)) cbMenu.push(FilterType.MediaOnly); + else if (isArchive(item.fileExst)) + cbMenu.push(FilterType.ArchiveOnly); + } + + const hasFiles = cbMenu.some( + (elem) => elem !== "all" && elem !== FilterType.FoldersOnly + ); + + if (hasFiles) cbMenu.push(FilterType.FilesOnly); + + cbMenu = cbMenu.filter((item, index) => cbMenu.indexOf(item) === index); + + return cbMenu; + } + + getCheckboxItemLabel = (t, key) => { + switch (key) { + case "all": + return t("All"); + case FilterType.FoldersOnly: + return t("Translations:Folders"); + case FilterType.DocumentsOnly: + return t("Common:Documents"); + case FilterType.PresentationsOnly: + return t("Translations:Presentations"); + case FilterType.SpreadsheetsOnly: + return t("Translations:Spreadsheets"); + case FilterType.ImagesOnly: + return t("Images"); + case FilterType.MediaOnly: + return t("Media"); + case FilterType.ArchiveOnly: + return t("Archives"); + case FilterType.FilesOnly: + return t("AllFiles"); + + default: + return ""; + } + }; + + get sortedFiles() { + const { + isSpreadsheet, + isPresentation, + isDocument, + } = this.formatsStore.iconFormatsStore; + const { filesConverts } = this.formatsStore.docserviceStore; + + let sortedFiles = { + documents: [], + spreadsheets: [], + presentations: [], + other: [], + }; + + const selection = this.selection.length + ? this.selection + : this.bufferSelection + ? [this.bufferSelection] + : []; + + for (let item of selection) { + item.checked = true; + item.format = null; + + const canConvert = filesConverts.find((f) => f[item.fileExst]); + + if (item.fileExst && canConvert) { + if (isSpreadsheet(item.fileExst)) { + sortedFiles.spreadsheets.push(item); + } else if (isPresentation(item.fileExst)) { + sortedFiles.presentations.push(item); + } else if (isDocument(item.fileExst)) { + sortedFiles.documents.push(item); + } else { + sortedFiles.other.push(item); + } + } else { + sortedFiles.other.push(item); + } + } + + return sortedFiles; + } + + get userAccess() { + switch (this.selectedFolderStore.rootFolderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + return false; + case FolderType.COMMON: + return ( + this.authStore.isAdmin || + this.selection.some((x) => x.access === 0 || x.access === 1) + ); + case FolderType.Privacy: + return true; + case FolderType.TRASH: + return true; + default: + return false; + } + } + + get isAccessedSelected() { + return ( + this.selection.length && + this.selection.every((x) => x.access === 1 || x.access === 0) + ); + } + + get isThirdPartyRootSelection() { + const withProvider = this.selection.find((x) => x.providerKey); + return withProvider && withProvider.rootFolderId === withProvider.id; + } + + get isThirdPartySelection() { + const withProvider = this.selection.find((x) => x.providerKey); + return !!withProvider; + } + + get canConvertSelected() { + const { filesConverts } = this.formatsStore.docserviceStore; + + const selection = this.selection.length + ? this.selection + : this.bufferSelection + ? [this.bufferSelection] + : []; + + return selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + const index = filesConverts.findIndex((f) => f[selected.fileExst]); + return index !== -1; + }); + } + + get isViewedSelected() { + const { canViewedDocs } = this.formatsStore.docserviceStore; + + return this.selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + return canViewedDocs(selected.fileExst); + }); + } + + get isMediaSelected() { + const { isMediaOrImage } = this.formatsStore.mediaViewersFormatsStore; + + return this.selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + return isMediaOrImage(selected.fileExst); + }); + } + + get selectionTitle() { + if (this.selection.length === 0) { + if (this.bufferSelection) { + return this.bufferSelection.title; + } + return null; + } + return this.selection.find((el) => el.title).title; + } + + get hasSelection() { + return !!this.selection.length; + } + + get isEmptyFilesList() { + const filesList = [...this.files, ...this.folders]; + return filesList.length <= 0; + } + + getOptions = (selection, externalAccess = false) => { + const { + canWebEdit, + canWebComment, + canWebReview, + canFormFillingDocs, + canWebFilterEditing, + } = this.formatsStore.docserviceStore; + + if (selection[0].encrypted) { + return ["FullAccess", "DenyAccess"]; + } + + let AccessOptions = []; + + AccessOptions.push("ReadOnly", "DenyAccess"); + + const webEdit = selection.find((x) => canWebEdit(x.fileExst)); + + const webComment = selection.find((x) => canWebComment(x.fileExst)); + + const webReview = selection.find((x) => canWebReview(x.fileExst)); + + const formFillingDocs = selection.find((x) => + canFormFillingDocs(x.fileExst) + ); + + const webFilter = selection.find((x) => + canWebFilterEditing(x.fileExst) + ); + + if (webEdit || !externalAccess) AccessOptions.push("FullAccess"); + + if (webComment) AccessOptions.push("Comment"); + if (webReview) AccessOptions.push("Review"); + if (formFillingDocs && !externalAccess) + AccessOptions.push("FormFilling"); + if (webFilter) AccessOptions.push("FilterEditing"); + + return AccessOptions; + }; + + getAccessOption = (selection) => { + return this.getOptions(selection); + }; + + getExternalAccessOption = (selection) => { + return this.getOptions(selection, true); + }; + + setSelections = (items) => { + if (!items.length && !this.selection.length) return; + + //if (items.length !== this.selection.length) { + const newSelection = []; + + for (let item of items) { + const value = item.getAttribute("value"); + const splitValue = value && value.split("_"); + + const fileType = splitValue[0]; + const id = + splitValue[splitValue.length - 1] === "draggable" + ? splitValue.slice(1, -1).join("_") + : splitValue.slice(1).join("_"); + + if (fileType === "file") { + newSelection.push(this.files.find((f) => f.id == id)); + } else { + const selectableFolder = this.folders.find((f) => f.id == id); + selectableFolder.isFolder = true; + newSelection.push(selectableFolder); + } + } + + //this.selected === "close" && this.setSelected("none"); + + //need fo table view + const clearSelection = Object.values( + newSelection.reduce((item, n) => ((item[n.id] = n), item), {}) + ); + + this.setSelection(clearSelection); + //} + }; + + getShareUsers(folderIds, fileIds) { + return api.files.getShareFiles(fileIds, folderIds); + } + + setShareFiles = ( + folderIds, + fileIds, + share, + notify, + sharingMessage, + externalAccess, + ownerId + ) => { + let externalAccessRequest = []; + if (fileIds.length === 1 && externalAccess !== null) { + externalAccessRequest = fileIds.map((id) => + api.files.setExternalAccess(id, externalAccess) + ); + } + + const ownerChangeRequest = ownerId + ? [this.setFilesOwner(folderIds, fileIds, ownerId)] + : []; + + const shareRequest = !!share.length + ? [ + api.files.setShareFiles( + fileIds, + folderIds, + share, + notify, + sharingMessage + ), + ] + : []; + + const requests = [ + ...ownerChangeRequest, + ...shareRequest, + ...externalAccessRequest, + ]; + + return Promise.all(requests); + }; + + markItemAsFavorite = (id) => api.files.markAsFavorite(id); + + removeItemFromFavorite = (id) => api.files.removeFromFavorite(id); + + fetchFavoritesFolder = async (folderId) => { + const favoritesFolder = await api.files.getFolder(folderId); + this.setFolders(favoritesFolder.folders); + this.setFiles(favoritesFolder.files); + + this.selectedFolderStore.setSelectedFolder({ + folders: favoritesFolder.folders, + ...favoritesFolder.current, + pathParts: favoritesFolder.pathParts, + }); + }; + + getFileInfo = async (id) => { + const fileInfo = await api.files.getFileInfo(id); + this.setFile(fileInfo); + return fileInfo; + }; + + getFolderInfo = async (id) => { + const folderInfo = await api.files.getFolderInfo(id); + this.setFolder(folderInfo); + return folderInfo; + }; + + openDocEditor = (id, providerKey = null, tab = null, url = null) => { + return openEditor(id, providerKey, tab, url); + }; + + createThumbnails = () => { + const filesList = [...this.files, this.folders]; + const fileIds = []; + + filesList.map((file) => { + const { thumbnailStatus } = file; + + if (thumbnailStatus === thumbnailStatuses.WAITING) + fileIds.push(file.id); + }); + + if (fileIds.length) return api.files.createThumbnails(fileIds); + }; } export default FilesStore; From 524ac82b9e297e3090bf52dd6726f0d3e49fc6e5 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Feb 2022 14:39:47 +0300 Subject: [PATCH 13/81] added Show Info option to file context menu --- .../PageLayout/sub-components/info-panel.js | 3 +- .../Client/public/images/info.react.svg | 3 + .../Client/src/HOCs/withContextOptions.js | 1262 +++++++++-------- .../src/pages/Home/InfoPanel/Body/index.js | 165 +-- .../ASC.Files/Client/src/store/FilesStore.js | 10 +- .../Client/src/store/InfoPanelStore.js | 4 + 6 files changed, 722 insertions(+), 725 deletions(-) create mode 100644 products/ASC.Files/Client/public/images/info.react.svg diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index 8141aa695f..f61911feb2 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -43,7 +43,8 @@ const InfoPanel = ({ children, isVisible, toggleIsVisible }) => { @media ${mobile} { bottom: 0; height: 80%; - max-width: calc(100vw - 32px); + width: 100vw; + max-width: 100vw; } `; diff --git a/products/ASC.Files/Client/public/images/info.react.svg b/products/ASC.Files/Client/public/images/info.react.svg new file mode 100644 index 0000000000..9a0368096e --- /dev/null +++ b/products/ASC.Files/Client/public/images/info.react.svg @@ -0,0 +1,3 @@ + + + diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index 77c6aac94f..a7fcd97209 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -1,639 +1,669 @@ -import React from "react"; -import { inject, observer } from "mobx-react"; -import copy from "copy-to-clipboard"; +import { AppServerConfig, FileAction } from "@appserver/common/constants"; import { combineUrl } from "@appserver/common/utils"; -import { FileAction, AppServerConfig } from "@appserver/common/constants"; import toastr from "@appserver/components/toast/toastr"; -import config from "../../package.json"; +import copy from "copy-to-clipboard"; import saveAs from "file-saver"; +import { inject, observer } from "mobx-react"; +import React from "react"; + +import config from "../../package.json"; +import InfoPanelStore from "../store/InfoPanelStore"; export default function withContextOptions(WrappedComponent) { - class WithContextOptions extends React.Component { - onOpenFolder = () => { - const { item, openLocationAction } = this.props; - const { id, folderId, fileExst } = item; - const locationId = !fileExst ? id : folderId; - openLocationAction(locationId, !fileExst); - }; - - onClickLinkFillForm = () => { - return this.gotoDocEditor(false); - }; - - onClickMakeForm = () => { - const { copyAsAction, item, formfillingDocs } = this.props; - const { title, id, folderId, fileExst } = item; - - const newTitle = - title.substring(0, title.length - fileExst.length) + formfillingDocs[0]; - - copyAsAction(id, newTitle, folderId).catch((err) => toastr.error(err)); - }; - - onOpenLocation = () => { - const { item, openLocationAction } = this.props; - const { parentId, folderId, fileExst } = item; - const locationId = !fileExst ? parentId : folderId; - openLocationAction(locationId, !fileExst); - }; - - onOwnerChange = () => { - const { setChangeOwnerPanelVisible } = this.props; - setChangeOwnerPanelVisible(true); - }; - onMoveAction = () => { - const { setMoveToPanelVisible } = this.props; - setMoveToPanelVisible(true); - }; - onCopyAction = () => { - const { setCopyPanelVisible } = this.props; - setCopyPanelVisible(true); - }; - - showVersionHistory = () => { - const { - item, - isTabletView, - fetchFileVersions, - setIsVerHistoryPanel, - history, - homepage, - isTrashFolder, - } = this.props; - const { id } = item; - if (isTrashFolder) return; - - if (!isTabletView) { - fetchFileVersions(id + ""); - setIsVerHistoryPanel(true); - } else { - history.push( - combineUrl(AppServerConfig.proxyURL, homepage, `/${id}/history`) - ); - } - }; - - finalizeVersion = () => { - const { item, finalizeVersionAction } = this.props; - const { id } = item; - finalizeVersionAction(id).catch((err) => toastr.error(err)); - }; - - onClickFavorite = (e) => { - const { item, setFavoriteAction, t } = this.props; - const { id } = item; - const data = (e.currentTarget && e.currentTarget.dataset) || e; - const { action } = data; - - setFavoriteAction(action, id) - .then(() => - action === "mark" - ? toastr.success(t("MarkedAsFavorite")) - : toastr.success(t("RemovedFromFavorites")) - ) - .catch((err) => toastr.error(err)); - }; - - lockFile = () => { - const { item, lockFileAction } = this.props; - const { id, locked } = item; - lockFileAction(id, !locked).catch((err) => toastr.error(err)); - }; - - onClickLinkForPortal = () => { - const { item, homepage, t } = this.props; - const { fileExst, canOpenPlayer, webUrl, id } = item; - - const isFile = !!fileExst; - copy( - isFile - ? canOpenPlayer - ? `${window.location.href}&preview=${id}` - : webUrl - : `${window.location.origin + homepage}/filter?folder=${id}` - ); - - toastr.success(t("Translations:LinkCopySuccess")); - }; - - onClickLinkEdit = () => { - const { - item, - canConvert, - setConvertItem, - setConvertDialogVisible, - } = this.props; - - if (canConvert) { - setConvertItem(item); - setConvertDialogVisible(true); - } else { - this.gotoDocEditor(false); - } - }; - - onPreviewClick = () => { - this.gotoDocEditor(true); - }; - - gotoDocEditor = (preview = false) => { - const { item, openDocEditor, isDesktop } = this.props; - const { id, providerKey, fileExst } = item; - - const urlFormation = preview - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/doceditor?fileId=${encodeURIComponent(id)}&action=view` - ) - : null; - - let tab = - !isDesktop && fileExst - ? window.open( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - "/doceditor" - ), - "_blank" - ) - : null; - - openDocEditor(id, providerKey, tab, urlFormation); - }; - - isPwa = () => { - return ["fullscreen", "standalone", "minimal-ui"].some( - (displayMode) => - window.matchMedia("(display-mode: " + displayMode + ")").matches - ); - }; - - onClickDownload = () => { - const { item, downloadAction, t } = this.props; - const { fileExst, contentLength, viewUrl } = item; - const isFile = !!fileExst && contentLength; - - if (this.isPwa()) { - const xhr = new XMLHttpRequest(); - xhr.open("GET", viewUrl); - xhr.responseType = "blob"; - - xhr.onload = () => { - saveAs(xhr.response, item.title); + class WithContextOptions extends React.Component { + onOpenFolder = () => { + const { item, openLocationAction } = this.props; + const { id, folderId, fileExst } = item; + const locationId = !fileExst ? id : folderId; + openLocationAction(locationId, !fileExst); }; - xhr.onerror = () => { - console.error("download failed", viewUrl); + onClickLinkFillForm = () => { + return this.gotoDocEditor(false); }; - xhr.send(); - return; - } + onClickMakeForm = () => { + const { copyAsAction, item, formfillingDocs } = this.props; + const { title, id, folderId, fileExst } = item; - isFile - ? window.open(viewUrl, "_self") - : downloadAction(t("Translations:ArchivingData")).catch((err) => - toastr.error(err) - ); - }; + const newTitle = + title.substring(0, title.length - fileExst.length) + + formfillingDocs[0]; - onClickDownloadAs = () => { - const { setDownloadDialogVisible } = this.props; - setDownloadDialogVisible(true); - }; + copyAsAction(id, newTitle, folderId).catch((err) => + toastr.error(err) + ); + }; - onDuplicate = () => { - const { duplicateAction, t, item } = this.props; - duplicateAction(item, t("Translations:CopyOperation")).catch((err) => - toastr.error(err) - ); - }; + onOpenLocation = () => { + const { item, openLocationAction } = this.props; + const { parentId, folderId, fileExst } = item; + const locationId = !fileExst ? parentId : folderId; + openLocationAction(locationId, !fileExst); + }; - onClickRename = () => { - const { item, setAction } = this.props; - const { id, fileExst } = item; - setAction({ - type: FileAction.Rename, - extension: fileExst, - id, - }); - }; + onSetInfoPanelVisible = () => { + this.props.setIsVisible(true); + }; - onChangeThirdPartyInfo = () => { - const { item, setThirdpartyInfo } = this.props; - const { providerKey } = item; - setThirdpartyInfo(providerKey); - }; + onOwnerChange = () => { + const { setChangeOwnerPanelVisible } = this.props; + setChangeOwnerPanelVisible(true); + }; + onMoveAction = () => { + const { setMoveToPanelVisible } = this.props; + setMoveToPanelVisible(true); + }; + onCopyAction = () => { + const { setCopyPanelVisible } = this.props; + setCopyPanelVisible(true); + }; - onMediaFileClick = (fileId) => { - const { item, setMediaViewerData } = this.props; - const itemId = typeof fileId !== "object" ? fileId : item.id; - setMediaViewerData({ visible: true, id: itemId }); - }; + showVersionHistory = () => { + const { + item, + isTabletView, + fetchFileVersions, + setIsVerHistoryPanel, + history, + homepage, + isTrashFolder, + } = this.props; + const { id } = item; + if (isTrashFolder) return; - onClickDelete = () => { - const { - item, - setRemoveItem, - setDeleteThirdPartyDialogVisible, - t, - deleteItemAction, - } = this.props; - const { id, title, providerKey, rootFolderId, isFolder } = item; - - const isRootThirdPartyFolder = providerKey && id === rootFolderId; - - if (isRootThirdPartyFolder) { - const splitItem = id.split("-"); - setRemoveItem({ id: splitItem[splitItem.length - 1], title }); - setDeleteThirdPartyDialogVisible(true); - return; - } - - const translations = { - deleteOperation: t("Translations:DeleteOperation"), - successRemoveFile: t("FileRemoved"), - successRemoveFolder: t("FolderRemoved"), - }; - - deleteItemAction(id, translations, !isFolder, providerKey); - }; - - onClickShare = () => { - const { setSharingPanelVisible } = this.props; - setTimeout(() => { - setSharingPanelVisible(true); - }, 10); //TODO: remove delay after fix context menu callback - }; - - onClickMarkRead = () => { - const { markAsRead, item } = this.props; - item.fileExst - ? markAsRead([], [item.id], item) - : markAsRead([item.id], [], item); - }; - - onClickUnsubscribe = () => { - const { setDeleteDialogVisible, setUnsubscribe } = this.props; - - setUnsubscribe(true); - setDeleteDialogVisible(true); - }; - - getFilesContextOptions = () => { - const { item, t } = this.props; - const { contextOptions } = item; - const isRootThirdPartyFolder = - item.providerKey && item.id === item.rootFolderId; - - const isShareable = item.canShare; - - return contextOptions.map((option) => { - switch (option) { - case "open": - return { - key: option, - label: t("Open"), - icon: "images/catalog.folder.react.svg", - onClick: this.onOpenFolder, - disabled: false, - }; - case "show-version-history": - return { - key: option, - label: t("ShowVersionHistory"), - icon: "images/history.react.svg", - onClick: this.showVersionHistory, - disabled: false, - }; - case "finalize-version": - return { - key: option, - label: t("FinalizeVersion"), - icon: "images/history-finalized.react.svg", - onClick: this.finalizeVersion, - disabled: false, - }; - case "separator0": - case "separator1": - case "separator2": - case "separator3": - return { key: option, isSeparator: true }; - case "open-location": - return { - key: option, - label: t("OpenLocation"), - icon: "images/download-as.react.svg", - onClick: this.onOpenLocation, - disabled: false, - }; - case "mark-as-favorite": - return { - key: option, - label: t("MarkAsFavorite"), - icon: "images/favorites.react.svg", - onClick: this.onClickFavorite, - disabled: false, - "data-action": "mark", - action: "mark", - }; - case "block-unblock-version": - return { - key: option, - label: t("UnblockVersion"), - icon: "images/lock.react.svg", - onClick: this.lockFile, - disabled: false, - }; - case "sharing-settings": - return { - key: option, - label: t("SharingSettings"), - icon: "/static/images/catalog.share.react.svg", - onClick: this.onClickShare, - disabled: !isShareable, - }; - case "send-by-email": - return { - key: option, - label: t("SendByEmail"), - icon: "/static/images/mail.react.svg", - disabled: true, - }; - case "owner-change": - return { - key: option, - label: t("Translations:OwnerChange"), - icon: "/static/images/catalog.user.react.svg", - onClick: this.onOwnerChange, - disabled: false, - }; - case "link-for-portal-users": - return { - key: option, - label: t("LinkForPortalUsers"), - icon: "/static/images/invitation.link.react.svg", - onClick: this.onClickLinkForPortal, - disabled: false, - }; - case "fill-form": - return { - key: option, - label: t("Common:FillFormButton"), - icon: "/static/images/form.fill.rect.svg", - onClick: this.onClickLinkFillForm, - disabled: false, - }; - case "make-form": - return { - key: option, - label: t("Common:MakeForm"), - icon: "/static/images/form.plus.react.svg", - onClick: this.onClickMakeForm, - disabled: false, - }; - case "edit": - return { - key: option, - label: t("Common:EditButton"), - icon: "/static/images/access.edit.react.svg", - onClick: this.onClickLinkEdit, - disabled: false, - }; - case "preview": - return { - key: option, - label: t("Preview"), - icon: "/static/images/eye.react.svg", - onClick: this.onPreviewClick, - disabled: false, - }; - case "view": - return { - key: option, - label: t("Common:View"), - icon: "/static/images/eye.react.svg", - onClick: this.onMediaFileClick, - disabled: false, - }; - case "download": - return { - key: option, - label: t("Common:Download"), - icon: "images/download.react.svg", - onClick: this.onClickDownload, - disabled: false, - }; - case "download-as": - return { - key: option, - label: t("Translations:DownloadAs"), - icon: "images/download-as.react.svg", - onClick: this.onClickDownloadAs, - disabled: false, - }; - case "move-to": - return { - key: option, - label: t("MoveTo"), - icon: "images/move.react.svg", - onClick: this.onMoveAction, - disabled: false, - }; - case "restore": - return { - key: option, - label: t("Translations:Restore"), - icon: "images/move.react.svg", - onClick: this.onMoveAction, - disabled: false, - }; - case "copy-to": - return { - key: option, - label: t("Translations:Copy"), - icon: "/static/images/copy.react.svg", - onClick: this.onCopyAction, - disabled: false, - }; - case "copy": - return { - key: option, - label: t("Duplicate"), - icon: "/static/images/copy.react.svg", - onClick: this.onDuplicate, - disabled: false, - }; - case "rename": - return { - key: option, - label: t("Rename"), - icon: "images/rename.react.svg", - onClick: this.onClickRename, - disabled: false, - }; - case "change-thirdparty-info": - return { - key: option, - label: t("Translations:ThirdPartyInfo"), - icon: "/static/images/access.edit.react.svg", - onClick: this.onChangeThirdPartyInfo, - disabled: false, - }; - case "delete": - return { - key: option, - label: isRootThirdPartyFolder - ? t("Translations:DeleteThirdParty") - : t("Common:Delete"), - icon: "/static/images/catalog.trash.react.svg", - onClick: this.onClickDelete, - disabled: false, - }; - case "remove-from-favorites": - return { - key: option, - label: t("RemoveFromFavorites"), - icon: "images/favorites.react.svg", - onClick: this.onClickFavorite, - disabled: false, - "data-action": "remove", - action: "remove", - }; - case "unsubscribe": - return { - key: option, - label: t("RemoveFromList"), - icon: "images/remove.svg", - onClick: this.onClickUnsubscribe, - disabled: false, - }; - case "mark-read": - return { - key: option, - label: t("MarkRead"), - icon: "images/tick.rounded.svg", - onClick: this.onClickMarkRead, - disabled: false, - }; - default: - break; - } - - return undefined; - }); - }; - render() { - const { actionType, actionId, actionExtension, item } = this.props; - const { id, fileExst, contextOptions } = item; - - const isEdit = - !!actionType && actionId === id && fileExst === actionExtension; - - const contextOptionsProps = - !isEdit && contextOptions && contextOptions.length > 0 - ? { - contextOptions: this.getFilesContextOptions(), + if (!isTabletView) { + fetchFileVersions(id + ""); + setIsVerHistoryPanel(true); + } else { + history.push( + combineUrl( + AppServerConfig.proxyURL, + homepage, + `/${id}/history` + ) + ); } - : {}; + }; - return ( - - ); + finalizeVersion = () => { + const { item, finalizeVersionAction } = this.props; + const { id } = item; + finalizeVersionAction(id).catch((err) => toastr.error(err)); + }; + + onClickFavorite = (e) => { + const { item, setFavoriteAction, t } = this.props; + const { id } = item; + const data = (e.currentTarget && e.currentTarget.dataset) || e; + const { action } = data; + + setFavoriteAction(action, id) + .then(() => + action === "mark" + ? toastr.success(t("MarkedAsFavorite")) + : toastr.success(t("RemovedFromFavorites")) + ) + .catch((err) => toastr.error(err)); + }; + + lockFile = () => { + const { item, lockFileAction } = this.props; + const { id, locked } = item; + lockFileAction(id, !locked).catch((err) => toastr.error(err)); + }; + + onClickLinkForPortal = () => { + const { item, homepage, t } = this.props; + const { fileExst, canOpenPlayer, webUrl, id } = item; + + const isFile = !!fileExst; + copy( + isFile + ? canOpenPlayer + ? `${window.location.href}&preview=${id}` + : webUrl + : `${window.location.origin + homepage}/filter?folder=${id}` + ); + + toastr.success(t("Translations:LinkCopySuccess")); + }; + + onClickLinkEdit = () => { + const { + item, + canConvert, + setConvertItem, + setConvertDialogVisible, + } = this.props; + + if (canConvert) { + setConvertItem(item); + setConvertDialogVisible(true); + } else { + this.gotoDocEditor(false); + } + }; + + onPreviewClick = () => { + this.gotoDocEditor(true); + }; + + gotoDocEditor = (preview = false) => { + const { item, openDocEditor, isDesktop } = this.props; + const { id, providerKey, fileExst } = item; + + const urlFormation = preview + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/doceditor?fileId=${encodeURIComponent(id)}&action=view` + ) + : null; + + let tab = + !isDesktop && fileExst + ? window.open( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + "/doceditor" + ), + "_blank" + ) + : null; + + openDocEditor(id, providerKey, tab, urlFormation); + }; + + isPwa = () => { + return ["fullscreen", "standalone", "minimal-ui"].some( + (displayMode) => + window.matchMedia("(display-mode: " + displayMode + ")") + .matches + ); + }; + + onClickDownload = () => { + const { item, downloadAction, t } = this.props; + const { fileExst, contentLength, viewUrl } = item; + const isFile = !!fileExst && contentLength; + + if (this.isPwa()) { + const xhr = new XMLHttpRequest(); + xhr.open("GET", viewUrl); + xhr.responseType = "blob"; + + xhr.onload = () => { + saveAs(xhr.response, item.title); + }; + + xhr.onerror = () => { + console.error("download failed", viewUrl); + }; + + xhr.send(); + return; + } + + isFile + ? window.open(viewUrl, "_self") + : downloadAction(t("Translations:ArchivingData")).catch((err) => + toastr.error(err) + ); + }; + + onClickDownloadAs = () => { + const { setDownloadDialogVisible } = this.props; + setDownloadDialogVisible(true); + }; + + onDuplicate = () => { + const { duplicateAction, t, item } = this.props; + duplicateAction( + item, + t("Translations:CopyOperation") + ).catch((err) => toastr.error(err)); + }; + + onClickRename = () => { + const { item, setAction } = this.props; + const { id, fileExst } = item; + setAction({ + type: FileAction.Rename, + extension: fileExst, + id, + }); + }; + + onChangeThirdPartyInfo = () => { + const { item, setThirdpartyInfo } = this.props; + const { providerKey } = item; + setThirdpartyInfo(providerKey); + }; + + onMediaFileClick = (fileId) => { + const { item, setMediaViewerData } = this.props; + const itemId = typeof fileId !== "object" ? fileId : item.id; + setMediaViewerData({ visible: true, id: itemId }); + }; + + onClickDelete = () => { + const { + item, + setRemoveItem, + setDeleteThirdPartyDialogVisible, + t, + deleteItemAction, + } = this.props; + const { id, title, providerKey, rootFolderId, isFolder } = item; + + const isRootThirdPartyFolder = providerKey && id === rootFolderId; + + if (isRootThirdPartyFolder) { + const splitItem = id.split("-"); + setRemoveItem({ id: splitItem[splitItem.length - 1], title }); + setDeleteThirdPartyDialogVisible(true); + return; + } + + const translations = { + deleteOperation: t("Translations:DeleteOperation"), + successRemoveFile: t("FileRemoved"), + successRemoveFolder: t("FolderRemoved"), + }; + + deleteItemAction(id, translations, !isFolder, providerKey); + }; + + onClickShare = () => { + const { setSharingPanelVisible } = this.props; + setTimeout(() => { + setSharingPanelVisible(true); + }, 10); //TODO: remove delay after fix context menu callback + }; + + onClickMarkRead = () => { + const { markAsRead, item } = this.props; + item.fileExst + ? markAsRead([], [item.id], item) + : markAsRead([item.id], [], item); + }; + + onClickUnsubscribe = () => { + const { setDeleteDialogVisible, setUnsubscribe } = this.props; + + setUnsubscribe(true); + setDeleteDialogVisible(true); + }; + + getFilesContextOptions = () => { + const { item, t } = this.props; + const { contextOptions } = item; + const isRootThirdPartyFolder = + item.providerKey && item.id === item.rootFolderId; + + const isShareable = item.canShare; + + return contextOptions.map((option) => { + switch (option) { + case "open": + return { + key: option, + label: t("Open"), + icon: "images/catalog.folder.react.svg", + onClick: this.onOpenFolder, + disabled: false, + }; + case "show-info": + return { + key: option, + label: t("Show info"), + icon: "images/info.react.svg", + onClick: this.onSetInfoPanelVisible, + disabled: false, + }; + case "show-version-history": + return { + key: option, + label: t("ShowVersionHistory"), + icon: "images/history.react.svg", + onClick: this.showVersionHistory, + disabled: false, + }; + case "finalize-version": + return { + key: option, + label: t("FinalizeVersion"), + icon: "images/history-finalized.react.svg", + onClick: this.finalizeVersion, + disabled: false, + }; + case "separator0": + case "separator1": + case "separator2": + case "separator3": + return { key: option, isSeparator: true }; + case "open-location": + return { + key: option, + label: t("OpenLocation"), + icon: "images/download-as.react.svg", + onClick: this.onOpenLocation, + disabled: false, + }; + case "mark-as-favorite": + return { + key: option, + label: t("MarkAsFavorite"), + icon: "images/favorites.react.svg", + onClick: this.onClickFavorite, + disabled: false, + "data-action": "mark", + action: "mark", + }; + case "block-unblock-version": + return { + key: option, + label: t("UnblockVersion"), + icon: "images/lock.react.svg", + onClick: this.lockFile, + disabled: false, + }; + case "sharing-settings": + return { + key: option, + label: t("SharingSettings"), + icon: "/static/images/catalog.share.react.svg", + onClick: this.onClickShare, + disabled: !isShareable, + }; + case "send-by-email": + return { + key: option, + label: t("SendByEmail"), + icon: "/static/images/mail.react.svg", + disabled: true, + }; + case "owner-change": + return { + key: option, + label: t("Translations:OwnerChange"), + icon: "/static/images/catalog.user.react.svg", + onClick: this.onOwnerChange, + disabled: false, + }; + case "link-for-portal-users": + return { + key: option, + label: t("LinkForPortalUsers"), + icon: "/static/images/invitation.link.react.svg", + onClick: this.onClickLinkForPortal, + disabled: false, + }; + case "fill-form": + return { + key: option, + label: t("Common:FillFormButton"), + icon: "/static/images/form.fill.rect.svg", + onClick: this.onClickLinkFillForm, + disabled: false, + }; + case "make-form": + return { + key: option, + label: t("Common:MakeForm"), + icon: "/static/images/form.plus.react.svg", + onClick: this.onClickMakeForm, + disabled: false, + }; + case "edit": + return { + key: option, + label: t("Common:EditButton"), + icon: "/static/images/access.edit.react.svg", + onClick: this.onClickLinkEdit, + disabled: false, + }; + case "preview": + return { + key: option, + label: t("Preview"), + icon: "/static/images/eye.react.svg", + onClick: this.onPreviewClick, + disabled: false, + }; + case "view": + return { + key: option, + label: t("Common:View"), + icon: "/static/images/eye.react.svg", + onClick: this.onMediaFileClick, + disabled: false, + }; + case "download": + return { + key: option, + label: t("Common:Download"), + icon: "images/download.react.svg", + onClick: this.onClickDownload, + disabled: false, + }; + case "download-as": + return { + key: option, + label: t("Translations:DownloadAs"), + icon: "images/download-as.react.svg", + onClick: this.onClickDownloadAs, + disabled: false, + }; + case "move-to": + return { + key: option, + label: t("MoveTo"), + icon: "images/move.react.svg", + onClick: this.onMoveAction, + disabled: false, + }; + case "restore": + return { + key: option, + label: t("Translations:Restore"), + icon: "images/move.react.svg", + onClick: this.onMoveAction, + disabled: false, + }; + case "copy-to": + return { + key: option, + label: t("Translations:Copy"), + icon: "/static/images/copy.react.svg", + onClick: this.onCopyAction, + disabled: false, + }; + case "copy": + return { + key: option, + label: t("Duplicate"), + icon: "/static/images/copy.react.svg", + onClick: this.onDuplicate, + disabled: false, + }; + case "rename": + return { + key: option, + label: t("Rename"), + icon: "images/rename.react.svg", + onClick: this.onClickRename, + disabled: false, + }; + case "change-thirdparty-info": + return { + key: option, + label: t("Translations:ThirdPartyInfo"), + icon: "/static/images/access.edit.react.svg", + onClick: this.onChangeThirdPartyInfo, + disabled: false, + }; + case "delete": + return { + key: option, + label: isRootThirdPartyFolder + ? t("Translations:DeleteThirdParty") + : t("Common:Delete"), + icon: "/static/images/catalog.trash.react.svg", + onClick: this.onClickDelete, + disabled: false, + }; + case "remove-from-favorites": + return { + key: option, + label: t("RemoveFromFavorites"), + icon: "images/favorites.react.svg", + onClick: this.onClickFavorite, + disabled: false, + "data-action": "remove", + action: "remove", + }; + case "unsubscribe": + return { + key: option, + label: t("RemoveFromList"), + icon: "images/remove.svg", + onClick: this.onClickUnsubscribe, + disabled: false, + }; + case "mark-read": + return { + key: option, + label: t("MarkRead"), + icon: "images/tick.rounded.svg", + onClick: this.onClickMarkRead, + disabled: false, + }; + default: + break; + } + + return undefined; + }); + }; + + render() { + const { actionType, actionId, actionExtension, item } = this.props; + const { id, fileExst, contextOptions } = item; + + const isEdit = + !!actionType && actionId === id && fileExst === actionExtension; + + const contextOptionsProps = + !isEdit && contextOptions && contextOptions.length > 0 + ? { + contextOptions: this.getFilesContextOptions(), + } + : {}; + + return ( + + ); + } } - } - return inject( - ( - { - auth, - dialogsStore, - filesActionsStore, - filesStore, - mediaViewerDataStore, - treeFoldersStore, - uploadDataStore, - versionHistoryStore, - }, - { item } - ) => { - const { openDocEditor, fileActionStore, formatsStore } = filesStore; - const { - deleteItemAction, - downloadAction, - duplicateAction, - finalizeVersionAction, - lockFileAction, - markAsRead, - onSelectItem, - openLocationAction, - setFavoriteAction, - setThirdpartyInfo, - unsubscribeAction, - } = filesActionsStore; - const { - setChangeOwnerPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - setDeleteThirdPartyDialogVisible, - setDownloadDialogVisible, - setMoveToPanelVisible, - setRemoveItem, - setSharingPanelVisible, - setUnsubscribe, - } = dialogsStore; - const { isTabletView, isDesktopClient } = auth.settingsStore; - const { setIsVerHistoryPanel, fetchFileVersions } = versionHistoryStore; - const { setAction, type, extension, id } = fileActionStore; - const { setMediaViewerData } = mediaViewerDataStore; - const { copyAsAction } = uploadDataStore; - const { formfillingDocs } = formatsStore.docserviceStore; + return inject( + ( + { + auth, + dialogsStore, + filesActionsStore, + filesStore, + mediaViewerDataStore, + treeFoldersStore, + uploadDataStore, + versionHistoryStore, + infoPanelStore, + }, + { item } + ) => { + const { openDocEditor, fileActionStore, formatsStore } = filesStore; + const { + deleteItemAction, + downloadAction, + duplicateAction, + finalizeVersionAction, + lockFileAction, + markAsRead, + onSelectItem, + openLocationAction, + setFavoriteAction, + setThirdpartyInfo, + unsubscribeAction, + } = filesActionsStore; + const { setIsVisible } = infoPanelStore; + const { + setChangeOwnerPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + setDeleteThirdPartyDialogVisible, + setDownloadDialogVisible, + setMoveToPanelVisible, + setRemoveItem, + setSharingPanelVisible, + setUnsubscribe, + } = dialogsStore; + const { isTabletView, isDesktopClient } = auth.settingsStore; + const { + setIsVerHistoryPanel, + fetchFileVersions, + } = versionHistoryStore; + const { setAction, type, extension, id } = fileActionStore; + const { setMediaViewerData } = mediaViewerDataStore; + const { copyAsAction } = uploadDataStore; + const { formfillingDocs } = formatsStore.docserviceStore; - const { isRecycleBinFolder, isShare } = treeFoldersStore; - const isShareFolder = isShare(item.rootFolderType); + const { isRecycleBinFolder, isShare } = treeFoldersStore; + const isShareFolder = isShare(item.rootFolderType); - return { - openLocationAction, - setChangeOwnerPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - isTabletView, - setIsVerHistoryPanel, - fetchFileVersions, - homepage: config.homepage, - finalizeVersionAction, - setFavoriteAction, - lockFileAction, - openDocEditor, - downloadAction, - setDownloadDialogVisible, - duplicateAction, - setAction, - setThirdpartyInfo, - setMediaViewerData, - setRemoveItem, - setDeleteThirdPartyDialogVisible, - deleteItemAction, - onSelectItem, - setSharingPanelVisible, - actionType: type, - actionId: id, - actionExtension: extension, - isTrashFolder: isRecycleBinFolder, - isShareFolder, - markAsRead, - unsubscribeAction, - setDeleteDialogVisible, - setUnsubscribe, - isDesktop: isDesktopClient, - copyAsAction, - formfillingDocs, - }; - } - )(observer(WithContextOptions)); + return { + openLocationAction, + setIsVisible, + setChangeOwnerPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + isTabletView, + setIsVerHistoryPanel, + fetchFileVersions, + homepage: config.homepage, + finalizeVersionAction, + setFavoriteAction, + lockFileAction, + openDocEditor, + downloadAction, + setDownloadDialogVisible, + duplicateAction, + setAction, + setThirdpartyInfo, + setMediaViewerData, + setRemoveItem, + setDeleteThirdPartyDialogVisible, + deleteItemAction, + onSelectItem, + setSharingPanelVisible, + actionType: type, + actionId: id, + actionExtension: extension, + isTrashFolder: isRecycleBinFolder, + isShareFolder, + markAsRead, + unsubscribeAction, + setDeleteDialogVisible, + setUnsubscribe, + isDesktop: isDesktopClient, + copyAsAction, + formfillingDocs, + }; + } + )(observer(WithContextOptions)); } diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 7568c3a9da..7ab5f4ffbc 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -1,4 +1,3 @@ -import Loaders from "@appserver/common/components/Loaders"; import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; import { FileType } from "@appserver/common/constants"; import Link from "@appserver/components/link"; @@ -127,22 +126,6 @@ const InfoPanelBodyContent = ({ getShareUsers, }) => { const [item, setItem] = useState({}); - // title: "", - // iconUrl: "", - // thumbnailUrl: "", - // properties: [{ title: "", content: {} }], - // access: { - // owner: { - // img: "", - // link: "", - // }, - // others: [ - // { - // img: "", - // link: "", - // }, - // ], - // }, const updateItemsInfo = async (selectedItem) => { const displayedItem = { @@ -194,7 +177,6 @@ const InfoPanelBodyContent = ({ const updateLoadedItemAccess = async (item) => { const accesses = await getShareUsers([item.folderId], [item.id]); - console.log(accesses); const result = { owner: {}, @@ -241,8 +223,6 @@ const InfoPanelBodyContent = ({ }; const getItemProperties = (item) => { - console.log(item); - const styledLink = (text, href) => ( {text} @@ -366,104 +346,88 @@ const InfoPanelBodyContent = ({ return ( - {!selectedItem ? ( + {!Object.keys(item).length ? (

Select an item to display it's info

) : ( <> - {item.title && ( - <> - - - - {item.title} + + + + {item.title} + + + + {item.thumbnailUrl && ( + + + + )} + + + + System Properties + + + + + {item.properties.map((p) => ( +
+ + {p.title} - + {p.content} +
+ ))} +
- {"thumbnailUrl" in selectedItem && ( - - - - )} + + + Who has access + + - - - System Properties - - + + +
+ + + +
+
- - {item.properties.map((p) => ( -
- - {p.title} - - {p.content} -
- ))} -
+ {item.access.others.length ? ( +
+ ) : null} - - - Who has access - - - - + {item.access.others.map((user) => ( + + ))} + - {item.access.others.length ? ( -
- ) : null} - - {item.access.others.map((user) => ( -
- -
- - - -
-
-
- ))} -
- - - dataTip ? ( - {dataTip} - ) : null - } - /> - - )} + + dataTip ? ( + {dataTip} + ) : null + } + /> )}
@@ -471,7 +435,6 @@ const InfoPanelBodyContent = ({ }; export default inject(({ filesStore, formatsStore }) => { - console.log(filesStore); const selectedItem = JSON.parse(JSON.stringify(filesStore.bufferSelection)); const { getFolderInfo, getShareUsers } = filesStore; diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index dcb8c1e3ce..cdb8e4d3e0 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -1,11 +1,5 @@ import api from "@appserver/common/api"; -import { - AppServerConfig, - FileAction, - FileType, - FilterType, - FolderType, -} from "@appserver/common/constants"; +import { AppServerConfig, FileAction, FileType, FilterType, FolderType } from "@appserver/common/constants"; import history from "@appserver/common/history"; import { combineUrl } from "@appserver/common/utils"; import { updateTempContent } from "@appserver/common/utils"; @@ -513,6 +507,7 @@ class FilesStore { "preview", "view", "make-form", + "show-info", "separator0", "sharing-settings", "external-link", @@ -826,6 +821,7 @@ class FilesStore { } else { let folderOptions = [ "open", + "show-info", "separator0", "sharing-settings", "owner-change", diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index df9247f1f7..80f2ce7669 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -11,6 +11,10 @@ class InfoPanelStore { this.isVisible = !this.isVisible; }; + setVisible = () => { + this.isVisible = true; + }; + setIsVisible = (bool) => { this.isVisible = bool; }; From 80603b2343a374666e8d6ab85e0ddf96bb714635 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Feb 2022 15:45:47 +0300 Subject: [PATCH 14/81] added panel close on background click in tablet- view --- .../PageLayout/sub-components/info-panel.js | 142 ++++++++++-------- .../Client/src/HOCs/withContextOptions.js | 1 - 2 files changed, 78 insertions(+), 65 deletions(-) diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index f61911feb2..f5e8b6e6e4 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -1,77 +1,90 @@ import IconButton from "@appserver/components/icon-button"; -import { mobile, tablet } from "@appserver/components/utils/device"; +import { isTablet, mobile, tablet } from "@appserver/components/utils/device"; import { inject } from "mobx-react"; import PropTypes from "prop-types"; -import React from "react"; +import React, { useEffect } from "react"; import styled from "styled-components"; -const InfoPanel = ({ children, isVisible, toggleIsVisible }) => { +const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ + title: title, +}))` + height: auto; + width: auto; + background: rgba(6, 22, 38, 0.2); + backdrop-filter: blur(18px); + + @media ${tablet} { + z-index: 200; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } +`; + +const StyledInfoPanel = styled.div` + height: 100%; + width: 368px; + background-color: #ffffff; + border-left: 1px solid #eceef1; + display: flex; + flex-direction: column; + + @media ${tablet} { + position: absolute; + border: none; + right: 0; + width: 448px; + max-width: calc(100vw - 69px); + } + + @media ${mobile} { + bottom: 0; + height: 80%; + width: 100vw; + max-width: 100vw; + } +`; + +const StyledCloseButtonWrapper = styled.div` + position: absolute; + display: none; + @media ${tablet} { + display: block; + top: 0; + left: 0; + margin-top: 18px; + margin-left: -27px; + } + @media ${mobile} { + right: 0; + left: auto; + margin-top: -27px; + margin-right: 10px; + } +`; + +const InfoPanel = ({ children, isVisible, setIsVisible }) => { if (!isVisible) return null; - const StyledInfoPanelWrapper = styled.div` - height: auto; - width: auto; - background: rgba(6, 22, 38, 0.2); - backdrop-filter: blur(18px); + const closeInfoPanel = () => setIsVisible(false); - @media ${tablet} { - z-index: 200; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - } - `; + useEffect(() => { + const onMouseDown = (e) => { + if (e.target.title === "InfoPanelWrapper") closeInfoPanel(); + }; - const StyledInfoPanel = styled.div` - height: 100%; - width: 368px; - background-color: #ffffff; - border-left: 1px solid #eceef1; - display: flex; - flex-direction: column; - - @media ${tablet} { - position: absolute; - border: none; - right: 0; - width: 448px; - max-width: calc(100vw - 69px); - } - - @media ${mobile} { - bottom: 0; - height: 80%; - width: 100vw; - max-width: 100vw; - } - `; - - const StyledCloseButtonWrapper = styled.div` - position: absolute; - display: none; - @media ${tablet} { - display: block; - top: 0; - left: 0; - margin-top: 18px; - margin-left: -27px; - } - @media ${mobile} { - right: 0; - left: auto; - margin-top: -27px; - margin-right: 10px; - } - `; + if (isTablet()) document.addEventListener("mousedown", onMouseDown); + return () => document.removeEventListener("mousedown", onMouseDown); + }, []); return ( - + { let isVisible = false; - let toggleIsVisible = () => {}; + let setIsVisible = () => {}; + if (infoPanelStore) { isVisible = infoPanelStore.isVisible; - toggleIsVisible = infoPanelStore.toggleIsVisible; + setIsVisible = infoPanelStore.setIsVisible; } + return { isVisible, - toggleIsVisible, + setIsVisible, }; })(InfoPanel); diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index a7fcd97209..4d5754529d 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -7,7 +7,6 @@ import { inject, observer } from "mobx-react"; import React from "react"; import config from "../../package.json"; -import InfoPanelStore from "../store/InfoPanelStore"; export default function withContextOptions(WrappedComponent) { class WithContextOptions extends React.Component { From 518abb7a2f757d05c27d07ce0939f31d0a0d0483 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Feb 2022 15:53:46 +0300 Subject: [PATCH 15/81] added sever files, fixed closeOnclick interaction, added alternative thumbnail and implemented destructorization --- config/kafka.json | 2 +- .../PageLayout/sub-components/info-panel.js | 2 +- .../Client/public/images/empty_screen.png | Bin 0 -> 11405 bytes .../Client/public/locales/en/InfoPanel.json | 16 + .../Client/public/locales/ru/InfoPanel.json | 16 + .../pages/Home/InfoPanel/Body/SeveralItems.js | 35 ++ .../pages/Home/InfoPanel/Body/SingleItem.js | 421 +++++++++++++++ .../src/pages/Home/InfoPanel/Body/index.js | 487 ++---------------- .../Home/InfoPanel/Body/styles/styles.js | 189 +++++++ .../src/pages/Home/InfoPanel/Header/index.js | 9 +- .../src/pages/Home/Section/Body/index.js | 3 +- .../src/pages/Home/Section/Header/index.js | 10 +- public/locales/en/Common.json | 270 +++++----- 13 files changed, 882 insertions(+), 578 deletions(-) create mode 100644 products/ASC.Files/Client/public/images/empty_screen.png create mode 100644 products/ASC.Files/Client/public/locales/en/InfoPanel.json create mode 100644 products/ASC.Files/Client/public/locales/ru/InfoPanel.json create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js diff --git a/config/kafka.json b/config/kafka.json index 4ffde92112..3a56691aae 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,5 +1,5 @@ { "kafka": { - "BootstrapServers": "" + "BootstrapServers": "localhost:9092" } } diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index f5e8b6e6e4..176d94b541 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -80,7 +80,7 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => { }, []); return ( - + (>{`)`Ox(~hj zrPqGg)xD~E*B7O#EQ5+ffCK;lP~~JL)&K2j|5*rd|5Oml`40fVs3|8Yrs=tQ?x&DI zwUoN~{UUCnx_Zpp&AlnxUfnlxPW2NgmT`ap-z>HsSPfK^)sw$}7Y-WX%p0 z#6}Y5eEab2?0l-eg=;7`n@5$SKA=9~2YGcCL3eF~{!&dkVVu+56}d-iTfHr?tI0qU zx83Iw^WmYDEq{7oo!~0fZt1Gybg5@4Dc%ZcGd2!H7qfkIgfPB< z#nO9+MY7SC0G~ke$BiF6Wgk9t46V0|x%qq_N3KOExcDrz_!%_;|MZ?^Z;t1G|4 zN5Hds%lPlf7pF!TOAcepi-JN1UViFWnLySV-tFh{BfzzZFC6MA7}#G94WTqP54`q7 zK`v;7v0MG9A-ECsGFE_3xF?6)TiqGK0|MU+h>?QsUz(_;-fDOld#~$6Rtf9=u7u@9 zMCOEqny+`>+v#^bKm$S|stD2sUxRu^k9fLptJYYP)70Dh{=I^Jf{+ch`zWJ;+x0$T zL2W+&_uG6k{*7=p80a8`jOm1iuJ3`bj~BbQb-h>;r@P{3*#U2TPM7H-{SQ1JY!9`* z_?IG}!9=K-K&h+L)7`Bj!E=JddA$O#mGkW^!L3wW&pDg_vNT4$5p)q=!V*^XK~B@-u-@G zXJ%)I95Y0b#wrf?bW&Ak++(=w)*xz7M`EUr^L|D8myYD`Ch?iUD!kYXZ;;a`3S@!I z0vn*Qv7Ha{w9qTxbST2tAX%^8oo5ewAs?JJe|PkGwt*}p3KVW!V`$enH4CwDl{8hE$w(qfE-csgB@XjkEA zyMMxhkp3NTwVM2sHL_46VJ#?{i4!=@%}GM+{&hF##_zZ3QN!3iP!C}tKd5$ z!Qw9QblVi%+PP1@q5wwk!^>#`eEr0~X2G#S_*PlqSjZW=T51G)J6w8qTu6Rb7ix7Uiz zjhTf?^YSha%z|Zr2@KUI!zyd}epkXCt!UR1Cun;&Tz@AgaY`u%eTT|Xu3GROMNFqe zhBtg3*({AU*(!Uiu5|hwShIn?&o39oAQkG@uE6VoxNIjfpht#snG+37IU&Sc5HdT9 zNwO|7`2NlvA5Th(^c`iOQ)6NhAsqt8GGPm{bFx_L2Y{*%5Y@cC7y%HFi8v}NVb_&* zjcbBjQ7r}1>jg8-;_=a}y4nLCmw1VU1`pBO)G&*8sDD9CEwC>3bD^~oh-J*yhj5j` zzCa@gBsKsOAV4iWm2T$mTQBJ@`*YZfmK^tf01=og;*TedxQ3~Tcam3OJ|o`0W9b2S z!L6b5odQAEUuJkCh8hQKJNh}Q?lXt8W43c2w;*^PsFp^5;UZy%A05ObjcZ_k4D^)3 z85^TMYuMlGq!RCraYT?|)$_0yVcH&wO4b*%wO(#PMn{F(=gnqzZh3qCKDqBY4P!_z z0IL?DlSgq+O2f%N1*$EfL4ZU=M8@1};dVr^7P4Bor=5vB-avYqCsH5ZS5$z=dx|%s zm+8YJXqjmRf!aN(@OH`MJIq%e+ftk0PgJT7%C&F z*{Rj(fty=@B1fWR5Zh}NvRnBiUf;2!)g?51Wo~%uIAvWxVR5_+5w*^OYpv`*10X~) zW)NQDpppfTnjcbH1VLtYYj+F#SOV^B(89L7v*7#uScDw(?KG?0?aV3qf8mwqr(ndM zW7o@Bvg1!TekAyRLLBpKjJP&uc@tW7NO;DU`!1o9lcjRs>q}I4wO-C+9y<7bh$vYR zx!r>2jMf>{Bb}S?@<)vH^mS_gZn`(LNrlT(1U;%2H4@)Ygt=#Em*%Y|A6-OgzMn6m zvv#^0KHx3J=V|ParLbtRXG731ShT%WfG-{MPAFi}^->tLJ$8X0pmkrE;C1m4Fi3PV zYz&&SGhewKa*Z?Nj8|K7_pSZA5%BloBRJTt<*SW_Ew{sFK~1NYNhxb zU8JHN{P0_%(AA|hsD*^ulRm1?ZWvUjuMbx$r1Sig`+YO49^6@L5<9fB19h?918;`H zh)KkOTZYUF*V@+BM2HdJBtpC+^0&z`IMSC#EaKq3j+G?tx+#AlutF5$w-TyH@QOWr z@ef!@CzsB^NaIefA!~Cd?@ow0Kg3(htg|I-JiX4;$}UtvN89uDt?$>)9kpUw+m+K) zy9(~<0yIQ3W6~1Dj90%{REZ)AH^nBc1&jM|uVC!c88$!vnMj|%f9Gda=D_jr1hffM zS8vpn-gd*uYOalH@WXf3%0+N9iJbw@zvv;B7>kQ(05LnALg35o;Blolx+6<%oG#z} zWOr40&}t2f2rhGok&0&p0zMO+gsXK?OKXLVVJR!)IWYotC>eDW5OhGyr@-%MXlMY? z*_kK!e*Mt4C73IgrTdCnv8^|Jp>g2)8c}+etr`;pAE*FYV93d17EQZaZ(6G7%9Jvr zi#yofW{*U$%ddENi;^%dzSl6aRm=G zLZ+%dP81z+-uiISc&y6%bz?bnx{ttHr*4R0@8z*NapMHKIj`DL${iJO@O{R?39KNTY)19EbQEd_Jox2(9M@Y`>aYh(MugYgqzmCI3{)+ zEdbYRcEVqP3O>VgKA^u77F?7<62N?9p4F$_mV7ZuK&G2M8qab->8)Yn!grK>6Gaow zcaGv~GXH5~<8v$78|{H{+v1p|$X)m18~#QABFMDjk}ME|hA&@yOs}E&vI*CGf*jOK zLsUEZ#hY<0jlBP+X1jOvCHs`uivlk?2(Db#Pgg89#bnXO^vldBWUD+p^&Bn%Lhox! zd9LOao=xmfjxZxTv7mQZFqq_$h8>IlUK)k2Fd*=>iE_;~cC@N$HD_a^qL`BJaJ9bU zd2S!d`pM2A;gh_RScGShn{tU{l)s_r-gFnFEplJHqwZu-NZZGy;(e#&4Qn=`s>(8Y zNwYQA`Q1`71Th@L0lKVSs^xZ2bX2H=Dg--$xICr=EP0hbc`SrkP?iX-{lpUbZj2y} zPixcR^7>3g5Ku90oRW_GM9=a9yV!moUrJMa+sgQ9gttlUZeq?PB11E67vd1+ zevf%y?#((_Bn1uWIwq;XCg|b!^H_ZzK1W4bmKSfQDseZ<5j2!;BMa}a&iL5^w2iBD zo>j1MBK^R83sBkt{$1mOzm31s?76R@uvhl;&G0a`wh$z1b) zD;Z|LE}9&tBhWYqw2O=;tg)9On1PUIh?&+MtG-#{l#@t(;tpK2YAo3#bm*n)25Pp-j7ULN6~Q}gQ1@U*Pmox5v`QWZm0o?>`Qv#>W~XzdD9k`XO2U~o8%{?Jp-AYVweZA* z(LnPKDKwX^a-@Zt5+hLl4Wlr~wF->0sldi1^-GE1JXy~{9~Z`qDx@Q7<3!LttYkHR z?MbxqBkJ}+2ttB~r*y-5=bHZV0GICeHG!*ER0%rId9jOG75mT;WI@40#d!Y8knErH zh_zE%p$c@6_RxszCW~2J89f8XW0P$~7^9C#0UE~=?b1J|Z*FNE-&63GG9%!P_L%*0 ze7_u%1d7_F2VFi0$d&N&lR#X9uV>;EN*w=v1CpH8rL(-UTO8;iH}V4P%`+7ae}m0V z!E%Grf0maTH9OG*>E}_k?9vD2jt#maKKq48aBCLFc+r3Ek)*N-Q3KgNw?ICt4S2eP zu)?m#FwT|@@5i z*@)n%bjsXYwNS+TaMcX_Sag~n)+oyio|zQ6rTw3ek%1#xMKFZHY*D7eT37`VrsqH& z2O^UO`+lWHTIZmABtuPSP&C|ers(tJJxP+T)A$K>d{!!}9j4 zvrJHFsJkCqgHRMoJK^frN91*e^tyj(Lit)-e-J?Hq*7jxRPm zDjSKwEiY}g$2@649vtS<+Ep28K8!Rn)eR~Y90!srv+zvYwK*8rv%+q1)>fZKybLAA z(s?8g&6aK~O?)^ZDvM`*?UU=R@8*FJae{D+`j!u9ZJO_FU-L};=a6t%E*+`YL6ua{ z3)`IaI)VCCjMz{_V0*DH^U$hy#X~v6V%wOCoBDR^pheh-!4X3i3Zd=gG8NfP$yJnC zNiw@7|9sV5WZfkBn2<8EDnXfDCLT{V*vk8Ra-$cM!}=x*lhI}>Dh6LGx5&?7`B+f+ zmwF>GT(c+BJr%?d%dpuC*T8jvQ}lB&Y>Bhy!B{-ASIeP|lHuolialHsn(XS;aT}MF zh}jJMQ`K``orn_iKZ9P?F*-cWG@jTS33TjuWBZi&qr*94!l^cVB=m0LsT7J*bTCwM zhK<=5R(2LUuja>l06uMvpQ($1*c(z~VBpV|NzrkSA_S_-RwYl>vM1!O>%+ zw#(ccze!M|WXY0AIKRmVkSl6TDouv|SNJE;*yyp~I_XaEYjakN2gv_;QSgUbZ?&o` zh3wE)Vt8t|l*<{;2B*5gY!vj_k?x=0N&bT)KRHle`8{VnA~kt&+(;?=F#ipZsFEur zbB@?h7QWZ}Trom+i6=@abEb6K{Z7@YccaD}hU5etk%l8pl;41#!Tw*)5l7?Sr&LSo zcd6bG1vC7KX9bh#znRJnZ-sc>(dxH9sG}+%IpS;07<4tCXioR?I}4~oPX)?AAJr

ZB6sr-#|o=*Ge zDw7fsQ2|`>M2zyon@W`Y^cxT> zbEu#J)%}ijQz7Gw7eK9)KF=t!pGB4LZ57B@4i$`t1S2FjRii7NsVa*`Wl zdHs{p$O2@J6Bd^;*^IwQVK$(<0PANR&6A4sWo@?_WXQ2+=Q=bIo6rIi>T)*ME}mRc z!UolbPwjfW!wq;;{w`e(?RcfU=xQ7OV#ENwdtv-|#TVP=!MaBBZ|b-U@j;(UHyP7Z#4vSB40$LvAPe7z+F&-Q@LWz?D2 z7UWMY2a2MgUeg!!nDdLL9{$RRuZ?+F1;~kpe1k-Xrb7=*jYt%x(b@go)f_Ru7ZQhC zUWeF!5J>;$3Yh(lA>a|_9b?O7JNM$#nn+`wq9~#gv7~+t`tyquiU6f?hp5bpngQPx z+hT>#21G}hJ&c=6U0i+5L8n84RI(=&tagKWcqmT*L><=MmMyx72;Z4KX@PouHg(WB7m^|XQVR;tozfxvZ3H)A=ve8AtIcr_yw|Prsd+YD} zZIJpgzbynzE)3R6@5WeHK)xGM*YqZ(k=x!Ck6hrAFSyr-Ut-OhsBaPy*AVc%dIyL4 z4Z@(nVNQwstu<)NAQ?2EGp;tkQVU<=%;B^cI3moGG24{A$}6eAeHxO{LQBfEHN_DO zo+@wFrmH_I(6pi&i|P4^8NP2s5POP21eTB;ej6ZAgXROECY8;(*j9na91(HVaTk56!?GapkS4)J?VMK7wrs+a|Wo?fv-g^X&Tj~q5q%h$Go zz66E!J1+HQB!U<u3vK}PZ{l=6Irh*uKZt0z}5|8`sF4VC2%?7g&k~5GEeXdws$)ai?9QVWUh^tR$feaO#i+_qpha%E=rUtPNS zRiMF2@R#3ePHFvu#N5&sMZrcA(Le&)R+2|r{K}PW)safm zi;{D6<8lP4B;GIdmZh|p*h0oot>cVJWiu@b;c#JUM2CgJ)O~#ZquL%5N$yMG6>Q2m zZ&I!0gc&JFQ3YFV(If6`8VbYcdB5ml%XB^I*=6X*^j5@Uf`iFfG7)RgM!uDs=q5L! z4GMBM(^`>ea%*K`oN9b9sv`Y>?D44Y#wc>h8CX!MiKK^;JS$JEdK;F-RU>WQFs9d7 zC$hgS5j&81T?=eWYNbrcn=V#iajl>nKc;ayKBBOR*U52gdq=WP7 zEM$Z}mC7~=qGxE;WAS1^ZTy9{h`kc~s80ZfNm$n5i6sfXb&~Hi)U7|LMUcqEP)(1c zMF!ks7l(qxYi-I`f{qHM3{jz*y&x=l8=X!lPxUkZwB$ zfv)gbWq#M;Jt>++Bvs9oR5BpVe9g;I`z*CsN*7))s>1UW=++mYlD(iPT+%>&|C@`8 zdk(Ia4kr9Y{s?Ote@9=FR5t%Jsr$&`00t7{yH3oTfrnk-?($ZZ+8p%N#ZNSf_ zkGa3Lu-X~z&OZ$sPs&G2NVOaiOs@PzctqV(%1VaH+r(OIX*61Cr7$@jvpnz8zz(Za z5INx#(wrx!;I7|*t4f8wqUNF0(O?bDQOo(0h_rF<=4AOUElGN;Qk7VqmE0`$Y0mRr zYF4KR>?g)m$PuG#+Tt8;!9LR-dEDhNV-iiEZC!+kRM^SnREAs1`U7r}ny=zI{GHYB zvwH@biB7aSvSu>R1`*HEkfD-`uzkzc4Avj?YpV z)fBDRFoUIjcxJd95T*rdRd+R@UCqf2^C#BX1(dD&~FhgO)F` zoXXBD^Ly^5I;dHGgC*@}pU_vjxMF!e~bA zIr`?mHg|3Cn+y@eg@}<~;|=5^?SHJKGNp}Gvzl`7jpeO@uJRhIy%eCc1W%Fi)-sxQ z`Ee}rg|$Q{M5!+`_uKVm7V}g-ofxZ57|1DZJ%^(C{*tPq+{@E(3ww-nbAq=|_SZbIiheOJk{ z@EEZenmIj*9;`XG;md{ko_yaD?cS|;Svw`>?L9aghlcdc8)8I$?~CU?r3)GB{~96H zk}bK|NF;?X@4`zi#a(F=nWVz-b5fT$4R58Do$$2bk2YZjSba{y-O|IzrnFxQ$}!YU z=u`X2!9w0Z8~1d5qt;LgOD^72oDTA135r0pq=kjK1#h%xVwd+*>^lO)E=3<+j=>_D zM7M}t{+Q0u8HyNWG#s2HrnYO|)9#s^`Iz_ueT#x}Iv32;ojBFGe41^FAaNmgm({WT zE|JFDDz&IXlJ8Q}UC8_}vy(XW6i@XQ%YBSe18;=YNnMN813#x#5<#a^w=bS5CS^L; zr6Fz9NOj8$vm)6^9@gc-Wr-4p)E#cKkFAl1Uv?My9*rS$HS8g0U4|zf8ncP*DT@Tx zYp-FD=0L%FajkCQ$+E_N@~XMwfIKElWTj{be}2}KTr!h6%p$;I)!)}&>80(j$*i^} z2req33FdO;&9q<$T`8o=J+)nzyGLSbl0tQnGNIjgBxmer{c@&XyX@j-G4LZ)6QsgY z2JM0loEmlRJ47}Ni^hsBpZjreCeIao!9wcUi-PV_Yq=n&NUDES{0)S=@<5B%-h4%8 zKbHb^0t?f$e$McadDqK7G^JbUg>W}!j4Bu++_T-wX}wUut>J)+x`QayWiM~>8Jmkw zgHgQ3-gNkrXKUDwb;zhDt_68kOz#E#&WL99zWjwaZ^rQlGWyTytruvwa$L^rZlgl; zoCPAuX-RfAdjqVj1AzZ%W<%A-&N)~kCF~@d9-A+PVr`5i zus)rRI8{=0N95cbb)tLbdzmNnX>} z;O-D3cAhw2Sd{2&TP3PSwTbl+Exj0*FcQ5+ zk6%Py1%ZO-8_W90GFzDXbJ4_JG-E=}CxYZ#ae|4iB32S8m&|KurpdSqdW)XWH@Ozk z{S7&o6s{Gfcxw8>8G~>7Co`YF*K$>ciSFJw5s4R;r{$5ySZ!`s&(ImK8b*3`t9HKB zJ?FNQQhb$X{(q-jAJ1R>;W zxK49Z%RA!Ks&pWVrC`dDj8&8?16w@77STR>~PT6BQEn4b-B@B<5a6 z4FL8A6zaZ0og2QaH*bA4cg0CguEA^~$H!Oa?0CM*ZU+w3@p20l*&e3CLFn`hq>go- z@poF4idW_|S`XnLO|~56(1GbLMCZEgnt1htJoJBmEy*t?3lY?p>Nj3+3kmA1kRVbI zsRL`RS;8d0J7sFp+Qg6GZ{;6E;dX$$z(YQa=KGOekSYM*vsL+;Sm`o#Z&QDuH}EW; zy-3EH%&Pik78sd$y1P`p>{LSi+DRZP#53gl=sSjNk;vk?uvZ32HSg^7oOC?4BNZ=5 z_HU70VwfzhjpOcFi-n*U6d#px&7_jtiyiAW*Y+%13;6hH(vmFzD`-;c56ZL#Gj5NK9o!I#o%Bgn4i)2)h2L^W z5##BK%oj_FAqYQstna->2_Mr?qUo7^brTFjBd&gc(DkIFF|G8DN_Bkkm}0n!Av0o5 zyWdxD5jX1`pZ+AuA~ZCzm%U&u^Apc5)?TejW9gTz>X!Lhx_LIVwYSOn4KrJ4L2A=$ML&yoP4&=~ zoA@VWd$K^PC6oLMJYF5;&QU}QJgHiR>+Wso;}7EGT!uJ4>yxVdu(ZM|cG-x;I&+U>3~N0<2PuH@~yi!Xf>PO(qW+0JJPLbK>xNhhCp zKy!LAUU7)7&={LxV?C-aNQ<(m0eaPyHEA8z8Pg&SvnCXAM~4>LhMk6zDP~MQK>243 z8dbndURjVca`v*%I!zsFrQEu#aI>DDE~4h=f#Kx8p*zKEMUoDg9h1(Rxm}wpr%n3W z@oVn{cGj`~Hn1nFJY|V)jAZ_Lil1?JOb$MCJB?W_>7NahF3EC$02!8VJt><0mOWcA7BJ4pwMb9ZA?{+hC@2 zgFD(s;VcB4V|rvaH9Z58EktN{9nQM`1L zk1{o4K%E^3CDpaKi*K?6S%j1uTRkDWWKctEv;XMaNXUBiqBpEs>XFf^**6~Bgl>!V z>%u*D!4i>L>!7q1Xy5;L*DU&m7m%0{LgM)z|}SKK3LHPZHD{;BU7>;fWfDbav@E$ap{ z)N%Qrrhn(-_%eAPGptixALX$2IlF^`i^c5X;wh01BYM@?_+tF3V037PHx9`?OuIh( zJ|GCeeZYrW{2=Cq|%%nEElKr5s)L^Gm5s9!Q{g^}6l1-md zTiwJ4g)}kLVRDL!|M$3h>4G^>25zq-_+Kao4{(F=k!Rv>z-P5+| zcVz(VORuiol`{A-$^#nnPJT=zUd@vzysswNZ(uHexD9#NAA9wNT*-83(ro87Opa4_ zdKYl?p_CNMq<}an5s}%OtEiJNgJ;{~VjK)YO~s^T=xbW665IT}9=iaWw~rNReNXYp zJiR_9E`2fSUj%~wUI{=`K#gbhUcY_ZB!4`p1YD1~zJ3(5AK+ueK3xqMM`FN0r*WG$ zvi?F`jtUS~d(aS-p-f#11!vqymai0fZ(XV-~T)k((f37{YUAiOC_jh|o zjK^J)}RVk0oHhb-} z3jZk(6hoSRe}8oS@r2&X1maS;WRx^-#{;)tnS?8_{x25$52$7Rzf|o%0{4G0-2V`` nX8(iX{s*D`{~8GS-$nYJ7$dC4wQv4m#sE1fWyxA` { + const { t, selectedItems, getIcon } = props; + + const itemsIcon = getIcon(24, ".file"); + + return ( + <> + + + + {`${t("ItemsSelected")}: ${selectedItems.length}`} + + + +

+ +
+ + ); +}; + +export default inject(({}) => { + return {}; +})(withTranslation(["InfoPanel"])(observer(SeveralItems))); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js new file mode 100644 index 0000000000..88add66211 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -0,0 +1,421 @@ +import { + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, + StyledProperties, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./styles/styles.js"; +import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; +import { FileType } from "@appserver/common/constants"; +import Link from "@appserver/components/link"; +import Text from "@appserver/components/text"; +import Tooltip from "@appserver/components/tooltip"; +import { inject, observer } from "mobx-react"; +import React, { useEffect, useState } from "react"; +import { withTranslation } from "react-i18next"; +import { ReactSVG } from "react-svg"; + +const SingleItem = (props) => { + const { + t, + selectedItem, + isRecycleBinFolder, + onSelectItem, + setSharingPanelVisible, + getFolderInfo, + getIcon, + getFolderIcon, + getShareUsers, + } = props; + + const [item, setItem] = useState({ + id: "", + isFolder: false, + title: "", + iconUrl: "", + thumbnailUrl: "", + properties: [], + access: { + owner: { + img: "", + link: "", + }, + others: [], + }, + }); + + const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); + + const updateItemsInfo = async (selectedItem) => { + const getItemIcon = (item, size) => { + const extension = item.fileExst; + const iconUrl = extension + ? getIcon(size, extension) + : getFolderIcon(item.providerKey, size); + + return iconUrl; + }; + + const getSingleItemProperties = (item) => { + const styledLink = (text, href) => ( + + {text} + + ); + + const styledText = (text) => ( + {text} + ); + + const parseAndFormatDate = (date) => { + date = new Date(date); + + const normalize = (num) => { + if (num > 9) return num; + return `0${num}`; + }; + + let day = normalize(date.getDate()), + month = normalize(date.getMonth()), + year = date.getFullYear(), + hours = date.getHours(), + minutes = normalize(date.getMinutes()), + a_p = hours > 12 ? "AM" : "PM"; + + if (hours === 0) hours = 12; + else if (hours > 12) hours = hours - 12; + + return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; + }; + + const getItemType = (fileType) => { + switch (fileType) { + case FileType.Unknown: + return t("Common:Unknown"); + case FileType.Archive: + return t("Common:Archive"); + case FileType.Video: + return t("Common:Video"); + case FileType.Audio: + return t("Common:Audio"); + case FileType.Image: + return t("Common:Image"); + case FileType.Spreadsheet: + return t("Home:Spreadsheet"); + case FileType.Presentation: + return t("Home:Presentation"); + case FileType.Document: + return t("Home:Document"); + default: + return t("Home:Folder"); + } + }; + + const itemSize = item.isFolder + ? `${item.foldersCount} ${t("Translations:Folders")} | ${ + item.filesCount + } ${t("Files")}` + : item.contentLength; + + const itemType = getItemType(item.fileType); + + let result = [ + { + title: t("Common:Owner"), + content: styledLink( + item.createdBy.displayName, + item.createdBy.profileUrl + ), + }, + { + title: t("InfoPanel:Location"), + content: , + }, + { + title: t("Common:Type"), + content: styledText(itemType), + }, + { + title: t("Common:Size"), + content: styledText(itemSize), + }, + { + title: t("Home:ByLastModifiedDate"), + content: styledText(parseAndFormatDate(item.updated)), + }, + { + title: t("LastModifiedBy"), + content: styledLink( + item.updatedBy.displayName, + item.updatedBy.profileUrl + ), + }, + { + title: t("Home:ByCreationDate"), + content: styledText(parseAndFormatDate(item.created)), + }, + ]; + + if (item.isFolder) return result; + + result.splice(3, 0, { + title: t("FileExtension"), + content: styledText(item.fileExst.split(".")[1].toUpperCase()), + }); + + result.push( + { + title: t("Versions"), + content: styledText(item.version), + }, + { + title: t("Comments"), + content: styledText(item.comment), + } + ); + + return result; + }; + + const displayedItem = { + id: selectedItem.id, + isFolder: selectedItem.isFolder, + title: selectedItem.title, + iconUrl: getItemIcon(selectedItem, 32), + thumbnailUrl: + selectedItem.thumbnailUrl || getItemIcon(selectedItem, 96), + properties: getSingleItemProperties(selectedItem), + access: { + owner: { + img: selectedItem.createdBy.avatarSmall, + link: selectedItem.createdBy.profileUrl, + }, + others: [], + }, + }; + + setItem(displayedItem); + loadAsyncData(displayedItem, selectedItem); + }; + + const loadAsyncData = async (displayedItem, selectedItem) => { + const updateLoadedItemProperties = async ( + displayedItem, + selectedItem + ) => { + const parentFolderId = selectedItem.isFolder + ? selectedItem.parentId + : selectedItem.folderId; + const folderInfo = await getFolderInfo(parentFolderId); + + return [...displayedItem.properties].map((dip) => + dip.title === t("Location") + ? { + title: t("Location"), + content: ( + + {folderInfo.title} + + ), + } + : dip + ); + }; + + const updateLoadedItemAccess = async (selectedItem) => { + const accesses = await getShareUsers( + [selectedItem.folderId], + [selectedItem.id] + ); + + const result = { + owner: {}, + others: [], + }; + + accesses.forEach((access) => { + const user = access.sharedTo; + const userData = { + key: user.id, + img: user.avatarSmall, + link: user.profileUrl, + name: user.displayName, + email: user.email, + }; + + if (access.isOwner) result.owner = userData; + else if (userData.email !== undefined) + result.others.push(userData); + }); + + return result; + }; + + const properties = await updateLoadedItemProperties( + displayedItem, + selectedItem + ); + + const access = await updateLoadedItemAccess(selectedItem); + + setItem({ + ...displayedItem, + properties: properties, + access: access, + }); + }; + + const showAllAccessUsers = () => { + setIsShowAllAccessUsers(true); + }; + + const openSharingPanel = () => { + const { id, isFolder } = item; + + onSelectItem({ id, isFolder }); + setSharingPanelVisible(true); + }; + + useEffect(() => { + if (selectedItem.id !== item.id) updateItemsInfo(selectedItem); + }, [selectedItem]); + + return ( + <> + + + + {item.title} + + + + {selectedItem.thumbnailUrl ? ( + + + + ) : ( +
+ +
+ )} + + + + {t("SystemProperties")} + + + + + {item.properties.map((p) => ( +
+ {p.title} + {p.content} +
+ ))} +
+ + {!isRecycleBinFolder && ( + <> + + + {t("WhoHasAccess")} + + + + + + dataTip ? ( + {dataTip} + ) : null + } + /> + + +
+ + + +
+
+ + {item.access.others.length ? ( +
+ ) : null} + + {!isShowAllAccessUsers && + item.access.others.length > 3 ? ( + <> + {item.access.others.map((user, i) => { + if (i < 3) + return ( +
+ +
+ + + +
+
+
+ ); + })} +
+ {`+ ${item.access.others.length - 3} ${t( + "Members" + )}`} +
+ + ) : ( + <> + {item.access.others.map((user) => ( +
+ +
+ + + +
+
+
+ ))} + + )} +
+ + {t("OpenSharingSettings")} + + + )} + + ); +}; + +export default inject(({}) => { + return {}; +})( + withTranslation(["InfoPanel", "Home", "Common", "Translations"])( + observer(SingleItem) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 7ab5f4ffbc..663e0a5217 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -1,457 +1,78 @@ -import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; -import { FileType } from "@appserver/common/constants"; -import Link from "@appserver/components/link"; -import Text from "@appserver/components/text"; -import Tooltip from "@appserver/components/tooltip"; import { inject, observer } from "mobx-react"; import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; -import { ReactSVG } from "react-svg"; -import styled from "styled-components"; -const StyledInfoRoomBody = styled.div` - padding: 0px 16px 16px; - .no-item { - text-align: center; - } -`; - -const StyledItemTitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - height: 80px; - - .icon { - svg { - height: 32px; - width: 32px; - } - } - - .text { - font-family: Open Sans; - line-height: 22px; - margin: 0px 8px; - } -`; - -const StyledItemThumbnail = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 200px; - padding: 4px; - border: solid 1px #eceef1; - border-radius: 6px; - margin-bottom: 24px; - img { - max-height: 200px; - max-width: 100%; - width: auto; - height: auto; - } -`; - -const StyledItemSubtitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - margin-bottom: 24px; -`; - -const StyledItemProperties = styled.div` - display: flex; - flex-direction: column; - width: 100%; - margin-bottom: 24px; - gap: 8px; - - .property { - width: 100%; - display: grid; - grid-template-columns: 110px 1fr; - grid-column-gap: 24px; - - .property-title { - font-size: 13px; - color: #333333; - } - - .property-content { - font-weight: 600; - font-size: 13px; - color: #333333; - } - } -`; - -const StyledItemAccess = styled.div` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } -`; - -const StyleditemAccessUser = styled.div` - width: 32px; - height: 32px; - border-radius: 50%; - - a { - img { - border-radius: 50%; - width: 100%; - height: 100%; - } - } -`; +import SeveralItems from "./SeveralItems"; +import SingleItem from "./SingleItem"; +import { StyledInfoRoomBody } from "./styles/styles.js"; const InfoPanelBodyContent = ({ - selectedItem, + t, + selectedItems, + bufferSelectedItem, getFolderInfo, getIcon, getFolderIcon, - getShareUsers, + onSelectItem, + setSharingPanelVisible, + isRecycleBinFolder, }) => { - const [item, setItem] = useState({}); - - const updateItemsInfo = async (selectedItem) => { - const displayedItem = { - id: selectedItem.id, - title: selectedItem.title, - iconUrl: getItemIcon(selectedItem), - thumbnailUrl: selectedItem.thumbnailUrl, - properties: getItemProperties(selectedItem), - access: { - owner: { - img: selectedItem.createdBy.avatarSmall, - link: selectedItem.createdBy.profileUrl, - }, - others: [], - }, - }; - - setItem(displayedItem); - loadAsyncData(displayedItem, selectedItem); - }; - - const loadAsyncData = async (displayedItem, selectedItem) => { - const updateLoadedItemProperties = async ( - displayedItem, - selectedItem - ) => { - const parentFolderId = selectedItem.isFolder - ? selectedItem.parentId - : selectedItem.folderId; - const folderInfo = await getFolderInfo(parentFolderId); - - return [...displayedItem.properties].map((op) => - op.title === "Location" - ? { - title: "Location", - content: ( - - {folderInfo.title} - - ), - } - : op - ); - }; - - const updateLoadedItemAccess = async (item) => { - const accesses = await getShareUsers([item.folderId], [item.id]); - - const result = { - owner: {}, - others: [], - }; - - accesses.forEach((access) => { - const user = access.sharedTo; - const userData = { - key: user.id, - img: user.avatarSmall, - link: user.profileUrl, - name: user.displayName, - email: user.email, - }; - - if (access.isOwner) result.owner = userData; - else result.others.push(userData); - }); - - return result; - }; - - const properties = await updateLoadedItemProperties( - displayedItem, - selectedItem - ); - const access = await updateLoadedItemAccess(selectedItem); - - setItem({ - ...displayedItem, - properties: properties, - access: access, - }); - }; - - const getItemIcon = (item) => { - const extension = item.fileExst; - const iconUrl = extension - ? getIcon(24, extension) - : getFolderIcon(item.providerKey, 24); - - return iconUrl; - }; - - const getItemProperties = (item) => { - const styledLink = (text, href) => ( - - {text} - - ); - - const styledText = (text) => ( - {text} - ); - - const parseAndFormatDate = (date) => { - date = new Date(date); - - const normalize = (num) => { - if (num > 9) return num; - return `0${num}`; - }; - - let hours = date.getHours(), - month = normalize(date.getMonth()), - day = normalize(date.getDate()), - a_p = hours > 12 ? "AM" : "PM"; - - if (hours === 0) hours = 12; - else if (hours > 12) hours = hours - 12; - - return `${day}.${month}.${date.getFullYear()} ${hours}:${date.getMinutes()} ${a_p}`; - }; - - const getItemType = (fileType) => { - switch (fileType) { - case FileType.Unknown: - return "Unknown"; - case FileType.Archive: - return "Archive"; - case FileType.Video: - return "Video"; - case FileType.Audio: - return "Audio"; - case FileType.Image: - return "Image"; - case FileType.Spreadsheet: - return "Spreadsheet"; - case FileType.Presentation: - return "Presentation"; - case FileType.Document: - return "Document"; - - default: - return "Folder"; - } - }; - - const itemSize = item.isFolder - ? `${item.foldersCount} Folders | ${item.filesCount} Files` - : item.contentLength; - - const itemType = getItemType(item.fileType); - - let result = [ - { - title: "Owner", - content: styledLink( - item.createdBy.displayName, - item.createdBy.profileUrl - ), - }, - { - title: "Location", - content: , - }, - { - title: "Type", - content: styledText(itemType), - }, - { - title: "Size", - content: styledText(itemSize), - }, - { - title: "Date modified", - content: styledText(parseAndFormatDate(item.updated)), - }, - { - title: "Last modified by", - content: styledLink( - item.updatedBy.displayName, - item.updatedBy.profileUrl - ), - }, - { - title: "Date creation", - content: styledText(parseAndFormatDate(item.created)), - }, - ]; - - if (itemType === "Folder") return result; - - result.splice(3, 0, { - title: "File extension", - content: styledText(item.fileExst.split(".")[1].toUpperCase()), - }); - - result.push( - { - title: "Versions", - content: styledText(item.version), - }, - { - title: "Comments", - content: styledText(item.comment), - } - ); - - return result; - }; - - useEffect(() => { - if (selectedItem !== null) updateItemsInfo(selectedItem); - }, [selectedItem]); - + console.log(bufferSelectedItem); return ( - {!Object.keys(item).length ? ( + {selectedItems.length === 0 ? (
-

Select an item to display it's info

+

{t("NoItemsSelected")}

+ ) : selectedItems.length === 1 || bufferSelectedItem ? ( + ) : ( - <> - - - - {item.title} - - - - {item.thumbnailUrl && ( - - - - )} - - - - System Properties - - - - - {item.properties.map((p) => ( -
- - {p.title} - - {p.content} -
- ))} -
- - - - Who has access - - - - - -
- - - -
-
- - {item.access.others.length ? ( -
- ) : null} - - {item.access.others.map((user) => ( -
- -
- - - -
-
-
- ))} -
- - - dataTip ? ( - {dataTip} - ) : null - } - /> - + )}
); }; -export default inject(({ filesStore, formatsStore }) => { - const selectedItem = JSON.parse(JSON.stringify(filesStore.bufferSelection)); - const { getFolderInfo, getShareUsers } = filesStore; +export default inject( + ({ + filesStore, + formatsStore, + filesActionsStore, + dialogsStore, + treeFoldersStore, + }) => { + const selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); + const bufferSelectedItem = JSON.parse( + JSON.stringify(filesStore.bufferSelection) + ); + const { getFolderInfo, getShareUsers } = filesStore; - const { getIcon, getFolderIcon } = formatsStore.iconFormatsStore; + const { getIcon, getFolderIcon } = formatsStore.iconFormatsStore; + const { onSelectItem } = filesActionsStore; + const { setSharingPanelVisible } = dialogsStore; + const { isRecycleBinFolder } = treeFoldersStore; - return { - selectedItem, - getFolderInfo, - getShareUsers, - - getIcon, - getFolderIcon, - }; -})( - withRouter( - withTranslation(["Home", "Common", "Translations"])( - observer(InfoPanelBodyContent) - ) - ) -); + return { + bufferSelectedItem, + selectedItems, + getFolderInfo, + getShareUsers, + getIcon, + getFolderIcon, + onSelectItem, + setSharingPanelVisible, + isRecycleBinFolder, + }; + } +)(withRouter(withTranslation(["InfoPanel"])(observer(InfoPanelBodyContent)))); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js new file mode 100644 index 0000000000..f90bdd385f --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -0,0 +1,189 @@ +import styled from "styled-components"; + +const StyledInfoRoomBody = styled.div` + padding: 0px 16px 16px; + .no-item { + text-align: center; + } + + .no-thumbnail-img-wrapper { + padding: 9px 0 34px; + height: auto; + width: 100%; + display: flex; + justify-content: center; + .no-thumbnail-img { + height: 96px; + width: 96px; + } + } +`; + +const StyledTitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: auto; + padding: 24px 0; + + .icon { + svg { + height: 32px; + width: 32px; + } + } + + .text { + font-family: Open Sans; + line-height: 22px; + margin: 0 8px; + } +`; + +const StyledThumbnail = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; + img { + max-height: 200px; + max-width: 100%; + width: auto; + height: auto; + } +`; + +const StyledSubtitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + margin-bottom: 24px; +`; + +const StyledProperties = styled.div` + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; + + .property { + width: 100%; + display: grid; + grid-template-columns: 135px 1fr; + grid-column-gap: 24px; + + .property-title { + font-size: 13px; + color: #333333; + } + + .property-content { + display: flex; + align-items: center; + + font-weight: 600; + font-size: 13px; + color: #333333; + } + } +`; + +const StyledAccess = styled.div` + display: flex; + flex-wrap: wrap; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } + + .show-more-users { + position: static; + width: 101px; + height: 16px; + left: 120px; + top: 8px; + + font-family: Open Sans; + font-style: normal; + font-weight: normal; + font-size: 12px; + line-height: 16px; + text-align: right; + + color: #a3a9ae; + + flex: none; + order: 3; + flex-grow: 0; + + cursor: pointer; + &:hover { + text-decoration: underline; + } + } +`; + +const StyledAccessUser = styled.div` + width: 32px; + height: 32px; + border-radius: 50%; + + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } + } +`; + +const StyledOpenSharingPanel = styled.div` + position: static; + width: auto; + height: 15px; + left: 0px; + top: 2px; + + font-family: Open Sans; + font-style: normal; + font-weight: 600; + font-size: 13px; + line-height: 15px; + + color: #3b72a7; + + flex: none; + order: 0; + flex-grow: 0; + margin: 16px 0px; + + cursor: pointer; + &:hover { + text-decoration: underline; + text-decoration-style: dashed; + } +`; + +export { + StyledInfoRoomBody, + StyledTitle, + StyledThumbnail, + StyledSubtitle, + StyledProperties, + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, +}; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js index 5283394fab..5e2140a88a 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js @@ -1,12 +1,11 @@ -import { inject, observer } from "mobx-react"; +import { inject } from "mobx-react"; import React from "react"; import { withTranslation } from "react-i18next"; -import { withRouter } from "react-router"; -const InfoPanelHeaderContent = () => { - return <>Info; +const InfoPanelHeaderContent = ({ t }) => { + return <>{t("Info")}; }; export default inject(({}) => { return {}; -})(observer(InfoPanelHeaderContent)); +})(withTranslation(["InfoPanel"])(InfoPanelHeaderContent)); 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 0dd5988669..df08cfc79a 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 @@ -66,7 +66,8 @@ const SectionBodyContent = (props) => { e.target.closest(".scroll-body") && !e.target.closest(".files-item") && !e.target.closest(".not-selectable") && - !e.target.closest(".table-container_group-menu") + !e.target.closest(".table-container_group-menu") && + !e.target.closest(".info-panel") ) { setSelection([]); setBufferSelection(null); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 24a550a03a..5e75cee0e3 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -41,9 +41,14 @@ const StyledContainer = styled.div` props.title && css` display: grid; - grid-template-columns: ${({ isRootFolder, canCreate }) => { + grid-template-columns: ${({ + isRootFolder, + canCreate, + isRecycleBinFolder, + }) => { if (isRootFolder) { - if (canCreate) return "auto auto 1fr"; + if (canCreate || isRecycleBinFolder) + return "auto auto 1fr"; return "auto 1fr"; } if (canCreate) return "auto auto auto 1fr 32px"; @@ -491,6 +496,7 @@ class SectionHeaderContent extends React.Component { width={context.sectionWidth} isRootFolder={isRootFolder} canCreate={canCreate} + isRecycleBinFolder={isRecycleBinFolder} title={title} isDesktop={isDesktop} isTabletView={isTabletView} diff --git a/public/locales/en/Common.json b/public/locales/en/Common.json index 1fbd05fa48..5d88e7316e 100644 --- a/public/locales/en/Common.json +++ b/public/locales/en/Common.json @@ -1,136 +1,136 @@ { - "About": "About", - "Actions": "Actions", - "Active": "Active", - "AddButton": "Add", - "AddFilter": "Add filter", - "AdminSettings": "Admin settings", - "Archive": "Archive", - "Audio": "Audio", - "BarMaintenanceDescription": "We apologize for any short-term technical issues in service functioning, that may appear on {{targetDate}} during the update of {{productName}}.", - "BarMaintenanceDisclaimer": "Please, make sure that all the changes are successfully saved during this day.", - "ByFirstNameSorting": "By first name", - "ByLastNameSorting": "By last name", - "CancelButton": "Cancel", - "ClearButton": "Reset filter", - "CloseButton": "Close", - "ComingSoon": "Coming soon", - "CommunityProduct": "Community", - "Confirmation": "Confirmation", - "ContinueButton": "Continue", - "CopyEmailAndPassword": "Copy email and password", - "CountPerPage": "{{count}} per page", - "Create": "Create", - "Culture_az": "Azerbaijani (Latin, Azerbaijan)", - "Culture_bg": "Bulgarian (Bulgaria)", - "Culture_cs": "Czech (Czech Republic)", - "Culture_de": "German (Germany)", - "Culture_de-CH": "German (Switzerland)", - "Culture_el": "Greek (Greece)", - "Culture_en": "English (United Kingdom)", - "Culture_en-US": "English (United States)", - "Culture_es": "Spanish (Spain)", - "Culture_es-MX": "Spanish (Mexico)", - "Culture_fi": "Finnish (Finland)", - "Culture_fr": "French (France)", - "Culture_it": "Italian (Italy)", - "Culture_ja": "Japanese (Japan)", - "Culture_ko": "Korean (Korea)", - "Culture_lo": "Laotian (Laos)", - "Culture_lv": "Latvian (Latvia)", - "Culture_nl": "Dutch (Netherlands)", - "Culture_pl": "Polish (Poland)", - "Culture_pt": "Portuguese (Portugal)", - "Culture_pt-BR": "Portuguese (Brazil)", - "Culture_ro": "Romanian (Romania)", - "Culture_ru": "Russian (Russia)", - "Culture_sk": "Slovak (Slovakia)", - "Culture_sl": "Slovenian (Slovenia)", - "Culture_tr": "Turkish (Turkey)", - "Culture_uk": "Ukrainian (Ukraine)", - "Culture_vi": "Vietnamese (Vietnam)", - "Culture_zh-CN": "Chinese (Simplified, PRC)", - "Delete": "Delete", - "Department": "Department", - "DirectionAscLabel": "A-Z", - "DirectionDescLabel": "Z-A", - "Documents": "Documents", - "Download": "Download", - "EditAvatar": "Edit", - "EditButton": "Edit", - "Email": "Email", - "EmptyFieldError": "Empty field", - "Enable": "Enable", - "EncryptingFile": "Encrypting file", - "EncryptionFilePreparing": "Preparing file for encryption", - "EncryptionKeysReload": "Encryption keys must be re-entered", - "Error": "Error", - "FillFormButton": "Fill in the form", - "FullAccess": "Full access", - "Guest": "Guest", - "Image": "Image", - "Language": "Language", - "LastName": "Last Name", - "LearnMore": "Learn more", - "Load": "Load", - "LoadingDescription": "Please wait...", - "LoadingProcessing": "Loading...", - "Mail": "Mail", - "MainHeaderSelectAll": "Select all", - "MakeForm": "Save as oform", - "MeLabel": "Me", - "More": "More", - "Name": "Name", - "NewVersionAvailable": "A new version of the website available", - "Next": "Next", - "NotFoundLanguage": "Can't find your language? Contact us at <1>{{supportEmail}} to take part in the translation and get rewards.", - "OKButton": "OK", - "OpenApp": "Open your {{title}} app", - "Owner": "Owner", - "PageOfTotalPage": "{{page}} of {{totalPage}}", - "Password": "Password", - "PasswordLimitDigits": "digits", - "PasswordLimitLength": "from {{fromNumber}} to {{toNumber}} characters", - "PasswordLimitMessage": "Password must contain", - "PasswordLimitSpecialSymbols": "special characters", - "PasswordLimitUpperCase": "capital letters", - "People": "People", - "Phone": "Phone", - "Pin": "Pin", - "Previous": "Previous", - "Profile": "Profile", - "ProjectsProduct": "Projects", - "ProviderLoginError": "Authorization error", - "ProviderNotConnected": "Provider is not connected to your account", - "RequiredField": "Required field", - "ResetApplication": "Reset application", - "Review": "Review", - "Role": "Role", - "SaveButton": "Save", - "Search": "Search", - "Select": "Select", - "SelectAll": "Select all", - "SendButton": "Send", - "Sending": "Sending...", - "Settings": "Settings", - "ShowUsersList": "View users list", - "SignInWithFacebook": "Sign in with Facebook", - "SignInWithGoogle": "Sign in with Google", - "SignInWithLinkedIn": "Sign in with LinkedIn", - "SignInWithTwitter": "Sign in with Twitter", - "Size": "Size", - "SomethingWentWrong": "Something went wrong.", - "SwitchToThumbnails": "Switch to thumbnails view", - "SwitchViewToCompact": "Switch to compact view", - "TitleSelectFile": "Select", - "Type": "Type", - "Unknown": "Unknown", - "UnknownError": "Unknown error", - "Unpin": "Unpin", - "User": "User", - "Version": "Version", - "Video": "Video", - "View": "View", - "ViewWeb": "View web version", - "Warning": "Warning" -} \ No newline at end of file + "About": "About", + "Actions": "Actions", + "Active": "Active", + "AddButton": "Add", + "AddFilter": "Add filter", + "AdminSettings": "Admin settings", + "Archive": "Archive", + "Audio": "Audio", + "BarMaintenanceDescription": "We apologize for any short-term technical issues in service functioning, that may appear on {{targetDate}} during the update of {{productName}}.", + "BarMaintenanceDisclaimer": "Please, make sure that all the changes are successfully saved during this day.", + "ByFirstNameSorting": "By first name", + "ByLastNameSorting": "By last name", + "CancelButton": "Cancel", + "ClearButton": "Reset filter", + "CloseButton": "Close", + "ComingSoon": "Coming soon", + "CommunityProduct": "Community", + "Confirmation": "Confirmation", + "ContinueButton": "Continue", + "CopyEmailAndPassword": "Copy email and password", + "CountPerPage": "{{count}} per page", + "Create": "Create", + "Culture_az": "Azerbaijani (Latin, Azerbaijan)", + "Culture_bg": "Bulgarian (Bulgaria)", + "Culture_cs": "Czech (Czech Republic)", + "Culture_de": "German (Germany)", + "Culture_de-CH": "German (Switzerland)", + "Culture_el": "Greek (Greece)", + "Culture_en": "English (United Kingdom)", + "Culture_en-US": "English (United States)", + "Culture_es": "Spanish (Spain)", + "Culture_es-MX": "Spanish (Mexico)", + "Culture_fi": "Finnish (Finland)", + "Culture_fr": "French (France)", + "Culture_it": "Italian (Italy)", + "Culture_ja": "Japanese (Japan)", + "Culture_ko": "Korean (Korea)", + "Culture_lo": "Laotian (Laos)", + "Culture_lv": "Latvian (Latvia)", + "Culture_nl": "Dutch (Netherlands)", + "Culture_pl": "Polish (Poland)", + "Culture_pt": "Portuguese (Portugal)", + "Culture_pt-BR": "Portuguese (Brazil)", + "Culture_ro": "Romanian (Romania)", + "Culture_ru": "Russian (Russia)", + "Culture_sk": "Slovak (Slovakia)", + "Culture_sl": "Slovenian (Slovenia)", + "Culture_tr": "Turkish (Turkey)", + "Culture_uk": "Ukrainian (Ukraine)", + "Culture_vi": "Vietnamese (Vietnam)", + "Culture_zh-CN": "Chinese (Simplified, PRC)", + "Delete": "Delete", + "Department": "Department", + "DirectionAscLabel": "A-Z", + "DirectionDescLabel": "Z-A", + "Documents": "Documents", + "Download": "Download", + "EditAvatar": "Edit", + "EditButton": "Edit", + "Email": "Email", + "EmptyFieldError": "Empty field", + "Enable": "Enable", + "EncryptingFile": "Encrypting file", + "EncryptionFilePreparing": "Preparing file for encryption", + "EncryptionKeysReload": "Encryption keys must be re-entered", + "Error": "Error", + "FillFormButton": "Fill in the form", + "FullAccess": "Full access", + "Guest": "Guest", + "Image": "Image", + "Language": "Language", + "LastName": "Last Name", + "LearnMore": "Learn more", + "Load": "Load", + "LoadingDescription": "Please wait...", + "LoadingProcessing": "Loading...", + "Mail": "Mail", + "MainHeaderSelectAll": "Select all", + "MakeForm": "Save as oform", + "MeLabel": "Me", + "More": "More", + "Name": "Name", + "NewVersionAvailable": "A new version of the website available", + "Next": "Next", + "NotFoundLanguage": "Can't find your language? Contact us at <1>{{supportEmail}} to take part in the translation and get rewards.", + "OKButton": "OK", + "OpenApp": "Open your {{title}} app", + "Owner": "Owner", + "PageOfTotalPage": "{{page}} of {{totalPage}}", + "Password": "Password", + "PasswordLimitDigits": "digits", + "PasswordLimitLength": "from {{fromNumber}} to {{toNumber}} characters", + "PasswordLimitMessage": "Password must contain", + "PasswordLimitSpecialSymbols": "special characters", + "PasswordLimitUpperCase": "capital letters", + "People": "People", + "Phone": "Phone", + "Pin": "Pin", + "Previous": "Previous", + "Profile": "Profile", + "ProjectsProduct": "Projects", + "ProviderLoginError": "Authorization error", + "ProviderNotConnected": "Provider is not connected to your account", + "RequiredField": "Required field", + "ResetApplication": "Reset application", + "Review": "Review", + "Role": "Role", + "SaveButton": "Save", + "Search": "Search", + "Select": "Select", + "SelectAll": "Select all", + "SendButton": "Send", + "Sending": "Sending...", + "Settings": "Settings", + "ShowUsersList": "View users list", + "SignInWithFacebook": "Sign in with Facebook", + "SignInWithGoogle": "Sign in with Google", + "SignInWithLinkedIn": "Sign in with LinkedIn", + "SignInWithTwitter": "Sign in with Twitter", + "Size": "Size", + "SomethingWentWrong": "Something went wrong.", + "SwitchToThumbnails": "Switch to thumbnails view", + "SwitchViewToCompact": "Switch to compact view", + "TitleSelectFile": "Select", + "Type": "Type", + "Unknown": "Unknown", + "UnknownError": "Unknown error", + "Unpin": "Unpin", + "User": "User", + "Version": "Version", + "Video": "Video", + "View": "View", + "ViewWeb": "View web version", + "Warning": "Warning" +} From d4c4a6ba820cd7f0ad6d93bdada2d1b8f2b6de6a Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Feb 2022 16:48:04 +0300 Subject: [PATCH 16/81] exclude buffer selection --- .../Client/src/pages/Home/InfoPanel/Body/SingleItem.js | 5 ++++- .../ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js | 5 ++--- .../Client/src/pages/Home/InfoPanel/Body/styles/styles.js | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index 88add66211..85dc5386fb 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -301,7 +301,10 @@ const SingleItem = (props) => { ) : (
- +
)} diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 663e0a5217..83b8da89a7 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -19,16 +19,15 @@ const InfoPanelBodyContent = ({ setSharingPanelVisible, isRecycleBinFolder, }) => { - console.log(bufferSelectedItem); return ( {selectedItems.length === 0 ? (

{t("NoItemsSelected")}

- ) : selectedItems.length === 1 || bufferSelectedItem ? ( + ) : selectedItems.length === 1 ? ( Date: Tue, 1 Mar 2022 12:24:56 +0300 Subject: [PATCH 17/81] several items update --- .../pages/Home/InfoPanel/Body/SeveralItems.js | 213 +++++++++++++++++- .../pages/Home/InfoPanel/Body/SingleItem.js | 2 +- .../InfoPanel/Body/filePropertyHelpers.js | 0 3 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js index 140d865862..5473520f87 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js @@ -1,16 +1,206 @@ +import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; +import { FileType } from "@appserver/common/constants"; +import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; import { inject, observer } from "mobx-react"; -import React from "react"; +import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; -import { StyledTitle } from "./styles/styles.js"; +import { + StyledProperties, + StyledSubtitle, + StyledTitle, +} from "./styles/styles.js"; const SeveralItems = (props) => { - const { t, selectedItems, getIcon } = props; - + const { t, selectedItems, getIcon, getFolderInfo } = props; const itemsIcon = getIcon(24, ".file"); + let items = []; + const [mixedProperties, setMixedProperties] = useState([]); + + const systemPropertiesTemplate = [ + { + title: t("Common:Owner"), + content: "", + }, + { + title: t("InfoPanel:Location"), + content: "", + }, + { + title: t("Common:Type"), + content: "", + }, + { + title: t("Common:Size"), + content: "", + }, + { + title: t("Home:ByLastModifiedDate"), + content: "", + }, + { + title: t("LastModifiedBy"), + content: "", + }, + { + title: t("Home:ByCreationDate"), + content: "", + }, + ]; + + const updateItems = (selectedItems) => { + let newProperties = selectedItems.map((selectedItem) => + getSingleItemProperties(selectedItem) + ); + + let mixedProperties = mixProperties(newProperties); + }; + + const getSingleItemProperties = (item) => { + const styledLink = (text, href) => ( + + {text} + + ); + + const styledText = (text) => ( + {text} + ); + + const parseAndFormatDate = (date) => { + date = new Date(date); + + const normalize = (num) => { + if (num > 9) return num; + return `0${num}`; + }; + + let day = normalize(date.getDate()), + month = normalize(date.getMonth()), + year = date.getFullYear(), + hours = date.getHours(), + minutes = normalize(date.getMinutes()), + a_p = hours > 12 ? "AM" : "PM"; + + if (hours === 0) hours = 12; + else if (hours > 12) hours = hours - 12; + + return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; + }; + + const getItemType = (fileType) => { + switch (fileType) { + case FileType.Unknown: + return t("Common:Unknown"); + case FileType.Archive: + return t("Common:Archive"); + case FileType.Video: + return t("Common:Video"); + case FileType.Audio: + return t("Common:Audio"); + case FileType.Image: + return t("Common:Image"); + case FileType.Spreadsheet: + return t("Home:Spreadsheet"); + case FileType.Presentation: + return t("Home:Presentation"); + case FileType.Document: + return t("Home:Document"); + default: + return t("Home:Folder"); + } + }; + + const itemSize = item.isFolder + ? `${item.foldersCount} ${t("Translations:Folders")} | ${ + item.filesCount + } ${t("Files")}` + : item.contentLength; + + const itemType = getItemType(item.fileType); + + let result = [ + { + title: t("Common:Owner"), + content: styledLink( + item.createdBy.displayName, + item.createdBy.profileUrl + ), + }, + { + title: t("InfoPanel:Location"), + content: , + }, + { + title: t("Common:Type"), + content: styledText(itemType), + }, + { + title: t("Common:Size"), + content: styledText(itemSize), + }, + { + title: t("Home:ByLastModifiedDate"), + content: styledText(parseAndFormatDate(item.updated)), + }, + { + title: t("LastModifiedBy"), + content: styledLink( + item.updatedBy.displayName, + item.updatedBy.profileUrl + ), + }, + { + title: t("Home:ByCreationDate"), + content: styledText(parseAndFormatDate(item.created)), + }, + ]; + + if (item.isFolder) return result; + + result.splice(3, 0, { + title: t("FileExtension"), + content: styledText(item.fileExst.split(".")[1].toUpperCase()), + }); + + result.push( + { + title: t("Versions"), + content: styledText(item.version), + }, + { + title: t("Comments"), + content: styledText(item.comment), + } + ); + + return result; + }; + + const mixProperties = (properties) => { + const result = [...systemPropertiesTemplate]; + result.forEach((finalProperty, i) => { + const itemsProperties = properties.map((itemProperties) => { + const [property] = itemProperties.filter((obj) => { + return obj.title === finalProperty.title; + }); + console.log(property, finalProperty); + return itemProperties[i].title === finalProperty.title + ? itemProperties[i].content + : null; + }); + + //console.log(itemsProperties); + }); + }; + + useEffect(() => { + if (selectedItems.length !== items.length) updateItems(selectedItems); + }, [selectedItems]); + return ( <> @@ -26,6 +216,21 @@ const SeveralItems = (props) => { src="images/empty_screen.png" />
+ + + + {t("SystemProperties")} + + + + + {mixedProperties.map((p) => ( +
+ {p.title} + {p.content} +
+ ))} +
); }; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index 85dc5386fb..ea9983102d 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -197,7 +197,7 @@ const SingleItem = (props) => { }; setItem(displayedItem); - loadAsyncData(displayedItem, selectedItem); + await loadAsyncData(displayedItem, selectedItem); }; const loadAsyncData = async (displayedItem, selectedItem) => { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js new file mode 100644 index 0000000000..e69de29bb2 From fd46496544084aa09e938b401b136400a2504d6a Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 2 Mar 2022 13:06:02 +0300 Subject: [PATCH 18/81] some tweaks --- .../pages/Home/InfoPanel/Body/SeveralItems.js | 210 +----------------- .../InfoPanel/Body/filePropertyHelpers.js | 0 .../ASC.Files/Client/src/pages/Home/index.js | 2 +- .../src/components/pages/Home/index.js | 181 +++++++-------- 4 files changed, 94 insertions(+), 299 deletions(-) delete mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js index 5473520f87..e22c8deef5 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js @@ -1,206 +1,15 @@ -import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; -import { FileType } from "@appserver/common/constants"; -import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; import { inject, observer } from "mobx-react"; -import React, { useEffect, useState } from "react"; +import React from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; -import { - StyledProperties, - StyledSubtitle, - StyledTitle, -} from "./styles/styles.js"; +import { StyledTitle } from "./styles/styles.js"; const SeveralItems = (props) => { const { t, selectedItems, getIcon, getFolderInfo } = props; const itemsIcon = getIcon(24, ".file"); - let items = []; - const [mixedProperties, setMixedProperties] = useState([]); - - const systemPropertiesTemplate = [ - { - title: t("Common:Owner"), - content: "", - }, - { - title: t("InfoPanel:Location"), - content: "", - }, - { - title: t("Common:Type"), - content: "", - }, - { - title: t("Common:Size"), - content: "", - }, - { - title: t("Home:ByLastModifiedDate"), - content: "", - }, - { - title: t("LastModifiedBy"), - content: "", - }, - { - title: t("Home:ByCreationDate"), - content: "", - }, - ]; - - const updateItems = (selectedItems) => { - let newProperties = selectedItems.map((selectedItem) => - getSingleItemProperties(selectedItem) - ); - - let mixedProperties = mixProperties(newProperties); - }; - - const getSingleItemProperties = (item) => { - const styledLink = (text, href) => ( - - {text} - - ); - - const styledText = (text) => ( - {text} - ); - - const parseAndFormatDate = (date) => { - date = new Date(date); - - const normalize = (num) => { - if (num > 9) return num; - return `0${num}`; - }; - - let day = normalize(date.getDate()), - month = normalize(date.getMonth()), - year = date.getFullYear(), - hours = date.getHours(), - minutes = normalize(date.getMinutes()), - a_p = hours > 12 ? "AM" : "PM"; - - if (hours === 0) hours = 12; - else if (hours > 12) hours = hours - 12; - - return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; - }; - - const getItemType = (fileType) => { - switch (fileType) { - case FileType.Unknown: - return t("Common:Unknown"); - case FileType.Archive: - return t("Common:Archive"); - case FileType.Video: - return t("Common:Video"); - case FileType.Audio: - return t("Common:Audio"); - case FileType.Image: - return t("Common:Image"); - case FileType.Spreadsheet: - return t("Home:Spreadsheet"); - case FileType.Presentation: - return t("Home:Presentation"); - case FileType.Document: - return t("Home:Document"); - default: - return t("Home:Folder"); - } - }; - - const itemSize = item.isFolder - ? `${item.foldersCount} ${t("Translations:Folders")} | ${ - item.filesCount - } ${t("Files")}` - : item.contentLength; - - const itemType = getItemType(item.fileType); - - let result = [ - { - title: t("Common:Owner"), - content: styledLink( - item.createdBy.displayName, - item.createdBy.profileUrl - ), - }, - { - title: t("InfoPanel:Location"), - content: , - }, - { - title: t("Common:Type"), - content: styledText(itemType), - }, - { - title: t("Common:Size"), - content: styledText(itemSize), - }, - { - title: t("Home:ByLastModifiedDate"), - content: styledText(parseAndFormatDate(item.updated)), - }, - { - title: t("LastModifiedBy"), - content: styledLink( - item.updatedBy.displayName, - item.updatedBy.profileUrl - ), - }, - { - title: t("Home:ByCreationDate"), - content: styledText(parseAndFormatDate(item.created)), - }, - ]; - - if (item.isFolder) return result; - - result.splice(3, 0, { - title: t("FileExtension"), - content: styledText(item.fileExst.split(".")[1].toUpperCase()), - }); - - result.push( - { - title: t("Versions"), - content: styledText(item.version), - }, - { - title: t("Comments"), - content: styledText(item.comment), - } - ); - - return result; - }; - - const mixProperties = (properties) => { - const result = [...systemPropertiesTemplate]; - result.forEach((finalProperty, i) => { - const itemsProperties = properties.map((itemProperties) => { - const [property] = itemProperties.filter((obj) => { - return obj.title === finalProperty.title; - }); - console.log(property, finalProperty); - return itemProperties[i].title === finalProperty.title - ? itemProperties[i].content - : null; - }); - - //console.log(itemsProperties); - }); - }; - - useEffect(() => { - if (selectedItems.length !== items.length) updateItems(selectedItems); - }, [selectedItems]); - return ( <> @@ -216,21 +25,6 @@ const SeveralItems = (props) => { src="images/empty_screen.png" />
- - - - {t("SystemProperties")} - - - - - {mixedProperties.map((p) => ( -
- {p.title} - {p.content} -
- ))} -
); }; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/filePropertyHelpers.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index a8f26c3f4d..c0fe780afe 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -20,9 +20,9 @@ import { } from "../../components/Article"; import DragTooltip from "../../components/DragTooltip"; import { createTreeFolders } from "../../helpers/files-helpers"; -import MediaViewer from "./MediaViewer"; import { InfoPanelBodyContent } from "./InfoPanel"; import { InfoPanelHeaderContent } from "./InfoPanel"; +import MediaViewer from "./MediaViewer"; import { SectionBodyContent, SectionFilterContent, diff --git a/web/ASC.Web.Client/src/components/pages/Home/index.js b/web/ASC.Web.Client/src/components/pages/Home/index.js index c6167bc523..616af7bfef 100644 --- a/web/ASC.Web.Client/src/components/pages/Home/index.js +++ b/web/ASC.Web.Client/src/components/pages/Home/index.js @@ -1,127 +1,128 @@ -import React, { useEffect } from "react"; -import PropTypes from "prop-types"; -import { withRouter } from "react-router"; -import { useTranslation } from "react-i18next"; -import styled from "styled-components"; -import Text from "@appserver/components/text"; -import toastr from "studio/toastr"; import PageLayout from "@appserver/common/components/PageLayout"; import history from "@appserver/common/history"; -import ModuleTile from "./ModuleTile"; import { tryRedirectTo } from "@appserver/common/utils"; -import { setDocumentTitle } from "../../../helpers/utils"; +import Text from "@appserver/components/text"; import { inject, observer } from "mobx-react"; +import PropTypes from "prop-types"; +import React, { useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { withRouter } from "react-router"; +import toastr from "studio/toastr"; +import styled from "styled-components"; + import config from "../../../../package.json"; +import { setDocumentTitle } from "../../../helpers/utils"; +import ModuleTile from "./ModuleTile"; const HomeContainer = styled.div` - padding: 62px 15px 0 15px; - margin: 0 auto; - max-width: 1140px; - width: 100%; - box-sizing: border-box; - /*justify-content: center;*/ + padding: 62px 15px 0 15px; + margin: 0 auto; + max-width: 1140px; + width: 100%; + box-sizing: border-box; + /*justify-content: center;*/ - .home-modules { - display: flex; - flex-wrap: wrap; - margin: 0 -15px; + .home-modules { + display: flex; + flex-wrap: wrap; + margin: 0 -15px; - .home-module { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; + .home-module { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; + } } - } - .home-error-text { - margin-top: 23px; - padding: 0 30px; - @media (min-width: 768px) { - margin-left: 25%; - flex: 0 0 50%; - max-width: 50%; + .home-error-text { + margin-top: 23px; + padding: 0 30px; + @media (min-width: 768px) { + margin-left: 25%; + flex: 0 0 50%; + max-width: 50%; + } + @media (min-width: 576px) { + flex: 0 0 100%; + max-width: 100%; + } } - @media (min-width: 576px) { - flex: 0 0 100%; - max-width: 100%; - } - } `; const Tiles = ({ modules, isPrimary }) => { - let index = 0; - const mapped = modules.filter( - (m) => m.isPrimary === isPrimary && m.isolateMode !== true - ); + let index = 0; + const mapped = modules.filter( + (m) => m.isPrimary === isPrimary && m.isolateMode !== true + ); - //console.log("Tiles", mapped, isPrimary); + //console.log("Tiles", mapped, isPrimary); - return mapped.length > 0 ? ( -
- {mapped.map((m) => ( -
- history.push(m.link)} /> + return mapped.length > 0 ? ( +
+ {mapped.map((m) => ( +
+ history.push(m.link)} /> +
+ ))}
- ))} -
- ) : ( - <> - ); + ) : ( + <> + ); }; Tiles.propTypes = { - modules: PropTypes.array.isRequired, - isPrimary: PropTypes.bool.isRequired, + modules: PropTypes.array.isRequired, + isPrimary: PropTypes.bool.isRequired, }; const Body = ({ modules, match, isLoaded }) => { - const { t } = useTranslation(); - const { error } = match.params; - setDocumentTitle(); + const { t } = useTranslation(); + const { error } = match.params; + setDocumentTitle(); - useEffect(() => error && toastr.error(error), [error]); + useEffect(() => error && toastr.error(error), [error]); - return !isLoaded ? ( - <> - ) : ( - - - + return !isLoaded ? ( + <> + ) : ( + + + - {!modules || !modules.length ? ( - - {t("NoOneModulesAvailable")} - - ) : null} - - ); + {!modules || !modules.length ? ( + + {t("NoOneModulesAvailable")} + + ) : null} + + ); }; const Home = ({ defaultPage, ...rest }) => { - return tryRedirectTo(defaultPage) ? ( - <> - ) : ( - - - - - - ); + return tryRedirectTo(defaultPage) ? ( + <> + ) : ( + + + + + + ); }; Home.propTypes = { - modules: PropTypes.array.isRequired, - isLoaded: PropTypes.bool, - defaultPage: PropTypes.string, + modules: PropTypes.array.isRequired, + isLoaded: PropTypes.bool, + defaultPage: PropTypes.string, }; export default inject(({ auth }) => { - const { isLoaded, settingsStore, moduleStore } = auth; - const { defaultPage } = settingsStore; - const { modules } = moduleStore; - return { - defaultPage, - modules, - isLoaded, - }; + const { isLoaded, settingsStore, moduleStore } = auth; + const { defaultPage } = settingsStore; + const { modules } = moduleStore; + return { + defaultPage, + modules, + isLoaded, + }; })(withRouter(observer(Home))); From e77a97e10501d5b42630480b6cb266158ec5a804 Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 2 Mar 2022 17:19:19 +0300 Subject: [PATCH 19/81] added checkbox menu interaction and new opening mechanics --- config/kafka.json | 2 +- .../PageLayout/sub-components/info-panel.js | 14 +- .../table-container/TableGroupMenu.js | 2 - .../Client/src/HOCs/withContextOptions.js | 2 +- .../Client/src/HOCs/withFileActions.js | 816 ++++---- .../pages/Home/InfoPanel/Body/SingleItem.js | 36 +- .../src/pages/Home/InfoPanel/Body/index.js | 9 +- .../Client/src/store/FilesActionsStore.js | 1860 +++++++++-------- products/ASC.Files/Client/src/store/index.js | 13 +- public/images/info.outline.react.svg | 12 + 10 files changed, 1457 insertions(+), 1309 deletions(-) create mode 100644 public/images/info.outline.react.svg diff --git a/config/kafka.json b/config/kafka.json index 3a56691aae..4ffde92112 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,5 +1,5 @@ { "kafka": { - "BootstrapServers": "localhost:9092" + "BootstrapServers": "" } } diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index 176d94b541..bced974bdf 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -1,5 +1,6 @@ import IconButton from "@appserver/components/icon-button"; import { isTablet, mobile, tablet } from "@appserver/components/utils/device"; +import { set } from "mobx"; import { inject } from "mobx-react"; import PropTypes from "prop-types"; import React, { useEffect } from "react"; @@ -65,7 +66,10 @@ const StyledCloseButtonWrapper = styled.div` } `; -const InfoPanel = ({ children, isVisible, setIsVisible }) => { +const InfoPanel = ({ children, selectedItems, isVisible, setIsVisible }) => { + //if (selectedItems.length > 0) setIsVisible(true); + //else setIsVisible(false); + if (!isVisible) return null; const closeInfoPanel = () => setIsVisible(false); @@ -108,7 +112,8 @@ InfoPanel.propTypes = { isVisible: PropTypes.bool, }; -export default inject(({ infoPanelStore }) => { +export default inject(({ infoPanelStore, filesStore }) => { + let selectedItems = []; let isVisible = false; let setIsVisible = () => {}; @@ -117,7 +122,12 @@ export default inject(({ infoPanelStore }) => { setIsVisible = infoPanelStore.setIsVisible; } + if (filesStore) { + selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); + } + return { + selectedItems, isVisible, setIsVisible, }; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index c8e00ff77b..dea0b41944 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -12,7 +12,6 @@ const TableGroupMenu = (props) => { isChecked, isIndeterminate, headerMenu, - infoPanelToggle, onChange, checkboxOptions, checkboxMargin, @@ -55,7 +54,6 @@ const TableGroupMenu = (props) => { {headerMenu.map((item, index) => ( ))} - {infoPanelToggle} diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index 4d5754529d..36867fecf6 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -317,7 +317,7 @@ export default function withContextOptions(WrappedComponent) { case "show-info": return { key: option, - label: t("Show info"), + label: t("InfoPanel:Info"), icon: "images/info.react.svg", onClick: this.onSetInfoPanelVisible, disabled: false, diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 7dfc96f74c..0ef88c425b 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -1,421 +1,457 @@ -import React from "react"; -import { inject, observer } from "mobx-react"; -import toastr from "@appserver/components/toast/toastr"; -import { checkProtocol } from "../helpers/files-helpers"; import { AppServerConfig } from "@appserver/common/constants"; import { combineUrl } from "@appserver/common/utils"; -import config from "../../package.json"; +import toastr from "@appserver/components/toast/toastr"; +import { inject, observer } from "mobx-react"; +import React from "react"; import { isMobile } from "react-device-detect"; +import config from "../../package.json"; +import { checkProtocol } from "../helpers/files-helpers"; + export default function withFileActions(WrappedFileItem) { - class WithFileActions extends React.Component { - constructor(props) { - super(props); - } + class WithFileActions extends React.Component { + constructor(props) { + super(props); + } - onContentFileSelect = (checked, file) => { - const { selectRowAction } = this.props; - if (!file || file.id === -1) return; - selectRowAction(checked, file); - }; + onContentFileSelect = (checked, file) => { + const { + selectRowAction, + infoPanelIsVisible, + showInfoPanel, + } = this.props; + if (!file || file.id === -1) return; + selectRowAction(checked, file); + if (!infoPanelIsVisible) showInfoPanel(); + }; - fileContextClick = () => { - const { onSelectItem, item } = this.props; - const { id, isFolder } = item; + fileContextClick = () => { + if (!this.props.infoPanelIsVisible) this.props.showInfoPanel(); - id !== -1 && onSelectItem({ id, isFolder }); - }; + const { onSelectItem, item } = this.props; + const { id, isFolder } = item; - onHideContextMenu = () => { - //this.props.setBufferSelection(null); - }; + id !== -1 && onSelectItem({ id, isFolder }); + }; - onDropZoneUpload = (files, uploadToFolder) => { - const { t, dragging, setDragging, startUpload } = this.props; + onHideContextMenu = () => { + //this.props.setBufferSelection(null); + }; - dragging && setDragging(false); - startUpload(files, uploadToFolder, t); - }; + onDropZoneUpload = (files, uploadToFolder) => { + const { t, dragging, setDragging, startUpload } = this.props; - onDrop = (items) => { - const { fileExst, id } = this.props.item; + dragging && setDragging(false); + startUpload(files, uploadToFolder, t); + }; - if (!fileExst) { - this.onDropZoneUpload(items, id); - } else { - this.onDropZoneUpload(items); - } - }; + onDrop = (items) => { + const { fileExst, id } = this.props.item; - onMouseDown = (e) => { - const { - draggable, - setTooltipPosition, - setStartDrag, - isPrivacy, - isTrashFolder, - onSelectItem, - item, - setBufferSelection, - isActive, - } = this.props; + if (!fileExst) { + this.onDropZoneUpload(items, id); + } else { + this.onDropZoneUpload(items); + } + }; - const { id, isFolder, isThirdPartyFolder } = item; + onMouseDown = (e) => { + const { + draggable, + setTooltipPosition, + setStartDrag, + isPrivacy, + isTrashFolder, + onSelectItem, + item, + setBufferSelection, + isActive, + } = this.props; - const notSelectable = e.target.classList.contains("not-selectable"); - const isFileName = e.target.classList.contains("item-file-name"); + const { id, isFolder, isThirdPartyFolder } = item; - if ( - isPrivacy || - isTrashFolder || - (!draggable && !isFileName && !isActive) - ) - return e; + const notSelectable = e.target.classList.contains("not-selectable"); + const isFileName = e.target.classList.contains("item-file-name"); - if ( - window.innerWidth < 1025 || - notSelectable || - isMobile || - isThirdPartyFolder - ) { - return e; - } + if ( + isPrivacy || + isTrashFolder || + (!draggable && !isFileName && !isActive) + ) + return e; - // if (!draggable) { - // id !== -1 && onSelectItem({ id, isFolder }); - // } + if ( + window.innerWidth < 1025 || + notSelectable || + isMobile || + isThirdPartyFolder + ) { + return e; + } - const mouseButton = e.which - ? e.which !== 1 - : e.button - ? e.button !== 0 - : false; - const label = e.currentTarget.getAttribute("label"); - if (mouseButton || e.currentTarget.tagName !== "DIV" || label) { - return e; - } - e.preventDefault(); - setTooltipPosition(e.pageX, e.pageY); - !isFileName && setStartDrag(true); - !isActive && setBufferSelection(null); - }; + // if (!draggable) { + // id !== -1 && onSelectItem({ id, isFolder }); + // } - onMarkAsRead = (id) => - this.props.markAsRead([], [`${id}`], this.props.item); + const mouseButton = e.which + ? e.which !== 1 + : e.button + ? e.button !== 0 + : false; + const label = e.currentTarget.getAttribute("label"); + if (mouseButton || e.currentTarget.tagName !== "DIV" || label) { + return e; + } - onMouseClick = (e) => { - const { viewAs, isItemsSelected } = this.props; + e.preventDefault(); + setTooltipPosition(e.pageX, e.pageY); + !isFileName && setStartDrag(true); + !isActive && setBufferSelection(null); + }; - if ( - e.target.closest(".checkbox") || - e.target.tagName === "INPUT" || - e.target.tagName === "SPAN" || - e.target.tagName === "A" || - e.target.closest(".expandButton") || - e.target.closest(".badges") || - e.button !== 0 /* || + onMarkAsRead = (id) => + this.props.markAsRead([], [`${id}`], this.props.item); + + onMouseClick = (e) => { + const { + viewAs, + isItemsSelected, + infoPanelIsVisible, + showInfoPanel, + } = this.props; + + if ( + e.target.closest(".checkbox") || + e.target.tagName === "INPUT" || + e.target.tagName === "SPAN" || + e.target.tagName === "A" || + e.target.closest(".expandButton") || + e.target.closest(".badges") || + e.button !== 0 /* || isItemsSelected */ - ) - return; + ) + return; - if (viewAs === "tile") { - if (e.target.closest(".edit-button") || e.target.tagName === "IMG") - return; - - if (e.detail === 1) this.fileContextClick(); - } else { - this.fileContextClick(); - } - }; - onFilesClick = (e) => { - const { - isDesktop, - //parentFolder, - setIsLoading, - fetchFiles, - isMediaOrImage, - canConvert, - canWebEdit, - canViewedDocs, - item, - isTrashFolder, - isPrivacy, - openDocEditor, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - setMediaViewerData, - setConvertItem, - setConvertDialogVisible, - setNewBadgeCount, - } = this.props; - const { - id, - viewUrl, - providerKey, - fileStatus, - encrypted, - isFolder, - } = item; - if (encrypted && isPrivacy) return checkProtocol(item.id, true); - - if (isTrashFolder) return; - if ((e && e.target.tagName === "INPUT") || e.target.closest(".badges")) - return; - - e.preventDefault(); - - if (isFolder) { - setIsLoading(true); - //addExpandedKeys(parentFolder + ""); - - fetchFiles(id, null, true, false) - .then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createNewExpandedKeys(pathParts); - setExpandedKeys(newExpandedKeys); - - setNewBadgeCount(item); - }) - .catch((err) => { - toastr.error(err); - setIsLoading(false); - }) - .finally(() => setIsLoading(false)); - } else { - if (canConvert) { - setConvertItem(item); - setConvertDialogVisible(true); - return; - } - - if (fileStatus === 2) this.onMarkAsRead(id); - - if (canWebEdit || canViewedDocs) { - let tab = - !isDesktop && !isFolder - ? window.open( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - "/doceditor" - ), - "_blank" + if (viewAs === "tile") { + if ( + e.target.closest(".edit-button") || + e.target.tagName === "IMG" ) - : null; + return; - return openDocEditor(id, providerKey, tab); + if (e.detail === 1) this.fileContextClick(); + } else { + this.fileContextClick(); + } + + if (!infoPanelIsVisible) showInfoPanel(); + }; + onFilesClick = (e) => { + const { + isDesktop, + //parentFolder, + setIsLoading, + fetchFiles, + isMediaOrImage, + canConvert, + canWebEdit, + canViewedDocs, + item, + isTrashFolder, + isPrivacy, + openDocEditor, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + setMediaViewerData, + setConvertItem, + setConvertDialogVisible, + setNewBadgeCount, + } = this.props; + const { + id, + viewUrl, + providerKey, + fileStatus, + encrypted, + isFolder, + } = item; + if (encrypted && isPrivacy) return checkProtocol(item.id, true); + + if (isTrashFolder) return; + if ( + (e && e.target.tagName === "INPUT") || + e.target.closest(".badges") + ) + return; + + e.preventDefault(); + + if (isFolder) { + setIsLoading(true); + //addExpandedKeys(parentFolder + ""); + + fetchFiles(id, null, true, false) + .then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createNewExpandedKeys( + pathParts + ); + setExpandedKeys(newExpandedKeys); + + setNewBadgeCount(item); + }) + .catch((err) => { + toastr.error(err); + setIsLoading(false); + }) + .finally(() => setIsLoading(false)); + } else { + if (canConvert) { + setConvertItem(item); + setConvertDialogVisible(true); + return; + } + + if (fileStatus === 2) this.onMarkAsRead(id); + + if (canWebEdit || canViewedDocs) { + let tab = + !isDesktop && !isFolder + ? window.open( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + "/doceditor" + ), + "_blank" + ) + : null; + + return openDocEditor(id, providerKey, tab); + } + + if (isMediaOrImage) { + setMediaViewerData({ visible: true, id }); + return; + } + + return window.open(viewUrl, "_self"); + } + }; + + render() { + const { + item, + isTrashFolder, + draggable, + allowShareIn, + isPrivacy, + actionType, + actionExtension, + actionId, + sectionWidth, + checked, + dragging, + isFolder, + isDesktop, + personal, + canWebEdit, + canViewedDocs, + } = this.props; + const { fileExst, access, id } = item; + + const isEdit = + actionType !== null && + actionId === id && + fileExst === actionExtension; + + const isDragging = + isFolder && access < 2 && !isTrashFolder && !isPrivacy; + + let className = isDragging ? " droppable" : ""; + if (draggable) className += " draggable"; + + let value = !item.isFolder ? `file_${id}` : `folder_${id}`; + value += draggable ? "_draggable" : ""; + + const isShareable = allowShareIn && item.canShare; + + const isMobileView = sectionWidth < 500; + + const displayShareButton = isMobileView + ? "26px" + : !isShareable + ? "38px" + : "96px"; + + const showShare = + !isShareable || + isEdit || + (isPrivacy && (!isDesktop || !fileExst)) || + (personal && !canWebEdit && !canViewedDocs) + ? false + : true; + + const checkedProps = isEdit || id <= 0 ? false : checked; + + return ( + + ); } + } - if (isMediaOrImage) { - setMediaViewerData({ visible: true, id }); - return; + return inject( + ( + { + auth, + filesActionsStore, + dialogsStore, + treeFoldersStore, + //selectedFolderStore, + filesStore, + uploadDataStore, + formatsStore, + mediaViewerDataStore, + infoPanelStore, + }, + { item, t, history } + ) => { + const { + selectRowAction, + onSelectItem, + markAsRead, + setNewBadgeCount, + } = filesActionsStore; + const { + setSharingPanelVisible, + setConvertDialogVisible, + setConvertItem, + } = dialogsStore; + const { + isPrivacyFolder, + isRecycleBinFolder, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + } = treeFoldersStore; + const { + dragging, + setDragging, + selection, + setTooltipPosition, + setStartDrag, + fileActionStore, + isFileSelected, + setIsLoading, + fetchFiles, + openDocEditor, + getFolderInfo, + viewAs, + bufferSelection, + setBufferSelection, + } = filesStore; + + const { startUpload } = uploadDataStore; + const { type, extension, id } = fileActionStore; + const { mediaViewersFormatsStore, docserviceStore } = formatsStore; + const { setMediaViewerData } = mediaViewerDataStore; + const { isVisible, setVisible } = infoPanelStore; + + const selectedItem = selection.find( + (x) => x.id === item.id && x.fileExst === item.fileExst + ); + + const draggable = + !isRecycleBinFolder && selectedItem && selectedItem.id !== id; + + const isFolder = selectedItem + ? false + : !item.isFolder + ? false + : true; + + const isMediaOrImage = mediaViewersFormatsStore.isMediaOrImage( + item.fileExst + ); + + const canWebEdit = docserviceStore.canWebEdit(item.fileExst); + const canConvert = docserviceStore.canConvert(item.fileExst); + const canViewedDocs = docserviceStore.canViewedDocs(item.fileExst); + + const isActive = + bufferSelection && + bufferSelection.id === item.id && + bufferSelection.fileExst === item.fileExst && + !selection.length; // need for select row item + + return { + t, + item, + selectRowAction, + onSelectItem, + setSharingPanelVisible, + isPrivacy: isPrivacyFolder, + dragging, + setDragging, + startUpload, + draggable, + setTooltipPosition, + setStartDrag, + history, + isFolder, + allowShareIn: filesStore.canShare, + actionType: type, + actionExtension: extension, + actionId: id, + checked: isFileSelected(item.id, item.parentId), + //parentFolder: selectedFolderStore.parentId, + setIsLoading, + fetchFiles, + isMediaOrImage, + canWebEdit, + canViewedDocs, + canConvert, + isTrashFolder: isRecycleBinFolder, + openDocEditor, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + setMediaViewerData, + getFolderInfo, + markAsRead, + viewAs, + setConvertItem, + setConvertDialogVisible, + isDesktop: auth.settingsStore.isDesktopClient, + personal: auth.settingsStore.personal, + isItemsSelected: selection.length > 0, + setNewBadgeCount, + isActive, + setBufferSelection, + bufferSelection, + isInfoPanelVisible: isVisible, + showInfoPanel: setVisible, + }; } - - return window.open(viewUrl, "_self"); - } - }; - - render() { - const { - item, - isTrashFolder, - draggable, - allowShareIn, - isPrivacy, - actionType, - actionExtension, - actionId, - sectionWidth, - checked, - dragging, - isFolder, - isDesktop, - personal, - canWebEdit, - canViewedDocs, - } = this.props; - const { fileExst, access, id } = item; - - const isEdit = - actionType !== null && actionId === id && fileExst === actionExtension; - - const isDragging = isFolder && access < 2 && !isTrashFolder && !isPrivacy; - - let className = isDragging ? " droppable" : ""; - if (draggable) className += " draggable"; - - let value = !item.isFolder ? `file_${id}` : `folder_${id}`; - value += draggable ? "_draggable" : ""; - - const isShareable = allowShareIn && item.canShare; - - const isMobileView = sectionWidth < 500; - - const displayShareButton = isMobileView - ? "26px" - : !isShareable - ? "38px" - : "96px"; - - const showShare = - !isShareable || - isEdit || - (isPrivacy && (!isDesktop || !fileExst)) || - (personal && !canWebEdit && !canViewedDocs) - ? false - : true; - - const checkedProps = isEdit || id <= 0 ? false : checked; - - return ( - - ); - } - } - - return inject( - ( - { - auth, - filesActionsStore, - dialogsStore, - treeFoldersStore, - //selectedFolderStore, - filesStore, - uploadDataStore, - formatsStore, - mediaViewerDataStore, - }, - { item, t, history } - ) => { - const { - selectRowAction, - onSelectItem, - markAsRead, - setNewBadgeCount, - } = filesActionsStore; - const { - setSharingPanelVisible, - setConvertDialogVisible, - setConvertItem, - } = dialogsStore; - const { - isPrivacyFolder, - isRecycleBinFolder, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - } = treeFoldersStore; - const { - dragging, - setDragging, - selection, - setTooltipPosition, - setStartDrag, - fileActionStore, - isFileSelected, - setIsLoading, - fetchFiles, - openDocEditor, - getFolderInfo, - viewAs, - bufferSelection, - setBufferSelection, - } = filesStore; - const { startUpload } = uploadDataStore; - const { type, extension, id } = fileActionStore; - const { mediaViewersFormatsStore, docserviceStore } = formatsStore; - const { setMediaViewerData } = mediaViewerDataStore; - - const selectedItem = selection.find( - (x) => x.id === item.id && x.fileExst === item.fileExst - ); - - const draggable = - !isRecycleBinFolder && selectedItem && selectedItem.id !== id; - - const isFolder = selectedItem ? false : !item.isFolder ? false : true; - - const isMediaOrImage = mediaViewersFormatsStore.isMediaOrImage( - item.fileExst - ); - - const canWebEdit = docserviceStore.canWebEdit(item.fileExst); - const canConvert = docserviceStore.canConvert(item.fileExst); - const canViewedDocs = docserviceStore.canViewedDocs(item.fileExst); - - const isActive = - bufferSelection && - bufferSelection.id === item.id && - bufferSelection.fileExst === item.fileExst && - !selection.length; // need for select row item - - return { - t, - item, - selectRowAction, - onSelectItem, - setSharingPanelVisible, - isPrivacy: isPrivacyFolder, - dragging, - setDragging, - startUpload, - draggable, - setTooltipPosition, - setStartDrag, - history, - isFolder, - allowShareIn: filesStore.canShare, - actionType: type, - actionExtension: extension, - actionId: id, - checked: isFileSelected(item.id, item.parentId), - //parentFolder: selectedFolderStore.parentId, - setIsLoading, - fetchFiles, - isMediaOrImage, - canWebEdit, - canViewedDocs, - canConvert, - isTrashFolder: isRecycleBinFolder, - openDocEditor, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - setMediaViewerData, - getFolderInfo, - markAsRead, - viewAs, - setConvertItem, - setConvertDialogVisible, - isDesktop: auth.settingsStore.isDesktopClient, - personal: auth.settingsStore.personal, - isItemsSelected: selection.length > 0, - setNewBadgeCount, - isActive, - setBufferSelection, - bufferSelection, - }; - } - )(observer(WithFileActions)); + )(observer(WithFileActions)); } diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index ea9983102d..f48ea7a365 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -1,12 +1,3 @@ -import { - StyledAccess, - StyledAccessUser, - StyledOpenSharingPanel, - StyledProperties, - StyledSubtitle, - StyledThumbnail, - StyledTitle, -} from "./styles/styles.js"; import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; import { FileType } from "@appserver/common/constants"; import Link from "@appserver/components/link"; @@ -17,6 +8,16 @@ import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; +import { + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, + StyledProperties, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./styles/styles.js"; + const SingleItem = (props) => { const { t, @@ -30,6 +31,7 @@ const SingleItem = (props) => { getShareUsers, } = props; + let updateSubscription = true; const [item, setItem] = useState({ id: "", isFolder: false, @@ -45,7 +47,6 @@ const SingleItem = (props) => { others: [], }, }); - const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); const updateItemsInfo = async (selectedItem) => { @@ -264,11 +265,12 @@ const SingleItem = (props) => { const access = await updateLoadedItemAccess(selectedItem); - setItem({ - ...displayedItem, - properties: properties, - access: access, - }); + if (updateSubscription) + setItem({ + ...displayedItem, + properties: properties, + access: access, + }); }; const showAllAccessUsers = () => { @@ -283,7 +285,9 @@ const SingleItem = (props) => { }; useEffect(() => { - if (selectedItem.id !== item.id) updateItemsInfo(selectedItem); + if (selectedItem.id !== item.id && updateSubscription) + updateItemsInfo(selectedItem); + return () => (updateSubscription = false); }, [selectedItem]); return ( diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 83b8da89a7..b4b14c73d2 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -19,15 +19,18 @@ const InfoPanelBodyContent = ({ setSharingPanelVisible, isRecycleBinFolder, }) => { + if (selectedItems.length) { + } + return ( - {selectedItems.length === 0 ? ( + {selectedItems.length === 0 && !bufferSelectedItem ? (

{t("NoItemsSelected")}

- ) : selectedItems.length === 1 ? ( + ) : selectedItems.length === 1 || bufferSelectedItem ? ( { - const { visible, setMediaViewerData, playlist } = this.mediaViewerDataStore; - if (visible && playlist.length === 1) { - setMediaViewerData({ visible: false, id: null }); - } - }; - - updateCurrentFolder = (selectionLength) => { - const { - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - const { - filter, - fetchFiles, - isEmptyLastPageAfterOperation, - resetFilterPage, - } = this.filesStore; - - let newFilter; - - if (selectionLength && isEmptyLastPageAfterOperation(selectionLength)) { - newFilter = resetFilterPage(); - } - - let updatedFolder = this.selectedFolderStore.id; - - if (this.dialogsStore.isFolderActions) { - updatedFolder = this.selectedFolderStore.parentId; - } - - fetchFiles( - updatedFolder, - newFilter ? newFilter : filter, - true, - true - ).finally(() => { - this.dialogsStore.setIsFolderActions(false); - return setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - }); - }; - - deleteAction = async ( - translations, - newSelection = null, - withoutDialog = false - ) => { - const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore; - - const selection = newSelection ? newSelection : this.filesStore.selection; - - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); - - const deleteAfter = false; //Delete after finished TODO: get from settings - const immediately = isRecycleBinFolder || isPrivacyFolder ? true : false; //Don't move to the Recycle Bin - - let folderIds = []; - let fileIds = []; - - let i = 0; - while (selection.length !== i) { - if (selection[i].fileExst || selection[i].contentLength) { - fileIds.push(selection[i].id); - } else { - folderIds.push(selection[i].id); - } - i++; - } - - if (this.dialogsStore.isFolderActions && withoutDialog) { - folderIds = []; - fileIds = []; - - folderIds.push(selection[0]); - } - - if (folderIds.length || fileIds.length) { - this.isMediaOpen(); - - try { - await removeFiles(folderIds, fileIds, deleteAfter, immediately).then( - async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "trash", - label: translations.deleteOperation, - }; - await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder(selection.length); - if (isRecycleBinFolder) { - return toastr.success(translations.deleteFromTrash); - } - - if (selection.length > 1) { - return toastr.success(translations.deleteSelectedElem); - } - if (selection[0].fileExst) { - return toastr.success(translations.FileRemoved); - } - return toastr.success(translations.FolderRemoved); - } - ); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - } - }; - - emptyTrash = async (translations) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); - - try { - await emptyTrash().then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "trash", - label: translations.deleteOperation, - }; - await this.uploadDataStore.loopFilesOperations(data, pbData); - toastr.success(translations.successOperation); - this.updateCurrentFolder(); - }); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - }; - - downloadFiles = async (fileConvertIds, folderIds, label) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "file", - visible: true, - percent: 0, - label, - alert: false, - }); - - try { - await downloadFiles(fileConvertIds, folderIds).then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "file", - label, - }; - - const item = - data?.finished && data?.url - ? data - : await this.uploadDataStore.loopFilesOperations(data, pbData); - - if (item.url) { - window.location.href = item.url; - } else { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - } - - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - }); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - }; - - downloadAction = (label, folderId) => { - const { bufferSelection } = this.filesStore; - - const selection = this.filesStore.selection.length - ? this.filesStore.selection - : [bufferSelection]; - - let fileIds = []; - let folderIds = []; - const items = []; - - if (selection.length === 1 && selection[0].fileExst && !folderId) { - window.open(selection[0].viewUrl, "_self"); - return Promise.resolve(); - } - - for (let item of selection) { - if (item.fileExst) { - fileIds.push(item.id); - items.push({ id: item.id, fileExst: item.fileExst }); - } else { - folderIds.push(item.id); - items.push({ id: item.id }); - } - } - - if (this.dialogsStore.isFolderActions) { - fileIds = []; - folderIds = []; - - folderIds.push(bufferSelection); - this.dialogsStore.setIsFolderActions(false); - } - - return this.downloadFiles(fileIds, folderIds, label); - }; - - editCompleteAction = async (id, selectedItem, isCancelled = false) => { - const { - filter, - folders, - files, - fileActionStore, - fetchFiles, - setIsLoading, - } = this.filesStore; - const { type, setAction } = fileActionStore; - 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); - } - } - setAction({ - type: null, - id: null, - extension: null, - title: "", - templateId: null, - }); - setIsLoading(false); - type === FileAction.Rename && - this.onSelectItem({ - id: selectedItem.id, - isFolder: selectedItem.isFolder, - }); - } - }; - - onSelectItem = ({ id, isFolder }) => { - const { setBufferSelection, selected, setSelected } = this.filesStore; - /* selected === "close" && */ setSelected("none"); - - if (!id) return; - - const item = this.filesStore[isFolder ? "folders" : "files"].find( - (elm) => elm.id === id - ); - - if (item) { - item.isFolder = isFolder; - setBufferSelection(item); - } - }; - - deleteItemAction = async (itemId, translations, isFile, isThirdParty) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - if ( - this.settingsStore.confirmDelete || - this.treeFoldersStore.isPrivacyFolder || - isThirdParty + constructor( + authStore, + uploadDataStore, + treeFoldersStore, + filesStore, + selectedFolderStore, + settingsStore, + dialogsStore, + mediaViewerDataStore, + infoPanelStore ) { - this.dialogsStore.setDeleteDialogVisible(true); - } else { - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); + makeAutoObservable(this); + this.authStore = authStore; + this.uploadDataStore = uploadDataStore; + this.treeFoldersStore = treeFoldersStore; + this.filesStore = filesStore; + this.selectedFolderStore = selectedFolderStore; + this.settingsStore = settingsStore; + this.dialogsStore = dialogsStore; + this.infoPanelStore = infoPanelStore; + this.mediaViewerDataStore = mediaViewerDataStore; + } - try { - await this.deleteItemOperation(isFile, itemId, translations); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, + isMediaOpen = () => { + const { + visible, + setMediaViewerData, + playlist, + } = this.mediaViewerDataStore; + if (visible && playlist.length === 1) { + setMediaViewerData({ visible: false, id: null }); + } + }; + + updateCurrentFolder = (selectionLength) => { + const { + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + const { + filter, + fetchFiles, + isEmptyLastPageAfterOperation, + resetFilterPage, + } = this.filesStore; + + let newFilter; + + if (selectionLength && isEmptyLastPageAfterOperation(selectionLength)) { + newFilter = resetFilterPage(); + } + + let updatedFolder = this.selectedFolderStore.id; + + if (this.dialogsStore.isFolderActions) { + updatedFolder = this.selectedFolderStore.parentId; + } + + fetchFiles( + updatedFolder, + newFilter ? newFilter : filter, + true, + true + ).finally(() => { + this.dialogsStore.setIsFolderActions(false); + return setTimeout(() => clearSecondaryProgressData(), TIMEOUT); }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - } - }; - - deleteItemOperation = (isFile, itemId, translations) => { - const pbData = { - icon: "trash", - label: translations.deleteOperation, }; - const selectionFilesLength = 1; + deleteAction = async ( + translations, + newSelection = null, + withoutDialog = false + ) => { + const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore; - if (isFile) { - this.isMediaOpen(); - return deleteFile(itemId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder(selectionFilesLength); - }) - .then(() => toastr.success(translations.successRemoveFile)); - } else { - return deleteFolder(itemId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations(data, pbData); - this.updateCurrentFolder(selectionFilesLength); - }) - .then(() => toastr.success(translations.successRemoveFolder)); - } - }; + const selection = newSelection + ? newSelection + : this.filesStore.selection; - unsubscribeAction = async (fileIds, folderIds) => { - const { setUnsubscribe } = this.dialogsStore; - const { filter, fetchFiles } = this.filesStore; + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; - return removeShareFiles(fileIds, folderIds) - .then(() => setUnsubscribe(false)) - .then(() => fetchFiles(this.selectedFolderStore.id, filter, true, true)); - }; + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); - lockFileAction = (id, locked) => { - const { setFile } = this.filesStore; - return lockFile(id, locked).then((res) => setFile(res)); - }; + const deleteAfter = false; //Delete after finished TODO: get from settings + const immediately = + isRecycleBinFolder || isPrivacyFolder ? true : false; //Don't move to the Recycle Bin - finalizeVersionAction = (id) => { - const { fetchFiles, setIsLoading } = this.filesStore; + let folderIds = []; + let fileIds = []; - setIsLoading(true); + let i = 0; + while (selection.length !== i) { + if (selection[i].fileExst || selection[i].contentLength) { + fileIds.push(selection[i].id); + } else { + folderIds.push(selection[i].id); + } + i++; + } - return finalizeVersion(id, 0, false) - .then(() => { - fetchFiles(this.selectedFolderStore.id, this.filesStore.filter); - }) - .finally(() => setIsLoading(false)); - }; + if (this.dialogsStore.isFolderActions && withoutDialog) { + folderIds = []; + fileIds = []; - duplicateAction = (item, label) => { - const { - setSecondaryProgressBarData, - } = this.uploadDataStore.secondaryProgressDataStore; + folderIds.push(selection[0]); + } - const folderIds = []; - const fileIds = []; - item.fileExst ? fileIds.push(item.id) : folderIds.push(item.id); - const conflictResolveType = ConflictResolveType.Duplicate; - const deleteAfter = false; //TODO: get from settings + if (folderIds.length || fileIds.length) { + this.isMediaOpen(); - setSecondaryProgressBarData({ - icon: "duplicate", - visible: true, - percent: 0, - label, - alert: false, - }); + try { + await removeFiles( + folderIds, + fileIds, + deleteAfter, + immediately + ).then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { + icon: "trash", + label: translations.deleteOperation, + }; + await this.uploadDataStore.loopFilesOperations( + data, + pbData + ); + this.updateCurrentFolder(selection.length); + if (isRecycleBinFolder) { + return toastr.success(translations.deleteFromTrash); + } - return this.uploadDataStore.copyToAction( - this.selectedFolderStore.id, - folderIds, - fileIds, - conflictResolveType, - deleteAfter - ); - }; - - setFavoriteAction = (action, id) => { - const { - markItemAsFavorite, - removeItemFromFavorite, - fetchFavoritesFolder, - getFileInfo, - setSelected, - } = this.filesStore; - - const items = Array.isArray(id) ? id : [id]; - - //let data = selection.map(item => item.id) - switch (action) { - case "mark": - return markItemAsFavorite([id]).then(() => getFileInfo(id)); - - case "remove": - return removeItemFromFavorite(items) - .then(() => { - return this.treeFoldersStore.isFavoritesFolder - ? fetchFavoritesFolder(this.selectedFolderStore.id) - : getFileInfo(id); - }) - .then(() => setSelected("close")); - default: - return; - } - }; - - selectRowAction = (checked, file) => { - const { - selected, - setSelected, - selectFile, - deselectFile, - setBufferSelection, - } = this.filesStore; - //selected === "close" && setSelected("none"); - setBufferSelection(null); - if (checked) { - selectFile(file); - } else { - deselectFile(file); - } - }; - - openLocationAction = (locationId, isFolder) => { - const { createNewExpandedKeys, setExpandedKeys } = this.treeFoldersStore; - - const locationFilter = isFolder ? this.filesStore.filter : null; - this.filesStore.setBufferSelection(null); - return this.filesStore - .fetchFiles(locationId, locationFilter) - .then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createNewExpandedKeys(pathParts); - setExpandedKeys(newExpandedKeys); - }); - /*.then(() => - //isFolder ? null : this.selectRowAction(!checked, item) - );*/ - }; - - setThirdpartyInfo = (providerKey) => { - const { setConnectDialogVisible, setConnectItem } = this.dialogsStore; - const { providers, capabilities } = this.settingsStore.thirdPartyStore; - const provider = providers.find((x) => x.provider_key === providerKey); - const capabilityItem = capabilities.find((x) => x[0] === providerKey); - const capability = { - title: capabilityItem ? capabilityItem[0] : provider.customer_title, - link: capabilityItem ? capabilityItem[1] : " ", + if (selection.length > 1) { + return toastr.success(translations.deleteSelectedElem); + } + if (selection[0].fileExst) { + return toastr.success(translations.FileRemoved); + } + return toastr.success(translations.FolderRemoved); + }); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + } }; - setConnectDialogVisible(true); - setConnectItem({ ...provider, ...capability }); - }; + emptyTrash = async (translations) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; - setNewBadgeCount = (item) => { - const { getRootFolder, updateRootBadge } = this.treeFoldersStore; - const { updateFileBadge, updateFolderBadge } = this.filesStore; - const { rootFolderType, fileExst, id } = item; + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); - const count = item.new ? item.new : 1; - const rootFolder = getRootFolder(rootFolderType); - updateRootBadge(rootFolder.id, count); - - if (fileExst) updateFileBadge(id); - else updateFolderBadge(id, item.new); - }; - - markAsRead = (folderIds, fileId, item) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "file", - label: "", //TODO: add translation if need "MarkAsRead": "Mark all as read", - percent: 0, - visible: true, - }); - - return markAsRead(folderIds, fileId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { icon: "file" }; - await this.uploadDataStore.loopFilesOperations(data, pbData); - }) - .then(() => item && this.setNewBadgeCount(item)) - .catch((err) => toastr.error(err)) - .finally(() => setTimeout(() => clearSecondaryProgressData(), TIMEOUT)); - }; - - moveDragItems = (destFolderId, folderTitle, translations) => { - const folderIds = []; - const fileIds = []; - const deleteAfter = false; - - const { selection } = this.filesStore; - const { isRootFolder } = this.selectedFolderStore; - const { - isShareFolder, - isCommonFolder, - isFavoritesFolder, - isRecentFolder, - } = this.treeFoldersStore; - const isCopy = - isShareFolder || - isFavoritesFolder || - isRecentFolder || - (!this.authStore.isAdmin && isCommonFolder); - - const operationData = { - destFolderId, - folderIds, - fileIds, - deleteAfter, - translations, - folderTitle, - isCopy, + try { + await emptyTrash().then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { + icon: "trash", + label: translations.deleteOperation, + }; + await this.uploadDataStore.loopFilesOperations(data, pbData); + toastr.success(translations.successOperation); + this.updateCurrentFolder(); + }); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } }; - const { - setThirdPartyMoveDialogVisible, - setDestFolderId, - } = this.dialogsStore; + downloadFiles = async (fileConvertIds, folderIds, label) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; - for (let item of selection) { - if (item.providerKey && !isRootFolder) { - setDestFolderId(destFolderId); - return setThirdPartyMoveDialogVisible(true); - } + setSecondaryProgressBarData({ + icon: "file", + visible: true, + percent: 0, + label, + alert: false, + }); - if (!item.isFolder) { - fileIds.push(item.id); - } else { - if (item.providerKey && isRootFolder) continue; - folderIds.push(item.id); - } - } - - if (!folderIds.length && !fileIds.length) return; - this.checkOperationConflict(operationData); - }; - - checkOperationConflict = async (operationData) => { - const { destFolderId, folderIds, fileIds } = operationData; - const { - setConflictResolveDialogData, - setConflictResolveDialogVisible, - setConflictResolveDialogItems, - } = this.dialogsStore; - const { setBufferSelection } = this.filesStore; - - let conflicts; - - try { - conflicts = await checkFileConflicts(destFolderId, folderIds, fileIds); - } catch (err) { - setBufferSelection(null); - return toastr.error(err.message ? err.message : err); - } - - if (conflicts.length) { - setConflictResolveDialogItems(conflicts); - setConflictResolveDialogData(operationData); - setConflictResolveDialogVisible(true); - } else { - try { - await this.uploadDataStore.itemOperationToFolder(operationData); - } catch (err) { - setBufferSelection(null); - return toastr.error(err.message ? err.message : err); - } - } - - setBufferSelection(null); - }; - - isAvailableOption = (option) => { - const { - isFavoritesFolder, - isRecentFolder, - isCommonFolder, - } = this.treeFoldersStore; - const { - isAccessedSelected, - canConvertSelected, - isThirdPartyRootSelection, - hasSelection, - } = this.filesStore; - const { personal } = this.authStore.settingsStore; - const { userAccess } = this.filesStore; - - switch (option) { - case "share": - return isAccessedSelected && !personal; //isFavoritesFolder ||isRecentFolder - case "copy": - case "download": - return hasSelection; - case "downloadAs": - return canConvertSelected; - case "moveTo": - return ( - !isThirdPartyRootSelection && - hasSelection && - isAccessedSelected && - !isRecentFolder && - !isFavoritesFolder - ); - - case "delete": - const deleteCondition = - !isThirdPartyRootSelection && hasSelection && isAccessedSelected; - - return isCommonFolder ? userAccess && deleteCondition : deleteCondition; - } - }; - - convertToArray = (itemsCollection) => { - const result = Array.from(itemsCollection.values()).filter((item) => { - return item != null; - }); - - itemsCollection.clear(); - - return result; - }; - - getOption = (option, t) => { - const { - setSharingPanelVisible, - setDownloadDialogVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - } = this.dialogsStore; - - switch (option) { - case "share": - if (!this.isAvailableOption("share")) return null; - else - return { - label: t("Share"), - onClick: () => setSharingPanelVisible(true), - iconUrl: "/static/images/share.react.svg", - title: t("Translations:ButtonShareAccess"), - }; - - case "copy": - if (!this.isAvailableOption("copy")) return null; - else - return { - label: t("Translations:Copy"), - onClick: () => setCopyPanelVisible(true), - iconUrl: "/static/images/copyTo.react.svg", - }; - - case "download": - if (!this.isAvailableOption("download")) return null; - else - return { - label: t("Common:Download"), - onClick: () => - this.downloadAction( - t("Translations:ArchivingData") - ).catch((err) => toastr.error(err)), - iconUrl: "/static/images/download.react.svg", - }; - - case "downloadAs": - if (!this.isAvailableOption("downloadAs")) return null; - else - return { - label: t("Translations:DownloadAs"), - onClick: () => setDownloadDialogVisible(true), - iconUrl: "/static/images/downloadAs.react.svg", - }; - - case "moveTo": - if (!this.isAvailableOption("moveTo")) return null; - else - return { - label: t("MoveTo"), - onClick: () => setMoveToPanelVisible(true), - iconUrl: "/static/images/move.react.svg", - }; - - case "delete": - if (!this.isAvailableOption("delete")) return null; - else - return { - label: t("Common:Delete"), - onClick: () => { - if (this.settingsStore.confirmDelete) { - setDeleteDialogVisible(true); - } else { - const translations = { - deleteOperation: t("Translations:DeleteOperation"), - deleteFromTrash: t("Translations:DeleteFromTrash"), - deleteSelectedElem: t("Translations:DeleteSelectedElem"), - FileRemoved: t("Home:FileRemoved"), - FolderRemoved: t("Home:FolderRemoved"), + try { + await downloadFiles(fileConvertIds, folderIds).then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { + icon: "file", + label, }; - this.deleteAction(translations).catch((err) => - toastr.error(err) + const item = + data?.finished && data?.url + ? data + : await this.uploadDataStore.loopFilesOperations( + data, + pbData + ); + + if (item.url) { + window.location.href = item.url; + } else { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + } + + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + }); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + }; + + downloadAction = (label, folderId) => { + const { bufferSelection } = this.filesStore; + + const selection = this.filesStore.selection.length + ? this.filesStore.selection + : [bufferSelection]; + + let fileIds = []; + let folderIds = []; + const items = []; + + if (selection.length === 1 && selection[0].fileExst && !folderId) { + window.open(selection[0].viewUrl, "_self"); + return Promise.resolve(); + } + + for (let item of selection) { + if (item.fileExst) { + fileIds.push(item.id); + items.push({ id: item.id, fileExst: item.fileExst }); + } else { + folderIds.push(item.id); + items.push({ id: item.id }); + } + } + + if (this.dialogsStore.isFolderActions) { + fileIds = []; + folderIds = []; + + folderIds.push(bufferSelection); + this.dialogsStore.setIsFolderActions(false); + } + + return this.downloadFiles(fileIds, folderIds, label); + }; + + editCompleteAction = async (id, selectedItem, isCancelled = false) => { + const { + filter, + folders, + files, + fileActionStore, + fetchFiles, + setIsLoading, + } = this.filesStore; + const { type, setAction } = fileActionStore; + 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 ); - } - }, - iconUrl: "/static/images/delete.react.svg", - }; - } - }; + 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); + } + } + setAction({ + type: null, + id: null, + extension: null, + title: "", + templateId: null, + }); + setIsLoading(false); + type === FileAction.Rename && + this.onSelectItem({ + id: selectedItem.id, + isFolder: selectedItem.isFolder, + }); + } + }; - getAnotherFolderOptions = (itemsCollection, t) => { - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const moveTo = this.getOption("moveTo", t); - const copy = this.getOption("copy", t); - const deleteOption = this.getOption("delete", t); + onSelectItem = ({ id, isFolder }) => { + const { setBufferSelection, selected, setSelected } = this.filesStore; + /* selected === "close" && */ setSelected("none"); - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("moveTo", moveTo) - .set("copy", copy) - .set("delete", deleteOption); + if (!id) return; - return this.convertToArray(itemsCollection); - }; + const item = this.filesStore[isFolder ? "folders" : "files"].find( + (elm) => elm.id === id + ); - getRecentFolderOptions = (itemsCollection, t) => { - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); + if (item) { + item.isFolder = isFolder; + setBufferSelection(item); + } + }; - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy); - return this.convertToArray(itemsCollection); - }; + deleteItemAction = async (itemId, translations, isFile, isThirdParty) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + if ( + this.settingsStore.confirmDelete || + this.treeFoldersStore.isPrivacyFolder || + isThirdParty + ) { + this.dialogsStore.setDeleteDialogVisible(true); + } else { + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); - getShareFolderOptions = (itemsCollection, t) => { - const { setDeleteDialogVisible, setUnsubscribe } = this.dialogsStore; + try { + await this.deleteItemOperation(isFile, itemId, translations); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + } + }; - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); + deleteItemOperation = (isFile, itemId, translations) => { + const pbData = { + icon: "trash", + label: translations.deleteOperation, + }; - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy) - .set("delete", { - label: t("RemoveFromList"), - onClick: () => { - setUnsubscribe(true); - setDeleteDialogVisible(true); - }, - }); - return this.convertToArray(itemsCollection); - }; + const selectionFilesLength = 1; - getPrivacyFolderOption = (itemsCollection, t) => { - const moveTo = this.getOption("moveTo", t); - const deleteOption = this.getOption("delete", t); - const download = this.getOption("download", t); + if (isFile) { + this.isMediaOpen(); + return deleteFile(itemId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations( + data, + pbData + ); + this.updateCurrentFolder(selectionFilesLength); + }) + .then(() => toastr.success(translations.successRemoveFile)); + } else { + return deleteFolder(itemId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations( + data, + pbData + ); + this.updateCurrentFolder(selectionFilesLength); + }) + .then(() => toastr.success(translations.successRemoveFolder)); + } + }; - itemsCollection - .set("download", download) - .set("moveTo", moveTo) + unsubscribeAction = async (fileIds, folderIds) => { + const { setUnsubscribe } = this.dialogsStore; + const { filter, fetchFiles } = this.filesStore; - .set("delete", deleteOption); - return this.convertToArray(itemsCollection); - }; + return removeShareFiles(fileIds, folderIds) + .then(() => setUnsubscribe(false)) + .then(() => + fetchFiles(this.selectedFolderStore.id, filter, true, true) + ); + }; - getFavoritesFolderOptions = (itemsCollection, t) => { - const { selection } = this.filesStore; + lockFileAction = (id, locked) => { + const { setFile } = this.filesStore; + return lockFile(id, locked).then((res) => setFile(res)); + }; - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); + finalizeVersionAction = (id) => { + const { fetchFiles, setIsLoading } = this.filesStore; - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy) - .set("delete", { - label: t("Common:Delete"), - alt: t("RemoveFromFavorites"), - onClick: () => { - const items = selection.map((item) => item.id); - this.setFavoriteAction("remove", items) - .then(() => toastr.success(t("RemovedFromFavorites"))) - .catch((err) => toastr.error(err)); - }, - }); - return this.convertToArray(itemsCollection); - }; + setIsLoading(true); - getRecycleBinFolderOptions = (itemsCollection, t) => { - const { - setEmptyTrashDialogVisible, - setMoveToPanelVisible, - } = this.dialogsStore; + return finalizeVersion(id, 0, false) + .then(() => { + fetchFiles(this.selectedFolderStore.id, this.filesStore.filter); + }) + .finally(() => setIsLoading(false)); + }; - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const deleteOption = this.getOption("delete", t); + duplicateAction = (item, label) => { + const { + setSecondaryProgressBarData, + } = this.uploadDataStore.secondaryProgressDataStore; - itemsCollection - .set("download", download) - .set("downloadAs", downloadAs) - .set("restore", { - label: t("Translations:Restore"), - onClick: () => setMoveToPanelVisible(true), - iconUrl: "/static/images/move.react.svg", - }) - .set("delete", deleteOption); - return this.convertToArray(itemsCollection); - }; - getHeaderMenu = (t) => { - const { - isFavoritesFolder, - isRecentFolder, - isRecycleBinFolder, - isPrivacyFolder, - isShareFolder, - } = this.treeFoldersStore; + const folderIds = []; + const fileIds = []; + item.fileExst ? fileIds.push(item.id) : folderIds.push(item.id); + const conflictResolveType = ConflictResolveType.Duplicate; + const deleteAfter = false; //TODO: get from settings - let itemsCollection = new Map(); + setSecondaryProgressBarData({ + icon: "duplicate", + visible: true, + percent: 0, + label, + alert: false, + }); - if (isRecycleBinFolder) - return this.getRecycleBinFolderOptions(itemsCollection, t); + return this.uploadDataStore.copyToAction( + this.selectedFolderStore.id, + folderIds, + fileIds, + conflictResolveType, + deleteAfter + ); + }; - if (isFavoritesFolder) - return this.getFavoritesFolderOptions(itemsCollection, t); + setFavoriteAction = (action, id) => { + const { + markItemAsFavorite, + removeItemFromFavorite, + fetchFavoritesFolder, + getFileInfo, + setSelected, + } = this.filesStore; - if (isPrivacyFolder) return this.getPrivacyFolderOption(itemsCollection, t); + const items = Array.isArray(id) ? id : [id]; - if (isShareFolder) return this.getShareFolderOptions(itemsCollection, t); + //let data = selection.map(item => item.id) + switch (action) { + case "mark": + return markItemAsFavorite([id]).then(() => getFileInfo(id)); - if (isRecentFolder) return this.getRecentFolderOptions(itemsCollection, t); + case "remove": + return removeItemFromFavorite(items) + .then(() => { + return this.treeFoldersStore.isFavoritesFolder + ? fetchFavoritesFolder(this.selectedFolderStore.id) + : getFileInfo(id); + }) + .then(() => setSelected("close")); + default: + return; + } + }; - return this.getAnotherFolderOptions(itemsCollection, t); - }; + selectRowAction = (checked, file) => { + const { + selected, + setSelected, + selectFile, + deselectFile, + setBufferSelection, + } = this.filesStore; + //selected === "close" && setSelected("none"); + setBufferSelection(null); + if (checked) { + selectFile(file); + } else { + deselectFile(file); + } + }; + + openLocationAction = (locationId, isFolder) => { + const { + createNewExpandedKeys, + setExpandedKeys, + } = this.treeFoldersStore; + + const locationFilter = isFolder ? this.filesStore.filter : null; + this.filesStore.setBufferSelection(null); + return this.filesStore + .fetchFiles(locationId, locationFilter) + .then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createNewExpandedKeys(pathParts); + setExpandedKeys(newExpandedKeys); + }); + /*.then(() => + //isFolder ? null : this.selectRowAction(!checked, item) + );*/ + }; + + setThirdpartyInfo = (providerKey) => { + const { setConnectDialogVisible, setConnectItem } = this.dialogsStore; + const { providers, capabilities } = this.settingsStore.thirdPartyStore; + const provider = providers.find((x) => x.provider_key === providerKey); + const capabilityItem = capabilities.find((x) => x[0] === providerKey); + const capability = { + title: capabilityItem ? capabilityItem[0] : provider.customer_title, + link: capabilityItem ? capabilityItem[1] : " ", + }; + + setConnectDialogVisible(true); + setConnectItem({ ...provider, ...capability }); + }; + + setNewBadgeCount = (item) => { + const { getRootFolder, updateRootBadge } = this.treeFoldersStore; + const { updateFileBadge, updateFolderBadge } = this.filesStore; + const { rootFolderType, fileExst, id } = item; + + const count = item.new ? item.new : 1; + const rootFolder = getRootFolder(rootFolderType); + updateRootBadge(rootFolder.id, count); + + if (fileExst) updateFileBadge(id); + else updateFolderBadge(id, item.new); + }; + + markAsRead = (folderIds, fileId, item) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + setSecondaryProgressBarData({ + icon: "file", + label: "", //TODO: add translation if need "MarkAsRead": "Mark all as read", + percent: 0, + visible: true, + }); + + return markAsRead(folderIds, fileId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { icon: "file" }; + await this.uploadDataStore.loopFilesOperations(data, pbData); + }) + .then(() => item && this.setNewBadgeCount(item)) + .catch((err) => toastr.error(err)) + .finally(() => + setTimeout(() => clearSecondaryProgressData(), TIMEOUT) + ); + }; + + moveDragItems = (destFolderId, folderTitle, translations) => { + const folderIds = []; + const fileIds = []; + const deleteAfter = false; + + const { selection } = this.filesStore; + const { isRootFolder } = this.selectedFolderStore; + const { + isShareFolder, + isCommonFolder, + isFavoritesFolder, + isRecentFolder, + } = this.treeFoldersStore; + const isCopy = + isShareFolder || + isFavoritesFolder || + isRecentFolder || + (!this.authStore.isAdmin && isCommonFolder); + + const operationData = { + destFolderId, + folderIds, + fileIds, + deleteAfter, + translations, + folderTitle, + isCopy, + }; + + const { + setThirdPartyMoveDialogVisible, + setDestFolderId, + } = this.dialogsStore; + + for (let item of selection) { + if (item.providerKey && !isRootFolder) { + setDestFolderId(destFolderId); + return setThirdPartyMoveDialogVisible(true); + } + + if (!item.isFolder) { + fileIds.push(item.id); + } else { + if (item.providerKey && isRootFolder) continue; + folderIds.push(item.id); + } + } + + if (!folderIds.length && !fileIds.length) return; + this.checkOperationConflict(operationData); + }; + + checkOperationConflict = async (operationData) => { + const { destFolderId, folderIds, fileIds } = operationData; + const { + setConflictResolveDialogData, + setConflictResolveDialogVisible, + setConflictResolveDialogItems, + } = this.dialogsStore; + const { setBufferSelection } = this.filesStore; + + let conflicts; + + try { + conflicts = await checkFileConflicts( + destFolderId, + folderIds, + fileIds + ); + } catch (err) { + setBufferSelection(null); + return toastr.error(err.message ? err.message : err); + } + + if (conflicts.length) { + setConflictResolveDialogItems(conflicts); + setConflictResolveDialogData(operationData); + setConflictResolveDialogVisible(true); + } else { + try { + await this.uploadDataStore.itemOperationToFolder(operationData); + } catch (err) { + setBufferSelection(null); + return toastr.error(err.message ? err.message : err); + } + } + + setBufferSelection(null); + }; + + isAvailableOption = (option) => { + const { + isFavoritesFolder, + isRecentFolder, + isCommonFolder, + } = this.treeFoldersStore; + const { + isAccessedSelected, + canConvertSelected, + isThirdPartyRootSelection, + hasSelection, + } = this.filesStore; + const { personal } = this.authStore.settingsStore; + const { userAccess } = this.filesStore; + + switch (option) { + case "share": + return isAccessedSelected && !personal; //isFavoritesFolder ||isRecentFolder + case "showInfo": + case "copy": + case "download": + return hasSelection; + case "downloadAs": + return canConvertSelected; + case "moveTo": + return ( + !isThirdPartyRootSelection && + hasSelection && + isAccessedSelected && + !isRecentFolder && + !isFavoritesFolder + ); + + case "delete": + const deleteCondition = + !isThirdPartyRootSelection && + hasSelection && + isAccessedSelected; + + return isCommonFolder + ? userAccess && deleteCondition + : deleteCondition; + } + }; + + convertToArray = (itemsCollection) => { + const result = Array.from(itemsCollection.values()).filter((item) => { + return item != null; + }); + + itemsCollection.clear(); + + return result; + }; + + getOption = (option, t) => { + const { + setSharingPanelVisible, + setDownloadDialogVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + } = this.dialogsStore; + + const { toggleIsVisible } = this.infoPanelStore; + + switch (option) { + case "share": + if (!this.isAvailableOption("share")) return null; + else + return { + label: t("Share"), + onClick: () => setSharingPanelVisible(true), + iconUrl: "/static/images/share.react.svg", + title: t("Translations:ButtonShareAccess"), + }; + + case "copy": + if (!this.isAvailableOption("copy")) return null; + else + return { + label: t("Translations:Copy"), + onClick: () => setCopyPanelVisible(true), + iconUrl: "/static/images/copyTo.react.svg", + }; + + case "download": + if (!this.isAvailableOption("download")) return null; + else + return { + label: t("Common:Download"), + onClick: () => + this.downloadAction( + t("Translations:ArchivingData") + ).catch((err) => toastr.error(err)), + iconUrl: "/static/images/download.react.svg", + }; + + case "downloadAs": + if (!this.isAvailableOption("downloadAs")) return null; + else + return { + label: t("Translations:DownloadAs"), + onClick: () => setDownloadDialogVisible(true), + iconUrl: "/static/images/downloadAs.react.svg", + }; + + case "moveTo": + if (!this.isAvailableOption("moveTo")) return null; + else + return { + label: t("MoveTo"), + onClick: () => setMoveToPanelVisible(true), + iconUrl: "/static/images/move.react.svg", + }; + + case "showInfo": + if (!this.isAvailableOption("showInfo")) return null; + else + return { + label: t("InfoPanel:Info"), + onClick: () => toggleIsVisible(), + iconUrl: "/static/images/info.outline.react.svg", + }; + + case "delete": + if (!this.isAvailableOption("delete")) return null; + else + return { + label: t("Common:Delete"), + onClick: () => { + if (this.settingsStore.confirmDelete) { + setDeleteDialogVisible(true); + } else { + const translations = { + deleteOperation: t( + "Translations:DeleteOperation" + ), + deleteFromTrash: t( + "Translations:DeleteFromTrash" + ), + deleteSelectedElem: t( + "Translations:DeleteSelectedElem" + ), + FileRemoved: t("Home:FileRemoved"), + FolderRemoved: t("Home:FolderRemoved"), + }; + + this.deleteAction(translations).catch((err) => + toastr.error(err) + ); + } + }, + iconUrl: "/static/images/delete.react.svg", + }; + } + }; + + getAnotherFolderOptions = (itemsCollection, t) => { + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const moveTo = this.getOption("moveTo", t); + const copy = this.getOption("copy", t); + const deleteOption = this.getOption("delete", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("moveTo", moveTo) + .set("copy", copy) + .set("delete", deleteOption) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getRecentFolderOptions = (itemsCollection, t) => { + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getShareFolderOptions = (itemsCollection, t) => { + const { setDeleteDialogVisible, setUnsubscribe } = this.dialogsStore; + + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("delete", { + label: t("RemoveFromList"), + onClick: () => { + setUnsubscribe(true); + setDeleteDialogVisible(true); + }, + }) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getPrivacyFolderOption = (itemsCollection, t) => { + const moveTo = this.getOption("moveTo", t); + const deleteOption = this.getOption("delete", t); + const download = this.getOption("download", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("download", download) + .set("moveTo", moveTo) + + .set("delete", deleteOption) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getFavoritesFolderOptions = (itemsCollection, t) => { + const { selection } = this.filesStore; + + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("delete", { + label: t("Common:Delete"), + alt: t("RemoveFromFavorites"), + onClick: () => { + const items = selection.map((item) => item.id); + this.setFavoriteAction("remove", items) + .then(() => toastr.success(t("RemovedFromFavorites"))) + .catch((err) => toastr.error(err)); + }, + }) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getRecycleBinFolderOptions = (itemsCollection, t) => { + const { + setEmptyTrashDialogVisible, + setMoveToPanelVisible, + } = this.dialogsStore; + + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const deleteOption = this.getOption("delete", t); + const showInfo = this.getOption("showInfo", t); + + itemsCollection + .set("download", download) + .set("downloadAs", downloadAs) + .set("restore", { + label: t("Translations:Restore"), + onClick: () => setMoveToPanelVisible(true), + iconUrl: "/static/images/move.react.svg", + }) + .set("delete", deleteOption) + .set("showInfo", showInfo); + + return this.convertToArray(itemsCollection); + }; + + getHeaderMenu = (t) => { + const { + isFavoritesFolder, + isRecentFolder, + isRecycleBinFolder, + isPrivacyFolder, + isShareFolder, + } = this.treeFoldersStore; + + let itemsCollection = new Map(); + + if (isRecycleBinFolder) + return this.getRecycleBinFolderOptions(itemsCollection, t); + + if (isFavoritesFolder) + return this.getFavoritesFolderOptions(itemsCollection, t); + + if (isPrivacyFolder) + return this.getPrivacyFolderOption(itemsCollection, t); + + if (isShareFolder) + return this.getShareFolderOptions(itemsCollection, t); + + if (isRecentFolder) + return this.getRecentFolderOptions(itemsCollection, t); + + return this.getAnotherFolderOptions(itemsCollection, t); + }; } export default FilesActionStore; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index 249e69c2e0..6ec2f52b19 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -7,10 +7,10 @@ import FilesActionsStore from "./FilesActionsStore"; import FilesStore from "./FilesStore"; import FormatsStore from "./FormatsStore"; import iconFormatsStore from "./IconFormatsStore"; +import InfoPanelStore from "./InfoPanelStore"; import MediaViewerDataStore from "./MediaViewerDataStore"; import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; -import InfoPanelStore from "./InfoPanelStore"; import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; import selectedFilesStore from "./SelectedFilesStore"; import selectedFolderStore from "./SelectedFolderStore"; @@ -37,8 +37,7 @@ const filesStore = new FilesStore( selectedFolderStore, treeFoldersStore, formatsStore, - settingsStore, - selectedFilesStore + settingsStore ); const mediaViewerDataStore = new MediaViewerDataStore(filesStore, formatsStore); @@ -60,6 +59,9 @@ const uploadDataStore = new UploadDataStore( dialogsStore, settingsStore ); + +const infoPanelStore = new InfoPanelStore(); + const filesActionsStore = new FilesActionsStore( store.auth, uploadDataStore, @@ -68,13 +70,12 @@ const filesActionsStore = new FilesActionsStore( selectedFolderStore, settingsStore, dialogsStore, - mediaViewerDataStore + mediaViewerDataStore, + infoPanelStore ); const versionHistoryStore = new VersionHistoryStore(filesStore); -const infoPanelStore = new InfoPanelStore(); - //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { filesStore, diff --git a/public/images/info.outline.react.svg b/public/images/info.outline.react.svg new file mode 100644 index 0000000000..ac41fda0d9 --- /dev/null +++ b/public/images/info.outline.react.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + From 424a7a7e3cf9941ad5d26029efcd687e6cd1fa73 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 13:43:43 +0300 Subject: [PATCH 20/81] change code formatting --- config/kafka.json | 5 +- frontend.code-workspace | 108 +- .../InfoPanelLoader/InfoPanelLoader.js | 111 - .../InfoPanelLoader/StyledInfoPanelLoader.js | 114 - .../Loaders/InfoPanelLoader/index.js | 1 - .../components/Loaders/index.js | 44 +- .../components/PageLayout/index.js | 998 +++-- packages/asc-web-common/constants/index.js | 173 +- packages/asc-web-common/custom.scss | 53 +- .../asc-web-common/store/SettingsStore.js | 659 ++-- .../table-container/StyledTableContainer.js | 5 +- .../table-container/TableGroupMenu.js | 15 +- .../Client/src/HOCs/withContextOptions.js | 1263 ++++--- .../Client/src/HOCs/withFileActions.js | 860 +++-- .../src/pages/Home/Section/Body/index.js | 464 ++- .../ASC.Files/Client/src/pages/Home/index.js | 811 ++--- .../Client/src/store/FilesActionsStore.js | 1813 +++++----- .../ASC.Files/Client/src/store/FilesStore.js | 3199 ++++++++--------- .../Client/src/store/SelectedFilesStore.js | 38 +- .../Client/src/store/SettingsStore.js | 338 +- products/ASC.Files/Client/src/store/index.js | 86 +- public/locales/en/Common.json | 268 +- .../src/components/pages/Home/index.js | 162 +- 23 files changed, 5550 insertions(+), 6038 deletions(-) delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js diff --git a/config/kafka.json b/config/kafka.json index 4ffde92112..67a89013af 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,5 +1,4 @@ { - "kafka": { - "BootstrapServers": "" - } + "kafka": { + } } diff --git a/frontend.code-workspace b/frontend.code-workspace index 1278b51607..e1a4403f8f 100644 --- a/frontend.code-workspace +++ b/frontend.code-workspace @@ -1,61 +1,61 @@ { "folders": [ - { - "name": "✨ appserver", - "path": "." - }, - { - "name": "📦 @appserver/common", - "path": "packages\\asc-web-common" - }, - { - "name": "🚀 @appserver/files", - "path": "products\\ASC.Files\\Client" - }, - { - "name": "📦 @appserver/components", - "path": "packages\\asc-web-components" - }, - { - "name": "🚀 @appserver/people", - "path": "products\\ASC.People\\Client" - }, - { - "name": "🚀 @appserver/crm", - "path": "products\\ASC.Crm\\Client" - }, - { - "name": "🚀 @appserver/projects", - "path": "products\\ASC.Projects\\Client" - }, - { - "name": "🚀 @appserver/mail", - "path": "products\\ASC.Mail\\Client" - }, - { - "name": "🚀 @appserver/calendar", - "path": "products\\ASC.Calendar\\Client" - }, - { - "name": "🚀 @appserver/studio", - "path": "web\\ASC.Web.Client" - }, - { - "name": "🚀 @appserver/login", - "path": "web\\ASC.Web.Login" - }, - { - "name": "🚀 @appserver/editor", - "path": "web\\ASC.Web.Editor" - } + { + "name": "✨ appserver", + "path": "." + }, + { + "name": "📦 @appserver/common", + "path": "packages\\asc-web-common" + }, + { + "name": "📦 @appserver/components", + "path": "packages\\asc-web-components" + }, + { + "name": "🚀 @appserver/files", + "path": "products\\ASC.Files\\Client" + }, + { + "name": "🚀 @appserver/people", + "path": "products\\ASC.People\\Client" + }, + { + "name": "🚀 @appserver/crm", + "path": "products\\ASC.Crm\\Client" + }, + { + "name": "🚀 @appserver/projects", + "path": "products\\ASC.Projects\\Client" + }, + { + "name": "🚀 @appserver/mail", + "path": "products\\ASC.Mail\\Client" + }, + { + "name": "🚀 @appserver/calendar", + "path": "products\\ASC.Calendar\\Client" + }, + { + "name": "🚀 @appserver/studio", + "path": "web\\ASC.Web.Client" + }, + { + "name": "🚀 @appserver/login", + "path": "web\\ASC.Web.Login" + }, + { + "name": "🚀 @appserver/editor", + "path": "web\\ASC.Web.Editor" + } ], "settings": { - "window.zoomLevel": 0, - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "liveServer.settings.multiRootWorkspaceName": "✨ appserver" + "window.zoomLevel": 0, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "liveServer.settings.multiRootWorkspaceName": "✨ appserver" }, "extensions": { - "recommendations": ["folke.vscode-monorepo-workspace"] + "recommendations": ["folke.vscode-monorepo-workspace"] } -} + } \ No newline at end of file diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js deleted file mode 100644 index 2c0ace2138..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js +++ /dev/null @@ -1,111 +0,0 @@ -import PropTypes from "prop-types"; -import React from "react"; - -import RectangleLoader from "../RectangleLoader"; -import { - StyledAccessRow, - StyledInfoRoomBody, - StyledPropertiesTable, - StyledPropertyRow, - StyledSubtitle, - StyledThumbnail, - StyledTitle, -} from "./StyledInfoPanelLoader"; - -const InfoPanelLoader = ({ - id, - className, - style, - isFolder, - hasThumbnail, - ...rest -}) => { - const {} = rest; - - const randomNumber = (min, max) => Math.random() * (max - min) + min; - - const customRectangleLoader = (width, height, rounded) => ( - - ); - - const properties = isFolder - ? [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - ] - : [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { "File Extension": 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - { Versions: 17.6 }, - { Comments: 17.6 }, - ]; - - return ( - - - {customRectangleLoader(32, 32)} - {customRectangleLoader(250, 22)} - - - System Properties - - {hasThumbnail && ( - - {customRectangleLoader(320.2, 200)} - - )} - - - {properties.map((property) => ( - -
- {Object.keys(property)[0]} -
- {customRectangleLoader( - randomNumber(125, 150), - Object.values(property)[0] - )} -
- ))} -
- - Who has access - - - {customRectangleLoader(32, 32, 16)} -
- {customRectangleLoader(32, 32, 16)} - {customRectangleLoader(32, 32, 16)} -
-
- ); -}; - -InfoPanelLoader.propTypes = { - id: PropTypes.string, - className: PropTypes.string, - style: PropTypes.object, -}; - -InfoPanelLoader.defaultProps = { - id: undefined, - className: undefined, - style: undefined, -}; - -export default InfoPanelLoader; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js deleted file mode 100644 index 59543d61bf..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js +++ /dev/null @@ -1,114 +0,0 @@ -import styled from "styled-components"; - -const StyledInfoRoomBody = styled.div``; - -const StyledTitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - height: 80px; - gap: 8px; -`; - -const StyledThumbnail = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 200px; - padding: 4px; - border: solid 1px #eceef1; - border-radius: 6px; - margin-bottom: 24px; -`; - -const StyledSubtitle = styled.div` - margin-bottom: 24px; - height: 19.2px; - font-weight: 600; - font-size: 14px; - color: #000000; -`; - -const StyledPropertiesTable = styled.div` - display: flex; - flex-direction: column; - width: 100%; - margin-bottom: 24px; - gap: 8px; -`; - -const StyledPropertyRow = styled.div` - width: 100%; - display: grid; - grid-template-columns: 110px 1fr; - grid-column-gap: 24px; - - .property-title { - font-size: 13px; - color: #333333; - } -`; - -const StyledAccessRow = styled.div` - width: 100%; - height: 32px; - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } -`; - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -export { - StyledInfoRoomBody, - StyledSubtitle, - StyledTitle, - StyledThumbnail, - StyledPropertiesTable, - StyledPropertyRow, - StyledAccessRow, -}; - -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -const StyledItemAccess = styled.div` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } -`; - -const StyleditemAccessUser = styled.div` - width: 32px; - height: 32px; - border-radius: 50%; - - a { - img { - border-radius: 50%; - width: 100%; - height: 100%; - } - } -`; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js deleted file mode 100644 index ed427373f5..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js +++ /dev/null @@ -1 +0,0 @@ -export default from "./InfoPanelLoader"; diff --git a/packages/asc-web-common/components/Loaders/index.js b/packages/asc-web-common/components/Loaders/index.js index d9900ad7db..9577fdd7c3 100644 --- a/packages/asc-web-common/components/Loaders/index.js +++ b/packages/asc-web-common/components/Loaders/index.js @@ -6,7 +6,6 @@ import Filter from "./FilterLoader"; import Group from "./GroupLoader"; import Header from "./HeaderLoader"; import HistoryRows from "./HistoryRowsLoader"; -import InfoPanelLoader from "./InfoPanelLoader"; import MainButton from "./MainButtonLoader"; import ProfileView from "./ProfileViewLoader"; import Rectangle from "./RectangleLoader"; @@ -21,25 +20,24 @@ import TreeFolders from "./TreeFolderLoader"; import TreeSettingsLoader from "./TreeSettingsLoader"; export default { - Rectangle, - Circle, - Header, - SectionHeader, - ArticleHeader, - TreeFolders, - TreeSettingsLoader, - Row, - Rows, - Text, - Filter, - ProfileView, - SettingsFiles, - Group, - HistoryRows, - Tile, - Tiles, - DialogLoader, - DialogAsideLoader, - MainButton, - InfoPanelLoader, -}; + Rectangle, + Circle, + Header, + SectionHeader, + ArticleHeader, + TreeFolders, + TreeSettingsLoader, + Row, + Rows, + Text, + Filter, + ProfileView, + SettingsFiles, + Group, + HistoryRows, + Tile, + Tiles, + DialogLoader, + DialogAsideLoader, + MainButton, +}; \ No newline at end of file diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 16c3455f74..8b9cc9d876 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -27,581 +27,535 @@ import SubSectionPaging from "./sub-components/section-paging"; import SectionToggler from "./sub-components/section-toggler"; const StyledSelectoWrapper = styled.div` - .selecto-selection { - z-index: 200; - } + .selecto-selection { + z-index: 200; + } `; const StyledMainBar = styled.div` - box-sizing: border-box; + box-sizing: border-box; - ${!isMobile - ? css` - padding-right: 24px; - @media ${tablet} { - padding-right: 16px; - } - ` - : css` - margin-top: 10px; - padding-right: 0px; + ${!isMobile + ? css` + padding-right: 24px; + @media ${tablet} { + padding-right: 16px; + } + ` + : css` + margin-top: 10px; + padding-right: 0px; - @media ${desktop} { - padding-right: 10px; - } - `} + @media ${desktop} { + padding-right: 10px; + } + `} `; function ArticleHeader() { - return null; + return null; } ArticleHeader.displayName = "ArticleHeader"; function ArticleMainButton() { - return null; + return null; } ArticleMainButton.displayName = "ArticleMainButton"; function ArticleBody() { - return null; + return null; } ArticleBody.displayName = "ArticleBody"; function SectionHeader() { - return null; + return null; } SectionHeader.displayName = "SectionHeader"; function SectionFilter() { - return null; + return null; } SectionFilter.displayName = "SectionFilter"; function SectionBody() { - return null; + return null; } SectionBody.displayName = "SectionBody"; function SectionPaging() { - return null; + return null; } SectionPaging.displayName = "SectionPaging"; function InfoPanelBody() { - return null; + return null; } InfoPanelBody.displayName = "InfoPanelBody"; function InfoPanelHeader() { - return null; + return null; } InfoPanelHeader.displayName = "InfoPanelHeader"; class PageLayout extends React.Component { - static ArticleHeader = ArticleHeader; - static ArticleMainButton = ArticleMainButton; - static ArticleBody = ArticleBody; - static SectionHeader = SectionHeader; - static SectionFilter = SectionFilter; - static SectionBody = SectionBody; - static SectionPaging = SectionPaging; - static InfoPanelBody = InfoPanelBody; - static InfoPanelHeader = InfoPanelHeader; + static ArticleHeader = ArticleHeader; + static ArticleMainButton = ArticleMainButton; + static ArticleBody = ArticleBody; + static SectionHeader = SectionHeader; + static SectionFilter = SectionFilter; + static SectionBody = SectionBody; + static SectionPaging = SectionPaging; + static InfoPanelBody = InfoPanelBody; + static InfoPanelHeader = InfoPanelHeader; - constructor(props) { - super(props); + constructor(props) { + super(props); - this.timeoutHandler = null; - this.intervalHandler = null; + this.timeoutHandler = null; + this.intervalHandler = null; - this.scroll = null; + this.scroll = null; + } + + componentDidUpdate(prevProps) { + if (!this.scroll) { + this.scroll = document.getElementsByClassName("section-scroll")[0]; } - componentDidUpdate(prevProps) { - if (!this.scroll) { - this.scroll = document.getElementsByClassName("section-scroll")[0]; - } - - if ( - this.props.hideAside && - !this.props.isArticlePinned && - this.props.hideAside !== prevProps.hideAside - ) { - this.backdropClick(); - } + if ( + this.props.hideAside && + !this.props.isArticlePinned && + this.props.hideAside !== prevProps.hideAside + ) { + this.backdropClick(); } + } - componentDidMount() { - window.addEventListener( - "orientationchange", - this.orientationChangeHandler - ); + componentDidMount() { + window.addEventListener("orientationchange", this.orientationChangeHandler); - this.orientationChangeHandler(); + this.orientationChangeHandler(); + } + + componentWillUnmount() { + window.removeEventListener( + "orientationchange", + this.orientationChangeHandler + ); + + if (this.intervalHandler) clearInterval(this.intervalHandler); + if (this.timeoutHandler) clearTimeout(this.timeoutHandler); + } + + orientationChangeHandler = () => { + const isValueExist = !!this.props.isArticlePinned; + const isEnoughWidth = screen.availWidth > size.smallTablet; + const isPortrait = + isFirefox && + isMobileOnly && + screen.orientation.type === "portrait-primary"; + + if ((!isEnoughWidth && isValueExist) || isPortrait) { + this.backdropClick(); + return; } - - componentWillUnmount() { - window.removeEventListener( - "orientationchange", - this.orientationChangeHandler - ); - - if (this.intervalHandler) clearInterval(this.intervalHandler); - if (this.timeoutHandler) clearTimeout(this.timeoutHandler); + if (isEnoughWidth && isValueExist) { + this.pinArticle(); } + }; - orientationChangeHandler = () => { - const isValueExist = !!this.props.isArticlePinned; - const isEnoughWidth = screen.availWidth > size.smallTablet; - const isPortrait = - isFirefox && - isMobileOnly && - screen.orientation.type === "portrait-primary"; + backdropClick = () => { + this.props.setArticlePinned(false); + this.props.setIsBackdropVisible(false); + this.props.setIsArticleVisible(false); + isMobile && this.props.setArticleVisibleOnUnpin(false); + }; - if ((!isEnoughWidth && isValueExist) || isPortrait) { - this.backdropClick(); - return; - } - if (isEnoughWidth && isValueExist) { - this.pinArticle(); - } - }; + pinArticle = () => { + this.props.setIsBackdropVisible(false); + this.props.setIsArticleVisible(true); + this.props.setArticlePinned(true); + isMobile && this.props.setArticleVisibleOnUnpin(false); + }; - backdropClick = () => { - this.props.setArticlePinned(false); - this.props.setIsBackdropVisible(false); - this.props.setIsArticleVisible(false); - isMobile && this.props.setArticleVisibleOnUnpin(false); - }; + unpinArticle = () => { + this.props.setIsBackdropVisible(true); + this.props.setIsArticleVisible(true); + this.props.setArticlePinned(false); + isMobile && this.props.setArticleVisibleOnUnpin(true); + }; - pinArticle = () => { - this.props.setIsBackdropVisible(false); - this.props.setIsArticleVisible(true); - this.props.setArticlePinned(true); - isMobile && this.props.setArticleVisibleOnUnpin(false); - }; + showArticle = () => { + this.props.setArticlePinned(false); + this.props.setIsBackdropVisible(true); + this.props.setIsArticleVisible(true); + isMobile && this.props.setArticleVisibleOnUnpin(true); + }; - unpinArticle = () => { - this.props.setIsBackdropVisible(true); - this.props.setIsArticleVisible(true); - this.props.setArticlePinned(false); - isMobile && this.props.setArticleVisibleOnUnpin(true); - }; + onSelect = (e) => { + if (this.props.dragging) return; + const items = e.selected; + this.props.setSelections(items); + }; - showArticle = () => { - this.props.setArticlePinned(false); - this.props.setIsBackdropVisible(true); - this.props.setIsArticleVisible(true); - isMobile && this.props.setArticleVisibleOnUnpin(true); - }; + dragCondition = (e) => { + const path = e.inputEvent.composedPath(); + const isBackdrop = path.some( + (x) => x.classList && x.classList.contains("backdrop-active") + ); + const notSelectablePath = path.some( + (x) => x.classList && x.classList.contains("not-selectable") + ); - onSelect = (e) => { - if (this.props.dragging) return; - const items = e.selected; - this.props.setSelections(items); - }; + const isDraggable = path.some( + (x) => x.classList && x.classList.contains("draggable") + ); - dragCondition = (e) => { - const path = e.inputEvent.composedPath(); - const isBackdrop = path.some( - (x) => x.classList && x.classList.contains("backdrop-active") - ); - const notSelectablePath = path.some( - (x) => x.classList && x.classList.contains("not-selectable") - ); + if (notSelectablePath || isBackdrop || isDraggable) { + return false; + } else return true; + }; - const isDraggable = path.some( - (x) => x.classList && x.classList.contains("draggable") - ); + onScroll = (e) => { + this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10); + }; - if (notSelectablePath || isBackdrop || isDraggable) { - return false; - } else return true; - }; + render() { + const { + onDrop, + showPrimaryProgressBar, + primaryProgressBarIcon, + primaryProgressBarValue, + showPrimaryButtonAlert, + showSecondaryProgressBar, + secondaryProgressBarValue, + secondaryProgressBarIcon, + showSecondaryButtonAlert, + uploadFiles, + viewAs, + //withBodyAutoFocus, + withBodyScroll, + children, + isHeaderVisible, + //headerBorderBottom, + onOpenUploadPanel, + isTabletView, + firstLoad, + dragging, + isArticleVisible, + isBackdropVisible, + isArticlePinned, + isDesktop, + } = this.props; + let articleHeaderContent = null; + let articleMainButtonContent = null; + let articleBodyContent = null; + let sectionHeaderContent = null; + let sectionFilterContent = null; + let sectionPagingContent = null; + let sectionBodyContent = null; + let infoPanelBodyContent = null; + let infoPanelHeaderContent = null; - onScroll = (e) => { - this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10); - }; + React.Children.forEach(children, (child) => { + const childType = + child && child.type && (child.type.displayName || child.type.name); - render() { - const { - onDrop, - showPrimaryProgressBar, - primaryProgressBarIcon, - primaryProgressBarValue, - showPrimaryButtonAlert, - showSecondaryProgressBar, - secondaryProgressBarValue, - secondaryProgressBarIcon, - showSecondaryButtonAlert, - uploadFiles, - viewAs, - //withBodyAutoFocus, - withBodyScroll, - children, - isHeaderVisible, - //headerBorderBottom, - onOpenUploadPanel, - isTabletView, - firstLoad, - dragging, - isArticleVisible, - isBackdropVisible, - isArticlePinned, - isDesktop, - } = this.props; - let articleHeaderContent = null; - let articleMainButtonContent = null; - let articleBodyContent = null; - let sectionHeaderContent = null; - let sectionFilterContent = null; - let sectionPagingContent = null; - let sectionBodyContent = null; - let infoPanelBodyContent = null; - let infoPanelHeaderContent = null; + switch (childType) { + case ArticleHeader.displayName: + articleHeaderContent = child; + break; + case ArticleMainButton.displayName: + articleMainButtonContent = child; + break; + case ArticleBody.displayName: + articleBodyContent = child; + break; + case SectionHeader.displayName: + sectionHeaderContent = child; + break; + case SectionFilter.displayName: + sectionFilterContent = child; + break; + case SectionPaging.displayName: + sectionPagingContent = child; + break; + case SectionBody.displayName: + sectionBodyContent = child; + break; + case InfoPanelBody.displayName: + infoPanelBodyContent = child; + break; + case InfoPanelHeader.displayName: + infoPanelHeaderContent = child; + break; + default: + break; + } + }); - React.Children.forEach(children, (child) => { - const childType = - child && - child.type && - (child.type.displayName || child.type.name); + const isArticleHeaderAvailable = !!articleHeaderContent, + isArticleMainButtonAvailable = !!articleMainButtonContent, + isArticleBodyAvailable = !!articleBodyContent, + isArticleAvailable = + isArticleHeaderAvailable || + isArticleMainButtonAvailable || + isArticleBodyAvailable, + isSectionHeaderAvailable = !!sectionHeaderContent, + isSectionFilterAvailable = !!sectionFilterContent, + isSectionPagingAvailable = !!sectionPagingContent, + isSectionBodyAvailable = + !!sectionBodyContent || + isSectionFilterAvailable || + isSectionPagingAvailable, + isSectionAvailable = + isSectionHeaderAvailable || + isSectionFilterAvailable || + isSectionBodyAvailable || + isSectionPagingAvailable || + isArticleAvailable, + isBackdropAvailable = isArticleAvailable; - switch (childType) { - case ArticleHeader.displayName: - articleHeaderContent = child; - break; - case ArticleMainButton.displayName: - articleMainButtonContent = child; - break; - case ArticleBody.displayName: - articleBodyContent = child; - break; - case SectionHeader.displayName: - sectionHeaderContent = child; - break; - case SectionFilter.displayName: - sectionFilterContent = child; - break; - case SectionPaging.displayName: - sectionPagingContent = child; - break; - case SectionBody.displayName: - sectionBodyContent = child; - break; - case InfoPanelBody.displayName: - infoPanelBodyContent = child; - break; - case InfoPanelHeader.displayName: - infoPanelHeaderContent = child; - break; - default: - break; - } - }); - - const isArticleHeaderAvailable = !!articleHeaderContent, - isArticleMainButtonAvailable = !!articleMainButtonContent, - isArticleBodyAvailable = !!articleBodyContent, - isArticleAvailable = - isArticleHeaderAvailable || - isArticleMainButtonAvailable || - isArticleBodyAvailable, - isSectionHeaderAvailable = !!sectionHeaderContent, - isSectionFilterAvailable = !!sectionFilterContent, - isSectionPagingAvailable = !!sectionPagingContent, - isSectionBodyAvailable = - !!sectionBodyContent || - isSectionFilterAvailable || - isSectionPagingAvailable, - isSectionAvailable = - isSectionHeaderAvailable || - isSectionFilterAvailable || - isSectionBodyAvailable || - isSectionPagingAvailable || - isArticleAvailable, - isBackdropAvailable = isArticleAvailable; - - const renderPageLayout = () => { - return ( - <> - {isBackdropAvailable && ( - + const renderPageLayout = () => { + return ( + <> + {isBackdropAvailable && ( + + )} + {isArticleAvailable && ( +
+ {isArticleHeaderAvailable && ( + + {articleHeaderContent + ? articleHeaderContent.props.children + : null} + + )} + {isArticleMainButtonAvailable && ( + + {articleMainButtonContent + ? articleMainButtonContent.props.children + : null} + + )} + {isArticleBodyAvailable && ( + + {articleBodyContent + ? articleBodyContent.props.children + : null} + + )} + {isArticleBodyAvailable && ( + + )} +
+ )} + {isSectionAvailable && ( + + {({ width, height }) => ( + +
+ {isSectionHeaderAvailable && ( + + {sectionHeaderContent + ? sectionHeaderContent.props.children + : null} + )} + {isSectionFilterAvailable && ( + <> + + + {sectionFilterContent + ? sectionFilterContent.props.children + : null} + + + )} + + {isSectionBodyAvailable && ( + <> + + {isSectionFilterAvailable && ( + + {sectionFilterContent + ? sectionFilterContent.props.children + : null} + + )} + + {sectionBodyContent + ? sectionBodyContent.props.children + : null} + + {isSectionPagingAvailable && ( + + {sectionPagingContent + ? sectionPagingContent.props.children + : null} + + )} + + + )} + {showPrimaryProgressBar && showSecondaryProgressBar ? ( + <> + + + + ) : showPrimaryProgressBar && !showSecondaryProgressBar ? ( + + ) : !showPrimaryProgressBar && showSecondaryProgressBar ? ( + + ) : ( + <> + )} + {isArticleAvailable && ( -
- {isArticleHeaderAvailable && ( - - {articleHeaderContent - ? articleHeaderContent.props.children - : null} - - )} - {isArticleMainButtonAvailable && ( - - {articleMainButtonContent - ? articleMainButtonContent.props - .children - : null} - - )} - {isArticleBodyAvailable && ( - - {articleBodyContent - ? articleBodyContent.props.children - : null} - - )} - {isArticleBodyAvailable && ( - - )} -
+ )} - {isSectionAvailable && ( - - {({ width, height }) => ( - -
- {isSectionHeaderAvailable && ( - - {sectionHeaderContent - ? sectionHeaderContent.props - .children - : null} - - )} - {isSectionFilterAvailable && ( - <> - - - {sectionFilterContent - ? sectionFilterContent - .props.children - : null} - - - )} +
+ + + {infoPanelHeaderContent} + + {infoPanelBodyContent} + +
+ )} +
+ )} + + ); + }; - {isSectionBodyAvailable && ( - <> - - {isSectionFilterAvailable && ( - - {sectionFilterContent - ? sectionFilterContent - .props - .children - : null} - - )} - - {sectionBodyContent - ? sectionBodyContent - .props - .children - : null} - - {isSectionPagingAvailable && ( - - {sectionPagingContent - ? sectionPagingContent - .props - .children - : null} - - )} - - - )} - {showPrimaryProgressBar && - showSecondaryProgressBar ? ( - <> - - - - ) : showPrimaryProgressBar && - !showSecondaryProgressBar ? ( - - ) : !showPrimaryProgressBar && - showSecondaryProgressBar ? ( - - ) : ( - <> - )} + const scrollOptions = this.scroll + ? { + container: this.scroll, + throttleTime: 0, + threshold: 100, + } + : {}; - {isArticleAvailable && ( - - )} -
- - - {infoPanelHeaderContent} - - - {infoPanelBodyContent} - - -
- )} -
- )} - - ); - }; - - const scrollOptions = this.scroll - ? { - container: this.scroll, - throttleTime: 0, - threshold: 100, - } - : {}; - - return ( - <> - {renderPageLayout()} - {!isMobile && uploadFiles && !dragging && ( - - - - )} - - ); - } + return ( + <> + {renderPageLayout()} + {!isMobile && uploadFiles && !dragging && ( + + + + )} + + ); + } } PageLayout.propTypes = { - children: PropTypes.any, - withBodyScroll: PropTypes.bool, - withBodyAutoFocus: PropTypes.bool, - showPrimaryProgressBar: PropTypes.bool, - primaryProgressBarValue: PropTypes.number, - showPrimaryButtonAlert: PropTypes.bool, - progressBarDropDownContent: PropTypes.any, - primaryProgressBarIcon: PropTypes.string, - showSecondaryProgressBar: PropTypes.bool, - secondaryProgressBarValue: PropTypes.number, - secondaryProgressBarIcon: PropTypes.string, - showSecondaryButtonAlert: PropTypes.bool, - onDrop: PropTypes.func, - setSelections: PropTypes.func, - uploadFiles: PropTypes.bool, - hideAside: PropTypes.bool, - viewAs: PropTypes.string, - uploadPanelVisible: PropTypes.bool, - onOpenUploadPanel: PropTypes.func, - isTabletView: PropTypes.bool, - isHeaderVisible: PropTypes.bool, - firstLoad: PropTypes.bool, + children: PropTypes.any, + withBodyScroll: PropTypes.bool, + withBodyAutoFocus: PropTypes.bool, + showPrimaryProgressBar: PropTypes.bool, + primaryProgressBarValue: PropTypes.number, + showPrimaryButtonAlert: PropTypes.bool, + progressBarDropDownContent: PropTypes.any, + primaryProgressBarIcon: PropTypes.string, + showSecondaryProgressBar: PropTypes.bool, + secondaryProgressBarValue: PropTypes.number, + secondaryProgressBarIcon: PropTypes.string, + showSecondaryButtonAlert: PropTypes.bool, + onDrop: PropTypes.func, + setSelections: PropTypes.func, + uploadFiles: PropTypes.bool, + hideAside: PropTypes.bool, + viewAs: PropTypes.string, + uploadPanelVisible: PropTypes.bool, + onOpenUploadPanel: PropTypes.func, + isTabletView: PropTypes.bool, + isHeaderVisible: PropTypes.bool, + firstLoad: PropTypes.bool, }; PageLayout.defaultProps = { - withBodyScroll: true, - withBodyAutoFocus: false, + withBodyScroll: true, + withBodyAutoFocus: false, }; PageLayout.ArticleHeader = ArticleHeader; @@ -615,31 +569,31 @@ PageLayout.InfoPanelHeader = InfoPanelHeader; PageLayout.InfoPanelBody = InfoPanelBody; export default inject(({ auth }) => { - const { isLoaded, settingsStore } = auth; - const { - isHeaderVisible, - isTabletView, - isArticlePinned, - isArticleVisible, - isBackdropVisible, - setArticlePinned, - setArticleVisibleOnUnpin, - setIsArticleVisible, - setIsBackdropVisible, - isDesktopClient, - } = settingsStore; + const { isLoaded, settingsStore } = auth; + const { + isHeaderVisible, + isTabletView, + isArticlePinned, + isArticleVisible, + isBackdropVisible, + setArticlePinned, + setArticleVisibleOnUnpin, + setIsArticleVisible, + setIsBackdropVisible, + isDesktopClient, + } = settingsStore; - return { - isLoaded, - isTabletView, - isHeaderVisible, - isArticlePinned, - isArticleVisible, - setArticlePinned, - setArticleVisibleOnUnpin, - setIsArticleVisible, - isBackdropVisible, - setIsBackdropVisible, - isDesktop: isDesktopClient, - }; + return { + isLoaded, + isTabletView, + isHeaderVisible, + isArticlePinned, + isArticleVisible, + setArticlePinned, + setArticleVisibleOnUnpin, + setIsArticleVisible, + isBackdropVisible, + setIsBackdropVisible, + isDesktop: isDesktopClient, + }; })(observer(PageLayout)); diff --git a/packages/asc-web-common/constants/index.js b/packages/asc-web-common/constants/index.js index df648b133b..bb575b6114 100644 --- a/packages/asc-web-common/constants/index.js +++ b/packages/asc-web-common/constants/index.js @@ -1,15 +1,14 @@ export const LANGUAGE = "language"; export const ARTICLE_PINNED_KEY = "asc_article_pinned_key"; - /** * Enum for employee activation status. * @readonly */ export const EmployeeActivationStatus = Object.freeze({ - NotActivated: 0, - Activated: 1, - Pending: 2, - AutoGenerated: 4, + NotActivated: 0, + Activated: 1, + Pending: 2, + AutoGenerated: 4, }); /** @@ -17,8 +16,8 @@ export const EmployeeActivationStatus = Object.freeze({ * @readonly */ export const EmployeeStatus = Object.freeze({ - Active: 1, - Disabled: 2, + Active: 1, + Disabled: 2, }); /** @@ -26,8 +25,8 @@ export const EmployeeStatus = Object.freeze({ * @readonly */ export const EmployeeType = Object.freeze({ - User: 1, - Guest: 2, + User: 1, + Guest: 2, }); /** @@ -35,18 +34,18 @@ export const EmployeeType = Object.freeze({ * @readonly */ export const FilterType = Object.freeze({ - None: 0, - FilesOnly: 1, - FoldersOnly: 2, - DocumentsOnly: 3, - PresentationsOnly: 4, - SpreadsheetsOnly: 5, - ImagesOnly: 7, - ByUser: 8, - ByDepartment: 9, - ArchiveOnly: 10, - ByExtension: 11, - MediaOnly: 12, + None: 0, + FilesOnly: 1, + FoldersOnly: 2, + DocumentsOnly: 3, + PresentationsOnly: 4, + SpreadsheetsOnly: 5, + ImagesOnly: 7, + ByUser: 8, + ByDepartment: 9, + ArchiveOnly: 10, + ByExtension: 11, + MediaOnly: 12, }); /** @@ -54,14 +53,14 @@ export const FilterType = Object.freeze({ * @readonly */ export const FileType = Object.freeze({ - Unknown: 0, - Archive: 1, - Video: 2, - Audio: 3, - Image: 4, - Spreadsheet: 5, - Presentation: 6, - Document: 7, + Unknown: 0, + Archive: 1, + Video: 2, + Audio: 3, + Image: 4, + Spreadsheet: 5, + Presentation: 6, + Document: 7, }); /** @@ -69,8 +68,8 @@ export const FileType = Object.freeze({ * @readonly */ export const FileAction = Object.freeze({ - Create: 0, - Rename: 1, + Create: 0, + Rename: 1, }); /** @@ -78,82 +77,80 @@ export const FileAction = Object.freeze({ * @readonly */ export const FolderType = Object.freeze({ - DEFAULT: 0, - COMMON: 1, - BUNCH: 2, - TRASH: 3, - USER: 5, - SHARE: 6, - Projects: 8, - Favorites: 10, - Recent: 11, - Templates: 12, - Privacy: 13, + DEFAULT: 0, + COMMON: 1, + BUNCH: 2, + TRASH: 3, + USER: 5, + SHARE: 6, + Projects: 8, + Favorites: 10, + Recent: 11, + Templates: 12, + Privacy: 13, }); export const ShareAccessRights = Object.freeze({ - None: 0, - FullAccess: 1, - ReadOnly: 2, - DenyAccess: 3, - Varies: 4, - Review: 5, - Comment: 6, - FormFilling: 7, - CustomFilter: 8, + None: 0, + FullAccess: 1, + ReadOnly: 2, + DenyAccess: 3, + Varies: 4, + Review: 5, + Comment: 6, + FormFilling: 7, + CustomFilter: 8, }); export const ConflictResolveType = Object.freeze({ - Skip: 0, - Overwrite: 1, - Duplicate: 2, + Skip: 0, + Overwrite: 1, + Duplicate: 2, }); export const providersData = Object.freeze({ - google: { - label: "google", - icon: "/static/images/share.google.react.svg", - }, - facebook: { - label: "facebook", - icon: "/static/images/share.facebook.react.svg", - }, - twitter: { - label: "twitter", - icon: "/static/images/share.twitter.react.svg", - iconOptions: { color: "#2AA3EF" }, - }, - linkedin: { - label: "linkedin", - icon: "/static/images/share.linkedin.react.svg", - }, + google: { + label: "google", + icon: "/static/images/share.google.react.svg", + }, + facebook: { + label: "facebook", + icon: "/static/images/share.facebook.react.svg", + }, + twitter: { + label: "twitter", + icon: "/static/images/share.twitter.react.svg", + iconOptions: { color: "#2AA3EF" }, + }, + linkedin: { + label: "linkedin", + icon: "/static/images/share.linkedin.react.svg", + }, }); export const LoaderStyle = { - title: "", - width: "100%", - height: "32", - backgroundColor: "#000000", - foregroundColor: "#000000", - backgroundOpacity: 0.1, - foregroundOpacity: 0.15, - borderRadius: "3", - radius: "3", - speed: 2, - animate: true, + title: "", + width: "100%", + height: "32", + backgroundColor: "#000000", + foregroundColor: "#000000", + backgroundOpacity: 0.1, + foregroundOpacity: 0.15, + borderRadius: "3", + radius: "3", + speed: 2, + animate: true, }; import config from "./AppServerConfig"; - export const AppServerConfig = config; - /** * Enum for Tenant trusted domains on registration. * @readonly */ export const TenantTrustedDomainsType = Object.freeze({ - None: 0, - Custom: 1, - All: 2, + None: 0, + Custom: 1, + All: 2, }); -export const PasswordLimitSpecialCharacters = "!@#$%^&*"; +export const PasswordLimitSpecialCharacters = "!@#$%^&*"; \ No newline at end of file diff --git a/packages/asc-web-common/custom.scss b/packages/asc-web-common/custom.scss index 37887bc202..3dc0e9b544 100644 --- a/packages/asc-web-common/custom.scss +++ b/packages/asc-web-common/custom.scss @@ -1,52 +1,51 @@ // Override default variables before the import $font-family-base: "Open Sans", sans-serif; - @import "./opensansoffline.scss"; html, body { - height: 100%; + height: 100%; } #root { - min-height: 100%; - position: relative; + min-height: 100%; + position: relative; - .pageLoader { - position: fixed; - left: calc(50% - 20px); - top: 35%; - } + .pageLoader { + position: fixed; + left: calc(50% - 20px); + top: 35%; + } } body { - margin: 0; + margin: 0; } body.loading * { - cursor: wait !important; + cursor: wait !important; } body.drag-cursor * { - cursor: url('data:image/svg+xml;utf8,') - 6 6, - auto !important; + cursor: url('data:image/svg+xml;utf8,') + 6 6, + auto !important; } body.desktop { - user-select: none; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; - mozuserselect: none; + user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -o-user-select: none; + mozuserselect: none; } #snackbar { - display: flex; - justify-content: center; - position: fixed; - width: calc(100vw - 60px); - padding: 30px; - bottom: 15px; -} + display: flex; + justify-content: center; + position: fixed; + width: calc(100vw - 60px); + padding: 30px; + bottom: 15px; +} \ No newline at end of file diff --git a/packages/asc-web-common/store/SettingsStore.js b/packages/asc-web-common/store/SettingsStore.js index ffa584c2f0..8b51a82136 100644 --- a/packages/asc-web-common/store/SettingsStore.js +++ b/packages/asc-web-common/store/SettingsStore.js @@ -8,357 +8,352 @@ import { version } from "../package.json"; const { proxyURL } = AppServerConfig; class SettingsStore { - isLoading = false; - isLoaded = false; + isLoading = false; + isLoaded = false; - currentProductId = ""; - culture = "en-US"; - cultures = []; - trustedDomains = []; - trustedDomainsType = 0; - trustedDomains = []; - timezone = "UTC"; - timezones = []; - utcOffset = "00:00:00"; - utcHoursOffset = 0; - defaultPage = "/"; - homepage = ""; - datePattern = "M/d/yyyy"; - datePatternJQ = "00/00/0000"; - dateTimePattern = "dddd, MMMM d, yyyy h:mm:ss tt"; - datepicker = { - datePattern: "mm/dd/yy", - dateTimePattern: "DD, mm dd, yy h:mm:ss tt", - timePattern: "h:mm tt", - }; - organizationName = "ONLYOFFICE"; - greetingSettings = "Web Office Applications"; - enableAdmMess = false; - enabledJoin = false; - urlLicense = "https://gnu.org/licenses/gpl-3.0.html"; - urlSupport = "https://helpdesk.onlyoffice.com/"; - logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg"); - customNames = { - id: "Common", - userCaption: "User", - usersCaption: "Users", - groupCaption: "Group", - groupsCaption: "Groups", - userPostCaption: "Title", - regDateCaption: "Registration Date", - groupHeadCaption: "Head", - guestCaption: "Guest", - guestsCaption: "Guests", - }; - isDesktopClient = window["AscDesktopEditor"] !== undefined; - //isDesktopEncryption: desktopEncryption; - isEncryptionSupport = false; - encryptionKeys = null; + currentProductId = ""; + culture = "en-US"; + cultures = []; + trustedDomains = []; + trustedDomainsType = 0; + trustedDomains = []; + timezone = "UTC"; + timezones = []; + utcOffset = "00:00:00"; + utcHoursOffset = 0; + defaultPage = "/"; + homepage = ""; + datePattern = "M/d/yyyy"; + datePatternJQ = "00/00/0000"; + dateTimePattern = "dddd, MMMM d, yyyy h:mm:ss tt"; + datepicker = { + datePattern: "mm/dd/yy", + dateTimePattern: "DD, mm dd, yy h:mm:ss tt", + timePattern: "h:mm tt", + }; + organizationName = "ONLYOFFICE"; + greetingSettings = "Web Office Applications"; + enableAdmMess = false; + enabledJoin = false; + urlLicense = "https://gnu.org/licenses/gpl-3.0.html"; + urlSupport = "https://helpdesk.onlyoffice.com/"; + logoUrl = combineUrl(proxyURL, "/static/images/nav.logo.opened.react.svg"); + customNames = { + id: "Common", + userCaption: "User", + usersCaption: "Users", + groupCaption: "Group", + groupsCaption: "Groups", + userPostCaption: "Title", + regDateCaption: "Registration Date", + groupHeadCaption: "Head", + guestCaption: "Guest", + guestsCaption: "Guests", + }; + isDesktopClient = window["AscDesktopEditor"] !== undefined; + //isDesktopEncryption: desktopEncryption; + isEncryptionSupport = false; + encryptionKeys = null; - personal = false; + personal = false; - isHeaderVisible = false; - isTabletView = false; - isArticlePinned = - localStorage.getItem(ARTICLE_PINNED_KEY) === "true" || false; - isArticleVisible = false; - isBackdropVisible = false; + isHeaderVisible = false; + isTabletView = false; + isArticlePinned = + localStorage.getItem(ARTICLE_PINNED_KEY) === "true" || false; + isArticleVisible = false; + isBackdropVisible = false; - isArticleVisibleOnUnpin = false; + isArticleVisibleOnUnpin = false; - hashSettings = null; - title = ""; - ownerId = null; - nameSchemaId = null; - owner = {}; - wizardToken = null; - passwordSettings = null; - hasShortenService = false; + hashSettings = null; + title = ""; + ownerId = null; + nameSchemaId = null; + owner = {}; + wizardToken = null; + passwordSettings = null; + hasShortenService = false; - customSchemaList = []; - firebase = { - apiKey: "", - authDomain: "", - projectId: "", - storageBucket: "", - messagingSenderId: "", - appId: "", - measurementId: "", - }; - version = ""; - buildVersionInfo = { - appServer: version, - documentServer: "6.4.1", - }; - debugInfo = false; + customSchemaList = []; + firebase = { + apiKey: "", + authDomain: "", + projectId: "", + storageBucket: "", + messagingSenderId: "", + appId: "", + measurementId: "", + }; + version = ""; + buildVersionInfo = { + appServer: version, + documentServer: "6.4.1", + }; + debugInfo = false; - userFormValidation = /^[\p{L}\p{M}'\-]+$/gu; - folderFormValidation = new RegExp('[*+:"<>?|\\\\/]', "gim"); + userFormValidation = /^[\p{L}\p{M}'\-]+$/gu; + folderFormValidation = new RegExp('[*+:"<>?|\\\\/]', "gim"); - constructor() { - makeAutoObservable(this); + constructor() { + makeAutoObservable(this); + } + + get urlAuthKeys() { + const splitted = this.culture.split("-"); + const lang = splitted.length > 0 ? splitted[0] : "en"; + return `https://helpcenter.onlyoffice.com/${lang}/installation/groups-authorization-keys.aspx`; + } + + get wizardCompleted() { + return this.isLoaded && !this.wizardToken; + } + + get helpUrlCommonSettings() { + const substring = this.culture.substring(0, this.culture.indexOf("-")); + const lang = substring.length > 0 ? substring : "en"; + + return `https://helpcenter.onlyoffice.com/${lang}/administration/configuration.aspx#CustomizingPortal_block`; + } + + setIsArticleVisible = (visible) => { + this.isArticleVisible = this.isArticlePinned ? true : visible; + }; + + setIsBackdropVisible = (visible) => { + this.isBackdropVisible = visible; + }; + + hideArticle = () => { + this.setIsArticleVisible(false); + this.setIsBackdropVisible(false); + }; + + setValue = (key, value) => { + this[key] = value; + }; + + setDefaultPage = (defaultPage) => { + this.defaultPage = defaultPage; + }; + + getSettings = async () => { + const newSettings = await api.settings.getSettings(); + + if (window["AscDesktopEditor"] !== undefined || this.personal) { + const dp = combineUrl(proxyURL, "/products/files/"); + this.setDefaultPage(dp); } - get urlAuthKeys() { - const splitted = this.culture.split("-"); - const lang = splitted.length > 0 ? splitted[0] : "en"; - return `https://helpcenter.onlyoffice.com/${lang}/installation/groups-authorization-keys.aspx`; - } - - get wizardCompleted() { - return this.isLoaded && !this.wizardToken; - } - - get helpUrlCommonSettings() { - const substring = this.culture.substring(0, this.culture.indexOf("-")); - const lang = substring.length > 0 ? substring : "en"; - - return `https://helpcenter.onlyoffice.com/${lang}/administration/configuration.aspx#CustomizingPortal_block`; - } - - setIsArticleVisible = (visible) => { - this.isArticleVisible = this.isArticlePinned ? true : visible; - }; - - setIsBackdropVisible = (visible) => { - this.isBackdropVisible = visible; - }; - - hideArticle = () => { - this.setIsArticleVisible(false); - this.setIsBackdropVisible(false); - }; - - setValue = (key, value) => { - this[key] = value; - }; - - setDefaultPage = (defaultPage) => { - this.defaultPage = defaultPage; - }; - - getSettings = async () => { - const newSettings = await api.settings.getSettings(); - - if (window["AscDesktopEditor"] !== undefined || this.personal) { - const dp = combineUrl(proxyURL, "/products/files/"); - this.setDefaultPage(dp); - } - - Object.keys(newSettings).map((key) => { - if (key in this) { - this.setValue( - key, - key === "defaultPage" - ? combineUrl(proxyURL, newSettings[key]) - : newSettings[key] - ); - if (key === "culture") { - const language = localStorage.getItem(LANGUAGE); - if (!language || language == "undefined") { - localStorage.setItem(LANGUAGE, newSettings[key]); - } - } - if (key === "personal") { - window.AppServer = { - ...window.AppServer, - personal: newSettings[key], - }; - } - } else if (key === "passwordHash") { - this.setValue("hashSettings", newSettings[key]); - } - }); - - return newSettings; - }; - - getCurrentCustomSchema = async (id) => { - this.customNames = await api.settings.getCurrentCustomSchema(id); - }; - - getCustomSchemaList = async () => { - this.customSchemaList = await api.settings.getCustomSchemaList(); - }; - - getPortalSettings = async () => { - const origSettings = await this.getSettings(); - - if (origSettings.nameSchemaId) { - this.getCurrentCustomSchema(origSettings.nameSchemaId); - } - }; - - init = async () => { - this.setIsLoading(true); - - await Promise.all([ - this.getPortalSettings(), - this.getBuildVersionInfo(), - ]); - - this.setIsLoading(false); - this.setIsLoaded(true); - }; - - setIsLoading = (isLoading) => { - this.isLoading = isLoading; - }; - - setIsLoaded = (isLoaded) => { - this.isLoaded = isLoaded; - }; - - getPortalCultures = async () => { - this.cultures = await api.settings.getPortalCultures(); - }; - - setIsEncryptionSupport = (isEncryptionSupport) => { - this.isEncryptionSupport = isEncryptionSupport; - }; - - getIsEncryptionSupport = async () => { - const isEncryptionSupport = await api.files.getIsEncryptionSupport(); - this.setIsEncryptionSupport(isEncryptionSupport); - }; - - updateEncryptionKeys = (encryptionKeys) => { - this.encryptionKeys = encryptionKeys ?? {}; - }; - - setEncryptionKeys = async (keys) => { - await api.files.setEncryptionKeys(keys); - this.updateEncryptionKeys(keys); - }; - - getEncryptionKeys = async () => { - const encryptionKeys = await api.files.getEncryptionKeys(); - this.updateEncryptionKeys(encryptionKeys); - }; - - getOAuthToken = (tokenGetterWin) => { - return new Promise((resolve, reject) => { - localStorage.removeItem("code"); - let interval = null; - interval = setInterval(() => { - try { - const code = localStorage.getItem("code"); - - if (code) { - localStorage.removeItem("code"); - clearInterval(interval); - resolve(code); - } else if (tokenGetterWin && tokenGetterWin.closed) { - clearInterval(interval); - reject(); - } - } catch { - return; - } - }, 500); - }); - }; - - getLoginLink = (token, code) => { - return combineUrl(proxyURL, `/login.ashx?p=${token}&code=${code}`); - }; - - setModuleInfo = (homepage, productId) => { - if (this.homepage === homepage || this.currentProductId === productId) - return; - - console.log(`setModuleInfo('${homepage}', '${productId}')`); - - this.homepage = homepage; - this.setCurrentProductId(productId); - - const baseElm = document.getElementsByTagName("base"); - if (baseElm && baseElm.length === 1) { - const baseUrl = homepage - ? homepage[homepage.length - 1] === "/" - ? homepage - : `${homepage}/` - : "/"; - - console.log("SET base URL", baseUrl); - - baseElm[0].setAttribute("href", baseUrl); - } - }; - - setCurrentProductId = (currentProductId) => { - this.currentProductId = currentProductId; - }; - - getPortalOwner = async () => { - const owner = await api.people.getUserById(this.ownerId); - this.owner = owner; - return owner; - }; - - setWizardComplete = () => { - this.wizardToken = null; - }; - - setPasswordSettings = (passwordSettings) => { - this.passwordSettings = passwordSettings; - }; - - getPortalPasswordSettings = async (confirmKey = null) => { - const settings = await api.settings.getPortalPasswordSettings( - confirmKey + Object.keys(newSettings).map((key) => { + if (key in this) { + this.setValue( + key, + key === "defaultPage" + ? combineUrl(proxyURL, newSettings[key]) + : newSettings[key] ); - this.setPasswordSettings(settings); - }; + if (key === "culture") { + const language = localStorage.getItem(LANGUAGE); + if (!language || language == "undefined") { + localStorage.setItem(LANGUAGE, newSettings[key]); + } + } + if (key === "personal") { + window.AppServer = { + ...window.AppServer, + personal: newSettings[key], + }; + } + } else if (key === "passwordHash") { + this.setValue("hashSettings", newSettings[key]); + } + }); - setTimezones = (timezones) => { - this.timezones = timezones; - }; + return newSettings; + }; - getPortalTimezones = async (token = undefined) => { - const timezones = await api.settings.getPortalTimezones(token); - this.setTimezones(timezones); - }; + getCurrentCustomSchema = async (id) => { + this.customNames = await api.settings.getCurrentCustomSchema(id); + }; - setHeaderVisible = (isHeaderVisible) => { - this.isHeaderVisible = isHeaderVisible; - }; + getCustomSchemaList = async () => { + this.customSchemaList = await api.settings.getCustomSchemaList(); + }; - setIsTabletView = (isTabletView) => { - this.isTabletView = isTabletView; - }; + getPortalSettings = async () => { + const origSettings = await this.getSettings(); - setArticlePinned = (isPinned) => { - isPinned - ? localStorage.setItem(ARTICLE_PINNED_KEY, isPinned) - : localStorage.removeItem(ARTICLE_PINNED_KEY); - this.isArticlePinned = isPinned; - }; - - setArticleVisibleOnUnpin = (visible) => { - this.isArticleVisibleOnUnpin = visible; - }; - - get firebaseHelper() { - window.firebaseHelper = new FirebaseHelper(this.firebase); - return window.firebaseHelper; + if (origSettings.nameSchemaId) { + this.getCurrentCustomSchema(origSettings.nameSchemaId); } + }; - getBuildVersionInfo = async () => { - const versionInfo = await api.settings.getBuildVersion(); - this.setBuildVersionInfo(versionInfo); + init = async () => { + this.setIsLoading(true); + + await Promise.all([this.getPortalSettings(), this.getBuildVersionInfo()]); + + this.setIsLoading(false); + this.setIsLoaded(true); + }; + + setIsLoading = (isLoading) => { + this.isLoading = isLoading; + }; + + setIsLoaded = (isLoaded) => { + this.isLoaded = isLoaded; + }; + + getPortalCultures = async () => { + this.cultures = await api.settings.getPortalCultures(); + }; + + setIsEncryptionSupport = (isEncryptionSupport) => { + this.isEncryptionSupport = isEncryptionSupport; + }; + + getIsEncryptionSupport = async () => { + const isEncryptionSupport = await api.files.getIsEncryptionSupport(); + this.setIsEncryptionSupport(isEncryptionSupport); + }; + + updateEncryptionKeys = (encryptionKeys) => { + this.encryptionKeys = encryptionKeys ?? {}; + }; + + setEncryptionKeys = async (keys) => { + await api.files.setEncryptionKeys(keys); + this.updateEncryptionKeys(keys); + }; + + getEncryptionKeys = async () => { + const encryptionKeys = await api.files.getEncryptionKeys(); + this.updateEncryptionKeys(encryptionKeys); + }; + + getOAuthToken = (tokenGetterWin) => { + return new Promise((resolve, reject) => { + localStorage.removeItem("code"); + let interval = null; + interval = setInterval(() => { + try { + const code = localStorage.getItem("code"); + + if (code) { + localStorage.removeItem("code"); + clearInterval(interval); + resolve(code); + } else if (tokenGetterWin && tokenGetterWin.closed) { + clearInterval(interval); + reject(); + } + } catch { + return; + } + }, 500); + }); + }; + + getLoginLink = (token, code) => { + return combineUrl(proxyURL, `/login.ashx?p=${token}&code=${code}`); + }; + + setModuleInfo = (homepage, productId) => { + if (this.homepage === homepage || this.currentProductId === productId) + return; + + console.log(`setModuleInfo('${homepage}', '${productId}')`); + + this.homepage = homepage; + this.setCurrentProductId(productId); + + const baseElm = document.getElementsByTagName("base"); + if (baseElm && baseElm.length === 1) { + const baseUrl = homepage + ? homepage[homepage.length - 1] === "/" + ? homepage + : `${homepage}/` + : "/"; + + console.log("SET base URL", baseUrl); + + baseElm[0].setAttribute("href", baseUrl); + } + }; + + setCurrentProductId = (currentProductId) => { + this.currentProductId = currentProductId; + }; + + getPortalOwner = async () => { + const owner = await api.people.getUserById(this.ownerId); + this.owner = owner; + return owner; + }; + + setWizardComplete = () => { + this.wizardToken = null; + }; + + setPasswordSettings = (passwordSettings) => { + this.passwordSettings = passwordSettings; + }; + + getPortalPasswordSettings = async (confirmKey = null) => { + const settings = await api.settings.getPortalPasswordSettings(confirmKey); + this.setPasswordSettings(settings); + }; + + setTimezones = (timezones) => { + this.timezones = timezones; + }; + + getPortalTimezones = async (token = undefined) => { + const timezones = await api.settings.getPortalTimezones(token); + this.setTimezones(timezones); + }; + + setHeaderVisible = (isHeaderVisible) => { + this.isHeaderVisible = isHeaderVisible; + }; + + setIsTabletView = (isTabletView) => { + this.isTabletView = isTabletView; + }; + + setArticlePinned = (isPinned) => { + isPinned + ? localStorage.setItem(ARTICLE_PINNED_KEY, isPinned) + : localStorage.removeItem(ARTICLE_PINNED_KEY); + this.isArticlePinned = isPinned; + }; + + setArticleVisibleOnUnpin = (visible) => { + this.isArticleVisibleOnUnpin = visible; + }; + + get firebaseHelper() { + window.firebaseHelper = new FirebaseHelper(this.firebase); + return window.firebaseHelper; + } + + getBuildVersionInfo = async () => { + const versionInfo = await api.settings.getBuildVersion(); + this.setBuildVersionInfo(versionInfo); + }; + + setBuildVersionInfo = (versionInfo) => { + this.buildVersionInfo = { + ...this.buildVersionInfo, + appServer: version, + ...versionInfo, }; - setBuildVersionInfo = (versionInfo) => { - this.buildVersionInfo = { - ...this.buildVersionInfo, - appServer: version, - ...versionInfo, - }; - - if (!this.buildVersionInfo.documentServer) - this.buildVersionInfo.documentServer = "6.4.1"; - }; + if (!this.buildVersionInfo.documentServer) + this.buildVersionInfo.documentServer = "6.4.1"; + }; } -export default SettingsStore; +export default SettingsStore; \ No newline at end of file diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index befb0778d0..7e3d63d192 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -1,9 +1,8 @@ -import { isMobile } from "react-device-detect"; import styled, { css } from "styled-components"; - -import Scrollbar from "../scrollbar"; import Base from "../themes/base"; import { mobile, tablet } from "../utils/device"; +import Scrollbar from "../scrollbar"; +import { isMobile } from "react-device-detect"; const StyledTableContainer = styled.div` -moz-user-select: none; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index dea0b41944..7a9c5ad381 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -1,11 +1,10 @@ -import PropTypes from "prop-types"; import React from "react"; -import { useTranslation } from "react-i18next"; - +import PropTypes from "prop-types"; import Checkbox from "../checkbox"; +import { StyledTableGroupMenu, StyledScrollbar } from "./StyledTableContainer"; import ComboBox from "../combobox"; import GroupMenuItem from "./GroupMenuItem"; -import { StyledScrollbar, StyledTableGroupMenu } from "./StyledTableContainer"; +import { useTranslation } from "react-i18next"; const TableGroupMenu = (props) => { const { @@ -17,13 +16,10 @@ const TableGroupMenu = (props) => { checkboxMargin, ...rest } = props; - const onCheckboxChange = (e) => { onChange && onChange(e.target && e.target.checked); }; - const { t } = useTranslation("Common"); - return ( <> { ); }; - TableGroupMenu.propTypes = { isChecked: PropTypes.bool, isIndeterminate: PropTypes.bool, headerMenu: PropTypes.arrayOf(PropTypes.object).isRequired, - infoPanelToggle: PropTypes.node, checkboxOptions: PropTypes.any.isRequired, onClick: PropTypes.func, onChange: PropTypes.func, checkboxMargin: PropTypes.string, }; - -export default TableGroupMenu; +export default TableGroupMenu; \ No newline at end of file diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index 36867fecf6..dd39c071c0 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -1,668 +1,655 @@ -import { AppServerConfig, FileAction } from "@appserver/common/constants"; -import { combineUrl } from "@appserver/common/utils"; -import toastr from "@appserver/components/toast/toastr"; -import copy from "copy-to-clipboard"; -import saveAs from "file-saver"; -import { inject, observer } from "mobx-react"; import React from "react"; - +import { inject, observer } from "mobx-react"; +import copy from "copy-to-clipboard"; +import { combineUrl } from "@appserver/common/utils"; +import { FileAction, AppServerConfig } from "@appserver/common/constants"; +import toastr from "@appserver/components/toast/toastr"; import config from "../../package.json"; +import saveAs from "file-saver"; export default function withContextOptions(WrappedComponent) { - class WithContextOptions extends React.Component { - onOpenFolder = () => { - const { item, openLocationAction } = this.props; - const { id, folderId, fileExst } = item; - const locationId = !fileExst ? id : folderId; - openLocationAction(locationId, !fileExst); + class WithContextOptions extends React.Component { + onOpenFolder = () => { + const { item, openLocationAction } = this.props; + const { id, folderId, fileExst } = item; + const locationId = !fileExst ? id : folderId; + openLocationAction(locationId, !fileExst); + }; + + onClickLinkFillForm = () => { + return this.gotoDocEditor(false); + }; + + onClickMakeForm = () => { + const { copyAsAction, item, formfillingDocs } = this.props; + const { title, id, folderId, fileExst } = item; + + const newTitle = + title.substring(0, title.length - fileExst.length) + formfillingDocs[0]; + + copyAsAction(id, newTitle, folderId).catch((err) => toastr.error(err)); + }; + + onOpenLocation = () => { + const { item, openLocationAction } = this.props; + const { parentId, folderId, fileExst } = item; + const locationId = !fileExst ? parentId : folderId; + openLocationAction(locationId, !fileExst); + }; + + onSetInfoPanelVisible = () => { + this.props.setIsVisible(true); + }; + + onOwnerChange = () => { + const { setChangeOwnerPanelVisible } = this.props; + setChangeOwnerPanelVisible(true); + }; + onMoveAction = () => { + const { setMoveToPanelVisible } = this.props; + setMoveToPanelVisible(true); + }; + onCopyAction = () => { + const { setCopyPanelVisible } = this.props; + setCopyPanelVisible(true); + }; + + showVersionHistory = () => { + const { + item, + isTabletView, + fetchFileVersions, + setIsVerHistoryPanel, + history, + homepage, + isTrashFolder, + } = this.props; + const { id } = item; + if (isTrashFolder) return; + + if (!isTabletView) { + fetchFileVersions(id + ""); + setIsVerHistoryPanel(true); + } else { + history.push( + combineUrl(AppServerConfig.proxyURL, homepage, `/${id}/history`) + ); + } + }; + + finalizeVersion = () => { + const { item, finalizeVersionAction } = this.props; + const { id } = item; + finalizeVersionAction(id).catch((err) => toastr.error(err)); + }; + + onClickFavorite = (e) => { + const { item, setFavoriteAction, t } = this.props; + const { id } = item; + const data = (e.currentTarget && e.currentTarget.dataset) || e; + const { action } = data; + + setFavoriteAction(action, id) + .then(() => + action === "mark" + ? toastr.success(t("MarkedAsFavorite")) + : toastr.success(t("RemovedFromFavorites")) + ) + .catch((err) => toastr.error(err)); + }; + + lockFile = () => { + const { item, lockFileAction } = this.props; + const { id, locked } = item; + lockFileAction(id, !locked).catch((err) => toastr.error(err)); + }; + + onClickLinkForPortal = () => { + const { item, homepage, t } = this.props; + const { fileExst, canOpenPlayer, webUrl, id } = item; + + const isFile = !!fileExst; + copy( + isFile + ? canOpenPlayer + ? `${window.location.href}&preview=${id}` + : webUrl + : `${window.location.origin + homepage}/filter?folder=${id}` + ); + + toastr.success(t("Translations:LinkCopySuccess")); + }; + + onClickLinkEdit = () => { + const { + item, + canConvert, + setConvertItem, + setConvertDialogVisible, + } = this.props; + + if (canConvert) { + setConvertItem(item); + setConvertDialogVisible(true); + } else { + this.gotoDocEditor(false); + } + }; + + onPreviewClick = () => { + this.gotoDocEditor(true); + }; + + gotoDocEditor = (preview = false) => { + const { item, openDocEditor, isDesktop } = this.props; + const { id, providerKey, fileExst } = item; + + const urlFormation = preview + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/doceditor?fileId=${encodeURIComponent(id)}&action=view` + ) + : null; + + let tab = + !isDesktop && fileExst + ? window.open( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + "/doceditor" + ), + "_blank" + ) + : null; + + openDocEditor(id, providerKey, tab, urlFormation); + }; + + isPwa = () => { + return ["fullscreen", "standalone", "minimal-ui"].some( + (displayMode) => + window.matchMedia("(display-mode: " + displayMode + ")").matches + ); + }; + + onClickDownload = () => { + const { item, downloadAction, t } = this.props; + const { fileExst, contentLength, viewUrl } = item; + const isFile = !!fileExst && contentLength; + + if (this.isPwa()) { + const xhr = new XMLHttpRequest(); + xhr.open("GET", viewUrl); + xhr.responseType = "blob"; + + xhr.onload = () => { + saveAs(xhr.response, item.title); }; - onClickLinkFillForm = () => { - return this.gotoDocEditor(false); + xhr.onerror = () => { + console.error("download failed", viewUrl); }; - onClickMakeForm = () => { - const { copyAsAction, item, formfillingDocs } = this.props; - const { title, id, folderId, fileExst } = item; + xhr.send(); + return; + } - const newTitle = - title.substring(0, title.length - fileExst.length) + - formfillingDocs[0]; + isFile + ? window.open(viewUrl, "_self") + : downloadAction(t("Translations:ArchivingData")).catch((err) => + toastr.error(err) + ); + }; - copyAsAction(id, newTitle, folderId).catch((err) => - toastr.error(err) - ); - }; + onClickDownloadAs = () => { + const { setDownloadDialogVisible } = this.props; + setDownloadDialogVisible(true); + }; - onOpenLocation = () => { - const { item, openLocationAction } = this.props; - const { parentId, folderId, fileExst } = item; - const locationId = !fileExst ? parentId : folderId; - openLocationAction(locationId, !fileExst); - }; + onDuplicate = () => { + const { duplicateAction, t, item } = this.props; + duplicateAction(item, t("Translations:CopyOperation")).catch((err) => + toastr.error(err) + ); + }; - onSetInfoPanelVisible = () => { - this.props.setIsVisible(true); - }; + onClickRename = () => { + const { item, setAction } = this.props; + const { id, fileExst } = item; + setAction({ + type: FileAction.Rename, + extension: fileExst, + id, + }); + }; - onOwnerChange = () => { - const { setChangeOwnerPanelVisible } = this.props; - setChangeOwnerPanelVisible(true); - }; - onMoveAction = () => { - const { setMoveToPanelVisible } = this.props; - setMoveToPanelVisible(true); - }; - onCopyAction = () => { - const { setCopyPanelVisible } = this.props; - setCopyPanelVisible(true); - }; + onChangeThirdPartyInfo = () => { + const { item, setThirdpartyInfo } = this.props; + const { providerKey } = item; + setThirdpartyInfo(providerKey); + }; - showVersionHistory = () => { - const { - item, - isTabletView, - fetchFileVersions, - setIsVerHistoryPanel, - history, - homepage, - isTrashFolder, - } = this.props; - const { id } = item; - if (isTrashFolder) return; + onMediaFileClick = (fileId) => { + const { item, setMediaViewerData } = this.props; + const itemId = typeof fileId !== "object" ? fileId : item.id; + setMediaViewerData({ visible: true, id: itemId }); + }; - if (!isTabletView) { - fetchFileVersions(id + ""); - setIsVerHistoryPanel(true); - } else { - history.push( - combineUrl( - AppServerConfig.proxyURL, - homepage, - `/${id}/history` - ) - ); - } - }; + onClickDelete = () => { + const { + item, + setRemoveItem, + setDeleteThirdPartyDialogVisible, + t, + deleteItemAction, + } = this.props; + const { id, title, providerKey, rootFolderId, isFolder } = item; - finalizeVersion = () => { - const { item, finalizeVersionAction } = this.props; - const { id } = item; - finalizeVersionAction(id).catch((err) => toastr.error(err)); - }; + const isRootThirdPartyFolder = providerKey && id === rootFolderId; - onClickFavorite = (e) => { - const { item, setFavoriteAction, t } = this.props; - const { id } = item; - const data = (e.currentTarget && e.currentTarget.dataset) || e; - const { action } = data; + if (isRootThirdPartyFolder) { + const splitItem = id.split("-"); + setRemoveItem({ id: splitItem[splitItem.length - 1], title }); + setDeleteThirdPartyDialogVisible(true); + return; + } - setFavoriteAction(action, id) - .then(() => - action === "mark" - ? toastr.success(t("MarkedAsFavorite")) - : toastr.success(t("RemovedFromFavorites")) - ) - .catch((err) => toastr.error(err)); - }; + const translations = { + deleteOperation: t("Translations:DeleteOperation"), + successRemoveFile: t("FileRemoved"), + successRemoveFolder: t("FolderRemoved"), + }; - lockFile = () => { - const { item, lockFileAction } = this.props; - const { id, locked } = item; - lockFileAction(id, !locked).catch((err) => toastr.error(err)); - }; + deleteItemAction(id, translations, !isFolder, providerKey); + }; - onClickLinkForPortal = () => { - const { item, homepage, t } = this.props; - const { fileExst, canOpenPlayer, webUrl, id } = item; + onClickShare = () => { + const { setSharingPanelVisible } = this.props; + setTimeout(() => { + setSharingPanelVisible(true); + }, 10); //TODO: remove delay after fix context menu callback + }; - const isFile = !!fileExst; - copy( - isFile - ? canOpenPlayer - ? `${window.location.href}&preview=${id}` - : webUrl - : `${window.location.origin + homepage}/filter?folder=${id}` - ); + onClickMarkRead = () => { + const { markAsRead, item } = this.props; + item.fileExst + ? markAsRead([], [item.id], item) + : markAsRead([item.id], [], item); + }; - toastr.success(t("Translations:LinkCopySuccess")); - }; + onClickUnsubscribe = () => { + const { setDeleteDialogVisible, setUnsubscribe } = this.props; - onClickLinkEdit = () => { - const { - item, - canConvert, - setConvertItem, - setConvertDialogVisible, - } = this.props; + setUnsubscribe(true); + setDeleteDialogVisible(true); + }; - if (canConvert) { - setConvertItem(item); - setConvertDialogVisible(true); - } else { - this.gotoDocEditor(false); - } - }; + getFilesContextOptions = () => { + const { item, t } = this.props; + const { contextOptions } = item; + const isRootThirdPartyFolder = + item.providerKey && item.id === item.rootFolderId; - onPreviewClick = () => { - this.gotoDocEditor(true); - }; - - gotoDocEditor = (preview = false) => { - const { item, openDocEditor, isDesktop } = this.props; - const { id, providerKey, fileExst } = item; - - const urlFormation = preview - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/doceditor?fileId=${encodeURIComponent(id)}&action=view` - ) - : null; - - let tab = - !isDesktop && fileExst - ? window.open( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - "/doceditor" - ), - "_blank" - ) - : null; - - openDocEditor(id, providerKey, tab, urlFormation); - }; - - isPwa = () => { - return ["fullscreen", "standalone", "minimal-ui"].some( - (displayMode) => - window.matchMedia("(display-mode: " + displayMode + ")") - .matches - ); - }; - - onClickDownload = () => { - const { item, downloadAction, t } = this.props; - const { fileExst, contentLength, viewUrl } = item; - const isFile = !!fileExst && contentLength; - - if (this.isPwa()) { - const xhr = new XMLHttpRequest(); - xhr.open("GET", viewUrl); - xhr.responseType = "blob"; - - xhr.onload = () => { - saveAs(xhr.response, item.title); - }; - - xhr.onerror = () => { - console.error("download failed", viewUrl); - }; - - xhr.send(); - return; - } - - isFile - ? window.open(viewUrl, "_self") - : downloadAction(t("Translations:ArchivingData")).catch((err) => - toastr.error(err) - ); - }; - - onClickDownloadAs = () => { - const { setDownloadDialogVisible } = this.props; - setDownloadDialogVisible(true); - }; - - onDuplicate = () => { - const { duplicateAction, t, item } = this.props; - duplicateAction( - item, - t("Translations:CopyOperation") - ).catch((err) => toastr.error(err)); - }; - - onClickRename = () => { - const { item, setAction } = this.props; - const { id, fileExst } = item; - setAction({ - type: FileAction.Rename, - extension: fileExst, - id, - }); - }; - - onChangeThirdPartyInfo = () => { - const { item, setThirdpartyInfo } = this.props; - const { providerKey } = item; - setThirdpartyInfo(providerKey); - }; - - onMediaFileClick = (fileId) => { - const { item, setMediaViewerData } = this.props; - const itemId = typeof fileId !== "object" ? fileId : item.id; - setMediaViewerData({ visible: true, id: itemId }); - }; - - onClickDelete = () => { - const { - item, - setRemoveItem, - setDeleteThirdPartyDialogVisible, - t, - deleteItemAction, - } = this.props; - const { id, title, providerKey, rootFolderId, isFolder } = item; - - const isRootThirdPartyFolder = providerKey && id === rootFolderId; - - if (isRootThirdPartyFolder) { - const splitItem = id.split("-"); - setRemoveItem({ id: splitItem[splitItem.length - 1], title }); - setDeleteThirdPartyDialogVisible(true); - return; - } - - const translations = { - deleteOperation: t("Translations:DeleteOperation"), - successRemoveFile: t("FileRemoved"), - successRemoveFolder: t("FolderRemoved"), - }; - - deleteItemAction(id, translations, !isFolder, providerKey); - }; - - onClickShare = () => { - const { setSharingPanelVisible } = this.props; - setTimeout(() => { - setSharingPanelVisible(true); - }, 10); //TODO: remove delay after fix context menu callback - }; - - onClickMarkRead = () => { - const { markAsRead, item } = this.props; - item.fileExst - ? markAsRead([], [item.id], item) - : markAsRead([item.id], [], item); - }; - - onClickUnsubscribe = () => { - const { setDeleteDialogVisible, setUnsubscribe } = this.props; - - setUnsubscribe(true); - setDeleteDialogVisible(true); - }; - - getFilesContextOptions = () => { - const { item, t } = this.props; - const { contextOptions } = item; - const isRootThirdPartyFolder = - item.providerKey && item.id === item.rootFolderId; - - const isShareable = item.canShare; - - return contextOptions.map((option) => { - switch (option) { - case "open": - return { - key: option, - label: t("Open"), - icon: "images/catalog.folder.react.svg", - onClick: this.onOpenFolder, - disabled: false, - }; - case "show-info": - return { - key: option, - label: t("InfoPanel:Info"), - icon: "images/info.react.svg", - onClick: this.onSetInfoPanelVisible, - disabled: false, - }; - case "show-version-history": - return { - key: option, - label: t("ShowVersionHistory"), - icon: "images/history.react.svg", - onClick: this.showVersionHistory, - disabled: false, - }; - case "finalize-version": - return { - key: option, - label: t("FinalizeVersion"), - icon: "images/history-finalized.react.svg", - onClick: this.finalizeVersion, - disabled: false, - }; - case "separator0": - case "separator1": - case "separator2": - case "separator3": - return { key: option, isSeparator: true }; - case "open-location": - return { - key: option, - label: t("OpenLocation"), - icon: "images/download-as.react.svg", - onClick: this.onOpenLocation, - disabled: false, - }; - case "mark-as-favorite": - return { - key: option, - label: t("MarkAsFavorite"), - icon: "images/favorites.react.svg", - onClick: this.onClickFavorite, - disabled: false, - "data-action": "mark", - action: "mark", - }; - case "block-unblock-version": - return { - key: option, - label: t("UnblockVersion"), - icon: "images/lock.react.svg", - onClick: this.lockFile, - disabled: false, - }; - case "sharing-settings": - return { - key: option, - label: t("SharingSettings"), - icon: "/static/images/catalog.share.react.svg", - onClick: this.onClickShare, - disabled: !isShareable, - }; - case "send-by-email": - return { - key: option, - label: t("SendByEmail"), - icon: "/static/images/mail.react.svg", - disabled: true, - }; - case "owner-change": - return { - key: option, - label: t("Translations:OwnerChange"), - icon: "/static/images/catalog.user.react.svg", - onClick: this.onOwnerChange, - disabled: false, - }; - case "link-for-portal-users": - return { - key: option, - label: t("LinkForPortalUsers"), - icon: "/static/images/invitation.link.react.svg", - onClick: this.onClickLinkForPortal, - disabled: false, - }; - case "fill-form": - return { - key: option, - label: t("Common:FillFormButton"), - icon: "/static/images/form.fill.rect.svg", - onClick: this.onClickLinkFillForm, - disabled: false, - }; - case "make-form": - return { - key: option, - label: t("Common:MakeForm"), - icon: "/static/images/form.plus.react.svg", - onClick: this.onClickMakeForm, - disabled: false, - }; - case "edit": - return { - key: option, - label: t("Common:EditButton"), - icon: "/static/images/access.edit.react.svg", - onClick: this.onClickLinkEdit, - disabled: false, - }; - case "preview": - return { - key: option, - label: t("Preview"), - icon: "/static/images/eye.react.svg", - onClick: this.onPreviewClick, - disabled: false, - }; - case "view": - return { - key: option, - label: t("Common:View"), - icon: "/static/images/eye.react.svg", - onClick: this.onMediaFileClick, - disabled: false, - }; - case "download": - return { - key: option, - label: t("Common:Download"), - icon: "images/download.react.svg", - onClick: this.onClickDownload, - disabled: false, - }; - case "download-as": - return { - key: option, - label: t("Translations:DownloadAs"), - icon: "images/download-as.react.svg", - onClick: this.onClickDownloadAs, - disabled: false, - }; - case "move-to": - return { - key: option, - label: t("MoveTo"), - icon: "images/move.react.svg", - onClick: this.onMoveAction, - disabled: false, - }; - case "restore": - return { - key: option, - label: t("Translations:Restore"), - icon: "images/move.react.svg", - onClick: this.onMoveAction, - disabled: false, - }; - case "copy-to": - return { - key: option, - label: t("Translations:Copy"), - icon: "/static/images/copy.react.svg", - onClick: this.onCopyAction, - disabled: false, - }; - case "copy": - return { - key: option, - label: t("Duplicate"), - icon: "/static/images/copy.react.svg", - onClick: this.onDuplicate, - disabled: false, - }; - case "rename": - return { - key: option, - label: t("Rename"), - icon: "images/rename.react.svg", - onClick: this.onClickRename, - disabled: false, - }; - case "change-thirdparty-info": - return { - key: option, - label: t("Translations:ThirdPartyInfo"), - icon: "/static/images/access.edit.react.svg", - onClick: this.onChangeThirdPartyInfo, - disabled: false, - }; - case "delete": - return { - key: option, - label: isRootThirdPartyFolder - ? t("Translations:DeleteThirdParty") - : t("Common:Delete"), - icon: "/static/images/catalog.trash.react.svg", - onClick: this.onClickDelete, - disabled: false, - }; - case "remove-from-favorites": - return { - key: option, - label: t("RemoveFromFavorites"), - icon: "images/favorites.react.svg", - onClick: this.onClickFavorite, - disabled: false, - "data-action": "remove", - action: "remove", - }; - case "unsubscribe": - return { - key: option, - label: t("RemoveFromList"), - icon: "images/remove.svg", - onClick: this.onClickUnsubscribe, - disabled: false, - }; - case "mark-read": - return { - key: option, - label: t("MarkRead"), - icon: "images/tick.rounded.svg", - onClick: this.onClickMarkRead, - disabled: false, - }; - default: - break; - } - - return undefined; - }); - }; - - render() { - const { actionType, actionId, actionExtension, item } = this.props; - const { id, fileExst, contextOptions } = item; - - const isEdit = - !!actionType && actionId === id && fileExst === actionExtension; - - const contextOptionsProps = - !isEdit && contextOptions && contextOptions.length > 0 - ? { - contextOptions: this.getFilesContextOptions(), - } - : {}; - - return ( - - ); - } - } - - return inject( - ( - { - auth, - dialogsStore, - filesActionsStore, - filesStore, - mediaViewerDataStore, - treeFoldersStore, - uploadDataStore, - versionHistoryStore, - infoPanelStore, - }, - { item } - ) => { - const { openDocEditor, fileActionStore, formatsStore } = filesStore; - const { - deleteItemAction, - downloadAction, - duplicateAction, - finalizeVersionAction, - lockFileAction, - markAsRead, - onSelectItem, - openLocationAction, - setFavoriteAction, - setThirdpartyInfo, - unsubscribeAction, - } = filesActionsStore; - const { setIsVisible } = infoPanelStore; - const { - setChangeOwnerPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - setDeleteThirdPartyDialogVisible, - setDownloadDialogVisible, - setMoveToPanelVisible, - setRemoveItem, - setSharingPanelVisible, - setUnsubscribe, - } = dialogsStore; - const { isTabletView, isDesktopClient } = auth.settingsStore; - const { - setIsVerHistoryPanel, - fetchFileVersions, - } = versionHistoryStore; - const { setAction, type, extension, id } = fileActionStore; - const { setMediaViewerData } = mediaViewerDataStore; - const { copyAsAction } = uploadDataStore; - const { formfillingDocs } = formatsStore.docserviceStore; - - const { isRecycleBinFolder, isShare } = treeFoldersStore; - const isShareFolder = isShare(item.rootFolderType); + const isShareable = item.canShare; + return contextOptions.map((option) => { + switch (option) { + case "open": return { - openLocationAction, - setIsVisible, - setChangeOwnerPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - isTabletView, - setIsVerHistoryPanel, - fetchFileVersions, - homepage: config.homepage, - finalizeVersionAction, - setFavoriteAction, - lockFileAction, - openDocEditor, - downloadAction, - setDownloadDialogVisible, - duplicateAction, - setAction, - setThirdpartyInfo, - setMediaViewerData, - setRemoveItem, - setDeleteThirdPartyDialogVisible, - deleteItemAction, - onSelectItem, - setSharingPanelVisible, - actionType: type, - actionId: id, - actionExtension: extension, - isTrashFolder: isRecycleBinFolder, - isShareFolder, - markAsRead, - unsubscribeAction, - setDeleteDialogVisible, - setUnsubscribe, - isDesktop: isDesktopClient, - copyAsAction, - formfillingDocs, + key: option, + label: t("Open"), + icon: "images/catalog.folder.react.svg", + onClick: this.onOpenFolder, + disabled: false, }; + case "show-info": + return { + key: option, + label: t("InfoPanel:Info"), + icon: "images/info.react.svg", + onClick: this.onSetInfoPanelVisible, + disabled: false, + }; + case "show-version-history": + return { + key: option, + label: t("ShowVersionHistory"), + icon: "images/history.react.svg", + onClick: this.showVersionHistory, + disabled: false, + }; + case "finalize-version": + return { + key: option, + label: t("FinalizeVersion"), + icon: "images/history-finalized.react.svg", + onClick: this.finalizeVersion, + disabled: false, + }; + case "separator0": + case "separator1": + case "separator2": + case "separator3": + return { key: option, isSeparator: true }; + case "open-location": + return { + key: option, + label: t("OpenLocation"), + icon: "images/download-as.react.svg", + onClick: this.onOpenLocation, + disabled: false, + }; + case "mark-as-favorite": + return { + key: option, + label: t("MarkAsFavorite"), + icon: "images/favorites.react.svg", + onClick: this.onClickFavorite, + disabled: false, + "data-action": "mark", + action: "mark", + }; + case "block-unblock-version": + return { + key: option, + label: t("UnblockVersion"), + icon: "images/lock.react.svg", + onClick: this.lockFile, + disabled: false, + }; + case "sharing-settings": + return { + key: option, + label: t("SharingSettings"), + icon: "/static/images/catalog.share.react.svg", + onClick: this.onClickShare, + disabled: !isShareable, + }; + case "send-by-email": + return { + key: option, + label: t("SendByEmail"), + icon: "/static/images/mail.react.svg", + disabled: true, + }; + case "owner-change": + return { + key: option, + label: t("Translations:OwnerChange"), + icon: "/static/images/catalog.user.react.svg", + onClick: this.onOwnerChange, + disabled: false, + }; + case "link-for-portal-users": + return { + key: option, + label: t("LinkForPortalUsers"), + icon: "/static/images/invitation.link.react.svg", + onClick: this.onClickLinkForPortal, + disabled: false, + }; + case "fill-form": + return { + key: option, + label: t("Common:FillFormButton"), + icon: "/static/images/form.fill.rect.svg", + onClick: this.onClickLinkFillForm, + disabled: false, + }; + case "make-form": + return { + key: option, + label: t("Common:MakeForm"), + icon: "/static/images/form.plus.react.svg", + onClick: this.onClickMakeForm, + disabled: false, + }; + case "edit": + return { + key: option, + label: t("Common:EditButton"), + icon: "/static/images/access.edit.react.svg", + onClick: this.onClickLinkEdit, + disabled: false, + }; + case "preview": + return { + key: option, + label: t("Preview"), + icon: "/static/images/eye.react.svg", + onClick: this.onPreviewClick, + disabled: false, + }; + case "view": + return { + key: option, + label: t("Common:View"), + icon: "/static/images/eye.react.svg", + onClick: this.onMediaFileClick, + disabled: false, + }; + case "download": + return { + key: option, + label: t("Common:Download"), + icon: "images/download.react.svg", + onClick: this.onClickDownload, + disabled: false, + }; + case "download-as": + return { + key: option, + label: t("Translations:DownloadAs"), + icon: "images/download-as.react.svg", + onClick: this.onClickDownloadAs, + disabled: false, + }; + case "move-to": + return { + key: option, + label: t("MoveTo"), + icon: "images/move.react.svg", + onClick: this.onMoveAction, + disabled: false, + }; + case "restore": + return { + key: option, + label: t("Translations:Restore"), + icon: "images/move.react.svg", + onClick: this.onMoveAction, + disabled: false, + }; + case "copy-to": + return { + key: option, + label: t("Translations:Copy"), + icon: "/static/images/copy.react.svg", + onClick: this.onCopyAction, + disabled: false, + }; + case "copy": + return { + key: option, + label: t("Duplicate"), + icon: "/static/images/copy.react.svg", + onClick: this.onDuplicate, + disabled: false, + }; + case "rename": + return { + key: option, + label: t("Rename"), + icon: "images/rename.react.svg", + onClick: this.onClickRename, + disabled: false, + }; + case "change-thirdparty-info": + return { + key: option, + label: t("Translations:ThirdPartyInfo"), + icon: "/static/images/access.edit.react.svg", + onClick: this.onChangeThirdPartyInfo, + disabled: false, + }; + case "delete": + return { + key: option, + label: isRootThirdPartyFolder + ? t("Translations:DeleteThirdParty") + : t("Common:Delete"), + icon: "/static/images/catalog.trash.react.svg", + onClick: this.onClickDelete, + disabled: false, + }; + case "remove-from-favorites": + return { + key: option, + label: t("RemoveFromFavorites"), + icon: "images/favorites.react.svg", + onClick: this.onClickFavorite, + disabled: false, + "data-action": "remove", + action: "remove", + }; + case "unsubscribe": + return { + key: option, + label: t("RemoveFromList"), + icon: "images/remove.svg", + onClick: this.onClickUnsubscribe, + disabled: false, + }; + case "mark-read": + return { + key: option, + label: t("MarkRead"), + icon: "images/tick.rounded.svg", + onClick: this.onClickMarkRead, + disabled: false, + }; + default: + break; } - )(observer(WithContextOptions)); + + return undefined; + }); + }; + + render() { + const { actionType, actionId, actionExtension, item } = this.props; + const { id, fileExst, contextOptions } = item; + + const isEdit = + !!actionType && actionId === id && fileExst === actionExtension; + + const contextOptionsProps = + !isEdit && contextOptions && contextOptions.length > 0 + ? { + contextOptions: this.getFilesContextOptions(), + } + : {}; + + return ( + + ); + } + } + + return inject( + ( + { + auth, + dialogsStore, + filesActionsStore, + filesStore, + mediaViewerDataStore, + treeFoldersStore, + uploadDataStore, + versionHistoryStore, + infoPanelStore, + }, + { item } + ) => { + const { openDocEditor, fileActionStore, formatsStore } = filesStore; + const { + deleteItemAction, + downloadAction, + duplicateAction, + finalizeVersionAction, + lockFileAction, + markAsRead, + onSelectItem, + openLocationAction, + setFavoriteAction, + setThirdpartyInfo, + unsubscribeAction, + } = filesActionsStore; + const { setIsVisible } = infoPanelStore; + const { + setChangeOwnerPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + setDeleteThirdPartyDialogVisible, + setDownloadDialogVisible, + setMoveToPanelVisible, + setRemoveItem, + setSharingPanelVisible, + setUnsubscribe, + } = dialogsStore; + const { isTabletView, isDesktopClient } = auth.settingsStore; + const { setIsVerHistoryPanel, fetchFileVersions } = versionHistoryStore; + const { setAction, type, extension, id } = fileActionStore; + const { setMediaViewerData } = mediaViewerDataStore; + const { copyAsAction } = uploadDataStore; + const { formfillingDocs } = formatsStore.docserviceStore; + + const { isRecycleBinFolder, isShare } = treeFoldersStore; + const isShareFolder = isShare(item.rootFolderType); + + return { + openLocationAction, + setIsVisible, + setChangeOwnerPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + isTabletView, + setIsVerHistoryPanel, + fetchFileVersions, + homepage: config.homepage, + finalizeVersionAction, + setFavoriteAction, + lockFileAction, + openDocEditor, + downloadAction, + setDownloadDialogVisible, + duplicateAction, + setAction, + setThirdpartyInfo, + setMediaViewerData, + setRemoveItem, + setDeleteThirdPartyDialogVisible, + deleteItemAction, + onSelectItem, + setSharingPanelVisible, + actionType: type, + actionId: id, + actionExtension: extension, + isTrashFolder: isRecycleBinFolder, + isShareFolder, + markAsRead, + unsubscribeAction, + setDeleteDialogVisible, + setUnsubscribe, + isDesktop: isDesktopClient, + copyAsAction, + formfillingDocs, + }; + } + )(observer(WithContextOptions)); } diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 0ef88c425b..efff5d6953 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -1,457 +1,437 @@ +import React from "react"; +import { inject, observer } from "mobx-react"; +import toastr from "@appserver/components/toast/toastr"; +import { checkProtocol } from "../helpers/files-helpers"; import { AppServerConfig } from "@appserver/common/constants"; import { combineUrl } from "@appserver/common/utils"; -import toastr from "@appserver/components/toast/toastr"; -import { inject, observer } from "mobx-react"; -import React from "react"; +import config from "../../package.json"; import { isMobile } from "react-device-detect"; -import config from "../../package.json"; -import { checkProtocol } from "../helpers/files-helpers"; - export default function withFileActions(WrappedFileItem) { - class WithFileActions extends React.Component { - constructor(props) { - super(props); - } - - onContentFileSelect = (checked, file) => { - const { - selectRowAction, - infoPanelIsVisible, - showInfoPanel, - } = this.props; - if (!file || file.id === -1) return; - selectRowAction(checked, file); - if (!infoPanelIsVisible) showInfoPanel(); - }; - - fileContextClick = () => { - if (!this.props.infoPanelIsVisible) this.props.showInfoPanel(); - - const { onSelectItem, item } = this.props; - const { id, isFolder } = item; - - id !== -1 && onSelectItem({ id, isFolder }); - }; - - onHideContextMenu = () => { - //this.props.setBufferSelection(null); - }; - - onDropZoneUpload = (files, uploadToFolder) => { - const { t, dragging, setDragging, startUpload } = this.props; - - dragging && setDragging(false); - startUpload(files, uploadToFolder, t); - }; - - onDrop = (items) => { - const { fileExst, id } = this.props.item; - - if (!fileExst) { - this.onDropZoneUpload(items, id); - } else { - this.onDropZoneUpload(items); - } - }; - - onMouseDown = (e) => { - const { - draggable, - setTooltipPosition, - setStartDrag, - isPrivacy, - isTrashFolder, - onSelectItem, - item, - setBufferSelection, - isActive, - } = this.props; - - const { id, isFolder, isThirdPartyFolder } = item; - - const notSelectable = e.target.classList.contains("not-selectable"); - const isFileName = e.target.classList.contains("item-file-name"); - - if ( - isPrivacy || - isTrashFolder || - (!draggable && !isFileName && !isActive) - ) - return e; - - if ( - window.innerWidth < 1025 || - notSelectable || - isMobile || - isThirdPartyFolder - ) { - return e; - } - - // if (!draggable) { - // id !== -1 && onSelectItem({ id, isFolder }); - // } - - const mouseButton = e.which - ? e.which !== 1 - : e.button - ? e.button !== 0 - : false; - const label = e.currentTarget.getAttribute("label"); - if (mouseButton || e.currentTarget.tagName !== "DIV" || label) { - return e; - } - - e.preventDefault(); - setTooltipPosition(e.pageX, e.pageY); - !isFileName && setStartDrag(true); - !isActive && setBufferSelection(null); - }; - - onMarkAsRead = (id) => - this.props.markAsRead([], [`${id}`], this.props.item); - - onMouseClick = (e) => { - const { - viewAs, - isItemsSelected, - infoPanelIsVisible, - showInfoPanel, - } = this.props; - - if ( - e.target.closest(".checkbox") || - e.target.tagName === "INPUT" || - e.target.tagName === "SPAN" || - e.target.tagName === "A" || - e.target.closest(".expandButton") || - e.target.closest(".badges") || - e.button !== 0 /* || - isItemsSelected */ - ) - return; - - if (viewAs === "tile") { - if ( - e.target.closest(".edit-button") || - e.target.tagName === "IMG" - ) - return; - - if (e.detail === 1) this.fileContextClick(); - } else { - this.fileContextClick(); - } - - if (!infoPanelIsVisible) showInfoPanel(); - }; - onFilesClick = (e) => { - const { - isDesktop, - //parentFolder, - setIsLoading, - fetchFiles, - isMediaOrImage, - canConvert, - canWebEdit, - canViewedDocs, - item, - isTrashFolder, - isPrivacy, - openDocEditor, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - setMediaViewerData, - setConvertItem, - setConvertDialogVisible, - setNewBadgeCount, - } = this.props; - const { - id, - viewUrl, - providerKey, - fileStatus, - encrypted, - isFolder, - } = item; - if (encrypted && isPrivacy) return checkProtocol(item.id, true); - - if (isTrashFolder) return; - if ( - (e && e.target.tagName === "INPUT") || - e.target.closest(".badges") - ) - return; - - e.preventDefault(); - - if (isFolder) { - setIsLoading(true); - //addExpandedKeys(parentFolder + ""); - - fetchFiles(id, null, true, false) - .then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createNewExpandedKeys( - pathParts - ); - setExpandedKeys(newExpandedKeys); - - setNewBadgeCount(item); - }) - .catch((err) => { - toastr.error(err); - setIsLoading(false); - }) - .finally(() => setIsLoading(false)); - } else { - if (canConvert) { - setConvertItem(item); - setConvertDialogVisible(true); - return; - } - - if (fileStatus === 2) this.onMarkAsRead(id); - - if (canWebEdit || canViewedDocs) { - let tab = - !isDesktop && !isFolder - ? window.open( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - "/doceditor" - ), - "_blank" - ) - : null; - - return openDocEditor(id, providerKey, tab); - } - - if (isMediaOrImage) { - setMediaViewerData({ visible: true, id }); - return; - } - - return window.open(viewUrl, "_self"); - } - }; - - render() { - const { - item, - isTrashFolder, - draggable, - allowShareIn, - isPrivacy, - actionType, - actionExtension, - actionId, - sectionWidth, - checked, - dragging, - isFolder, - isDesktop, - personal, - canWebEdit, - canViewedDocs, - } = this.props; - const { fileExst, access, id } = item; - - const isEdit = - actionType !== null && - actionId === id && - fileExst === actionExtension; - - const isDragging = - isFolder && access < 2 && !isTrashFolder && !isPrivacy; - - let className = isDragging ? " droppable" : ""; - if (draggable) className += " draggable"; - - let value = !item.isFolder ? `file_${id}` : `folder_${id}`; - value += draggable ? "_draggable" : ""; - - const isShareable = allowShareIn && item.canShare; - - const isMobileView = sectionWidth < 500; - - const displayShareButton = isMobileView - ? "26px" - : !isShareable - ? "38px" - : "96px"; - - const showShare = - !isShareable || - isEdit || - (isPrivacy && (!isDesktop || !fileExst)) || - (personal && !canWebEdit && !canViewedDocs) - ? false - : true; - - const checkedProps = isEdit || id <= 0 ? false : checked; - - return ( - - ); - } + class WithFileActions extends React.Component { + constructor(props) { + super(props); } - return inject( - ( - { - auth, - filesActionsStore, - dialogsStore, - treeFoldersStore, - //selectedFolderStore, - filesStore, - uploadDataStore, - formatsStore, - mediaViewerDataStore, - infoPanelStore, - }, - { item, t, history } - ) => { - const { - selectRowAction, - onSelectItem, - markAsRead, - setNewBadgeCount, - } = filesActionsStore; - const { - setSharingPanelVisible, - setConvertDialogVisible, - setConvertItem, - } = dialogsStore; - const { - isPrivacyFolder, - isRecycleBinFolder, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - } = treeFoldersStore; - const { - dragging, - setDragging, - selection, - setTooltipPosition, - setStartDrag, - fileActionStore, - isFileSelected, - setIsLoading, - fetchFiles, - openDocEditor, - getFolderInfo, - viewAs, - bufferSelection, - setBufferSelection, - } = filesStore; + onContentFileSelect = (checked, file) => { + const { selectRowAction, infoPanelIsVisible, showInfoPanel } = this.props; + if (!file || file.id === -1) return; + selectRowAction(checked, file); + if (!infoPanelIsVisible) showInfoPanel(); + }; - const { startUpload } = uploadDataStore; - const { type, extension, id } = fileActionStore; - const { mediaViewersFormatsStore, docserviceStore } = formatsStore; - const { setMediaViewerData } = mediaViewerDataStore; - const { isVisible, setVisible } = infoPanelStore; + fileContextClick = () => { + if (!this.props.infoPanelIsVisible) this.props.showInfoPanel(); - const selectedItem = selection.find( - (x) => x.id === item.id && x.fileExst === item.fileExst - ); + const { onSelectItem, item } = this.props; + const { id, isFolder } = item; - const draggable = - !isRecycleBinFolder && selectedItem && selectedItem.id !== id; + id !== -1 && onSelectItem({ id, isFolder }); + }; - const isFolder = selectedItem - ? false - : !item.isFolder - ? false - : true; + onHideContextMenu = () => { + //this.props.setBufferSelection(null); + }; - const isMediaOrImage = mediaViewersFormatsStore.isMediaOrImage( - item.fileExst - ); + onDropZoneUpload = (files, uploadToFolder) => { + const { t, dragging, setDragging, startUpload } = this.props; - const canWebEdit = docserviceStore.canWebEdit(item.fileExst); - const canConvert = docserviceStore.canConvert(item.fileExst); - const canViewedDocs = docserviceStore.canViewedDocs(item.fileExst); + dragging && setDragging(false); + startUpload(files, uploadToFolder, t); + }; - const isActive = - bufferSelection && - bufferSelection.id === item.id && - bufferSelection.fileExst === item.fileExst && - !selection.length; // need for select row item + onDrop = (items) => { + const { fileExst, id } = this.props.item; - return { - t, - item, - selectRowAction, - onSelectItem, - setSharingPanelVisible, - isPrivacy: isPrivacyFolder, - dragging, - setDragging, - startUpload, - draggable, - setTooltipPosition, - setStartDrag, - history, - isFolder, - allowShareIn: filesStore.canShare, - actionType: type, - actionExtension: extension, - actionId: id, - checked: isFileSelected(item.id, item.parentId), - //parentFolder: selectedFolderStore.parentId, - setIsLoading, - fetchFiles, - isMediaOrImage, - canWebEdit, - canViewedDocs, - canConvert, - isTrashFolder: isRecycleBinFolder, - openDocEditor, - //addExpandedKeys, - setExpandedKeys, - createNewExpandedKeys, - setMediaViewerData, - getFolderInfo, - markAsRead, - viewAs, - setConvertItem, - setConvertDialogVisible, - isDesktop: auth.settingsStore.isDesktopClient, - personal: auth.settingsStore.personal, - isItemsSelected: selection.length > 0, - setNewBadgeCount, - isActive, - setBufferSelection, - bufferSelection, - isInfoPanelVisible: isVisible, - showInfoPanel: setVisible, - }; + if (!fileExst) { + this.onDropZoneUpload(items, id); + } else { + this.onDropZoneUpload(items); + } + }; + + onMouseDown = (e) => { + const { + draggable, + setTooltipPosition, + setStartDrag, + isPrivacy, + isTrashFolder, + onSelectItem, + item, + setBufferSelection, + isActive, + } = this.props; + + const { id, isFolder, isThirdPartyFolder } = item; + + const notSelectable = e.target.classList.contains("not-selectable"); + const isFileName = e.target.classList.contains("item-file-name"); + + if ( + isPrivacy || + isTrashFolder || + (!draggable && !isFileName && !isActive) + ) + return e; + + if ( + window.innerWidth < 1025 || + notSelectable || + isMobile || + isThirdPartyFolder + ) { + return e; + } + + // if (!draggable) { + // id !== -1 && onSelectItem({ id, isFolder }); + // } + + const mouseButton = e.which + ? e.which !== 1 + : e.button + ? e.button !== 0 + : false; + const label = e.currentTarget.getAttribute("label"); + if (mouseButton || e.currentTarget.tagName !== "DIV" || label) { + return e; + } + + e.preventDefault(); + setTooltipPosition(e.pageX, e.pageY); + !isFileName && setStartDrag(true); + !isActive && setBufferSelection(null); + }; + + onMarkAsRead = (id) => + this.props.markAsRead([], [`${id}`], this.props.item); + + onMouseClick = (e) => { + const { + viewAs, + isItemsSelected, + infoPanelIsVisible, + showInfoPanel, + } = this.props; + + if ( + e.target.closest(".checkbox") || + e.target.tagName === "INPUT" || + e.target.tagName === "SPAN" || + e.target.tagName === "A" || + e.target.closest(".expandButton") || + e.target.closest(".badges") || + e.button !== 0 /* || + isItemsSelected */ + ) + return; + + if (viewAs === "tile") { + if (e.target.closest(".edit-button") || e.target.tagName === "IMG") + return; + + if (e.detail === 1) this.fileContextClick(); + } else { + this.fileContextClick(); + } + + if (!infoPanelIsVisible) showInfoPanel(); + }; + onFilesClick = (e) => { + const { + isDesktop, + //parentFolder, + setIsLoading, + fetchFiles, + isMediaOrImage, + canConvert, + canWebEdit, + canViewedDocs, + item, + isTrashFolder, + isPrivacy, + openDocEditor, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + setMediaViewerData, + setConvertItem, + setConvertDialogVisible, + setNewBadgeCount, + } = this.props; + const { + id, + viewUrl, + providerKey, + fileStatus, + encrypted, + isFolder, + } = item; + if (encrypted && isPrivacy) return checkProtocol(item.id, true); + + if (isTrashFolder) return; + if ((e && e.target.tagName === "INPUT") || e.target.closest(".badges")) + return; + + e.preventDefault(); + + if (isFolder) { + setIsLoading(true); + //addExpandedKeys(parentFolder + ""); + + fetchFiles(id, null, true, false) + .then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createNewExpandedKeys(pathParts); + setExpandedKeys(newExpandedKeys); + + setNewBadgeCount(item); + }) + .catch((err) => { + toastr.error(err); + setIsLoading(false); + }) + .finally(() => setIsLoading(false)); + } else { + if (canConvert) { + setConvertItem(item); + setConvertDialogVisible(true); + return; } - )(observer(WithFileActions)); + + if (fileStatus === 2) this.onMarkAsRead(id); + + if (canWebEdit || canViewedDocs) { + let tab = + !isDesktop && !isFolder + ? window.open( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + "/doceditor" + ), + "_blank" + ) + : null; + + return openDocEditor(id, providerKey, tab); + } + + if (isMediaOrImage) { + setMediaViewerData({ visible: true, id }); + return; + } + + return window.open(viewUrl, "_self"); + } + }; + + render() { + const { + item, + isTrashFolder, + draggable, + allowShareIn, + isPrivacy, + actionType, + actionExtension, + actionId, + sectionWidth, + checked, + dragging, + isFolder, + isDesktop, + personal, + canWebEdit, + canViewedDocs, + } = this.props; + const { fileExst, access, id } = item; + + const isEdit = + actionType !== null && actionId === id && fileExst === actionExtension; + + const isDragging = isFolder && access < 2 && !isTrashFolder && !isPrivacy; + + let className = isDragging ? " droppable" : ""; + if (draggable) className += " draggable"; + + let value = !item.isFolder ? `file_${id}` : `folder_${id}`; + value += draggable ? "_draggable" : ""; + + const isShareable = allowShareIn && item.canShare; + + const isMobileView = sectionWidth < 500; + + const displayShareButton = isMobileView + ? "26px" + : !isShareable + ? "38px" + : "96px"; + + const showShare = + !isShareable || + isEdit || + (isPrivacy && (!isDesktop || !fileExst)) || + (personal && !canWebEdit && !canViewedDocs) + ? false + : true; + + const checkedProps = isEdit || id <= 0 ? false : checked; + + return ( + + ); + } + } + + return inject( + ( + { + auth, + filesActionsStore, + dialogsStore, + treeFoldersStore, + //selectedFolderStore, + filesStore, + uploadDataStore, + formatsStore, + mediaViewerDataStore, + infoPanelStore, + }, + { item, t, history } + ) => { + const { + selectRowAction, + onSelectItem, + markAsRead, + setNewBadgeCount, + } = filesActionsStore; + const { + setSharingPanelVisible, + setConvertDialogVisible, + setConvertItem, + } = dialogsStore; + const { + isPrivacyFolder, + isRecycleBinFolder, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + } = treeFoldersStore; + const { + dragging, + setDragging, + selection, + setTooltipPosition, + setStartDrag, + fileActionStore, + isFileSelected, + setIsLoading, + fetchFiles, + openDocEditor, + getFolderInfo, + viewAs, + bufferSelection, + setBufferSelection, + } = filesStore; + + const { startUpload } = uploadDataStore; + const { type, extension, id } = fileActionStore; + const { mediaViewersFormatsStore, docserviceStore } = formatsStore; + const { setMediaViewerData } = mediaViewerDataStore; + const { isVisible, setVisible } = infoPanelStore; + + const selectedItem = selection.find( + (x) => x.id === item.id && x.fileExst === item.fileExst + ); + + const draggable = + !isRecycleBinFolder && selectedItem && selectedItem.id !== id; + + const isFolder = selectedItem ? false : !item.isFolder ? false : true; + + const isMediaOrImage = mediaViewersFormatsStore.isMediaOrImage( + item.fileExst + ); + + const canWebEdit = docserviceStore.canWebEdit(item.fileExst); + const canConvert = docserviceStore.canConvert(item.fileExst); + const canViewedDocs = docserviceStore.canViewedDocs(item.fileExst); + + const isActive = + bufferSelection && + bufferSelection.id === item.id && + bufferSelection.fileExst === item.fileExst && + !selection.length; // need for select row item + + return { + t, + item, + selectRowAction, + onSelectItem, + setSharingPanelVisible, + isPrivacy: isPrivacyFolder, + dragging, + setDragging, + startUpload, + draggable, + setTooltipPosition, + setStartDrag, + history, + isFolder, + allowShareIn: filesStore.canShare, + actionType: type, + actionExtension: extension, + actionId: id, + checked: isFileSelected(item.id, item.parentId), + //parentFolder: selectedFolderStore.parentId, + setIsLoading, + fetchFiles, + isMediaOrImage, + canWebEdit, + canViewedDocs, + canConvert, + isTrashFolder: isRecycleBinFolder, + openDocEditor, + //addExpandedKeys, + setExpandedKeys, + createNewExpandedKeys, + setMediaViewerData, + getFolderInfo, + markAsRead, + viewAs, + setConvertItem, + setConvertDialogVisible, + isDesktop: auth.settingsStore.isDesktopClient, + personal: auth.settingsStore.personal, + isItemsSelected: selection.length > 0, + setNewBadgeCount, + isActive, + setBufferSelection, + bufferSelection, + isInfoPanelVisible: isVisible, + showInfoPanel: setVisible, + }; + } + )(observer(WithFileActions)); } 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 df08cfc79a..715cd5e13d 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 @@ -13,249 +13,239 @@ import { Consumer } from "@appserver/components/utils/context"; let currentDroppable = null; const SectionBodyContent = (props) => { - const { - t, - tReady, - fileActionId, - isEmptyFilesList, - folderId, - dragging, - setDragging, - startDrag, - setStartDrag, - setTooltipPosition, - isRecycleBinFolder, - moveDragItems, - viewAs, - setSelection, - setBufferSelection, - tooltipPageX, - tooltipPageY, - } = props; + const { + t, + tReady, + fileActionId, + isEmptyFilesList, + folderId, + dragging, + setDragging, + startDrag, + setStartDrag, + setTooltipPosition, + isRecycleBinFolder, + moveDragItems, + viewAs, + setSelection, + setBufferSelection, + tooltipPageX, + tooltipPageY, + } = props; - useEffect(() => { - const customScrollElm = document.querySelector( - "#customScrollBar > .scroll-body" - ); - - if (isMobile) { - customScrollElm && customScrollElm.scrollTo(0, 0); - } - - !isMobile && window.addEventListener("mousedown", onMouseDown); - startDrag && window.addEventListener("mouseup", onMouseUp); - startDrag && document.addEventListener("mousemove", onMouseMove); - - document.addEventListener("dragover", onDragOver); - document.addEventListener("dragleave", onDragLeaveDoc); - document.addEventListener("drop", onDropEvent); - - return () => { - window.removeEventListener("mousedown", onMouseDown); - window.removeEventListener("mouseup", onMouseUp); - document.removeEventListener("mousemove", onMouseMove); - - document.removeEventListener("dragover", onDragOver); - document.removeEventListener("dragleave", onDragLeaveDoc); - document.removeEventListener("drop", onDropEvent); - }; - }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); - - const onMouseDown = (e) => { - if ( - e.target.closest(".scroll-body") && - !e.target.closest(".files-item") && - !e.target.closest(".not-selectable") && - !e.target.closest(".table-container_group-menu") && - !e.target.closest(".info-panel") - ) { - setSelection([]); - setBufferSelection(null); - } - }; - - const onMouseMove = (e) => { - if ( - Math.abs(e.pageX - tooltipPageX) < 5 && - Math.abs(e.pageY - tooltipPageY) < 5 - ) { - return false; - } - - if (!dragging) { - document.body.classList.add("drag-cursor"); - setDragging(true); - } - - setTooltipPosition(e.pageX, e.pageY); - const wrapperElement = document.elementFromPoint(e.clientX, e.clientY); - if (!wrapperElement) { - return; - } - - const droppable = wrapperElement.closest(".droppable"); - if (currentDroppable !== droppable) { - if (currentDroppable) { - if (viewAs === "table") { - const value = currentDroppable.getAttribute("value"); - const classElements = document.getElementsByClassName( - value - ); - - for (let cl of classElements) { - cl.classList.remove("droppable-hover"); - } - } else { - currentDroppable.classList.remove("droppable-hover"); - } - } - currentDroppable = droppable; - - if (currentDroppable) { - if (viewAs === "table") { - const value = currentDroppable.getAttribute("value"); - const classElements = document.getElementsByClassName( - value - ); - - for (let cl of classElements) { - cl.classList.add("droppable-hover"); - } - } else { - currentDroppable.classList.add("droppable-hover"); - currentDroppable = droppable; - } - } - } - }; - - const onMouseUp = (e) => { - document.body.classList.remove("drag-cursor"); - - const treeElem = e.target.closest(".tree-drag"); - const treeDataValue = treeElem?.dataset?.value; - const splitValue = treeDataValue && treeDataValue.split(" "); - const isDragging = splitValue && splitValue.includes("dragging"); - const treeValue = isDragging ? splitValue[0] : null; - - const elem = e.target.closest(".droppable"); - const title = elem && elem.dataset.title; - const value = elem && elem.getAttribute("value"); - if ((!value && !treeValue) || isRecycleBinFolder) { - setDragging(false); - setStartDrag(false); - return; - } - - const folderId = value ? value.split("_")[1] : treeValue; - - setStartDrag(false); - setDragging(false); - onMoveTo(folderId, title); - return; - }; - - const onMoveTo = (destFolderId, title) => { - const id = isNaN(+destFolderId) ? destFolderId : +destFolderId; - moveDragItems(id, title, { - copy: t("Translations:CopyOperation"), - move: t("Translations:MoveToOperation"), - }); //TODO: then catch - }; - - const onDropEvent = () => { - setDragging(false); - }; - - const onDragOver = (e) => { - e.preventDefault(); - if ( - e.dataTransfer.items.length > 0 && - e.dataTransfer.dropEffect !== "none" - ) { - setDragging(true); - } - }; - - const onDragLeaveDoc = (e) => { - e.preventDefault(); - if (!e.relatedTarget || !e.dataTransfer.items.length) { - setDragging(false); - } - }; - - //console.log("Files Home SectionBodyContent render", props); - - return ( - - {(context) => - (!fileActionId && isEmptyFilesList) || null ? ( - - ) : viewAs === "tile" ? ( - - ) : viewAs === "table" ? ( - - ) : ( - - ) - } - + useEffect(() => { + const customScrollElm = document.querySelector( + "#customScrollBar > .scroll-body" ); + + if (isMobile) { + customScrollElm && customScrollElm.scrollTo(0, 0); + } + + !isMobile && window.addEventListener("mousedown", onMouseDown); + startDrag && window.addEventListener("mouseup", onMouseUp); + startDrag && document.addEventListener("mousemove", onMouseMove); + + document.addEventListener("dragover", onDragOver); + document.addEventListener("dragleave", onDragLeaveDoc); + document.addEventListener("drop", onDropEvent); + + return () => { + window.removeEventListener("mousedown", onMouseDown); + window.removeEventListener("mouseup", onMouseUp); + document.removeEventListener("mousemove", onMouseMove); + + document.removeEventListener("dragover", onDragOver); + document.removeEventListener("dragleave", onDragLeaveDoc); + document.removeEventListener("drop", onDropEvent); + }; + }, [onMouseUp, onMouseMove, startDrag, folderId, viewAs]); + + const onMouseDown = (e) => { + if ( + e.target.closest(".scroll-body") && + !e.target.closest(".files-item") && + !e.target.closest(".not-selectable") && + !e.target.closest(".table-container_group-menu") && + !e.target.closest(".info-panel") + ) { + setSelection([]); + setBufferSelection(null); + } + }; + + const onMouseMove = (e) => { + if ( + Math.abs(e.pageX - tooltipPageX) < 5 && + Math.abs(e.pageY - tooltipPageY) < 5 + ) { + return false; + } + + if (!dragging) { + document.body.classList.add("drag-cursor"); + setDragging(true); + } + + setTooltipPosition(e.pageX, e.pageY); + const wrapperElement = document.elementFromPoint(e.clientX, e.clientY); + if (!wrapperElement) { + return; + } + + const droppable = wrapperElement.closest(".droppable"); + if (currentDroppable !== droppable) { + if (currentDroppable) { + if (viewAs === "table") { + const value = currentDroppable.getAttribute("value"); + const classElements = document.getElementsByClassName(value); + + for (let cl of classElements) { + cl.classList.remove("droppable-hover"); + } + } else { + currentDroppable.classList.remove("droppable-hover"); + } + } + currentDroppable = droppable; + + if (currentDroppable) { + if (viewAs === "table") { + const value = currentDroppable.getAttribute("value"); + const classElements = document.getElementsByClassName(value); + + for (let cl of classElements) { + cl.classList.add("droppable-hover"); + } + } else { + currentDroppable.classList.add("droppable-hover"); + currentDroppable = droppable; + } + } + } + }; + + const onMouseUp = (e) => { + document.body.classList.remove("drag-cursor"); + + const treeElem = e.target.closest(".tree-drag"); + const treeDataValue = treeElem?.dataset?.value; + const splitValue = treeDataValue && treeDataValue.split(" "); + const isDragging = splitValue && splitValue.includes("dragging"); + const treeValue = isDragging ? splitValue[0] : null; + + const elem = e.target.closest(".droppable"); + const title = elem && elem.dataset.title; + const value = elem && elem.getAttribute("value"); + if ((!value && !treeValue) || isRecycleBinFolder) { + setDragging(false); + setStartDrag(false); + return; + } + + const folderId = value ? value.split("_")[1] : treeValue; + + setStartDrag(false); + setDragging(false); + onMoveTo(folderId, title); + return; + }; + + const onMoveTo = (destFolderId, title) => { + const id = isNaN(+destFolderId) ? destFolderId : +destFolderId; + moveDragItems(id, title, { + copy: t("Translations:CopyOperation"), + move: t("Translations:MoveToOperation"), + }); //TODO: then catch + }; + + const onDropEvent = () => { + setDragging(false); + }; + + const onDragOver = (e) => { + e.preventDefault(); + if ( + e.dataTransfer.items.length > 0 && + e.dataTransfer.dropEffect !== "none" + ) { + setDragging(true); + } + }; + + const onDragLeaveDoc = (e) => { + e.preventDefault(); + if (!e.relatedTarget || !e.dataTransfer.items.length) { + setDragging(false); + } + }; + + //console.log("Files Home SectionBodyContent render", props); + + return ( + + {(context) => + (!fileActionId && isEmptyFilesList) || null ? ( + + ) : viewAs === "tile" ? ( + + ) : viewAs === "table" ? ( + + ) : ( + + ) + } + + ); }; export default inject( - ({ - filesStore, - selectedFolderStore, - treeFoldersStore, - filesActionsStore, - }) => { - const { - fileActionStore, - isEmptyFilesList, - dragging, - setDragging, - viewAs, - setTooltipPosition, - startDrag, - setStartDrag, - setSelection, - tooltipPageX, - tooltipPageY, - setBufferSelection, - } = filesStore; + ({ + filesStore, + selectedFolderStore, + treeFoldersStore, + filesActionsStore, + }) => { + const { + fileActionStore, + isEmptyFilesList, + dragging, + setDragging, + viewAs, + setTooltipPosition, + startDrag, + setStartDrag, + setSelection, + tooltipPageX, + tooltipPageY, + setBufferSelection, + } = filesStore; - return { - dragging, - startDrag, - setStartDrag, - fileActionId: fileActionStore.id, - isEmptyFilesList, - setDragging, - folderId: selectedFolderStore.id, - setTooltipPosition, - isRecycleBinFolder: treeFoldersStore.isRecycleBinFolder, - moveDragItems: filesActionsStore.moveDragItems, - viewAs, - setSelection, - setBufferSelection, - tooltipPageX, - tooltipPageY, - }; - } + return { + dragging, + startDrag, + setStartDrag, + fileActionId: fileActionStore.id, + isEmptyFilesList, + setDragging, + folderId: selectedFolderStore.id, + setTooltipPosition, + isRecycleBinFolder: treeFoldersStore.isRecycleBinFolder, + moveDragItems: filesActionsStore.moveDragItems, + viewAs, + setSelection, + setBufferSelection, + tooltipPageX, + tooltipPageY, + }; + } )( - withRouter( - withTranslation(["Home", "Common", "Translations"])( - withLoader(observer(SectionBodyContent))() - ) + withRouter( + withTranslation(["Home", "Common", "Translations"])( + withLoader(observer(SectionBodyContent))() ) + ) ); diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index c0fe780afe..5939482e4d 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -14,9 +14,9 @@ import { withRouter } from "react-router"; import config from "../../../package.json"; import { - ArticleBodyContent, - ArticleHeaderContent, - ArticleMainButtonContent, + ArticleBodyContent, + ArticleHeaderContent, + ArticleMainButtonContent, } from "../../components/Article"; import DragTooltip from "../../components/DragTooltip"; import { createTreeFolders } from "../../helpers/files-helpers"; @@ -24,451 +24,436 @@ import { InfoPanelBodyContent } from "./InfoPanel"; import { InfoPanelHeaderContent } from "./InfoPanel"; import MediaViewer from "./MediaViewer"; import { - SectionBodyContent, - SectionFilterContent, - SectionHeaderContent, - SectionPagingContent, + SectionBodyContent, + SectionFilterContent, + SectionHeaderContent, + SectionPagingContent, } from "./Section"; class PureHome extends React.Component { - componentDidMount() { - const { - fetchFiles, - homepage, - setIsLoading, - setFirstLoad, - expandedKeys, - setExpandedKeys, - setToPreviewFile, - mediaViewersFormatsStore, - getFileInfo, - } = this.props; + componentDidMount() { + const { + fetchFiles, + homepage, + setIsLoading, + setFirstLoad, + expandedKeys, + setExpandedKeys, + setToPreviewFile, + mediaViewersFormatsStore, + getFileInfo, + } = this.props; - const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gmi"); //TODO: Always find? - const match = window.location.pathname.match(reg); - let filterObj = null; + const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gmi"); //TODO: Always find? + const match = window.location.pathname.match(reg); + let filterObj = null; - if (window.location.href.indexOf("/files/#preview") > 1) { - const pathname = window.location.href; - const fileId = pathname.slice(pathname.indexOf("#preview") + 9); + if (window.location.href.indexOf("/files/#preview") > 1) { + const pathname = window.location.href; + const fileId = pathname.slice(pathname.indexOf("#preview") + 9); - getFileInfo(fileId) - .then((data) => { - const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( - data.fileExst - ); - const file = { ...data, canOpenPlayer }; - setToPreviewFile(file, true); - }) - .catch((err) => { - toastr.error(err); - this.fetchDefaultFiles(); - }); - - return; - } - - if (match && match.length > 0) { - filterObj = FilesFilter.getFilter(window.location); - - if (!filterObj) { - setIsLoading(true); - this.fetchDefaultFiles(); - - return; - } - } - - if (!filterObj) return; - - let dataObj = { filter: filterObj }; - - if (filterObj && filterObj.authorType) { - const authorType = filterObj.authorType; - const indexOfUnderscore = authorType.indexOf("_"); - const type = authorType.slice(0, indexOfUnderscore); - const itemId = authorType.slice(indexOfUnderscore + 1); - - if (itemId) { - dataObj = { - type, - itemId, - filter: filterObj, - }; - } else { - filterObj.authorType = null; - dataObj = { filter: filterObj }; - } - } - - if (!dataObj) return; - - const { filter, itemId, type } = dataObj; - const newFilter = filter ? filter.clone() : FilesFilter.getDefault(); - const requests = [Promise.resolve(newFilter)]; - - if (type === "group") { - requests.push(getGroup(itemId)); - } else if (type === "user") { - requests.push(getUserById(itemId)); - } - - setIsLoading(true); - - axios - .all(requests) - .catch((err) => { - Promise.resolve(FilesFilter.getDefault()); - console.warn("Filter restored by default", err); - }) - .then((data) => { - const filter = data[0]; - const result = data[1]; - if (result) { - const type = result.displayName ? "user" : "group"; - const selectedItem = { - key: result.id, - label: - type === "user" ? result.displayName : result.name, - type, - }; - filter.selectedItem = selectedItem; - } - - if (filter) { - const folderId = filter.folder; - //console.log("filter", filter); - - return fetchFiles(folderId, filter).then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createTreeFolders( - pathParts, - expandedKeys - ); - setExpandedKeys(newExpandedKeys); - }); - } - - return Promise.resolve(); - }) - .finally(() => { - setIsLoading(false); - setFirstLoad(false); - }); - } - - fetchDefaultFiles = () => { - const { - isVisitor, - fetchFiles, - setIsLoading, - setFirstLoad, - } = this.props; - const filterObj = FilesFilter.getDefault(); - const folderId = isVisitor ? "@common" : filterObj.folder; - - fetchFiles(folderId).finally(() => { - setIsLoading(false); - setFirstLoad(false); + getFileInfo(fileId) + .then((data) => { + const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( + data.fileExst + ); + const file = { ...data, canOpenPlayer }; + setToPreviewFile(file, true); + }) + .catch((err) => { + toastr.error(err); + this.fetchDefaultFiles(); }); - }; - onDrop = (files, uploadToFolder) => { - const { t, startUpload, setDragging, dragging } = this.props; - dragging && setDragging(false); - startUpload(files, uploadToFolder, t); - }; - - showOperationToast = (type, qty, title) => { - const { t } = this.props; - switch (type) { - case "move": - if (qty > 1) { - return toastr.success( - - {{ qty }} elements has been moved - - ); - } - return toastr.success( - - {{ title }} moved - - ); - case "duplicate": - if (qty > 1) { - return toastr.success( - - {{ qty }} elements copied - - ); - } - return toastr.success( - - {{ title }} copied - - ); - default: - break; - } - }; - - showUploadPanel = () => { - const { - uploaded, - converted, - uploadPanelVisible, - setUploadPanelVisible, - clearPrimaryProgressData, - primaryProgressDataVisible, - } = this.props; - setUploadPanelVisible(!uploadPanelVisible); - - if (primaryProgressDataVisible && uploaded && converted) - clearPrimaryProgressData(); - }; - componentDidUpdate(prevProps) { - const { - isProgressFinished, - secondaryProgressDataStoreIcon, - selectionLength, - selectionTitle, - } = this.props; - - if (this.props.isHeaderVisible !== prevProps.isHeaderVisible) { - this.props.setHeaderVisible(this.props.isHeaderVisible); - } - if ( - isProgressFinished && - isProgressFinished !== prevProps.isProgressFinished - ) { - this.showOperationToast( - secondaryProgressDataStoreIcon, - selectionLength, - selectionTitle - ); - } + return; } - render() { - //console.log("Home render"); - const { - viewAs, - fileActionId, - firstLoad, - isHeaderVisible, - isPrivacyFolder, - isRecycleBinFolder, + if (match && match.length > 0) { + filterObj = FilesFilter.getFilter(window.location); - primaryProgressDataVisible, - primaryProgressDataPercent, - primaryProgressDataIcon, - primaryProgressDataAlert, + if (!filterObj) { + setIsLoading(true); + this.fetchDefaultFiles(); - secondaryProgressDataStoreVisible, - secondaryProgressDataStorePercent, - secondaryProgressDataStoreIcon, - secondaryProgressDataStoreAlert, + return; + } + } - dragging, - tReady, - } = this.props; + if (!filterObj) return; - return ( - <> - - - - - - + let dataObj = { filter: filterObj }; - - - + if (filterObj && filterObj.authorType) { + const authorType = filterObj.authorType; + const indexOfUnderscore = authorType.indexOf("_"); + const type = authorType.slice(0, indexOfUnderscore); + const itemId = authorType.slice(indexOfUnderscore + 1); - - - + if (itemId) { + dataObj = { + type, + itemId, + filter: filterObj, + }; + } else { + filterObj.authorType = null; + dataObj = { filter: filterObj }; + } + } - - - + if (!dataObj) return; - - - + const { filter, itemId, type } = dataObj; + const newFilter = filter ? filter.clone() : FilesFilter.getDefault(); + const requests = [Promise.resolve(newFilter)]; - - - + if (type === "group") { + requests.push(getGroup(itemId)); + } else if (type === "user") { + requests.push(getUserById(itemId)); + } - - - + setIsLoading(true); - - - + axios + .all(requests) + .catch((err) => { + Promise.resolve(FilesFilter.getDefault()); + console.warn("Filter restored by default", err); + }) + .then((data) => { + const filter = data[0]; + const result = data[1]; + if (result) { + const type = result.displayName ? "user" : "group"; + const selectedItem = { + key: result.id, + label: type === "user" ? result.displayName : result.name, + type, + }; + filter.selectedItem = selectedItem; + } - - - - - + if (filter) { + const folderId = filter.folder; + //console.log("filter", filter); + + return fetchFiles(folderId, filter).then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createTreeFolders(pathParts, expandedKeys); + setExpandedKeys(newExpandedKeys); + }); + } + + return Promise.resolve(); + }) + .finally(() => { + setIsLoading(false); + setFirstLoad(false); + }); + } + + fetchDefaultFiles = () => { + const { isVisitor, fetchFiles, setIsLoading, setFirstLoad } = this.props; + const filterObj = FilesFilter.getDefault(); + const folderId = isVisitor ? "@common" : filterObj.folder; + + fetchFiles(folderId).finally(() => { + setIsLoading(false); + setFirstLoad(false); + }); + }; + + onDrop = (files, uploadToFolder) => { + const { t, startUpload, setDragging, dragging } = this.props; + dragging && setDragging(false); + startUpload(files, uploadToFolder, t); + }; + + showOperationToast = (type, qty, title) => { + const { t } = this.props; + switch (type) { + case "move": + if (qty > 1) { + return toastr.success( + + {{ qty }} elements has been moved + + ); + } + return toastr.success( + + {{ title }} moved + ); + case "duplicate": + if (qty > 1) { + return toastr.success( + + {{ qty }} elements copied + + ); + } + return toastr.success( + + {{ title }} copied + + ); + default: + break; } + }; + + showUploadPanel = () => { + const { + uploaded, + converted, + uploadPanelVisible, + setUploadPanelVisible, + clearPrimaryProgressData, + primaryProgressDataVisible, + } = this.props; + setUploadPanelVisible(!uploadPanelVisible); + + if (primaryProgressDataVisible && uploaded && converted) + clearPrimaryProgressData(); + }; + componentDidUpdate(prevProps) { + const { + isProgressFinished, + secondaryProgressDataStoreIcon, + selectionLength, + selectionTitle, + } = this.props; + + if (this.props.isHeaderVisible !== prevProps.isHeaderVisible) { + this.props.setHeaderVisible(this.props.isHeaderVisible); + } + if ( + isProgressFinished && + isProgressFinished !== prevProps.isProgressFinished + ) { + this.showOperationToast( + secondaryProgressDataStoreIcon, + selectionLength, + selectionTitle + ); + } + } + + render() { + //console.log("Home render"); + const { + viewAs, + fileActionId, + firstLoad, + isHeaderVisible, + isPrivacyFolder, + isRecycleBinFolder, + + primaryProgressDataVisible, + primaryProgressDataPercent, + primaryProgressDataIcon, + primaryProgressDataAlert, + + secondaryProgressDataStoreVisible, + secondaryProgressDataStorePercent, + secondaryProgressDataStoreIcon, + secondaryProgressDataStoreAlert, + + dragging, + tReady, + } = this.props; + + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + } } const Home = withTranslation("Home")(PureHome); export default inject( - ({ - auth, - filesStore, - uploadDataStore, - treeFoldersStore, - mediaViewerDataStore, - formatsStore, - }) => { - const { - secondaryProgressDataStore, - primaryProgressDataStore, - } = uploadDataStore; - const { - firstLoad, - setFirstLoad, - fetchFiles, - fileActionStore, - selection, - setSelections, - dragging, - setDragging, - setIsLoading, - isLoading, - viewAs, - getFileInfo, - } = filesStore; + ({ + auth, + filesStore, + uploadDataStore, + treeFoldersStore, + mediaViewerDataStore, + formatsStore, + }) => { + const { + secondaryProgressDataStore, + primaryProgressDataStore, + } = uploadDataStore; + const { + firstLoad, + setFirstLoad, + fetchFiles, + fileActionStore, + selection, + setSelections, + dragging, + setDragging, + setIsLoading, + isLoading, + viewAs, + getFileInfo, + } = filesStore; - const { mediaViewersFormatsStore } = formatsStore; + const { mediaViewersFormatsStore } = formatsStore; - const { id } = fileActionStore; - const { - isRecycleBinFolder, - isPrivacyFolder, - expandedKeys, - setExpandedKeys, - } = treeFoldersStore; + const { id } = fileActionStore; + const { + isRecycleBinFolder, + isPrivacyFolder, + expandedKeys, + setExpandedKeys, + } = treeFoldersStore; - const { - visible: primaryProgressDataVisible, - percent: primaryProgressDataPercent, - icon: primaryProgressDataIcon, - alert: primaryProgressDataAlert, - clearPrimaryProgressData, - } = primaryProgressDataStore; + const { + visible: primaryProgressDataVisible, + percent: primaryProgressDataPercent, + icon: primaryProgressDataIcon, + alert: primaryProgressDataAlert, + clearPrimaryProgressData, + } = primaryProgressDataStore; - const { - visible: secondaryProgressDataStoreVisible, - percent: secondaryProgressDataStorePercent, - icon: secondaryProgressDataStoreIcon, - alert: secondaryProgressDataStoreAlert, - isSecondaryProgressFinished: isProgressFinished, - } = secondaryProgressDataStore; + const { + visible: secondaryProgressDataStoreVisible, + percent: secondaryProgressDataStorePercent, + icon: secondaryProgressDataStoreIcon, + alert: secondaryProgressDataStoreAlert, + isSecondaryProgressFinished: isProgressFinished, + } = secondaryProgressDataStore; - const { - setUploadPanelVisible, - startUpload, - uploaded, - converted, - } = uploadDataStore; + const { + setUploadPanelVisible, + startUpload, + uploaded, + converted, + } = uploadDataStore; - const selectionLength = isProgressFinished ? selection.length : null; - const selectionTitle = isProgressFinished - ? filesStore.selectionTitle - : null; + const selectionLength = isProgressFinished ? selection.length : null; + const selectionTitle = isProgressFinished + ? filesStore.selectionTitle + : null; - const { setToPreviewFile } = mediaViewerDataStore; - if (!firstLoad) { - if (isLoading) { - showLoader(); - } else { - hideLoader(); - } - } - - return { - homepage: config.homepage, - firstLoad, - dragging, - fileActionId: id, - viewAs, - uploaded, - converted, - isRecycleBinFolder, - isPrivacyFolder, - isVisitor: auth.userStore.user.isVisitor, - expandedKeys, - - primaryProgressDataVisible, - primaryProgressDataPercent, - primaryProgressDataIcon, - primaryProgressDataAlert, - clearPrimaryProgressData, - - secondaryProgressDataStoreVisible, - secondaryProgressDataStorePercent, - secondaryProgressDataStoreIcon, - secondaryProgressDataStoreAlert, - - selectionLength, - isProgressFinished, - selectionTitle, - - setExpandedKeys, - setFirstLoad, - setDragging, - setIsLoading, - fetchFiles, - setUploadPanelVisible, - setSelections, - startUpload, - isHeaderVisible: auth.settingsStore.isHeaderVisible, - setHeaderVisible: auth.settingsStore.setHeaderVisible, - setToPreviewFile, - mediaViewersFormatsStore, - getFileInfo, - }; + const { setToPreviewFile } = mediaViewerDataStore; + if (!firstLoad) { + if (isLoading) { + showLoader(); + } else { + hideLoader(); + } } + + return { + homepage: config.homepage, + firstLoad, + dragging, + fileActionId: id, + viewAs, + uploaded, + converted, + isRecycleBinFolder, + isPrivacyFolder, + isVisitor: auth.userStore.user.isVisitor, + expandedKeys, + + primaryProgressDataVisible, + primaryProgressDataPercent, + primaryProgressDataIcon, + primaryProgressDataAlert, + clearPrimaryProgressData, + + secondaryProgressDataStoreVisible, + secondaryProgressDataStorePercent, + secondaryProgressDataStoreIcon, + secondaryProgressDataStoreAlert, + + selectionLength, + isProgressFinished, + selectionTitle, + + setExpandedKeys, + setFirstLoad, + setDragging, + setIsLoading, + fetchFiles, + setUploadPanelVisible, + setSelections, + startUpload, + isHeaderVisible: auth.settingsStore.isHeaderVisible, + setHeaderVisible: auth.settingsStore.setHeaderVisible, + setToPreviewFile, + mediaViewersFormatsStore, + getFileInfo, + }; + } )(withRouter(observer(Home))); diff --git a/products/ASC.Files/Client/src/store/FilesActionsStore.js b/products/ASC.Files/Client/src/store/FilesActionsStore.js index a647898a7f..4c89d783cd 100644 --- a/products/ASC.Files/Client/src/store/FilesActionsStore.js +++ b/products/ASC.Files/Client/src/store/FilesActionsStore.js @@ -1,15 +1,15 @@ import { - checkFileConflicts, - deleteFile, - deleteFolder, - downloadFiles, - emptyTrash, - finalizeVersion, - getSubfolders, - lockFile, - markAsRead, - removeFiles, - removeShareFiles, + checkFileConflicts, + deleteFile, + deleteFolder, + downloadFiles, + emptyTrash, + finalizeVersion, + getSubfolders, + lockFile, + markAsRead, + removeFiles, + removeShareFiles, } from "@appserver/common/api/files"; import { ConflictResolveType, FileAction } from "@appserver/common/constants"; import { makeAutoObservable } from "mobx"; @@ -19,1015 +19,964 @@ import { TIMEOUT } from "../helpers/constants"; import { loopTreeFolders } from "../helpers/files-helpers"; class FilesActionStore { - authStore; - uploadDataStore; - treeFoldersStore; - filesStore; - selectedFolderStore; - settingsStore; - dialogsStore; - mediaViewerDataStore; - infoPanelStore; + authStore; + uploadDataStore; + treeFoldersStore; + filesStore; + selectedFolderStore; + settingsStore; + dialogsStore; + mediaViewerDataStore; + infoPanelStore; - constructor( - authStore, - uploadDataStore, - treeFoldersStore, - filesStore, - selectedFolderStore, - settingsStore, - dialogsStore, - mediaViewerDataStore, - infoPanelStore - ) { - makeAutoObservable(this); - this.authStore = authStore; - this.uploadDataStore = uploadDataStore; - this.treeFoldersStore = treeFoldersStore; - this.filesStore = filesStore; - this.selectedFolderStore = selectedFolderStore; - this.settingsStore = settingsStore; - this.dialogsStore = dialogsStore; - this.infoPanelStore = infoPanelStore; - this.mediaViewerDataStore = mediaViewerDataStore; + constructor( + authStore, + uploadDataStore, + treeFoldersStore, + filesStore, + selectedFolderStore, + settingsStore, + dialogsStore, + mediaViewerDataStore, + infoPanelStore + ) { + makeAutoObservable(this); + this.authStore = authStore; + this.uploadDataStore = uploadDataStore; + this.treeFoldersStore = treeFoldersStore; + this.filesStore = filesStore; + this.selectedFolderStore = selectedFolderStore; + this.settingsStore = settingsStore; + this.dialogsStore = dialogsStore; + this.infoPanelStore = infoPanelStore; + this.mediaViewerDataStore = mediaViewerDataStore; + } + + isMediaOpen = () => { + const { visible, setMediaViewerData, playlist } = this.mediaViewerDataStore; + if (visible && playlist.length === 1) { + setMediaViewerData({ visible: false, id: null }); + } + }; + + updateCurrentFolder = (selectionLength) => { + const { + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + const { + filter, + fetchFiles, + isEmptyLastPageAfterOperation, + resetFilterPage, + } = this.filesStore; + + let newFilter; + + if (selectionLength && isEmptyLastPageAfterOperation(selectionLength)) { + newFilter = resetFilterPage(); } - isMediaOpen = () => { - const { - visible, - setMediaViewerData, - playlist, - } = this.mediaViewerDataStore; - if (visible && playlist.length === 1) { - setMediaViewerData({ visible: false, id: null }); - } - }; + let updatedFolder = this.selectedFolderStore.id; - updateCurrentFolder = (selectionLength) => { - const { - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; + if (this.dialogsStore.isFolderActions) { + updatedFolder = this.selectedFolderStore.parentId; + } - const { - filter, - fetchFiles, - isEmptyLastPageAfterOperation, - resetFilterPage, - } = this.filesStore; + fetchFiles( + updatedFolder, + newFilter ? newFilter : filter, + true, + true + ).finally(() => { + this.dialogsStore.setIsFolderActions(false); + return setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + }); + }; - let newFilter; + deleteAction = async ( + translations, + newSelection = null, + withoutDialog = false + ) => { + const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore; - if (selectionLength && isEmptyLastPageAfterOperation(selectionLength)) { - newFilter = resetFilterPage(); - } + const selection = newSelection ? newSelection : this.filesStore.selection; - let updatedFolder = this.selectedFolderStore.id; + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; - if (this.dialogsStore.isFolderActions) { - updatedFolder = this.selectedFolderStore.parentId; - } + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); - fetchFiles( - updatedFolder, - newFilter ? newFilter : filter, - true, - true - ).finally(() => { - this.dialogsStore.setIsFolderActions(false); - return setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - }); - }; + const deleteAfter = false; //Delete after finished TODO: get from settings + const immediately = isRecycleBinFolder || isPrivacyFolder ? true : false; //Don't move to the Recycle Bin - deleteAction = async ( - translations, - newSelection = null, - withoutDialog = false - ) => { - const { isRecycleBinFolder, isPrivacyFolder } = this.treeFoldersStore; + let folderIds = []; + let fileIds = []; - const selection = newSelection - ? newSelection - : this.filesStore.selection; + let i = 0; + while (selection.length !== i) { + if (selection[i].fileExst || selection[i].contentLength) { + fileIds.push(selection[i].id); + } else { + folderIds.push(selection[i].id); + } + i++; + } - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; + if (this.dialogsStore.isFolderActions && withoutDialog) { + folderIds = []; + fileIds = []; - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); + folderIds.push(selection[0]); + } - const deleteAfter = false; //Delete after finished TODO: get from settings - const immediately = - isRecycleBinFolder || isPrivacyFolder ? true : false; //Don't move to the Recycle Bin + if (folderIds.length || fileIds.length) { + this.isMediaOpen(); - let folderIds = []; - let fileIds = []; - - let i = 0; - while (selection.length !== i) { - if (selection[i].fileExst || selection[i].contentLength) { - fileIds.push(selection[i].id); - } else { - folderIds.push(selection[i].id); + try { + await removeFiles(folderIds, fileIds, deleteAfter, immediately).then( + async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { + icon: "trash", + label: translations.deleteOperation, + }; + await this.uploadDataStore.loopFilesOperations(data, pbData); + this.updateCurrentFolder(selection.length); + if (isRecycleBinFolder) { + return toastr.success(translations.deleteFromTrash); } - i++; - } - if (this.dialogsStore.isFolderActions && withoutDialog) { - folderIds = []; - fileIds = []; - - folderIds.push(selection[0]); - } - - if (folderIds.length || fileIds.length) { - this.isMediaOpen(); - - try { - await removeFiles( - folderIds, - fileIds, - deleteAfter, - immediately - ).then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "trash", - label: translations.deleteOperation, - }; - await this.uploadDataStore.loopFilesOperations( - data, - pbData - ); - this.updateCurrentFolder(selection.length); - if (isRecycleBinFolder) { - return toastr.success(translations.deleteFromTrash); - } - - if (selection.length > 1) { - return toastr.success(translations.deleteSelectedElem); - } - if (selection[0].fileExst) { - return toastr.success(translations.FileRemoved); - } - return toastr.success(translations.FolderRemoved); - }); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); + if (selection.length > 1) { + return toastr.success(translations.deleteSelectedElem); } - } - }; - - emptyTrash = async (translations) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); - - try { - await emptyTrash().then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "trash", - label: translations.deleteOperation, - }; - await this.uploadDataStore.loopFilesOperations(data, pbData); - toastr.success(translations.successOperation); - this.updateCurrentFolder(); - }); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - }; - - downloadFiles = async (fileConvertIds, folderIds, label) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - - setSecondaryProgressBarData({ - icon: "file", - visible: true, - percent: 0, - label, - alert: false, - }); - - try { - await downloadFiles(fileConvertIds, folderIds).then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { - icon: "file", - label, - }; - - const item = - data?.finished && data?.url - ? data - : await this.uploadDataStore.loopFilesOperations( - data, - pbData - ); - - if (item.url) { - window.location.href = item.url; - } else { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - } - - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - }); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - }; - - downloadAction = (label, folderId) => { - const { bufferSelection } = this.filesStore; - - const selection = this.filesStore.selection.length - ? this.filesStore.selection - : [bufferSelection]; - - let fileIds = []; - let folderIds = []; - const items = []; - - if (selection.length === 1 && selection[0].fileExst && !folderId) { - window.open(selection[0].viewUrl, "_self"); - return Promise.resolve(); - } - - for (let item of selection) { - if (item.fileExst) { - fileIds.push(item.id); - items.push({ id: item.id, fileExst: item.fileExst }); - } else { - folderIds.push(item.id); - items.push({ id: item.id }); + if (selection[0].fileExst) { + return toastr.success(translations.FileRemoved); } - } - - if (this.dialogsStore.isFolderActions) { - fileIds = []; - folderIds = []; - - folderIds.push(bufferSelection); - this.dialogsStore.setIsFolderActions(false); - } - - return this.downloadFiles(fileIds, folderIds, label); - }; - - editCompleteAction = async (id, selectedItem, isCancelled = false) => { - const { - filter, - folders, - files, - fileActionStore, - fetchFiles, - setIsLoading, - } = this.filesStore; - const { type, setAction } = fileActionStore; - 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); - } - } - setAction({ - type: null, - id: null, - extension: null, - title: "", - templateId: null, - }); - setIsLoading(false); - type === FileAction.Rename && - this.onSelectItem({ - id: selectedItem.id, - isFolder: selectedItem.isFolder, - }); - } - }; - - onSelectItem = ({ id, isFolder }) => { - const { setBufferSelection, selected, setSelected } = this.filesStore; - /* selected === "close" && */ setSelected("none"); - - if (!id) return; - - const item = this.filesStore[isFolder ? "folders" : "files"].find( - (elm) => elm.id === id + return toastr.success(translations.FolderRemoved); + } ); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + } + }; - if (item) { - item.isFolder = isFolder; - setBufferSelection(item); - } - }; + emptyTrash = async (translations) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; - deleteItemAction = async (itemId, translations, isFile, isThirdParty) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; - if ( - this.settingsStore.confirmDelete || - this.treeFoldersStore.isPrivacyFolder || - isThirdParty - ) { - this.dialogsStore.setDeleteDialogVisible(true); - } else { - setSecondaryProgressBarData({ - icon: "trash", - visible: true, - percent: 0, - label: translations.deleteOperation, - alert: false, - }); + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); - try { - await this.deleteItemOperation(isFile, itemId, translations); - } catch (err) { - setSecondaryProgressBarData({ - visible: true, - alert: true, - }); - setTimeout(() => clearSecondaryProgressData(), TIMEOUT); - return toastr.error(err.message ? err.message : err); - } - } - }; - - deleteItemOperation = (isFile, itemId, translations) => { + try { + await emptyTrash().then(async (res) => { + const data = res[0] ? res[0] : null; const pbData = { - icon: "trash", - label: translations.deleteOperation, + icon: "trash", + label: translations.deleteOperation, + }; + await this.uploadDataStore.loopFilesOperations(data, pbData); + toastr.success(translations.successOperation); + this.updateCurrentFolder(); + }); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + }; + + downloadFiles = async (fileConvertIds, folderIds, label) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + setSecondaryProgressBarData({ + icon: "file", + visible: true, + percent: 0, + label, + alert: false, + }); + + try { + await downloadFiles(fileConvertIds, folderIds).then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { + icon: "file", + label, }; - const selectionFilesLength = 1; + const item = + data?.finished && data?.url + ? data + : await this.uploadDataStore.loopFilesOperations(data, pbData); - if (isFile) { - this.isMediaOpen(); - return deleteFile(itemId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations( - data, - pbData - ); - this.updateCurrentFolder(selectionFilesLength); - }) - .then(() => toastr.success(translations.successRemoveFile)); + if (item.url) { + window.location.href = item.url; } else { - return deleteFolder(itemId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - await this.uploadDataStore.loopFilesOperations( - data, - pbData - ); - this.updateCurrentFolder(selectionFilesLength); - }) - .then(() => toastr.success(translations.successRemoveFolder)); - } - }; - - unsubscribeAction = async (fileIds, folderIds) => { - const { setUnsubscribe } = this.dialogsStore; - const { filter, fetchFiles } = this.filesStore; - - return removeShareFiles(fileIds, folderIds) - .then(() => setUnsubscribe(false)) - .then(() => - fetchFiles(this.selectedFolderStore.id, filter, true, true) - ); - }; - - lockFileAction = (id, locked) => { - const { setFile } = this.filesStore; - return lockFile(id, locked).then((res) => setFile(res)); - }; - - finalizeVersionAction = (id) => { - const { fetchFiles, setIsLoading } = this.filesStore; - - setIsLoading(true); - - return finalizeVersion(id, 0, false) - .then(() => { - fetchFiles(this.selectedFolderStore.id, this.filesStore.filter); - }) - .finally(() => setIsLoading(false)); - }; - - duplicateAction = (item, label) => { - const { - setSecondaryProgressBarData, - } = this.uploadDataStore.secondaryProgressDataStore; - - const folderIds = []; - const fileIds = []; - item.fileExst ? fileIds.push(item.id) : folderIds.push(item.id); - const conflictResolveType = ConflictResolveType.Duplicate; - const deleteAfter = false; //TODO: get from settings - - setSecondaryProgressBarData({ - icon: "duplicate", + setSecondaryProgressBarData({ visible: true, - percent: 0, - label, - alert: false, + alert: true, + }); + } + + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + }); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + }; + + downloadAction = (label, folderId) => { + const { bufferSelection } = this.filesStore; + + const selection = this.filesStore.selection.length + ? this.filesStore.selection + : [bufferSelection]; + + let fileIds = []; + let folderIds = []; + const items = []; + + if (selection.length === 1 && selection[0].fileExst && !folderId) { + window.open(selection[0].viewUrl, "_self"); + return Promise.resolve(); + } + + for (let item of selection) { + if (item.fileExst) { + fileIds.push(item.id); + items.push({ id: item.id, fileExst: item.fileExst }); + } else { + folderIds.push(item.id); + items.push({ id: item.id }); + } + } + + if (this.dialogsStore.isFolderActions) { + fileIds = []; + folderIds = []; + + folderIds.push(bufferSelection); + this.dialogsStore.setIsFolderActions(false); + } + + return this.downloadFiles(fileIds, folderIds, label); + }; + + editCompleteAction = async (id, selectedItem, isCancelled = false) => { + const { + filter, + folders, + files, + fileActionStore, + fetchFiles, + setIsLoading, + } = this.filesStore; + const { type, setAction } = fileActionStore; + 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); + } + } + setAction({ + type: null, + id: null, + extension: null, + title: "", + templateId: null, + }); + setIsLoading(false); + type === FileAction.Rename && + this.onSelectItem({ + id: selectedItem.id, + isFolder: selectedItem.isFolder, }); + } + }; - return this.uploadDataStore.copyToAction( - this.selectedFolderStore.id, - folderIds, - fileIds, - conflictResolveType, - deleteAfter - ); + onSelectItem = ({ id, isFolder }) => { + const { setBufferSelection, selected, setSelected } = this.filesStore; + /* selected === "close" && */ setSelected("none"); + + if (!id) return; + + const item = this.filesStore[isFolder ? "folders" : "files"].find( + (elm) => elm.id === id + ); + + if (item) { + item.isFolder = isFolder; + setBufferSelection(item); + } + }; + + deleteItemAction = async (itemId, translations, isFile, isThirdParty) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + if ( + this.settingsStore.confirmDelete || + this.treeFoldersStore.isPrivacyFolder || + isThirdParty + ) { + this.dialogsStore.setDeleteDialogVisible(true); + } else { + setSecondaryProgressBarData({ + icon: "trash", + visible: true, + percent: 0, + label: translations.deleteOperation, + alert: false, + }); + + try { + await this.deleteItemOperation(isFile, itemId, translations); + } catch (err) { + setSecondaryProgressBarData({ + visible: true, + alert: true, + }); + setTimeout(() => clearSecondaryProgressData(), TIMEOUT); + return toastr.error(err.message ? err.message : err); + } + } + }; + + deleteItemOperation = (isFile, itemId, translations) => { + const pbData = { + icon: "trash", + label: translations.deleteOperation, }; - setFavoriteAction = (action, id) => { - const { - markItemAsFavorite, - removeItemFromFavorite, - fetchFavoritesFolder, - getFileInfo, - setSelected, - } = this.filesStore; + const selectionFilesLength = 1; - const items = Array.isArray(id) ? id : [id]; + if (isFile) { + this.isMediaOpen(); + return deleteFile(itemId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations(data, pbData); + this.updateCurrentFolder(selectionFilesLength); + }) + .then(() => toastr.success(translations.successRemoveFile)); + } else { + return deleteFolder(itemId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + await this.uploadDataStore.loopFilesOperations(data, pbData); + this.updateCurrentFolder(selectionFilesLength); + }) + .then(() => toastr.success(translations.successRemoveFolder)); + } + }; - //let data = selection.map(item => item.id) - switch (action) { - case "mark": - return markItemAsFavorite([id]).then(() => getFileInfo(id)); + unsubscribeAction = async (fileIds, folderIds) => { + const { setUnsubscribe } = this.dialogsStore; + const { filter, fetchFiles } = this.filesStore; - case "remove": - return removeItemFromFavorite(items) - .then(() => { - return this.treeFoldersStore.isFavoritesFolder - ? fetchFavoritesFolder(this.selectedFolderStore.id) - : getFileInfo(id); - }) - .then(() => setSelected("close")); - default: - return; - } - }; + return removeShareFiles(fileIds, folderIds) + .then(() => setUnsubscribe(false)) + .then(() => fetchFiles(this.selectedFolderStore.id, filter, true, true)); + }; - selectRowAction = (checked, file) => { - const { - selected, - setSelected, - selectFile, - deselectFile, - setBufferSelection, - } = this.filesStore; - //selected === "close" && setSelected("none"); - setBufferSelection(null); - if (checked) { - selectFile(file); - } else { - deselectFile(file); - } - }; + lockFileAction = (id, locked) => { + const { setFile } = this.filesStore; + return lockFile(id, locked).then((res) => setFile(res)); + }; - openLocationAction = (locationId, isFolder) => { - const { - createNewExpandedKeys, - setExpandedKeys, - } = this.treeFoldersStore; + finalizeVersionAction = (id) => { + const { fetchFiles, setIsLoading } = this.filesStore; - const locationFilter = isFolder ? this.filesStore.filter : null; - this.filesStore.setBufferSelection(null); - return this.filesStore - .fetchFiles(locationId, locationFilter) - .then((data) => { - const pathParts = data.selectedFolder.pathParts; - const newExpandedKeys = createNewExpandedKeys(pathParts); - setExpandedKeys(newExpandedKeys); - }); - /*.then(() => + setIsLoading(true); + + return finalizeVersion(id, 0, false) + .then(() => { + fetchFiles(this.selectedFolderStore.id, this.filesStore.filter); + }) + .finally(() => setIsLoading(false)); + }; + + duplicateAction = (item, label) => { + const { + setSecondaryProgressBarData, + } = this.uploadDataStore.secondaryProgressDataStore; + + const folderIds = []; + const fileIds = []; + item.fileExst ? fileIds.push(item.id) : folderIds.push(item.id); + const conflictResolveType = ConflictResolveType.Duplicate; + const deleteAfter = false; //TODO: get from settings + + setSecondaryProgressBarData({ + icon: "duplicate", + visible: true, + percent: 0, + label, + alert: false, + }); + + return this.uploadDataStore.copyToAction( + this.selectedFolderStore.id, + folderIds, + fileIds, + conflictResolveType, + deleteAfter + ); + }; + + setFavoriteAction = (action, id) => { + const { + markItemAsFavorite, + removeItemFromFavorite, + fetchFavoritesFolder, + getFileInfo, + setSelected, + } = this.filesStore; + + const items = Array.isArray(id) ? id : [id]; + + //let data = selection.map(item => item.id) + switch (action) { + case "mark": + return markItemAsFavorite([id]).then(() => getFileInfo(id)); + + case "remove": + return removeItemFromFavorite(items) + .then(() => { + return this.treeFoldersStore.isFavoritesFolder + ? fetchFavoritesFolder(this.selectedFolderStore.id) + : getFileInfo(id); + }) + .then(() => setSelected("close")); + default: + return; + } + }; + + selectRowAction = (checked, file) => { + const { + selected, + setSelected, + selectFile, + deselectFile, + setBufferSelection, + } = this.filesStore; + //selected === "close" && setSelected("none"); + setBufferSelection(null); + if (checked) { + selectFile(file); + } else { + deselectFile(file); + } + }; + + openLocationAction = (locationId, isFolder) => { + const { createNewExpandedKeys, setExpandedKeys } = this.treeFoldersStore; + + const locationFilter = isFolder ? this.filesStore.filter : null; + this.filesStore.setBufferSelection(null); + return this.filesStore + .fetchFiles(locationId, locationFilter) + .then((data) => { + const pathParts = data.selectedFolder.pathParts; + const newExpandedKeys = createNewExpandedKeys(pathParts); + setExpandedKeys(newExpandedKeys); + }); + /*.then(() => //isFolder ? null : this.selectRowAction(!checked, item) );*/ + }; + + setThirdpartyInfo = (providerKey) => { + const { setConnectDialogVisible, setConnectItem } = this.dialogsStore; + const { providers, capabilities } = this.settingsStore.thirdPartyStore; + const provider = providers.find((x) => x.provider_key === providerKey); + const capabilityItem = capabilities.find((x) => x[0] === providerKey); + const capability = { + title: capabilityItem ? capabilityItem[0] : provider.customer_title, + link: capabilityItem ? capabilityItem[1] : " ", }; - setThirdpartyInfo = (providerKey) => { - const { setConnectDialogVisible, setConnectItem } = this.dialogsStore; - const { providers, capabilities } = this.settingsStore.thirdPartyStore; - const provider = providers.find((x) => x.provider_key === providerKey); - const capabilityItem = capabilities.find((x) => x[0] === providerKey); - const capability = { - title: capabilityItem ? capabilityItem[0] : provider.customer_title, - link: capabilityItem ? capabilityItem[1] : " ", - }; + setConnectDialogVisible(true); + setConnectItem({ ...provider, ...capability }); + }; - setConnectDialogVisible(true); - setConnectItem({ ...provider, ...capability }); + setNewBadgeCount = (item) => { + const { getRootFolder, updateRootBadge } = this.treeFoldersStore; + const { updateFileBadge, updateFolderBadge } = this.filesStore; + const { rootFolderType, fileExst, id } = item; + + const count = item.new ? item.new : 1; + const rootFolder = getRootFolder(rootFolderType); + updateRootBadge(rootFolder.id, count); + + if (fileExst) updateFileBadge(id); + else updateFolderBadge(id, item.new); + }; + + markAsRead = (folderIds, fileId, item) => { + const { + setSecondaryProgressBarData, + clearSecondaryProgressData, + } = this.uploadDataStore.secondaryProgressDataStore; + + setSecondaryProgressBarData({ + icon: "file", + label: "", //TODO: add translation if need "MarkAsRead": "Mark all as read", + percent: 0, + visible: true, + }); + + return markAsRead(folderIds, fileId) + .then(async (res) => { + const data = res[0] ? res[0] : null; + const pbData = { icon: "file" }; + await this.uploadDataStore.loopFilesOperations(data, pbData); + }) + .then(() => item && this.setNewBadgeCount(item)) + .catch((err) => toastr.error(err)) + .finally(() => setTimeout(() => clearSecondaryProgressData(), TIMEOUT)); + }; + + moveDragItems = (destFolderId, folderTitle, translations) => { + const folderIds = []; + const fileIds = []; + const deleteAfter = false; + + const { selection } = this.filesStore; + const { isRootFolder } = this.selectedFolderStore; + const { + isShareFolder, + isCommonFolder, + isFavoritesFolder, + isRecentFolder, + } = this.treeFoldersStore; + const isCopy = + isShareFolder || + isFavoritesFolder || + isRecentFolder || + (!this.authStore.isAdmin && isCommonFolder); + + const operationData = { + destFolderId, + folderIds, + fileIds, + deleteAfter, + translations, + folderTitle, + isCopy, }; - setNewBadgeCount = (item) => { - const { getRootFolder, updateRootBadge } = this.treeFoldersStore; - const { updateFileBadge, updateFolderBadge } = this.filesStore; - const { rootFolderType, fileExst, id } = item; + const { + setThirdPartyMoveDialogVisible, + setDestFolderId, + } = this.dialogsStore; - const count = item.new ? item.new : 1; - const rootFolder = getRootFolder(rootFolderType); - updateRootBadge(rootFolder.id, count); + for (let item of selection) { + if (item.providerKey && !isRootFolder) { + setDestFolderId(destFolderId); + return setThirdPartyMoveDialogVisible(true); + } - if (fileExst) updateFileBadge(id); - else updateFolderBadge(id, item.new); - }; + if (!item.isFolder) { + fileIds.push(item.id); + } else { + if (item.providerKey && isRootFolder) continue; + folderIds.push(item.id); + } + } - markAsRead = (folderIds, fileId, item) => { - const { - setSecondaryProgressBarData, - clearSecondaryProgressData, - } = this.uploadDataStore.secondaryProgressDataStore; + if (!folderIds.length && !fileIds.length) return; + this.checkOperationConflict(operationData); + }; - setSecondaryProgressBarData({ - icon: "file", - label: "", //TODO: add translation if need "MarkAsRead": "Mark all as read", - percent: 0, - visible: true, - }); + checkOperationConflict = async (operationData) => { + const { destFolderId, folderIds, fileIds } = operationData; + const { + setConflictResolveDialogData, + setConflictResolveDialogVisible, + setConflictResolveDialogItems, + } = this.dialogsStore; + const { setBufferSelection } = this.filesStore; - return markAsRead(folderIds, fileId) - .then(async (res) => { - const data = res[0] ? res[0] : null; - const pbData = { icon: "file" }; - await this.uploadDataStore.loopFilesOperations(data, pbData); - }) - .then(() => item && this.setNewBadgeCount(item)) - .catch((err) => toastr.error(err)) - .finally(() => - setTimeout(() => clearSecondaryProgressData(), TIMEOUT) - ); - }; + let conflicts; - moveDragItems = (destFolderId, folderTitle, translations) => { - const folderIds = []; - const fileIds = []; - const deleteAfter = false; - - const { selection } = this.filesStore; - const { isRootFolder } = this.selectedFolderStore; - const { - isShareFolder, - isCommonFolder, - isFavoritesFolder, - isRecentFolder, - } = this.treeFoldersStore; - const isCopy = - isShareFolder || - isFavoritesFolder || - isRecentFolder || - (!this.authStore.isAdmin && isCommonFolder); - - const operationData = { - destFolderId, - folderIds, - fileIds, - deleteAfter, - translations, - folderTitle, - isCopy, - }; - - const { - setThirdPartyMoveDialogVisible, - setDestFolderId, - } = this.dialogsStore; - - for (let item of selection) { - if (item.providerKey && !isRootFolder) { - setDestFolderId(destFolderId); - return setThirdPartyMoveDialogVisible(true); - } - - if (!item.isFolder) { - fileIds.push(item.id); - } else { - if (item.providerKey && isRootFolder) continue; - folderIds.push(item.id); - } - } - - if (!folderIds.length && !fileIds.length) return; - this.checkOperationConflict(operationData); - }; - - checkOperationConflict = async (operationData) => { - const { destFolderId, folderIds, fileIds } = operationData; - const { - setConflictResolveDialogData, - setConflictResolveDialogVisible, - setConflictResolveDialogItems, - } = this.dialogsStore; - const { setBufferSelection } = this.filesStore; - - let conflicts; - - try { - conflicts = await checkFileConflicts( - destFolderId, - folderIds, - fileIds - ); - } catch (err) { - setBufferSelection(null); - return toastr.error(err.message ? err.message : err); - } - - if (conflicts.length) { - setConflictResolveDialogItems(conflicts); - setConflictResolveDialogData(operationData); - setConflictResolveDialogVisible(true); - } else { - try { - await this.uploadDataStore.itemOperationToFolder(operationData); - } catch (err) { - setBufferSelection(null); - return toastr.error(err.message ? err.message : err); - } - } + try { + conflicts = await checkFileConflicts(destFolderId, folderIds, fileIds); + } catch (err) { + setBufferSelection(null); + return toastr.error(err.message ? err.message : err); + } + if (conflicts.length) { + setConflictResolveDialogItems(conflicts); + setConflictResolveDialogData(operationData); + setConflictResolveDialogVisible(true); + } else { + try { + await this.uploadDataStore.itemOperationToFolder(operationData); + } catch (err) { setBufferSelection(null); - }; + return toastr.error(err.message ? err.message : err); + } + } - isAvailableOption = (option) => { - const { - isFavoritesFolder, - isRecentFolder, - isCommonFolder, - } = this.treeFoldersStore; - const { - isAccessedSelected, - canConvertSelected, - isThirdPartyRootSelection, - hasSelection, - } = this.filesStore; - const { personal } = this.authStore.settingsStore; - const { userAccess } = this.filesStore; + setBufferSelection(null); + }; - switch (option) { - case "share": - return isAccessedSelected && !personal; //isFavoritesFolder ||isRecentFolder - case "showInfo": - case "copy": - case "download": - return hasSelection; - case "downloadAs": - return canConvertSelected; - case "moveTo": - return ( - !isThirdPartyRootSelection && - hasSelection && - isAccessedSelected && - !isRecentFolder && - !isFavoritesFolder + isAvailableOption = (option) => { + const { + isFavoritesFolder, + isRecentFolder, + isCommonFolder, + } = this.treeFoldersStore; + const { + isAccessedSelected, + canConvertSelected, + isThirdPartyRootSelection, + hasSelection, + } = this.filesStore; + const { personal } = this.authStore.settingsStore; + const { userAccess } = this.filesStore; + + switch (option) { + case "share": + return isAccessedSelected && !personal; //isFavoritesFolder ||isRecentFolder + case "showInfo": + case "copy": + case "download": + return hasSelection; + case "downloadAs": + return canConvertSelected; + case "moveTo": + return ( + !isThirdPartyRootSelection && + hasSelection && + isAccessedSelected && + !isRecentFolder && + !isFavoritesFolder + ); + + case "delete": + const deleteCondition = + !isThirdPartyRootSelection && hasSelection && isAccessedSelected; + + return isCommonFolder ? userAccess && deleteCondition : deleteCondition; + } + }; + + convertToArray = (itemsCollection) => { + const result = Array.from(itemsCollection.values()).filter((item) => { + return item != null; + }); + + itemsCollection.clear(); + + return result; + }; + + getOption = (option, t) => { + const { + setSharingPanelVisible, + setDownloadDialogVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + } = this.dialogsStore; + + const { toggleIsVisible } = this.infoPanelStore; + + switch (option) { + case "share": + if (!this.isAvailableOption("share")) return null; + else + return { + label: t("Share"), + onClick: () => setSharingPanelVisible(true), + iconUrl: "/static/images/share.react.svg", + title: t("Translations:ButtonShareAccess"), + }; + + case "copy": + if (!this.isAvailableOption("copy")) return null; + else + return { + label: t("Translations:Copy"), + onClick: () => setCopyPanelVisible(true), + iconUrl: "/static/images/copyTo.react.svg", + }; + + case "download": + if (!this.isAvailableOption("download")) return null; + else + return { + label: t("Common:Download"), + onClick: () => + this.downloadAction( + t("Translations:ArchivingData") + ).catch((err) => toastr.error(err)), + iconUrl: "/static/images/download.react.svg", + }; + + case "downloadAs": + if (!this.isAvailableOption("downloadAs")) return null; + else + return { + label: t("Translations:DownloadAs"), + onClick: () => setDownloadDialogVisible(true), + iconUrl: "/static/images/downloadAs.react.svg", + }; + + case "moveTo": + if (!this.isAvailableOption("moveTo")) return null; + else + return { + label: t("MoveTo"), + onClick: () => setMoveToPanelVisible(true), + iconUrl: "/static/images/move.react.svg", + }; + + case "showInfo": + if (!this.isAvailableOption("showInfo")) return null; + else + return { + label: t("InfoPanel:Info"), + onClick: () => toggleIsVisible(), + iconUrl: "/static/images/info.outline.react.svg", + }; + + case "delete": + if (!this.isAvailableOption("delete")) return null; + else + return { + label: t("Common:Delete"), + onClick: () => { + if (this.settingsStore.confirmDelete) { + setDeleteDialogVisible(true); + } else { + const translations = { + deleteOperation: t("Translations:DeleteOperation"), + deleteFromTrash: t("Translations:DeleteFromTrash"), + deleteSelectedElem: t("Translations:DeleteSelectedElem"), + FileRemoved: t("Home:FileRemoved"), + FolderRemoved: t("Home:FolderRemoved"), + }; + + this.deleteAction(translations).catch((err) => + toastr.error(err) ); + } + }, + iconUrl: "/static/images/delete.react.svg", + }; + } + }; - case "delete": - const deleteCondition = - !isThirdPartyRootSelection && - hasSelection && - isAccessedSelected; + getAnotherFolderOptions = (itemsCollection, t) => { + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const moveTo = this.getOption("moveTo", t); + const copy = this.getOption("copy", t); + const deleteOption = this.getOption("delete", t); + const showInfo = this.getOption("showInfo", t); - return isCommonFolder - ? userAccess && deleteCondition - : deleteCondition; - } - }; + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("moveTo", moveTo) + .set("copy", copy) + .set("delete", deleteOption) + .set("showInfo", showInfo); - convertToArray = (itemsCollection) => { - const result = Array.from(itemsCollection.values()).filter((item) => { - return item != null; - }); + return this.convertToArray(itemsCollection); + }; - itemsCollection.clear(); + getRecentFolderOptions = (itemsCollection, t) => { + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); - return result; - }; + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("showInfo", showInfo); - getOption = (option, t) => { - const { - setSharingPanelVisible, - setDownloadDialogVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - } = this.dialogsStore; + return this.convertToArray(itemsCollection); + }; - const { toggleIsVisible } = this.infoPanelStore; + getShareFolderOptions = (itemsCollection, t) => { + const { setDeleteDialogVisible, setUnsubscribe } = this.dialogsStore; - switch (option) { - case "share": - if (!this.isAvailableOption("share")) return null; - else - return { - label: t("Share"), - onClick: () => setSharingPanelVisible(true), - iconUrl: "/static/images/share.react.svg", - title: t("Translations:ButtonShareAccess"), - }; + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); - case "copy": - if (!this.isAvailableOption("copy")) return null; - else - return { - label: t("Translations:Copy"), - onClick: () => setCopyPanelVisible(true), - iconUrl: "/static/images/copyTo.react.svg", - }; + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("delete", { + label: t("RemoveFromList"), + onClick: () => { + setUnsubscribe(true); + setDeleteDialogVisible(true); + }, + }) + .set("showInfo", showInfo); - case "download": - if (!this.isAvailableOption("download")) return null; - else - return { - label: t("Common:Download"), - onClick: () => - this.downloadAction( - t("Translations:ArchivingData") - ).catch((err) => toastr.error(err)), - iconUrl: "/static/images/download.react.svg", - }; + return this.convertToArray(itemsCollection); + }; - case "downloadAs": - if (!this.isAvailableOption("downloadAs")) return null; - else - return { - label: t("Translations:DownloadAs"), - onClick: () => setDownloadDialogVisible(true), - iconUrl: "/static/images/downloadAs.react.svg", - }; + getPrivacyFolderOption = (itemsCollection, t) => { + const moveTo = this.getOption("moveTo", t); + const deleteOption = this.getOption("delete", t); + const download = this.getOption("download", t); + const showInfo = this.getOption("showInfo", t); - case "moveTo": - if (!this.isAvailableOption("moveTo")) return null; - else - return { - label: t("MoveTo"), - onClick: () => setMoveToPanelVisible(true), - iconUrl: "/static/images/move.react.svg", - }; + itemsCollection + .set("download", download) + .set("moveTo", moveTo) - case "showInfo": - if (!this.isAvailableOption("showInfo")) return null; - else - return { - label: t("InfoPanel:Info"), - onClick: () => toggleIsVisible(), - iconUrl: "/static/images/info.outline.react.svg", - }; + .set("delete", deleteOption) + .set("showInfo", showInfo); - case "delete": - if (!this.isAvailableOption("delete")) return null; - else - return { - label: t("Common:Delete"), - onClick: () => { - if (this.settingsStore.confirmDelete) { - setDeleteDialogVisible(true); - } else { - const translations = { - deleteOperation: t( - "Translations:DeleteOperation" - ), - deleteFromTrash: t( - "Translations:DeleteFromTrash" - ), - deleteSelectedElem: t( - "Translations:DeleteSelectedElem" - ), - FileRemoved: t("Home:FileRemoved"), - FolderRemoved: t("Home:FolderRemoved"), - }; + return this.convertToArray(itemsCollection); + }; - this.deleteAction(translations).catch((err) => - toastr.error(err) - ); - } - }, - iconUrl: "/static/images/delete.react.svg", - }; - } - }; + getFavoritesFolderOptions = (itemsCollection, t) => { + const { selection } = this.filesStore; - getAnotherFolderOptions = (itemsCollection, t) => { - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const moveTo = this.getOption("moveTo", t); - const copy = this.getOption("copy", t); - const deleteOption = this.getOption("delete", t); - const showInfo = this.getOption("showInfo", t); + const share = this.getOption("share", t); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const copy = this.getOption("copy", t); + const showInfo = this.getOption("showInfo", t); - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("moveTo", moveTo) - .set("copy", copy) - .set("delete", deleteOption) - .set("showInfo", showInfo); + itemsCollection + .set("share", share) + .set("download", download) + .set("downloadAs", downloadAs) + .set("copy", copy) + .set("delete", { + label: t("Common:Delete"), + alt: t("RemoveFromFavorites"), + onClick: () => { + const items = selection.map((item) => item.id); + this.setFavoriteAction("remove", items) + .then(() => toastr.success(t("RemovedFromFavorites"))) + .catch((err) => toastr.error(err)); + }, + }) + .set("showInfo", showInfo); - return this.convertToArray(itemsCollection); - }; + return this.convertToArray(itemsCollection); + }; - getRecentFolderOptions = (itemsCollection, t) => { - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); - const showInfo = this.getOption("showInfo", t); + getRecycleBinFolderOptions = (itemsCollection, t) => { + const { + setEmptyTrashDialogVisible, + setMoveToPanelVisible, + } = this.dialogsStore; - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy) - .set("showInfo", showInfo); + const download = this.getOption("download", t); + const downloadAs = this.getOption("downloadAs", t); + const deleteOption = this.getOption("delete", t); + const showInfo = this.getOption("showInfo", t); - return this.convertToArray(itemsCollection); - }; + itemsCollection + .set("download", download) + .set("downloadAs", downloadAs) + .set("restore", { + label: t("Translations:Restore"), + onClick: () => setMoveToPanelVisible(true), + iconUrl: "/static/images/move.react.svg", + }) + .set("delete", deleteOption) + .set("showInfo", showInfo); - getShareFolderOptions = (itemsCollection, t) => { - const { setDeleteDialogVisible, setUnsubscribe } = this.dialogsStore; + return this.convertToArray(itemsCollection); + }; - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); - const showInfo = this.getOption("showInfo", t); + getHeaderMenu = (t) => { + const { + isFavoritesFolder, + isRecentFolder, + isRecycleBinFolder, + isPrivacyFolder, + isShareFolder, + } = this.treeFoldersStore; - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy) - .set("delete", { - label: t("RemoveFromList"), - onClick: () => { - setUnsubscribe(true); - setDeleteDialogVisible(true); - }, - }) - .set("showInfo", showInfo); + let itemsCollection = new Map(); - return this.convertToArray(itemsCollection); - }; + if (isRecycleBinFolder) + return this.getRecycleBinFolderOptions(itemsCollection, t); - getPrivacyFolderOption = (itemsCollection, t) => { - const moveTo = this.getOption("moveTo", t); - const deleteOption = this.getOption("delete", t); - const download = this.getOption("download", t); - const showInfo = this.getOption("showInfo", t); + if (isFavoritesFolder) + return this.getFavoritesFolderOptions(itemsCollection, t); - itemsCollection - .set("download", download) - .set("moveTo", moveTo) + if (isPrivacyFolder) return this.getPrivacyFolderOption(itemsCollection, t); - .set("delete", deleteOption) - .set("showInfo", showInfo); + if (isShareFolder) return this.getShareFolderOptions(itemsCollection, t); - return this.convertToArray(itemsCollection); - }; + if (isRecentFolder) return this.getRecentFolderOptions(itemsCollection, t); - getFavoritesFolderOptions = (itemsCollection, t) => { - const { selection } = this.filesStore; - - const share = this.getOption("share", t); - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const copy = this.getOption("copy", t); - const showInfo = this.getOption("showInfo", t); - - itemsCollection - .set("share", share) - .set("download", download) - .set("downloadAs", downloadAs) - .set("copy", copy) - .set("delete", { - label: t("Common:Delete"), - alt: t("RemoveFromFavorites"), - onClick: () => { - const items = selection.map((item) => item.id); - this.setFavoriteAction("remove", items) - .then(() => toastr.success(t("RemovedFromFavorites"))) - .catch((err) => toastr.error(err)); - }, - }) - .set("showInfo", showInfo); - - return this.convertToArray(itemsCollection); - }; - - getRecycleBinFolderOptions = (itemsCollection, t) => { - const { - setEmptyTrashDialogVisible, - setMoveToPanelVisible, - } = this.dialogsStore; - - const download = this.getOption("download", t); - const downloadAs = this.getOption("downloadAs", t); - const deleteOption = this.getOption("delete", t); - const showInfo = this.getOption("showInfo", t); - - itemsCollection - .set("download", download) - .set("downloadAs", downloadAs) - .set("restore", { - label: t("Translations:Restore"), - onClick: () => setMoveToPanelVisible(true), - iconUrl: "/static/images/move.react.svg", - }) - .set("delete", deleteOption) - .set("showInfo", showInfo); - - return this.convertToArray(itemsCollection); - }; - - getHeaderMenu = (t) => { - const { - isFavoritesFolder, - isRecentFolder, - isRecycleBinFolder, - isPrivacyFolder, - isShareFolder, - } = this.treeFoldersStore; - - let itemsCollection = new Map(); - - if (isRecycleBinFolder) - return this.getRecycleBinFolderOptions(itemsCollection, t); - - if (isFavoritesFolder) - return this.getFavoritesFolderOptions(itemsCollection, t); - - if (isPrivacyFolder) - return this.getPrivacyFolderOption(itemsCollection, t); - - if (isShareFolder) - return this.getShareFolderOptions(itemsCollection, t); - - if (isRecentFolder) - return this.getRecentFolderOptions(itemsCollection, t); - - return this.getAnotherFolderOptions(itemsCollection, t); - }; + return this.getAnotherFolderOptions(itemsCollection, t); + }; } export default FilesActionStore; diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index cdb8e4d3e0..8994f67716 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -1,5 +1,11 @@ import api from "@appserver/common/api"; -import { AppServerConfig, FileAction, FileType, FilterType, FolderType } from "@appserver/common/constants"; +import { + AppServerConfig, + FileAction, + FileType, + FilterType, + FolderType, +} from "@appserver/common/constants"; import history from "@appserver/common/history"; import { combineUrl } from "@appserver/common/utils"; import { updateTempContent } from "@appserver/common/utils"; @@ -16,1735 +22,1652 @@ const { FilesFilter } = api; const storageViewAs = localStorage.getItem("viewAs"); class FilesStore { - authStore; - settingsStore; - userStore; - fileActionStore; - selectedFolderStore; - treeFoldersStore; - formatsStore; - filesSettingsStore; + authStore; + settingsStore; + userStore; + fileActionStore; + selectedFolderStore; + treeFoldersStore; + formatsStore; + filesSettingsStore; - isLoaded = false; - isLoading = false; - viewAs = - isMobile && storageViewAs !== "tile" ? "row" : storageViewAs || "table"; - dragging = false; - privacyInstructions = "https://www.onlyoffice.com/private-rooms.aspx"; - isInit = false; + isLoaded = false; + isLoading = false; + viewAs = + isMobile && storageViewAs !== "tile" ? "row" : storageViewAs || "table"; + dragging = false; + privacyInstructions = "https://www.onlyoffice.com/private-rooms.aspx"; + isInit = false; - tooltipPageX = 0; - tooltipPageY = 0; - startDrag = false; + tooltipPageX = 0; + tooltipPageY = 0; + startDrag = false; - firstLoad = true; - files = []; - folders = []; - selection = []; - bufferSelection = null; - selected = "close"; - filter = FilesFilter.getDefault(); //TODO: FILTER - loadTimeout = null; + firstLoad = true; + files = []; + folders = []; + selection = []; + bufferSelection = null; + selected = "close"; + filter = FilesFilter.getDefault(); //TODO: FILTER + loadTimeout = null; - constructor( - authStore, - settingsStore, - userStore, - fileActionStore, - selectedFolderStore, - treeFoldersStore, - formatsStore, - filesSettingsStore - ) { - const pathname = window.location.pathname.toLowerCase(); - this.isEditor = pathname.indexOf("doceditor") !== -1; + constructor( + authStore, + settingsStore, + userStore, + fileActionStore, + selectedFolderStore, + treeFoldersStore, + formatsStore, + filesSettingsStore + ) { + const pathname = window.location.pathname.toLowerCase(); + this.isEditor = pathname.indexOf("doceditor") !== -1; - makeAutoObservable(this); - this.authStore = authStore; - this.settingsStore = settingsStore; - this.userStore = userStore; - this.fileActionStore = fileActionStore; - this.selectedFolderStore = selectedFolderStore; - this.treeFoldersStore = treeFoldersStore; - this.formatsStore = formatsStore; - this.filesSettingsStore = filesSettingsStore; + makeAutoObservable(this); + this.authStore = authStore; + this.settingsStore = settingsStore; + this.userStore = userStore; + this.fileActionStore = fileActionStore; + this.selectedFolderStore = selectedFolderStore; + this.treeFoldersStore = treeFoldersStore; + this.formatsStore = formatsStore; + this.filesSettingsStore = filesSettingsStore; + } + + setIsLoaded = (isLoaded) => { + this.isLoaded = isLoaded; + }; + + setViewAs = (viewAs) => { + this.viewAs = viewAs; + localStorage.setItem("viewAs", viewAs); + }; + + setDragging = (dragging) => { + this.dragging = dragging; + }; + + setIsLoading = (isLoading) => { + this.isLoading = isLoading; + }; + + setTooltipPosition = (tooltipPageX, tooltipPageY) => { + this.tooltipPageX = tooltipPageX; + this.tooltipPageY = tooltipPageY; + }; + + setStartDrag = (startDrag) => { + this.selection = this.selection.filter((x) => !x.providerKey); // removed root thirdparty folders + this.startDrag = startDrag; + }; + + get tooltipOptions() { + if (!this.dragging) return null; + + const selectionLength = this.selection.length; + const elementTitle = selectionLength && this.selection[0].title; + const singleElement = selectionLength === 1; + const filesCount = singleElement ? elementTitle : selectionLength; + const { isShareFolder, isCommonFolder } = this.treeFoldersStore; + + let operationName; + + if (this.authStore.isAdmin && isShareFolder) { + operationName = "copy"; + } else if (!this.authStore.isAdmin && (isShareFolder || isCommonFolder)) { + operationName = "copy"; + } else { + operationName = "move"; } - setIsLoaded = (isLoaded) => { - this.isLoaded = isLoaded; + return { + filesCount, + operationName, }; + } - setViewAs = (viewAs) => { - this.viewAs = viewAs; - localStorage.setItem("viewAs", viewAs); - }; + initFiles = () => { + if (this.isInit) return; - setDragging = (dragging) => { - this.dragging = dragging; - }; + const { isAuthenticated, settingsStore } = this.authStore; + const { getFilesSettings } = this.filesSettingsStore; - setIsLoading = (isLoading) => { - this.isLoading = isLoading; - }; + const { + getPortalCultures, + getIsEncryptionSupport, + getEncryptionKeys, + setModuleInfo, + } = this.settingsStore; + const { isDesktopClient } = settingsStore; - setTooltipPosition = (tooltipPageX, tooltipPageY) => { - this.tooltipPageX = tooltipPageX; - this.tooltipPageY = tooltipPageY; - }; + setModuleInfo(config.homepage, config.id); - setStartDrag = (startDrag) => { - this.selection = this.selection.filter((x) => !x.providerKey); // removed root thirdparty folders - this.startDrag = startDrag; - }; + const requests = []; - get tooltipOptions() { - if (!this.dragging) return null; - - const selectionLength = this.selection.length; - const elementTitle = selectionLength && this.selection[0].title; - const singleElement = selectionLength === 1; - const filesCount = singleElement ? elementTitle : selectionLength; - const { isShareFolder, isCommonFolder } = this.treeFoldersStore; - - let operationName; - - if (this.authStore.isAdmin && isShareFolder) { - operationName = "copy"; - } else if ( - !this.authStore.isAdmin && - (isShareFolder || isCommonFolder) - ) { - operationName = "copy"; - } else { - operationName = "move"; - } - - return { - filesCount, - operationName, - }; + updateTempContent(); + if (!isAuthenticated) { + return this.setIsLoaded(true); + } else { + updateTempContent(isAuthenticated); } - initFiles = () => { - if (this.isInit) return; + if (!this.isEditor) { + requests.push( + getPortalCultures(), + this.treeFoldersStore.fetchTreeFolders() + ); - const { isAuthenticated, settingsStore } = this.authStore; - const { getFilesSettings } = this.filesSettingsStore; + if (isDesktopClient) { + requests.push(getIsEncryptionSupport(), getEncryptionKeys()); + } + } + requests.push(getFilesSettings()); - const { - getPortalCultures, - getIsEncryptionSupport, - getEncryptionKeys, - setModuleInfo, - } = this.settingsStore; - const { isDesktopClient } = settingsStore; + return Promise.all(requests).then(() => (this.isInit = true)); + }; - setModuleInfo(config.homepage, config.id); + setFirstLoad = (firstLoad) => { + this.firstLoad = firstLoad; + }; - const requests = []; + setFiles = (files) => { + this.files = files; + }; - updateTempContent(); - if (!isAuthenticated) { - return this.setIsLoaded(true); - } else { - updateTempContent(isAuthenticated); - } + setFolders = (folders) => { + this.folders = folders; + }; - if (!this.isEditor) { - requests.push( - getPortalCultures(), - this.treeFoldersStore.fetchTreeFolders() + setFile = (file) => { + const index = this.files.findIndex((x) => x.id === file.id); + if (index !== -1) this.files[index] = file; + }; + + setFolder = (folder) => { + const index = this.folders.findIndex((x) => x.id === folder.id); + if (index !== -1) this.folders[index] = folder; + }; + + getFilesChecked = (file, selected) => { + const type = file.fileType; + switch (selected) { + case "all": + return true; + case FilterType.FoldersOnly.toString(): + return file.parentId; + case FilterType.DocumentsOnly.toString(): + return type === FileType.Document; + case FilterType.PresentationsOnly.toString(): + return type === FileType.Presentation; + case FilterType.SpreadsheetsOnly.toString(): + return type === FileType.Spreadsheet; + case FilterType.ImagesOnly.toString(): + return type === FileType.Image; + case FilterType.MediaOnly.toString(): + return type === FileType.Video || type === FileType.Audio; + case FilterType.ArchiveOnly.toString(): + return type === FileType.Archive; + case FilterType.FilesOnly.toString(): + return type || !file.parentId; + default: + return false; + } + }; + + getFilesBySelected = (files, selected) => { + let newSelection = []; + files.forEach((file) => { + const checked = this.getFilesChecked(file, selected); + + if (checked) newSelection.push(file); + }); + + return newSelection; + }; + + setSelected = (selected) => { + if (selected === "close" || selected === "none") + this.setBufferSelection(null); + + this.selected = selected; + const files = this.files.concat(this.folders); + this.selection = this.getFilesBySelected(files, selected); + }; + + setSelection = (selection) => { + this.selection = selection; + }; + + setBufferSelection = (bufferSelection) => { + this.bufferSelection = bufferSelection; + }; + + //TODO: FILTER + setFilesFilter = (filter) => { + const key = `UserFilter=${this.userStore.user.id}`; + const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; + localStorage.setItem(key, value); + + this.setFilterUrl(filter); + this.filter = filter; + }; + + setFilter = (filter) => { + this.filter = filter; + }; + + setFilesOwner = (folderIds, fileIds, ownerId) => { + return api.files.setFileOwner(folderIds, fileIds, ownerId); + }; + + setFilterUrl = (filter) => { + const urlFilter = filter.toUrlParams(); + history.push( + combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/filter?${urlFilter}` + ) + ); + }; + + isEmptyLastPageAfterOperation = (newSelection) => { + const selection = + newSelection || this.selection?.length || [this.bufferSelection].length; + + return ( + selection && + this.filter.page > 0 && + !this.filter.hasNext() && + selection === this.files.length + this.folders.length + ); + }; + + resetFilterPage = () => { + let newFilter; + newFilter = this.filter.clone(); + newFilter.page--; + + return newFilter; + }; + + fetchFiles = ( + folderId, + filter, + clearFilter = true, + withSubfolders = false + ) => { + const { + treeFolders, + setSelectedNode, + getSubfolders, + } = this.treeFoldersStore; + + const filterData = filter ? filter.clone() : FilesFilter.getDefault(); + filterData.folder = folderId; + + const filterStorageItem = localStorage.getItem( + `UserFilter=${this.userStore.user.id}` + ); + + if (filterStorageItem && !filter) { + const splitFilter = filterStorageItem.split(","); + + filterData.sortBy = splitFilter[0]; + filterData.pageCount = splitFilter[1]; + filterData.sortOrder = splitFilter[2]; + } + + setSelectedNode([folderId + ""]); + + //TODO: fix @my + let requestCounter = 1; + const request = () => + api.files + .getFolder(folderId, filterData) + .then(async (data) => { + const isRecycleBinFolder = + data.current.rootFolderType === FolderType.TRASH; + + !isRecycleBinFolder && this.checkUpdateNode(data, folderId); + + if (!isRecycleBinFolder && withSubfolders) { + const path = data.pathParts.slice(0); + const foldersCount = data.current.foldersCount; + const subfolders = await getSubfolders(folderId); + loopTreeFolders(path, treeFolders, subfolders, foldersCount); + } + + const isPrivacyFolder = + data.current.rootFolderType === FolderType.Privacy; + + filterData.total = data.total; + this.setFilesFilter(filterData); //TODO: FILTER + this.setFolders(isPrivacyFolder && isMobile ? [] : data.folders); + this.setFiles(isPrivacyFolder && isMobile ? [] : data.files); + + if (clearFilter) { + this.fileActionStore.setAction({ type: null }); + this.setSelected("close"); + } + + this.selectedFolderStore.setSelectedFolder({ + folders: data.folders, + ...data.current, + pathParts: data.pathParts, + ...{ new: data.new }, + }); + + const selectedFolder = { + selectedFolder: { ...this.selectedFolderStore }, + }; + this.viewAs === "tile" && this.createThumbnails(); + return Promise.resolve(selectedFolder); + }) + .catch((err) => { + toastr.error(err); + if (!requestCounter) return; + requestCounter--; + + if (folderId === "@my" /* && !this.isInit */) { + setTimeout(() => { + return request(); + }, 5000); + } else { + this.treeFoldersStore.fetchTreeFolders(); + return this.fetchFiles( + this.userStore.user.isVisitor ? "@common" : "@my" ); - - if (isDesktopClient) { - requests.push(getIsEncryptionSupport(), getEncryptionKeys()); - } - } - requests.push(getFilesSettings()); - - return Promise.all(requests).then(() => (this.isInit = true)); - }; - - setFirstLoad = (firstLoad) => { - this.firstLoad = firstLoad; - }; - - setFiles = (files) => { - this.files = files; - }; - - setFolders = (folders) => { - this.folders = folders; - }; - - setFile = (file) => { - const index = this.files.findIndex((x) => x.id === file.id); - if (index !== -1) this.files[index] = file; - }; - - setFolder = (folder) => { - const index = this.folders.findIndex((x) => x.id === folder.id); - if (index !== -1) this.folders[index] = folder; - }; - - getFilesChecked = (file, selected) => { - const type = file.fileType; - switch (selected) { - case "all": - return true; - case FilterType.FoldersOnly.toString(): - return file.parentId; - case FilterType.DocumentsOnly.toString(): - return type === FileType.Document; - case FilterType.PresentationsOnly.toString(): - return type === FileType.Presentation; - case FilterType.SpreadsheetsOnly.toString(): - return type === FileType.Spreadsheet; - case FilterType.ImagesOnly.toString(): - return type === FileType.Image; - case FilterType.MediaOnly.toString(): - return type === FileType.Video || type === FileType.Audio; - case FilterType.ArchiveOnly.toString(): - return type === FileType.Archive; - case FilterType.FilesOnly.toString(): - return type || !file.parentId; - default: - return false; - } - }; - - getFilesBySelected = (files, selected) => { - let newSelection = []; - files.forEach((file) => { - const checked = this.getFilesChecked(file, selected); - - if (checked) newSelection.push(file); + } }); - return newSelection; - }; - - setSelected = (selected) => { - if (selected === "close" || selected === "none") - this.setBufferSelection(null); - - this.selected = selected; - const files = this.files.concat(this.folders); - this.selection = this.getFilesBySelected(files, selected); - }; - - setSelection = (selection) => { - this.selection = selection; - }; - - setBufferSelection = (bufferSelection) => { - this.bufferSelection = bufferSelection; - }; - - //TODO: FILTER - setFilesFilter = (filter) => { - const key = `UserFilter=${this.userStore.user.id}`; - const value = `${filter.sortBy},${filter.pageCount},${filter.sortOrder}`; - localStorage.setItem(key, value); - - this.setFilterUrl(filter); - this.filter = filter; - }; - - setFilter = (filter) => { - this.filter = filter; - }; - - setFilesOwner = (folderIds, fileIds, ownerId) => { - return api.files.setFileOwner(folderIds, fileIds, ownerId); - }; - - setFilterUrl = (filter) => { - const urlFilter = filter.toUrlParams(); - history.push( - combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/filter?${urlFilter}` - ) - ); - }; - - isEmptyLastPageAfterOperation = (newSelection) => { - const selection = - newSelection || - this.selection?.length || - [this.bufferSelection].length; - - return ( - selection && - this.filter.page > 0 && - !this.filter.hasNext() && - selection === this.files.length + this.folders.length - ); - }; - - resetFilterPage = () => { - let newFilter; - newFilter = this.filter.clone(); - newFilter.page--; - - return newFilter; - }; - - fetchFiles = ( - folderId, - filter, - clearFilter = true, - withSubfolders = false - ) => { - const { - treeFolders, - setSelectedNode, - getSubfolders, - } = this.treeFoldersStore; - - const filterData = filter ? filter.clone() : FilesFilter.getDefault(); - filterData.folder = folderId; - - const filterStorageItem = localStorage.getItem( - `UserFilter=${this.userStore.user.id}` - ); - - if (filterStorageItem && !filter) { - const splitFilter = filterStorageItem.split(","); - - filterData.sortBy = splitFilter[0]; - filterData.pageCount = splitFilter[1]; - filterData.sortOrder = splitFilter[2]; - } - - setSelectedNode([folderId + ""]); - - //TODO: fix @my - let requestCounter = 1; - const request = () => - api.files - .getFolder(folderId, filterData) - .then(async (data) => { - const isRecycleBinFolder = - data.current.rootFolderType === FolderType.TRASH; - - !isRecycleBinFolder && this.checkUpdateNode(data, folderId); - - if (!isRecycleBinFolder && withSubfolders) { - const path = data.pathParts.slice(0); - const foldersCount = data.current.foldersCount; - const subfolders = await getSubfolders(folderId); - loopTreeFolders( - path, - treeFolders, - subfolders, - foldersCount - ); - } - - const isPrivacyFolder = - data.current.rootFolderType === FolderType.Privacy; - - filterData.total = data.total; - this.setFilesFilter(filterData); //TODO: FILTER - this.setFolders( - isPrivacyFolder && isMobile ? [] : data.folders - ); - this.setFiles( - isPrivacyFolder && isMobile ? [] : data.files - ); - - if (clearFilter) { - this.fileActionStore.setAction({ type: null }); - this.setSelected("close"); - } - - this.selectedFolderStore.setSelectedFolder({ - folders: data.folders, - ...data.current, - pathParts: data.pathParts, - ...{ new: data.new }, - }); - - const selectedFolder = { - selectedFolder: { ...this.selectedFolderStore }, - }; - this.viewAs === "tile" && this.createThumbnails(); - return Promise.resolve(selectedFolder); - }) - .catch((err) => { - toastr.error(err); - if (!requestCounter) return; - requestCounter--; - - if (folderId === "@my" /* && !this.isInit */) { - setTimeout(() => { - return request(); - }, 5000); - } else { - this.treeFoldersStore.fetchTreeFolders(); - return this.fetchFiles( - this.userStore.user.isVisitor ? "@common" : "@my" - ); - } - }); - - return request(); - }; - - checkUpdateNode = async (data, folderId) => { - const { treeFolders, getSubfolders } = this.treeFoldersStore; - const { pathParts, current } = data; - - if (current.parentId === 0) return; - - const somePath = pathParts.slice(0); - const path = pathParts.slice(0); - let newItems = treeFolders; - - while (somePath.length !== 1) { - const folderItem = newItems.find((x) => x.id === somePath[0]); - newItems = folderItem?.folders - ? folderItem.folders - : somePath.length > 1 - ? [] - : null; - if (!newItems) { - return; - } - - somePath.shift(); - } - - if (!newItems.find((x) => x.id == folderId)) { - path.splice(pathParts.length - 1, 1); - const subfolders = await getSubfolders(current.parentId); - loopTreeFolders(path, treeFolders, subfolders, 0); - } - }; - - isFileSelected = (fileId, parentId) => { - const item = this.selection.find( - (x) => x.id === fileId && x.parentId === parentId - ); - - return item !== undefined; - }; - - selectFile = (file) => { - const { id, parentId } = file; - const isFileSelected = this.isFileSelected(id, parentId); - if (!isFileSelected) this.selection.push(file); - }; - - deselectFile = (file) => { - const { id, parentId } = file; - const isFileSelected = this.isFileSelected(id, parentId); - if (isFileSelected) - this.selection = this.selection.filter((x) => x.id !== id); - }; - - removeOptions = (options, toRemoveArray) => - options.filter((o) => !toRemoveArray.includes(o)); - - getFilesContextOptions = (item, canOpenPlayer) => { - const isVisitor = - (this.userStore.user && this.userStore.user.isVisitor) || false; - const isFile = !!item.fileExst || item.contentLength; - const isFavorite = - item.fileStatus === 32 || - item.fileStatus === 33 || - item.fileStatus === 34; - const isFullAccess = item.access < 2; - const withoutShare = false; //TODO: need this prop - const isThirdPartyItem = !!item.providerKey; - const hasNew = - item.new > 0 || item.fileStatus === 2 || item.fileStatus === 34; - const canConvert = false; //TODO: fix of added convert check; - const isEncrypted = item.encrypted; - const isDocuSign = false; //TODO: need this prop; - const isEditing = false; //TODO: need this prop; - const isFileOwner = item.createdBy.id === this.userStore.user.id; - - const { - isRecycleBinFolder, - isPrivacyFolder, - isRecentFolder, - isCommon, - isShare, - isFavoritesFolder, - isShareFolder, - isMy, - } = this.treeFoldersStore; - - const { - canWebEdit, - canViewedDocs, - canFormFillingDocs, - } = this.formatsStore.docserviceStore; - - const isThirdPartyFolder = - item.providerKey && item.id === item.rootFolderId; - const isShareItem = isShare(item.rootFolderType); - const isCommonFolder = isCommon(item.rootFolderType); - const isMyFolder = isMy(item.rootFolderType); - - const { personal } = this.settingsStore; - const { isDesktopClient } = this.authStore.settingsStore; - - if (isFile) { - const shouldFillForm = canFormFillingDocs(item.fileExst); - const shouldEdit = !shouldFillForm && canWebEdit(item.fileExst); - const shouldView = canViewedDocs(item.fileExst); - const isMasterForm = item.fileExst === ".docxf"; - - let fileOptions = [ - //"open", - "fill-form", - "edit", - "preview", - "view", - "make-form", - "show-info", - "separator0", - "sharing-settings", - "external-link", - "owner-change", - "link-for-portal-users", - "send-by-email", - "docu-sign", - "version", //category - "finalize-version", - "show-version-history", - "block-unblock-version", //need split - "separator1", - "open-location", - "mark-read", - "mark-as-favorite", - "remove-from-favorites", - "download", - "download-as", - "convert", - "move", //category - "move-to", - "copy-to", - "copy", - "restore", - "rename", - "separator2", - "unsubscribe", - "delete", - ]; - - if (!isMasterForm) - fileOptions = this.removeOptions(fileOptions, ["make-form"]); - - if (!shouldFillForm) - fileOptions = this.removeOptions(fileOptions, ["fill-form"]); - - if (personal) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "link-for-portal-users", - "docu-sign", - "mark-read", - "unsubscribe", - ]); - - if (!shouldEdit && !shouldView) { - fileOptions = this.removeOptions(fileOptions, [ - "sharing-settings", - ]); - } - } - - if (!this.canConvertSelected) { - fileOptions = this.removeOptions(fileOptions, ["download-as"]); - } - - if (!canConvert || isEncrypted) { - fileOptions = this.removeOptions(fileOptions, ["convert"]); - } - - if (!canOpenPlayer) { - fileOptions = this.removeOptions(fileOptions, ["view"]); - } else { - fileOptions = this.removeOptions(fileOptions, [ - "edit", - "preview", - ]); - } - - if (!isDocuSign) { - fileOptions = this.removeOptions(fileOptions, ["docu-sign"]); - } - - if (isEditing) { - fileOptions = this.removeOptions(fileOptions, [ - "finalize-version", - "move-to", - "delete", - ]); - if (isThirdPartyFolder) { - fileOptions = this.removeOptions(fileOptions, ["rename"]); - } - } - - if (isFavorite) { - fileOptions = this.removeOptions(fileOptions, [ - "mark-as-favorite", - ]); - } else { - fileOptions = this.removeOptions(fileOptions, [ - "remove-from-favorites", - ]); - - if (isFavoritesFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "mark-as-favorite", - ]); - } - } - - if (isFavoritesFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "move-to", - "delete", - "copy", - ]); - - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, [ - "separator2", - ]); - } - } - - if (isEncrypted) { - fileOptions = this.removeOptions(fileOptions, [ - "open", - "edit", - "make-form", - "link-for-portal-users", - "external-link", - "send-by-email", - "block-unblock-version", //need split - "version", //category - "finalize-version", - "copy-to", - "copy", - "mark-as-favorite", - ]); - } - - if (isRecentFolder) { - fileOptions = this.removeOptions(fileOptions, ["delete"]); - - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, [ - "separator2", - ]); - } - } - - if (isFavoritesFolder || isRecentFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "make-form", - "copy", - "move-to", - //"sharing-settings", - "unsubscribe", - "separator2", - ]); - } - - if (isRecycleBinFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "fill-form", - "open", - "open-location", - "view", - "preview", - "edit", - "make-form", - "link-for-portal-users", - "sharing-settings", - "external-link", - "send-by-email", - "block-unblock-version", //need split - "version", //category - "finalize-version", - "show-version-history", - "move", //category - "move-to", - "copy-to", - "copy", - "mark-read", - "mark-as-favorite", - "remove-from-favorites", - "rename", - "separator0", - "separator1", - ]); - } else { - fileOptions = this.removeOptions(fileOptions, ["restore"]); - } - - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, [ - "finalize-version", - "rename", - "block-unblock-version", - "copy", - "sharing-settings", - ]); - } - - if (isVisitor) { - fileOptions = this.removeOptions(fileOptions, [ - "block-unblock-version", - "finalize-version", - "mark-as-favorite", - "remove-from-favorites", - ]); - - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, ["rename"]); - } - } - - if (!this.canShareOwnerChange(item)) { - fileOptions = this.removeOptions(fileOptions, ["owner-change"]); - } - - if (isThirdPartyItem) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "finalize-version", - "copy", - ]); - } - - if (isCommonFolder) { - if (!this.userAccess) { - fileOptions = this.removeOptions(fileOptions, [ - "owner-change", - "move-to", - "delete", - "copy", - "separator2", - ]); - if (!isFavorite) { - fileOptions = this.removeOptions(fileOptions, [ - "separator2", - ]); - } - } - } - - if (withoutShare) { - fileOptions = this.removeOptions(fileOptions, [ - "sharing-settings", - "external-link", - ]); - } - - if (!hasNew) { - fileOptions = this.removeOptions(fileOptions, ["mark-read"]); - } - - if ( - !( - isRecentFolder || - isFavoritesFolder || - (isMyFolder && - (this.filter.filterType || this.filter.search)) - ) - ) { - fileOptions = this.removeOptions(fileOptions, [ - "open-location", - ]); - } - - if (isShareItem) { - if (!isFullAccess) { - fileOptions = this.removeOptions(fileOptions, ["edit"]); - } - - if (isShareFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "copy", - "move-to", - "delete", - ]); - } - } else if (!isEncrypted) { - fileOptions = this.removeOptions(fileOptions, ["unsubscribe"]); - } - - if (isPrivacyFolder) { - fileOptions = this.removeOptions(fileOptions, [ - "preview", - "view", - "separator0", - "copy", - "download-as", - ]); - - if (!isDesktopClient) { - fileOptions = this.removeOptions(fileOptions, [ - "sharing-settings", - ]); - } - - fileOptions = this.removeOptions( - fileOptions, - isFileOwner ? ["unsubscribe"] : ["move-to", "delete"] - ); - } - - if (!shouldEdit && !shouldView && !fileOptions.includes("view")) { - fileOptions = this.removeOptions(fileOptions, [ - "edit", - "preview", - "separator0", - ]); - } - - if (!shouldEdit && shouldView) { - fileOptions = this.removeOptions(fileOptions, ["edit"]); - } - - return fileOptions; - } else { - let folderOptions = [ - "open", - "show-info", - "separator0", - "sharing-settings", - "owner-change", - "link-for-portal-users", - "separator1", - "open-location", - "download", - "move", //category - "move-to", - "copy-to", - "mark-read", - "restore", - "rename", - "change-thirdparty-info", - "separator2", - "unsubscribe", - "delete", - ]; - - if (personal) { - folderOptions = this.removeOptions(folderOptions, [ - "sharing-settings", - "owner-change", - "link-for-portal-users", - "separator1", - "docu-sign", - "mark-read", - "unsubscribe", - ]); - } - - if (isPrivacyFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "sharing-settings", - "copy", - "copy-to", - ]); - - if (!isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, [ - "rename", - ]); - } - } - - if (isShareItem) { - if (isShareFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "move-to", - "delete", - ]); - } - } else { - folderOptions = this.removeOptions(folderOptions, [ - "unsubscribe", - ]); - } - - if (isRecycleBinFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "open", - "link-for-portal-users", - "sharing-settings", - "move", - "move-to", - "copy-to", - "mark-read", - "rename", - "separator0", - "separator1", - ]); - } else { - folderOptions = this.removeOptions(folderOptions, ["restore"]); - } - - if (!isFullAccess) { - //TODO: if added Projects, add project folder check - folderOptions = this.removeOptions(folderOptions, [ - "rename", - "change-thirdparty-info", - ]); - } - - if (!this.canShareOwnerChange(item)) { - folderOptions = this.removeOptions(folderOptions, [ - "owner-change", - ]); - } - - if (!isFullAccess) { - folderOptions = this.removeOptions(folderOptions, [ - "owner-change", - "move-to", - "delete", - "change-thirdparty-info", - ]); - - if (!isShareItem) { - folderOptions = this.removeOptions(folderOptions, [ - "separator2", - ]); - } - - if (isVisitor) { - folderOptions = this.removeOptions(folderOptions, [ - "rename", - ]); - } - } - - if (withoutShare) { - folderOptions = this.removeOptions(folderOptions, [ - "sharing-settings", - ]); - } - - if (!hasNew) { - folderOptions = this.removeOptions(folderOptions, [ - "mark-read", - ]); - } - - if (isThirdPartyFolder) { - folderOptions = this.removeOptions(folderOptions, ["move-to"]); - - if (isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, [ - "separator2", - "delete", - ]); - } - } else { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - if (isThirdPartyItem) { - folderOptions = this.removeOptions(folderOptions, [ - "owner-change", - ]); - - if (isShareFolder) { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } else { - if (isDesktopClient) { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - folderOptions = this.removeOptions(folderOptions, [ - "remove", - ]); - - if (!item) { - //For damaged items - folderOptions = this.removeOptions(folderOptions, [ - "open", - "download", - "copy-to", - "rename", - ]); - } - } - } else { - folderOptions = this.removeOptions(folderOptions, [ - "change-thirdparty-info", - ]); - } - - if ( - !(isMyFolder && (this.filter.filterType || this.filter.search)) - ) { - folderOptions = this.removeOptions(folderOptions, [ - "open-location", - ]); - } - - return folderOptions; - } - }; - - addFileToRecentlyViewed = (fileId) => { - if (this.treeFoldersStore.isPrivacyFolder) return Promise.resolve(); - return api.files.addFileToRecentlyViewed(fileId); - }; - - createFile = (folderId, title, templateId) => { - return api.files - .createFile(folderId, title, templateId) - .then((file) => { - return Promise.resolve(file); - }); - }; - - createFolder(parentFolderId, title) { - return api.files.createFolder(parentFolderId, title); + return request(); + }; + + checkUpdateNode = async (data, folderId) => { + const { treeFolders, getSubfolders } = this.treeFoldersStore; + const { pathParts, current } = data; + + if (current.parentId === 0) return; + + const somePath = pathParts.slice(0); + const path = pathParts.slice(0); + let newItems = treeFolders; + + while (somePath.length !== 1) { + const folderItem = newItems.find((x) => x.id === somePath[0]); + newItems = folderItem?.folders + ? folderItem.folders + : somePath.length > 1 + ? [] + : null; + if (!newItems) { + return; + } + + somePath.shift(); } - setFile = (file) => { - const fileIndex = this.files.findIndex((f) => f.id === file.id); - if (fileIndex !== -1) this.files[fileIndex] = file; - }; + if (!newItems.find((x) => x.id == folderId)) { + path.splice(pathParts.length - 1, 1); + const subfolders = await getSubfolders(current.parentId); + loopTreeFolders(path, treeFolders, subfolders, 0); + } + }; - setFolder = (folder) => { - const folderIndex = this.folders.findIndex((f) => f.id === folder.id); - if (folderIndex !== -1) this.folders[folderIndex] = folder; - }; + isFileSelected = (fileId, parentId) => { + const item = this.selection.find( + (x) => x.id === fileId && x.parentId === parentId + ); - updateFolderBadge = (id, count) => { - const folder = this.folders.find((x) => x.id === id); - if (folder) folder.new -= count; - }; + return item !== undefined; + }; - updateFileBadge = (id) => { - const file = this.files.find((x) => x.id === id); - if (file) file.fileStatus = 0; - }; + selectFile = (file) => { + const { id, parentId } = file; + const isFileSelected = this.isFileSelected(id, parentId); + if (!isFileSelected) this.selection.push(file); + }; - updateFilesBadge = () => { - for (let file of this.files) { - file.fileStatus = 0; + deselectFile = (file) => { + const { id, parentId } = file; + const isFileSelected = this.isFileSelected(id, parentId); + if (isFileSelected) + this.selection = this.selection.filter((x) => x.id !== id); + }; + + removeOptions = (options, toRemoveArray) => + options.filter((o) => !toRemoveArray.includes(o)); + + getFilesContextOptions = (item, canOpenPlayer) => { + const isVisitor = + (this.userStore.user && this.userStore.user.isVisitor) || false; + const isFile = !!item.fileExst || item.contentLength; + const isFavorite = + item.fileStatus === 32 || + item.fileStatus === 33 || + item.fileStatus === 34; + const isFullAccess = item.access < 2; + const withoutShare = false; //TODO: need this prop + const isThirdPartyItem = !!item.providerKey; + const hasNew = + item.new > 0 || item.fileStatus === 2 || item.fileStatus === 34; + const canConvert = false; //TODO: fix of added convert check; + const isEncrypted = item.encrypted; + const isDocuSign = false; //TODO: need this prop; + const isEditing = false; //TODO: need this prop; + const isFileOwner = item.createdBy.id === this.userStore.user.id; + + const { + isRecycleBinFolder, + isPrivacyFolder, + isRecentFolder, + isCommon, + isShare, + isFavoritesFolder, + isShareFolder, + isMy, + } = this.treeFoldersStore; + + const { + canWebEdit, + canViewedDocs, + canFormFillingDocs, + } = this.formatsStore.docserviceStore; + + const isThirdPartyFolder = + item.providerKey && item.id === item.rootFolderId; + const isShareItem = isShare(item.rootFolderType); + const isCommonFolder = isCommon(item.rootFolderType); + const isMyFolder = isMy(item.rootFolderType); + + const { personal } = this.settingsStore; + const { isDesktopClient } = this.authStore.settingsStore; + + if (isFile) { + const shouldFillForm = canFormFillingDocs(item.fileExst); + const shouldEdit = !shouldFillForm && canWebEdit(item.fileExst); + const shouldView = canViewedDocs(item.fileExst); + const isMasterForm = item.fileExst === ".docxf"; + + let fileOptions = [ + //"open", + "fill-form", + "edit", + "preview", + "view", + "make-form", + "show-info", + "separator0", + "sharing-settings", + "external-link", + "owner-change", + "link-for-portal-users", + "send-by-email", + "docu-sign", + "version", //category + "finalize-version", + "show-version-history", + "block-unblock-version", //need split + "separator1", + "open-location", + "mark-read", + "mark-as-favorite", + "remove-from-favorites", + "download", + "download-as", + "convert", + "move", //category + "move-to", + "copy-to", + "copy", + "restore", + "rename", + "separator2", + "unsubscribe", + "delete", + ]; + + if (!isMasterForm) + fileOptions = this.removeOptions(fileOptions, ["make-form"]); + + if (!shouldFillForm) + fileOptions = this.removeOptions(fileOptions, ["fill-form"]); + + if (personal) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "link-for-portal-users", + "docu-sign", + "mark-read", + "unsubscribe", + ]); + + if (!shouldEdit && !shouldView) { + fileOptions = this.removeOptions(fileOptions, ["sharing-settings"]); } - }; + } - updateFoldersBadge = () => { - for (let folder of this.folders) { - folder.new = 0; + if (!this.canConvertSelected) { + fileOptions = this.removeOptions(fileOptions, ["download-as"]); + } + + if (!canConvert || isEncrypted) { + fileOptions = this.removeOptions(fileOptions, ["convert"]); + } + + if (!canOpenPlayer) { + fileOptions = this.removeOptions(fileOptions, ["view"]); + } else { + fileOptions = this.removeOptions(fileOptions, ["edit", "preview"]); + } + + if (!isDocuSign) { + fileOptions = this.removeOptions(fileOptions, ["docu-sign"]); + } + + if (isEditing) { + fileOptions = this.removeOptions(fileOptions, [ + "finalize-version", + "move-to", + "delete", + ]); + if (isThirdPartyFolder) { + fileOptions = this.removeOptions(fileOptions, ["rename"]); } - }; + } - updateFile = (fileId, title) => { - return api.files - .updateFile(fileId, title) - .then((file) => this.setFile(file)); - }; + if (isFavorite) { + fileOptions = this.removeOptions(fileOptions, ["mark-as-favorite"]); + } else { + fileOptions = this.removeOptions(fileOptions, [ + "remove-from-favorites", + ]); - renameFolder = (folderId, title) => { - return api.files.renameFolder(folderId, title).then((folder) => { - this.setFolder(folder); - }); - }; - - getFilesCount = () => { - const { filesCount, foldersCount } = this.selectedFolderStore; - return filesCount + this.folders ? this.folders.length : foldersCount; - }; - - getServiceFilesCount = () => { - const filesLength = this.files ? this.files.length : 0; - const foldersLength = this.folders ? this.folders.length : 0; - return filesLength + foldersLength; - }; - - canShareOwnerChange = (item) => { - const userId = this.userStore.user && this.userStore.user.id; - const isCommonFolder = - this.treeFoldersStore.commonFolder && - this.selectedFolderStore.pathParts && - this.treeFoldersStore.commonFolder.id === - this.selectedFolderStore.pathParts[0]; - - if (item.providerKey || !isCommonFolder) { - return false; - } else if (this.authStore.isAdmin) { - return true; - } else if (item.createdBy.id === userId) { - return true; - } else { - return false; + if (isFavoritesFolder) { + fileOptions = this.removeOptions(fileOptions, ["mark-as-favorite"]); } - }; + } - get canShare() { - const folderType = this.selectedFolderStore.rootFolderType; - const isVisitor = - (this.userStore.user && this.userStore.user.isVisitor) || false; + if (isFavoritesFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "move-to", + "delete", + "copy", + ]); + + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, ["separator2"]); + } + } + + if (isEncrypted) { + fileOptions = this.removeOptions(fileOptions, [ + "open", + "edit", + "make-form", + "link-for-portal-users", + "external-link", + "send-by-email", + "block-unblock-version", //need split + "version", //category + "finalize-version", + "copy-to", + "copy", + "mark-as-favorite", + ]); + } + + if (isRecentFolder) { + fileOptions = this.removeOptions(fileOptions, ["delete"]); + + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, ["separator2"]); + } + } + + if (isFavoritesFolder || isRecentFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "make-form", + "copy", + "move-to", + //"sharing-settings", + "unsubscribe", + "separator2", + ]); + } + + if (isRecycleBinFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "fill-form", + "open", + "open-location", + "view", + "preview", + "edit", + "make-form", + "link-for-portal-users", + "sharing-settings", + "external-link", + "send-by-email", + "block-unblock-version", //need split + "version", //category + "finalize-version", + "show-version-history", + "move", //category + "move-to", + "copy-to", + "copy", + "mark-read", + "mark-as-favorite", + "remove-from-favorites", + "rename", + "separator0", + "separator1", + ]); + } else { + fileOptions = this.removeOptions(fileOptions, ["restore"]); + } + + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, [ + "finalize-version", + "rename", + "block-unblock-version", + "copy", + "sharing-settings", + ]); + } + + if (isVisitor) { + fileOptions = this.removeOptions(fileOptions, [ + "block-unblock-version", + "finalize-version", + "mark-as-favorite", + "remove-from-favorites", + ]); + + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, ["rename"]); + } + } + + if (!this.canShareOwnerChange(item)) { + fileOptions = this.removeOptions(fileOptions, ["owner-change"]); + } + + if (isThirdPartyItem) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "finalize-version", + "copy", + ]); + } + + if (isCommonFolder) { + if (!this.userAccess) { + fileOptions = this.removeOptions(fileOptions, [ + "owner-change", + "move-to", + "delete", + "copy", + "separator2", + ]); + if (!isFavorite) { + fileOptions = this.removeOptions(fileOptions, ["separator2"]); + } + } + } + + if (withoutShare) { + fileOptions = this.removeOptions(fileOptions, [ + "sharing-settings", + "external-link", + ]); + } + + if (!hasNew) { + fileOptions = this.removeOptions(fileOptions, ["mark-read"]); + } + + if ( + !( + isRecentFolder || + isFavoritesFolder || + (isMyFolder && (this.filter.filterType || this.filter.search)) + ) + ) { + fileOptions = this.removeOptions(fileOptions, ["open-location"]); + } + + if (isShareItem) { + if (!isFullAccess) { + fileOptions = this.removeOptions(fileOptions, ["edit"]); + } + + if (isShareFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "copy", + "move-to", + "delete", + ]); + } + } else if (!isEncrypted) { + fileOptions = this.removeOptions(fileOptions, ["unsubscribe"]); + } + + if (isPrivacyFolder) { + fileOptions = this.removeOptions(fileOptions, [ + "preview", + "view", + "separator0", + "copy", + "download-as", + ]); + + if (!isDesktopClient) { + fileOptions = this.removeOptions(fileOptions, ["sharing-settings"]); + } + + fileOptions = this.removeOptions( + fileOptions, + isFileOwner ? ["unsubscribe"] : ["move-to", "delete"] + ); + } + + if (!shouldEdit && !shouldView && !fileOptions.includes("view")) { + fileOptions = this.removeOptions(fileOptions, [ + "edit", + "preview", + "separator0", + ]); + } + + if (!shouldEdit && shouldView) { + fileOptions = this.removeOptions(fileOptions, ["edit"]); + } + + return fileOptions; + } else { + let folderOptions = [ + "open", + "show-info", + "separator0", + "sharing-settings", + "owner-change", + "link-for-portal-users", + "separator1", + "open-location", + "download", + "move", //category + "move-to", + "copy-to", + "mark-read", + "restore", + "rename", + "change-thirdparty-info", + "separator2", + "unsubscribe", + "delete", + ]; + + if (personal) { + folderOptions = this.removeOptions(folderOptions, [ + "sharing-settings", + "owner-change", + "link-for-portal-users", + "separator1", + "docu-sign", + "mark-read", + "unsubscribe", + ]); + } + + if (isPrivacyFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "sharing-settings", + "copy", + "copy-to", + ]); + + if (!isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, ["rename"]); + } + } + + if (isShareItem) { + if (isShareFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "move-to", + "delete", + ]); + } + } else { + folderOptions = this.removeOptions(folderOptions, ["unsubscribe"]); + } + + if (isRecycleBinFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "open", + "link-for-portal-users", + "sharing-settings", + "move", + "move-to", + "copy-to", + "mark-read", + "rename", + "separator0", + "separator1", + ]); + } else { + folderOptions = this.removeOptions(folderOptions, ["restore"]); + } + + if (!isFullAccess) { + //TODO: if added Projects, add project folder check + folderOptions = this.removeOptions(folderOptions, [ + "rename", + "change-thirdparty-info", + ]); + } + + if (!this.canShareOwnerChange(item)) { + folderOptions = this.removeOptions(folderOptions, ["owner-change"]); + } + + if (!isFullAccess) { + folderOptions = this.removeOptions(folderOptions, [ + "owner-change", + "move-to", + "delete", + "change-thirdparty-info", + ]); + + if (!isShareItem) { + folderOptions = this.removeOptions(folderOptions, ["separator2"]); + } if (isVisitor) { - return false; + folderOptions = this.removeOptions(folderOptions, ["rename"]); } + } - switch (folderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - return true; - case FolderType.COMMON: - return this.authStore.isAdmin; - case FolderType.TRASH: - return false; - case FolderType.Favorites: - return true; // false; - case FolderType.Recent: - return true; //false; - case FolderType.Privacy: - return true; - default: - return false; + if (withoutShare) { + folderOptions = this.removeOptions(folderOptions, ["sharing-settings"]); + } + + if (!hasNew) { + folderOptions = this.removeOptions(folderOptions, ["mark-read"]); + } + + if (isThirdPartyFolder) { + folderOptions = this.removeOptions(folderOptions, ["move-to"]); + + if (isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, [ + "separator2", + "delete", + ]); } - } + } else { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } - get currentFilesCount() { - const serviceFilesCount = this.getServiceFilesCount(); - const filesCount = this.getFilesCount(); - return this.selectedFolderStore.providerItem - ? serviceFilesCount - : filesCount; - } + if (isThirdPartyItem) { + folderOptions = this.removeOptions(folderOptions, ["owner-change"]); - get iconOfDraggedFile() { - const { getIcon } = this.formatsStore.iconFormatsStore; + if (isShareFolder) { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } else { + if (isDesktopClient) { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } - if (this.selection.length === 1) { - return getIcon( - 24, - this.selection[0].fileExst, - this.selection[0].providerKey - ); + folderOptions = this.removeOptions(folderOptions, ["remove"]); + + if (!item) { + //For damaged items + folderOptions = this.removeOptions(folderOptions, [ + "open", + "download", + "copy-to", + "rename", + ]); + } } - return null; + } else { + folderOptions = this.removeOptions(folderOptions, [ + "change-thirdparty-info", + ]); + } + + if (!(isMyFolder && (this.filter.filterType || this.filter.search))) { + folderOptions = this.removeOptions(folderOptions, ["open-location"]); + } + + return folderOptions; + } + }; + + addFileToRecentlyViewed = (fileId) => { + if (this.treeFoldersStore.isPrivacyFolder) return Promise.resolve(); + return api.files.addFileToRecentlyViewed(fileId); + }; + + createFile = (folderId, title, templateId) => { + return api.files.createFile(folderId, title, templateId).then((file) => { + return Promise.resolve(file); + }); + }; + + createFolder(parentFolderId, title) { + return api.files.createFolder(parentFolderId, title); + } + + setFile = (file) => { + const fileIndex = this.files.findIndex((f) => f.id === file.id); + if (fileIndex !== -1) this.files[fileIndex] = file; + }; + + setFolder = (folder) => { + const folderIndex = this.folders.findIndex((f) => f.id === folder.id); + if (folderIndex !== -1) this.folders[folderIndex] = folder; + }; + + updateFolderBadge = (id, count) => { + const folder = this.folders.find((x) => x.id === id); + if (folder) folder.new -= count; + }; + + updateFileBadge = (id) => { + const file = this.files.find((x) => x.id === id); + if (file) file.fileStatus = 0; + }; + + updateFilesBadge = () => { + for (let file of this.files) { + file.fileStatus = 0; + } + }; + + updateFoldersBadge = () => { + for (let folder of this.folders) { + folder.new = 0; + } + }; + + updateFile = (fileId, title) => { + return api.files + .updateFile(fileId, title) + .then((file) => this.setFile(file)); + }; + + renameFolder = (folderId, title) => { + return api.files.renameFolder(folderId, title).then((folder) => { + this.setFolder(folder); + }); + }; + + getFilesCount = () => { + const { filesCount, foldersCount } = this.selectedFolderStore; + return filesCount + this.folders ? this.folders.length : foldersCount; + }; + + getServiceFilesCount = () => { + const filesLength = this.files ? this.files.length : 0; + const foldersLength = this.folders ? this.folders.length : 0; + return filesLength + foldersLength; + }; + + canShareOwnerChange = (item) => { + const userId = this.userStore.user && this.userStore.user.id; + const isCommonFolder = + this.treeFoldersStore.commonFolder && + this.selectedFolderStore.pathParts && + this.treeFoldersStore.commonFolder.id === + this.selectedFolderStore.pathParts[0]; + + if (item.providerKey || !isCommonFolder) { + return false; + } else if (this.authStore.isAdmin) { + return true; + } else if (item.createdBy.id === userId) { + return true; + } else { + return false; + } + }; + + get canShare() { + const folderType = this.selectedFolderStore.rootFolderType; + const isVisitor = + (this.userStore.user && this.userStore.user.isVisitor) || false; + + if (isVisitor) { + return false; } - get isHeaderVisible() { - return this.selection.length > 0; + switch (folderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + return true; + case FolderType.COMMON: + return this.authStore.isAdmin; + case FolderType.TRASH: + return false; + case FolderType.Favorites: + return true; // false; + case FolderType.Recent: + return true; //false; + case FolderType.Privacy: + return true; + default: + return false; } + } - get isHeaderIndeterminate() { - const items = [...this.files, ...this.folders]; - return this.isHeaderVisible && this.selection.length - ? this.selection.length < items.length - : false; + get currentFilesCount() { + const serviceFilesCount = this.getServiceFilesCount(); + const filesCount = this.getFilesCount(); + return this.selectedFolderStore.providerItem + ? serviceFilesCount + : filesCount; + } + + get iconOfDraggedFile() { + const { getIcon } = this.formatsStore.iconFormatsStore; + + if (this.selection.length === 1) { + return getIcon( + 24, + this.selection[0].fileExst, + this.selection[0].providerKey + ); } + return null; + } - get isHeaderChecked() { - const items = [...this.files, ...this.folders]; - return this.isHeaderVisible && this.selection.length === items.length; - } + get isHeaderVisible() { + return this.selection.length > 0; + } - get canCreate() { - switch (this.selectedFolderStore.rootFolderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - const canCreateInSharedFolder = - this.selectedFolderStore.access === 1; - return ( - !this.selectedFolderStore.isRootFolder && - canCreateInSharedFolder - ); - case FolderType.Privacy: - return ( - this.authStore.settingsStore.isDesktopClient && - this.settingsStore.isEncryptionSupport - ); - case FolderType.COMMON: - return this.authStore.isAdmin; - case FolderType.TRASH: - default: - return false; - } - } + get isHeaderIndeterminate() { + const items = [...this.files, ...this.folders]; + return this.isHeaderVisible && this.selection.length + ? this.selection.length < items.length + : false; + } - onCreateAddTempItem = (items) => { - const { - getFileIcon, - getFolderIcon, - } = this.formatsStore.iconFormatsStore; - const { extension, title } = this.fileActionStore; + get isHeaderChecked() { + const items = [...this.files, ...this.folders]; + return this.isHeaderVisible && this.selection.length === items.length; + } - if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this; - - const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24; - const icon = extension - ? getFileIcon(`.${extension}`, iconSize) - : getFolderIcon(null, iconSize); - - items.unshift({ - id: -1, - title: title, - parentId: this.selectedFolderStore.id, - fileExst: extension, - icon, - }); - }; - - get filesList() { - const { - mediaViewersFormatsStore, - iconFormatsStore, - } = this.formatsStore; - const { getIcon } = iconFormatsStore; - //return [...this.folders, ...this.files]; - - const items = [...this.folders, ...this.files]; - const newItem = items.map((item) => { - const { - access, - comment, - contentLength, - created, - createdBy, - encrypted, - fileExst, - filesCount, - fileStatus, - fileType, - folderId, - foldersCount, - id, - locked, - parentId, - pureContentLength, - rootFolderType, - rootFolderId, - shared, - title, - updated, - updatedBy, - version, - versionGroup, - viewUrl, - webUrl, - providerKey, - thumbnailUrl, - thumbnailStatus, - canShare, - canEdit, - } = item; - - const { canConvert } = this.formatsStore.docserviceStore; - - const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( - item.fileExst - ); - - const previewUrl = canOpenPlayer - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/#preview/${id}` - ) - : null; - const contextOptions = this.getFilesContextOptions( - item, - canOpenPlayer - ); - const isThirdPartyFolder = providerKey && id === rootFolderId; - - const iconSize = this.viewAs === "table" ? 24 : 32; - const icon = getIcon( - iconSize, - fileExst, - providerKey, - contentLength - ); - - let isFolder = false; - this.folders.map((x) => { - if (x.id === item.id) isFolder = true; - }); - - const { isRecycleBinFolder } = this.treeFoldersStore; - - const folderUrl = isFolder - ? combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/filter?folder=${id}` - ) - : null; - - const needConvert = canConvert(fileExst); - - const docUrl = combineUrl( - AppServerConfig.proxyURL, - config.homepage, - `/doceditor?fileId=${id}${needConvert ? "&action=view" : ""}` - ); - - const href = isRecycleBinFolder - ? null - : previewUrl - ? previewUrl - : !isFolder - ? docUrl - : folderUrl; - - return { - access, - //checked, - comment, - contentLength, - contextOptions, - created, - createdBy, - encrypted, - fileExst, - filesCount, - fileStatus, - fileType, - folderId, - foldersCount, - icon, - id, - isFolder, - locked, - new: item.new, - parentId, - pureContentLength, - rootFolderType, - rootFolderId, - //selectedItem, - shared, - title, - updated, - updatedBy, - version, - versionGroup, - viewUrl, - webUrl, - providerKey, - canOpenPlayer, - //canShare, - canShare, - canEdit, - thumbnailUrl, - thumbnailStatus, - previewUrl, - folderUrl, - href, - isThirdPartyFolder, - }; - }); - - if (this.fileActionStore.type === FileAction.Create) { - this.onCreateAddTempItem(newItem); - } - - return newItem; - } - - get cbMenuItems() { - const { - mediaViewersFormatsStore, - iconFormatsStore, - } = this.formatsStore; - const { - isDocument, - isPresentation, - isSpreadsheet, - isArchive, - } = iconFormatsStore; - const { isImage, isVideo } = mediaViewersFormatsStore; - - let cbMenu = ["all"]; - const filesItems = [...this.files, ...this.folders]; - - if (this.folders.length) cbMenu.push(FilterType.FoldersOnly); - for (let item of filesItems) { - if (isDocument(item.fileExst)) - cbMenu.push(FilterType.DocumentsOnly); - else if (isPresentation(item.fileExst)) - cbMenu.push(FilterType.PresentationsOnly); - else if (isSpreadsheet(item.fileExst)) - cbMenu.push(FilterType.SpreadsheetsOnly); - else if (isImage(item.fileExst)) cbMenu.push(FilterType.ImagesOnly); - else if (isVideo(item.fileExst)) cbMenu.push(FilterType.MediaOnly); - else if (isArchive(item.fileExst)) - cbMenu.push(FilterType.ArchiveOnly); - } - - const hasFiles = cbMenu.some( - (elem) => elem !== "all" && elem !== FilterType.FoldersOnly - ); - - if (hasFiles) cbMenu.push(FilterType.FilesOnly); - - cbMenu = cbMenu.filter((item, index) => cbMenu.indexOf(item) === index); - - return cbMenu; - } - - getCheckboxItemLabel = (t, key) => { - switch (key) { - case "all": - return t("All"); - case FilterType.FoldersOnly: - return t("Translations:Folders"); - case FilterType.DocumentsOnly: - return t("Common:Documents"); - case FilterType.PresentationsOnly: - return t("Translations:Presentations"); - case FilterType.SpreadsheetsOnly: - return t("Translations:Spreadsheets"); - case FilterType.ImagesOnly: - return t("Images"); - case FilterType.MediaOnly: - return t("Media"); - case FilterType.ArchiveOnly: - return t("Archives"); - case FilterType.FilesOnly: - return t("AllFiles"); - - default: - return ""; - } - }; - - get sortedFiles() { - const { - isSpreadsheet, - isPresentation, - isDocument, - } = this.formatsStore.iconFormatsStore; - const { filesConverts } = this.formatsStore.docserviceStore; - - let sortedFiles = { - documents: [], - spreadsheets: [], - presentations: [], - other: [], - }; - - const selection = this.selection.length - ? this.selection - : this.bufferSelection - ? [this.bufferSelection] - : []; - - for (let item of selection) { - item.checked = true; - item.format = null; - - const canConvert = filesConverts.find((f) => f[item.fileExst]); - - if (item.fileExst && canConvert) { - if (isSpreadsheet(item.fileExst)) { - sortedFiles.spreadsheets.push(item); - } else if (isPresentation(item.fileExst)) { - sortedFiles.presentations.push(item); - } else if (isDocument(item.fileExst)) { - sortedFiles.documents.push(item); - } else { - sortedFiles.other.push(item); - } - } else { - sortedFiles.other.push(item); - } - } - - return sortedFiles; - } - - get userAccess() { - switch (this.selectedFolderStore.rootFolderType) { - case FolderType.USER: - return true; - case FolderType.SHARE: - return false; - case FolderType.COMMON: - return ( - this.authStore.isAdmin || - this.selection.some((x) => x.access === 0 || x.access === 1) - ); - case FolderType.Privacy: - return true; - case FolderType.TRASH: - return true; - default: - return false; - } - } - - get isAccessedSelected() { + get canCreate() { + switch (this.selectedFolderStore.rootFolderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + const canCreateInSharedFolder = this.selectedFolderStore.access === 1; return ( - this.selection.length && - this.selection.every((x) => x.access === 1 || x.access === 0) + !this.selectedFolderStore.isRootFolder && canCreateInSharedFolder ); - } - - get isThirdPartyRootSelection() { - const withProvider = this.selection.find((x) => x.providerKey); - return withProvider && withProvider.rootFolderId === withProvider.id; - } - - get isThirdPartySelection() { - const withProvider = this.selection.find((x) => x.providerKey); - return !!withProvider; - } - - get canConvertSelected() { - const { filesConverts } = this.formatsStore.docserviceStore; - - const selection = this.selection.length - ? this.selection - : this.bufferSelection - ? [this.bufferSelection] - : []; - - return selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - const index = filesConverts.findIndex((f) => f[selected.fileExst]); - return index !== -1; - }); - } - - get isViewedSelected() { - const { canViewedDocs } = this.formatsStore.docserviceStore; - - return this.selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - return canViewedDocs(selected.fileExst); - }); - } - - get isMediaSelected() { - const { isMediaOrImage } = this.formatsStore.mediaViewersFormatsStore; - - return this.selection.some((selected) => { - if (selected.isFolder === true || !selected.fileExst) return false; - return isMediaOrImage(selected.fileExst); - }); - } - - get selectionTitle() { - if (this.selection.length === 0) { - if (this.bufferSelection) { - return this.bufferSelection.title; - } - return null; - } - return this.selection.find((el) => el.title).title; - } - - get hasSelection() { - return !!this.selection.length; - } - - get isEmptyFilesList() { - const filesList = [...this.files, ...this.folders]; - return filesList.length <= 0; - } - - getOptions = (selection, externalAccess = false) => { - const { - canWebEdit, - canWebComment, - canWebReview, - canFormFillingDocs, - canWebFilterEditing, - } = this.formatsStore.docserviceStore; - - if (selection[0].encrypted) { - return ["FullAccess", "DenyAccess"]; - } - - let AccessOptions = []; - - AccessOptions.push("ReadOnly", "DenyAccess"); - - const webEdit = selection.find((x) => canWebEdit(x.fileExst)); - - const webComment = selection.find((x) => canWebComment(x.fileExst)); - - const webReview = selection.find((x) => canWebReview(x.fileExst)); - - const formFillingDocs = selection.find((x) => - canFormFillingDocs(x.fileExst) + case FolderType.Privacy: + return ( + this.authStore.settingsStore.isDesktopClient && + this.settingsStore.isEncryptionSupport ); + case FolderType.COMMON: + return this.authStore.isAdmin; + case FolderType.TRASH: + default: + return false; + } + } - const webFilter = selection.find((x) => - canWebFilterEditing(x.fileExst) - ); + onCreateAddTempItem = (items) => { + const { getFileIcon, getFolderIcon } = this.formatsStore.iconFormatsStore; + const { extension, title } = this.fileActionStore; - if (webEdit || !externalAccess) AccessOptions.push("FullAccess"); + if (items.length && items[0].id === -1) return; //TODO: if change media collection from state remove this; - if (webComment) AccessOptions.push("Comment"); - if (webReview) AccessOptions.push("Review"); - if (formFillingDocs && !externalAccess) - AccessOptions.push("FormFilling"); - if (webFilter) AccessOptions.push("FilterEditing"); + const iconSize = this.viewAs === "tile" && isMobile ? 32 : 24; + const icon = extension + ? getFileIcon(`.${extension}`, iconSize) + : getFolderIcon(null, iconSize); - return AccessOptions; - }; + items.unshift({ + id: -1, + title: title, + parentId: this.selectedFolderStore.id, + fileExst: extension, + icon, + }); + }; - getAccessOption = (selection) => { - return this.getOptions(selection); - }; + get filesList() { + const { mediaViewersFormatsStore, iconFormatsStore } = this.formatsStore; + const { getIcon } = iconFormatsStore; + //return [...this.folders, ...this.files]; - getExternalAccessOption = (selection) => { - return this.getOptions(selection, true); - }; + const items = [...this.folders, ...this.files]; + const newItem = items.map((item) => { + const { + access, + comment, + contentLength, + created, + createdBy, + encrypted, + fileExst, + filesCount, + fileStatus, + fileType, + folderId, + foldersCount, + id, + locked, + parentId, + pureContentLength, + rootFolderType, + rootFolderId, + shared, + title, + updated, + updatedBy, + version, + versionGroup, + viewUrl, + webUrl, + providerKey, + thumbnailUrl, + thumbnailStatus, + canShare, + canEdit, + } = item; - setSelections = (items) => { - if (!items.length && !this.selection.length) return; + const { canConvert } = this.formatsStore.docserviceStore; - //if (items.length !== this.selection.length) { - const newSelection = []; + const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage( + item.fileExst + ); - for (let item of items) { - const value = item.getAttribute("value"); - const splitValue = value && value.split("_"); + const previewUrl = canOpenPlayer + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/#preview/${id}` + ) + : null; + const contextOptions = this.getFilesContextOptions(item, canOpenPlayer); + const isThirdPartyFolder = providerKey && id === rootFolderId; - const fileType = splitValue[0]; - const id = - splitValue[splitValue.length - 1] === "draggable" - ? splitValue.slice(1, -1).join("_") - : splitValue.slice(1).join("_"); + const iconSize = this.viewAs === "table" ? 24 : 32; + const icon = getIcon(iconSize, fileExst, providerKey, contentLength); - if (fileType === "file") { - newSelection.push(this.files.find((f) => f.id == id)); - } else { - const selectableFolder = this.folders.find((f) => f.id == id); - selectableFolder.isFolder = true; - newSelection.push(selectableFolder); - } - } + let isFolder = false; + this.folders.map((x) => { + if (x.id === item.id) isFolder = true; + }); - //this.selected === "close" && this.setSelected("none"); + const { isRecycleBinFolder } = this.treeFoldersStore; - //need fo table view - const clearSelection = Object.values( - newSelection.reduce((item, n) => ((item[n.id] = n), item), {}) - ); + const folderUrl = isFolder + ? combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/filter?folder=${id}` + ) + : null; - this.setSelection(clearSelection); - //} - }; + const needConvert = canConvert(fileExst); - getShareUsers(folderIds, fileIds) { - return api.files.getShareFiles(fileIds, folderIds); + const docUrl = combineUrl( + AppServerConfig.proxyURL, + config.homepage, + `/doceditor?fileId=${id}${needConvert ? "&action=view" : ""}` + ); + + const href = isRecycleBinFolder + ? null + : previewUrl + ? previewUrl + : !isFolder + ? docUrl + : folderUrl; + + return { + access, + //checked, + comment, + contentLength, + contextOptions, + created, + createdBy, + encrypted, + fileExst, + filesCount, + fileStatus, + fileType, + folderId, + foldersCount, + icon, + id, + isFolder, + locked, + new: item.new, + parentId, + pureContentLength, + rootFolderType, + rootFolderId, + //selectedItem, + shared, + title, + updated, + updatedBy, + version, + versionGroup, + viewUrl, + webUrl, + providerKey, + canOpenPlayer, + //canShare, + canShare, + canEdit, + thumbnailUrl, + thumbnailStatus, + previewUrl, + folderUrl, + href, + isThirdPartyFolder, + }; + }); + + if (this.fileActionStore.type === FileAction.Create) { + this.onCreateAddTempItem(newItem); } - setShareFiles = ( - folderIds, - fileIds, - share, - notify, - sharingMessage, - externalAccess, - ownerId - ) => { - let externalAccessRequest = []; - if (fileIds.length === 1 && externalAccess !== null) { - externalAccessRequest = fileIds.map((id) => - api.files.setExternalAccess(id, externalAccess) - ); + return newItem; + } + + get cbMenuItems() { + const { mediaViewersFormatsStore, iconFormatsStore } = this.formatsStore; + const { + isDocument, + isPresentation, + isSpreadsheet, + isArchive, + } = iconFormatsStore; + const { isImage, isVideo } = mediaViewersFormatsStore; + + let cbMenu = ["all"]; + const filesItems = [...this.files, ...this.folders]; + + if (this.folders.length) cbMenu.push(FilterType.FoldersOnly); + for (let item of filesItems) { + if (isDocument(item.fileExst)) cbMenu.push(FilterType.DocumentsOnly); + else if (isPresentation(item.fileExst)) + cbMenu.push(FilterType.PresentationsOnly); + else if (isSpreadsheet(item.fileExst)) + cbMenu.push(FilterType.SpreadsheetsOnly); + else if (isImage(item.fileExst)) cbMenu.push(FilterType.ImagesOnly); + else if (isVideo(item.fileExst)) cbMenu.push(FilterType.MediaOnly); + else if (isArchive(item.fileExst)) cbMenu.push(FilterType.ArchiveOnly); + } + + const hasFiles = cbMenu.some( + (elem) => elem !== "all" && elem !== FilterType.FoldersOnly + ); + + if (hasFiles) cbMenu.push(FilterType.FilesOnly); + + cbMenu = cbMenu.filter((item, index) => cbMenu.indexOf(item) === index); + + return cbMenu; + } + + getCheckboxItemLabel = (t, key) => { + switch (key) { + case "all": + return t("All"); + case FilterType.FoldersOnly: + return t("Translations:Folders"); + case FilterType.DocumentsOnly: + return t("Common:Documents"); + case FilterType.PresentationsOnly: + return t("Translations:Presentations"); + case FilterType.SpreadsheetsOnly: + return t("Translations:Spreadsheets"); + case FilterType.ImagesOnly: + return t("Images"); + case FilterType.MediaOnly: + return t("Media"); + case FilterType.ArchiveOnly: + return t("Archives"); + case FilterType.FilesOnly: + return t("AllFiles"); + + default: + return ""; + } + }; + + get sortedFiles() { + const { + isSpreadsheet, + isPresentation, + isDocument, + } = this.formatsStore.iconFormatsStore; + const { filesConverts } = this.formatsStore.docserviceStore; + + let sortedFiles = { + documents: [], + spreadsheets: [], + presentations: [], + other: [], + }; + + const selection = this.selection.length + ? this.selection + : this.bufferSelection + ? [this.bufferSelection] + : []; + + for (let item of selection) { + item.checked = true; + item.format = null; + + const canConvert = filesConverts.find((f) => f[item.fileExst]); + + if (item.fileExst && canConvert) { + if (isSpreadsheet(item.fileExst)) { + sortedFiles.spreadsheets.push(item); + } else if (isPresentation(item.fileExst)) { + sortedFiles.presentations.push(item); + } else if (isDocument(item.fileExst)) { + sortedFiles.documents.push(item); + } else { + sortedFiles.other.push(item); } + } else { + sortedFiles.other.push(item); + } + } - const ownerChangeRequest = ownerId - ? [this.setFilesOwner(folderIds, fileIds, ownerId)] - : []; + return sortedFiles; + } - const shareRequest = !!share.length - ? [ - api.files.setShareFiles( - fileIds, - folderIds, - share, - notify, - sharingMessage - ), - ] - : []; + get userAccess() { + switch (this.selectedFolderStore.rootFolderType) { + case FolderType.USER: + return true; + case FolderType.SHARE: + return false; + case FolderType.COMMON: + return ( + this.authStore.isAdmin || + this.selection.some((x) => x.access === 0 || x.access === 1) + ); + case FolderType.Privacy: + return true; + case FolderType.TRASH: + return true; + default: + return false; + } + } - const requests = [ - ...ownerChangeRequest, - ...shareRequest, - ...externalAccessRequest, - ]; + get isAccessedSelected() { + return ( + this.selection.length && + this.selection.every((x) => x.access === 1 || x.access === 0) + ); + } - return Promise.all(requests); - }; + get isThirdPartyRootSelection() { + const withProvider = this.selection.find((x) => x.providerKey); + return withProvider && withProvider.rootFolderId === withProvider.id; + } - markItemAsFavorite = (id) => api.files.markAsFavorite(id); + get isThirdPartySelection() { + const withProvider = this.selection.find((x) => x.providerKey); + return !!withProvider; + } - removeItemFromFavorite = (id) => api.files.removeFromFavorite(id); + get canConvertSelected() { + const { filesConverts } = this.formatsStore.docserviceStore; - fetchFavoritesFolder = async (folderId) => { - const favoritesFolder = await api.files.getFolder(folderId); - this.setFolders(favoritesFolder.folders); - this.setFiles(favoritesFolder.files); + const selection = this.selection.length + ? this.selection + : this.bufferSelection + ? [this.bufferSelection] + : []; - this.selectedFolderStore.setSelectedFolder({ - folders: favoritesFolder.folders, - ...favoritesFolder.current, - pathParts: favoritesFolder.pathParts, - }); - }; + return selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + const index = filesConverts.findIndex((f) => f[selected.fileExst]); + return index !== -1; + }); + } - getFileInfo = async (id) => { - const fileInfo = await api.files.getFileInfo(id); - this.setFile(fileInfo); - return fileInfo; - }; + get isViewedSelected() { + const { canViewedDocs } = this.formatsStore.docserviceStore; - getFolderInfo = async (id) => { - const folderInfo = await api.files.getFolderInfo(id); - this.setFolder(folderInfo); - return folderInfo; - }; + return this.selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + return canViewedDocs(selected.fileExst); + }); + } - openDocEditor = (id, providerKey = null, tab = null, url = null) => { - return openEditor(id, providerKey, tab, url); - }; + get isMediaSelected() { + const { isMediaOrImage } = this.formatsStore.mediaViewersFormatsStore; - createThumbnails = () => { - const filesList = [...this.files, this.folders]; - const fileIds = []; + return this.selection.some((selected) => { + if (selected.isFolder === true || !selected.fileExst) return false; + return isMediaOrImage(selected.fileExst); + }); + } - filesList.map((file) => { - const { thumbnailStatus } = file; + get selectionTitle() { + if (this.selection.length === 0) { + if (this.bufferSelection) { + return this.bufferSelection.title; + } + return null; + } + return this.selection.find((el) => el.title).title; + } - if (thumbnailStatus === thumbnailStatuses.WAITING) - fileIds.push(file.id); - }); + get hasSelection() { + return !!this.selection.length; + } - if (fileIds.length) return api.files.createThumbnails(fileIds); - }; + get isEmptyFilesList() { + const filesList = [...this.files, ...this.folders]; + return filesList.length <= 0; + } + + getOptions = (selection, externalAccess = false) => { + const { + canWebEdit, + canWebComment, + canWebReview, + canFormFillingDocs, + canWebFilterEditing, + } = this.formatsStore.docserviceStore; + + if (selection[0].encrypted) { + return ["FullAccess", "DenyAccess"]; + } + + let AccessOptions = []; + + AccessOptions.push("ReadOnly", "DenyAccess"); + + const webEdit = selection.find((x) => canWebEdit(x.fileExst)); + + const webComment = selection.find((x) => canWebComment(x.fileExst)); + + const webReview = selection.find((x) => canWebReview(x.fileExst)); + + const formFillingDocs = selection.find((x) => + canFormFillingDocs(x.fileExst) + ); + + const webFilter = selection.find((x) => canWebFilterEditing(x.fileExst)); + + if (webEdit || !externalAccess) AccessOptions.push("FullAccess"); + + if (webComment) AccessOptions.push("Comment"); + if (webReview) AccessOptions.push("Review"); + if (formFillingDocs && !externalAccess) AccessOptions.push("FormFilling"); + if (webFilter) AccessOptions.push("FilterEditing"); + + return AccessOptions; + }; + + getAccessOption = (selection) => { + return this.getOptions(selection); + }; + + getExternalAccessOption = (selection) => { + return this.getOptions(selection, true); + }; + + setSelections = (items) => { + if (!items.length && !this.selection.length) return; + + //if (items.length !== this.selection.length) { + const newSelection = []; + + for (let item of items) { + const value = item.getAttribute("value"); + const splitValue = value && value.split("_"); + + const fileType = splitValue[0]; + const id = + splitValue[splitValue.length - 1] === "draggable" + ? splitValue.slice(1, -1).join("_") + : splitValue.slice(1).join("_"); + + if (fileType === "file") { + newSelection.push(this.files.find((f) => f.id == id)); + } else { + const selectableFolder = this.folders.find((f) => f.id == id); + selectableFolder.isFolder = true; + newSelection.push(selectableFolder); + } + } + + //this.selected === "close" && this.setSelected("none"); + + //need fo table view + const clearSelection = Object.values( + newSelection.reduce((item, n) => ((item[n.id] = n), item), {}) + ); + + this.setSelection(clearSelection); + //} + }; + + getShareUsers(folderIds, fileIds) { + return api.files.getShareFiles(fileIds, folderIds); + } + + setShareFiles = ( + folderIds, + fileIds, + share, + notify, + sharingMessage, + externalAccess, + ownerId + ) => { + let externalAccessRequest = []; + if (fileIds.length === 1 && externalAccess !== null) { + externalAccessRequest = fileIds.map((id) => + api.files.setExternalAccess(id, externalAccess) + ); + } + + const ownerChangeRequest = ownerId + ? [this.setFilesOwner(folderIds, fileIds, ownerId)] + : []; + + const shareRequest = !!share.length + ? [ + api.files.setShareFiles( + fileIds, + folderIds, + share, + notify, + sharingMessage + ), + ] + : []; + + const requests = [ + ...ownerChangeRequest, + ...shareRequest, + ...externalAccessRequest, + ]; + + return Promise.all(requests); + }; + + markItemAsFavorite = (id) => api.files.markAsFavorite(id); + + removeItemFromFavorite = (id) => api.files.removeFromFavorite(id); + + fetchFavoritesFolder = async (folderId) => { + const favoritesFolder = await api.files.getFolder(folderId); + this.setFolders(favoritesFolder.folders); + this.setFiles(favoritesFolder.files); + + this.selectedFolderStore.setSelectedFolder({ + folders: favoritesFolder.folders, + ...favoritesFolder.current, + pathParts: favoritesFolder.pathParts, + }); + }; + + getFileInfo = async (id) => { + const fileInfo = await api.files.getFileInfo(id); + this.setFile(fileInfo); + return fileInfo; + }; + + getFolderInfo = async (id) => { + const folderInfo = await api.files.getFolderInfo(id); + this.setFolder(folderInfo); + return folderInfo; + }; + + openDocEditor = (id, providerKey = null, tab = null, url = null) => { + return openEditor(id, providerKey, tab, url); + }; + + createThumbnails = () => { + const filesList = [...this.files, this.folders]; + const fileIds = []; + + filesList.map((file) => { + const { thumbnailStatus } = file; + + if (thumbnailStatus === thumbnailStatuses.WAITING) fileIds.push(file.id); + }); + + if (fileIds.length) return api.files.createThumbnails(fileIds); + }; } export default FilesStore; diff --git a/products/ASC.Files/Client/src/store/SelectedFilesStore.js b/products/ASC.Files/Client/src/store/SelectedFilesStore.js index 9cf072a5ed..f7a66915e3 100644 --- a/products/ASC.Files/Client/src/store/SelectedFilesStore.js +++ b/products/ASC.Files/Client/src/store/SelectedFilesStore.js @@ -1,29 +1,29 @@ import { makeObservable, action, observable } from "mobx"; class SelectedFilesStore { - folderId = null; - fileInfo = null; + folderId = null; + fileInfo = null; - constructor() { - makeObservable(this, { - fileInfo: observable, - folderId: observable, + constructor() { + makeObservable(this, { + fileInfo: observable, + folderId: observable, - setFolderId: action, - setFile: action, - }); - } + setFolderId: action, + setFile: action, + }); + } - setFolderId = (id) => { - this.folderId = id; - }; - setFile = (obj) => { - this.fileInfo = obj; - }; + setFolderId = (id) => { + this.folderId = id; + }; + setFile = (obj) => { + this.fileInfo = obj; + }; - get fileInfo() { - return this.fileInfo; - } + get fileInfo() { + return this.fileInfo; + } } export default new SelectedFilesStore(); diff --git a/products/ASC.Files/Client/src/store/SettingsStore.js b/products/ASC.Files/Client/src/store/SettingsStore.js index 32c35e6f8e..92da105f9f 100644 --- a/products/ASC.Files/Client/src/store/SettingsStore.js +++ b/products/ASC.Files/Client/src/store/SettingsStore.js @@ -1,202 +1,192 @@ import api from "@appserver/common/api"; import { - setFavoritesSetting, - setRecentSetting, + setFavoritesSetting, + setRecentSetting, } from "@appserver/common/api/files"; import { FolderType } from "@appserver/common/constants"; import axios from "axios"; import { makeAutoObservable } from "mobx"; class SettingsStore { - thirdPartyStore; - treeFoldersStore; + thirdPartyStore; + treeFoldersStore; - isErrorSettings = null; - expandedSetting = null; + isErrorSettings = null; + expandedSetting = null; - confirmDelete = null; - enableThirdParty = null; - forcesave = null; - storeForcesave = null; - storeOriginalFiles = null; - updateIfExist = null; - favoritesSection = null; - recentSection = null; - hideConfirmConvertSave = null; - chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb + confirmDelete = null; + enableThirdParty = null; + forcesave = null; + storeForcesave = null; + storeOriginalFiles = null; + updateIfExist = null; + favoritesSection = null; + recentSection = null; + hideConfirmConvertSave = null; + chunkUploadSize = 1024 * 1023; // 1024 * 1023; //~0.999mb - settingsIsLoaded = false; + settingsIsLoaded = false; - constructor(thirdPartyStore, treeFoldersStore) { - makeAutoObservable(this); + constructor(thirdPartyStore, treeFoldersStore) { + makeAutoObservable(this); - this.thirdPartyStore = thirdPartyStore; - this.treeFoldersStore = treeFoldersStore; + this.thirdPartyStore = thirdPartyStore; + this.treeFoldersStore = treeFoldersStore; + } + + get infoPanelIsVisible() { + return this.infoPanelIsVisible; + } + + setIsLoaded = (isLoaded) => { + this.settingsIsLoaded = isLoaded; + }; + + get isLoadedSettingsTree() { + return ( + this.confirmDelete !== null && + this.enableThirdParty !== null && + this.forcesave !== null && + this.storeForcesave !== null && + this.storeOriginalFiles !== null && + this.updateIfExist !== null + ); + } + + setFilesSettings = (settings) => { + const settingsItems = Object.keys(settings); + for (let key of settingsItems) { + this[key] = settings[key]; } + }; - get infoPanelIsVisible() { - return this.infoPanelIsVisible; - } + setIsErrorSettings = (isError) => { + this.isErrorSettings = isError; + }; - setIsLoaded = (isLoaded) => { - this.settingsIsLoaded = isLoaded; - }; + setExpandSettingsTree = (expandedSetting) => { + this.expandedSetting = expandedSetting; + }; - get isLoadedSettingsTree() { - return ( - this.confirmDelete !== null && - this.enableThirdParty !== null && - this.forcesave !== null && - this.storeForcesave !== null && - this.storeOriginalFiles !== null && - this.updateIfExist !== null - ); - } - - setFilesSettings = (settings) => { - const settingsItems = Object.keys(settings); - for (let key of settingsItems) { - this[key] = settings[key]; - } - }; - - setIsErrorSettings = (isError) => { - this.isErrorSettings = isError; - }; - - setExpandSettingsTree = (expandedSetting) => { - this.expandedSetting = expandedSetting; - }; - - getFilesSettings = () => { - if (!this.isLoadedSettingsTree) { - return api.files - .getSettingsFiles() - .then((settings) => { - this.setFilesSettings(settings); - if (settings.enableThirdParty) { - this.setIsLoaded(true); - return axios - .all([ - api.files.getThirdPartyCapabilities(), - api.files.getThirdPartyList(), - ]) - .then(([capabilities, providers]) => { - for (let item of capabilities) { - item.splice(1, 1); - } - this.thirdPartyStore.setThirdPartyCapabilities( - capabilities - ); //TODO: Out of bounds read: 1 - this.thirdPartyStore.setThirdPartyProviders( - providers - ); - }); - } - return this.setIsLoaded(true); - }) - .catch(() => this.setIsErrorSettings(true)); - } else { - return Promise.resolve(); - } - }; - - setFilesSetting = (setting, val) => { - this[setting] = val; - }; - - setUpdateIfExist = (data, setting) => - api.files - .updateIfExist(data) - .then((res) => this.setFilesSetting(setting, res)); - - setStoreOriginal = (data, setting) => - api.files - .storeOriginal(data) - .then((res) => this.setFilesSetting(setting, res)); - - setConfirmDelete = (data, setting) => - api.files - .changeDeleteConfirm(data) - .then((res) => this.setFilesSetting(setting, res)); - - setStoreForceSave = (data, setting) => - api.files - .storeForceSave(data) - .then((res) => this.setFilesSetting(setting, res)); - - setEnableThirdParty = async (data, setting) => { - const res = await api.files.thirdParty(data); - this.setFilesSetting(setting, res); - - if (data) { + getFilesSettings = () => { + if (!this.isLoadedSettingsTree) { + return api.files + .getSettingsFiles() + .then((settings) => { + this.setFilesSettings(settings); + if (settings.enableThirdParty) { + this.setIsLoaded(true); return axios - .all([ - api.files.getThirdPartyCapabilities(), - api.files.getThirdPartyList(), - ]) - .then(([capabilities, providers]) => { - for (let item of capabilities) { - item.splice(1, 1); - } - this.thirdPartyStore.setThirdPartyCapabilities( - capabilities - ); //TODO: Out of bounds read: 1 - this.thirdPartyStore.setThirdPartyProviders(providers); - }); - } else { - return Promise.resolve(); - } - }; + .all([ + api.files.getThirdPartyCapabilities(), + api.files.getThirdPartyList(), + ]) + .then(([capabilities, providers]) => { + for (let item of capabilities) { + item.splice(1, 1); + } + this.thirdPartyStore.setThirdPartyCapabilities(capabilities); //TODO: Out of bounds read: 1 + this.thirdPartyStore.setThirdPartyProviders(providers); + }); + } + return this.setIsLoaded(true); + }) + .catch(() => this.setIsErrorSettings(true)); + } else { + return Promise.resolve(); + } + }; - setForceSave = (data, setting) => - api.files - .forceSave(data) - .then((res) => this.setFilesSetting(setting, res)); + setFilesSetting = (setting, val) => { + this[setting] = val; + }; - updateRootTreeFolders = (set, rootFolderIndex, folderType) => { - const { - getFoldersTree, - treeFolders, - setTreeFolders, - } = this.treeFoldersStore; + setUpdateIfExist = (data, setting) => + api.files + .updateIfExist(data) + .then((res) => this.setFilesSetting(setting, res)); - getFoldersTree().then((root) => { - if (set) { - const rootFolder = root.find( - (x) => x.rootFolderType === folderType - ); - const newTreeFolders = treeFolders; - newTreeFolders.splice(rootFolderIndex, 0, rootFolder); - setTreeFolders(newTreeFolders); - } else { - const newTreeFolders = treeFolders.filter( - (x) => x.rootFolderType !== folderType - ); - setTreeFolders(newTreeFolders); - } + setStoreOriginal = (data, setting) => + api.files + .storeOriginal(data) + .then((res) => this.setFilesSetting(setting, res)); + + setConfirmDelete = (data, setting) => + api.files + .changeDeleteConfirm(data) + .then((res) => this.setFilesSetting(setting, res)); + + setStoreForceSave = (data, setting) => + api.files + .storeForceSave(data) + .then((res) => this.setFilesSetting(setting, res)); + + setEnableThirdParty = async (data, setting) => { + const res = await api.files.thirdParty(data); + this.setFilesSetting(setting, res); + + if (data) { + return axios + .all([ + api.files.getThirdPartyCapabilities(), + api.files.getThirdPartyList(), + ]) + .then(([capabilities, providers]) => { + for (let item of capabilities) { + item.splice(1, 1); + } + this.thirdPartyStore.setThirdPartyCapabilities(capabilities); //TODO: Out of bounds read: 1 + this.thirdPartyStore.setThirdPartyProviders(providers); }); - }; + } else { + return Promise.resolve(); + } + }; - setFavoritesSetting = (set, setting) => { - return setFavoritesSetting(set).then((res) => { - this.setFilesSetting(setting, res); - this.updateRootTreeFolders(set, 2, FolderType.Favorites); - }); - }; + setForceSave = (data, setting) => + api.files.forceSave(data).then((res) => this.setFilesSetting(setting, res)); - setRecentSetting = (set, setting) => { - return setRecentSetting(set).then((res) => { - this.setFilesSetting(setting, res); - const index = this.treeFoldersStore.favoritesFolder ? 3 : 2; - this.updateRootTreeFolders(set, index, FolderType.Recent); - }); - }; + updateRootTreeFolders = (set, rootFolderIndex, folderType) => { + const { + getFoldersTree, + treeFolders, + setTreeFolders, + } = this.treeFoldersStore; - hideConfirmConvert = async (save = true) => { - const hideConfirmConvertSave = await api.files.hideConfirmConvert(save); - this.hideConfirmConvertSave = hideConfirmConvertSave; - }; + getFoldersTree().then((root) => { + if (set) { + const rootFolder = root.find((x) => x.rootFolderType === folderType); + const newTreeFolders = treeFolders; + newTreeFolders.splice(rootFolderIndex, 0, rootFolder); + setTreeFolders(newTreeFolders); + } else { + const newTreeFolders = treeFolders.filter( + (x) => x.rootFolderType !== folderType + ); + setTreeFolders(newTreeFolders); + } + }); + }; + + setFavoritesSetting = (set, setting) => { + return setFavoritesSetting(set).then((res) => { + this.setFilesSetting(setting, res); + this.updateRootTreeFolders(set, 2, FolderType.Favorites); + }); + }; + + setRecentSetting = (set, setting) => { + return setRecentSetting(set).then((res) => { + this.setFilesSetting(setting, res); + const index = this.treeFoldersStore.favoritesFolder ? 3 : 2; + this.updateRootTreeFolders(set, index, FolderType.Recent); + }); + }; + + hideConfirmConvert = async (save = true) => { + const hideConfirmConvertSave = await api.files.hideConfirmConvert(save); + this.hideConfirmConvertSave = hideConfirmConvertSave; + }; } export default SettingsStore; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index 6ec2f52b19..6ace4ce131 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -21,23 +21,23 @@ import UploadDataStore from "./UploadDataStore"; import VersionHistoryStore from "./VersionHistoryStore"; const formatsStore = new FormatsStore( - iconFormatsStore, - mediaViewersFormatsStore, - docserviceStore + iconFormatsStore, + mediaViewersFormatsStore, + docserviceStore ); const treeFoldersStore = new TreeFoldersStore(selectedFolderStore); const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore); const filesStore = new FilesStore( - store.auth, - store.auth.settingsStore, - store.auth.userStore, - fileActionStore, - selectedFolderStore, - treeFoldersStore, - formatsStore, - settingsStore + store.auth, + store.auth.settingsStore, + store.auth.userStore, + fileActionStore, + selectedFolderStore, + treeFoldersStore, + formatsStore, + settingsStore ); const mediaViewerDataStore = new MediaViewerDataStore(filesStore, formatsStore); @@ -45,51 +45,51 @@ const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); const dialogsStore = new DialogsStore( - treeFoldersStore, - filesStore, - selectedFolderStore + treeFoldersStore, + filesStore, + selectedFolderStore ); const uploadDataStore = new UploadDataStore( - formatsStore, - treeFoldersStore, - selectedFolderStore, - filesStore, - secondaryProgressDataStore, - primaryProgressDataStore, - dialogsStore, - settingsStore + formatsStore, + treeFoldersStore, + selectedFolderStore, + filesStore, + secondaryProgressDataStore, + primaryProgressDataStore, + dialogsStore, + settingsStore ); const infoPanelStore = new InfoPanelStore(); const filesActionsStore = new FilesActionsStore( - store.auth, - uploadDataStore, - treeFoldersStore, - filesStore, - selectedFolderStore, - settingsStore, - dialogsStore, - mediaViewerDataStore, - infoPanelStore + store.auth, + uploadDataStore, + treeFoldersStore, + filesStore, + selectedFolderStore, + settingsStore, + dialogsStore, + mediaViewerDataStore, + infoPanelStore ); const versionHistoryStore = new VersionHistoryStore(filesStore); //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { - filesStore, - settingsStore, - mediaViewerDataStore, - formatsStore, - versionHistoryStore, - uploadDataStore, - dialogsStore, - treeFoldersStore, - selectedFolderStore, - filesActionsStore, - selectedFilesStore, - infoPanelStore, + filesStore, + settingsStore, + mediaViewerDataStore, + formatsStore, + versionHistoryStore, + uploadDataStore, + dialogsStore, + treeFoldersStore, + selectedFolderStore, + filesActionsStore, + selectedFilesStore, + infoPanelStore, }; export default stores; diff --git a/public/locales/en/Common.json b/public/locales/en/Common.json index 5d88e7316e..a1a040c2e2 100644 --- a/public/locales/en/Common.json +++ b/public/locales/en/Common.json @@ -1,136 +1,136 @@ { - "About": "About", - "Actions": "Actions", - "Active": "Active", - "AddButton": "Add", - "AddFilter": "Add filter", - "AdminSettings": "Admin settings", - "Archive": "Archive", - "Audio": "Audio", - "BarMaintenanceDescription": "We apologize for any short-term technical issues in service functioning, that may appear on {{targetDate}} during the update of {{productName}}.", - "BarMaintenanceDisclaimer": "Please, make sure that all the changes are successfully saved during this day.", - "ByFirstNameSorting": "By first name", - "ByLastNameSorting": "By last name", - "CancelButton": "Cancel", - "ClearButton": "Reset filter", - "CloseButton": "Close", - "ComingSoon": "Coming soon", - "CommunityProduct": "Community", - "Confirmation": "Confirmation", - "ContinueButton": "Continue", - "CopyEmailAndPassword": "Copy email and password", - "CountPerPage": "{{count}} per page", - "Create": "Create", - "Culture_az": "Azerbaijani (Latin, Azerbaijan)", - "Culture_bg": "Bulgarian (Bulgaria)", - "Culture_cs": "Czech (Czech Republic)", - "Culture_de": "German (Germany)", - "Culture_de-CH": "German (Switzerland)", - "Culture_el": "Greek (Greece)", - "Culture_en": "English (United Kingdom)", - "Culture_en-US": "English (United States)", - "Culture_es": "Spanish (Spain)", - "Culture_es-MX": "Spanish (Mexico)", - "Culture_fi": "Finnish (Finland)", - "Culture_fr": "French (France)", - "Culture_it": "Italian (Italy)", - "Culture_ja": "Japanese (Japan)", - "Culture_ko": "Korean (Korea)", - "Culture_lo": "Laotian (Laos)", - "Culture_lv": "Latvian (Latvia)", - "Culture_nl": "Dutch (Netherlands)", - "Culture_pl": "Polish (Poland)", - "Culture_pt": "Portuguese (Portugal)", - "Culture_pt-BR": "Portuguese (Brazil)", - "Culture_ro": "Romanian (Romania)", - "Culture_ru": "Russian (Russia)", - "Culture_sk": "Slovak (Slovakia)", - "Culture_sl": "Slovenian (Slovenia)", - "Culture_tr": "Turkish (Turkey)", - "Culture_uk": "Ukrainian (Ukraine)", - "Culture_vi": "Vietnamese (Vietnam)", - "Culture_zh-CN": "Chinese (Simplified, PRC)", - "Delete": "Delete", - "Department": "Department", - "DirectionAscLabel": "A-Z", - "DirectionDescLabel": "Z-A", - "Documents": "Documents", - "Download": "Download", - "EditAvatar": "Edit", - "EditButton": "Edit", - "Email": "Email", - "EmptyFieldError": "Empty field", - "Enable": "Enable", - "EncryptingFile": "Encrypting file", - "EncryptionFilePreparing": "Preparing file for encryption", - "EncryptionKeysReload": "Encryption keys must be re-entered", - "Error": "Error", - "FillFormButton": "Fill in the form", - "FullAccess": "Full access", - "Guest": "Guest", - "Image": "Image", - "Language": "Language", - "LastName": "Last Name", - "LearnMore": "Learn more", - "Load": "Load", - "LoadingDescription": "Please wait...", - "LoadingProcessing": "Loading...", - "Mail": "Mail", - "MainHeaderSelectAll": "Select all", - "MakeForm": "Save as oform", - "MeLabel": "Me", - "More": "More", - "Name": "Name", - "NewVersionAvailable": "A new version of the website available", - "Next": "Next", - "NotFoundLanguage": "Can't find your language? Contact us at <1>{{supportEmail}} to take part in the translation and get rewards.", - "OKButton": "OK", - "OpenApp": "Open your {{title}} app", - "Owner": "Owner", - "PageOfTotalPage": "{{page}} of {{totalPage}}", - "Password": "Password", - "PasswordLimitDigits": "digits", - "PasswordLimitLength": "from {{fromNumber}} to {{toNumber}} characters", - "PasswordLimitMessage": "Password must contain", - "PasswordLimitSpecialSymbols": "special characters", - "PasswordLimitUpperCase": "capital letters", - "People": "People", - "Phone": "Phone", - "Pin": "Pin", - "Previous": "Previous", - "Profile": "Profile", - "ProjectsProduct": "Projects", - "ProviderLoginError": "Authorization error", - "ProviderNotConnected": "Provider is not connected to your account", - "RequiredField": "Required field", - "ResetApplication": "Reset application", - "Review": "Review", - "Role": "Role", - "SaveButton": "Save", - "Search": "Search", - "Select": "Select", - "SelectAll": "Select all", - "SendButton": "Send", - "Sending": "Sending...", - "Settings": "Settings", - "ShowUsersList": "View users list", - "SignInWithFacebook": "Sign in with Facebook", - "SignInWithGoogle": "Sign in with Google", - "SignInWithLinkedIn": "Sign in with LinkedIn", - "SignInWithTwitter": "Sign in with Twitter", - "Size": "Size", - "SomethingWentWrong": "Something went wrong.", - "SwitchToThumbnails": "Switch to thumbnails view", - "SwitchViewToCompact": "Switch to compact view", - "TitleSelectFile": "Select", - "Type": "Type", - "Unknown": "Unknown", - "UnknownError": "Unknown error", - "Unpin": "Unpin", - "User": "User", - "Version": "Version", - "Video": "Video", - "View": "View", - "ViewWeb": "View web version", - "Warning": "Warning" + "About": "About", + "Actions": "Actions", + "Active": "Active", + "AddButton": "Add", + "AddFilter": "Add filter", + "AdminSettings": "Admin settings", + "Archive": "Archive", + "Audio": "Audio", + "BarMaintenanceDescription": "We apologize for any short-term technical issues in service functioning, that may appear on {{targetDate}} during the update of {{productName}}.", + "BarMaintenanceDisclaimer": "Please, make sure that all the changes are successfully saved during this day.", + "ByFirstNameSorting": "By first name", + "ByLastNameSorting": "By last name", + "CancelButton": "Cancel", + "ClearButton": "Reset filter", + "CloseButton": "Close", + "ComingSoon": "Coming soon", + "CommunityProduct": "Community", + "Confirmation": "Confirmation", + "ContinueButton": "Continue", + "CopyEmailAndPassword": "Copy email and password", + "CountPerPage": "{{count}} per page", + "Create": "Create", + "Culture_az": "Azerbaijani (Latin, Azerbaijan)", + "Culture_bg": "Bulgarian (Bulgaria)", + "Culture_cs": "Czech (Czech Republic)", + "Culture_de": "German (Germany)", + "Culture_de-CH": "German (Switzerland)", + "Culture_el": "Greek (Greece)", + "Culture_en": "English (United Kingdom)", + "Culture_en-US": "English (United States)", + "Culture_es": "Spanish (Spain)", + "Culture_es-MX": "Spanish (Mexico)", + "Culture_fi": "Finnish (Finland)", + "Culture_fr": "French (France)", + "Culture_it": "Italian (Italy)", + "Culture_ja": "Japanese (Japan)", + "Culture_ko": "Korean (Korea)", + "Culture_lo": "Laotian (Laos)", + "Culture_lv": "Latvian (Latvia)", + "Culture_nl": "Dutch (Netherlands)", + "Culture_pl": "Polish (Poland)", + "Culture_pt": "Portuguese (Portugal)", + "Culture_pt-BR": "Portuguese (Brazil)", + "Culture_ro": "Romanian (Romania)", + "Culture_ru": "Russian (Russia)", + "Culture_sk": "Slovak (Slovakia)", + "Culture_sl": "Slovenian (Slovenia)", + "Culture_tr": "Turkish (Turkey)", + "Culture_uk": "Ukrainian (Ukraine)", + "Culture_vi": "Vietnamese (Vietnam)", + "Culture_zh-CN": "Chinese (Simplified, PRC)", + "Delete": "Delete", + "Department": "Department", + "DirectionAscLabel": "A-Z", + "DirectionDescLabel": "Z-A", + "Documents": "Documents", + "Download": "Download", + "EditAvatar": "Edit", + "EditButton": "Edit", + "Email": "Email", + "EmptyFieldError": "Empty field", + "Enable": "Enable", + "EncryptingFile": "Encrypting file", + "EncryptionFilePreparing": "Preparing file for encryption", + "EncryptionKeysReload": "Encryption keys must be re-entered", + "Error": "Error", + "FillFormButton": "Fill in the form", + "FullAccess": "Full access", + "Guest": "Guest", + "Image": "Image", + "Language": "Language", + "LastName": "Last Name", + "LearnMore": "Learn more", + "Load": "Load", + "LoadingDescription": "Please wait...", + "LoadingProcessing": "Loading...", + "Mail": "Mail", + "MainHeaderSelectAll": "Select all", + "MakeForm": "Save as oform", + "MeLabel": "Me", + "More": "More", + "Name": "Name", + "NewVersionAvailable": "A new version of the website available", + "Next": "Next", + "NotFoundLanguage": "Can't find your language? Contact us at <1>{{supportEmail}} to take part in the translation and get rewards.", + "OKButton": "OK", + "OpenApp": "Open your {{title}} app", + "Owner": "Owner", + "PageOfTotalPage": "{{page}} of {{totalPage}}", + "Password": "Password", + "PasswordLimitDigits": "digits", + "PasswordLimitLength": "from {{fromNumber}} to {{toNumber}} characters", + "PasswordLimitMessage": "Password must contain", + "PasswordLimitSpecialSymbols": "special characters", + "PasswordLimitUpperCase": "capital letters", + "People": "People", + "Phone": "Phone", + "Pin": "Pin", + "Previous": "Previous", + "Profile": "Profile", + "ProjectsProduct": "Projects", + "ProviderLoginError": "Authorization error", + "ProviderNotConnected": "Provider is not connected to your account", + "RequiredField": "Required field", + "ResetApplication": "Reset application", + "Review": "Review", + "Role": "Role", + "SaveButton": "Save", + "Search": "Search", + "Select": "Select", + "SelectAll": "Select all", + "SendButton": "Send", + "Sending": "Sending...", + "Settings": "Settings", + "ShowUsersList": "View users list", + "SignInWithFacebook": "Sign in with Facebook", + "SignInWithGoogle": "Sign in with Google", + "SignInWithLinkedIn": "Sign in with LinkedIn", + "SignInWithTwitter": "Sign in with Twitter", + "Size": "Size", + "SomethingWentWrong": "Something went wrong.", + "SwitchToThumbnails": "Switch to thumbnails view", + "SwitchViewToCompact": "Switch to compact view", + "TitleSelectFile": "Select", + "Type": "Type", + "Unknown": "Unknown", + "UnknownError": "Unknown error", + "Unpin": "Unpin", + "User": "User", + "Version": "Version", + "Video": "Video", + "View": "View", + "ViewWeb": "View web version", + "Warning": "Warning" } diff --git a/web/ASC.Web.Client/src/components/pages/Home/index.js b/web/ASC.Web.Client/src/components/pages/Home/index.js index 616af7bfef..5e726177c1 100644 --- a/web/ASC.Web.Client/src/components/pages/Home/index.js +++ b/web/ASC.Web.Client/src/components/pages/Home/index.js @@ -15,114 +15,114 @@ import { setDocumentTitle } from "../../../helpers/utils"; import ModuleTile from "./ModuleTile"; const HomeContainer = styled.div` - padding: 62px 15px 0 15px; - margin: 0 auto; - max-width: 1140px; - width: 100%; - box-sizing: border-box; - /*justify-content: center;*/ + padding: 62px 15px 0 15px; + margin: 0 auto; + max-width: 1140px; + width: 100%; + box-sizing: border-box; + /*justify-content: center;*/ - .home-modules { - display: flex; - flex-wrap: wrap; - margin: 0 -15px; + .home-modules { + display: flex; + flex-wrap: wrap; + margin: 0 -15px; - .home-module { - flex-basis: 0; - flex-grow: 1; - max-width: 100%; - } + .home-module { + flex-basis: 0; + flex-grow: 1; + max-width: 100%; } + } - .home-error-text { - margin-top: 23px; - padding: 0 30px; - @media (min-width: 768px) { - margin-left: 25%; - flex: 0 0 50%; - max-width: 50%; - } - @media (min-width: 576px) { - flex: 0 0 100%; - max-width: 100%; - } + .home-error-text { + margin-top: 23px; + padding: 0 30px; + @media (min-width: 768px) { + margin-left: 25%; + flex: 0 0 50%; + max-width: 50%; } + @media (min-width: 576px) { + flex: 0 0 100%; + max-width: 100%; + } + } `; const Tiles = ({ modules, isPrimary }) => { - let index = 0; - const mapped = modules.filter( - (m) => m.isPrimary === isPrimary && m.isolateMode !== true - ); + let index = 0; + const mapped = modules.filter( + (m) => m.isPrimary === isPrimary && m.isolateMode !== true + ); - //console.log("Tiles", mapped, isPrimary); + //console.log("Tiles", mapped, isPrimary); - return mapped.length > 0 ? ( -
- {mapped.map((m) => ( -
- history.push(m.link)} /> -
- ))} + return mapped.length > 0 ? ( +
+ {mapped.map((m) => ( +
+ history.push(m.link)} />
- ) : ( - <> - ); + ))} +
+ ) : ( + <> + ); }; Tiles.propTypes = { - modules: PropTypes.array.isRequired, - isPrimary: PropTypes.bool.isRequired, + modules: PropTypes.array.isRequired, + isPrimary: PropTypes.bool.isRequired, }; const Body = ({ modules, match, isLoaded }) => { - const { t } = useTranslation(); - const { error } = match.params; - setDocumentTitle(); + const { t } = useTranslation(); + const { error } = match.params; + setDocumentTitle(); - useEffect(() => error && toastr.error(error), [error]); + useEffect(() => error && toastr.error(error), [error]); - return !isLoaded ? ( - <> - ) : ( - - - + return !isLoaded ? ( + <> + ) : ( + + + - {!modules || !modules.length ? ( - - {t("NoOneModulesAvailable")} - - ) : null} - - ); + {!modules || !modules.length ? ( + + {t("NoOneModulesAvailable")} + + ) : null} + + ); }; const Home = ({ defaultPage, ...rest }) => { - return tryRedirectTo(defaultPage) ? ( - <> - ) : ( - - - - - - ); + return tryRedirectTo(defaultPage) ? ( + <> + ) : ( + + + + + + ); }; Home.propTypes = { - modules: PropTypes.array.isRequired, - isLoaded: PropTypes.bool, - defaultPage: PropTypes.string, + modules: PropTypes.array.isRequired, + isLoaded: PropTypes.bool, + defaultPage: PropTypes.string, }; export default inject(({ auth }) => { - const { isLoaded, settingsStore, moduleStore } = auth; - const { defaultPage } = settingsStore; - const { modules } = moduleStore; - return { - defaultPage, - modules, - isLoaded, - }; + const { isLoaded, settingsStore, moduleStore } = auth; + const { defaultPage } = settingsStore; + const { modules } = moduleStore; + return { + defaultPage, + modules, + isLoaded, + }; })(withRouter(observer(Home))); From 6b88a2dd43a8ae007a328f279275650065a3c152 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 13:59:20 +0300 Subject: [PATCH 21/81] change code formatting 2 --- config/kafka.json | 3 +- frontend.code-workspace | 116 +- packages/asc-web-common/constants/index.js | 2 +- .../src/pages/Home/Section/Header/index.js | 1260 ++++++++--------- 4 files changed, 678 insertions(+), 703 deletions(-) diff --git a/config/kafka.json b/config/kafka.json index 67a89013af..8f173fe541 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,4 +1,3 @@ { - "kafka": { - } + "kafka": {} } diff --git a/frontend.code-workspace b/frontend.code-workspace index e1a4403f8f..ecd0bea263 100644 --- a/frontend.code-workspace +++ b/frontend.code-workspace @@ -1,61 +1,61 @@ { - "folders": [ - { - "name": "✨ appserver", - "path": "." - }, - { - "name": "📦 @appserver/common", - "path": "packages\\asc-web-common" - }, - { - "name": "📦 @appserver/components", - "path": "packages\\asc-web-components" - }, - { - "name": "🚀 @appserver/files", - "path": "products\\ASC.Files\\Client" - }, - { - "name": "🚀 @appserver/people", - "path": "products\\ASC.People\\Client" - }, - { - "name": "🚀 @appserver/crm", - "path": "products\\ASC.Crm\\Client" - }, - { - "name": "🚀 @appserver/projects", - "path": "products\\ASC.Projects\\Client" - }, - { - "name": "🚀 @appserver/mail", - "path": "products\\ASC.Mail\\Client" - }, - { - "name": "🚀 @appserver/calendar", - "path": "products\\ASC.Calendar\\Client" - }, - { - "name": "🚀 @appserver/studio", - "path": "web\\ASC.Web.Client" - }, - { - "name": "🚀 @appserver/login", - "path": "web\\ASC.Web.Login" - }, - { - "name": "🚀 @appserver/editor", - "path": "web\\ASC.Web.Editor" - } - ], - "settings": { - "window.zoomLevel": 0, - "editor.formatOnSave": true, - "editor.defaultFormatter": "esbenp.prettier-vscode", - "liveServer.settings.multiRootWorkspaceName": "✨ appserver" + "folders": [ + { + "name": "✨ appserver", + "path": "." }, - "extensions": { - "recommendations": ["folke.vscode-monorepo-workspace"] + { + "name": "📦 @appserver/common", + "path": "packages\\asc-web-common" + }, + { + "name": "📦 @appserver/components", + "path": "packages\\asc-web-components" + }, + { + "name": "🚀 @appserver/files", + "path": "products\\ASC.Files\\Client" + }, + { + "name": "🚀 @appserver/people", + "path": "products\\ASC.People\\Client" + }, + { + "name": "🚀 @appserver/crm", + "path": "products\\ASC.Crm\\Client" + }, + { + "name": "🚀 @appserver/projects", + "path": "products\\ASC.Projects\\Client" + }, + { + "name": "🚀 @appserver/mail", + "path": "products\\ASC.Mail\\Client" + }, + { + "name": "🚀 @appserver/calendar", + "path": "products\\ASC.Calendar\\Client" + }, + { + "name": "🚀 @appserver/studio", + "path": "web\\ASC.Web.Client" + }, + { + "name": "🚀 @appserver/login", + "path": "web\\ASC.Web.Login" + }, + { + "name": "🚀 @appserver/editor", + "path": "web\\ASC.Web.Editor" } - } \ No newline at end of file + ], + "settings": { + "window.zoomLevel": 0, + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "liveServer.settings.multiRootWorkspaceName": "✨ appserver" + }, + "extensions": { + "recommendations": ["folke.vscode-monorepo-workspace"] + } +} diff --git a/packages/asc-web-common/constants/index.js b/packages/asc-web-common/constants/index.js index bb575b6114..36c6853900 100644 --- a/packages/asc-web-common/constants/index.js +++ b/packages/asc-web-common/constants/index.js @@ -153,4 +153,4 @@ export const TenantTrustedDomainsType = Object.freeze({ All: 2, }); -export const PasswordLimitSpecialCharacters = "!@#$%^&*"; \ No newline at end of file +export const PasswordLimitSpecialCharacters = "!@#$%^&*"; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 5e75cee0e3..c25f4bf3e2 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -17,706 +17,682 @@ import toastr from "studio/toastr"; import styled, { css } from "styled-components"; const StyledContainer = styled.div` - .table-container_group-menu { - ${(props) => - props.viewAs === "table" - ? css` - margin: 0px -20px; - width: calc(100% + 44px); - ` - : css` - margin: 0px -24px; - width: calc(100% + 48px); - `} + .table-container_group-menu { + ${(props) => + props.viewAs === "table" + ? css` + margin: 0px -20px; + width: calc(100% + 44px); + ` + : css` + margin: 0px -24px; + width: calc(100% + 48px); + `} - @media ${tablet} { - margin: 0 -16px; - width: calc(100% + 32px); - } + @media ${tablet} { + margin: 0 -16px; + width: calc(100% + 32px); + } + } + + .header-container { + position: relative; + ${(props) => + props.title && + css` + display: grid; + grid-template-columns: ${({ + isRootFolder, + canCreate, + isRecycleBinFolder, + }) => { + if (isRootFolder) { + if (canCreate || isRecycleBinFolder) return "auto auto 1fr"; + return "auto 1fr"; + } + if (canCreate) return "auto auto auto 1fr 32px"; + return "auto auto 1fr 32px"; + }}; + `} + align-items: center; + max-width: calc(100vw - 32px); + + @media ${tablet} { + .headline-header { + margin-left: -1px; + } + } + .arrow-button { + margin-right: 15px; + min-width: 17px; + + @media ${tablet} { + padding: 8px 0 8px 8px; + margin-left: -8px; + margin-right: 16px; + } } - .header-container { - position: relative; - ${(props) => - props.title && - css` - display: grid; - grid-template-columns: ${({ - isRootFolder, - canCreate, - isRecycleBinFolder, - }) => { - if (isRootFolder) { - if (canCreate || isRecycleBinFolder) - return "auto auto 1fr"; - return "auto 1fr"; - } - if (canCreate) return "auto auto auto 1fr 32px"; - return "auto auto 1fr 32px"; - }}; - `} - align-items: center; - max-width: calc(100vw - 32px); + .add-button { + margin-bottom: -1px; + margin-left: 16px; - @media ${tablet} { - .headline-header { - margin-left: -1px; - } + @media ${tablet} { + margin-left: auto; + margin-right: 32px; + + & > div:first-child { + padding: 8px 8px 8px 8px; + margin-right: -8px; } - .arrow-button { - margin-right: 15px; - min-width: 17px; + } + } - @media ${tablet} { - padding: 8px 0 8px 8px; - margin-left: -8px; - margin-right: 16px; - } - } + .option-button { + margin-bottom: -1px; - .add-button { - margin-bottom: -1px; - margin-left: 16px; + margin-left: auto; + margin-right: 16px; - @media ${tablet} { - margin-left: auto; - margin-right: 32px; - - & > div:first-child { - padding: 8px 8px 8px 8px; - margin-right: -8px; - } - } - } - - .option-button { - margin-bottom: -1px; - - margin-left: auto; - margin-right: 16px; - - /* @media (min-width: 1024px) { + /* @media (min-width: 1024px) { margin-left: 8px; } */ - @media ${tablet} { - /* margin-left: auto; + @media ${tablet} { + /* margin-left: auto; margin-right: 32px; */ - & > div:first-child { - padding: 8px 8px 8px 8px; - margin-right: -8px; - } - } - } - - .trash-button { - margin-bottom: -1px; - - @media (min-width: 1024px) { - margin-left: 8px; - } - - @media ${tablet} { - margin-left: auto; - margin-right: 32px; - & > div:first-child { - padding: 3px; - margin-right: -8px; - } - } + & > div:first-child { + padding: 8px 8px 8px 8px; + margin-right: -8px; } + } } - .group-button-menu-container { - margin: 0 -16px; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + .trash-button { + margin-bottom: -1px; - ${isMobile && - css` - position: sticky; - `} + @media (min-width: 1024px) { + margin-left: 8px; + } - ${(props) => - !props.isTabletView - ? props.width && - isMobile && - css` - width: ${props.width + 40 + "px"}; - ` - : props.width && - isMobile && - css` - width: ${props.width + 32 + "px"}; - `} + @media ${tablet} { + margin-left: auto; + margin-right: 32px; + & > div:first-child { + padding: 3px; + margin-right: -8px; + } + } + } + } + + .group-button-menu-container { + margin: 0 -16px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + + ${isMobile && + css` + position: sticky; + `} + + ${(props) => + !props.isTabletView + ? props.width && + isMobile && + css` + width: ${props.width + 40 + "px"}; + ` + : props.width && + isMobile && + css` + width: ${props.width + 32 + "px"}; + `} @media ${tablet} { - padding-bottom: 0; - ${!isMobile && - css` - height: 56px; - `} - & > div:first-child { - ${(props) => - !isMobile && - props.width && - css` - width: ${props.width + 16 + "px"}; - `} + padding-bottom: 0; + ${!isMobile && + css` + height: 56px; + `} + & > div:first-child { + ${(props) => + !isMobile && + props.width && + css` + width: ${props.width + 16 + "px"}; + `} - position: absolute; - ${(props) => - !props.isDesktop && - css` - top: 48px; - `} - z-index: 180; - } - } - - @media ${desktop} { - margin: 0 -24px; - } + position: absolute; + ${(props) => + !props.isDesktop && + css` + top: 48px; + `} + z-index: 180; + } } + + @media ${desktop} { + margin: 0 -24px; + } + } `; const StyledInfoPanelToggleWrapper = styled.div` + display: flex; + margin-left: auto; + align-items: center; + align-self: center; + justify-content: center; + + .info-panel-toggle-bg { + height: 32px; + width: 32px; display: flex; - margin-left: auto; align-items: center; - align-self: center; justify-content: center; + border-radius: 50%; + background-color: ${(props) => + props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; + } - .info-panel-toggle-bg { - height: 32px; - width: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - background-color: ${(props) => - props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; - } - - ${(props) => - props.isHeaderVisible && - css` - margin-bottom: 2px; - margin-right: 24px; - padding-left: 12px; - `} + ${(props) => + props.isHeaderVisible && + css` + margin-bottom: 2px; + margin-right: 24px; + padding-left: 12px; + `} `; class SectionHeaderContent extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); + } + + onCreate = (format) => { + this.props.setAction({ + type: FileAction.Create, + extension: format, + id: -1, + }); + }; + + createDocument = () => this.onCreate("docx"); + + createSpreadsheet = () => this.onCreate("xlsx"); + + createPresentation = () => this.onCreate("pptx"); + + createForm = () => this.onCreate("docxf"); + + createFormFromFile = () => { + const { setSelectFileDialogVisible } = this.props; + setSelectFileDialogVisible(true); + }; + + createFolder = () => this.onCreate(); + + uploadToFolder = () => console.log("Upload To Folder click"); + + getContextOptionsPlus = () => { + const { t, isPrivacyFolder } = this.props; + + return [ + { + key: "new-document", + label: t("NewDocument"), + onClick: this.createDocument, + }, + { + key: "new-spreadsheet", + label: t("NewSpreadsheet"), + onClick: this.createSpreadsheet, + }, + { + key: "new-presentation", + label: t("NewPresentation"), + onClick: this.createPresentation, + }, + { + label: t("Translations:NewForm"), + onClick: this.createForm, + }, + { + label: t("Translations:NewFormFile"), + onClick: this.createFormFromFile, + disabled: isPrivacyFolder, + }, + { + key: "new-folder", + label: t("NewFolder"), + onClick: this.createFolder, + }, + { key: "separator", isSeparator: true }, + { + key: "make-invitation-link", + label: t("UploadToFolder"), + onClick: this.uploadToFolder, + disabled: true, + }, + ]; + }; + + createLinkForPortalUsers = () => { + const { currentFolderId } = this.props; + const { t } = this.props; + + copy( + `${window.location.origin}/products/files/filter?folder=${currentFolderId}` + ); + + toastr.success(t("Translations:LinkCopySuccess")); + }; + + onMoveAction = () => { + this.props.setIsFolderActions(true); + this.props.setBufferSelection(this.props.currentFolderId); + return this.props.setMoveToPanelVisible(true); + }; + onCopyAction = () => { + this.props.setIsFolderActions(true); + this.props.setBufferSelection(this.props.currentFolderId); + return this.props.setCopyPanelVisible(true); + }; + downloadAction = () => { + this.props.setBufferSelection(this.props.currentFolderId); + this.props.setIsFolderActions(true); + this.props + .downloadAction(this.props.t("Translations:ArchivingData"), [ + this.props.currentFolderId, + ]) + .catch((err) => toastr.error(err)); + }; + + renameAction = () => console.log("renameAction click"); + onOpenSharingPanel = () => { + this.props.setBufferSelection(this.props.currentFolderId); + this.props.setIsFolderActions(true); + return this.props.setSharingPanelVisible(true); + }; + + onDeleteAction = () => { + const { + t, + deleteAction, + confirmDelete, + setDeleteDialogVisible, + isThirdPartySelection, + currentFolderId, + getFolderInfo, + setBufferSelection, + } = this.props; + + this.props.setIsFolderActions(true); + + if (confirmDelete || isThirdPartySelection) { + getFolderInfo(currentFolderId).then((data) => { + setBufferSelection(data); + setDeleteDialogVisible(true); + }); + } else { + const translations = { + deleteOperation: t("Translations:DeleteOperation"), + deleteFromTrash: t("Translations:DeleteFromTrash"), + deleteSelectedElem: t("Translations:DeleteSelectedElem"), + }; + + deleteAction(translations, [currentFolderId], true).catch((err) => + toastr.error(err) + ); } + }; - onCreate = (format) => { - this.props.setAction({ - type: FileAction.Create, - extension: format, - id: -1, - }); - }; + onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); + onToggleInfoPanel = () => this.props.toggleInfoPanel(); - createDocument = () => this.onCreate("docx"); + getContextOptionsFolder = () => { + const { t, personal } = this.props; - createSpreadsheet = () => this.onCreate("xlsx"); + return [ + { + key: "sharing-settings", + label: t("SharingSettings"), + onClick: this.onOpenSharingPanel, + disabled: personal ? true : false, + }, + { + key: "link-portal-users", + label: t("LinkForPortalUsers"), + onClick: this.createLinkForPortalUsers, + disabled: personal ? true : false, + }, + { key: "separator-2", isSeparator: true }, + { + key: "move-to", + label: t("MoveTo"), + onClick: this.onMoveAction, + disabled: false, + }, + { + key: "copy", + label: t("Translations:Copy"), + onClick: this.onCopyAction, + disabled: false, + }, + { + key: "download", + label: t("Common:Download"), + onClick: this.downloadAction, + disabled: false, + }, + { + key: "rename", + label: t("Rename"), + onClick: this.renameAction, + disabled: true, + }, + { + key: "delete", + label: t("Common:Delete"), + onClick: this.onDeleteAction, + disabled: false, + }, + ]; + }; - createPresentation = () => this.onCreate("pptx"); + onBackToParentFolder = () => { + const { setIsLoading, parentId, filter, fetchFiles } = this.props; + setIsLoading(true); + fetchFiles(parentId, null, true, false).finally(() => setIsLoading(false)); + }; - createForm = () => this.onCreate("docxf"); + onSelect = (e) => { + const key = e.currentTarget.dataset.key; + this.props.setSelected(key); + }; - createFormFromFile = () => { - const { setSelectFileDialogVisible } = this.props; - setSelectFileDialogVisible(true); - }; + onClose = () => { + this.props.setSelected("close"); + }; - createFolder = () => this.onCreate(); + getMenuItems = () => { + const { t, cbMenuItems, getCheckboxItemLabel } = this.props; - uploadToFolder = () => console.log("Upload To Folder click"); + const checkboxOptions = ( + <> + {cbMenuItems.map((key) => { + const label = getCheckboxItemLabel(t, key); + return ( + + ); + })} + + ); - getContextOptionsPlus = () => { - const { t, isPrivacyFolder } = this.props; + return checkboxOptions; + }; - return [ - { - key: "new-document", - label: t("NewDocument"), - onClick: this.createDocument, - }, - { - key: "new-spreadsheet", - label: t("NewSpreadsheet"), - onClick: this.createSpreadsheet, - }, - { - key: "new-presentation", - label: t("NewPresentation"), - onClick: this.createPresentation, - }, - { - label: t("Translations:NewForm"), - onClick: this.createForm, - }, - { - label: t("Translations:NewFormFile"), - onClick: this.createFormFromFile, - disabled: isPrivacyFolder, - }, - { - key: "new-folder", - label: t("NewFolder"), - onClick: this.createFolder, - }, - { key: "separator", isSeparator: true }, - { - key: "make-invitation-link", - label: t("UploadToFolder"), - onClick: this.uploadToFolder, - disabled: true, - }, - ]; - }; + onChange = (checked) => { + this.props.setSelected(checked ? "all" : "none"); + }; - createLinkForPortalUsers = () => { - const { currentFolderId } = this.props; - const { t } = this.props; + render() { + //console.log("Body header render"); - copy( - `${window.location.origin}/products/files/filter?folder=${currentFolderId}` - ); + const { + t, + tReady, + isHeaderVisible, + isHeaderChecked, + isHeaderIndeterminate, + isInfoPanelVisible, + isRootFolder, + title, + canCreate, + isDesktop, + isTabletView, + personal, + getHeaderMenu, + viewAs, + isRecycleBinFolder, + isEmptyFilesList, + } = this.props; - toastr.success(t("Translations:LinkCopySuccess")); - }; + const menuItems = this.getMenuItems(); + const isLoading = !title || !tReady; + const headerMenu = getHeaderMenu(t); - onMoveAction = () => { - this.props.setIsFolderActions(true); - this.props.setBufferSelection(this.props.currentFolderId); - return this.props.setMoveToPanelVisible(true); - }; - onCopyAction = () => { - this.props.setIsFolderActions(true); - this.props.setBufferSelection(this.props.currentFolderId); - return this.props.setCopyPanelVisible(true); - }; - downloadAction = () => { - this.props.setBufferSelection(this.props.currentFolderId); - this.props.setIsFolderActions(true); - this.props - .downloadAction(this.props.t("Translations:ArchivingData"), [ - this.props.currentFolderId, - ]) - .catch((err) => toastr.error(err)); - }; + const infoPanelToggle = ( + +
+ +
+
+ ); - renameAction = () => console.log("renameAction click"); - onOpenSharingPanel = () => { - this.props.setBufferSelection(this.props.currentFolderId); - this.props.setIsFolderActions(true); - return this.props.setSharingPanelVisible(true); - }; - - onDeleteAction = () => { - const { - t, - deleteAction, - confirmDelete, - setDeleteDialogVisible, - isThirdPartySelection, - currentFolderId, - getFolderInfo, - setBufferSelection, - } = this.props; - - this.props.setIsFolderActions(true); - - if (confirmDelete || isThirdPartySelection) { - getFolderInfo(currentFolderId).then((data) => { - setBufferSelection(data); - setDeleteDialogVisible(true); - }); - } else { - const translations = { - deleteOperation: t("Translations:DeleteOperation"), - deleteFromTrash: t("Translations:DeleteFromTrash"), - deleteSelectedElem: t("Translations:DeleteSelectedElem"), - }; - - deleteAction(translations, [currentFolderId], true).catch((err) => - toastr.error(err) - ); - } - }; - - onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); - onToggleInfoPanel = () => this.props.toggleInfoPanel(); - - getContextOptionsFolder = () => { - const { t, personal } = this.props; - - return [ - { - key: "sharing-settings", - label: t("SharingSettings"), - onClick: this.onOpenSharingPanel, - disabled: personal ? true : false, - }, - { - key: "link-portal-users", - label: t("LinkForPortalUsers"), - onClick: this.createLinkForPortalUsers, - disabled: personal ? true : false, - }, - { key: "separator-2", isSeparator: true }, - { - key: "move-to", - label: t("MoveTo"), - onClick: this.onMoveAction, - disabled: false, - }, - { - key: "copy", - label: t("Translations:Copy"), - onClick: this.onCopyAction, - disabled: false, - }, - { - key: "download", - label: t("Common:Download"), - onClick: this.downloadAction, - disabled: false, - }, - { - key: "rename", - label: t("Rename"), - onClick: this.renameAction, - disabled: true, - }, - { - key: "delete", - label: t("Common:Delete"), - onClick: this.onDeleteAction, - disabled: false, - }, - ]; - }; - - onBackToParentFolder = () => { - const { setIsLoading, parentId, filter, fetchFiles } = this.props; - setIsLoading(true); - fetchFiles(parentId, null, true, false).finally(() => - setIsLoading(false) - ); - }; - - onSelect = (e) => { - const key = e.currentTarget.dataset.key; - this.props.setSelected(key); - }; - - onClose = () => { - this.props.setSelected("close"); - }; - - getMenuItems = () => { - const { t, cbMenuItems, getCheckboxItemLabel } = this.props; - - const checkboxOptions = ( - <> - {cbMenuItems.map((key) => { - const label = getCheckboxItemLabel(t, key); - return ( - - ); - })} - - ); - - return checkboxOptions; - }; - - onChange = (checked) => { - this.props.setSelected(checked ? "all" : "none"); - }; - - render() { - //console.log("Body header render"); - - const { - t, - tReady, - isHeaderVisible, - isHeaderChecked, - isHeaderIndeterminate, - isInfoPanelVisible, - isRootFolder, - title, - canCreate, - isDesktop, - isTabletView, - personal, - getHeaderMenu, - viewAs, - isRecycleBinFolder, - isEmptyFilesList, - } = this.props; - - const menuItems = this.getMenuItems(); - const isLoading = !title || !tReady; - const headerMenu = getHeaderMenu(t); - - const infoPanelToggle = ( - -
- + {(context) => ( + + {isHeaderVisible ? ( + + ) : ( +
+ {isLoading ? ( + + ) : ( + <> + {!isRootFolder && ( + -
- - ); - - return ( - - {(context) => ( - + )} + - {isHeaderVisible ? ( - - ) : ( -
- {isLoading ? ( - - ) : ( - <> - {!isRootFolder && ( - - )} - - {title} - - {!isRootFolder && canCreate ? ( - <> - + {title} + + {!isRootFolder && canCreate ? ( + <> + - - - ) : ( - canCreate && ( - - ) - )} - {isRecycleBinFolder && - !isEmptyFilesList && ( - - - - )} - {infoPanelToggle} - - )} -
- )} -
+ + + ) : ( + canCreate && ( + + ) + )} + {isRecycleBinFolder && !isEmptyFilesList && ( + + + + )} + {infoPanelToggle} + )} -
- ); - } +
+ )} + + )} + + ); + } } export default inject( - ({ - auth, - filesStore, - dialogsStore, - selectedFolderStore, - filesActionsStore, - settingsStore, - treeFoldersStore, - infoPanelStore, - }) => { - const { - setSelected, - setSelection, - fileActionStore, - fetchFiles, - filter, - canCreate, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, - isThirdPartySelection, - setIsLoading, - cbMenuItems, - getCheckboxItemLabel, - isEmptyFilesList, - getFolderInfo, - setBufferSelection, - viewAs, - } = filesStore; - const { setAction } = fileActionStore; - const { - setSharingPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setDeleteDialogVisible, - setEmptyTrashDialogVisible, - setSelectFileDialogVisible, - setIsFolderActions, - } = dialogsStore; + ({ + auth, + filesStore, + dialogsStore, + selectedFolderStore, + filesActionsStore, + settingsStore, + treeFoldersStore, + infoPanelStore, + }) => { + const { + setSelected, + setSelection, + fileActionStore, + fetchFiles, + filter, + canCreate, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + isThirdPartySelection, + setIsLoading, + cbMenuItems, + getCheckboxItemLabel, + isEmptyFilesList, + getFolderInfo, + setBufferSelection, + viewAs, + } = filesStore; + const { setAction } = fileActionStore; + const { + setSharingPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setDeleteDialogVisible, + setEmptyTrashDialogVisible, + setSelectFileDialogVisible, + setIsFolderActions, + } = dialogsStore; - const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore; - const { - deleteAction, - downloadAction, - getHeaderMenu, - } = filesActionsStore; + const { isRecycleBinFolder, isPrivacyFolder } = treeFoldersStore; + const { deleteAction, downloadAction, getHeaderMenu } = filesActionsStore; - //const { toggleInfoPanel, isInfoPanelVisible } = infoPanelStore; - const toggleInfoPanel = infoPanelStore.toggleIsVisible; - const isInfoPanelVisible = infoPanelStore.isVisible; + //const { toggleInfoPanel, isInfoPanelVisible } = infoPanelStore; + const toggleInfoPanel = infoPanelStore.toggleIsVisible; + const isInfoPanelVisible = infoPanelStore.isVisible; - return { - isDesktop: auth.settingsStore.isDesktopClient, - isRootFolder: selectedFolderStore.parentId === 0, - title: selectedFolderStore.title, - parentId: selectedFolderStore.parentId, - currentFolderId: selectedFolderStore.id, - filter, - canCreate, - toggleInfoPanel, - isInfoPanelVisible, - isHeaderVisible, - isHeaderIndeterminate, - isHeaderChecked, - isThirdPartySelection, - isTabletView: auth.settingsStore.isTabletView, - confirmDelete: settingsStore.confirmDelete, - personal: auth.settingsStore.personal, - cbMenuItems, - getFolderInfo, + return { + isDesktop: auth.settingsStore.isDesktopClient, + isRootFolder: selectedFolderStore.parentId === 0, + title: selectedFolderStore.title, + parentId: selectedFolderStore.parentId, + currentFolderId: selectedFolderStore.id, + filter, + canCreate, + toggleInfoPanel, + isInfoPanelVisible, + isHeaderVisible, + isHeaderIndeterminate, + isHeaderChecked, + isThirdPartySelection, + isTabletView: auth.settingsStore.isTabletView, + confirmDelete: settingsStore.confirmDelete, + personal: auth.settingsStore.personal, + cbMenuItems, + getFolderInfo, - setSelected, - setSelection, - setAction, - setIsLoading, - fetchFiles, - setSharingPanelVisible, - setMoveToPanelVisible, - setCopyPanelVisible, - setBufferSelection, - setIsFolderActions, - deleteAction, - setDeleteDialogVisible, - downloadAction, - getHeaderMenu, - getCheckboxItemLabel, - setSelectFileDialogVisible, + setSelected, + setSelection, + setAction, + setIsLoading, + fetchFiles, + setSharingPanelVisible, + setMoveToPanelVisible, + setCopyPanelVisible, + setBufferSelection, + setIsFolderActions, + deleteAction, + setDeleteDialogVisible, + downloadAction, + getHeaderMenu, + getCheckboxItemLabel, + setSelectFileDialogVisible, - isRecycleBinFolder, - setEmptyTrashDialogVisible, - isEmptyFilesList, - isPrivacyFolder, - viewAs, - }; - } + isRecycleBinFolder, + setEmptyTrashDialogVisible, + isEmptyFilesList, + isPrivacyFolder, + viewAs, + }; + } )( - withTranslation(["Home", "Common", "Translations"])( - withRouter(observer(SectionHeaderContent)) - ) + withTranslation(["Home", "Common", "Translations"])( + withRouter(observer(SectionHeaderContent)) + ) ); From 807fe75b72ace8f37bbd0c4e02d630a8f3666a40 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 14:25:10 +0300 Subject: [PATCH 22/81] change code formatting 3 --- .../components/Loaders/index.js | 34 +-- .../components/PageLayout/index.js | 37 ++- .../sub-components/section-header.js | 256 +++++++++--------- packages/asc-web-common/constants/index.js | 13 +- packages/asc-web-common/custom.scss | 10 +- .../asc-web-common/store/SettingsStore.js | 2 +- .../table-container/TableGroupMenu.js | 2 +- .../Client/src/HOCs/withContextOptions.js | 53 ---- .../src/pages/Home/Section/Header/index.js | 28 +- .../ASC.Files/Client/src/pages/Home/index.js | 37 ++- 10 files changed, 202 insertions(+), 270 deletions(-) diff --git a/packages/asc-web-common/components/Loaders/index.js b/packages/asc-web-common/components/Loaders/index.js index 9577fdd7c3..53a13fe12f 100644 --- a/packages/asc-web-common/components/Loaders/index.js +++ b/packages/asc-web-common/components/Loaders/index.js @@ -1,23 +1,23 @@ -import ArticleHeader from "./ArticleHeaderLoader"; -import Circle from "./CircleLoader"; -import DialogAsideLoader from "./DialogAsideLoader"; -import DialogLoader from "./DialogLoader"; -import Filter from "./FilterLoader"; -import Group from "./GroupLoader"; -import Header from "./HeaderLoader"; -import HistoryRows from "./HistoryRowsLoader"; -import MainButton from "./MainButtonLoader"; -import ProfileView from "./ProfileViewLoader"; import Rectangle from "./RectangleLoader"; -import Row from "./RowLoader"; -import Rows from "./RowsLoader"; +import Circle from "./CircleLoader"; +import Header from "./HeaderLoader"; import SectionHeader from "./SectionHeaderLoader"; -import SettingsFiles from "./SettingsFilesLoader"; -import Text from "./TextLoader"; -import Tile from "./TileLoader"; -import Tiles from "./TilesLoader"; +import ArticleHeader from "./ArticleHeaderLoader"; import TreeFolders from "./TreeFolderLoader"; import TreeSettingsLoader from "./TreeSettingsLoader"; +import Row from "./RowLoader"; +import Rows from "./RowsLoader"; +import Text from "./TextLoader"; +import Filter from "./FilterLoader"; +import ProfileView from "./ProfileViewLoader"; +import SettingsFiles from "./SettingsFilesLoader"; +import Group from "./GroupLoader"; +import HistoryRows from "./HistoryRowsLoader"; +import Tile from "./TileLoader"; +import Tiles from "./TilesLoader"; +import DialogLoader from "./DialogLoader"; +import DialogAsideLoader from "./DialogAsideLoader"; +import MainButton from "./MainButtonLoader"; export default { Rectangle, @@ -40,4 +40,4 @@ export default { DialogLoader, DialogAsideLoader, MainButton, -}; \ No newline at end of file +}; diff --git a/packages/asc-web-common/components/PageLayout/index.js b/packages/asc-web-common/components/PageLayout/index.js index 8b9cc9d876..dd919e949d 100644 --- a/packages/asc-web-common/components/PageLayout/index.js +++ b/packages/asc-web-common/components/PageLayout/index.js @@ -1,30 +1,29 @@ -import Backdrop from "@appserver/components/backdrop"; -import { Provider } from "@appserver/components/utils/context"; -import { desktop, size, tablet } from "@appserver/components/utils/device"; -import { inject, observer } from "mobx-react"; -import PropTypes from "prop-types"; import React from "react"; -import { isFirefox, isMobile, isMobileOnly } from "react-device-detect"; -import ReactResizeDetector from "react-resize-detector"; -import Selecto from "react-selecto"; -import styled, { css } from "styled-components"; - -import FloatingButton from "../FloatingButton"; +import PropTypes from "prop-types"; +import Backdrop from "@appserver/components/backdrop"; +import { desktop, size, tablet } from "@appserver/components/utils/device"; +import { Provider } from "@appserver/components/utils/context"; +import { isMobile, isFirefox, isMobileOnly } from "react-device-detect"; import Article from "./sub-components/article"; -import SubArticleBody from "./sub-components/article-body"; import SubArticleHeader from "./sub-components/article-header"; import SubArticleMainButton from "./sub-components/article-main-button"; +import SubArticleBody from "./sub-components/article-body"; import ArticlePinPanel from "./sub-components/article-pin-panel"; +import Section from "./sub-components/section"; +import SubSectionHeader from "./sub-components/section-header"; +import SubSectionFilter from "./sub-components/section-filter"; +import SubSectionBody from "./sub-components/section-body"; +import SubSectionBodyContent from "./sub-components/section-body-content"; +import SubSectionPaging from "./sub-components/section-paging"; +import SectionToggler from "./sub-components/section-toggler"; import InfoPanel from "./sub-components/info-panel"; import SubInfoPanelBody from "./sub-components/info-panel-body"; import SubInfoPanelHeader from "./sub-components/info-panel-header"; -import Section from "./sub-components/section"; -import SubSectionBody from "./sub-components/section-body"; -import SubSectionBodyContent from "./sub-components/section-body-content"; -import SubSectionFilter from "./sub-components/section-filter"; -import SubSectionHeader from "./sub-components/section-header"; -import SubSectionPaging from "./sub-components/section-paging"; -import SectionToggler from "./sub-components/section-toggler"; +import ReactResizeDetector from "react-resize-detector"; +import FloatingButton from "../FloatingButton"; +import { inject, observer } from "mobx-react"; +import Selecto from "react-selecto"; +import styled, { css } from "styled-components"; const StyledSelectoWrapper = styled.div` .selecto-selection { diff --git a/packages/asc-web-common/components/PageLayout/sub-components/section-header.js b/packages/asc-web-common/components/PageLayout/sub-components/section-header.js index fcf3ea9ae8..bccee3626f 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/section-header.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/section-header.js @@ -1,165 +1,153 @@ -import NoUserSelect from "@appserver/components/utils/commonStyles"; -import { desktop, tablet } from "@appserver/components/utils/device"; -import classnames from "classnames"; -import equal from "fast-deep-equal/react"; -import PropTypes from "prop-types"; import React from "react"; -import { isMobile } from "react-device-detect"; -import { LayoutContextConsumer } from "studio/Layout/context"; import styled, { css } from "styled-components"; +import equal from "fast-deep-equal/react"; +import classnames from "classnames"; +import PropTypes from "prop-types"; +import { LayoutContextConsumer } from "studio/Layout/context"; +import { isMobile } from "react-device-detect"; +import { tablet, desktop } from "@appserver/components/utils/device"; +import NoUserSelect from "@appserver/components/utils/commonStyles"; const StyledSectionHeader = styled.div` - height: 42px; - margin-right: 24px; - ${NoUserSelect} - ${isMobile && - css` - height: 20px; - width: ${(props) => !props.isLoaded && "100%"}; + height: 42px; + margin-right: 24px; + ${NoUserSelect} + ${isMobile && + css` + height: 20px; + width: ${(props) => !props.isLoaded && "100%"}; - margin-top: 62px; - @media ${tablet} { - margin-top: 48px; - } - `} + margin-top: 62px; + @media ${tablet} { + margin-top: 48px; + } + `} @media ${desktop} { - ${(props) => - (props.viewAs === "table" || props.viewAs === "tile") && - "margin-left: -4px"}; - } + ${(props) => + (props.viewAs === "table" || props.viewAs === "tile") && + "margin-left: -4px"}; + } - @media ${tablet} { - ${(props) => - props.viewAs !== "tablet" && - css` - height: 49px; + @media ${tablet} { + ${(props) => + props.viewAs !== "tablet" && + css` + height: 49px; - .arrow-button { - svg { - width: 14px !important; - } - margin-right: 10px !important; - } - `} - } + .arrow-button { + svg { + width: 14px !important; + } + margin-right: 10px !important; + } + `} + } - @media ${tablet} { - margin-right: 16px; - } + @media ${tablet} { + margin-right: 16px; + } - .section-header { - height: 50px; - ${isMobile && - css` - max-width: calc(100vw - 32px); - width: 100%; - `} - - ${isMobile && - css` - position: fixed; - top: 48px; - - width: ${(props) => - props.isArticlePinned ? `calc(100% - 272px)` : "100%"}; - - background-color: #fff; - z-index: 149; - padding-right: 16px; - `} - } + .section-header { + height: 50px; ${isMobile && css` - .section-header, - .section-header--hidden { - &, - .group-button-menu-container > div:first-child { - transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); - } - .group-button-menu-container { - padding-bottom: 0 !important; - > div:first-child { - top: ${(props) => - !props.isSectionHeaderVisible - ? "56px" - : "0px"} !important; - - @media ${desktop} { - ${isMobile && - css` - position: absolute; - `} - } - } - } - } + max-width: calc(100vw - 32px); + width: 100%; `} + + ${isMobile && + css` + position: fixed; + top: 48px; + + width: ${(props) => + props.isArticlePinned ? `calc(100% - 272px)` : "100%"}; + + background-color: #fff; + z-index: 149; + padding-right: 16px; + `} + } + ${isMobile && + css` + .section-header, .section-header--hidden { - ${isMobile && - css` - top: -61px; - `} + &, + .group-button-menu-container > div:first-child { + transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -moz-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -ms-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -webkit-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + -o-transition: top 0.3s cubic-bezier(0, 0, 0.8, 1); + } + .group-button-menu-container { + padding-bottom: 0 !important; + > div:first-child { + top: ${(props) => + !props.isSectionHeaderVisible ? "56px" : "0px"} !important; + + @media ${desktop} { + ${isMobile && + css` + position: absolute; + `} + } + } + } } + `} + .section-header--hidden { + ${isMobile && + css` + top: -61px; + `} + } `; class SectionHeader extends React.Component { - constructor(props) { - super(props); + constructor(props) { + super(props); - this.focusRef = React.createRef(); - } + this.focusRef = React.createRef(); + } - shouldComponentUpdate(nextProps) { - return !equal(this.props, nextProps); - } + shouldComponentUpdate(nextProps) { + return !equal(this.props, nextProps); + } - render() { - //console.log("PageLayout SectionHeader render"); - // eslint-disable-next-line react/prop-types + render() { + //console.log("PageLayout SectionHeader render"); + // eslint-disable-next-line react/prop-types - const { - isArticlePinned, - isHeaderVisible, - viewAs, - ...rest - } = this.props; + const { isArticlePinned, isHeaderVisible, viewAs, ...rest } = this.props; - return ( - - {(value) => ( - -
- - )} - - ); - } + return ( + + {(value) => ( + +
+ + )} + + ); + } } SectionHeader.displayName = "SectionHeader"; SectionHeader.propTypes = { - isArticlePinned: PropTypes.bool, - isHeaderVisible: PropTypes.bool, + isArticlePinned: PropTypes.bool, + isHeaderVisible: PropTypes.bool, }; export default SectionHeader; diff --git a/packages/asc-web-common/constants/index.js b/packages/asc-web-common/constants/index.js index 36c6853900..e40571097c 100644 --- a/packages/asc-web-common/constants/index.js +++ b/packages/asc-web-common/constants/index.js @@ -1,5 +1,6 @@ export const LANGUAGE = "language"; export const ARTICLE_PINNED_KEY = "asc_article_pinned_key"; + /** * Enum for employee activation status. * @readonly @@ -10,7 +11,6 @@ export const EmployeeActivationStatus = Object.freeze({ Pending: 2, AutoGenerated: 4, }); - /** * Enum for employee status. * @readonly @@ -19,7 +19,6 @@ export const EmployeeStatus = Object.freeze({ Active: 1, Disabled: 2, }); - /** * Enum for employee type. * @readonly @@ -28,7 +27,6 @@ export const EmployeeType = Object.freeze({ User: 1, Guest: 2, }); - /** * Enum for filter type. * @readonly @@ -47,7 +45,6 @@ export const FilterType = Object.freeze({ ByExtension: 11, MediaOnly: 12, }); - /** * Enum for file type. * @readonly @@ -62,7 +59,6 @@ export const FileType = Object.freeze({ Presentation: 6, Document: 7, }); - /** * Enum for file action. * @readonly @@ -71,7 +67,6 @@ export const FileAction = Object.freeze({ Create: 0, Rename: 1, }); - /** * Enum for root folders type. * @readonly @@ -89,7 +84,6 @@ export const FolderType = Object.freeze({ Templates: 12, Privacy: 13, }); - export const ShareAccessRights = Object.freeze({ None: 0, FullAccess: 1, @@ -101,7 +95,6 @@ export const ShareAccessRights = Object.freeze({ FormFilling: 7, CustomFilter: 8, }); - export const ConflictResolveType = Object.freeze({ Skip: 0, Overwrite: 1, @@ -126,7 +119,6 @@ export const providersData = Object.freeze({ icon: "/static/images/share.linkedin.react.svg", }, }); - export const LoaderStyle = { title: "", width: "100%", @@ -142,7 +134,9 @@ export const LoaderStyle = { }; import config from "./AppServerConfig"; + export const AppServerConfig = config; + /** * Enum for Tenant trusted domains on registration. * @readonly @@ -152,5 +146,4 @@ export const TenantTrustedDomainsType = Object.freeze({ Custom: 1, All: 2, }); - export const PasswordLimitSpecialCharacters = "!@#$%^&*"; diff --git a/packages/asc-web-common/custom.scss b/packages/asc-web-common/custom.scss index 3dc0e9b544..65dfe14b6e 100644 --- a/packages/asc-web-common/custom.scss +++ b/packages/asc-web-common/custom.scss @@ -1,37 +1,32 @@ // Override default variables before the import $font-family-base: "Open Sans", sans-serif; + @import "./opensansoffline.scss"; html, body { height: 100%; } - #root { min-height: 100%; position: relative; - .pageLoader { position: fixed; left: calc(50% - 20px); top: 35%; } } - body { margin: 0; } - body.loading * { cursor: wait !important; } - body.drag-cursor * { cursor: url('data:image/svg+xml;utf8,') 6 6, auto !important; } - body.desktop { user-select: none; -moz-user-select: none; @@ -40,7 +35,6 @@ body.desktop { -o-user-select: none; mozuserselect: none; } - #snackbar { display: flex; justify-content: center; @@ -48,4 +42,4 @@ body.desktop { width: calc(100vw - 60px); padding: 30px; bottom: 15px; -} \ No newline at end of file +} diff --git a/packages/asc-web-common/store/SettingsStore.js b/packages/asc-web-common/store/SettingsStore.js index 8b51a82136..ae97b55929 100644 --- a/packages/asc-web-common/store/SettingsStore.js +++ b/packages/asc-web-common/store/SettingsStore.js @@ -356,4 +356,4 @@ class SettingsStore { }; } -export default SettingsStore; \ No newline at end of file +export default SettingsStore; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 7a9c5ad381..8b0317221a 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -64,4 +64,4 @@ TableGroupMenu.propTypes = { onChange: PropTypes.func, checkboxMargin: PropTypes.string, }; -export default TableGroupMenu; \ No newline at end of file +export default TableGroupMenu; diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index dd39c071c0..60a77a3d76 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -6,7 +6,6 @@ import { FileAction, AppServerConfig } from "@appserver/common/constants"; import toastr from "@appserver/components/toast/toastr"; import config from "../../package.json"; import saveAs from "file-saver"; - export default function withContextOptions(WrappedComponent) { class WithContextOptions extends React.Component { onOpenFolder = () => { @@ -15,21 +14,16 @@ export default function withContextOptions(WrappedComponent) { const locationId = !fileExst ? id : folderId; openLocationAction(locationId, !fileExst); }; - onClickLinkFillForm = () => { return this.gotoDocEditor(false); }; - onClickMakeForm = () => { const { copyAsAction, item, formfillingDocs } = this.props; const { title, id, folderId, fileExst } = item; - const newTitle = title.substring(0, title.length - fileExst.length) + formfillingDocs[0]; - copyAsAction(id, newTitle, folderId).catch((err) => toastr.error(err)); }; - onOpenLocation = () => { const { item, openLocationAction } = this.props; const { parentId, folderId, fileExst } = item; @@ -53,7 +47,6 @@ export default function withContextOptions(WrappedComponent) { const { setCopyPanelVisible } = this.props; setCopyPanelVisible(true); }; - showVersionHistory = () => { const { item, @@ -66,7 +59,6 @@ export default function withContextOptions(WrappedComponent) { } = this.props; const { id } = item; if (isTrashFolder) return; - if (!isTabletView) { fetchFileVersions(id + ""); setIsVerHistoryPanel(true); @@ -76,19 +68,16 @@ export default function withContextOptions(WrappedComponent) { ); } }; - finalizeVersion = () => { const { item, finalizeVersionAction } = this.props; const { id } = item; finalizeVersionAction(id).catch((err) => toastr.error(err)); }; - onClickFavorite = (e) => { const { item, setFavoriteAction, t } = this.props; const { id } = item; const data = (e.currentTarget && e.currentTarget.dataset) || e; const { action } = data; - setFavoriteAction(action, id) .then(() => action === "mark" @@ -97,17 +86,14 @@ export default function withContextOptions(WrappedComponent) { ) .catch((err) => toastr.error(err)); }; - lockFile = () => { const { item, lockFileAction } = this.props; const { id, locked } = item; lockFileAction(id, !locked).catch((err) => toastr.error(err)); }; - onClickLinkForPortal = () => { const { item, homepage, t } = this.props; const { fileExst, canOpenPlayer, webUrl, id } = item; - const isFile = !!fileExst; copy( isFile @@ -116,10 +102,8 @@ export default function withContextOptions(WrappedComponent) { : webUrl : `${window.location.origin + homepage}/filter?folder=${id}` ); - toastr.success(t("Translations:LinkCopySuccess")); }; - onClickLinkEdit = () => { const { item, @@ -127,7 +111,6 @@ export default function withContextOptions(WrappedComponent) { setConvertItem, setConvertDialogVisible, } = this.props; - if (canConvert) { setConvertItem(item); setConvertDialogVisible(true); @@ -135,15 +118,12 @@ export default function withContextOptions(WrappedComponent) { this.gotoDocEditor(false); } }; - onPreviewClick = () => { this.gotoDocEditor(true); }; - gotoDocEditor = (preview = false) => { const { item, openDocEditor, isDesktop } = this.props; const { id, providerKey, fileExst } = item; - const urlFormation = preview ? combineUrl( AppServerConfig.proxyURL, @@ -151,7 +131,6 @@ export default function withContextOptions(WrappedComponent) { `/doceditor?fileId=${encodeURIComponent(id)}&action=view` ) : null; - let tab = !isDesktop && fileExst ? window.open( @@ -163,58 +142,47 @@ export default function withContextOptions(WrappedComponent) { "_blank" ) : null; - openDocEditor(id, providerKey, tab, urlFormation); }; - isPwa = () => { return ["fullscreen", "standalone", "minimal-ui"].some( (displayMode) => window.matchMedia("(display-mode: " + displayMode + ")").matches ); }; - onClickDownload = () => { const { item, downloadAction, t } = this.props; const { fileExst, contentLength, viewUrl } = item; const isFile = !!fileExst && contentLength; - if (this.isPwa()) { const xhr = new XMLHttpRequest(); xhr.open("GET", viewUrl); xhr.responseType = "blob"; - xhr.onload = () => { saveAs(xhr.response, item.title); }; - xhr.onerror = () => { console.error("download failed", viewUrl); }; - xhr.send(); return; } - isFile ? window.open(viewUrl, "_self") : downloadAction(t("Translations:ArchivingData")).catch((err) => toastr.error(err) ); }; - onClickDownloadAs = () => { const { setDownloadDialogVisible } = this.props; setDownloadDialogVisible(true); }; - onDuplicate = () => { const { duplicateAction, t, item } = this.props; duplicateAction(item, t("Translations:CopyOperation")).catch((err) => toastr.error(err) ); }; - onClickRename = () => { const { item, setAction } = this.props; const { id, fileExst } = item; @@ -224,19 +192,16 @@ export default function withContextOptions(WrappedComponent) { id, }); }; - onChangeThirdPartyInfo = () => { const { item, setThirdpartyInfo } = this.props; const { providerKey } = item; setThirdpartyInfo(providerKey); }; - onMediaFileClick = (fileId) => { const { item, setMediaViewerData } = this.props; const itemId = typeof fileId !== "object" ? fileId : item.id; setMediaViewerData({ visible: true, id: itemId }); }; - onClickDelete = () => { const { item, @@ -246,54 +211,43 @@ export default function withContextOptions(WrappedComponent) { deleteItemAction, } = this.props; const { id, title, providerKey, rootFolderId, isFolder } = item; - const isRootThirdPartyFolder = providerKey && id === rootFolderId; - if (isRootThirdPartyFolder) { const splitItem = id.split("-"); setRemoveItem({ id: splitItem[splitItem.length - 1], title }); setDeleteThirdPartyDialogVisible(true); return; } - const translations = { deleteOperation: t("Translations:DeleteOperation"), successRemoveFile: t("FileRemoved"), successRemoveFolder: t("FolderRemoved"), }; - deleteItemAction(id, translations, !isFolder, providerKey); }; - onClickShare = () => { const { setSharingPanelVisible } = this.props; setTimeout(() => { setSharingPanelVisible(true); }, 10); //TODO: remove delay after fix context menu callback }; - onClickMarkRead = () => { const { markAsRead, item } = this.props; item.fileExst ? markAsRead([], [item.id], item) : markAsRead([item.id], [], item); }; - onClickUnsubscribe = () => { const { setDeleteDialogVisible, setUnsubscribe } = this.props; - setUnsubscribe(true); setDeleteDialogVisible(true); }; - getFilesContextOptions = () => { const { item, t } = this.props; const { contextOptions } = item; const isRootThirdPartyFolder = item.providerKey && item.id === item.rootFolderId; - const isShareable = item.canShare; - return contextOptions.map((option) => { switch (option) { case "open": @@ -533,25 +487,20 @@ export default function withContextOptions(WrappedComponent) { default: break; } - return undefined; }); }; - render() { const { actionType, actionId, actionExtension, item } = this.props; const { id, fileExst, contextOptions } = item; - const isEdit = !!actionType && actionId === id && fileExst === actionExtension; - const contextOptionsProps = !isEdit && contextOptions && contextOptions.length > 0 ? { contextOptions: this.getFilesContextOptions(), } : {}; - return ( div:first-child { padding: 8px 8px 8px 8px; margin-right: -8px; diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 5939482e4d..738aec6bc0 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -1,16 +1,33 @@ +import React from "react"; +//import PropTypes from "prop-types"; +import { withRouter } from "react-router"; +import { isMobile } from "react-device-detect"; +import axios from "axios"; +import toastr from "@appserver/components/toast/toastr"; +import PageLayout from "@appserver/common/components/PageLayout"; +import { showLoader, hideLoader } from "@appserver/common/utils"; import FilesFilter from "@appserver/common/api/files/filter"; import { getGroup } from "@appserver/common/api/groups"; import { getUserById } from "@appserver/common/api/people"; -import PageLayout from "@appserver/common/components/PageLayout"; -import { hideLoader, showLoader } from "@appserver/common/utils"; -import toastr from "@appserver/components/toast/toastr"; -import axios from "axios"; -import { inject, observer } from "mobx-react"; -import React from "react"; -import { isMobile } from "react-device-detect"; -import { Trans, withTranslation } from "react-i18next"; -//import PropTypes from "prop-types"; -import { withRouter } from "react-router"; +import { withTranslation, Trans } from "react-i18next"; +import { + ArticleBodyContent, + ArticleHeaderContent, + ArticleMainButtonContent, +} from "../../components/Article"; +import { + SectionBodyContent, + SectionFilterContent, + SectionHeaderContent, + SectionPagingContent, +} from "./Section"; +import { InfoPanelBodyContent, InfoPanelHeaderContent } from "./InfoPanel"; + +import { createTreeFolders } from "../../helpers/files-helpers"; +import MediaViewer from "./MediaViewer"; +import DragTooltip from "../../components/DragTooltip"; +import { observer, inject } from "mobx-react"; +import config from "../../../package.json"; import config from "../../../package.json"; import { From a11a40e61b64b0f4eb1fa3ba00168a471eb3e362 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 14:38:28 +0300 Subject: [PATCH 23/81] fix import mixins --- packages/asc-web-common/custom.scss | 19 +++++++++++++++ .../Client/src/HOCs/withFileActions.js | 1 + .../src/pages/Home/Section/Body/index.js | 13 +++++++---- .../src/components/pages/Home/index.js | 23 +++++++++---------- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/packages/asc-web-common/custom.scss b/packages/asc-web-common/custom.scss index 65dfe14b6e..83fc18eafe 100644 --- a/packages/asc-web-common/custom.scss +++ b/packages/asc-web-common/custom.scss @@ -16,6 +16,25 @@ body { top: 35%; } } + +.table-container_settings-checkbox { + padding: 8px 16px; +} + +.hide-filter-drop-down { + padding: 16px !important; + margin-top: 2px; +} + +.styled-close-button { + margin-left: 7px; + margin-top: -1px; +} + +.styled-combobox { + margin-top: -2px; +} + body { margin: 0; } diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index efff5d6953..c5a5f21064 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -317,6 +317,7 @@ export default function withFileActions(WrappedFileItem) { formatsStore, mediaViewerDataStore, infoPanelStore, + settingsStore, }, { item, t, history } ) => { 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 715cd5e13d..8d39f0d417 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 @@ -63,11 +63,14 @@ const SectionBodyContent = (props) => { const onMouseDown = (e) => { if ( - e.target.closest(".scroll-body") && - !e.target.closest(".files-item") && - !e.target.closest(".not-selectable") && - !e.target.closest(".table-container_group-menu") && - !e.target.closest(".info-panel") + (e.target.closest(".scroll-body") && + !e.target.closest(".files-item") && + !e.target.closest(".not-selectable") && + !e.target.closest(".info-panel") && + !e.target.closest(".table-container_group-menu")) || + e.target.closest(".files-main-button") || + e.target.closest(".add-button") || + e.target.closest(".search-input-block") ) { setSelection([]); setBufferSelection(null); diff --git a/web/ASC.Web.Client/src/components/pages/Home/index.js b/web/ASC.Web.Client/src/components/pages/Home/index.js index 5e726177c1..c6167bc523 100644 --- a/web/ASC.Web.Client/src/components/pages/Home/index.js +++ b/web/ASC.Web.Client/src/components/pages/Home/index.js @@ -1,18 +1,17 @@ +import React, { useEffect } from "react"; +import PropTypes from "prop-types"; +import { withRouter } from "react-router"; +import { useTranslation } from "react-i18next"; +import styled from "styled-components"; +import Text from "@appserver/components/text"; +import toastr from "studio/toastr"; import PageLayout from "@appserver/common/components/PageLayout"; import history from "@appserver/common/history"; -import { tryRedirectTo } from "@appserver/common/utils"; -import Text from "@appserver/components/text"; -import { inject, observer } from "mobx-react"; -import PropTypes from "prop-types"; -import React, { useEffect } from "react"; -import { useTranslation } from "react-i18next"; -import { withRouter } from "react-router"; -import toastr from "studio/toastr"; -import styled from "styled-components"; - -import config from "../../../../package.json"; -import { setDocumentTitle } from "../../../helpers/utils"; import ModuleTile from "./ModuleTile"; +import { tryRedirectTo } from "@appserver/common/utils"; +import { setDocumentTitle } from "../../../helpers/utils"; +import { inject, observer } from "mobx-react"; +import config from "../../../../package.json"; const HomeContainer = styled.div` padding: 62px 15px 0 15px; From 55d9a76f4dedcc65f13c7348393f1101da9d39bc Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 15:45:16 +0300 Subject: [PATCH 24/81] fix Home config import duplication --- products/ASC.Files/Client/src/pages/Home/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index 738aec6bc0..b0f8d87404 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -29,7 +29,6 @@ import DragTooltip from "../../components/DragTooltip"; import { observer, inject } from "mobx-react"; import config from "../../../package.json"; -import config from "../../../package.json"; import { ArticleBodyContent, ArticleHeaderContent, From a0aa53d57a53388b99d013eaa22ed451865ba6e1 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 16:17:55 +0300 Subject: [PATCH 25/81] fix Home config import duplication 2 --- .../ASC.Files/Client/src/pages/Home/index.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/index.js b/products/ASC.Files/Client/src/pages/Home/index.js index b0f8d87404..5c3fdedd2d 100644 --- a/products/ASC.Files/Client/src/pages/Home/index.js +++ b/products/ASC.Files/Client/src/pages/Home/index.js @@ -29,23 +29,6 @@ import DragTooltip from "../../components/DragTooltip"; import { observer, inject } from "mobx-react"; import config from "../../../package.json"; -import { - ArticleBodyContent, - ArticleHeaderContent, - ArticleMainButtonContent, -} from "../../components/Article"; -import DragTooltip from "../../components/DragTooltip"; -import { createTreeFolders } from "../../helpers/files-helpers"; -import { InfoPanelBodyContent } from "./InfoPanel"; -import { InfoPanelHeaderContent } from "./InfoPanel"; -import MediaViewer from "./MediaViewer"; -import { - SectionBodyContent, - SectionFilterContent, - SectionHeaderContent, - SectionPagingContent, -} from "./Section"; - class PureHome extends React.Component { componentDidMount() { const { From bb69417dbf9faeed9397514382a0f76904eacd1e Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 3 Mar 2022 16:22:27 +0300 Subject: [PATCH 26/81] fix kafka code formatting and ContextMenu - InfoPanel layering interaction --- config/kafka.json | 5 +- .../PageLayout/sub-components/info-panel.js | 194 +++++++++--------- 2 files changed, 100 insertions(+), 99 deletions(-) diff --git a/config/kafka.json b/config/kafka.json index 8f173fe541..a2e3ca6b4e 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,3 +1,4 @@ { - "kafka": {} -} + "kafka": { + } +} \ No newline at end of file diff --git a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js index bced974bdf..2203b14b6a 100644 --- a/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js +++ b/packages/asc-web-common/components/PageLayout/sub-components/info-panel.js @@ -7,128 +7,128 @@ import React, { useEffect } from "react"; import styled from "styled-components"; const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ - title: title, + title: title, }))` - height: auto; - width: auto; - background: rgba(6, 22, 38, 0.2); - backdrop-filter: blur(18px); + height: auto; + width: auto; + background: rgba(6, 22, 38, 0.2); + backdrop-filter: blur(18px); - @media ${tablet} { - z-index: 200; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - } + @media ${tablet} { + z-index: 1002; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } `; const StyledInfoPanel = styled.div` - height: 100%; - width: 368px; - background-color: #ffffff; - border-left: 1px solid #eceef1; - display: flex; - flex-direction: column; + height: 100%; + width: 368px; + background-color: #ffffff; + border-left: 1px solid #eceef1; + display: flex; + flex-direction: column; - @media ${tablet} { - position: absolute; - border: none; - right: 0; - width: 448px; - max-width: calc(100vw - 69px); - } + @media ${tablet} { + position: absolute; + border: none; + right: 0; + width: 448px; + max-width: calc(100vw - 69px); + } - @media ${mobile} { - bottom: 0; - height: 80%; - width: 100vw; - max-width: 100vw; - } + @media ${mobile} { + bottom: 0; + height: 80%; + width: 100vw; + max-width: 100vw; + } `; const StyledCloseButtonWrapper = styled.div` - position: absolute; - display: none; - @media ${tablet} { - display: block; - top: 0; - left: 0; - margin-top: 18px; - margin-left: -27px; - } - @media ${mobile} { - right: 0; - left: auto; - margin-top: -27px; - margin-right: 10px; - } + position: absolute; + display: none; + @media ${tablet} { + display: block; + top: 0; + left: 0; + margin-top: 18px; + margin-left: -27px; + } + @media ${mobile} { + right: 0; + left: auto; + margin-top: -27px; + margin-right: 10px; + } `; const InfoPanel = ({ children, selectedItems, isVisible, setIsVisible }) => { - //if (selectedItems.length > 0) setIsVisible(true); - //else setIsVisible(false); + //if (selectedItems.length > 0) setIsVisible(true); + //else setIsVisible(false); - if (!isVisible) return null; + if (!isVisible) return null; - const closeInfoPanel = () => setIsVisible(false); + const closeInfoPanel = () => setIsVisible(false); - useEffect(() => { - const onMouseDown = (e) => { - if (e.target.title === "InfoPanelWrapper") closeInfoPanel(); - }; + useEffect(() => { + const onMouseDown = (e) => { + if (e.target.title === "InfoPanelWrapper") closeInfoPanel(); + }; - if (isTablet()) document.addEventListener("mousedown", onMouseDown); - return () => document.removeEventListener("mousedown", onMouseDown); - }, []); + if (isTablet()) document.addEventListener("mousedown", onMouseDown); + return () => document.removeEventListener("mousedown", onMouseDown); + }, []); - return ( - - - - - - {children} - - - ); + return ( + + + + + + {children} + + + ); }; InfoPanel.propTypes = { - children: PropTypes.oneOfType([ - PropTypes.arrayOf(PropTypes.node), - PropTypes.node, - PropTypes.any, - ]), - isVisible: PropTypes.bool, + children: PropTypes.oneOfType([ + PropTypes.arrayOf(PropTypes.node), + PropTypes.node, + PropTypes.any, + ]), + isVisible: PropTypes.bool, }; export default inject(({ infoPanelStore, filesStore }) => { - let selectedItems = []; - let isVisible = false; - let setIsVisible = () => {}; + let selectedItems = []; + let isVisible = false; + let setIsVisible = () => {}; - if (infoPanelStore) { - isVisible = infoPanelStore.isVisible; - setIsVisible = infoPanelStore.setIsVisible; - } + if (infoPanelStore) { + isVisible = infoPanelStore.isVisible; + setIsVisible = infoPanelStore.setIsVisible; + } - if (filesStore) { - selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); - } + if (filesStore) { + selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); + } - return { - selectedItems, - isVisible, - setIsVisible, - }; + return { + selectedItems, + isVisible, + setIsVisible, + }; })(InfoPanel); From 0ac0f8f50876a357464f413dcddf9e0bfa7e13a5 Mon Sep 17 00:00:00 2001 From: mushka Date: Sat, 5 Mar 2022 13:11:14 +0300 Subject: [PATCH 27/81] fixed opening on context menu click --- .../Client/src/HOCs/withContextOptions.js | 20 ++++------ .../Client/src/HOCs/withFileActions.js | 21 +++++----- .../src/pages/Home/InfoPanel/Body/index.js | 7 ++-- .../ASC.Files/Client/src/store/FilesStore.js | 1 - products/ASC.Files/Client/src/store/index.js | 38 +++++++------------ 5 files changed, 36 insertions(+), 51 deletions(-) diff --git a/products/ASC.Files/Client/src/HOCs/withContextOptions.js b/products/ASC.Files/Client/src/HOCs/withContextOptions.js index 0ec892232f..31bdd4be33 100644 --- a/products/ASC.Files/Client/src/HOCs/withContextOptions.js +++ b/products/ASC.Files/Client/src/HOCs/withContextOptions.js @@ -54,11 +54,9 @@ export default function withContextOptions(WrappedComponent) { const locationId = !fileExst ? parentId : folderId; openLocationAction(locationId, !fileExst); }; - onSetInfoPanelVisible = () => { this.props.setIsVisible(true); }; - onOwnerChange = () => { const { setChangeOwnerPanelVisible } = this.props; setChangeOwnerPanelVisible(true); @@ -397,16 +395,13 @@ export default function withContextOptions(WrappedComponent) { onClick: this.onOpenFolder, disabled: false, }, - - // case "show-info": - // return { - // key: option, - // label: t("InfoPanel:Info"), - // icon: "images/info.react.svg", - // onClick: this.onSetInfoPanelVisible, - // disabled: false, - // }; - + { + key: "show-info", + label: t("InfoPanel:Info"), + icon: "images/info.react.svg", + onClick: this.onSetInfoPanelVisible, + disabled: false, + }, { key: "fill-form", label: t("Common:FillFormButton"), @@ -647,7 +642,6 @@ export default function withContextOptions(WrappedComponent) { const { setAction, type, extension, id } = fileActionStore; const { setMediaViewerData } = mediaViewerDataStore; const { copyAsAction } = uploadDataStore; - const { formfillingDocs } = formatsStore.docserviceStore; const { extsWebRestrictedEditing } = settingsStore; const { isRecycleBinFolder, isShare } = treeFoldersStore; diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index a418e4d2b9..6383272747 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -6,6 +6,7 @@ import { AppServerConfig, FileStatus } from "@appserver/common/constants"; import { combineUrl } from "@appserver/common/utils"; import config from "../../package.json"; import { isMobile } from "react-device-detect"; +import { isDesktop } from "@appserver/components/utils/device"; export default function withFileActions(WrappedFileItem) { class WithFileActions extends React.Component { @@ -17,13 +18,12 @@ export default function withFileActions(WrappedFileItem) { const { selectRowAction, infoPanelIsVisible, showInfoPanel } = this.props; if (!file || file.id === -1) return; selectRowAction(checked, file); - if (!infoPanelIsVisible) showInfoPanel(); + + if (!infoPanelIsVisible && isDesktop()) showInfoPanel(); }; fileContextClick = () => { - if (!this.props.infoPanelIsVisible) this.props.showInfoPanel(); - - const { onSelectItem, item } = this.props; + const { onSelectItem, item, infoPanelIsVisible, showInfoPanel } = this.props; const { id, isFolder } = item; id !== -1 && onSelectItem({ id, isFolder }); @@ -108,17 +108,18 @@ export default function withFileActions(WrappedFileItem) { showInfoPanel, } = this.props; - if ( - e.target.closest(".checkbox") || + if( e.target.tagName === "INPUT" || e.target.tagName === "SPAN" || e.target.tagName === "A" || - e.target.closest(".expandButton") || - e.target.closest(".badges") || + e.target.closest(".checkbox") || e.button !== 0 || + e.target.closest('.expandButton') || + e.target.querySelector('.expandButton') || + e.target.closest(".badges") || e.target.closest(".not-selectable") ) - return; + return if (viewAs === "tile") { if (e.target.closest(".edit-button") || e.target.tagName === "IMG") @@ -129,7 +130,7 @@ export default function withFileActions(WrappedFileItem) { this.fileContextClick(); } - if (!infoPanelIsVisible) showInfoPanel(); + if (!infoPanelIsVisible && isDesktop()) showInfoPanel(); }; onFilesClick = (e) => { const { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index b4b14c73d2..3a436518c8 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -49,7 +49,7 @@ const InfoPanelBodyContent = ({ export default inject( ({ filesStore, - formatsStore, + settingsStore, filesActionsStore, dialogsStore, treeFoldersStore, @@ -58,9 +58,10 @@ export default inject( const bufferSelectedItem = JSON.parse( JSON.stringify(filesStore.bufferSelection) ); - const { getFolderInfo, getShareUsers } = filesStore; - const { getIcon, getFolderIcon } = formatsStore.iconFormatsStore; + //console.log(settin); + const { getFolderInfo, getShareUsers } = filesStore; + const { getIcon, getFolderIcon } = settingsStore; const { onSelectItem } = filesActionsStore; const { setSharingPanelVisible } = dialogsStore; const { isRecycleBinFolder } = treeFoldersStore; diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 9f3ffc53bb..ade7326cac 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -11,7 +11,6 @@ import { import history from "@appserver/common/history"; import { combineUrl } from "@appserver/common/utils"; import { updateTempContent } from "@appserver/common/utils"; -import { makeAutoObservable } from "mobx"; import { isMobile } from "react-device-detect"; import toastr from "studio/toastr"; diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index 1064805344..a7b75c5d4e 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -1,31 +1,25 @@ -import store from "studio/store"; - -import DialogsStore from "./DialogsStore"; -import docserviceStore from "./DocserviceStore"; -import fileActionStore from "./FileActionStore"; -import FilesActionsStore from "./FilesActionsStore"; import FilesStore from "./FilesStore"; -import FormatsStore from "./FormatsStore"; -import iconFormatsStore from "./IconFormatsStore"; -import InfoPanelStore from "./InfoPanelStore"; -import MediaViewerDataStore from "./MediaViewerDataStore"; -import mediaViewersFormatsStore from "./MediaViewersFormatsStore"; -import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; -import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; -import selectedFilesStore from "./SelectedFilesStore"; -import selectedFolderStore from "./SelectedFolderStore"; -import SettingsStore from "./SettingsStore"; -import thirdPartyStore from "./ThirdPartyStore"; +import fileActionStore from "./FileActionStore"; +import SelectedFolderStore from "./SelectedFolderStore"; import TreeFoldersStore from "./TreeFoldersStore"; +import thirdPartyStore from "./ThirdPartyStore"; +import SettingsStore from "./SettingsStore"; +import FilesActionsStore from "./FilesActionsStore"; +import MediaViewerDataStore from "./MediaViewerDataStore"; import UploadDataStore from "./UploadDataStore"; +import SecondaryProgressDataStore from "./SecondaryProgressDataStore"; +import PrimaryProgressDataStore from "./PrimaryProgressDataStore"; + import VersionHistoryStore from "./VersionHistoryStore"; +import DialogsStore from "./DialogsStore"; +import selectedFilesStore from "./SelectedFilesStore"; +import store from "studio/store"; +import InfoPanelStore from "./InfoPanelStore"; const selectedFolderStore = new SelectedFolderStore(store.auth.settingsStore); const treeFoldersStore = new TreeFoldersStore(selectedFolderStore); - const settingsStore = new SettingsStore(thirdPartyStore, treeFoldersStore); - const filesStore = new FilesStore( store.auth, store.auth.settingsStore, @@ -33,7 +27,6 @@ const filesStore = new FilesStore( fileActionStore, selectedFolderStore, treeFoldersStore, - formatsStore, settingsStore, selectedFilesStore ); @@ -41,10 +34,8 @@ const mediaViewerDataStore = new MediaViewerDataStore( filesStore, settingsStore ); - const secondaryProgressDataStore = new SecondaryProgressDataStore(); const primaryProgressDataStore = new PrimaryProgressDataStore(); - const dialogsStore = new DialogsStore( store.auth, treeFoldersStore, @@ -76,7 +67,6 @@ const filesActionsStore = new FilesActionsStore( ); const versionHistoryStore = new VersionHistoryStore(filesStore); - //const selectedFilesStore = new SelectedFilesStore(selectedFilesStore); const stores = { filesStore, @@ -92,4 +82,4 @@ const stores = { infoPanelStore, }; -export default stores; +export default stores; \ No newline at end of file From 7f7acd14efcd6bdec6bde432344bfa763df9c5c5 Mon Sep 17 00:00:00 2001 From: mushka Date: Sat, 5 Mar 2022 13:32:27 +0300 Subject: [PATCH 28/81] header button to toast --- .../src/pages/Home/Section/Header/index.js | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index f600e07c9d..e580593c32 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -186,17 +186,9 @@ const StyledInfoPanelToggleWrapper = styled.div` align-items: center; justify-content: center; border-radius: 50%; - background-color: ${(props) => - props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; + /* background-color: ${(props) => + props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; */ } - - ${(props) => - props.isHeaderVisible && - css` - margin-bottom: 2px; - margin-right: 24px; - padding-left: 12px; - `} `; class SectionHeaderContent extends React.Component { @@ -462,24 +454,6 @@ class SectionHeaderContent extends React.Component { const isLoading = !title || !tReady; const headerMenu = getHeaderMenu(t); - const infoPanelToggle = ( - -
- -
-
- ); - return ( {(context) => ( @@ -502,7 +476,6 @@ class SectionHeaderContent extends React.Component { isChecked={isHeaderChecked} isIndeterminate={isHeaderIndeterminate} headerMenu={headerMenu} - infoPanelToggle={infoPanelToggle} /> ) : (
@@ -583,7 +556,22 @@ class SectionHeaderContent extends React.Component { /> )} - {infoPanelToggle} + +
+ toastr.info("Feature in development", Room info panel, true)} + //onClick={this.onToggleInfoPanel} + /> +
+
)}
From 2d452e18dae261232002b69ed3669463ce81e0ff Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 17 Mar 2022 17:16:21 +0300 Subject: [PATCH 29/81] fixed after-merge room-info button deletion and configured new showCurrentFolderInfo feature --- .../components/Navigation/Navigation.js | 6 + .../components/Navigation/StyledNavigation.js | 4 +- .../Navigation/sub-components/control-btn.js | 91 +++++++---- .../Client/src/HOCs/withFileActions.js | 37 +++-- .../src/pages/Home/InfoPanel/Body/index.js | 148 ++++++++++-------- .../src/pages/Home/Section/Header/index.js | 44 +++--- .../Client/src/store/InfoPanelStore.js | 41 +++-- 7 files changed, 226 insertions(+), 145 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/Navigation.js b/packages/asc-web-common/components/Navigation/Navigation.js index d93df7d5ff..021dc2c5a3 100644 --- a/packages/asc-web-common/components/Navigation/Navigation.js +++ b/packages/asc-web-common/components/Navigation/Navigation.js @@ -30,6 +30,9 @@ const Navigation = ({ isRecycleBinFolder, isEmptyFilesList, clearTrash, + showFolderInfo, + isCurrentFolderInfo, + isInfoPanelVisible, ...rest }) => { const [isOpen, setIsOpen] = React.useState(false); @@ -134,6 +137,9 @@ const Navigation = ({ isRecycleBinFolder={isRecycleBinFolder} isEmptyFilesList={isEmptyFilesList} clearTrash={clearTrash} + showFolderInfo={showFolderInfo} + isCurrentFolderInfo={isCurrentFolderInfo} + isInfoPanelVisible={isInfoPanelVisible} /> diff --git a/packages/asc-web-common/components/Navigation/StyledNavigation.js b/packages/asc-web-common/components/Navigation/StyledNavigation.js index b427e29879..a357b984b6 100644 --- a/packages/asc-web-common/components/Navigation/StyledNavigation.js +++ b/packages/asc-web-common/components/Navigation/StyledNavigation.js @@ -5,12 +5,12 @@ import { tablet, desktop, mobile } from "@appserver/components/utils/device"; const StyledContainer = styled.div` padding: ${(props) => (props.isDropBox ? "14px 0 3px" : "14px 0 0px")}; - width: fit-content; + width: 100%; display: grid; grid-template-columns: ${(props) => - props.isRootFolder ? "1fr auto" : "29px 1fr auto"}; + props.isRootFolder ? "auto 1fr" : "29px auto 1fr"}; align-items: center; diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index e7b5e1a463..2550ae5946 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -30,7 +30,8 @@ const StyledContainer = styled.div` } .option-button { - margin-right: 8px; + margin-left: auto; + margin-right: 15px; min-width: 17px; } @@ -39,6 +40,27 @@ const StyledContainer = styled.div` } `; +const StyledInfoPanelToggleWrapper = styled.div` + display: flex; + align-items: center; + align-self: center; + justify-content: center; + margin-left: ${({ isRootFolder }) => (isRootFolder ? "auto" : "none")}; + + .info-panel-toggle-bg { + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: ${(props) => + props.isInfoPanelVisible && props.isCurrentFolderInfo + ? "#F8F9F9" + : "transparent"}; + } +`; + const ControlButtons = ({ personal, isDropBox, @@ -49,43 +71,25 @@ const ControlButtons = ({ isRecycleBinFolder, isEmptyFilesList, clearTrash, + showFolderInfo, + isCurrentFolderInfo, + isInfoPanelVisible, }) => { return ( - {!isRootFolder && canCreate ? ( - <> - - {!personal && ( - - )} - - ) : canCreate ? ( + {canCreate && ( - ) : isRecycleBinFolder && !isEmptyFilesList ? ( + )} + + {isRecycleBinFolder && !isEmptyFilesList && ( - ) : ( - <> )} + + {!isRootFolder && !personal && ( + + )} + + +
+ +
+
); }; diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 218cf570a5..3500d39356 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -10,15 +10,28 @@ export default function withFileActions(WrappedFileItem) { } onContentFileSelect = (checked, file) => { - const { selectRowAction, infoPanelIsVisible, showInfoPanel } = this.props; + const { + selectRowAction, + infoPanelIsVisible, + showInfoPanel, + setShowCurrentFolder, + } = this.props; if (!file || file.id === -1) return; selectRowAction(checked, file); - if (!infoPanelIsVisible && isDesktop()) showInfoPanel(); + if (!infoPanelIsVisible && isDesktop()) { + setShowCurrentFolder(false); + showInfoPanel(); + } }; fileContextClick = () => { - const { onSelectItem, item, infoPanelIsVisible, showInfoPanel } = this.props; + const { + onSelectItem, + item, + infoPanelIsVisible, + showInfoPanel, + } = this.props; const { id, isFolder } = item; id !== -1 && onSelectItem({ id, isFolder }); @@ -98,20 +111,21 @@ export default function withFileActions(WrappedFileItem) { isItemsSelected, infoPanelIsVisible, showInfoPanel, + setShowCurrentFolder, } = this.props; - if( + if ( e.target.tagName === "INPUT" || e.target.tagName === "SPAN" || e.target.tagName === "A" || e.target.closest(".checkbox") || e.button !== 0 || - e.target.closest('.expandButton') || - e.target.querySelector('.expandButton') || + e.target.closest(".expandButton") || + e.target.querySelector(".expandButton") || e.target.closest(".badges") || e.target.closest(".not-selectable") ) - return + return; if (viewAs === "tile") { if (e.target.closest(".edit-button") || e.target.tagName === "IMG") @@ -122,8 +136,12 @@ export default function withFileActions(WrappedFileItem) { this.fileContextClick(); } - if (!infoPanelIsVisible && isDesktop()) showInfoPanel(); + if (!infoPanelIsVisible && isDesktop()) { + setShowCurrentFolder(false); + showInfoPanel(); + } }; + onFilesClick = (e) => { const { item, openFileAction } = this.props; if ( @@ -263,7 +281,7 @@ export default function withFileActions(WrappedFileItem) { const { startUpload } = uploadDataStore; const { type, extension, id } = fileActionStore; - const { isVisible, setVisible } = infoPanelStore; + const { isVisible, setVisible, setShowCurrentFolder } = infoPanelStore; const selectedItem = selection.find( (x) => x.id === item.id && x.fileExst === item.fileExst @@ -332,6 +350,7 @@ export default function withFileActions(WrappedFileItem) { openFileAction, isInfoPanelVisible: isVisible, showInfoPanel: setVisible, + setShowCurrentFolder, }; } )(observer(WithFileActions)); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 3a436518c8..f25b847696 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -8,74 +8,96 @@ import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; const InfoPanelBodyContent = ({ - t, - selectedItems, - bufferSelectedItem, - getFolderInfo, - getIcon, - getFolderIcon, - getShareUsers, - onSelectItem, - setSharingPanelVisible, - isRecycleBinFolder, + t, + selectedItems, + bufferSelectedItem, + getFolderInfo, + getIcon, + getFolderIcon, + getShareUsers, + onSelectItem, + setSharingPanelVisible, + isRecycleBinFolder, + showCurrentFolder, }) => { - if (selectedItems.length) { - } + if (selectedItems.length) { + } - return ( - - {selectedItems.length === 0 && !bufferSelectedItem ? ( -
-

{t("NoItemsSelected")}

-
- ) : selectedItems.length === 1 || bufferSelectedItem ? ( - - ) : ( - - )} -
- ); + return ( + + <>{console.log(showCurrentFolder)} + + {showCurrentFolder ? ( +
Room Info
+ ) : ( + // + <> + {selectedItems.length === 0 && !bufferSelectedItem ? ( +
+

{t("NoItemsSelected")}

+
+ ) : selectedItems.length === 1 || bufferSelectedItem ? ( + + ) : ( + + )} + + )} +
+ ); }; export default inject( - ({ - filesStore, - settingsStore, - filesActionsStore, - dialogsStore, - treeFoldersStore, - }) => { - const selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); - const bufferSelectedItem = JSON.parse( - JSON.stringify(filesStore.bufferSelection) - ); + ({ + infoPanelStore, + filesStore, + settingsStore, + filesActionsStore, + dialogsStore, + treeFoldersStore, + }) => { + const selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); + const bufferSelectedItem = JSON.parse( + JSON.stringify(filesStore.bufferSelection) + ); - //console.log(settin); - const { getFolderInfo, getShareUsers } = filesStore; - const { getIcon, getFolderIcon } = settingsStore; - const { onSelectItem } = filesActionsStore; - const { setSharingPanelVisible } = dialogsStore; - const { isRecycleBinFolder } = treeFoldersStore; + //console.log(settin); + const { showCurrentFolder } = infoPanelStore; + const { getFolderInfo, getShareUsers } = filesStore; + const { getIcon, getFolderIcon } = settingsStore; + const { onSelectItem } = filesActionsStore; + const { setSharingPanelVisible } = dialogsStore; + const { isRecycleBinFolder } = treeFoldersStore; - return { - bufferSelectedItem, - selectedItems, - getFolderInfo, - getShareUsers, - getIcon, - getFolderIcon, - onSelectItem, - setSharingPanelVisible, - isRecycleBinFolder, - }; - } + return { + bufferSelectedItem, + selectedItems, + getFolderInfo, + getShareUsers, + getIcon, + getFolderIcon, + onSelectItem, + setSharingPanelVisible, + isRecycleBinFolder, + showCurrentFolder, + }; + } )(withRouter(withTranslation(["InfoPanel"])(observer(InfoPanelBodyContent)))); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 6e954f321a..e930c8f003 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -57,25 +57,6 @@ const StyledContainer = styled.div` } `; -const StyledInfoPanelToggleWrapper = styled.div` - display: flex; - margin-left: auto; - align-items: center; - align-self: center; - justify-content: center; - - .info-panel-toggle-bg { - height: 32px; - width: 32px; - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; - /* background-color: ${(props) => - props.isInfoPanelVisible ? "#F8F9F9" : "#FFFFFF"}; */ - } -`; - class SectionHeaderContent extends React.Component { constructor(props) { super(props); @@ -221,7 +202,11 @@ class SectionHeaderContent extends React.Component { }; onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); - onToggleInfoPanel = () => this.props.toggleInfoPanel(); + showFolderInfo = () => { + this.props.setShowCurrentFolder(true); + console.log(this.props.showCurrentFolder); + this.props.setIsInfoPanelVisible(true); + }; getContextOptionsFolder = () => { const { t, personal } = this.props; @@ -394,6 +379,9 @@ class SectionHeaderContent extends React.Component { isEmptyFilesList={isEmptyFilesList} clearTrash={this.onEmptyTrashAction} onBackToParentFolder={this.onBackToParentFolder} + showFolderInfo={this.showFolderInfo} + isCurrentFolderInfo={this.props.showCurrentFolder} + isInfoPanelVisible={this.props.isInfoPanelVisible} /> )}
@@ -451,13 +439,15 @@ export default inject( backToParentFolder, } = filesActionsStore; - //const { toggleInfoPanel, isInfoPanelVisible } = infoPanelStore; - const toggleInfoPanel = infoPanelStore.toggleIsVisible; - const isInfoPanelVisible = infoPanelStore.isVisible; + const { + showCurrentFolder, + setShowCurrentFolder, + setIsVisible, + isVisible, + } = infoPanelStore; return { showText: auth.settingsStore.showText, - isDesktop: auth.settingsStore.isDesktopClient, isRootFolder: selectedFolderStore.parentId === 0, title: selectedFolderStore.title, @@ -465,8 +455,10 @@ export default inject( pathParts: selectedFolderStore.pathParts, navigationPath: selectedFolderStore.navigationPath, canCreate, - toggleInfoPanel, - isInfoPanelVisible, + setIsInfoPanelVisible: setIsVisible, + isInfoPanelVisible: isVisible, + showCurrentFolder, + setShowCurrentFolder, isHeaderVisible, isHeaderIndeterminate, isHeaderChecked, diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index 80f2ce7669..5b6c46764f 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -1,27 +1,36 @@ import { makeAutoObservable } from "mobx"; class InfoPanelStore { - isVisible = false; + isVisible = false; + showCurrentFolder = false; - constructor() { - makeAutoObservable(this); - } + constructor() { + makeAutoObservable(this); + } - toggleIsVisible = () => { - this.isVisible = !this.isVisible; - }; + setShowCurrentFolder = (bool) => { + this.showCurrentFolder = bool; + }; - setVisible = () => { - this.isVisible = true; - }; + get showCurrenFolder() { + return this.showCurrenFolder; + } - setIsVisible = (bool) => { - this.isVisible = bool; - }; + toggleIsVisible = () => { + this.isVisible = !this.isVisible; + }; - get isVisible() { - return this.isVisible; - } + setVisible = () => { + this.isVisible = true; + }; + + setIsVisible = (bool) => { + this.isVisible = bool; + }; + + get isVisible() { + return this.isVisible; + } } export default InfoPanelStore; From a80ada2c37cd90110ba948256a21f7f783b32131 Mon Sep 17 00:00:00 2001 From: mushka Date: Sun, 20 Mar 2022 22:29:42 +0300 Subject: [PATCH 30/81] added current folder info visualization on room-info button click --- .../Home/InfoPanel/Body/CurrentFolder.js | 93 +++ .../Home/InfoPanel/Body/CurrentFolderItem.js | 405 ++++++++++ .../pages/Home/InfoPanel/Body/SingleItem.js | 759 +++++++++--------- .../src/pages/Home/InfoPanel/Body/index.js | 78 +- .../src/pages/Home/Section/Header/index.js | 7 +- 5 files changed, 935 insertions(+), 407 deletions(-) create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolder.js create mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolderItem.js diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolder.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolder.js new file mode 100644 index 0000000000..2754eb993d --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolder.js @@ -0,0 +1,93 @@ +import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; +import { FileType } from "@appserver/common/constants"; +import Link from "@appserver/components/link"; +import Text from "@appserver/components/text"; +import Tooltip from "@appserver/components/tooltip"; +import { inject, observer } from "mobx-react"; +import React, { useEffect, useState } from "react"; +import { withTranslation } from "react-i18next"; +import { ReactSVG } from "react-svg"; +import { combineUrl } from "@appserver/common/utils"; +//import config from "@appserever/files/package.json"; + +import { AppServerConfig } from "@appserver/common/constants"; + +import { + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, + StyledProperties, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./styles/styles.js"; + +const SingleItem = (props) => { + const { + t, + currentFolderItem, + isRecycleBinFolder, + onSelectItem, + setSharingPanelVisible, + getFolderInfo, + getIcon, + getFolderIcon, + getShareUsers, + } = props; + + const [item, setItem] = useState({ + id: currentFolderItem.id, + isFolder: true, + title: currentFolderItem.title, + iconUrl: currentFolderItem.iconUrl, + thumbnailUrl: currentFolderItem.thumbnailUrl, + properties: [], + access: { + owner: { + img: "", + link: "", + }, + others: [], + }, + }); + + console.log(currentFolderItem); + + return ( + <> + + + + {item.title} + + + +
+ +
+ + + + {t("SystemProperties")} + + + + + {item.properties.map((p) => ( +
+ {p.title} + {p.content} +
+ ))} +
+ + ); +}; + +export default inject(({}) => { + return {}; +})( + withTranslation(["InfoPanel", "Home", "Common", "Translations"])( + observer(SingleItem) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolderItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolderItem.js new file mode 100644 index 0000000000..1a68a8f260 --- /dev/null +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolderItem.js @@ -0,0 +1,405 @@ +import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; +import { FileType } from "@appserver/common/constants"; +import Link from "@appserver/components/link"; +import Text from "@appserver/components/text"; +import Tooltip from "@appserver/components/tooltip"; +import { inject, observer } from "mobx-react"; +import React, { useEffect, useState } from "react"; +import { withTranslation } from "react-i18next"; +import { ReactSVG } from "react-svg"; + +import { + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, + StyledProperties, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./styles/styles.js"; + +const SingleItem = (props) => { + const { + t, + selectedItem, + isRecycleBinFolder, + onSelectItem, + setSharingPanelVisible, + getFolderInfo, + getIcon, + getFolderIcon, + getShareUsers, + } = props; + + let updateSubscription = true; + const [item, setItem] = useState({ + id: "", + isFolder: false, + title: "", + iconUrl: "", + thumbnailUrl: "", + properties: [], + access: { + owner: { + img: "", + link: "", + }, + others: [], + }, + }); + const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); + + const updateItemsInfo = async (selectedItem) => { + const getItemIcon = (item, size) => { + const extension = item.fileExst; + const iconUrl = extension + ? getIcon(size, extension) + : getFolderIcon(item.providerKey, size); + + return iconUrl; + }; + + const getSingleItemProperties = (item) => { + const styledLink = (text, href) => ( + + {text} + + ); + + const styledText = (text) => ( + {text} + ); + + const parseAndFormatDate = (date) => { + date = new Date(date); + + const normalize = (num) => { + if (num > 9) return num; + return `0${num}`; + }; + + let day = normalize(date.getDate()), + month = normalize(date.getMonth()), + year = date.getFullYear(), + hours = date.getHours(), + minutes = normalize(date.getMinutes()), + a_p = hours > 12 ? "AM" : "PM"; + + if (hours === 0) hours = 12; + else if (hours > 12) hours = hours - 12; + + return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; + }; + + const getItemType = (fileType) => { + switch (fileType) { + case FileType.Unknown: + return t("Common:Unknown"); + case FileType.Archive: + return t("Common:Archive"); + case FileType.Video: + return t("Common:Video"); + case FileType.Audio: + return t("Common:Audio"); + case FileType.Image: + return t("Common:Image"); + case FileType.Spreadsheet: + return t("Home:Spreadsheet"); + case FileType.Presentation: + return t("Home:Presentation"); + case FileType.Document: + return t("Home:Document"); + default: + return t("Home:Folder"); + } + }; + + const itemSize = item.isFolder + ? `${item.foldersCount} ${t("Translations:Folders")} | ${ + item.filesCount + } ${t("Files")}` + : item.contentLength; + + const itemType = getItemType(item.fileType); + + let result = [ + { + title: t("Common:Owner"), + content: styledLink( + item.createdBy.displayName, + item.createdBy.profileUrl + ), + }, + { + title: t("InfoPanel:Location"), + content: , + }, + { + title: t("Common:Type"), + content: styledText(itemType), + }, + { + title: t("Common:Size"), + content: styledText(itemSize), + }, + { + title: t("Home:ByLastModifiedDate"), + content: styledText(parseAndFormatDate(item.updated)), + }, + { + title: t("LastModifiedBy"), + content: styledLink( + item.updatedBy.displayName, + item.updatedBy.profileUrl + ), + }, + { + title: t("Home:ByCreationDate"), + content: styledText(parseAndFormatDate(item.created)), + }, + ]; + + if (item.isFolder) return result; + + result.splice(3, 0, { + title: t("FileExtension"), + content: styledText(item.fileExst.split(".")[1].toUpperCase()), + }); + + result.push( + { + title: t("Versions"), + content: styledText(item.version), + }, + { + title: t("Comments"), + content: styledText(item.comment), + } + ); + + return result; + }; + + const displayedItem = { + id: selectedItem.id, + isFolder: selectedItem.isFolder, + title: selectedItem.title, + iconUrl: getItemIcon(selectedItem, 32), + thumbnailUrl: selectedItem.thumbnailUrl || getItemIcon(selectedItem, 96), + properties: getSingleItemProperties(selectedItem), + access: { + owner: { + img: selectedItem.createdBy.avatarSmall, + link: selectedItem.createdBy.profileUrl, + }, + others: [], + }, + }; + + setItem(displayedItem); + await loadAsyncData(displayedItem, selectedItem); + }; + + const loadAsyncData = async (displayedItem, selectedItem) => { + const updateLoadedItemProperties = async (displayedItem, selectedItem) => { + const parentFolderId = selectedItem.isFolder + ? selectedItem.parentId + : selectedItem.folderId; + const folderInfo = await getFolderInfo(parentFolderId); + + return [...displayedItem.properties].map((dip) => + dip.title === t("Location") + ? { + title: t("Location"), + content: ( + + {folderInfo.title} + + ), + } + : dip + ); + }; + + const updateLoadedItemAccess = async (selectedItem) => { + const accesses = await getShareUsers( + [selectedItem.folderId], + [selectedItem.id] + ); + + const result = { + owner: {}, + others: [], + }; + + accesses.forEach((access) => { + const user = access.sharedTo; + const userData = { + key: user.id, + img: user.avatarSmall, + link: user.profileUrl, + name: user.displayName, + email: user.email, + }; + + if (access.isOwner) result.owner = userData; + else if (userData.email !== undefined) result.others.push(userData); + }); + + return result; + }; + + const properties = await updateLoadedItemProperties( + displayedItem, + selectedItem + ); + + const access = await updateLoadedItemAccess(selectedItem); + + if (updateSubscription) + setItem({ + ...displayedItem, + properties: properties, + access: access, + }); + }; + + const showAllAccessUsers = () => { + setIsShowAllAccessUsers(true); + }; + + const openSharingPanel = () => { + const { id, isFolder } = item; + + onSelectItem({ id, isFolder }); + setSharingPanelVisible(true); + }; + + useEffect(() => { + if (selectedItem.id !== item.id && updateSubscription) + updateItemsInfo(selectedItem); + return () => (updateSubscription = false); + }, [selectedItem]); + + return ( + <> + + + + {item.title} + + + + {selectedItem.thumbnailUrl ? ( + + + + ) : ( +
+ +
+ )} + + + + {t("SystemProperties")} + + + + + {item.properties.map((p) => ( +
+ {p.title} + {p.content} +
+ ))} +
+ + {!isRecycleBinFolder && ( + <> + + + {t("WhoHasAccess")} + + + + + + dataTip ? {dataTip} : null + } + /> + + +
+ + + +
+
+ + {item.access.others.length ?
: null} + + {!isShowAllAccessUsers && item.access.others.length > 3 ? ( + <> + {item.access.others.map((user, i) => { + if (i < 3) + return ( +
+ +
+ + + +
+
+
+ ); + })} +
+ {`+ ${item.access.others.length - 3} ${t("Members")}`} +
+ + ) : ( + <> + {item.access.others.map((user) => ( +
+ +
+ + + +
+
+
+ ))} + + )} +
+ + {t("OpenSharingSettings")} + + + )} + + ); +}; + +export default inject(({}) => { + return {}; +})( + withTranslation(["InfoPanel", "Home", "Common", "Translations"])( + observer(SingleItem) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index f48ea7a365..d49cbe8795 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -9,420 +9,403 @@ import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; import { - StyledAccess, - StyledAccessUser, - StyledOpenSharingPanel, - StyledProperties, - StyledSubtitle, - StyledThumbnail, - StyledTitle, + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, + StyledProperties, + StyledSubtitle, + StyledThumbnail, + StyledTitle, } from "./styles/styles.js"; const SingleItem = (props) => { - const { - t, - selectedItem, - isRecycleBinFolder, - onSelectItem, - setSharingPanelVisible, - getFolderInfo, - getIcon, - getFolderIcon, - getShareUsers, - } = props; + const { + t, + selectedItem, + isRecycleBinFolder, + onSelectItem, + setSharingPanelVisible, + getFolderInfo, + getIcon, + getFolderIcon, + getShareUsers, + } = props; - let updateSubscription = true; - const [item, setItem] = useState({ - id: "", - isFolder: false, - title: "", - iconUrl: "", - thumbnailUrl: "", - properties: [], - access: { - owner: { - img: "", - link: "", - }, - others: [], - }, - }); - const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); + let updateSubscription = true; + const [item, setItem] = useState({ + id: "", + isFolder: false, + title: "", + iconUrl: "", + thumbnailUrl: "", + properties: [], + access: { + owner: { + img: "", + link: "", + }, + others: [], + }, + }); + const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); - const updateItemsInfo = async (selectedItem) => { - const getItemIcon = (item, size) => { - const extension = item.fileExst; - const iconUrl = extension - ? getIcon(size, extension) - : getFolderIcon(item.providerKey, size); + const updateItemsInfo = async (selectedItem) => { + const getItemIcon = (item, size) => { + const extension = item.fileExst; + const iconUrl = extension + ? getIcon(size, extension) + : getFolderIcon(item.providerKey, size); - return iconUrl; - }; - - const getSingleItemProperties = (item) => { - const styledLink = (text, href) => ( - - {text} - - ); - - const styledText = (text) => ( - {text} - ); - - const parseAndFormatDate = (date) => { - date = new Date(date); - - const normalize = (num) => { - if (num > 9) return num; - return `0${num}`; - }; - - let day = normalize(date.getDate()), - month = normalize(date.getMonth()), - year = date.getFullYear(), - hours = date.getHours(), - minutes = normalize(date.getMinutes()), - a_p = hours > 12 ? "AM" : "PM"; - - if (hours === 0) hours = 12; - else if (hours > 12) hours = hours - 12; - - return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; - }; - - const getItemType = (fileType) => { - switch (fileType) { - case FileType.Unknown: - return t("Common:Unknown"); - case FileType.Archive: - return t("Common:Archive"); - case FileType.Video: - return t("Common:Video"); - case FileType.Audio: - return t("Common:Audio"); - case FileType.Image: - return t("Common:Image"); - case FileType.Spreadsheet: - return t("Home:Spreadsheet"); - case FileType.Presentation: - return t("Home:Presentation"); - case FileType.Document: - return t("Home:Document"); - default: - return t("Home:Folder"); - } - }; - - const itemSize = item.isFolder - ? `${item.foldersCount} ${t("Translations:Folders")} | ${ - item.filesCount - } ${t("Files")}` - : item.contentLength; - - const itemType = getItemType(item.fileType); - - let result = [ - { - title: t("Common:Owner"), - content: styledLink( - item.createdBy.displayName, - item.createdBy.profileUrl - ), - }, - { - title: t("InfoPanel:Location"), - content: , - }, - { - title: t("Common:Type"), - content: styledText(itemType), - }, - { - title: t("Common:Size"), - content: styledText(itemSize), - }, - { - title: t("Home:ByLastModifiedDate"), - content: styledText(parseAndFormatDate(item.updated)), - }, - { - title: t("LastModifiedBy"), - content: styledLink( - item.updatedBy.displayName, - item.updatedBy.profileUrl - ), - }, - { - title: t("Home:ByCreationDate"), - content: styledText(parseAndFormatDate(item.created)), - }, - ]; - - if (item.isFolder) return result; - - result.splice(3, 0, { - title: t("FileExtension"), - content: styledText(item.fileExst.split(".")[1].toUpperCase()), - }); - - result.push( - { - title: t("Versions"), - content: styledText(item.version), - }, - { - title: t("Comments"), - content: styledText(item.comment), - } - ); - - return result; - }; - - const displayedItem = { - id: selectedItem.id, - isFolder: selectedItem.isFolder, - title: selectedItem.title, - iconUrl: getItemIcon(selectedItem, 32), - thumbnailUrl: - selectedItem.thumbnailUrl || getItemIcon(selectedItem, 96), - properties: getSingleItemProperties(selectedItem), - access: { - owner: { - img: selectedItem.createdBy.avatarSmall, - link: selectedItem.createdBy.profileUrl, - }, - others: [], - }, - }; - - setItem(displayedItem); - await loadAsyncData(displayedItem, selectedItem); + return iconUrl; }; - const loadAsyncData = async (displayedItem, selectedItem) => { - const updateLoadedItemProperties = async ( - displayedItem, - selectedItem - ) => { - const parentFolderId = selectedItem.isFolder - ? selectedItem.parentId - : selectedItem.folderId; - const folderInfo = await getFolderInfo(parentFolderId); + const getSingleItemProperties = (item) => { + const styledLink = (text, href) => ( + + {text} + + ); - return [...displayedItem.properties].map((dip) => - dip.title === t("Location") - ? { - title: t("Location"), - content: ( - - {folderInfo.title} - - ), - } - : dip - ); + const styledText = (text) => ( + {text} + ); + + const parseAndFormatDate = (date) => { + date = new Date(date); + + const normalize = (num) => { + if (num > 9) return num; + return `0${num}`; }; - const updateLoadedItemAccess = async (selectedItem) => { - const accesses = await getShareUsers( - [selectedItem.folderId], - [selectedItem.id] - ); + let day = normalize(date.getDate()), + month = normalize(date.getMonth()), + year = date.getFullYear(), + hours = date.getHours(), + minutes = normalize(date.getMinutes()), + a_p = hours > 12 ? "AM" : "PM"; - const result = { - owner: {}, - others: [], - }; + if (hours === 0) hours = 12; + else if (hours > 12) hours = hours - 12; - accesses.forEach((access) => { - const user = access.sharedTo; - const userData = { - key: user.id, - img: user.avatarSmall, - link: user.profileUrl, - name: user.displayName, - email: user.email, - }; + return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; + }; - if (access.isOwner) result.owner = userData; - else if (userData.email !== undefined) - result.others.push(userData); - }); + const getItemType = (fileType) => { + switch (fileType) { + case FileType.Unknown: + return t("Common:Unknown"); + case FileType.Archive: + return t("Common:Archive"); + case FileType.Video: + return t("Common:Video"); + case FileType.Audio: + return t("Common:Audio"); + case FileType.Image: + return t("Common:Image"); + case FileType.Spreadsheet: + return t("Home:Spreadsheet"); + case FileType.Presentation: + return t("Home:Presentation"); + case FileType.Document: + return t("Home:Document"); + default: + return t("Home:Folder"); + } + }; - return result; - }; + const itemSize = item.isFolder + ? `${item.foldersCount} ${t("Translations:Folders")} | ${ + item.filesCount + } ${t("Files")}` + : item.contentLength; - const properties = await updateLoadedItemProperties( - displayedItem, - selectedItem + const itemType = getItemType(item.fileType); + + let result = [ + { + title: t("Common:Owner"), + content: styledLink( + item.createdBy.displayName, + item.createdBy.profileUrl + ), + }, + { + title: t("InfoPanel:Location"), + content: , + }, + { + title: t("Common:Type"), + content: styledText(itemType), + }, + { + title: t("Common:Size"), + content: styledText(itemSize), + }, + { + title: t("Home:ByLastModifiedDate"), + content: styledText(parseAndFormatDate(item.updated)), + }, + { + title: t("LastModifiedBy"), + content: styledLink( + item.updatedBy.displayName, + item.updatedBy.profileUrl + ), + }, + { + title: t("Home:ByCreationDate"), + content: styledText(parseAndFormatDate(item.created)), + }, + ]; + + if (item.isFolder) return result; + + result.splice(3, 0, { + title: t("FileExtension"), + content: styledText(item.fileExst.split(".")[1].toUpperCase()), + }); + + result.push( + { + title: t("Versions"), + content: styledText(item.version), + }, + { + title: t("Comments"), + content: styledText(item.comment), + } + ); + + return result; + }; + + const displayedItem = { + id: selectedItem.id, + isFolder: selectedItem.isFolder, + title: selectedItem.title, + iconUrl: getItemIcon(selectedItem, 32), + thumbnailUrl: selectedItem.thumbnailUrl || getItemIcon(selectedItem, 96), + properties: getSingleItemProperties(selectedItem), + access: { + owner: { + img: selectedItem.createdBy.avatarSmall, + link: selectedItem.createdBy.profileUrl, + }, + others: [], + }, + }; + + setItem(displayedItem); + await loadAsyncData(displayedItem, selectedItem); + }; + + const loadAsyncData = async (displayedItem, selectedItem) => { + const updateLoadedItemProperties = async (displayedItem, selectedItem) => { + const parentFolderId = selectedItem.isFolder + ? selectedItem.parentId + : selectedItem.folderId; + + if (!parentFolderId) + return [...displayedItem.properties].filter( + (dip) => dip.title !== t("Location") ); - const access = await updateLoadedItemAccess(selectedItem); + const folderInfo = await getFolderInfo(parentFolderId); - if (updateSubscription) - setItem({ - ...displayedItem, - properties: properties, - access: access, - }); + return [...displayedItem.properties].map((dip) => + dip.title === t("Location") + ? { + title: t("Location"), + content: ( + + {folderInfo.title} + + ), + } + : dip + ); }; - const showAllAccessUsers = () => { - setIsShowAllAccessUsers(true); + const updateLoadedItemAccess = async (selectedItem) => { + const accesses = await getShareUsers( + [selectedItem.folderId], + [selectedItem.id] + ); + + const result = { + owner: {}, + others: [], + }; + + accesses.forEach((access) => { + const user = access.sharedTo; + const userData = { + key: user.id, + img: user.avatarSmall, + link: user.profileUrl, + name: user.displayName, + email: user.email, + }; + + if (access.isOwner) result.owner = userData; + else if (userData.email !== undefined) result.others.push(userData); + }); + + return result; }; - const openSharingPanel = () => { - const { id, isFolder } = item; - - onSelectItem({ id, isFolder }); - setSharingPanelVisible(true); - }; - - useEffect(() => { - if (selectedItem.id !== item.id && updateSubscription) - updateItemsInfo(selectedItem); - return () => (updateSubscription = false); - }, [selectedItem]); - - return ( - <> - - - - {item.title} - - - - {selectedItem.thumbnailUrl ? ( - - - - ) : ( -
- -
- )} - - - - {t("SystemProperties")} - - - - - {item.properties.map((p) => ( -
- {p.title} - {p.content} -
- ))} -
- - {!isRecycleBinFolder && ( - <> - - - {t("WhoHasAccess")} - - - - - - dataTip ? ( - {dataTip} - ) : null - } - /> - - -
- - - -
-
- - {item.access.others.length ? ( -
- ) : null} - - {!isShowAllAccessUsers && - item.access.others.length > 3 ? ( - <> - {item.access.others.map((user, i) => { - if (i < 3) - return ( -
- -
- - - -
-
-
- ); - })} -
- {`+ ${item.access.others.length - 3} ${t( - "Members" - )}`} -
- - ) : ( - <> - {item.access.others.map((user) => ( -
- -
- - - -
-
-
- ))} - - )} -
- - {t("OpenSharingSettings")} - - - )} - + const properties = await updateLoadedItemProperties( + displayedItem, + selectedItem ); + + const access = await updateLoadedItemAccess(selectedItem); + + if (updateSubscription) + setItem({ + ...displayedItem, + properties: properties, + access: access, + }); + }; + + const showAllAccessUsers = () => { + setIsShowAllAccessUsers(true); + }; + + const openSharingPanel = () => { + const { id, isFolder } = item; + + onSelectItem({ id, isFolder }); + setSharingPanelVisible(true); + }; + + useEffect(() => { + if (selectedItem.id !== item.id && updateSubscription) + updateItemsInfo(selectedItem); + return () => (updateSubscription = false); + }, [selectedItem]); + + return ( + <> + + + + {item.title} + + + + {selectedItem.thumbnailUrl ? ( + + + + ) : ( +
+ +
+ )} + + + + {t("SystemProperties")} + + + + + {item.properties.map((p) => ( +
+ {p.title} + {p.content} +
+ ))} +
+ + {!isRecycleBinFolder && ( + <> + + + {t("WhoHasAccess")} + + + + + + dataTip ? {dataTip} : null + } + /> + + +
+ + + +
+
+ + {item.access.others.length ?
: null} + + {!isShowAllAccessUsers && item.access.others.length > 3 ? ( + <> + {item.access.others.map((user, i) => { + if (i < 3) + return ( +
+ +
+ + + +
+
+
+ ); + })} +
+ {`+ ${item.access.others.length - 3} ${t("Members")}`} +
+ + ) : ( + <> + {item.access.others.map((user) => ( +
+ +
+ + + +
+
+
+ ))} + + )} +
+ + {t("OpenSharingSettings")} + + + )} + + ); }; export default inject(({}) => { - return {}; + return {}; })( - withTranslation(["InfoPanel", "Home", "Common", "Translations"])( - observer(SingleItem) - ) + withTranslation(["InfoPanel", "Home", "Common", "Translations"])( + observer(SingleItem) + ) ); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index f25b847696..829c4baf31 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -2,7 +2,9 @@ import { inject, observer } from "mobx-react"; import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import { withRouter } from "react-router"; - +import { useParams } from "react-router-dom"; +import CurrentFolder from "./CurrentFolder"; +import api from "@appserver/common/api"; import SeveralItems from "./SeveralItems"; import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; @@ -19,27 +21,54 @@ const InfoPanelBodyContent = ({ setSharingPanelVisible, isRecycleBinFolder, showCurrentFolder, + ...props }) => { - if (selectedItems.length) { - } + const [currentFolderLoading, setCurrentFolderLoading] = useState(false); + const [currentFolder, setCurrentFolder] = useState({}); + + const getCurrentFolderInfo = async () => { + setCurrentFolderLoading(true); + + const folderId = new URL(window.location.href).searchParams.get("folder"); + const folder = await getFolderInfo(folderId); + + const fileExst = folder.fileExst, + providerKey = folder.providerKey, + contentLength = folderId.contentLength; + + folder.iconUrl = getIcon(32, fileExst, providerKey, contentLength); + folder.thumbnailUrl = getIcon(96, fileExst, providerKey, contentLength); + folder.isFolder = true; + + console.log(folder); + setCurrentFolder(folder); + setCurrentFolderLoading(false); + }; + + useEffect(() => { + getCurrentFolderInfo(); + }, [window.location.href]); return ( - <>{console.log(showCurrentFolder)} - {showCurrentFolder ? ( -
Room Info
+ <> + {currentFolderLoading ? ( + <>Loading ... + ) : ( + + )} + ) : ( - // <> {selectedItems.length === 0 && !bufferSelectedItem ? (
@@ -79,14 +108,23 @@ export default inject( JSON.stringify(filesStore.bufferSelection) ); - //console.log(settin); const { showCurrentFolder } = infoPanelStore; - const { getFolderInfo, getShareUsers } = filesStore; + const { + getFolderInfo, + getShareUsers, + getFileInfo, + filesList, + folders, + viewAs, + } = filesStore; const { getIcon, getFolderIcon } = settingsStore; const { onSelectItem } = filesActionsStore; const { setSharingPanelVisible } = dialogsStore; const { isRecycleBinFolder } = treeFoldersStore; + console.log(filesList); + console.log(folders); + return { bufferSelectedItem, selectedItems, @@ -98,6 +136,10 @@ export default inject( setSharingPanelVisible, isRecycleBinFolder, showCurrentFolder, + getFileInfo, + filesList, + folders, + viewAs, }; } )(withRouter(withTranslation(["InfoPanel"])(observer(InfoPanelBodyContent)))); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index e930c8f003..6b5aba0a51 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -203,8 +203,13 @@ class SectionHeaderContent extends React.Component { onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); showFolderInfo = () => { + if (this.props.showCurrentFolder && this.props.isInfoPanelVisible) { + this.props.setShowCurrentFolder(false); + this.props.setIsInfoPanelVisible(false); + return; + } + this.props.setShowCurrentFolder(true); - console.log(this.props.showCurrentFolder); this.props.setIsInfoPanelVisible(true); }; From 3e951462d804b86728117f1bc61180d4823267e9 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Mar 2022 10:24:43 +0300 Subject: [PATCH 31/81] fixes with unexpcted info loading --- .../sub-components/FilterBlock.js | 2 +- .../sub-components/info-panel-body.js | 14 +- .../sub-components/info-panel-header.js | 94 ++-- .../Home/InfoPanel/Body/CurrentFolder.js | 93 ---- .../Home/InfoPanel/Body/CurrentFolderItem.js | 405 ------------------ .../pages/Home/InfoPanel/Body/SingleItem.js | 47 +- .../src/pages/Home/InfoPanel/Body/index.js | 85 ++-- .../src/pages/Home/Section/Header/index.js | 1 - 8 files changed, 124 insertions(+), 617 deletions(-) delete mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolder.js delete mode 100644 products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/CurrentFolderItem.js diff --git a/packages/asc-web-common/components/NewFilterInput/sub-components/FilterBlock.js b/packages/asc-web-common/components/NewFilterInput/sub-components/FilterBlock.js index 3b3a488d8c..1b6a1ee0f0 100644 --- a/packages/asc-web-common/components/NewFilterInput/sub-components/FilterBlock.js +++ b/packages/asc-web-common/components/NewFilterInput/sub-components/FilterBlock.js @@ -230,7 +230,7 @@ const FilterBlock = ({ })}
) : selectedItems.length === 1 || bufferSelectedItem ? ( - + singleItem(selectedItems[0] || bufferSelectedItem) ) : ( )} @@ -109,21 +106,16 @@ export default inject( ); const { showCurrentFolder } = infoPanelStore; - const { - getFolderInfo, - getShareUsers, - getFileInfo, - filesList, - folders, - viewAs, - } = filesStore; + const { getFolderInfo, getShareUsers } = filesStore; const { getIcon, getFolderIcon } = settingsStore; const { onSelectItem } = filesActionsStore; const { setSharingPanelVisible } = dialogsStore; - const { isRecycleBinFolder } = treeFoldersStore; - - console.log(filesList); - console.log(folders); + const { + isRecycleBinFolder, + isCommonFolder, + isRecentFolder, + isFavoritesFolder, + } = treeFoldersStore; return { bufferSelectedItem, @@ -135,11 +127,10 @@ export default inject( onSelectItem, setSharingPanelVisible, isRecycleBinFolder, + isCommonFolder, showCurrentFolder, - getFileInfo, - filesList, - folders, - viewAs, + isRecentFolder, + isFavoritesFolder, }; } )(withRouter(withTranslation(["InfoPanel"])(observer(InfoPanelBodyContent)))); diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 6b5aba0a51..73cf8f0c50 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -208,7 +208,6 @@ class SectionHeaderContent extends React.Component { this.props.setIsInfoPanelVisible(false); return; } - this.props.setShowCurrentFolder(true); this.props.setIsInfoPanelVisible(true); }; From 61aac91d079e4e2386bb91fa003540b4ae4201d6 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Mar 2022 11:28:40 +0300 Subject: [PATCH 32/81] fix arrow keys not working with showCurrentFolder === true --- .../InfoPanelLoader/InfoPanelLoader.js | 111 +++++++++++++++++ .../InfoPanelLoader/StyledInfoPanelLoader.js | 114 ++++++++++++++++++ .../Loaders/InfoPanelLoader/index.js | 1 + .../src/pages/Home/InfoPanel/Body/index.js | 2 +- 4 files changed, 227 insertions(+), 1 deletion(-) create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js create mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js new file mode 100644 index 0000000000..2c0ace2138 --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js @@ -0,0 +1,111 @@ +import PropTypes from "prop-types"; +import React from "react"; + +import RectangleLoader from "../RectangleLoader"; +import { + StyledAccessRow, + StyledInfoRoomBody, + StyledPropertiesTable, + StyledPropertyRow, + StyledSubtitle, + StyledThumbnail, + StyledTitle, +} from "./StyledInfoPanelLoader"; + +const InfoPanelLoader = ({ + id, + className, + style, + isFolder, + hasThumbnail, + ...rest +}) => { + const {} = rest; + + const randomNumber = (min, max) => Math.random() * (max - min) + min; + + const customRectangleLoader = (width, height, rounded) => ( + + ); + + const properties = isFolder + ? [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + ] + : [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { "File Extension": 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + { Versions: 17.6 }, + { Comments: 17.6 }, + ]; + + return ( + + + {customRectangleLoader(32, 32)} + {customRectangleLoader(250, 22)} + + + System Properties + + {hasThumbnail && ( + + {customRectangleLoader(320.2, 200)} + + )} + + + {properties.map((property) => ( + +
+ {Object.keys(property)[0]} +
+ {customRectangleLoader( + randomNumber(125, 150), + Object.values(property)[0] + )} +
+ ))} +
+ + Who has access + + + {customRectangleLoader(32, 32, 16)} +
+ {customRectangleLoader(32, 32, 16)} + {customRectangleLoader(32, 32, 16)} +
+
+ ); +}; + +InfoPanelLoader.propTypes = { + id: PropTypes.string, + className: PropTypes.string, + style: PropTypes.object, +}; + +InfoPanelLoader.defaultProps = { + id: undefined, + className: undefined, + style: undefined, +}; + +export default InfoPanelLoader; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js new file mode 100644 index 0000000000..59543d61bf --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js @@ -0,0 +1,114 @@ +import styled from "styled-components"; + +const StyledInfoRoomBody = styled.div``; + +const StyledTitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 80px; + gap: 8px; +`; + +const StyledThumbnail = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; +`; + +const StyledSubtitle = styled.div` + margin-bottom: 24px; + height: 19.2px; + font-weight: 600; + font-size: 14px; + color: #000000; +`; + +const StyledPropertiesTable = styled.div` + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; +`; + +const StyledPropertyRow = styled.div` + width: 100%; + display: grid; + grid-template-columns: 110px 1fr; + grid-column-gap: 24px; + + .property-title { + font-size: 13px; + color: #333333; + } +`; + +const StyledAccessRow = styled.div` + width: 100%; + height: 32px; + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } +`; + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +export { + StyledInfoRoomBody, + StyledSubtitle, + StyledTitle, + StyledThumbnail, + StyledPropertiesTable, + StyledPropertyRow, + StyledAccessRow, +}; + +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// + +const StyledItemAccess = styled.div` + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } +`; + +const StyleditemAccessUser = styled.div` + width: 32px; + height: 32px; + border-radius: 50%; + + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } + } +`; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js new file mode 100644 index 0000000000..ed427373f5 --- /dev/null +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js @@ -0,0 +1 @@ +export default from "./InfoPanelLoader"; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 3d7af88857..2a7e9f99a1 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -70,7 +70,7 @@ const InfoPanelBodyContent = ({ return ( - {showCurrentFolder ? ( + {showCurrentFolder && selectedItems.length === 0 ? ( <> {currentFolderLoading ? <>Loading ... : singleItem(currentFolder)} From f659632108c3c5061e72033aaa73b01c2f56ca8d Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Mar 2022 13:12:45 +0300 Subject: [PATCH 33/81] fixed exception warning --- .../sub-components/info-panel-header.js | 43 ++++++++++--------- .../pages/Home/InfoPanel/Body/SingleItem.js | 14 +++--- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index edba45ea13..cc9e86c50c 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -6,30 +6,31 @@ import PropTypes from "prop-types"; import React from "react"; import styled from "styled-components"; +const StyledInfoPanelHeader = styled.div` + width: 100%; + max-width: 100%; + height: 52px; + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 0; + border-bottom: 1px solid #eceef1; + + .header-text { + margin-left: 16px; + } + + .close-btn { + margin-right: 16px; + @media ${tablet} { + display: none; + } + } +`; + const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { const content = children?.props?.children; - const StyledInfoPanelHeader = styled.div` - width: 100%; - max-width: 100%; - height: 52px; - display: flex; - justify-content: space-between; - align-items: center; - padding: 8px 0; - border-bottom: 1px solid #eceef1; - - .header-text { - margin-left: 16px; - } - - .close-btn { - margin-right: 16px; - @media ${tablet} { - display: none; - } - } - `; return ( diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index b3bf63c59e..ede2b1a1fd 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -129,8 +129,8 @@ const SingleItem = (props) => { id: "Owner", title: t("Common:Owner"), content: styledLink( - item.createdBy.displayName, - item.createdBy.profileUrl + item.createdBy?.displayName, + item.createdBy?.profileUrl ), }, { @@ -157,8 +157,8 @@ const SingleItem = (props) => { id: "LastModifiedBy", title: t("LastModifiedBy"), content: styledLink( - item.updatedBy.displayName, - item.updatedBy.profileUrl + item.updatedBy?.displayName, + item.updatedBy?.profileUrl ), }, { @@ -173,7 +173,7 @@ const SingleItem = (props) => { result.splice(3, 0, { id: "FileExtension", title: t("FileExtension"), - content: styledText(item.fileExst.split(".")[1].toUpperCase()), + content: styledText(item.fileExst?.split(".")[1].toUpperCase()), }); result.push( @@ -201,8 +201,8 @@ const SingleItem = (props) => { properties: getSingleItemProperties(selectedItem), access: { owner: { - img: selectedItem.createdBy.avatarSmall, - link: selectedItem.createdBy.profileUrl, + img: selectedItem.createdBy?.avatarSmall, + link: selectedItem.createdBy?.profileUrl, }, others: [], }, From c4b470f98a70509b1ebe610c671bfed62ec83ef6 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 21 Mar 2022 18:42:23 +0300 Subject: [PATCH 34/81] bugfixes --- .../InfoPanelLoader/InfoPanelLoader.js | 166 +++++----- .../InfoPanelLoader/StyledInfoPanelLoader.js | 165 +++++----- .../components/Loaders/index.js | 2 + .../Section/sub-components/info-panel.js | 15 +- .../Client/src/HOCs/withFileActions.js | 9 +- .../src/pages/Home/InfoPanel/Body/index.js | 10 +- .../Home/InfoPanel/Body/styles/styles.js | 308 +++++++++--------- .../Client/src/store/InfoPanelStore.js | 2 +- 8 files changed, 350 insertions(+), 327 deletions(-) diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js index 2c0ace2138..e6b95c643f 100644 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js @@ -3,109 +3,107 @@ import React from "react"; import RectangleLoader from "../RectangleLoader"; import { - StyledAccessRow, - StyledInfoRoomBody, - StyledPropertiesTable, - StyledPropertyRow, - StyledSubtitle, - StyledThumbnail, - StyledTitle, + StyledAccessRow, + StyledInfoRoomBody, + StyledPropertiesTable, + StyledPropertyRow, + StyledSubtitle, + StyledThumbnail, + StyledTitle, } from "./StyledInfoPanelLoader"; const InfoPanelLoader = ({ - id, - className, - style, - isFolder, - hasThumbnail, - ...rest + id, + className, + style, + isFolder, + hasThumbnail, + ...rest }) => { - const {} = rest; + const {} = rest; - const randomNumber = (min, max) => Math.random() * (max - min) + min; + const randomNumber = (min, max) => Math.random() * (max - min) + min; - const customRectangleLoader = (width, height, rounded) => ( - - ); + const customRectangleLoader = (width, height, rounded) => ( + + ); - const properties = isFolder - ? [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - ] - : [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { "File Extension": 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - { Versions: 17.6 }, - { Comments: 17.6 }, - ]; + const properties = isFolder + ? [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + ] + : [ + { Owner: 19 }, + { Location: 19 }, + { Type: 17.6 }, + { "File Extension": 17.6 }, + { Size: 17.6 }, + { "Date modified": 17.6 }, + { "Last modified by": 19 }, + { "Date creation": 17.6 }, + { Versions: 17.6 }, + { Comments: 17.6 }, + ]; - return ( - - - {customRectangleLoader(32, 32)} - {customRectangleLoader(250, 22)} - + return ( + + + {customRectangleLoader(32, 32, 3)} + {customRectangleLoader(250, 22)} + - System Properties + System Properties - {hasThumbnail && ( - - {customRectangleLoader(320.2, 200)} - + {hasThumbnail ? ( + {customRectangleLoader(320.2, 200)} + ) : ( + {customRectangleLoader(96, 96)} + )} + + + {properties.map((property) => ( + +
{Object.keys(property)[0]}
+ {customRectangleLoader( + randomNumber(125, 150), + Object.values(property)[0] )} +
+ ))} +
- - {properties.map((property) => ( - -
- {Object.keys(property)[0]} -
- {customRectangleLoader( - randomNumber(125, 150), - Object.values(property)[0] - )} -
- ))} -
+ Who has access - Who has access - - - {customRectangleLoader(32, 32, 16)} -
- {customRectangleLoader(32, 32, 16)} - {customRectangleLoader(32, 32, 16)} -
-
- ); + + {customRectangleLoader(32, 32, 16)} +
+ {customRectangleLoader(32, 32, 16)} + {customRectangleLoader(32, 32, 16)} +
+
+ ); }; InfoPanelLoader.propTypes = { - id: PropTypes.string, - className: PropTypes.string, - style: PropTypes.object, + id: PropTypes.string, + className: PropTypes.string, + style: PropTypes.object, }; InfoPanelLoader.defaultProps = { - id: undefined, - className: undefined, - style: undefined, + id: undefined, + className: undefined, + style: undefined, }; export default InfoPanelLoader; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js index 59543d61bf..24c2e803fd 100644 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js +++ b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js @@ -1,114 +1,117 @@ import styled from "styled-components"; -const StyledInfoRoomBody = styled.div``; +const StyledInfoRoomBody = styled.div` + .no-thumbnail-img-wrapper { + padding: 9px 0 34px; + height: auto; + width: 100%; + display: flex; + justify-content: center; + .no-thumbnail-img { + height: 96px; + width: 96px; + } + } +`; const StyledTitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - height: 80px; - gap: 8px; + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: 80px; + gap: 8px; `; const StyledThumbnail = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 200px; - padding: 4px; - border: solid 1px #eceef1; - border-radius: 6px; - margin-bottom: 24px; + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; `; const StyledSubtitle = styled.div` - margin-bottom: 24px; - height: 19.2px; - font-weight: 600; - font-size: 14px; - color: #000000; + margin-bottom: 24px; + height: 19.2px; + font-weight: 600; + font-size: 14px; + color: #000000; `; const StyledPropertiesTable = styled.div` - display: flex; - flex-direction: column; - width: 100%; - margin-bottom: 24px; - gap: 8px; + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; `; const StyledPropertyRow = styled.div` - width: 100%; - display: grid; - grid-template-columns: 110px 1fr; - grid-column-gap: 24px; + width: 100%; + display: grid; + grid-template-columns: 110px 1fr; + grid-column-gap: 24px; - .property-title { - font-size: 13px; - color: #333333; - } + .property-title { + font-size: 13px; + color: #333333; + } `; const StyledAccessRow = styled.div` - width: 100%; - height: 32px; - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; + width: 100%; + height: 32px; + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } `; -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - export { - StyledInfoRoomBody, - StyledSubtitle, - StyledTitle, - StyledThumbnail, - StyledPropertiesTable, - StyledPropertyRow, - StyledAccessRow, + StyledInfoRoomBody, + StyledSubtitle, + StyledTitle, + StyledThumbnail, + StyledPropertiesTable, + StyledPropertyRow, + StyledAccessRow, }; -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - const StyledItemAccess = styled.div` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } + display: flex; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } `; const StyleditemAccessUser = styled.div` - width: 32px; - height: 32px; - border-radius: 50%; + width: 32px; + height: 32px; + border-radius: 50%; - a { - img { - border-radius: 50%; - width: 100%; - height: 100%; - } + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; } + } `; diff --git a/packages/asc-web-common/components/Loaders/index.js b/packages/asc-web-common/components/Loaders/index.js index c711951a2e..f487e79d66 100644 --- a/packages/asc-web-common/components/Loaders/index.js +++ b/packages/asc-web-common/components/Loaders/index.js @@ -20,6 +20,7 @@ import Tile from "./TileLoader"; import Tiles from "./TilesLoader"; import DialogLoader from "./DialogLoader"; import DialogAsideLoader from "./DialogAsideLoader"; +import InfoPanelLoader from "./InfoPanelLoader"; export default { Rectangle, @@ -44,4 +45,5 @@ export default { ArticleButton, ArticleFolder, ArticleGroup, + InfoPanelLoader, }; diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 2203b14b6a..24043908a0 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -66,10 +66,14 @@ const StyledCloseButtonWrapper = styled.div` } `; -const InfoPanel = ({ children, selectedItems, isVisible, setIsVisible }) => { - //if (selectedItems.length > 0) setIsVisible(true); - //else setIsVisible(false); - +const InfoPanel = ({ + children, + selectedItems, + isVisible, + setIsVisible, + showCurrentFolder, +}) => { + //if (!showCurrentFolder && selectedItems.length === 0) return null; if (!isVisible) return null; const closeInfoPanel = () => setIsVisible(false); @@ -115,9 +119,11 @@ InfoPanel.propTypes = { export default inject(({ infoPanelStore, filesStore }) => { let selectedItems = []; let isVisible = false; + let showCurrentFolder = false; let setIsVisible = () => {}; if (infoPanelStore) { + showCurrentFolder = infoPanelStore.showCurrentFolder; isVisible = infoPanelStore.isVisible; setIsVisible = infoPanelStore.setIsVisible; } @@ -129,6 +135,7 @@ export default inject(({ infoPanelStore, filesStore }) => { return { selectedItems, isVisible, + showCurrentFolder, setIsVisible, }; })(InfoPanel); diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 3500d39356..66dbd915b8 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -21,17 +21,12 @@ export default function withFileActions(WrappedFileItem) { if (!infoPanelIsVisible && isDesktop()) { setShowCurrentFolder(false); - showInfoPanel(); + if (checked) showInfoPanel(); } }; fileContextClick = () => { - const { - onSelectItem, - item, - infoPanelIsVisible, - showInfoPanel, - } = this.props; + const { onSelectItem, item } = this.props; const { id, isFolder } = item; id !== -1 && onSelectItem({ id, isFolder }); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 2a7e9f99a1..9d4c97a9e6 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -5,6 +5,8 @@ import { withRouter } from "react-router"; import SeveralItems from "./SeveralItems"; import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; +import Loaders from "@appserver/common/components/Loaders"; +import Loader from "@appserver/components/loader"; const InfoPanelBodyContent = ({ t, @@ -72,7 +74,13 @@ const InfoPanelBodyContent = ({ {showCurrentFolder && selectedItems.length === 0 ? ( <> - {currentFolderLoading ? <>Loading ... : singleItem(currentFolder)} + {currentFolderLoading ? ( +
+ +
+ ) : ( + singleItem(currentFolder) + )} ) : ( <> diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index 079ed0e9d8..75b43e9b65 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -1,189 +1,199 @@ import styled from "styled-components"; const StyledInfoRoomBody = styled.div` - padding: 0px 16px 16px; - .no-item { - text-align: center; - } + padding: 0px 16px 16px; + height: 100%; + .no-item { + text-align: center; + } - .no-thumbnail-img-wrapper { - padding: 9px 0 34px; - height: auto; - width: 100%; - display: flex; - justify-content: center; - .no-thumbnail-img { - height: 96px; - width: 96px; - } - } -`; - -const StyledTitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; + .no-thumbnail-img-wrapper { + padding: 9px 0 34px; height: auto; - padding: 24px 0; - - .icon { - svg { - height: 32px; - width: 32px; - } + width: 100%; + display: flex; + justify-content: center; + .no-thumbnail-img { + height: 96px; + width: 96px; } + } - .text { - font-family: Open Sans; - line-height: 22px; - margin: 0 8px; - } -`; - -const StyledThumbnail = styled.div` + .current-folder-loader-wrapper { + width: 100%; + height: 100%; display: flex; justify-content: center; align-items: center; - width: 100%; - height: 200px; - padding: 4px; - border: solid 1px #eceef1; - border-radius: 6px; - margin-bottom: 24px; - img { - max-height: 200px; - max-width: 100%; - width: auto; - height: auto; + margin-top: auto; + } +`; + +const StyledTitle = styled.div` + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + height: auto; + padding: 24px 0; + + .icon { + svg { + height: 32px; + width: 32px; } + } + + .text { + font-family: Open Sans; + line-height: 22px; + margin: 0 8px; + } +`; + +const StyledThumbnail = styled.div` + display: flex; + justify-content: center; + align-items: center; + width: 100%; + height: 200px; + padding: 4px; + border: solid 1px #eceef1; + border-radius: 6px; + margin-bottom: 24px; + img { + max-height: 200px; + max-width: 100%; + width: auto; + height: auto; + } `; const StyledSubtitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - margin-bottom: 24px; + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + margin-bottom: 24px; `; const StyledProperties = styled.div` - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; + width: 100%; + margin-bottom: 24px; + gap: 8px; + + .property { width: 100%; - margin-bottom: 24px; - gap: 8px; + display: grid; + grid-template-columns: 110px 1fr; + grid-column-gap: 24px; - .property { - width: 100%; - display: grid; - grid-template-columns: 110px 1fr; - grid-column-gap: 24px; - - .property-title { - font-size: 13px; - color: #333333; - } - - .property-content { - display: flex; - align-items: center; - - font-weight: 600; - font-size: 13px; - color: #333333; - } + .property-title { + font-size: 13px; + color: #333333; } + + .property-content { + display: flex; + align-items: center; + + font-weight: 600; + font-size: 13px; + color: #333333; + } + } `; const StyledAccess = styled.div` - display: flex; - flex-wrap: wrap; - flex-direction: row; - gap: 8px; - align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } + display: flex; + flex-wrap: wrap; + flex-direction: row; + gap: 8px; + align-items: center; + .divider { + background: #eceef1; + margin: 2px 4px; + width: 1px; + height: 28px; + } - .show-more-users { - position: static; - width: 101px; - height: 16px; - left: 120px; - top: 8px; - - font-family: Open Sans; - font-style: normal; - font-weight: normal; - font-size: 12px; - line-height: 16px; - text-align: right; - - color: #a3a9ae; - - flex: none; - order: 3; - flex-grow: 0; - - cursor: pointer; - &:hover { - text-decoration: underline; - } - } -`; - -const StyledAccessUser = styled.div` - width: 32px; - height: 32px; - border-radius: 50%; - - a { - img { - border-radius: 50%; - width: 100%; - height: 100%; - } - } -`; - -const StyledOpenSharingPanel = styled.div` + .show-more-users { position: static; - width: auto; - height: 15px; - left: 0px; - top: 2px; + width: 101px; + height: 16px; + left: 120px; + top: 8px; font-family: Open Sans; font-style: normal; - font-weight: 600; - font-size: 13px; - line-height: 15px; + font-weight: normal; + font-size: 12px; + line-height: 16px; + text-align: right; - color: #3b72a7; + color: #a3a9ae; flex: none; - order: 0; + order: 3; flex-grow: 0; - margin: 16px 0px; cursor: pointer; &:hover { - text-decoration: underline; - text-decoration-style: dashed; + text-decoration: underline; } + } +`; + +const StyledAccessUser = styled.div` + width: 32px; + height: 32px; + border-radius: 50%; + + a { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } + } +`; + +const StyledOpenSharingPanel = styled.div` + position: static; + width: auto; + height: 15px; + left: 0px; + top: 2px; + + font-family: Open Sans; + font-style: normal; + font-weight: 600; + font-size: 13px; + line-height: 15px; + + color: #3b72a7; + + flex: none; + order: 0; + flex-grow: 0; + margin: 16px 0px; + + cursor: pointer; + &:hover { + text-decoration: underline; + text-decoration-style: dashed; + } `; export { - StyledInfoRoomBody, - StyledTitle, - StyledThumbnail, - StyledSubtitle, - StyledProperties, - StyledAccess, - StyledAccessUser, - StyledOpenSharingPanel, + StyledInfoRoomBody, + StyledTitle, + StyledThumbnail, + StyledSubtitle, + StyledProperties, + StyledAccess, + StyledAccessUser, + StyledOpenSharingPanel, }; diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index 5b6c46764f..6977cff1c9 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -12,7 +12,7 @@ class InfoPanelStore { this.showCurrentFolder = bool; }; - get showCurrenFolder() { + get showCurrentFolder() { return this.showCurrenFolder; } From bd20587a2b72d174c816c3590ee103d7243d48f4 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 22 Mar 2022 14:59:34 +0300 Subject: [PATCH 35/81] fixed context menu and added first-close-disable interaction --- .../sub-components/info-panel-header.js | 27 +++++++++++++++---- .../Client/src/HOCs/withFileActions.js | 24 +++++------------ .../Client/src/store/ContextOptionsStore.js | 17 +++++++++++- .../Client/src/store/InfoPanelStore.js | 18 +++++++++++++ products/ASC.Files/Client/src/store/index.js | 5 ++-- 5 files changed, 66 insertions(+), 25 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index cc9e86c50c..4e9399073f 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -28,7 +28,11 @@ const StyledInfoPanelHeader = styled.div` } `; -const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { +const SubInfoPanelHeader = ({ + children, + onHeaderCrossClick, + revertHeaderCrossClick, +}) => { const content = children?.props?.children; return ( @@ -36,9 +40,20 @@ const SubInfoPanelHeader = ({ children, toggleIsVisible }) => { {content} + + + { - let toggleIsVisible = () => {}; + let onHeaderCrossClick = () => {}; + let revertHeaderCrossClick = () => {}; if (infoPanelStore) { - toggleIsVisible = infoPanelStore.toggleIsVisible; + onHeaderCrossClick = infoPanelStore.onHeaderCrossClick; + revertHeaderCrossClick = infoPanelStore.revertHeaderCrossClick; } - return { toggleIsVisible }; + return { onHeaderCrossClick, revertHeaderCrossClick }; })(observer(SubInfoPanelHeader)); diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index 66dbd915b8..d676d6e4cd 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -13,16 +13,13 @@ export default function withFileActions(WrappedFileItem) { const { selectRowAction, infoPanelIsVisible, - showInfoPanel, + infoPanelonItemClick, setShowCurrentFolder, } = this.props; if (!file || file.id === -1) return; selectRowAction(checked, file); - if (!infoPanelIsVisible && isDesktop()) { - setShowCurrentFolder(false); - if (checked) showInfoPanel(); - } + infoPanelonItemClick(checked); }; fileContextClick = () => { @@ -105,8 +102,7 @@ export default function withFileActions(WrappedFileItem) { viewAs, isItemsSelected, infoPanelIsVisible, - showInfoPanel, - setShowCurrentFolder, + infoPanelonItemClick, } = this.props; if ( @@ -125,16 +121,10 @@ export default function withFileActions(WrappedFileItem) { if (viewAs === "tile") { if (e.target.closest(".edit-button") || e.target.tagName === "IMG") return; - if (e.detail === 1) this.fileContextClick(); - } else { - this.fileContextClick(); - } + } else this.fileContextClick(); - if (!infoPanelIsVisible && isDesktop()) { - setShowCurrentFolder(false); - showInfoPanel(); - } + infoPanelonItemClick(); }; onFilesClick = (e) => { @@ -276,7 +266,7 @@ export default function withFileActions(WrappedFileItem) { const { startUpload } = uploadDataStore; const { type, extension, id } = fileActionStore; - const { isVisible, setVisible, setShowCurrentFolder } = infoPanelStore; + const { isVisible, onItemClick, setShowCurrentFolder } = infoPanelStore; const selectedItem = selection.find( (x) => x.id === item.id && x.fileExst === item.fileExst @@ -344,7 +334,7 @@ export default function withFileActions(WrappedFileItem) { showHotkeyBorder, openFileAction, isInfoPanelVisible: isVisible, - showInfoPanel: setVisible, + infoPanelonItemClick: onItemClick, setShowCurrentFolder, }; } diff --git a/products/ASC.Files/Client/src/store/ContextOptionsStore.js b/products/ASC.Files/Client/src/store/ContextOptionsStore.js index 7e258cc129..a429628637 100644 --- a/products/ASC.Files/Client/src/store/ContextOptionsStore.js +++ b/products/ASC.Files/Client/src/store/ContextOptionsStore.js @@ -18,6 +18,7 @@ class ContextOptionsStore { uploadDataStore; versionHistoryStore; settingsStore; + infoPanelStore; constructor( authStore, @@ -28,7 +29,8 @@ class ContextOptionsStore { treeFoldersStore, uploadDataStore, versionHistoryStore, - settingsStore + settingsStore, + infoPanelStore ) { makeAutoObservable(this); this.authStore = authStore; @@ -40,6 +42,7 @@ class ContextOptionsStore { this.uploadDataStore = uploadDataStore; this.versionHistoryStore = versionHistoryStore; this.settingsStore = settingsStore; + this.infoPanelStore = infoPanelStore; } onOpenFolder = (item) => { @@ -331,6 +334,11 @@ class ContextOptionsStore { return options; }; + onToggleInfoPanel = () => { + const { toggleIsVisible } = this.infoPanelStore; + toggleIsVisible(); + }; + getFilesContextOptions = (item, t) => { const { contextOptions } = item; const isRootThirdPartyFolder = @@ -437,6 +445,13 @@ class ContextOptionsStore { onClick: () => this.onOpenFolder(item), disabled: false, }, + { + key: "show-info", + label: t("InfoPanel:Info"), + icon: "/static/images/info.outline.react.svg", + onClick: () => this.onToggleInfoPanel(), + disabled: false, + }, { key: "fill-form", label: t("Common:FillFormButton"), diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index 6977cff1c9..40abf3e6f1 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -1,3 +1,4 @@ +import { isDesktop } from "@appserver/components/utils/device"; import { makeAutoObservable } from "mobx"; class InfoPanelStore { @@ -12,6 +13,23 @@ class InfoPanelStore { this.showCurrentFolder = bool; }; + onItemClick = (checked = true) => { + if (localStorage.getItem("disableOpenOnFileClick")) return; + if (!this.isVisible && isDesktop()) { + this.showCurrentFolder = false; + if (checked) this.isVisible = true; + } + }; + + onHeaderCrossClick = () => { + localStorage.setItem("disableOpenOnFileClick", "true"); + this.isVisible = false; + }; + + revertHeaderCrossClick = () => { + localStorage.removeItem("disableOpenOnFileClick"); + }; + get showCurrentFolder() { return this.showCurrenFolder; } diff --git a/products/ASC.Files/Client/src/store/index.js b/products/ASC.Files/Client/src/store/index.js index dbeb346b7e..850cc5af36 100644 --- a/products/ASC.Files/Client/src/store/index.js +++ b/products/ASC.Files/Client/src/store/index.js @@ -78,7 +78,8 @@ const contextOptionsStore = new ContextOptionsStore( treeFoldersStore, uploadDataStore, versionHistoryStore, - settingsStore + settingsStore, + infoPanelStore ); const hotkeyStore = new HotkeyStore( @@ -107,4 +108,4 @@ const stores = { infoPanelStore, }; -export default stores; \ No newline at end of file +export default stores; From 1d80eb1a9d8c55b5c356197a3c6ebf8afb5d45b8 Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 24 Mar 2022 17:57:36 +0300 Subject: [PATCH 36/81] refactored open/close behaviour + redesigned checkbox header --- .../components/Navigation/Navigation.js | 4 +- .../Navigation/sub-components/control-btn.js | 14 ++-- .../sub-components/info-panel-header.js | 20 +----- .../Section/sub-components/info-panel.js | 12 +--- .../table-container/GroupMenuItem.js | 7 ++ .../table-container/StyledTableContainer.js | 30 +++++++++ .../table-container/TableGroupMenu.js | 22 ++++++- .../pages/Home/InfoPanel/Body/SingleItem.js | 16 ++--- .../src/pages/Home/InfoPanel/Body/index.js | 66 ++++++++----------- .../Home/InfoPanel/Body/styles/styles.js | 24 ++++--- .../src/pages/Home/Section/Header/index.js | 25 ++----- .../Client/src/store/FilesActionsStore.js | 9 --- .../Client/src/store/InfoPanelStore.js | 10 --- 13 files changed, 116 insertions(+), 143 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/Navigation.js b/packages/asc-web-common/components/Navigation/Navigation.js index 021dc2c5a3..13c88aeb8e 100644 --- a/packages/asc-web-common/components/Navigation/Navigation.js +++ b/packages/asc-web-common/components/Navigation/Navigation.js @@ -32,6 +32,7 @@ const Navigation = ({ clearTrash, showFolderInfo, isCurrentFolderInfo, + toggleInfoPanel, isInfoPanelVisible, ...rest }) => { @@ -137,8 +138,7 @@ const Navigation = ({ isRecycleBinFolder={isRecycleBinFolder} isEmptyFilesList={isEmptyFilesList} clearTrash={clearTrash} - showFolderInfo={showFolderInfo} - isCurrentFolderInfo={isCurrentFolderInfo} + toggleInfoPanel={toggleInfoPanel} isInfoPanelVisible={isInfoPanelVisible} /> diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index 2550ae5946..00f99cd460 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -55,9 +55,7 @@ const StyledInfoPanelToggleWrapper = styled.div` justify-content: center; border-radius: 50%; background-color: ${(props) => - props.isInfoPanelVisible && props.isCurrentFolderInfo - ? "#F8F9F9" - : "transparent"}; + props.isInfoPanelVisible ? "#F8F9F9" : "transparent"}; } `; @@ -71,9 +69,8 @@ const ControlButtons = ({ isRecycleBinFolder, isEmptyFilesList, clearTrash, - showFolderInfo, - isCurrentFolderInfo, isInfoPanelVisible, + toggleInfoPanel, }) => { return ( @@ -113,7 +110,6 @@ const ControlButtons = ({
@@ -121,11 +117,9 @@ const ControlButtons = ({ className="info-panel-toggle" iconName="images/panel.svg" size="17" - color={ - isInfoPanelVisible && isCurrentFolderInfo ? "#3B72A7" : "#A3A9AE" - } + color={isInfoPanelVisible ? "#3B72A7" : "#A3A9AE"} isFill={true} - onClick={showFolderInfo} + onClick={toggleInfoPanel} />
diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index 4e9399073f..a4279aa2d5 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -28,11 +28,7 @@ const StyledInfoPanelHeader = styled.div` } `; -const SubInfoPanelHeader = ({ - children, - onHeaderCrossClick, - revertHeaderCrossClick, -}) => { +const SubInfoPanelHeader = ({ children, onHeaderCrossClick }) => { const content = children?.props?.children; return ( @@ -41,16 +37,6 @@ const SubInfoPanelHeader = ({ {content}
- - { let onHeaderCrossClick = () => {}; - let revertHeaderCrossClick = () => {}; if (infoPanelStore) { onHeaderCrossClick = infoPanelStore.onHeaderCrossClick; - revertHeaderCrossClick = infoPanelStore.revertHeaderCrossClick; } - return { onHeaderCrossClick, revertHeaderCrossClick }; + return { onHeaderCrossClick }; })(observer(SubInfoPanelHeader)); diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 24043908a0..9e4cb896ee 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -66,14 +66,7 @@ const StyledCloseButtonWrapper = styled.div` } `; -const InfoPanel = ({ - children, - selectedItems, - isVisible, - setIsVisible, - showCurrentFolder, -}) => { - //if (!showCurrentFolder && selectedItems.length === 0) return null; +const InfoPanel = ({ children, selectedItems, isVisible, setIsVisible }) => { if (!isVisible) return null; const closeInfoPanel = () => setIsVisible(false); @@ -119,11 +112,9 @@ InfoPanel.propTypes = { export default inject(({ infoPanelStore, filesStore }) => { let selectedItems = []; let isVisible = false; - let showCurrentFolder = false; let setIsVisible = () => {}; if (infoPanelStore) { - showCurrentFolder = infoPanelStore.showCurrentFolder; isVisible = infoPanelStore.isVisible; setIsVisible = infoPanelStore.setIsVisible; } @@ -135,7 +126,6 @@ export default inject(({ infoPanelStore, filesStore }) => { return { selectedItems, isVisible, - showCurrentFolder, setIsVisible, }; })(InfoPanel); diff --git a/packages/asc-web-components/table-container/GroupMenuItem.js b/packages/asc-web-components/table-container/GroupMenuItem.js index 1af70c9332..0b7e697c8a 100644 --- a/packages/asc-web-components/table-container/GroupMenuItem.js +++ b/packages/asc-web-components/table-container/GroupMenuItem.js @@ -21,6 +21,13 @@ const StyledButton = styled(Button)` padding-right: 8px; } + .button-content { + @media ${tablet} { + flex-direction: column; + gap: 0px; + } + } + @media ${tablet} { display: flex; flex-direction: column; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 61aac0becd..27b3b4910e 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -125,6 +125,32 @@ const StyledTableGroupMenu = styled.div` StyledTableGroupMenu.defaultProps = { theme: Base }; +const StyledInfoPanelToggleWrapper = styled.div` + display: flex; + align-items: center; + align-self: center; + justify-content: center; + margin: 0 20px 0 auto; + height: 100%; + width: auto; + padding-left: 20px; + + @media ${tablet} { + margin: 0 16px 0 auto; + } + + .info-panel-toggle-bg { + height: 32px; + width: 32px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 50%; + background-color: ${(props) => + props.isInfoPanelVisible ? "#F8F9F9" : "transparent"}; + } +`; + const StyledTableHeader = styled.div` position: fixed; background: ${(props) => props.theme.tableContainer.header.background}; @@ -302,6 +328,9 @@ const StyledScrollbar = styled(Scrollbar)` .scroll-body { display: flex; } + .nav-thumb-vertical { + display: none !important; + } .nav-thumb-horizontal { ${isMobile && "display: none !important"}; } @@ -318,6 +347,7 @@ export { StyledTableCell, StyledTableSettings, StyledTableGroupMenu, + StyledInfoPanelToggleWrapper, StyledEmptyTableContainer, StyledScrollbar, }; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index 8b0317221a..dfc59e1268 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -1,10 +1,16 @@ import React from "react"; import PropTypes from "prop-types"; import Checkbox from "../checkbox"; -import { StyledTableGroupMenu, StyledScrollbar } from "./StyledTableContainer"; +import { + StyledTableGroupMenu, + StyledScrollbar, + StyledInfoPanelToggleWrapper, +} from "./StyledTableContainer"; import ComboBox from "../combobox"; import GroupMenuItem from "./GroupMenuItem"; import { useTranslation } from "react-i18next"; +import styled from "styled-components"; +import IconButton from "../icon-button"; const TableGroupMenu = (props) => { const { @@ -14,6 +20,8 @@ const TableGroupMenu = (props) => { onChange, checkboxOptions, checkboxMargin, + isInfoPanelVisible, + toggleInfoPanel, ...rest } = props; const onCheckboxChange = (e) => { @@ -51,6 +59,18 @@ const TableGroupMenu = (props) => { ))} + +
+ +
+
); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index ede2b1a1fd..c938ed0ce6 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -3,9 +3,7 @@ import { FileType } from "@appserver/common/constants"; import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; import Tooltip from "@appserver/components/tooltip"; -import { inject, observer } from "mobx-react"; import React, { useEffect, useState } from "react"; -import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; import { @@ -117,9 +115,9 @@ const SingleItem = (props) => { }; const itemSize = item.isFolder - ? `${item.foldersCount} ${t("Translations:Folders")} | ${ - item.filesCount - } ${t("Files")}` + ? `${t("Translations:Folders")}: ${item.foldersCount} | ${t( + "Translations:Files" + )}: ${item.filesCount}` : item.contentLength; const itemType = getItemType(item.fileType); @@ -417,10 +415,4 @@ const SingleItem = (props) => { ); }; -export default inject(({}) => { - return {}; -})( - withTranslation(["InfoPanel", "Home", "Common", "Translations"])( - observer(SingleItem) - ) -); +export default SingleItem; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 9d4c97a9e6..1841908def 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -5,13 +5,11 @@ import { withRouter } from "react-router"; import SeveralItems from "./SeveralItems"; import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; -import Loaders from "@appserver/common/components/Loaders"; import Loader from "@appserver/components/loader"; const InfoPanelBodyContent = ({ t, selectedItems, - bufferSelectedItem, getFolderInfo, getIcon, getFolderIcon, @@ -19,7 +17,6 @@ const InfoPanelBodyContent = ({ onSelectItem, setSharingPanelVisible, isRecycleBinFolder, - showCurrentFolder, isCommonFolder, isRecentFolder, isFavoritesFolder, @@ -38,7 +35,7 @@ const InfoPanelBodyContent = ({ contentLength = folderId.contentLength; folder.iconUrl = getIcon(32, fileExst, providerKey, contentLength); - folder.thumbnailUrl = getIcon(96, fileExst, providerKey, contentLength); + //folder.thumbnailUrl = getIcon(96, fileExst, providerKey, contentLength); folder.isFolder = true; setCurrentFolder(folder); @@ -46,16 +43,17 @@ const InfoPanelBodyContent = ({ }; useEffect(() => { - if (showCurrentFolder) getCurrentFolderInfo(); - }, [window.location.href, showCurrentFolder]); + getCurrentFolderInfo(); + }, [window.location.href]); const singleItem = (item) => { const dontShowLocation = item.isFolder && item.parentId === 0; const dontShowSize = item.isFolder && (isFavoritesFolder || isRecentFolder); const dontShowAccess = - showCurrentFolder || isRecycleBinFolder || isCommonFolder; + isRecycleBinFolder || isCommonFolder || selectedItems.length === 0; return ( - {showCurrentFolder && selectedItems.length === 0 ? ( - <> - {currentFolderLoading ? ( -
- -
- ) : ( - singleItem(currentFolder) - )} - - ) : ( - <> - {selectedItems.length === 0 && !bufferSelectedItem ? ( -
-

{t("NoItemsSelected")}

-
- ) : selectedItems.length === 1 || bufferSelectedItem ? ( - singleItem(selectedItems[0] || bufferSelectedItem) - ) : ( - - )} - - )} + <> + {selectedItems.length === 0 ? ( +
+ {currentFolderLoading ? ( +
+ +
+ ) : ( + singleItem(currentFolder) + )} +
+ ) : selectedItems.length === 1 ? ( + singleItem(selectedItems[0]) + ) : ( + + )} +
); }; @@ -109,11 +101,7 @@ export default inject( treeFoldersStore, }) => { const selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); - const bufferSelectedItem = JSON.parse( - JSON.stringify(filesStore.bufferSelection) - ); - const { showCurrentFolder } = infoPanelStore; const { getFolderInfo, getShareUsers } = filesStore; const { getIcon, getFolderIcon } = settingsStore; const { onSelectItem } = filesActionsStore; @@ -126,7 +114,6 @@ export default inject( } = treeFoldersStore; return { - bufferSelectedItem, selectedItems, getFolderInfo, getShareUsers, @@ -136,9 +123,14 @@ export default inject( setSharingPanelVisible, isRecycleBinFolder, isCommonFolder, - showCurrentFolder, isRecentFolder, isFavoritesFolder, }; } -)(withRouter(withTranslation(["InfoPanel"])(observer(InfoPanelBodyContent)))); +)( + withRouter( + withTranslation(["InfoPanel", "Home", "Common", "Translations"])( + observer(InfoPanelBodyContent) + ) + ) +); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index 75b43e9b65..27e5b94899 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -1,8 +1,9 @@ import styled from "styled-components"; const StyledInfoRoomBody = styled.div` - padding: 0px 16px 16px; - height: 100%; + padding: 0px 0px 0 16px; + height: auto; + //margin-right: -16px; .no-item { text-align: center; } @@ -21,11 +22,10 @@ const StyledInfoRoomBody = styled.div` .current-folder-loader-wrapper { width: 100%; - height: 100%; display: flex; justify-content: center; - align-items: center; - margin-top: auto; + height: 96px; + margin-top: 116.56px; } `; @@ -55,17 +55,17 @@ const StyledThumbnail = styled.div` display: flex; justify-content: center; align-items: center; - width: 100%; + width: calc(100% + 6px -16px); height: 200px; padding: 4px; border: solid 1px #eceef1; border-radius: 6px; - margin-bottom: 24px; + margin: 0 0 24px 0; img { - max-height: 200px; - max-width: 100%; + height: 100%; width: auto; - height: auto; + max-height: auto; + max-width: 100%; } `; @@ -175,9 +175,7 @@ const StyledOpenSharingPanel = styled.div` color: #3b72a7; - flex: none; - order: 0; - flex-grow: 0; + display: flex; margin: 16px 0px; cursor: pointer; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index e384908a62..4b17cac2c9 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -202,15 +202,6 @@ class SectionHeaderContent extends React.Component { }; onEmptyTrashAction = () => this.props.setEmptyTrashDialogVisible(true); - showFolderInfo = () => { - if (this.props.showCurrentFolder && this.props.isInfoPanelVisible) { - this.props.setShowCurrentFolder(false); - this.props.setIsInfoPanelVisible(false); - return; - } - this.props.setShowCurrentFolder(true); - this.props.setIsInfoPanelVisible(true); - }; getContextOptionsFolder = () => { const { t, personal } = this.props; @@ -357,6 +348,8 @@ class SectionHeaderContent extends React.Component { isChecked={isHeaderChecked} isIndeterminate={isHeaderIndeterminate} headerMenu={headerMenu} + isInfoPanelVisible={this.props.isInfoPanelVisible} + toggleInfoPanel={this.props.toggleInfoPanel} /> ) : (
@@ -383,8 +376,7 @@ class SectionHeaderContent extends React.Component { isEmptyFilesList={isEmptyFilesList} clearTrash={this.onEmptyTrashAction} onBackToParentFolder={this.onBackToParentFolder} - showFolderInfo={this.showFolderInfo} - isCurrentFolderInfo={this.props.showCurrentFolder} + toggleInfoPanel={this.props.toggleInfoPanel} isInfoPanelVisible={this.props.isInfoPanelVisible} /> )} @@ -445,12 +437,7 @@ export default inject( backToParentFolder, } = filesActionsStore; - const { - showCurrentFolder, - setShowCurrentFolder, - setIsVisible, - isVisible, - } = infoPanelStore; + const { toggleIsVisible, isVisible } = infoPanelStore; return { showText: auth.settingsStore.showText, @@ -461,10 +448,8 @@ export default inject( pathParts: selectedFolderStore.pathParts, navigationPath: selectedFolderStore.navigationPath, canCreate, - setIsInfoPanelVisible: setIsVisible, + toggleInfoPanel: toggleIsVisible, isInfoPanelVisible: isVisible, - showCurrentFolder, - setShowCurrentFolder, isHeaderVisible, isHeaderIndeterminate, isHeaderChecked, diff --git a/products/ASC.Files/Client/src/store/FilesActionsStore.js b/products/ASC.Files/Client/src/store/FilesActionsStore.js index 9ca643d568..c4b4031219 100644 --- a/products/ASC.Files/Client/src/store/FilesActionsStore.js +++ b/products/ASC.Files/Client/src/store/FilesActionsStore.js @@ -887,15 +887,6 @@ class FilesActionStore { iconUrl: "/static/images/move.react.svg", }; - case "showInfo": - if (!this.isAvailableOption("showInfo")) return null; - else - return { - label: t("InfoPanel:Info"), - onClick: () => toggleIsVisible(), - iconUrl: "/static/images/info.outline.react.svg", - }; - case "delete": if (!this.isAvailableOption("delete")) return null; else diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index 40abf3e6f1..390da8d338 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -3,20 +3,14 @@ import { makeAutoObservable } from "mobx"; class InfoPanelStore { isVisible = false; - showCurrentFolder = false; constructor() { makeAutoObservable(this); } - setShowCurrentFolder = (bool) => { - this.showCurrentFolder = bool; - }; - onItemClick = (checked = true) => { if (localStorage.getItem("disableOpenOnFileClick")) return; if (!this.isVisible && isDesktop()) { - this.showCurrentFolder = false; if (checked) this.isVisible = true; } }; @@ -30,10 +24,6 @@ class InfoPanelStore { localStorage.removeItem("disableOpenOnFileClick"); }; - get showCurrentFolder() { - return this.showCurrenFolder; - } - toggleIsVisible = () => { this.isVisible = !this.isVisible; }; From 9de69a3ff609d12cab598441efc71375194737b2 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 25 Mar 2022 12:10:23 +0300 Subject: [PATCH 37/81] some tweaks --- .../components/FilterInput/index.js | 176 +++++++++--------- .../Navigation/sub-components/control-btn.js | 2 +- .../table-container/GroupMenuItem.js | 5 +- .../table-container/TableGroupMenu.js | 2 +- .../pages/Home/InfoPanel/Body/SeveralItems.js | 39 ++-- .../pages/Home/InfoPanel/Body/SingleItem.js | 117 +++++++----- 6 files changed, 188 insertions(+), 153 deletions(-) diff --git a/packages/asc-web-common/components/FilterInput/index.js b/packages/asc-web-common/components/FilterInput/index.js index 034fd0bfcb..5a94aa689b 100644 --- a/packages/asc-web-common/components/FilterInput/index.js +++ b/packages/asc-web-common/components/FilterInput/index.js @@ -13,103 +13,105 @@ import SortButton from "./sub-components/SortButton"; import { StyledFilterInput, StyledSearchInput } from "./StyledFilterInput"; -const FilterInput = ({ - t, - sectionWidth, - getFilterData, - getSortData, - getViewSettingsData, - getSelectedFilterData, - onFilter, - onSearch, - onSort, - onChangeViewAs, - viewAs, - placeholder, - contextMenuHeader, - headerLabel, - viewSelectorVisible, - isRecentFolder, - isFavoritesFolder, - ...props -}) => { - const [viewSettings, setViewSettings] = React.useState([]); - const [selectedFilterData, setSelectedFilterData] = React.useState([]); +const FilterInput = React.memo( + ({ + t, + sectionWidth, + getFilterData, + getSortData, + getViewSettingsData, + getSelectedFilterData, + onFilter, + onSearch, + onSort, + onChangeViewAs, + viewAs, + placeholder, + contextMenuHeader, + headerLabel, + viewSelectorVisible, + isRecentFolder, + isFavoritesFolder, + ...props + }) => { + const [viewSettings, setViewSettings] = React.useState([]); + const [selectedFilterData, setSelectedFilterData] = React.useState([]); - const [inputValue, setInputValue] = React.useState(""); + const [inputValue, setInputValue] = React.useState(""); - const getSelectedFilterDataAction = React.useCallback(async () => { - const data = await getSelectedFilterData(); + const getSelectedFilterDataAction = React.useCallback(async () => { + const data = await getSelectedFilterData(); - setSelectedFilterData(data); - setInputValue(!!data.inputValue ? data.inputValue : ""); - }, [getSelectedFilterData]); + setSelectedFilterData(data); + setInputValue(!!data.inputValue ? data.inputValue : ""); + }, [getSelectedFilterData]); - React.useEffect(() => { - getSelectedFilterDataAction(); - }, [getSelectedFilterData]); + React.useEffect(() => { + getSelectedFilterDataAction(); + }, [getSelectedFilterData]); - React.useEffect(() => { - getViewSettingsData && setViewSettings(getViewSettingsData()); - }, [getViewSettingsData]); + React.useEffect(() => { + getViewSettingsData && setViewSettings(getViewSettingsData()); + }, [getViewSettingsData]); - const onClearSearch = () => { - onSearch && onSearch(); - }; + const onClearSearch = () => { + onSearch && onSearch(); + }; - return ( - - - - - - {viewSettings && - !isMobile && - viewSelectorVisible && - !isMobileUtils() && - !isTabletUtils() ? ( - + - ) : ( - <> - {(isMobile || isTabletUtils() || isMobileUtils()) && ( - - )} - - )} - - ); -}; + + + + {viewSettings && + !isMobile && + viewSelectorVisible && + !isMobileUtils() && + !isTabletUtils() ? ( + + ) : ( + <> + {(isMobile || isTabletUtils() || isMobileUtils()) && ( + + )} + + )} + + ); + } +); FilterInput.defaultProps = { viewSelectorVisible: false, }; -export default React.memo(FilterInput); +export default FilterInput; diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index 00f99cd460..0ed48ec807 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -116,7 +116,7 @@ const ControlButtons = ({ { { - const { t, selectedItems, getIcon, getFolderInfo } = props; - const itemsIcon = getIcon(24, ".file"); + const { t, selectedItems, getIcon, getFolderInfo } = props; + const itemsIcon = getIcon(24, ".file"); - return ( - <> - - - - {`${t("ItemsSelected")}: ${selectedItems.length}`} - - + return ( + <> + + + + {`${t("ItemsSelected")}: ${selectedItems.length}`} + + -
- -
- - ); +
+ +
+ + ); }; export default inject(({}) => { - return {}; + return {}; })(withTranslation(["InfoPanel"])(observer(SeveralItems))); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index c938ed0ce6..b0aac16ef4 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -17,7 +17,7 @@ import { } from "./styles/styles.js"; const SingleItem = (props) => { - const { + let { t, selectedItem, onSelectItem, @@ -47,6 +47,7 @@ const SingleItem = (props) => { others: [], }, }); + const [showAccess, setShowAccess] = useState(false); const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); const updateItemsInfo = async (selectedItem) => { @@ -218,52 +219,79 @@ const SingleItem = (props) => { ? selectedItem.parentId : selectedItem.folderId; - const folderInfo = await getFolderInfo(parentFolderId); - - return [...displayedItem.properties].map((dip) => - dip.id === "Location" - ? { - id: "Location", - title: t("Location"), - content: ( - - {folderInfo.title} - - ), - } - : dip + const noLocationProperties = [...displayedItem.properties].filter( + (dip) => dip.id !== "Location" ); + + let result; + await getFolderInfo(parentFolderId) + .catch(() => { + result = noLocationProperties; + }) + .then((data) => { + if (!data) { + result = noLocationProperties; + return; + } + result = [...displayedItem.properties].map((dip) => + dip.id === "Location" + ? { + id: "Location", + title: t("Location"), + content: ( + + {data.title} + + ), + } + : dip + ); + }); + + return result; }; const updateLoadedItemAccess = async (selectedItem) => { - const accesses = await getShareUsers( - [selectedItem.folderId], - [selectedItem.id] - ); + const parentFolderId = selectedItem.isFolder + ? selectedItem.parentId + : selectedItem.folderId; - const result = { - owner: {}, - others: [], - }; + let result; + await getShareUsers([parentFolderId], [selectedItem.id]) + .catch((e) => { + setShowAccess(false); + }) + .then((accesses) => { + if (!accesses) { + setShowAccess(false); + return; + } + const accessResult = { + owner: {}, + others: [], + }; - accesses.forEach((access) => { - const user = access.sharedTo; - const userData = { - key: user.id, - img: user.avatarSmall, - link: user.profileUrl, - name: user.displayName, - email: user.email, - }; + accesses.forEach((access) => { + const user = access.sharedTo; + const userData = { + key: user.id, + img: user.avatarSmall, + link: user.profileUrl, + name: user.displayName, + email: user.email, + }; - if (access.isOwner) result.owner = userData; - else if (userData.email !== undefined) result.others.push(userData); - }); + if (access.isOwner) accessResult.owner = userData; + else if (userData.email !== undefined) + accessResult.others.push(userData); + }); + result = accessResult; + }); return result; }; @@ -273,14 +301,18 @@ const SingleItem = (props) => { ); let access; - if (!dontShowAccess) access = await updateLoadedItemAccess(selectedItem); + if (!dontShowAccess) { + access = await updateLoadedItemAccess(selectedItem); + } - if (updateSubscription) + if (updateSubscription) { setItem({ ...displayedItem, properties: properties, access: access, }); + if (access) setShowAccess(true); + } }; const showAllAccessUsers = () => { @@ -289,7 +321,6 @@ const SingleItem = (props) => { const openSharingPanel = () => { const { id, isFolder } = item; - console.log(id, isFolder); onSelectItem({ id, isFolder }); setSharingPanelVisible(true); }; @@ -338,7 +369,7 @@ const SingleItem = (props) => { })} - {!dontShowAccess && ( + {showAccess && ( <> From ae33a464e3712027c90464a1457bbfdc81d1f01e Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 25 Mar 2022 17:04:55 +0300 Subject: [PATCH 38/81] removed onFileClick action --- .../Client/src/HOCs/withFileActions.js | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index d676d6e4cd..e96680051a 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -1,7 +1,6 @@ import React from "react"; import { inject, observer } from "mobx-react"; import { isMobile } from "react-device-detect"; -import { isDesktop } from "@appserver/components/utils/device"; export default function withFileActions(WrappedFileItem) { class WithFileActions extends React.Component { @@ -10,16 +9,9 @@ export default function withFileActions(WrappedFileItem) { } onContentFileSelect = (checked, file) => { - const { - selectRowAction, - infoPanelIsVisible, - infoPanelonItemClick, - setShowCurrentFolder, - } = this.props; + const { selectRowAction } = this.props; if (!file || file.id === -1) return; selectRowAction(checked, file); - - infoPanelonItemClick(checked); }; fileContextClick = () => { @@ -98,12 +90,7 @@ export default function withFileActions(WrappedFileItem) { }; onMouseClick = (e) => { - const { - viewAs, - isItemsSelected, - infoPanelIsVisible, - infoPanelonItemClick, - } = this.props; + const { viewAs } = this.props; if ( e.target.tagName === "INPUT" || @@ -123,8 +110,6 @@ export default function withFileActions(WrappedFileItem) { return; if (e.detail === 1) this.fileContextClick(); } else this.fileContextClick(); - - infoPanelonItemClick(); }; onFilesClick = (e) => { @@ -229,7 +214,6 @@ export default function withFileActions(WrappedFileItem) { //selectedFolderStore, filesStore, uploadDataStore, - infoPanelStore, settingsStore, contextOptionsStore, }, @@ -266,7 +250,6 @@ export default function withFileActions(WrappedFileItem) { const { startUpload } = uploadDataStore; const { type, extension, id } = fileActionStore; - const { isVisible, onItemClick, setShowCurrentFolder } = infoPanelStore; const selectedItem = selection.find( (x) => x.id === item.id && x.fileExst === item.fileExst @@ -333,8 +316,6 @@ export default function withFileActions(WrappedFileItem) { getModel: contextOptionsStore.getModel, showHotkeyBorder, openFileAction, - isInfoPanelVisible: isVisible, - infoPanelonItemClick: onItemClick, setShowCurrentFolder, }; } From cd22e7da4141ccd45b98034d6f975681a9a3e338 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 25 Mar 2022 17:09:24 +0300 Subject: [PATCH 39/81] fixed withFileActions bug --- products/ASC.Files/Client/src/HOCs/withFileActions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/products/ASC.Files/Client/src/HOCs/withFileActions.js b/products/ASC.Files/Client/src/HOCs/withFileActions.js index e96680051a..257365b2d4 100644 --- a/products/ASC.Files/Client/src/HOCs/withFileActions.js +++ b/products/ASC.Files/Client/src/HOCs/withFileActions.js @@ -316,7 +316,6 @@ export default function withFileActions(WrappedFileItem) { getModel: contextOptionsStore.getModel, showHotkeyBorder, openFileAction, - setShowCurrentFolder, }; } )(observer(WithFileActions)); From b0dd8d1077770dc11483c323fb9fce5f0ee475ad Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 25 Mar 2022 18:58:07 +0300 Subject: [PATCH 40/81] fixed content gaps and deleted loaders --- .../InfoPanelLoader/InfoPanelLoader.js | 109 ---------------- .../InfoPanelLoader/StyledInfoPanelLoader.js | 117 ------------------ .../Loaders/InfoPanelLoader/index.js | 1 - .../components/Loaders/index.js | 2 - .../sub-components/info-panel-header.js | 7 +- .../Section/sub-components/info-panel.js | 5 +- .../Home/InfoPanel/Body/styles/styles.js | 8 +- .../src/pages/Home/InfoPanel/Header/index.js | 7 +- 8 files changed, 11 insertions(+), 245 deletions(-) delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js delete mode 100644 packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js deleted file mode 100644 index e6b95c643f..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/InfoPanelLoader.js +++ /dev/null @@ -1,109 +0,0 @@ -import PropTypes from "prop-types"; -import React from "react"; - -import RectangleLoader from "../RectangleLoader"; -import { - StyledAccessRow, - StyledInfoRoomBody, - StyledPropertiesTable, - StyledPropertyRow, - StyledSubtitle, - StyledThumbnail, - StyledTitle, -} from "./StyledInfoPanelLoader"; - -const InfoPanelLoader = ({ - id, - className, - style, - isFolder, - hasThumbnail, - ...rest -}) => { - const {} = rest; - - const randomNumber = (min, max) => Math.random() * (max - min) + min; - - const customRectangleLoader = (width, height, rounded) => ( - - ); - - const properties = isFolder - ? [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - ] - : [ - { Owner: 19 }, - { Location: 19 }, - { Type: 17.6 }, - { "File Extension": 17.6 }, - { Size: 17.6 }, - { "Date modified": 17.6 }, - { "Last modified by": 19 }, - { "Date creation": 17.6 }, - { Versions: 17.6 }, - { Comments: 17.6 }, - ]; - - return ( - - - {customRectangleLoader(32, 32, 3)} - {customRectangleLoader(250, 22)} - - - System Properties - - {hasThumbnail ? ( - {customRectangleLoader(320.2, 200)} - ) : ( - {customRectangleLoader(96, 96)} - )} - - - {properties.map((property) => ( - -
{Object.keys(property)[0]}
- {customRectangleLoader( - randomNumber(125, 150), - Object.values(property)[0] - )} -
- ))} -
- - Who has access - - - {customRectangleLoader(32, 32, 16)} -
- {customRectangleLoader(32, 32, 16)} - {customRectangleLoader(32, 32, 16)} -
-
- ); -}; - -InfoPanelLoader.propTypes = { - id: PropTypes.string, - className: PropTypes.string, - style: PropTypes.object, -}; - -InfoPanelLoader.defaultProps = { - id: undefined, - className: undefined, - style: undefined, -}; - -export default InfoPanelLoader; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js deleted file mode 100644 index 24c2e803fd..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/StyledInfoPanelLoader.js +++ /dev/null @@ -1,117 +0,0 @@ -import styled from "styled-components"; - -const StyledInfoRoomBody = styled.div` - .no-thumbnail-img-wrapper { - padding: 9px 0 34px; - height: auto; - width: 100%; - display: flex; - justify-content: center; - .no-thumbnail-img { - height: 96px; - width: 96px; - } - } -`; - -const StyledTitle = styled.div` - display: flex; - flex-direction: row; - align-items: center; - width: 100%; - height: 80px; - gap: 8px; -`; - -const StyledThumbnail = styled.div` - display: flex; - justify-content: center; - align-items: center; - width: 100%; - height: 200px; - padding: 4px; - border: solid 1px #eceef1; - border-radius: 6px; - margin-bottom: 24px; -`; - -const StyledSubtitle = styled.div` - margin-bottom: 24px; - height: 19.2px; - font-weight: 600; - font-size: 14px; - color: #000000; -`; - -const StyledPropertiesTable = styled.div` - display: flex; - flex-direction: column; - width: 100%; - margin-bottom: 24px; - gap: 8px; -`; - -const StyledPropertyRow = styled.div` - width: 100%; - display: grid; - grid-template-columns: 110px 1fr; - grid-column-gap: 24px; - - .property-title { - font-size: 13px; - color: #333333; - } -`; - -const StyledAccessRow = styled.div` - width: 100%; - height: 32px; - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } -`; - -export { - StyledInfoRoomBody, - StyledSubtitle, - StyledTitle, - StyledThumbnail, - StyledPropertiesTable, - StyledPropertyRow, - StyledAccessRow, -}; - -const StyledItemAccess = styled.div` - display: flex; - flex-direction: row; - gap: 8px; - align-items: center; - .divider { - background: #eceef1; - margin: 2px 4px; - width: 1px; - height: 28px; - } -`; - -const StyleditemAccessUser = styled.div` - width: 32px; - height: 32px; - border-radius: 50%; - - a { - img { - border-radius: 50%; - width: 100%; - height: 100%; - } - } -`; diff --git a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js b/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js deleted file mode 100644 index ed427373f5..0000000000 --- a/packages/asc-web-common/components/Loaders/InfoPanelLoader/index.js +++ /dev/null @@ -1 +0,0 @@ -export default from "./InfoPanelLoader"; diff --git a/packages/asc-web-common/components/Loaders/index.js b/packages/asc-web-common/components/Loaders/index.js index 965512412d..75373943ef 100644 --- a/packages/asc-web-common/components/Loaders/index.js +++ b/packages/asc-web-common/components/Loaders/index.js @@ -20,7 +20,6 @@ import Tile from "./TileLoader"; import Tiles from "./TilesLoader"; import DialogLoader from "./DialogLoader"; import DialogAsideLoader from "./DialogAsideLoader"; -import InfoPanelLoader from "./InfoPanelLoader"; import ListLoader from "./ListLoader"; export default { @@ -46,6 +45,5 @@ export default { ArticleButton, ArticleFolder, ArticleGroup, - InfoPanelLoader, ListLoader, }; diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index a4279aa2d5..7d734dc0be 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -9,15 +9,16 @@ import styled from "styled-components"; const StyledInfoPanelHeader = styled.div` width: 100%; max-width: 100%; - height: 52px; + height: 53px; + min-height: 53px; + box-sizing: border-box; display: flex; justify-content: space-between; align-items: center; - padding: 8px 0; border-bottom: 1px solid #eceef1; .header-text { - margin-left: 16px; + margin-left: 20px; } .close-btn { diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 9e4cb896ee..85a6cb169a 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -1,6 +1,5 @@ import IconButton from "@appserver/components/icon-button"; import { isTablet, mobile, tablet } from "@appserver/components/utils/device"; -import { set } from "mobx"; import { inject } from "mobx-react"; import PropTypes from "prop-types"; import React, { useEffect } from "react"; @@ -26,7 +25,7 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ const StyledInfoPanel = styled.div` height: 100%; - width: 368px; + width: 400px; background-color: #ffffff; border-left: 1px solid #eceef1; display: flex; @@ -36,7 +35,7 @@ const StyledInfoPanel = styled.div` position: absolute; border: none; right: 0; - width: 448px; + width: 480px; max-width: calc(100vw - 69px); } diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index 27e5b94899..7a1fbbe7e3 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -9,7 +9,6 @@ const StyledInfoRoomBody = styled.div` } .no-thumbnail-img-wrapper { - padding: 9px 0 34px; height: auto; width: 100%; display: flex; @@ -35,7 +34,7 @@ const StyledTitle = styled.div` align-items: center; width: 100%; height: auto; - padding: 24px 0; + padding: 29px 0; .icon { svg { @@ -74,20 +73,19 @@ const StyledSubtitle = styled.div` flex-direction: row; align-items: center; width: 100%; - margin-bottom: 24px; + padding: 24px 0; `; const StyledProperties = styled.div` display: flex; flex-direction: column; width: 100%; - margin-bottom: 24px; gap: 8px; .property { width: 100%; display: grid; - grid-template-columns: 110px 1fr; + grid-template-columns: 150px 1fr; grid-column-gap: 24px; .property-title { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js index 5e2140a88a..09ab3e8913 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Header/index.js @@ -1,11 +1,8 @@ -import { inject } from "mobx-react"; import React from "react"; import { withTranslation } from "react-i18next"; const InfoPanelHeaderContent = ({ t }) => { - return <>{t("Info")}; + return <>{t("Info")}; }; -export default inject(({}) => { - return {}; -})(withTranslation(["InfoPanel"])(InfoPanelHeaderContent)); +export default withTranslation(["InfoPanel"])(InfoPanelHeaderContent); From 05fe1a8cb9ccca98dab6c95372773abbfd24c50f Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 11:14:48 +0300 Subject: [PATCH 41/81] removed unused InfoPanelStore methods --- .../Client/src/store/InfoPanelStore.js | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/products/ASC.Files/Client/src/store/InfoPanelStore.js b/products/ASC.Files/Client/src/store/InfoPanelStore.js index 390da8d338..e02d4f9b85 100644 --- a/products/ASC.Files/Client/src/store/InfoPanelStore.js +++ b/products/ASC.Files/Client/src/store/InfoPanelStore.js @@ -1,4 +1,3 @@ -import { isDesktop } from "@appserver/components/utils/device"; import { makeAutoObservable } from "mobx"; class InfoPanelStore { @@ -8,22 +7,10 @@ class InfoPanelStore { makeAutoObservable(this); } - onItemClick = (checked = true) => { - if (localStorage.getItem("disableOpenOnFileClick")) return; - if (!this.isVisible && isDesktop()) { - if (checked) this.isVisible = true; - } - }; - onHeaderCrossClick = () => { - localStorage.setItem("disableOpenOnFileClick", "true"); this.isVisible = false; }; - revertHeaderCrossClick = () => { - localStorage.removeItem("disableOpenOnFileClick"); - }; - toggleIsVisible = () => { this.isVisible = !this.isVisible; }; @@ -35,10 +22,6 @@ class InfoPanelStore { setIsVisible = (bool) => { this.isVisible = bool; }; - - get isVisible() { - return this.isVisible; - } } export default InfoPanelStore; From 8df40dbca7352671960852487d600b0a749eb5dd Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 12:01:12 +0300 Subject: [PATCH 42/81] changed dateTime format to vary with language settings --- .../pages/Home/InfoPanel/Body/SeveralItems.js | 5 +--- .../pages/Home/InfoPanel/Body/SingleItem.js | 24 +++++-------------- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js index 1ed2a04a6c..5b79344972 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SeveralItems.js @@ -1,5 +1,4 @@ import Text from "@appserver/components/text"; -import { inject, observer } from "mobx-react"; import React from "react"; import { withTranslation } from "react-i18next"; import { ReactSVG } from "react-svg"; @@ -30,6 +29,4 @@ const SeveralItems = (props) => { ); }; -export default inject(({}) => { - return {}; -})(withTranslation(["InfoPanel"])(observer(SeveralItems))); +export default withTranslation(["InfoPanel"])(SeveralItems); diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index b0aac16ef4..6a2a8b24c3 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -1,5 +1,8 @@ import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; import { FileType } from "@appserver/common/constants"; +import { LANGUAGE } from "@appserver/common/constants"; +const moment = require("moment"); + import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; import Tooltip from "@appserver/components/tooltip"; @@ -72,24 +75,9 @@ const SingleItem = (props) => { ); const parseAndFormatDate = (date) => { - date = new Date(date); - - const normalize = (num) => { - if (num > 9) return num; - return `0${num}`; - }; - - let day = normalize(date.getDate()), - month = normalize(date.getMonth()), - year = date.getFullYear(), - hours = date.getHours(), - minutes = normalize(date.getMinutes()), - a_p = hours > 12 ? "AM" : "PM"; - - if (hours === 0) hours = 12; - else if (hours > 12) hours = hours - 12; - - return `${day}.${month}.${year} ${hours}:${minutes} ${a_p}`; + return moment(date) + .locale(localStorage.getItem(LANGUAGE)) + .format("DD.MM.YY hh:mm A"); }; const getItemType = (fileType) => { From 5bec92e1903bc945cd176682d56bbf7d05f2cafd Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 12:33:57 +0300 Subject: [PATCH 43/81] fixed read-only section header button positioning --- .../Navigation/sub-components/control-btn.js | 46 +++++++++++-------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index 0ed48ec807..5b23e272af 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -74,19 +74,40 @@ const ControlButtons = ({ }) => { return ( - {canCreate && ( + {!isRootFolder && canCreate ? ( + <> + + {!personal && ( + + )} + + ) : canCreate ? ( - )} - - {isRecycleBinFolder && !isEmptyFilesList && ( + ) : isRecycleBinFolder && !isEmptyFilesList ? ( + ) : ( + <> )} - - {!isRootFolder && !personal && ( - - )} - Date: Mon, 28 Mar 2022 12:44:35 +0300 Subject: [PATCH 44/81] tweaked getting selection, removed unused code --- .../components/Section/sub-components/info-panel.js | 10 ++-------- .../Client/src/pages/Home/InfoPanel/Body/index.js | 7 ++----- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 85a6cb169a..1a0a2752e7 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -65,7 +65,7 @@ const StyledCloseButtonWrapper = styled.div` } `; -const InfoPanel = ({ children, selectedItems, isVisible, setIsVisible }) => { +const InfoPanel = ({ children, isVisible, setIsVisible }) => { if (!isVisible) return null; const closeInfoPanel = () => setIsVisible(false); @@ -108,8 +108,7 @@ InfoPanel.propTypes = { isVisible: PropTypes.bool, }; -export default inject(({ infoPanelStore, filesStore }) => { - let selectedItems = []; +export default inject(({ infoPanelStore }) => { let isVisible = false; let setIsVisible = () => {}; @@ -118,12 +117,7 @@ export default inject(({ infoPanelStore, filesStore }) => { setIsVisible = infoPanelStore.setIsVisible; } - if (filesStore) { - selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); - } - return { - selectedItems, isVisible, setIsVisible, }; diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 1841908def..64ebe4d46a 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -93,16 +93,13 @@ const InfoPanelBodyContent = ({ export default inject( ({ - infoPanelStore, filesStore, settingsStore, filesActionsStore, dialogsStore, treeFoldersStore, }) => { - const selectedItems = JSON.parse(JSON.stringify(filesStore.selection)); - - const { getFolderInfo, getShareUsers } = filesStore; + const { selection, getFolderInfo, getShareUsers } = filesStore; const { getIcon, getFolderIcon } = settingsStore; const { onSelectItem } = filesActionsStore; const { setSharingPanelVisible } = dialogsStore; @@ -114,7 +111,7 @@ export default inject( } = treeFoldersStore; return { - selectedItems, + selectedItems: selection, getFolderInfo, getShareUsers, getIcon, From 8e76326f08d86f71b84dce1887087b547c7aa634 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 12:49:01 +0300 Subject: [PATCH 45/81] minor tweaks --- .../components/Section/sub-components/info-panel-body.js | 5 +---- .../components/Section/sub-components/section-body.js | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-body.js b/packages/asc-web-common/components/Section/sub-components/info-panel-body.js index 6e9e8b06eb..918caefd6b 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-body.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-body.js @@ -1,5 +1,4 @@ import Scrollbar from "@appserver/components/scrollbar"; -import { inject, observer } from "mobx-react"; import React from "react"; const SubInfoPanelBody = ({ children }) => { @@ -14,6 +13,4 @@ const SubInfoPanelBody = ({ children }) => { SubInfoPanelBody.displayName = "SubInfoPanelBody"; -export default inject(() => { - return {}; -})(observer(SubInfoPanelBody)); +export default SubInfoPanelBody; 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 25e7aca016..0d6e855576 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 @@ -45,9 +45,6 @@ const commonStyles = css` .section-wrapper-content { ${paddingStyles} flex: 1 0 auto; - //display: flex; - //flex-direction: row; - padding-right: 0; outline: none; ${(props) => From 5accb9ba8e2f83b9602700fe5b079f8c05de19f6 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 16:45:17 +0300 Subject: [PATCH 46/81] fixed SectionHeader and CheckboxMenu differenciation --- .../components/Navigation/StyledNavigation.js | 33 ++++--------------- .../table-container/StyledTableContainer.js | 2 +- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/StyledNavigation.js b/packages/asc-web-common/components/Navigation/StyledNavigation.js index a357b984b6..f22b796854 100644 --- a/packages/asc-web-common/components/Navigation/StyledNavigation.js +++ b/packages/asc-web-common/components/Navigation/StyledNavigation.js @@ -3,45 +3,26 @@ import { isMobile, isMobileOnly } from "react-device-detect"; import { tablet, desktop, mobile } from "@appserver/components/utils/device"; const StyledContainer = styled.div` - padding: ${(props) => (props.isDropBox ? "14px 0 3px" : "14px 0 0px")}; - - width: 100%; - + width: 100% !important; display: grid; - + align-items: center; grid-template-columns: ${(props) => props.isRootFolder ? "auto 1fr" : "29px auto 1fr"}; - align-items: center; - .arrow-button { width: 17px; min-width: 17px; } - @media ${tablet} { - width: 100%; - padding: ${(props) => (props.isDropBox ? "16px 0 5px" : "16px 0 0px")}; - } + height: 53px; - ${isMobile && - css` - width: 100% !important; - padding: ${(props) => - props.isDropBox ? "16px 0 5px" : " 16px 0 0px"} !important; - `} + @media ${tablet} { + height: 61px; + } @media ${mobile} { - width: 100%; - padding: ${(props) => (props.isDropBox ? "12px 0 5px" : "12px 0 0")}; + height: 53px; } - - ${isMobileOnly && - css` - width: 100% !important; - padding: ${(props) => - props.isDropBox ? "12px 0 5px" : "12px 0 0"} !important; - `} `; export default StyledContainer; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 27b3b4910e..03c9b76605 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -79,7 +79,7 @@ const StyledTableGroupMenu = styled.div` align-items: center; width: 100%; z-index: 199; - height: 52px; + height: 53px; box-shadow: ${(props) => props.theme.tableContainer.groupMenu.boxShadow}; border-radius: 0px 0px 6px 6px; margin: 0; From 5a4b36df74f63faffc8a50c2e29dabe484a9507f Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 28 Mar 2022 16:53:27 +0300 Subject: [PATCH 47/81] translation tweaks --- .../Client/public/locales/en/InfoPanel.json | 24 +++++++++---------- .../Client/public/locales/ru/InfoPanel.json | 24 +++++++++---------- 2 files changed, 22 insertions(+), 26 deletions(-) diff --git a/products/ASC.Files/Client/public/locales/en/InfoPanel.json b/products/ASC.Files/Client/public/locales/en/InfoPanel.json index f55a481aef..19fb071aae 100644 --- a/products/ASC.Files/Client/public/locales/en/InfoPanel.json +++ b/products/ASC.Files/Client/public/locales/en/InfoPanel.json @@ -1,16 +1,14 @@ { - "Info": "Info", - "NoItemsSelected": "Select one or more items to display their info", - "ItemsSelected": "Items selected", - "SystemProperties": "System properties", - "WhoHasAccess": "Who has access", - "Members": "members", - "OpenSharingSettings": "Open sharing settings", + "Info": "Info", + "ItemsSelected": "Items selected", + "SystemProperties": "System properties", + "WhoHasAccess": "Who has access", + "Members": "members", + "OpenSharingSettings": "Open sharing settings", - "Location": "Location", - "FileExtension": "File extension", - "LastModifiedBy": "Last modified by", - "Versions": "Versions", - "Files": "Files", - "Comments": "Comments" + "Location": "Location", + "FileExtension": "File extension", + "LastModifiedBy": "Last modified by", + "Versions": "Versions", + "Comments": "Comments" } diff --git a/products/ASC.Files/Client/public/locales/ru/InfoPanel.json b/products/ASC.Files/Client/public/locales/ru/InfoPanel.json index 90f8373dfc..4302f0935a 100644 --- a/products/ASC.Files/Client/public/locales/ru/InfoPanel.json +++ b/products/ASC.Files/Client/public/locales/ru/InfoPanel.json @@ -1,16 +1,14 @@ { - "Info": "Информация", - "NoItemsSelected": "Выберите один или несколько элементов, чтобы отобразить их информацию", - "ItemsSelected": "Выбрано элементов", - "SystemProperties": "Системные свойства", - "WhoHasAccess": "У кого есть доступ", - "Members": "участников", - "OpenSharingSettings": "Открыть настройки общего доступа", + "Info": "Информация", + "ItemsSelected": "Выбрано элементов", + "SystemProperties": "Системные свойства", + "WhoHasAccess": "У кого есть доступ", + "Members": "участников", + "OpenSharingSettings": "Открыть настройки общего доступа", - "Location": "Местоположение", - "FileExtension": "Расширение файла", - "LastModifiedBy": "Последнеее изменение от", - "Versions": "Версии", - "Files": "Файлов", - "Comments": "Комментарии" + "Location": "Местоположение", + "FileExtension": "Расширение файла", + "LastModifiedBy": "Автор последнего корректива", + "Versions": "Версии", + "Comments": "Комментарии" } From 4e4ecec78fdd2c33ca94b23bfd7ecead211d01a5 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 29 Mar 2022 13:59:56 +0300 Subject: [PATCH 48/81] added dark theme support & moved context options "view details" button --- .../Navigation/sub-components/control-btn.js | 14 +++++++++-- .../sub-components/info-panel-header.js | 14 +++++++---- .../Section/sub-components/info-panel.js | 9 ++++++-- .../table-container/StyledTableContainer.js | 12 +++++++++- packages/asc-web-components/themes/base.js | 15 ++++++++++++ packages/asc-web-components/themes/dark.js | 15 ++++++++++++ .../Client/public/locales/en/InfoPanel.json | 1 + .../Client/public/locales/ru/InfoPanel.json | 1 + .../pages/Home/InfoPanel/Body/SingleItem.js | 4 ++-- .../src/pages/Home/InfoPanel/Body/index.js | 6 ++++- .../Home/InfoPanel/Body/styles/styles.js | 23 ++++++++++++------- .../Client/src/store/ContextOptionsStore.js | 20 ++++++++-------- .../ASC.Files/Client/src/store/FilesStore.js | 4 ++-- .../Client/src/store/SelectedFilesStore.js | 4 ---- 14 files changed, 105 insertions(+), 37 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js index 5b23e272af..c7bdb84f36 100644 --- a/packages/asc-web-common/components/Navigation/sub-components/control-btn.js +++ b/packages/asc-web-common/components/Navigation/sub-components/control-btn.js @@ -5,6 +5,7 @@ import ContextMenuButton from "@appserver/components/context-menu-button"; import IconButton from "@appserver/components/icon-button"; import { isMobile } from "react-device-detect"; import { tablet } from "@appserver/components/utils/device"; +import { Base } from "@appserver/components/themes"; const StyledContainer = styled.div` margin-left: 20px; @@ -55,9 +56,19 @@ const StyledInfoPanelToggleWrapper = styled.div` justify-content: center; border-radius: 50%; background-color: ${(props) => - props.isInfoPanelVisible ? "#F8F9F9" : "transparent"}; + props.isInfoPanelVisible + ? props.theme.infoPanel.sectionHeaderToggleBgActive + : props.theme.infoPanel.sectionHeaderToggleBg}; + + path { + fill: ${(props) => + props.isInfoPanelVisible + ? props.theme.infoPanel.sectionHeaderToggleIconActive + : props.theme.infoPanel.sectionHeaderToggleIcon}; + } } `; +StyledInfoPanelToggleWrapper.defaultProps = { theme: Base }; const ControlButtons = ({ personal, @@ -127,7 +138,6 @@ const ControlButtons = ({ className="info-panel-toggle" iconName="images/panel.svg" size="16" - color={isInfoPanelVisible ? "#3B72A7" : "#A3A9AE"} isFill={true} onClick={toggleInfoPanel} /> diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index 7d734dc0be..2bdb76fce5 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -1,5 +1,6 @@ import IconButton from "@appserver/components/icon-button"; import Text from "@appserver/components/text"; +import { Base } from "@appserver/components/themes"; import { tablet } from "@appserver/components/utils/device"; import { inject, observer } from "mobx-react"; import PropTypes from "prop-types"; @@ -9,13 +10,13 @@ import styled from "styled-components"; const StyledInfoPanelHeader = styled.div` width: 100%; max-width: 100%; - height: 53px; - min-height: 53px; + height: 54px; + min-height: 54px; box-sizing: border-box; display: flex; justify-content: space-between; align-items: center; - border-bottom: 1px solid #eceef1; + border-bottom: ${(props) => `1px solid ${props.theme.infoPanel.borderColor}`}; .header-text { margin-left: 20px; @@ -51,8 +52,6 @@ const SubInfoPanelHeader = ({ children, onHeaderCrossClick }) => { ); }; -SubInfoPanelHeader.displayName = "SubInfoPanelHeader"; - SubInfoPanelHeader.propTypes = { children: PropTypes.oneOfType([ PropTypes.arrayOf(PropTypes.node), @@ -62,6 +61,11 @@ SubInfoPanelHeader.propTypes = { toggleIsVisible: PropTypes.func, }; +StyledInfoPanelHeader.defaultProps = { theme: Base }; +SubInfoPanelHeader.defaultProps = { theme: Base }; + +SubInfoPanelHeader.displayName = "SubInfoPanelHeader"; + export default inject(({ infoPanelStore }) => { let onHeaderCrossClick = () => {}; if (infoPanelStore) { diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 1a0a2752e7..ce22eb0e09 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -1,4 +1,5 @@ import IconButton from "@appserver/components/icon-button"; +import { Base } from "@appserver/components/themes"; import { isTablet, mobile, tablet } from "@appserver/components/utils/device"; import { inject } from "mobx-react"; import PropTypes from "prop-types"; @@ -26,8 +27,8 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ const StyledInfoPanel = styled.div` height: 100%; width: 400px; - background-color: #ffffff; - border-left: 1px solid #eceef1; + background-color: ${(props) => props.theme.infoPanel.backgroundColor}; + border-left: ${(props) => `1px solid ${props.theme.infoPanel.borderColor}`}; display: flex; flex-direction: column; @@ -108,6 +109,10 @@ InfoPanel.propTypes = { isVisible: PropTypes.bool, }; +StyledInfoPanelWrapper.defaultProps = { theme: Base }; +StyledInfoPanel.defaultProps = { theme: Base }; +InfoPanel.defaultProps = { theme: Base }; + export default inject(({ infoPanelStore }) => { let isVisible = false; let setIsVisible = () => {}; diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 03c9b76605..2756c79a75 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -147,9 +147,19 @@ const StyledInfoPanelToggleWrapper = styled.div` justify-content: center; border-radius: 50%; background-color: ${(props) => - props.isInfoPanelVisible ? "#F8F9F9" : "transparent"}; + props.isInfoPanelVisible + ? props.theme.infoPanel.sectionHeaderToggleBgActive + : props.theme.infoPanel.sectionHeaderToggleBg}; + + path { + fill: ${(props) => + props.isInfoPanelVisible + ? props.theme.infoPanel.sectionHeaderToggleIconActive + : props.theme.infoPanel.sectionHeaderToggleIcon}; + } } `; +StyledInfoPanelToggleWrapper.defaultProps = { theme: Base }; const StyledTableHeader = styled.div` position: fixed; diff --git a/packages/asc-web-components/themes/base.js b/packages/asc-web-components/themes/base.js index 3173ecbcd2..50890deeb2 100644 --- a/packages/asc-web-components/themes/base.js +++ b/packages/asc-web-components/themes/base.js @@ -1950,6 +1950,21 @@ const Base = { }, }, + infoPanel: { + backgroundColor: white, + borderColor: grayLightMid, + textColor: black, + showAccessUsersTextColor: gray, + showAccessPanelTextColor: "#3b72a7", + headerCrossColor: gray, + + sectionHeaderToggleIcon: gray, + sectionHeaderToggleIconActive: "#3B72A7", + + sectionHeaderToggleBg: "transparent", + sectionHeaderToggleBgActive: grayLight, + }, + filesArticleBody: { background: lightGrayishStrongBlue, panelBackground: lightGrayishStrongBlue, diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index a40686390f..24395bf69e 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1952,6 +1952,21 @@ const Dark = { }, }, + infoPanel: { + backgroundColor: black, + borderColor: "#292929", + textColor: white, + showAccessUsersTextColor: gray, + showAccessPanelTextColor: graySilver, + headerCrossColor: gray, + + sectionHeaderToggleIcon: "#858585", + sectionHeaderToggleIconActive: white, + + sectionHeaderToggleBg: "transparent", + sectionHeaderToggleBgActive: "#292929", + }, + filesArticleBody: { background: black, panelBackground: "#474747", diff --git a/products/ASC.Files/Client/public/locales/en/InfoPanel.json b/products/ASC.Files/Client/public/locales/en/InfoPanel.json index 19fb071aae..42218ea27a 100644 --- a/products/ASC.Files/Client/public/locales/en/InfoPanel.json +++ b/products/ASC.Files/Client/public/locales/en/InfoPanel.json @@ -1,5 +1,6 @@ { "Info": "Info", + "ViewDetails": "View Details", "ItemsSelected": "Items selected", "SystemProperties": "System properties", "WhoHasAccess": "Who has access", diff --git a/products/ASC.Files/Client/public/locales/ru/InfoPanel.json b/products/ASC.Files/Client/public/locales/ru/InfoPanel.json index 4302f0935a..426fb5c3d5 100644 --- a/products/ASC.Files/Client/public/locales/ru/InfoPanel.json +++ b/products/ASC.Files/Client/public/locales/ru/InfoPanel.json @@ -1,5 +1,6 @@ { "Info": "Информация", + "ViewDetails": "Просмотреть подробную информацию", "ItemsSelected": "Выбрано элементов", "SystemProperties": "Системные свойства", "WhoHasAccess": "У кого есть доступ", diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index 6a2a8b24c3..2bcb0eb1b5 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -339,7 +339,7 @@ const SingleItem = (props) => { )} - + {t("SystemProperties")} @@ -360,7 +360,7 @@ const SingleItem = (props) => { {showAccess && ( <> - + {t("WhoHasAccess")} diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index 64ebe4d46a..b8d20a659a 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -6,6 +6,7 @@ import SeveralItems from "./SeveralItems"; import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; import Loader from "@appserver/components/loader"; +import { Base } from "@appserver/components/themes"; const InfoPanelBodyContent = ({ t, @@ -30,12 +31,13 @@ const InfoPanelBodyContent = ({ const folderId = new URL(window.location.href).searchParams.get("folder"); const folder = await getFolderInfo(folderId); + if (!folder) console.log("Cant Load Data"); + const fileExst = folder.fileExst, providerKey = folder.providerKey, contentLength = folderId.contentLength; folder.iconUrl = getIcon(32, fileExst, providerKey, contentLength); - //folder.thumbnailUrl = getIcon(96, fileExst, providerKey, contentLength); folder.isFolder = true; setCurrentFolder(folder); @@ -91,6 +93,8 @@ const InfoPanelBodyContent = ({ ); }; +InfoPanelBodyContent.defaultProps = { theme: Base }; + export default inject( ({ filesStore, diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index 7a1fbbe7e3..b6430b2d26 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -1,9 +1,13 @@ import styled from "styled-components"; +import { Base } from "@appserver/components/themes"; + const StyledInfoRoomBody = styled.div` padding: 0px 0px 0 16px; height: auto; - //margin-right: -16px; + background-color: ${(props) => props.theme.infoPanel.backgroundColor}; + color: ${(props) => props.theme.infoPanel.textColor}; + .no-item { text-align: center; } @@ -44,7 +48,7 @@ const StyledTitle = styled.div` } .text { - font-family: Open Sans; + font-family: "Open Sans"; line-height: 22px; margin: 0 8px; } @@ -57,7 +61,7 @@ const StyledThumbnail = styled.div` width: calc(100% + 6px -16px); height: 200px; padding: 4px; - border: solid 1px #eceef1; + border: ${(props) => `solid 1px ${props.theme.infoPanel.borderColor}`}; border-radius: 6px; margin: 0 0 24px 0; img { @@ -90,7 +94,6 @@ const StyledProperties = styled.div` .property-title { font-size: 13px; - color: #333333; } .property-content { @@ -99,7 +102,6 @@ const StyledProperties = styled.div` font-weight: 600; font-size: 13px; - color: #333333; } } `; @@ -111,7 +113,7 @@ const StyledAccess = styled.div` gap: 8px; align-items: center; .divider { - background: #eceef1; + background: ${(props) => props.theme.infoPanel.borderColor}; margin: 2px 4px; width: 1px; height: 28px; @@ -131,7 +133,7 @@ const StyledAccess = styled.div` line-height: 16px; text-align: right; - color: #a3a9ae; + color: ${(props) => props.theme.infoPanel.showAccessUsersTextColor}; flex: none; order: 3; @@ -171,7 +173,7 @@ const StyledOpenSharingPanel = styled.div` font-size: 13px; line-height: 15px; - color: #3b72a7; + color: ${(props) => props.theme.infoPanel.showAccessPanelTextColor}; display: flex; margin: 16px 0px; @@ -183,6 +185,11 @@ const StyledOpenSharingPanel = styled.div` } `; +StyledInfoRoomBody.defaultProps = { theme: Base }; +StyledThumbnail.defaultProps = { theme: Base }; +StyledAccess.defaultProps = { theme: Base }; +StyledOpenSharingPanel.defaultProps = { theme: Base }; + export { StyledInfoRoomBody, StyledTitle, diff --git a/products/ASC.Files/Client/src/store/ContextOptionsStore.js b/products/ASC.Files/Client/src/store/ContextOptionsStore.js index 18a1a3f223..92f9aff574 100644 --- a/products/ASC.Files/Client/src/store/ContextOptionsStore.js +++ b/products/ASC.Files/Client/src/store/ContextOptionsStore.js @@ -338,9 +338,9 @@ class ContextOptionsStore { return options; }; - onToggleInfoPanel = () => { - const { toggleIsVisible } = this.infoPanelStore; - toggleIsVisible(); + onShowInfoPanel = () => { + const { setIsVisible } = this.infoPanelStore; + setIsVisible(true); }; getFilesContextOptions = (item, t) => { @@ -451,13 +451,6 @@ class ContextOptionsStore { onClick: () => this.onOpenFolder(item), disabled: false, }, - { - key: "show-info", - label: t("InfoPanel:Info"), - icon: "/static/images/info.outline.react.svg", - onClick: () => this.onToggleInfoPanel(), - disabled: false, - }, { key: "fill-form", label: t("Common:FillFormButton"), @@ -525,6 +518,13 @@ class ContextOptionsStore { disabled: true, }, ...versionActions, + { + key: "show-info", + label: t("InfoPanel:ViewDetails"), + icon: "/static/images/info.outline.react.svg", + onClick: this.onShowInfoPanel, + disabled: false, + }, { key: "block-unblock-version", label: t("UnblockVersion"), diff --git a/products/ASC.Files/Client/src/store/FilesStore.js b/products/ASC.Files/Client/src/store/FilesStore.js index 2f8004325f..dc253ac5d8 100644 --- a/products/ASC.Files/Client/src/store/FilesStore.js +++ b/products/ASC.Files/Client/src/store/FilesStore.js @@ -708,7 +708,6 @@ class FilesStore { "preview", "view", "make-form", - "show-info", "separator0", "sharing-settings", "external-link", @@ -719,6 +718,7 @@ class FilesStore { "version", //category "finalize-version", "show-version-history", + "show-info", "block-unblock-version", //need split "separator1", "open-location", @@ -1003,10 +1003,10 @@ class FilesStore { } else { let folderOptions = [ "open", - "show-info", "separator0", "sharing-settings", "owner-change", + "show-info", "link-for-portal-users", "separator1", "open-location", diff --git a/products/ASC.Files/Client/src/store/SelectedFilesStore.js b/products/ASC.Files/Client/src/store/SelectedFilesStore.js index f7a66915e3..cf7681320d 100644 --- a/products/ASC.Files/Client/src/store/SelectedFilesStore.js +++ b/products/ASC.Files/Client/src/store/SelectedFilesStore.js @@ -20,10 +20,6 @@ class SelectedFilesStore { setFile = (obj) => { this.fileInfo = obj; }; - - get fileInfo() { - return this.fileInfo; - } } export default new SelectedFilesStore(); From 463a1f54a95a8200e9354a503aec0ccdc6bf1666 Mon Sep 17 00:00:00 2001 From: mushka Date: Tue, 29 Mar 2022 14:32:50 +0300 Subject: [PATCH 49/81] fix kafka conflict --- config/kafka.json | 2 +- .../components/Section/sub-components/info-panel.js | 2 +- packages/asc-web-components/themes/dark.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/kafka.json b/config/kafka.json index 02fa6e1afb..282f0503a2 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,5 +1,5 @@ { "kafka": { - "BootstrapServers": "localhost:9092" + "BootstrapServers": "" } } diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index ce22eb0e09..615df06b37 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -15,7 +15,7 @@ const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ backdrop-filter: blur(18px); @media ${tablet} { - z-index: 1002; + z-index: 309; position: absolute; top: 0; bottom: 0; diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index 24395bf69e..ece3d7e78b 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1957,7 +1957,7 @@ const Dark = { borderColor: "#292929", textColor: white, showAccessUsersTextColor: gray, - showAccessPanelTextColor: graySilver, + showAccessPanelTextColor: "#858585", headerCrossColor: gray, sectionHeaderToggleIcon: "#858585", From 85663d7e5b8efbb726058e9ccbfe3656c0f112c4 Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 30 Mar 2022 20:48:54 +0300 Subject: [PATCH 50/81] removed title from InfoPanelWrapper & coded exception for files with undefined extension --- .../components/Section/sub-components/info-panel.js | 8 ++++---- .../src/pages/Home/InfoPanel/Body/SingleItem.js | 13 ++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 615df06b37..82cb76b860 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -6,8 +6,8 @@ import PropTypes from "prop-types"; import React, { useEffect } from "react"; import styled from "styled-components"; -const StyledInfoPanelWrapper = styled.div.attrs(({ title }) => ({ - title: title, +const StyledInfoPanelWrapper = styled.div.attrs(({ id }) => ({ + id: id, }))` height: auto; width: auto; @@ -73,7 +73,7 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => { useEffect(() => { const onMouseDown = (e) => { - if (e.target.title === "InfoPanelWrapper") closeInfoPanel(); + if (e.target.id === "InfoPanelWrapper") closeInfoPanel(); }; if (isTablet()) document.addEventListener("mousedown", onMouseDown); @@ -81,7 +81,7 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => { }, []); return ( - + { const updateItemsInfo = async (selectedItem) => { const getItemIcon = (item, size) => { - const extension = item.fileExst; - const iconUrl = extension - ? getIcon(size, extension) - : getFolderIcon(item.providerKey, size); - - return iconUrl; + return item.isFolder + ? getFolderIcon(item.providerKey, size) + : getIcon(size, item.fileExst || ".file"); }; const getSingleItemProperties = (item) => { @@ -160,7 +157,9 @@ const SingleItem = (props) => { result.splice(3, 0, { id: "FileExtension", title: t("FileExtension"), - content: styledText(item.fileExst?.split(".")[1].toUpperCase()), + content: styledText( + item.fileExst ? item.fileExst.split(".")[1].toUpperCase() : "-" + ), }); result.push( From e4ab022fb9fc79c80d81e63d898cc823ac6d33b0 Mon Sep 17 00:00:00 2001 From: mushka Date: Wed, 30 Mar 2022 21:59:00 +0300 Subject: [PATCH 51/81] dark theme redesign --- .../sub-components/info-panel-header.js | 17 ----------------- .../Section/sub-components/info-panel.js | 19 ++++++++++++++----- .../table-container/TableGroupMenu.js | 2 -- packages/asc-web-components/themes/base.js | 2 ++ packages/asc-web-components/themes/dark.js | 6 ++++-- .../Home/InfoPanel/Body/styles/styles.js | 9 ++++----- 6 files changed, 24 insertions(+), 31 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js index 2bdb76fce5..d4741c0ec7 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel-header.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel-header.js @@ -21,13 +21,6 @@ const StyledInfoPanelHeader = styled.div` .header-text { margin-left: 20px; } - - .close-btn { - margin-right: 16px; - @media ${tablet} { - display: none; - } - } `; const SubInfoPanelHeader = ({ children, onHeaderCrossClick }) => { @@ -38,16 +31,6 @@ const SubInfoPanelHeader = ({ children, onHeaderCrossClick }) => { {content} - - ); }; diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index 82cb76b860..e59345e1d1 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -51,17 +51,27 @@ const StyledInfoPanel = styled.div` const StyledCloseButtonWrapper = styled.div` position: absolute; display: none; + background-color: ${(props) => props.theme.infoPanel.closeButtonBg}; + padding: 6px; + border-radius: 50%; + + .info-panel-button { + path { + fill: ${(props) => props.theme.infoPanel.closeButtonIcon}; + } + } + @media ${tablet} { display: block; top: 0; left: 0; margin-top: 18px; - margin-left: -27px; + margin-left: -34px; } @media ${mobile} { right: 0; left: auto; - margin-top: -27px; + margin-top: -34px; margin-right: 10px; } `; @@ -87,9 +97,7 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => { @@ -110,6 +118,7 @@ InfoPanel.propTypes = { }; StyledInfoPanelWrapper.defaultProps = { theme: Base }; +StyledCloseButtonWrapper.defaultProps = { theme: Base }; StyledInfoPanel.defaultProps = { theme: Base }; InfoPanel.defaultProps = { theme: Base }; diff --git a/packages/asc-web-components/table-container/TableGroupMenu.js b/packages/asc-web-components/table-container/TableGroupMenu.js index bd7d9bc2cf..6052f1387a 100644 --- a/packages/asc-web-components/table-container/TableGroupMenu.js +++ b/packages/asc-web-components/table-container/TableGroupMenu.js @@ -9,7 +9,6 @@ import { import ComboBox from "../combobox"; import GroupMenuItem from "./GroupMenuItem"; import { useTranslation } from "react-i18next"; -import styled from "styled-components"; import IconButton from "../icon-button"; const TableGroupMenu = (props) => { @@ -65,7 +64,6 @@ const TableGroupMenu = (props) => { className="info-panel-toggle" iconName="images/panel.svg" size="16" - color={isInfoPanelVisible ? "#3B72A7" : "#A3A9AE"} isFill={true} onClick={toggleInfoPanel} /> diff --git a/packages/asc-web-components/themes/base.js b/packages/asc-web-components/themes/base.js index 50890deeb2..2190d86b49 100644 --- a/packages/asc-web-components/themes/base.js +++ b/packages/asc-web-components/themes/base.js @@ -1957,6 +1957,8 @@ const Base = { showAccessUsersTextColor: gray, showAccessPanelTextColor: "#3b72a7", headerCrossColor: gray, + closeButtonIcon: gray, + closeButtonBg: "transparent", sectionHeaderToggleIcon: gray, sectionHeaderToggleIconActive: "#3B72A7", diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index ece3d7e78b..1b6dae9dfe 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1957,11 +1957,13 @@ const Dark = { borderColor: "#292929", textColor: white, showAccessUsersTextColor: gray, - showAccessPanelTextColor: "#858585", + showAccessPanelTextColor: "#E06A1B", headerCrossColor: gray, + closeButtonIcon: black, + closeButtonBg: "#a2a2a2", sectionHeaderToggleIcon: "#858585", - sectionHeaderToggleIconActive: white, + sectionHeaderToggleIconActive: "#c4c4c4", sectionHeaderToggleBg: "transparent", sectionHeaderToggleBgActive: "#292929", diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index b6430b2d26..fe63035b82 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -125,13 +125,14 @@ const StyledAccess = styled.div` height: 16px; left: 120px; top: 8px; + padding-left: 1px; font-family: Open Sans; font-style: normal; font-weight: normal; font-size: 12px; line-height: 16px; - text-align: right; + text-align: left; color: ${(props) => props.theme.infoPanel.showAccessUsersTextColor}; @@ -179,10 +180,8 @@ const StyledOpenSharingPanel = styled.div` margin: 16px 0px; cursor: pointer; - &:hover { - text-decoration: underline; - text-decoration-style: dashed; - } + text-decoration: underline; + text-decoration-style: dashed; `; StyledInfoRoomBody.defaultProps = { theme: Base }; From 1c5be7f82e3fcda7e7ffb52b27d6e330153483da Mon Sep 17 00:00:00 2001 From: mushka Date: Thu, 31 Mar 2022 15:04:09 +0300 Subject: [PATCH 52/81] fixed visualization of items with long titles --- .../pages/Home/InfoPanel/Body/SingleItem.js | 10 ++--- .../src/pages/Home/InfoPanel/Body/index.js | 44 ++++--------------- .../Home/InfoPanel/Body/styles/styles.js | 16 +++++-- 3 files changed, 26 insertions(+), 44 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index 8b3b855ec6..c87835dba5 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -322,9 +322,7 @@ const SingleItem = (props) => { <> - - {item.title} - + {item.title} {selectedItem.thumbnailUrl ? ( @@ -375,10 +373,10 @@ const SingleItem = (props) => { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index b8d20a659a..b4e8b97d6a 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -10,6 +10,7 @@ import { Base } from "@appserver/components/themes"; const InfoPanelBodyContent = ({ t, + selectedFolder, selectedItems, getFolderInfo, getIcon, @@ -22,31 +23,7 @@ const InfoPanelBodyContent = ({ isRecentFolder, isFavoritesFolder, }) => { - const [currentFolderLoading, setCurrentFolderLoading] = useState(false); - const [currentFolder, setCurrentFolder] = useState({}); - - const getCurrentFolderInfo = async () => { - setCurrentFolderLoading(true); - - const folderId = new URL(window.location.href).searchParams.get("folder"); - const folder = await getFolderInfo(folderId); - - if (!folder) console.log("Cant Load Data"); - - const fileExst = folder.fileExst, - providerKey = folder.providerKey, - contentLength = folderId.contentLength; - - folder.iconUrl = getIcon(32, fileExst, providerKey, contentLength); - folder.isFolder = true; - - setCurrentFolder(folder); - setCurrentFolderLoading(false); - }; - - useEffect(() => { - getCurrentFolderInfo(); - }, [window.location.href]); + console.log("--- ||| RENDER INFO PANEL ||| ---"); const singleItem = (item) => { const dontShowLocation = item.isFolder && item.parentId === 0; @@ -74,15 +51,10 @@ const InfoPanelBodyContent = ({ <> {selectedItems.length === 0 ? ( -
- {currentFolderLoading ? ( -
- -
- ) : ( - singleItem(currentFolder) - )} -
+ singleItem({ + ...selectedFolder, + isFolder: true, + }) ) : selectedItems.length === 1 ? ( singleItem(selectedItems[0]) ) : ( @@ -102,6 +74,7 @@ export default inject( filesActionsStore, dialogsStore, treeFoldersStore, + selectedFolderStore, }) => { const { selection, getFolderInfo, getShareUsers } = filesStore; const { getIcon, getFolderIcon } = settingsStore; @@ -115,7 +88,8 @@ export default inject( } = treeFoldersStore; return { - selectedItems: selection, + selectedFolder: { ...selectedFolderStore }, + selectedItems: [...selection], getFolderInfo, getShareUsers, getIcon, diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index fe63035b82..7d34dd1c6c 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -34,13 +34,16 @@ const StyledInfoRoomBody = styled.div` const StyledTitle = styled.div` display: flex; + flex-wrap: no-wrap; flex-direction: row; align-items: center; width: 100%; - height: auto; - padding: 29px 0; + height: 44px; + padding: 23px 0; .icon { + display: flex; + align-items: center; svg { height: 32px; width: 32px; @@ -48,9 +51,16 @@ const StyledTitle = styled.div` } .text { - font-family: "Open Sans"; + font-weight: 600; + font-size: 16px; line-height: 22px; + max-height: 44px; margin: 0 8px; + overflow: hidden; + text-overflow: ellipsis; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; } `; From 6a3e94a0d5786d1b3d373a65be214da79b1bc3f0 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 1 Apr 2022 12:16:40 +0300 Subject: [PATCH 53/81] added group support for access component & temporary removed `Location` system property --- packages/asc-web-components/themes/base.js | 17 +- packages/asc-web-components/themes/dark.js | 17 +- .../pages/Home/InfoPanel/Body/SingleItem.js | 187 ++++++++---------- .../src/pages/Home/InfoPanel/Body/index.js | 12 +- .../Home/InfoPanel/Body/styles/styles.js | 37 +++- 5 files changed, 140 insertions(+), 130 deletions(-) diff --git a/packages/asc-web-components/themes/base.js b/packages/asc-web-components/themes/base.js index 2190d86b49..128754c3ca 100644 --- a/packages/asc-web-components/themes/base.js +++ b/packages/asc-web-components/themes/base.js @@ -1951,20 +1951,23 @@ const Base = { }, infoPanel: { + sectionHeaderToggleIcon: gray, + sectionHeaderToggleIconActive: "#3B72A7", + sectionHeaderToggleBg: "transparent", + sectionHeaderToggleBgActive: grayLight, + backgroundColor: white, borderColor: grayLightMid, textColor: black, - showAccessUsersTextColor: gray, - showAccessPanelTextColor: "#3b72a7", - headerCrossColor: gray, + closeButtonIcon: gray, closeButtonBg: "transparent", - sectionHeaderToggleIcon: gray, - sectionHeaderToggleIconActive: "#3B72A7", + accessGroupBg: grayLightMid, + accessGroupText: black, - sectionHeaderToggleBg: "transparent", - sectionHeaderToggleBgActive: grayLight, + showAccessUsersTextColor: gray, + showAccessPanelTextColor: "#3b72a7", }, filesArticleBody: { diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index 1b6dae9dfe..faaf121477 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1953,20 +1953,23 @@ const Dark = { }, infoPanel: { + sectionHeaderToggleIcon: "#858585", + sectionHeaderToggleIconActive: "#c4c4c4", + sectionHeaderToggleBg: "transparent", + sectionHeaderToggleBgActive: "#292929", + backgroundColor: black, borderColor: "#292929", textColor: white, - showAccessUsersTextColor: gray, - showAccessPanelTextColor: "#E06A1B", - headerCrossColor: gray, + closeButtonIcon: black, closeButtonBg: "#a2a2a2", - sectionHeaderToggleIcon: "#858585", - sectionHeaderToggleIconActive: "#c4c4c4", + accessGroupBg: "#242424", + accessGroupText: white, - sectionHeaderToggleBg: "transparent", - sectionHeaderToggleBgActive: "#292929", + showAccessUsersTextColor: gray, + showAccessPanelTextColor: "#E06A1B", }, filesArticleBody: { diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index c87835dba5..db0e0a2d67 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -1,17 +1,13 @@ -import RectangleLoader from "@appserver/common/components/Loaders/RectangleLoader"; import { FileType } from "@appserver/common/constants"; import { LANGUAGE } from "@appserver/common/constants"; -const moment = require("moment"); - import Link from "@appserver/components/link"; import Text from "@appserver/components/text"; import Tooltip from "@appserver/components/tooltip"; import React, { useEffect, useState } from "react"; import { ReactSVG } from "react-svg"; - import { StyledAccess, - StyledAccessUser, + StyledAccessItem, StyledOpenSharingPanel, StyledProperties, StyledSubtitle, @@ -19,8 +15,10 @@ import { StyledTitle, } from "./styles/styles.js"; +const moment = require("moment"); + const SingleItem = (props) => { - let { + const { t, selectedItem, onSelectItem, @@ -50,8 +48,6 @@ const SingleItem = (props) => { others: [], }, }); - const [showAccess, setShowAccess] = useState(false); - const [isShowAllAccessUsers, setIsShowAllAccessUsers] = useState(false); const updateItemsInfo = async (selectedItem) => { const getItemIcon = (item, size) => { @@ -117,11 +113,11 @@ const SingleItem = (props) => { item.createdBy?.profileUrl ), }, - { - id: "Location", - title: t("InfoPanel:Location"), - content: , - }, + // { + // id: "Location", + // title: t("InfoPanel:Location"), + // content: styledText("..."), + // }, { id: "Type", title: t("Common:Type"), @@ -243,67 +239,55 @@ const SingleItem = (props) => { }; const updateLoadedItemAccess = async (selectedItem) => { - const parentFolderId = selectedItem.isFolder - ? selectedItem.parentId - : selectedItem.folderId; + const accesses = await getShareUsers( + [selectedItem.isFolder ? selectedItem.parentId : selectedItem.folderId], + [selectedItem.id] + ); - let result; - await getShareUsers([parentFolderId], [selectedItem.id]) - .catch((e) => { - setShowAccess(false); - }) - .then((accesses) => { - if (!accesses) { - setShowAccess(false); - return; - } - const accessResult = { - owner: {}, - others: [], - }; + const result = { + owner: {}, + others: [], + }; - accesses.forEach((access) => { - const user = access.sharedTo; - const userData = { - key: user.id, - img: user.avatarSmall, - link: user.profileUrl, - name: user.displayName, - email: user.email, - }; + accesses.forEach((access) => { + let key = access.sharedTo.id, + img = access.sharedTo.avatarSmall, + link = access.sharedTo.profileUrl, + name = access.sharedTo.displayName || access.sharedTo.name, + { manager } = access.sharedTo; - if (access.isOwner) accessResult.owner = userData; - else if (userData.email !== undefined) - accessResult.others.push(userData); - }); + if (access.isOwner) result.owner = { key, img, link, name }; + else { + if (access.sharedTo.email) + result.others.push({ key, type: "user", img, link, name }); + else if (access.sharedTo.manager) + result.others.push({ key, type: "group", name, manager }); + } + }); - result = accessResult; - }); + result.others = result.others.sort((a) => (a.type === "group" ? -1 : 1)); return result; }; - const properties = await updateLoadedItemProperties( - displayedItem, - selectedItem - ); + // const properties = await updateLoadedItemProperties( + // displayedItem, + // selectedItem + // ); - let access; - if (!dontShowAccess) { - access = await updateLoadedItemAccess(selectedItem); - } - - if (updateSubscription) { + if (dontShowAccess) { setItem({ ...displayedItem, properties: properties, - access: access, }); - if (access) setShowAccess(true); + return; } - }; - const showAllAccessUsers = () => { - setIsShowAllAccessUsers(true); + const access = await updateLoadedItemAccess(selectedItem); + setItem({ + ...displayedItem, + // properties: properties, + access: access, + }); }; const openSharingPanel = () => { @@ -354,7 +338,7 @@ const SingleItem = (props) => { })} - {showAccess && ( + {!dontShowAccess && item.access && ( <> @@ -364,62 +348,59 @@ const SingleItem = (props) => { dataTip ? {dataTip} : null } /> - +
- - - +
+ + + +
-
+ - {item.access.others.length ?
: null} + {item.access.others.length > 0 &&
} - {!isShowAllAccessUsers && item.access.others.length > 3 ? ( - <> - {item.access.others.map((user, i) => { - if (i < 3) - return ( -
- -
- - + {item.access.others.map((item, i) => { + if (i < 3) + return ( +
+ +
+ {item.type === "user" ? ( + - + ) : ( +
+ {item.name.substr(0, 2).toUpperCase()} +
+ )}
- ); - })} -
- {`+ ${item.access.others.length - 3} ${t("Members")}`} -
- - ) : ( - <> - {item.access.others.map((user) => ( -
- -
- - - -
-
+
- ))} - + ); + })} + + {item.access.others.length > 3 && ( +
+ {`+ ${item.access.others.length - 3} ${t("Members")}`} +
)} diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index b4e8b97d6a..f4d5ed3146 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -5,7 +5,6 @@ import { withRouter } from "react-router"; import SeveralItems from "./SeveralItems"; import SingleItem from "./SingleItem"; import { StyledInfoRoomBody } from "./styles/styles.js"; -import Loader from "@appserver/components/loader"; import { Base } from "@appserver/components/themes"; const InfoPanelBodyContent = ({ @@ -19,17 +18,18 @@ const InfoPanelBodyContent = ({ onSelectItem, setSharingPanelVisible, isRecycleBinFolder, - isCommonFolder, isRecentFolder, isFavoritesFolder, }) => { - console.log("--- ||| RENDER INFO PANEL ||| ---"); - const singleItem = (item) => { const dontShowLocation = item.isFolder && item.parentId === 0; const dontShowSize = item.isFolder && (isFavoritesFolder || isRecentFolder); const dontShowAccess = - isRecycleBinFolder || isCommonFolder || selectedItems.length === 0; + isRecycleBinFolder || + (item.isFolder && item.parentId === 0) || + item.rootFolderId === 7 || + (item.isFolder && item.pathParts[0] === 7); + return ( props.theme.infoPanel.accessGroupBg}; width: 100%; height: 100%; + display: flex; + align-items: center; + justify-content: center; + + span { + font-family: "Open Sans"; + font-weight: 700; + font-size: 12px; + color: ${(props) => props.theme.infoPanel.accessGroupText}; + line-height: 16px; + } + } + + .item-user { + img { + border-radius: 50%; + width: 100%; + height: 100%; + } } } `; @@ -178,7 +202,7 @@ const StyledOpenSharingPanel = styled.div` left: 0px; top: 2px; - font-family: Open Sans; + font-family: "Open Sans"; font-style: normal; font-weight: 600; font-size: 13px; @@ -197,6 +221,7 @@ const StyledOpenSharingPanel = styled.div` StyledInfoRoomBody.defaultProps = { theme: Base }; StyledThumbnail.defaultProps = { theme: Base }; StyledAccess.defaultProps = { theme: Base }; +StyledAccessItem.defaultProps = { theme: Base }; StyledOpenSharingPanel.defaultProps = { theme: Base }; export { @@ -206,6 +231,6 @@ export { StyledSubtitle, StyledProperties, StyledAccess, - StyledAccessUser, + StyledAccessItem, StyledOpenSharingPanel, }; From 562e047da134639a3d4ff72cba0a32e7fd0949cd Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 1 Apr 2022 13:53:35 +0300 Subject: [PATCH 54/81] fixed undefined properties bug --- .../Client/src/pages/Home/InfoPanel/Body/SingleItem.js | 2 +- products/ASC.Files/Server/DocStore | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js index db0e0a2d67..fcb31a8e2f 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/SingleItem.js @@ -277,7 +277,7 @@ const SingleItem = (props) => { if (dontShowAccess) { setItem({ ...displayedItem, - properties: properties, + //properties: properties, }); return; } diff --git a/products/ASC.Files/Server/DocStore b/products/ASC.Files/Server/DocStore index b9a3b81a25..2bb4d878b4 160000 --- a/products/ASC.Files/Server/DocStore +++ b/products/ASC.Files/Server/DocStore @@ -1 +1 @@ -Subproject commit b9a3b81a255ccaa6f174e7ad2dd3bf4d4911aa8f +Subproject commit 2bb4d878b42e8c648dd44fed7d445163772551fa From 119d283027118672c40608c83e3890074f2928d6 Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Fri, 1 Apr 2022 15:44:03 +0300 Subject: [PATCH 55/81] Web: Files: Fix pathParts undefined --- .../ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js index f4d5ed3146..10552e759b 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/index.js @@ -28,7 +28,7 @@ const InfoPanelBodyContent = ({ isRecycleBinFolder || (item.isFolder && item.parentId === 0) || item.rootFolderId === 7 || - (item.isFolder && item.pathParts[0] === 7); + (item.isFolder && item.pathParts && item.pathParts[0] === 7); return ( Date: Fri, 1 Apr 2022 15:44:39 +0300 Subject: [PATCH 56/81] Web: Files: Fix get target of undefined --- products/ASC.Files/Client/src/store/HotkeyStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/products/ASC.Files/Client/src/store/HotkeyStore.js b/products/ASC.Files/Client/src/store/HotkeyStore.js index 871f53f38d..a0486e4a56 100644 --- a/products/ASC.Files/Client/src/store/HotkeyStore.js +++ b/products/ASC.Files/Client/src/store/HotkeyStore.js @@ -31,7 +31,7 @@ class HotkeyStore { } activateHotkeys = (e) => { - if (this.dialogsStore.someDialogIsOpen || ev.target?.tagName === "INPUT") + if (this.dialogsStore.someDialogIsOpen || e.target?.tagName === "INPUT") return e; const isDefaultKeys = From fb2cb1316ad85524a0fe6b14c635bf38af41e4a4 Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 1 Apr 2022 17:39:03 +0300 Subject: [PATCH 57/81] changed thumbnail styling --- config/kafka.json | 2 +- .../src/pages/Home/InfoPanel/Body/styles/styles.js | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/config/kafka.json b/config/kafka.json index 282f0503a2..02fa6e1afb 100644 --- a/config/kafka.json +++ b/config/kafka.json @@ -1,5 +1,5 @@ { "kafka": { - "BootstrapServers": "" + "BootstrapServers": "localhost:9092" } } diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index b42a4f7b8c..c07b2799a1 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -68,17 +68,14 @@ const StyledThumbnail = styled.div` display: flex; justify-content: center; align-items: center; - width: calc(100% + 6px -16px); - height: 200px; - padding: 4px; + width: 100%; + //width: calc(100% - 10px); + height: auto; border: ${(props) => `solid 1px ${props.theme.infoPanel.borderColor}`}; border-radius: 6px; - margin: 0 0 24px 0; img { - height: 100%; - width: auto; - max-height: auto; - max-width: 100%; + width: 100%; + height: auto; } `; From 562bd9d0886d1df44ab733fc7184b24a43e0392d Mon Sep 17 00:00:00 2001 From: mushka Date: Fri, 1 Apr 2022 17:42:45 +0300 Subject: [PATCH 58/81] changed thumbnail border --- packages/asc-web-components/themes/base.js | 1 + packages/asc-web-components/themes/dark.js | 1 + .../Client/src/pages/Home/InfoPanel/Body/styles/styles.js | 1 + 3 files changed, 3 insertions(+) diff --git a/packages/asc-web-components/themes/base.js b/packages/asc-web-components/themes/base.js index 902eba9b2d..ca42b5d44b 100644 --- a/packages/asc-web-components/themes/base.js +++ b/packages/asc-web-components/themes/base.js @@ -1960,6 +1960,7 @@ const Base = { backgroundColor: white, borderColor: grayLightMid, + thumbnailBorderColor: grayLightMid, textColor: black, closeButtonIcon: gray, diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index e409a4c9d4..e874fc6fd3 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1962,6 +1962,7 @@ const Dark = { backgroundColor: black, borderColor: "#292929", + thumbnailBorderColor: grayLightMid, textColor: white, closeButtonIcon: black, diff --git a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js index c07b2799a1..4405fef919 100644 --- a/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js +++ b/products/ASC.Files/Client/src/pages/Home/InfoPanel/Body/styles/styles.js @@ -74,6 +74,7 @@ const StyledThumbnail = styled.div` border: ${(props) => `solid 1px ${props.theme.infoPanel.borderColor}`}; border-radius: 6px; img { + border-radius: 6px; width: 100%; height: auto; } From a985ad95a9a40268cc577b5269002e43a539f99e Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 4 Apr 2022 12:22:08 +0300 Subject: [PATCH 59/81] resolving conflicts before updating to branch feature/virtual-rooms-1.2 --- .../components/Navigation/StyledNavigation.js | 20 ++++++++++++++++++- .../components/Section/index.js | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/StyledNavigation.js b/packages/asc-web-common/components/Navigation/StyledNavigation.js index f22b796854..920b6d758c 100644 --- a/packages/asc-web-common/components/Navigation/StyledNavigation.js +++ b/packages/asc-web-common/components/Navigation/StyledNavigation.js @@ -14,15 +14,33 @@ const StyledContainer = styled.div` min-width: 17px; } - height: 53px; + /* height: 53px; @media ${tablet} { height: 61px; + } */ + + @media ${tablet} { + width: 100%; + padding: ${(props) => (props.isDropBox ? "16px 0 5px" : "16px 0 0px")}; } + ${isMobile && + css` + width: 100%; + padding: ${(props) => + props.isDropBox ? "16px 0 5px" : " 16px 0 0px"} !important; + `} @media ${mobile} { height: 53px; } + + ${isMobileOnly && + css` + width: 100% !important; + padding: ${(props) => + props.isDropBox ? "18px 0 5px" : "18px 0 0"} !important; + `} `; export default StyledContainer; diff --git a/packages/asc-web-common/components/Section/index.js b/packages/asc-web-common/components/Section/index.js index 1bc345db83..569e66fef3 100644 --- a/packages/asc-web-common/components/Section/index.js +++ b/packages/asc-web-common/components/Section/index.js @@ -233,7 +233,7 @@ class Section extends React.Component { }} > - {isSectionHeaderAvailable && ( + {isSectionHeaderAvailable && !isMobile && ( Date: Mon, 4 Apr 2022 12:25:16 +0300 Subject: [PATCH 60/81] resolving conflicts before updating to feature/virtual-rooms-1.2 2 --- .../components/Section/index.js | 157 ++++++++++++++++-- 1 file changed, 139 insertions(+), 18 deletions(-) diff --git a/packages/asc-web-common/components/Section/index.js b/packages/asc-web-common/components/Section/index.js index 569e66fef3..00583bbab6 100644 --- a/packages/asc-web-common/components/Section/index.js +++ b/packages/asc-web-common/components/Section/index.js @@ -5,6 +5,7 @@ import { desktop, size, tablet, + mobile, isMobile as isMobileUtils, isTablet as isTabletUtils, } from "@appserver/components/utils/device"; @@ -16,6 +17,7 @@ import SubSectionHeader from "./sub-components/section-header"; import SubSectionFilter from "./sub-components/section-filter"; import SubSectionBody from "./sub-components/section-body"; import SubSectionBodyContent from "./sub-components/section-body-content"; +import SubSectionBar from "./sub-components/section-bar"; import SubSectionPaging from "./sub-components/section-paging"; //import SectionToggler from "./sub-components/section-toggler"; import InfoPanel from "./sub-components/info-panel"; @@ -37,20 +39,66 @@ const StyledSelectoWrapper = styled.div` const StyledMainBar = styled.div` box-sizing: border-box; - ${!isMobile - ? css` - padding-right: 20px; - @media ${tablet} { - padding-right: 16px; - } - ` - : css` - padding-right: 0px; + margin-left: -20px; + width: calc(100vw - 256px); + max-width: calc(100vw - 256px); - @media ${desktop} { - padding-right: 10px; - } + #bar-banner { + margin-bottom: -3px; + } + + #bar-frame { + min-width: 100%; + max-width: 100%; + } + + @media ${tablet} { + width: ${(props) => + props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"}; + max-width: ${(props) => + props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"}; + margin-left: -16px; + } + + ${isMobile && + css` + width: ${(props) => + props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"} !important; + max-width: ${(props) => + props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"} !important; + margin-left: -16px; + `} + + @media ${mobile} { + width: 100vw !important; + max-width: 100vw !important; + } + + ${isMobileOnly && + css` + width: 100vw !important; + max-width: 100vw !important; + + #bar-frame { + min-width: 100vw; + } + `} + + ${(props) => + !props.isSectionHeaderAvailable && + css` + width: 100vw !important; + max-width: 100vw !important; + + ${isMobile && + css` + position: fixed; + top: 48px; + left: 0; + margin-left: 0 !important; + box-sizing: border-box; `} + `} `; function SectionHeader() { @@ -58,6 +106,12 @@ function SectionHeader() { } SectionHeader.displayName = "SectionHeader"; +function SectionBar() { + return null; +} + +SectionBar.displayName = "SectionBar"; + function SectionFilter() { return null; } @@ -87,6 +141,7 @@ class Section extends React.Component { static SectionHeader = SectionHeader; static SectionFilter = SectionFilter; static SectionBody = SectionBody; + static SectionBar = SectionBar; static SectionPaging = SectionPaging; static InfoPanelBody = InfoPanelBody; static InfoPanelHeader = InfoPanelHeader; @@ -140,7 +195,6 @@ class Section extends React.Component { onScroll = (e) => { this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10); }; - render() { const { onDrop, @@ -166,9 +220,14 @@ class Section extends React.Component { isBackdropVisible, isDesktop, isHomepage, + maintenanceExist, + setMaintenanceExist, + snackbarExist, + showText, } = this.props; let sectionHeaderContent = null; + let sectionBarContent = null; let sectionFilterContent = null; let sectionPagingContent = null; let sectionBodyContent = null; @@ -186,6 +245,9 @@ class Section extends React.Component { case SectionFilter.displayName: sectionFilterContent = child; break; + case SectionBar.displayName: + sectionBarContent = child; + break; case SectionPaging.displayName: sectionPagingContent = child; break; @@ -210,6 +272,7 @@ class Section extends React.Component { !!sectionBodyContent || isSectionFilterAvailable || isSectionPagingAvailable, + isSectionBarAvailable = !!sectionBarContent, isSectionAvailable = isSectionHeaderAvailable || isSectionFilterAvailable || @@ -232,21 +295,48 @@ class Section extends React.Component { sectionHeight: height, }} > - + + {!isMobile && ( + + + {sectionBarContent + ? sectionBarContent.props.children + : null} + + + )} + {isSectionHeaderAvailable && !isMobile && ( {sectionHeaderContent ? sectionHeaderContent.props.children : null} )} - {isSectionFilterAvailable && ( + {isSectionFilterAvailable && !isMobile && ( <> - - {isSectionHeaderAvailable && ( + {isMobile && ( + + + {sectionBarContent + ? sectionBarContent.props.children + : null} + + + )} + + {isSectionHeaderAvailable && isMobile && ( {sectionHeaderContent ? sectionHeaderContent.props.children @@ -280,7 +391,7 @@ class Section extends React.Component { )} - {isSectionFilterAvailable && ( + {isSectionFilterAvailable && isMobile && ( {sectionFilterContent ? sectionFilterContent.props.children @@ -442,6 +553,11 @@ export default inject(({ auth }) => { setIsBackdropVisible, isDesktopClient, + maintenanceExist, + snackbarExist, + setMaintenanceExist, + + showText, } = settingsStore; return { @@ -451,6 +567,11 @@ export default inject(({ auth }) => { isBackdropVisible, setIsBackdropVisible, + maintenanceExist, + snackbarExist, + setMaintenanceExist, isDesktop: isDesktopClient, + + showText, }; })(observer(Section)); From 1af038351451efd7a72929f3a2073fe2db969641 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 4 Apr 2022 14:57:22 +0300 Subject: [PATCH 61/81] resolved problem with updated section width calculation --- .../components/Navigation/StyledNavigation.js | 6 ------ packages/asc-web-common/components/Section/index.js | 11 ++++++++++- .../Section/sub-components/section-container.js | 6 ++++-- .../Section/sub-components/section-header.js | 12 ++++++++++-- .../Client/src/pages/Home/Section/Header/index.js | 4 ++-- 5 files changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/asc-web-common/components/Navigation/StyledNavigation.js b/packages/asc-web-common/components/Navigation/StyledNavigation.js index 920b6d758c..5765ce9195 100644 --- a/packages/asc-web-common/components/Navigation/StyledNavigation.js +++ b/packages/asc-web-common/components/Navigation/StyledNavigation.js @@ -14,12 +14,6 @@ const StyledContainer = styled.div` min-width: 17px; } - /* height: 53px; - - @media ${tablet} { - height: 61px; - } */ - @media ${tablet} { width: 100%; padding: ${(props) => (props.isDropBox ? "16px 0 5px" : "16px 0 0px")}; diff --git a/packages/asc-web-common/components/Section/index.js b/packages/asc-web-common/components/Section/index.js index 00583bbab6..46f13512f3 100644 --- a/packages/asc-web-common/components/Section/index.js +++ b/packages/asc-web-common/components/Section/index.js @@ -224,6 +224,7 @@ class Section extends React.Component { setMaintenanceExist, snackbarExist, showText, + infoPanelIsVisible, } = this.props; let sectionHeaderContent = null; @@ -302,6 +303,7 @@ class Section extends React.Component { maintenanceExist={maintenanceExist} isSectionBarAvailable={isSectionBarAvailable} isSectionHeaderAvailable={isSectionHeaderAvailable} + infoPanelIsVisible={infoPanelIsVisible} > {!isMobile && ( @@ -384,6 +387,7 @@ class Section extends React.Component { isHeaderVisible={isHeaderVisible} viewAs={viewAs} showText={showText} + infoPanelIsVisible={infoPanelIsVisible} > {sectionHeaderContent ? sectionHeaderContent.props.children @@ -543,7 +547,7 @@ Section.SectionFilter = SectionFilter; Section.SectionBody = SectionBody; Section.SectionPaging = SectionPaging; -export default inject(({ auth }) => { +export default inject(({ auth, infoPanelStore }) => { const { isLoaded, settingsStore } = auth; const { isHeaderVisible, @@ -560,6 +564,9 @@ export default inject(({ auth }) => { showText, } = settingsStore; + let infoPanelIsVisible = false; + if (infoPanelStore) infoPanelIsVisible = infoPanelStore.isVisible; + return { isLoaded, isTabletView, @@ -573,5 +580,7 @@ export default inject(({ auth }) => { isDesktop: isDesktopClient, showText, + + infoPanelIsVisible: infoPanelIsVisible, }; })(observer(Section)); diff --git a/packages/asc-web-common/components/Section/sub-components/section-container.js b/packages/asc-web-common/components/Section/sub-components/section-container.js index ebffeea9c4..a694addf86 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-container.js +++ b/packages/asc-web-common/components/Section/sub-components/section-container.js @@ -38,8 +38,10 @@ const StyledSectionContainer = styled.section` display: flex; flex-direction: column; - width: calc(100vw - 256px); - max-width: calc(100vw - 256px); + width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 677px)" : "calc(100vw - 256px)"}; + max-width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 677px)" : "calc(100vw - 256px)"}; @media ${tablet} { width: ${(props) => diff --git a/packages/asc-web-common/components/Section/sub-components/section-header.js b/packages/asc-web-common/components/Section/sub-components/section-header.js index 8ce1c3f1b7..c541768aed 100644 --- a/packages/asc-web-common/components/Section/sub-components/section-header.js +++ b/packages/asc-web-common/components/Section/sub-components/section-header.js @@ -16,8 +16,16 @@ const StyledSectionHeader = styled.div` margin-right: 20px; ${NoUserSelect} - width: calc(100vw - 296px); - max-width: calc(100vw - 296px); + display: grid; + align-items: center; + + /* width: calc(100vw - 296px); + max-width: calc(100vw - 296px); */ + + width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 696px)" : "calc(100vw - 296px)"}; + max-width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 696px)" : "calc(100vw - 296px)"}; @media ${tablet} { width: ${(props) => diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js index 99b5e8f2fa..5a945ef7bb 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Header/index.js @@ -18,7 +18,7 @@ import TableGroupMenu from "@appserver/components/table-container/TableGroupMenu import Navigation from "@appserver/common/components/Navigation"; const StyledContainer = styled.div` - padding: 0 0 15px; + /* padding: 0 0 15px; @media ${tablet} { padding: 0 0 17px; @@ -36,7 +36,7 @@ const StyledContainer = styled.div` ${isMobileOnly && css` padding: 0 0 13px; - `} + `} */ .table-container_group-menu { ${(props) => From a226566a625ec675032c2d4ab6952665e64a9f54 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 4 Apr 2022 15:19:59 +0300 Subject: [PATCH 62/81] fix close button design --- .../components/Section/sub-components/info-panel.js | 8 +++++--- packages/asc-web-components/themes/base.js | 4 +++- packages/asc-web-components/themes/dark.js | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/asc-web-common/components/Section/sub-components/info-panel.js b/packages/asc-web-common/components/Section/sub-components/info-panel.js index e59345e1d1..95f28418c4 100644 --- a/packages/asc-web-common/components/Section/sub-components/info-panel.js +++ b/packages/asc-web-common/components/Section/sub-components/info-panel.js @@ -52,10 +52,14 @@ const StyledCloseButtonWrapper = styled.div` position: absolute; display: none; background-color: ${(props) => props.theme.infoPanel.closeButtonBg}; - padding: 6px; + padding: ${(props) => props.theme.infoPanel.closeButtonWrapperPadding}; border-radius: 50%; .info-panel-button { + svg { + width: ${(props) => props.theme.infoPanel.closeButtonSize}; + height: ${(props) => props.theme.infoPanel.closeButtonSize}; + } path { fill: ${(props) => props.theme.infoPanel.closeButtonIcon}; } @@ -97,8 +101,6 @@ const InfoPanel = ({ children, isVisible, setIsVisible }) => { diff --git a/packages/asc-web-components/themes/base.js b/packages/asc-web-components/themes/base.js index 3117491b22..ca007dbc09 100644 --- a/packages/asc-web-components/themes/base.js +++ b/packages/asc-web-components/themes/base.js @@ -1963,7 +1963,9 @@ const Base = { thumbnailBorderColor: grayLightMid, textColor: black, - closeButtonIcon: gray, + closeButtonWrapperPadding: "0px", + closeButtonIcon: white, + closeButtonSize: "17px", closeButtonBg: "transparent", accessGroupBg: grayLightMid, diff --git a/packages/asc-web-components/themes/dark.js b/packages/asc-web-components/themes/dark.js index 2589d95fff..b9bf32194d 100644 --- a/packages/asc-web-components/themes/dark.js +++ b/packages/asc-web-components/themes/dark.js @@ -1965,7 +1965,9 @@ const Dark = { thumbnailBorderColor: grayLightMid, textColor: white, + closeButtonWrapperPadding: "6px", closeButtonIcon: black, + closeButtonSize: "12px", closeButtonBg: "#a2a2a2", accessGroupBg: "#242424", From 5a5237d9271a30a59ba856d3e6aec8300e584b44 Mon Sep 17 00:00:00 2001 From: mushka Date: Mon, 4 Apr 2022 17:40:45 +0300 Subject: [PATCH 63/81] fixed ad bar sizing with InfoPanel open & redesigned thumbnail scaling --- config/appsettings.json | 482 ++++++++++++------ .../components/Section/index.js | 11 +- .../Home/InfoPanel/Body/styles/styles.js | 8 +- .../Section/Body/RowsView/SimpleFilesRow.js | 4 +- 4 files changed, 335 insertions(+), 170 deletions(-) diff --git a/config/appsettings.json b/config/appsettings.json index 564e5652f1..6a78550fd8 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -1,165 +1,323 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" - }, - "EventLog": { - "LogLevel": { - "Default": "Information", - "Microsoft.Hosting.Lifetime": "Information" - } - } + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" }, - "AllowedHosts": "*", - "core": { - "base-domain": "", - "machinekey": "1123askdasjklasbnd", - "notify": { - "postman": "log" - }, - "payment": { - "delay": "10", - "partners": "https://partners.teamlab.info/api", - "region": "test", - "test": true - }, - "personal": false, - "products": { - "folder": "../../products", - "subfolder": "Server" - } - }, - "license": { - "file": { - "path": "" - } - }, - "mail": { - "certificate-permit": false, - "daemon-email": "mail-daemon@onlyoffice.com", - "server-mailbox-limit-per-user": 2 - }, - "messaging": { - "enabled": "enabled" - }, - "version": { - "number": "11.5.0", - "release": { - "date": "", - "sign": "" - } - }, - "files": { - "thirdparty": { - "enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ] - }, - "docservice": { - "coauthor-docs": [ ".pptx", ".ppsx", ".xlsx", ".csv", ".docx", ".docxf", ".oform", ".txt" ], - "commented-docs": [ ".docx", ".docxf", ".xlsx", ".pptx" ], - "convert-docs": [ ".pptm", ".ppt", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".rtf" ], - "edited-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".txt", ".rtf", ".mht", ".html", ".htm" ], - "encrypted-docs": [ ".docx", ".docxf", ".xlsx", ".pptx", ".oform" ], - "formfilling-docs": [ ".oform" ], - "customfilter-docs": [ ".xlsx" ], - "reviewed-docs": [ ".docx", ".docxf" ], - "viewed-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ], - "secret": { - "value": "", - "header": "" - }, - "url": { - "public": "http://localhost:8085/", - "internal": "", - "portal": "" - } - }, - "ffmpeg": { - "value": "", - "exts": [ "avi", "mpeg", "mpg", "wmv" ] - }, - "uploader": { - "chunk-size": 10485760, - "url": "products/files/" - }, - "viewed-images": [ ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ico", ".tif", ".tiff", ".webp" ], - "viewed-media": [ ".aac", ".flac", ".m4a", ".mp3", ".oga", ".ogg", ".wav", ".f4v", ".m4v", ".mov", ".mp4", ".ogv", ".webm" ], - "index": [ ".pptx", ".xlsx", ".docx" ] - }, - "web": { - "api": "api/2.0", - "alias": { - "min": "" - }, - "images": "images", - "hide-settings": "Monitoring,LdapSettings,DocService,MailService,PublicPortal,ProxyHttpContent,SpamSubscription,FullTextSearch", - "hub": { - "url": "/socket.io", - "internal": "http://localhost:9899/" - }, - "cultures": "de,en,fr,it,pt-BR,ru", - "url-shortener": { - "value": "/sh/", - "internal": "http://localhost:9999/" - }, - "controlpanel": { - "url": "" - }, - "support-feedback": "https://helpdesk.onlyoffice.com", - "teamlab-site": "http://www.onlyoffice.com" - }, - "ConnectionStrings": { - "default": { - "name": "default", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", - "providerName": "MySql.Data.MySqlClient" - }, - "postgre": { - "name": "postgre", - "connectionString": "Host=localhost;Port=5432;Database=onlyoffice;Username=postgres;Password=dev;", - "providerName": "Npgsql" - }, - "mysql": { - "name": "mysql", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", - "providerName": "MySql.Data.MySqlClient" - } - }, - "migration": { - "enabled": "false" - }, - "DbProviderFactories": { - "mysql": { - "name": "MySQL Data Provider", - "invariant": "MySql.Data.MySqlClient", - "description": ".Net Framework Data Provider for MySQL", - "type": "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" - } - }, - "bookmarking": { - "thumbnail-url": "http://localhost:9800/?url={0}" - }, - "storage": { - "encryption": { - "progressfile": "false", - "tempdir": "" - } - }, - "firebase": { - "apiKey": "", - "authDomain": "", - "projectId": "", - "storageBucket": "", - "messagingSenderId": "", - "appId": "", - "measurementId": "" - }, - "debug-info": { - "enabled": "true" - }, - "thumbnail": { - "thumbnaillHeight": 156, - "thumbnaillWidth": 216 + "EventLog": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } } -} \ No newline at end of file + }, + "AllowedHosts": "*", + "core": { + "base-domain": "", + "machinekey": "1123askdasjklasbnd", + "notify": { + "postman": "log" + }, + "payment": { + "delay": "10", + "partners": "https://partners.teamlab.info/api", + "region": "test", + "test": true + }, + "personal": false, + "products": { + "folder": "../../products", + "subfolder": "Server" + } + }, + "license": { + "file": { + "path": "" + } + }, + "mail": { + "certificate-permit": false, + "daemon-email": "mail-daemon@onlyoffice.com", + "server-mailbox-limit-per-user": 2 + }, + "messaging": { + "enabled": "enabled" + }, + "version": { + "number": "11.5.0", + "release": { + "date": "", + "sign": "" + } + }, + "files": { + "thirdparty": { + "enable": [ + "box", + "dropboxv2", + "docusign", + "google", + "onedrive", + "sharepoint", + "nextcloud", + "owncloud", + "webdav", + "kdrive", + "yandex" + ] + }, + "docservice": { + "coauthor-docs": [ + ".pptx", + ".ppsx", + ".xlsx", + ".csv", + ".docx", + ".docxf", + ".oform", + ".txt" + ], + "commented-docs": [".docx", ".docxf", ".xlsx", ".pptx"], + "convert-docs": [ + ".pptm", + ".ppt", + ".ppsm", + ".pps", + ".potx", + ".potm", + ".pot", + ".odp", + ".fodp", + ".otp", + ".xlsm", + ".xls", + ".xltx", + ".xltm", + ".xlt", + ".ods", + ".fods", + ".ots", + ".docm", + ".doc", + ".dotx", + ".dotm", + ".dot", + ".odt", + ".fodt", + ".ott", + ".rtf" + ], + "edited-docs": [ + ".pptx", + ".pptm", + ".ppt", + ".ppsx", + ".ppsm", + ".pps", + ".potx", + ".potm", + ".pot", + ".odp", + ".fodp", + ".otp", + ".xlsx", + ".xlsm", + ".xls", + ".xltx", + ".xltm", + ".xlt", + ".ods", + ".fods", + ".ots", + ".csv", + ".docx", + ".docxf", + ".oform", + ".docm", + ".doc", + ".dotx", + ".dotm", + ".dot", + ".odt", + ".fodt", + ".ott", + ".txt", + ".rtf", + ".mht", + ".html", + ".htm" + ], + "encrypted-docs": [".docx", ".docxf", ".xlsx", ".pptx", ".oform"], + "formfilling-docs": [".oform"], + "customfilter-docs": [".xlsx"], + "reviewed-docs": [".docx", ".docxf"], + "viewed-docs": [ + ".pptx", + ".pptm", + ".ppt", + ".ppsx", + ".ppsm", + ".pps", + ".potx", + ".potm", + ".pot", + ".odp", + ".fodp", + ".otp", + ".gslides", + ".xlsx", + ".xlsm", + ".xls", + ".xltx", + ".xltm", + ".xlt", + ".ods", + ".fods", + ".ots", + ".gsheet", + ".csv", + ".docx", + ".docxf", + ".oform", + ".docm", + ".doc", + ".dotx", + ".dotm", + ".dot", + ".odt", + ".fodt", + ".ott", + ".gdoc", + ".txt", + ".rtf", + ".mht", + ".html", + ".htm", + ".epub", + ".pdf", + ".djvu", + ".xps" + ], + "secret": { + "value": "", + "header": "" + }, + "url": { + "public": "http://localhost:8085/", + "internal": "", + "portal": "" + } + }, + "ffmpeg": { + "value": "", + "exts": ["avi", "mpeg", "mpg", "wmv"] + }, + "uploader": { + "chunk-size": 10485760, + "url": "products/files/" + }, + "viewed-images": [ + ".bmp", + ".gif", + ".jpeg", + ".jpg", + ".png", + ".ico", + ".tif", + ".tiff", + ".webp" + ], + "viewed-media": [ + ".aac", + ".flac", + ".m4a", + ".mp3", + ".oga", + ".ogg", + ".wav", + ".f4v", + ".m4v", + ".mov", + ".mp4", + ".ogv", + ".webm" + ], + "index": [".pptx", ".xlsx", ".docx"] + }, + "web": { + "api": "api/2.0", + "alias": { + "min": "" + }, + "images": "images", + "hide-settings": "Monitoring,LdapSettings,DocService,MailService,PublicPortal,ProxyHttpContent,SpamSubscription,FullTextSearch", + "hub": { + "url": "/socket.io", + "internal": "http://localhost:9899/" + }, + "cultures": "de,en,fr,it,pt-BR,ru", + "url-shortener": { + "value": "/sh/", + "internal": "http://localhost:9999/" + }, + "controlpanel": { + "url": "" + }, + "support-feedback": "https://helpdesk.onlyoffice.com", + "teamlab-site": "http://www.onlyoffice.com" + }, + "ConnectionStrings": { + "default": { + "name": "default", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "providerName": "MySql.Data.MySqlClient" + }, + "postgre": { + "name": "postgre", + "connectionString": "Host=localhost;Port=5432;Database=onlyoffice;Username=postgres;Password=dev;", + "providerName": "Npgsql" + }, + "mysql": { + "name": "mysql", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "providerName": "MySql.Data.MySqlClient" + } + }, + "migration": { + "enabled": "false" + }, + "DbProviderFactories": { + "mysql": { + "name": "MySQL Data Provider", + "invariant": "MySql.Data.MySqlClient", + "description": ".Net Framework Data Provider for MySQL", + "type": "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" + } + }, + "bookmarking": { + "thumbnail-url": "http://localhost:9800/?url={0}" + }, + "storage": { + "encryption": { + "progressfile": "false", + "tempdir": "" + } + }, + "firebase": { + "apiKey": "AIzaSyBpwXzH4toHP5Dr38DmwjsY9VqS4fTk4FM", + "authDomain": "appserver-c011a.firebaseapp.com", + "projectId": "appserver-c011a", + "storageBucket": "appserver-c011a.appspot.com", + "messagingSenderId": "92050394157", + "appId": "1:92050394157:web:da52e02c3eef65e5ca7ca4", + "measurementId": "G-7MEFVW27MJ" + }, + "debug-info": { + "enabled": "true" + }, + "thumbnail": { + "thumbnaillHeight": 156, + "thumbnaillWidth": 216 + } +} diff --git a/packages/asc-web-common/components/Section/index.js b/packages/asc-web-common/components/Section/index.js index 46f13512f3..516f1d919f 100644 --- a/packages/asc-web-common/components/Section/index.js +++ b/packages/asc-web-common/components/Section/index.js @@ -40,8 +40,13 @@ const StyledMainBar = styled.div` box-sizing: border-box; margin-left: -20px; - width: calc(100vw - 256px); - max-width: calc(100vw - 256px); + /* width: calc(100vw - 256px); + max-width: calc(100vw - 256px); */ + + width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 657px)" : "calc(100vw - 256px)"}; + max-width: ${(props) => + props.infoPanelIsVisible ? "calc(100vw - 657px)" : "calc(100vw - 256px)"}; #bar-banner { margin-bottom: -3px; @@ -312,6 +317,7 @@ class Section extends React.Component { className={"main-bar"} showText={showText} isSectionHeaderAvailable={isSectionHeaderAvailable} + infoPanelIsVisible={infoPanelIsVisible} > `solid 1px ${props.theme.infoPanel.borderColor}`}; - border-radius: 6px; img { + border: ${(props) => `solid 1px ${props.theme.infoPanel.borderColor}`}; border-radius: 6px; - width: 100%; + //width: 100%; + width: auto; + max-width: 100%; height: auto; } `; diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js index 9261a61e68..c6e78706e1 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/RowsView/SimpleFilesRow.js @@ -97,8 +97,8 @@ const StyledSimpleFilesRow = styled(Row)` } .row_content { - ${(props) => props.sectionWidth > 500 && `max-width: fit-content;`} - min-width: auto; + ${(props) => + props.sectionWidth > 500 && `max-width: fit-content;`}//min-width: auto;; } .badges { From 5220e96b7e5c218c0e2783b1f93f7f04bf281c60 Mon Sep 17 00:00:00 2001 From: Eugene Kozyrev <67453079+EugeneKozyrev@users.noreply.github.com> Date: Wed, 6 Apr 2022 11:17:26 +0300 Subject: [PATCH 64/81] Add elasticsearch connection check (#606) --- build/install/win/AppServer.aip | 70 +++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/build/install/win/AppServer.aip b/build/install/win/AppServer.aip index b6ff919de0..66777e5387 100644 --- a/build/install/win/AppServer.aip +++ b/build/install/win/AppServer.aip @@ -22,6 +22,10 @@ + + + + @@ -231,6 +235,7 @@ + @@ -243,6 +248,21 @@ + + + + + + + + + + + + + + + @@ -280,11 +300,11 @@ - - + + - + @@ -305,23 +325,40 @@ - - + + - - + + - - + + - - - - + + + + + + + + + + + + + + + + + + + + + @@ -331,6 +368,8 @@ + + @@ -388,9 +427,14 @@ + + + + + From 48240c6f778db5b577930c7bf90bb0694dfe088a Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Wed, 6 Apr 2022 12:37:15 +0300 Subject: [PATCH 65/81] Web:Studio:Added locales en PleaseNote, PleaseNoteDescription, PortalRenaming, PortalRenamingDescription, PortalRenamingDescriptionTooltip, PortalRenamingLabelText, PortalRenamingSettingsTooltip. Added tooltip PortalRenamingTooltip. --- .../public/locales/en/Settings.json | 7 +++ .../settingsCustomization/portal-renaming.js | 20 +++--- .../common/sub-components/common-tooltips.js | 61 ++++++++++++++++--- 3 files changed, 68 insertions(+), 20 deletions(-) diff --git a/web/ASC.Web.Client/public/locales/en/Settings.json b/web/ASC.Web.Client/public/locales/en/Settings.json index d0e9321f10..19a982a6d4 100644 --- a/web/ASC.Web.Client/public/locales/en/Settings.json +++ b/web/ASC.Web.Client/public/locales/en/Settings.json @@ -89,12 +89,19 @@ "NotFoundTitle": "Nothing found", "PasswordMinLenght": "Minimal password length", "Path": "Path", + "PleaseNote": "Please note", + "PleaseNoteDescription": " <0>{{pleaseNote}}: your old portal address will become available to new ©linney users once you click the <2>{{save}} button.", "PeopleAdministratorsCan": "People module admins can create profiles and groups, import people, and invite users.", "PortalAccess": "Portal access", "PortalAccessSubTitle": "This section allows you to provide users with safe and convenient ways to access the portal.", "PortalAdmins": "Portal admins", "PortalAdminsDescription": "Have the same access rights as the portal owner, except the right to: change portal owner; deactivate or delete portal.", "PortalOwner": "Portal Owner", + "PortalRenaming": "Portal Renaming", + "PortalRenamingDescription": "Here you can change your portal address.", + "PortalRenamingDescriptionTooltip": "Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.", + "PortalRenamingLabelText": "New portal name", + "PortalRenamingSettingsTooltip": "<0>{{text}} Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.", "ProductUserOpportunities": "View profiles and groups", "RegistrationDate": "Registration date", "RestoreBackup": "Data Restore", diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js index dbcdcb537b..6679e31feb 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js @@ -17,6 +17,7 @@ import Text from "@appserver/components/text"; import Link from "@appserver/components/link"; import { isSmallTablet } from "@appserver/components/utils/device"; import checkScrollSettingsBlock from "../utils"; +import { PortalRenamingTooltip } from "../sub-components/common-tooltips"; import { StyledSettingsComponent, StyledScrollbar, @@ -174,12 +175,14 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { } }; - // TODO: Move to a file const onClickLink = (e) => { e.preventDefault(); history.push(e.target.pathname); }; + const tooltipPortalRenamingTooltip = ; + const hasError = errorValue === null ? false : true; + const isMobileViewPortalRenaming = (
@@ -192,26 +195,22 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { "/settings/common/customization/portal-renaming" )} > - Portal Renaming - {/* {t("CustomTitlesWelcome")} */} + {t("PortalRenaming")}
- {/* {t("CustomTitlesSettingsDescription")} */} - Here you can change your portal address. + {t("PortalRenamingDescription")}
); - const hasError = errorValue === null ? false : true; - const settingsBlock = (
{ value={portalName} onChange={onChangePortalName} // isDisabled={isLoadingGreetingSave || isLoadingGreetingRestore} - placeholder={`${t("room")}`} hasError={hasError} />
{errorValue}
@@ -236,11 +234,11 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { {checkInnerWidth() && !isMobileView && (
-
{t("Portal Renaming")}
+
{t("PortalRenaming")}
)} diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/common-tooltips.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/common-tooltips.js index 585f28e08b..d1cc69deac 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/common-tooltips.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/common-tooltips.js @@ -11,10 +11,10 @@ const StyledTooltip = styled.div` .bold { font-weight: 600; } - .display { + .display-inline { display: inline; } - .display-link { + .display-block { display: block; } `; @@ -28,7 +28,7 @@ export const LanguageTimeSettingsTooltip = ({ t, theme }) => { - {{ text }}{" "} + {{ text }}{" "} @@ -39,10 +39,13 @@ export const LanguageTimeSettingsTooltip = ({ t, theme }) => { save={save} > {" "} - {{ save }}{" "} + + {" "} + {{ save }} + {" "} @@ -69,9 +72,12 @@ export const CustomTitlesTooltip = ({ t }) => { text={text} from={from} > - {{ welcomeText }}{" "} - {{ text }}{" "} - {{ from }}{" "} + + {" "} + {{ welcomeText }} + {" "} + {{ text }}{" "} + {{ from }}{" "} @@ -81,7 +87,44 @@ export const CustomTitlesTooltip = ({ t }) => { header={header} > {" "} - {{ header }}{" "} + + {" "} + {{ header }} + {" "} + + + + ); +}; + +export const PortalRenamingTooltip = ({ t }) => { + const text = t("Settings:PortalRenamingDescription"); + const pleaseNote = t("Settings:PleaseNote"); + const save = t("Common:SaveButton"); + + return ( + + + + {{ text }}{" "} + + + + + + {" "} + {{ pleaseNote }} + {" "} + {{ save }}{" "} From 3bf51c882b18c3555782e7b558a1d8d7b8a1bddd Mon Sep 17 00:00:00 2001 From: gopienkonikita Date: Wed, 6 Apr 2022 14:34:00 +0300 Subject: [PATCH 66/81] Web: Components: fixed table resize --- .../table-container/StyledTableContainer.js | 2 +- .../table-container/TableHeader.js | 38 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/asc-web-components/table-container/StyledTableContainer.js b/packages/asc-web-components/table-container/StyledTableContainer.js index 459afead08..2756c79a75 100644 --- a/packages/asc-web-components/table-container/StyledTableContainer.js +++ b/packages/asc-web-components/table-container/StyledTableContainer.js @@ -7,7 +7,7 @@ import { isMobile } from "react-device-detect"; const StyledTableContainer = styled.div` -moz-user-select: none; - width: calc(100% - 5px); + width: 100%; max-width: 100%; margin-top: -19px; diff --git a/packages/asc-web-components/table-container/TableHeader.js b/packages/asc-web-components/table-container/TableHeader.js index a6558643aa..54b7ed9809 100644 --- a/packages/asc-web-components/table-container/TableHeader.js +++ b/packages/asc-web-components/table-container/TableHeader.js @@ -117,7 +117,7 @@ class TableHeader extends React.Component { const column2Width = this.getSubstring(widths[colIndex]); const defaultColumn = document.getElementById("column_" + colIndex); - if (defaultColumn.dataset.defaultSize) return; + if (!defaultColumn || defaultColumn.dataset.defaultSize) return; if (column2Width + offset >= defaultMinColumnSize) { widths[+columnIndex] = newWidth + "px"; @@ -236,8 +236,8 @@ class TableHeader extends React.Component { const storageSize = !resetColumnsSize && localStorage.getItem(columnStorageName); - const defaultSize = this.props.columns.find((col) => col.defaultSize) - ?.defaultSize; + const defaultSize = + this.props.columns.find((col) => col.defaultSize)?.defaultSize || 0; //TODO: Fixed columns size if something went wrong if (storageSize) { @@ -262,9 +262,12 @@ class TableHeader extends React.Component { const containerWidth = +container.clientWidth; - const oldWidth = tableContainer - .map((column) => this.getSubstring(column)) - .reduce((x, y) => x + y); + const oldWidth = + tableContainer + .map((column) => this.getSubstring(column)) + .reduce((x, y) => x + y) - + defaultSize - + settingsSize; let str = ""; @@ -278,7 +281,7 @@ class TableHeader extends React.Component { const enable = index == tableContainer.length - 1 || (column ? column.dataset.enable === "true" : item !== "0px"); - const defaultSize = column && column.dataset.defaultSize; + const defaultColumnSize = column && column.dataset.defaultSize; const isActiveNow = item === "0px" && enable; if (isActiveNow && column) activeColumnIndex = index; @@ -301,18 +304,14 @@ class TableHeader extends React.Component { } else if (item !== `${settingsSize}px`) { const percent = (this.getSubstring(item) / oldWidth) * 100; - if (index == 1) { - const newItemWidth = (containerWidth * percent) / 100 + "px"; - gridTemplateColumns.push(newItemWidth); - } else { - const newItemWidth = defaultSize - ? `${defaultSize}px` - : percent === 0 - ? `${minColumnSize}px` - : (containerWidth * percent) / 100 + "px"; + const newItemWidth = defaultColumnSize + ? `${defaultColumnSize}px` + : percent === 0 + ? `${minColumnSize}px` + : ((containerWidth - defaultSize - settingsSize) * percent) / 100 + + "px"; - gridTemplateColumns.push(newItemWidth); - } + gridTemplateColumns.push(newItemWidth); } else { gridTemplateColumns.push(item); } @@ -351,7 +350,8 @@ class TableHeader extends React.Component { const enableColumns = this.props.columns .filter((x) => x.enable) - .filter((x) => !x.defaultSize); + .filter((x) => !x.defaultSize) + .filter((x) => !x.default); const container = containerRef.current ? containerRef.current From 1755d03b4e320c46050c60c3af470ac08c7ad18e Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Wed, 6 Apr 2022 17:07:48 +0300 Subject: [PATCH 67/81] Web:Studio:Styling Settings. Added locales en PortalRenamingMobile. --- .../public/locales/en/Settings.json | 1 + .../settingsCustomization/StyledSettings.js | 16 ++++++ .../language-and-time-zone.js | 2 - .../settingsCustomization/portal-renaming.js | 49 +++++++++---------- .../Settings/categories/common/whitelabel.js | 2 +- 5 files changed, 40 insertions(+), 30 deletions(-) diff --git a/web/ASC.Web.Client/public/locales/en/Settings.json b/web/ASC.Web.Client/public/locales/en/Settings.json index 19a982a6d4..4f9a7aca71 100644 --- a/web/ASC.Web.Client/public/locales/en/Settings.json +++ b/web/ASC.Web.Client/public/locales/en/Settings.json @@ -101,6 +101,7 @@ "PortalRenamingDescription": "Here you can change your portal address.", "PortalRenamingDescriptionTooltip": "Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.", "PortalRenamingLabelText": "New portal name", + "PortalRenamingMobile": "Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address. Please note: your old portal address will become available to new ©linney users once you click the Save button.", "PortalRenamingSettingsTooltip": "<0>{{text}} Enter the part that will appear next to the onlyoffice.com/onlyoffice.eu portal address.", "ProductUserOpportunities": "View profiles and groups", "RegistrationDate": "Registration date", diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js index 91834ddd5b..ea46eb77c4 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js @@ -54,6 +54,12 @@ const StyledSettingsComponent = styled.div` line-height: 20px; } + .errorText { + position: absolute; + font-size: 10px; + color: #f21c0e; + } + @media (max-width: 599px) { ${(props) => props.hasScroll && @@ -68,6 +74,12 @@ const StyledSettingsComponent = styled.div` padding-left: 16px; } `} + + .settings-block-description { + line-height: 20px; + color: #657077; + padding-bottom: 12px; + } } @media (min-width: 600px) { @@ -75,6 +87,10 @@ const StyledSettingsComponent = styled.div` max-width: 350px; height: auto; } + + .settings-block-description { + display: none; + } } @media (orientation: landscape) and (max-width: 600px) { diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js index 1334cd4fb4..ba692cb984 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js @@ -90,8 +90,6 @@ class LanguageAndTimeZone extends React.Component { timezoneDefault: timezoneDefaultFromSessionStorage || timezone, language: languageFromSessionStorage || language, languageDefault: languageDefaultFromSessionStorage || language, - isLoadingGreetingSave: false, - isLoadingGreetingRestore: false, hasChanged: false, showReminder: false, hasScroll: false, diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js index 6679e31feb..09f11855da 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js @@ -25,27 +25,6 @@ import { } from "./StyledSettings"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; -const StyledComponent = styled.div` - .settings-block { - margin-bottom: 70px; - } - - .settings-block { - max-width: 350px; - } - - .combo-button-label { - max-width: 100%; - } - - .error { - font-weight: 400; - font-size: 10px; - line-height: 14px; - color: #f21c0e; - } -`; - const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { // TODO: Change false const [isLoadedData, setIsLoadedData] = useState(true); @@ -84,6 +63,15 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { setHasScroll(scrollPortalName); } + // TODO: Remove div with height 64 and remove settings-mobile class + const settingsMobile = document.getElementsByClassName( + "settings-mobile" + )[0]; + + if (settingsMobile) { + settingsMobile.style.display = "none"; + } + return () => window.removeEventListener( "resize", @@ -136,7 +124,8 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { saveToSessionStorage("errorValue", lengthNameError); break; default: - setErrorValue(""); + saveToSessionStorage("errorValue", null); + setErrorValue(null); } }; @@ -207,6 +196,9 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { const settingsBlock = (
+
+ {t("PortalRenamingMobile")} +
{ scale={true} value={portalName} onChange={onChangePortalName} - // isDisabled={isLoadingGreetingSave || isLoadingGreetingRestore} + isDisabled={isLoadingPortalNameSave} hasError={hasError} /> -
{errorValue}
+
{errorValue}
); @@ -231,7 +223,10 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { isMobileViewPortalRenaming ) : ( <> - + {checkInnerWidth() && !isMobileView && (
{t("PortalRenaming")}
@@ -256,9 +251,9 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { showReminder={showReminder} reminderTest={t("YouHaveUnsavedChanges")} displaySettings={true} - // hasScroll={hasScroll} + hasScroll={hasScroll} /> - + ); }; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js index c07ac084a1..05b3533c07 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/whitelabel.js @@ -302,7 +302,7 @@ class WhiteLabel extends React.Component { } = this.state; console.log("WhiteLabelSettings render"); - return <> В разработке; + return <>In development; return !isLoadedData ? ( From 8252bce3109dae86ede3d1d763d4bdfdac7c43f0 Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Wed, 6 Apr 2022 20:26:20 +0300 Subject: [PATCH 68/81] Fix Bug 54901 - Docs: Desktop. infinite loader on Linux --- web/ASC.Web.Editor/src/Editor.jsx | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/web/ASC.Web.Editor/src/Editor.jsx b/web/ASC.Web.Editor/src/Editor.jsx index b325e999c2..08ed8f456e 100644 --- a/web/ASC.Web.Editor/src/Editor.jsx +++ b/web/ASC.Web.Editor/src/Editor.jsx @@ -238,7 +238,6 @@ const Editor = () => { data: "backup-restore", }); socketHelper.on("restore-backup", () => { - setPreparationPortalDialogVisible(true); }); } catch (e) { @@ -625,20 +624,23 @@ const Editor = () => { const onSDKAppReady = () => { console.log("ONLYOFFICE Document Editor is ready"); - const index = url.indexOf("#message/"); - if (index > -1) { - const splitUrl = url.split("#message/"); - const message = decodeURIComponent(splitUrl[1]).replaceAll("+", " "); - history.pushState({}, null, url.substring(0, index)); - docEditor.showMessage(message); - } else { - if (config?.Error) docEditor.showMessage(config.Error); - } - const tempElm = document.getElementById("loader"); if (tempElm) { tempElm.outerHTML = ""; } + + const index = url.indexOf("#message/"); + if (index > -1) { + const splitUrl = url.split("#message/"); + if (splitUrl.length === 2) { + let raw = splitUrl[1]?.trim(); + const message = decodeURIComponent(raw).replace(/\+/g, " "); + docEditor.showMessage(message); + history.pushState({}, null, url.substring(0, index)); + } + } else { + if (config?.Error) docEditor.showMessage(config.Error); + } }; const onSDKInfo = (event) => { @@ -961,7 +963,9 @@ const Editor = () => { )} {preparationPortalDialogVisible && ( - + )} ) : ( From 22181e08d717bae4b1cdc2d2a01712700d72ce54 Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Wed, 6 Apr 2022 21:08:08 +0300 Subject: [PATCH 69/81] Web: Files: Restore thumbnail-image cover and increased thumbnaillHeight and thumbnaillWidth for Info Panel --- config/appsettings.json | 4 ++-- .../pages/Home/Section/Body/TilesView/sub-components/Tile.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/appsettings.json b/config/appsettings.json index 6a78550fd8..aca23564ab 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -317,7 +317,7 @@ "enabled": "true" }, "thumbnail": { - "thumbnaillHeight": 156, - "thumbnaillWidth": 216 + "thumbnaillHeight": 260, + "thumbnaillWidth": 360 } } diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js index ec2f040f74..6dffadeb38 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js @@ -152,7 +152,7 @@ const StyledFileTileTop = styled.div` position: absolute; height: 100%; width: 100%; - object-fit: ${(props) => (props.isMedia ? "cover" : "none")}; + object-fit: cover; object-position: top; z-index: 0; } From b135de806f80494c6f30c6101011d88b0f138b3d Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Wed, 6 Apr 2022 21:16:44 +0300 Subject: [PATCH 70/81] Web: Files: Fix borders on thumbnails --- .../pages/Home/Section/Body/TilesView/sub-components/Tile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js index 6dffadeb38..c0d8b0da60 100644 --- a/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js +++ b/products/ASC.Files/Client/src/pages/Home/Section/Body/TilesView/sub-components/Tile.js @@ -146,6 +146,7 @@ const StyledFileTileTop = styled.div` align-items: baseline; height: 156px; position: relative; + border-radius: 6px 6px 0 0; .thumbnail-image { pointer-events: none; @@ -155,6 +156,7 @@ const StyledFileTileTop = styled.div` object-fit: cover; object-position: top; z-index: 0; + border-radius: 6px 6px 0 0; } .temporary-icon > .injected-svg { From 406c07d8af6f75ee11539a26fb8cda8017529eca Mon Sep 17 00:00:00 2001 From: Alexey Safronov Date: Wed, 6 Apr 2022 21:25:10 +0300 Subject: [PATCH 71/81] Config: Restored formatting --- config/appsettings.json | 482 ++++++++++++++-------------------------- 1 file changed, 162 insertions(+), 320 deletions(-) diff --git a/config/appsettings.json b/config/appsettings.json index aca23564ab..0e4ae5e01b 100644 --- a/config/appsettings.json +++ b/config/appsettings.json @@ -1,323 +1,165 @@ { - "Logging": { - "LogLevel": { - "Default": "Information", - "Microsoft": "Warning", - "Microsoft.Hosting.Lifetime": "Information" + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + }, + "EventLog": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } }, - "EventLog": { - "LogLevel": { - "Default": "Information", - "Microsoft.Hosting.Lifetime": "Information" - } + "AllowedHosts": "*", + "core": { + "base-domain": "", + "machinekey": "1123askdasjklasbnd", + "notify": { + "postman": "log" + }, + "payment": { + "delay": "10", + "partners": "https://partners.teamlab.info/api", + "region": "test", + "test": true + }, + "personal": false, + "products": { + "folder": "../../products", + "subfolder": "Server" + } + }, + "license": { + "file": { + "path": "" + } + }, + "mail": { + "certificate-permit": false, + "daemon-email": "mail-daemon@onlyoffice.com", + "server-mailbox-limit-per-user": 2 + }, + "messaging": { + "enabled": "enabled" + }, + "version": { + "number": "11.5.0", + "release": { + "date": "", + "sign": "" + } + }, + "files": { + "thirdparty": { + "enable": [ "box", "dropboxv2", "docusign", "google", "onedrive", "sharepoint", "nextcloud", "owncloud", "webdav", "kdrive", "yandex" ] + }, + "docservice": { + "coauthor-docs": [ ".pptx", ".ppsx", ".xlsx", ".csv", ".docx", ".docxf", ".oform", ".txt" ], + "commented-docs": [ ".docx", ".docxf", ".xlsx", ".pptx" ], + "convert-docs": [ ".pptm", ".ppt", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".rtf" ], + "edited-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".txt", ".rtf", ".mht", ".html", ".htm" ], + "encrypted-docs": [ ".docx", ".docxf", ".xlsx", ".pptx", ".oform" ], + "formfilling-docs": [ ".oform" ], + "customfilter-docs": [ ".xlsx" ], + "reviewed-docs": [ ".docx", ".docxf" ], + "viewed-docs": [ ".pptx", ".pptm", ".ppt", ".ppsx", ".ppsm", ".pps", ".potx", ".potm", ".pot", ".odp", ".fodp", ".otp", ".gslides", ".xlsx", ".xlsm", ".xls", ".xltx", ".xltm", ".xlt", ".ods", ".fods", ".ots", ".gsheet", ".csv", ".docx", ".docxf", ".oform", ".docm", ".doc", ".dotx", ".dotm", ".dot", ".odt", ".fodt", ".ott", ".gdoc", ".txt", ".rtf", ".mht", ".html", ".htm", ".epub", ".pdf", ".djvu", ".xps" ], + "secret": { + "value": "", + "header": "" + }, + "url": { + "public": "http://localhost:8085/", + "internal": "", + "portal": "" + } + }, + "ffmpeg": { + "value": "", + "exts": [ "avi", "mpeg", "mpg", "wmv" ] + }, + "uploader": { + "chunk-size": 10485760, + "url": "products/files/" + }, + "viewed-images": [ ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ico", ".tif", ".tiff", ".webp" ], + "viewed-media": [ ".aac", ".flac", ".m4a", ".mp3", ".oga", ".ogg", ".wav", ".f4v", ".m4v", ".mov", ".mp4", ".ogv", ".webm" ], + "index": [ ".pptx", ".xlsx", ".docx" ] + }, + "web": { + "api": "api/2.0", + "alias": { + "min": "" + }, + "images": "images", + "hide-settings": "Monitoring,LdapSettings,DocService,MailService,PublicPortal,ProxyHttpContent,SpamSubscription,FullTextSearch", + "hub": { + "url": "/socket.io", + "internal": "http://localhost:9899/" + }, + "cultures": "de,en,fr,it,pt-BR,ru", + "url-shortener": { + "value": "/sh/", + "internal": "http://localhost:9999/" + }, + "controlpanel": { + "url": "" + }, + "support-feedback": "https://helpdesk.onlyoffice.com", + "teamlab-site": "http://www.onlyoffice.com" + }, + "ConnectionStrings": { + "default": { + "name": "default", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "providerName": "MySql.Data.MySqlClient" + }, + "postgre": { + "name": "postgre", + "connectionString": "Host=localhost;Port=5432;Database=onlyoffice;Username=postgres;Password=dev;", + "providerName": "Npgsql" + }, + "mysql": { + "name": "mysql", + "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", + "providerName": "MySql.Data.MySqlClient" + } + }, + "migration": { + "enabled": "false" + }, + "DbProviderFactories": { + "mysql": { + "name": "MySQL Data Provider", + "invariant": "MySql.Data.MySqlClient", + "description": ".Net Framework Data Provider for MySQL", + "type": "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" + } + }, + "bookmarking": { + "thumbnail-url": "http://localhost:9800/?url={0}" + }, + "storage": { + "encryption": { + "progressfile": "false", + "tempdir": "" + } + }, + "firebase": { + "apiKey": "", + "authDomain": "", + "projectId": "", + "storageBucket": "", + "messagingSenderId": "", + "appId": "", + "measurementId": "" + }, + "debug-info": { + "enabled": "true" + }, + "thumbnail": { + "thumbnaillHeight": 260, + "thumbnaillWidth": 360 } - }, - "AllowedHosts": "*", - "core": { - "base-domain": "", - "machinekey": "1123askdasjklasbnd", - "notify": { - "postman": "log" - }, - "payment": { - "delay": "10", - "partners": "https://partners.teamlab.info/api", - "region": "test", - "test": true - }, - "personal": false, - "products": { - "folder": "../../products", - "subfolder": "Server" - } - }, - "license": { - "file": { - "path": "" - } - }, - "mail": { - "certificate-permit": false, - "daemon-email": "mail-daemon@onlyoffice.com", - "server-mailbox-limit-per-user": 2 - }, - "messaging": { - "enabled": "enabled" - }, - "version": { - "number": "11.5.0", - "release": { - "date": "", - "sign": "" - } - }, - "files": { - "thirdparty": { - "enable": [ - "box", - "dropboxv2", - "docusign", - "google", - "onedrive", - "sharepoint", - "nextcloud", - "owncloud", - "webdav", - "kdrive", - "yandex" - ] - }, - "docservice": { - "coauthor-docs": [ - ".pptx", - ".ppsx", - ".xlsx", - ".csv", - ".docx", - ".docxf", - ".oform", - ".txt" - ], - "commented-docs": [".docx", ".docxf", ".xlsx", ".pptx"], - "convert-docs": [ - ".pptm", - ".ppt", - ".ppsm", - ".pps", - ".potx", - ".potm", - ".pot", - ".odp", - ".fodp", - ".otp", - ".xlsm", - ".xls", - ".xltx", - ".xltm", - ".xlt", - ".ods", - ".fods", - ".ots", - ".docm", - ".doc", - ".dotx", - ".dotm", - ".dot", - ".odt", - ".fodt", - ".ott", - ".rtf" - ], - "edited-docs": [ - ".pptx", - ".pptm", - ".ppt", - ".ppsx", - ".ppsm", - ".pps", - ".potx", - ".potm", - ".pot", - ".odp", - ".fodp", - ".otp", - ".xlsx", - ".xlsm", - ".xls", - ".xltx", - ".xltm", - ".xlt", - ".ods", - ".fods", - ".ots", - ".csv", - ".docx", - ".docxf", - ".oform", - ".docm", - ".doc", - ".dotx", - ".dotm", - ".dot", - ".odt", - ".fodt", - ".ott", - ".txt", - ".rtf", - ".mht", - ".html", - ".htm" - ], - "encrypted-docs": [".docx", ".docxf", ".xlsx", ".pptx", ".oform"], - "formfilling-docs": [".oform"], - "customfilter-docs": [".xlsx"], - "reviewed-docs": [".docx", ".docxf"], - "viewed-docs": [ - ".pptx", - ".pptm", - ".ppt", - ".ppsx", - ".ppsm", - ".pps", - ".potx", - ".potm", - ".pot", - ".odp", - ".fodp", - ".otp", - ".gslides", - ".xlsx", - ".xlsm", - ".xls", - ".xltx", - ".xltm", - ".xlt", - ".ods", - ".fods", - ".ots", - ".gsheet", - ".csv", - ".docx", - ".docxf", - ".oform", - ".docm", - ".doc", - ".dotx", - ".dotm", - ".dot", - ".odt", - ".fodt", - ".ott", - ".gdoc", - ".txt", - ".rtf", - ".mht", - ".html", - ".htm", - ".epub", - ".pdf", - ".djvu", - ".xps" - ], - "secret": { - "value": "", - "header": "" - }, - "url": { - "public": "http://localhost:8085/", - "internal": "", - "portal": "" - } - }, - "ffmpeg": { - "value": "", - "exts": ["avi", "mpeg", "mpg", "wmv"] - }, - "uploader": { - "chunk-size": 10485760, - "url": "products/files/" - }, - "viewed-images": [ - ".bmp", - ".gif", - ".jpeg", - ".jpg", - ".png", - ".ico", - ".tif", - ".tiff", - ".webp" - ], - "viewed-media": [ - ".aac", - ".flac", - ".m4a", - ".mp3", - ".oga", - ".ogg", - ".wav", - ".f4v", - ".m4v", - ".mov", - ".mp4", - ".ogv", - ".webm" - ], - "index": [".pptx", ".xlsx", ".docx"] - }, - "web": { - "api": "api/2.0", - "alias": { - "min": "" - }, - "images": "images", - "hide-settings": "Monitoring,LdapSettings,DocService,MailService,PublicPortal,ProxyHttpContent,SpamSubscription,FullTextSearch", - "hub": { - "url": "/socket.io", - "internal": "http://localhost:9899/" - }, - "cultures": "de,en,fr,it,pt-BR,ru", - "url-shortener": { - "value": "/sh/", - "internal": "http://localhost:9999/" - }, - "controlpanel": { - "url": "" - }, - "support-feedback": "https://helpdesk.onlyoffice.com", - "teamlab-site": "http://www.onlyoffice.com" - }, - "ConnectionStrings": { - "default": { - "name": "default", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", - "providerName": "MySql.Data.MySqlClient" - }, - "postgre": { - "name": "postgre", - "connectionString": "Host=localhost;Port=5432;Database=onlyoffice;Username=postgres;Password=dev;", - "providerName": "Npgsql" - }, - "mysql": { - "name": "mysql", - "connectionString": "Server=localhost;Database=onlyoffice;User ID=dev;Password=dev;Pooling=true;Character Set=utf8;AutoEnlist=false;SSL Mode=none;AllowPublicKeyRetrieval=True;ConnectionReset=false", - "providerName": "MySql.Data.MySqlClient" - } - }, - "migration": { - "enabled": "false" - }, - "DbProviderFactories": { - "mysql": { - "name": "MySQL Data Provider", - "invariant": "MySql.Data.MySqlClient", - "description": ".Net Framework Data Provider for MySQL", - "type": "MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" - } - }, - "bookmarking": { - "thumbnail-url": "http://localhost:9800/?url={0}" - }, - "storage": { - "encryption": { - "progressfile": "false", - "tempdir": "" - } - }, - "firebase": { - "apiKey": "AIzaSyBpwXzH4toHP5Dr38DmwjsY9VqS4fTk4FM", - "authDomain": "appserver-c011a.firebaseapp.com", - "projectId": "appserver-c011a", - "storageBucket": "appserver-c011a.appspot.com", - "messagingSenderId": "92050394157", - "appId": "1:92050394157:web:da52e02c3eef65e5ca7ca4", - "measurementId": "G-7MEFVW27MJ" - }, - "debug-info": { - "enabled": "true" - }, - "thumbnail": { - "thumbnaillHeight": 260, - "thumbnaillWidth": 360 - } -} +} \ No newline at end of file From a68d6ffcdf99888c6eb3bef6632edec7c9aafd2d Mon Sep 17 00:00:00 2001 From: gazizova-vlada Date: Wed, 6 Apr 2022 22:27:25 +0300 Subject: [PATCH 72/81] Web:Studio:Added PortalRenaming to settingsTree. Refactoring Customization. --- .../categories/common/SettingsPageLayout.js | 76 ---------- .../common/SettingsPageMobileView.js | 40 ----- .../categories/common/customization-navbar.js | 137 ++++++++++++++++++ .../categories/common/customization.js | 69 +++++---- .../settingsCustomization/StyledSettings.js | 12 +- .../language-and-time-zone.js | 51 +------ .../settingsCustomization/portal-renaming.js | 103 +++++-------- .../welcome-page-settings.js | 36 +---- .../sub-components/loaderLngTZSettings.js | 15 ++ .../pages/Settings/utils/settingsTree.js | 4 +- 10 files changed, 243 insertions(+), 300 deletions(-) delete mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageLayout.js delete mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageMobileView.js create mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js create mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/common/sub-components/loaderLngTZSettings.js diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageLayout.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageLayout.js deleted file mode 100644 index 4eac160559..0000000000 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageLayout.js +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useEffect, useState } from "react"; -import styled from "styled-components"; -import { Base } from "@appserver/components/themes"; -import { isSmallTablet } from "@appserver/components/utils/device"; - -const StyledComponent = styled.div` - .combo-button-label { - max-width: 100%; - } - - .settings-block { - margin-bottom: 24px; - } - - .category-description { - line-height: 20px; - color: #657077; - margin-bottom: 20px; - } - - /* .category-item-wrapper:not(:last-child) { - border-bottom: 1px solid #eceef1; - margin-bottom: 24px; - } */ - - .category-item-description { - color: ${(props) => props.theme.studio.settings.common.descriptionColor}; - font-size: 12px; - max-width: 1024px; - } - - .category-item-heading { - display: flex; - align-items: center; - padding-bottom: 16px; - } - - .category-item-title { - font-weight: bold; - font-size: 16px; - line-height: 22px; - margin-right: 4px; - } - - @media (min-width: 600px) { - .settings-block { - max-width: 350px; - height: auto; - } - } -`; - -StyledComponent.defaultProps = { theme: Base }; - -const SettingsPageLayout = ({ children }) => { - const [mobileView, setMobileView] = useState(true); - - const checkInnerWidth = () => { - if (isSmallTablet()) { - setMobileView(true); - } else { - setMobileView(false); - } - }; - - useEffect(() => { - window.addEventListener("resize", checkInnerWidth); - return () => window.removeEventListener("resize", checkInnerWidth); - }, []); - - const isMobile = !!(isSmallTablet() && mobileView); - - return <>{children(isMobile)}; -}; - -export default SettingsPageLayout; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageMobileView.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageMobileView.js deleted file mode 100644 index 236f0efa22..0000000000 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/SettingsPageMobileView.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import { Base } from "@appserver/components/themes"; - -const StyledComponent = styled.div` - .combo-button-label { - max-width: 100%; - } - - .category-item-wrapper { - padding-top: 20px; - - .category-item-heading { - padding-bottom: 8px; - svg { - padding-bottom: 5px; - } - } - - .category-item-description { - color: #657077; - font-size: 13px; - max-width: 1024px; - } - - .inherit-title-link { - margin-right: 4px; - font-size: 16px; - font-weight: 700; - } - } -`; - -StyledComponent.defaultProps = { theme: Base }; - -const SettingsPageMobileView = ({ children }) => { - return {children}; -}; - -export default SettingsPageMobileView; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js new file mode 100644 index 0000000000..18e10239d3 --- /dev/null +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization-navbar.js @@ -0,0 +1,137 @@ +import React from "react"; +import { withTranslation } from "react-i18next"; +import styled from "styled-components"; +import Text from "@appserver/components/text"; +import Box from "@appserver/components/box"; +import Link from "@appserver/components/link"; +import { combineUrl } from "@appserver/common/utils"; +import { inject, observer } from "mobx-react"; +import { AppServerConfig } from "@appserver/common/constants"; +import withCultureNames from "@appserver/common/hoc/withCultureNames"; +import history from "@appserver/common/history"; +import { Base } from "@appserver/components/themes"; + +import { StyledArrowRightIcon } from "../common/settingsCustomization/StyledSettings"; + +const StyledComponent = styled.div` + padding-top: 13px; + + .combo-button-label { + max-width: 100%; + } + + .category-item-wrapper { + padding-bottom: 20px; + + .category-item-heading { + padding-bottom: 8px; + svg { + padding-bottom: 5px; + } + } + + .category-item-description { + color: #657077; + font-size: 13px; + max-width: 1024px; + } + + .inherit-title-link { + margin-right: 4px; + font-size: 16px; + font-weight: 700; + } + } +`; + +StyledComponent.defaultProps = { theme: Base }; + +const CustomizationNavbar = ({ t, theme, helpUrlCommonSettings }) => { + const onClickLink = (e) => { + e.preventDefault(); + history.push(e.target.pathname); + }; + return ( + +
+
+ + {t("StudioTimeLanguageSettings")} + + +
+ + {t("LanguageAndTimeZoneSettingsDescription")} + + + + {t("Common:LearnMore")} + + +
+
+
+ + {t("CustomTitlesWelcome")} + + +
+ + {t("CustomTitlesSettingsDescription")} + +
+
+
+ + {t("PortalRenaming")} + + +
+ + {t("PortalRenamingDescription")} + +
+
+ ); +}; + +export default inject(({ auth }) => { + const { helpUrlCommonSettings, theme } = auth.settingsStore; + return { + theme, + helpUrlCommonSettings, + }; +})( + withCultureNames( + observer(withTranslation(["Settings", "Common"])(CustomizationNavbar)) + ) +); diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js index 56ca23af23..dd6a0fade3 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/customization.js @@ -1,15 +1,14 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import { withTranslation } from "react-i18next"; import styled from "styled-components"; import withCultureNames from "@appserver/common/hoc/withCultureNames"; import LanguageAndTimeZone from "./settingsCustomization/language-and-time-zone"; import WelcomePageSettings from "./settingsCustomization/welcome-page-settings"; import PortalRenaming from "./settingsCustomization/portal-renaming"; - -import SettingsPageLayout from "./SettingsPageLayout"; -import SettingsPageMobileView from "./SettingsPageMobileView"; - +import { isSmallTablet } from "@appserver/components/utils/device"; +import CustomizationNavbar from "./customization-navbar"; import { Base } from "@appserver/components/themes"; +import { setDocumentTitle } from "../../../../../helpers/utils"; const StyledComponent = styled.div` .combo-button-label { @@ -24,12 +23,12 @@ const StyledComponent = styled.div` line-height: 20px; color: #657077; margin-bottom: 20px; + max-width: 700px; } .category-item-wrapper:not(:last-child) { border-bottom: 1px solid #eceef1; margin-bottom: 24px; - // Add padding-bottom: 24px; } @@ -63,28 +62,42 @@ const StyledComponent = styled.div` StyledComponent.defaultProps = { theme: Base }; const Customization = ({ t }) => { - return ( - - {(isMobile) => - isMobile ? ( - - - - - - ) : ( - -
{`${t( - "Settings:CustomizationDescription" - )}`}
- {/* TODO: Add isMobile = false in component */} - - - -
- ) - } -
+ const [mobileView, setMobileView] = useState(true); + const [isLoadingCustomization, setIsLoadingCustomization] = useState(true); + + const checkInnerWidth = () => { + if (isSmallTablet()) { + setMobileView(true); + } else { + setMobileView(false); + } + }; + + useEffect(() => { + setDocumentTitle(t("Customization")); + //TODO: add method to get the portal name + setIsLoadingCustomization(false); + + window.addEventListener("resize", checkInnerWidth); + return () => window.removeEventListener("resize", checkInnerWidth); + }, []); + + const isMobile = !!(isSmallTablet() && mobileView); + + return isMobile ? ( + + ) : ( + +
{`${t( + "Settings:CustomizationDescription" + )}`}
+ + + +
); }; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js index ea46eb77c4..ca1008a8ad 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/StyledSettings.js @@ -60,6 +60,12 @@ const StyledSettingsComponent = styled.div` color: #f21c0e; } + .settings-block-description { + line-height: 20px; + color: #657077; + padding-bottom: 12px; + } + @media (max-width: 599px) { ${(props) => props.hasScroll && @@ -74,12 +80,6 @@ const StyledSettingsComponent = styled.div` padding-left: 16px; } `} - - .settings-block-description { - line-height: 20px; - color: #657077; - padding-bottom: 12px; - } } @media (min-width: 600px) { diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js index ba692cb984..13662c6656 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/language-and-time-zone.js @@ -19,17 +19,10 @@ import { AppServerConfig } from "@appserver/common/constants"; import config from "../../../../../../../package.json"; import history from "@appserver/common/history"; import { isMobileOnly } from "react-device-detect"; -import Text from "@appserver/components/text"; -import Box from "@appserver/components/box"; -import Link from "@appserver/components/link"; import { isSmallTablet } from "@appserver/components/utils/device"; import checkScrollSettingsBlock from "../utils"; -import { - StyledSettingsComponent, - StyledScrollbar, - StyledArrowRightIcon, -} from "./StyledSettings"; - +import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; +import LoaderLngTZSettings from "../sub-components/loaderLngTZSettings"; const mapTimezonesToArray = (timezones) => { return timezones.map((timezone) => { return { key: timezone.id, label: timezone.displayName }; @@ -80,7 +73,7 @@ class LanguageAndTimeZone extends React.Component { "timezoneDefault" ); - setDocumentTitle(t("Customization")); + setDocumentTitle(t("StudioTimeLanguageSettings")); this.state = { isLoadedData: false, @@ -341,8 +334,9 @@ class LanguageAndTimeZone extends React.Component { theme, cultureNames, isMobileView, - helpUrlCommonSettings, + isLoadingCustomization, } = this.props; + const { isLoadedData, language, @@ -357,37 +351,6 @@ class LanguageAndTimeZone extends React.Component { ); - const isMobileViewLanguageTimeSettings = ( -
-
- - {t("StudioTimeLanguageSettings")} - - -
- - {t("LanguageAndTimeZoneSettingsDescription")} - - - - {t("Common:LearnMore")} - - -
- ); const settingsBlock = (
- ) : isMobileView ? ( - isMobileViewLanguageTimeSettings ) : ( { //getPortalCultures, getPortalTimezones, getCurrentCustomSchema, - helpUrlCommonSettings, } = auth.settingsStore; const { user } = auth.userStore; @@ -512,7 +472,6 @@ export default inject(({ auth, setup }) => { setLanguageAndTime, getCurrentCustomSchema, getPortalTimezones, - helpUrlCommonSettings, }; })( withCultureNames( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js index 09f11855da..dadc5d78e2 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/portal-renaming.js @@ -1,6 +1,5 @@ import React, { useState, useEffect } from "react"; import { withTranslation } from "react-i18next"; -import styled from "styled-components"; import Loader from "@appserver/components/loader"; import toastr from "@appserver/components/toast/toastr"; import HelpButton from "@appserver/components/help-button"; @@ -13,17 +12,12 @@ import { AppServerConfig } from "@appserver/common/constants"; import config from "../../../../../../../package.json"; import history from "@appserver/common/history"; import { isMobileOnly } from "react-device-detect"; -import Text from "@appserver/components/text"; -import Link from "@appserver/components/link"; import { isSmallTablet } from "@appserver/components/utils/device"; import checkScrollSettingsBlock from "../utils"; import { PortalRenamingTooltip } from "../sub-components/common-tooltips"; -import { - StyledSettingsComponent, - StyledScrollbar, - StyledArrowRightIcon, -} from "./StyledSettings"; +import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; import { saveToSessionStorage, getFromSessionStorage } from "../../../utils"; +import { setDocumentTitle } from "../../../../../../helpers/utils"; const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { // TODO: Change false @@ -52,6 +46,8 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { "The account name must be between 6 and 50 characters long"; useEffect(() => { + setDocumentTitle(t("PortalRenaming")); + const checkScroll = checkScrollSettingsBlock(); window.addEventListener("resize", checkInnerWidth); @@ -164,36 +160,9 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { } }; - const onClickLink = (e) => { - e.preventDefault(); - history.push(e.target.pathname); - }; - const tooltipPortalRenamingTooltip = ; const hasError = errorValue === null ? false : true; - const isMobileViewPortalRenaming = ( -
-
- - {t("PortalRenaming")} - - -
- - {t("PortalRenamingDescription")} - -
- ); - const settingsBlock = (
@@ -219,42 +188,38 @@ const PortalRenaming = ({ t, setPortalRename, isMobileView }) => { return !isLoadedData ? ( - ) : isMobileView ? ( - isMobileViewPortalRenaming ) : ( - <> - + {checkInnerWidth() && !isMobileView && ( +
+
{t("PortalRenaming")}
+ +
+ )} + {(isMobileOnly && isSmallTablet()) || isSmallTablet() ? ( + {settingsBlock} + ) : ( + <> {settingsBlock} + )} + - {checkInnerWidth() && !isMobileView && ( -
-
{t("PortalRenaming")}
- -
- )} - {(isMobileOnly && isSmallTablet()) || isSmallTablet() ? ( - {settingsBlock} - ) : ( - <> {settingsBlock} - )} - -
- + /> + ); }; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js index c932371371..c64ca67997 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/common/settingsCustomization/welcome-page-settings.js @@ -16,15 +16,10 @@ import { AppServerConfig } from "@appserver/common/constants"; import config from "../../../../../../../package.json"; import history from "@appserver/common/history"; import { isMobileOnly } from "react-device-detect"; -import Text from "@appserver/components/text"; -import Link from "@appserver/components/link"; import { isSmallTablet } from "@appserver/components/utils/device"; import checkScrollSettingsBlock from "../utils"; -import { - StyledSettingsComponent, - StyledScrollbar, - StyledArrowRightIcon, -} from "./StyledSettings"; +import { StyledSettingsComponent, StyledScrollbar } from "./StyledSettings"; +import LoaderLngTZSettings from "../sub-components/loaderLngTZSettings"; let greetingTitleFromSessionStorage = ""; let greetingTitleDefaultFromSessionStorage = ""; @@ -47,7 +42,7 @@ class WelcomePageSettings extends React.Component { "isFirstWelcomePageSettings" ); - setDocumentTitle(t("Customization")); + setDocumentTitle(t("CustomTitlesWelcome")); this.state = { isLoadedData: false, @@ -235,29 +230,6 @@ class WelcomePageSettings extends React.Component { const tooltipCustomTitlesTooltip = ; - // TODO: Move to a file - const isMobileViewWelcomePageSettings = ( -
-
- - {t("CustomTitlesWelcome")} - - -
- - {t("CustomTitlesSettingsDescription")} - -
- ); - const settingsBlock = (
- ) : isMobileView ? ( - isMobileViewWelcomePageSettings ) : ( { + return ( + + + + ); +}; + +export default LoaderLngTZSettings; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/utils/settingsTree.js b/web/ASC.Web.Client/src/components/pages/Settings/utils/settingsTree.js index 1f451341de..510ee24cd4 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/utils/settingsTree.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/utils/settingsTree.js @@ -32,8 +32,8 @@ export const settingsTree = [ { key: "0-0-2", icon: "", - link: "team-template", - tKey: "TeamTemplate", + link: "portal-renaming", + tKey: "PortalRenaming", }, ], }, From a502c4ee52cfbce1a52582f9daa644e11dc93a33 Mon Sep 17 00:00:00 2001 From: pavelbannov Date: Thu, 7 Apr 2022 08:41:58 +0300 Subject: [PATCH 73/81] IPRestrictionsRepository: fixed saving data --- common/ASC.IPSecurity/IPRestrictionsRepository.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/common/ASC.IPSecurity/IPRestrictionsRepository.cs b/common/ASC.IPSecurity/IPRestrictionsRepository.cs index 419aafcffa..c4cc851059 100644 --- a/common/ASC.IPSecurity/IPRestrictionsRepository.cs +++ b/common/ASC.IPSecurity/IPRestrictionsRepository.cs @@ -75,6 +75,7 @@ namespace ASC.IPSecurity }); TenantDbContext.TenantIpRestrictions.AddRange(ipsList); + TenantDbContext.SaveChanges(); tx.Commit(); return ips.ToList(); From b7344594eec2560989b845f18ec1971d59f05c35 Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 12:46:26 +0300 Subject: [PATCH 74/81] Web: Components: Submenu: delete paddings --- packages/asc-web-components/submenu/styled-submenu.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/asc-web-components/submenu/styled-submenu.js b/packages/asc-web-components/submenu/styled-submenu.js index 860bb59fb3..1f1453a839 100644 --- a/packages/asc-web-components/submenu/styled-submenu.js +++ b/packages/asc-web-components/submenu/styled-submenu.js @@ -37,10 +37,6 @@ export const StyledSubmenuItems = styled.div` display: flex; flex-direction: row; gap: 4px; - padding: 0 20px; - @media ${tablet} { - padding: 0 16px; - } overflow: hidden; &::-webkit-scrollbar { From 5c93fd9fbfe7e54ddabeb5d9b82a51384e2c1a5d Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 12:48:18 +0300 Subject: [PATCH 75/81] Web: Client: Settings: fix --- .../Settings/categories/security/access-portal/trustedMail.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js index 3b88cbea73..ee5cece034 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js @@ -130,7 +130,7 @@ const TrustedMail = (props) => { const onSaveClick = () => { const valid = domains.map((domain) => regexp.test(domain)); - if (valid.includes(false)) { + if (type === "1" && valid.includes(false)) { toastr.error(t("Common:IncorrectDomain")); return; } From fae0973b4a38cc82eb1e0ea6db4ce23093fa32eb Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 14:04:13 +0300 Subject: [PATCH 76/81] Web: Client: fix show errors --- .../security/sub-components/user-fields.js | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/user-fields.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/user-fields.js index 70445b2b41..49f78ee670 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/user-fields.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/user-fields.js @@ -1,4 +1,4 @@ -import React, { useState } from "react"; +import React, { useState, useEffect, useRef } from "react"; import styled from "styled-components"; import commonIconsStyles from "@appserver/components/utils/common-icons-style"; import { PlusIcon, TrashIcon } from "./svg"; @@ -38,6 +38,14 @@ const StyledAddWrapper = styled.div` cursor: pointer; `; +const usePrevious = (value) => { + const ref = useRef(); + useEffect(() => { + ref.current = value; + }, [value]); + return ref.current; +}; + const UserFields = (props) => { const { className, @@ -49,6 +57,33 @@ const UserFields = (props) => { regexp, } = props; + const [errors, setErrors] = useState(new Array(inputs.length).fill(false)); + const prevInputs = usePrevious(inputs.length); + + useEffect(() => { + if (inputs.length > prevInputs) setErrors([...errors, false]); + }, [inputs]); + + const onBlur = (index) => { + let newErrors = Array.from(errors); + newErrors[index] = true; + setErrors(newErrors); + }; + + const onFocus = (index) => { + let newErrors = Array.from(errors); + newErrors[index] = false; + setErrors(newErrors); + }; + + const onDelete = (index) => { + let newErrors = Array.from(errors); + newErrors.splice(index, 1); + setErrors(newErrors); + + onDeleteInput(index); + }; + return (
{inputs ? ( @@ -59,14 +94,14 @@ const UserFields = (props) => { onChangeInput(e, index)} - hasError={error} - /> - onDeleteInput(index)} + onBlur={() => onBlur(index)} + onFocus={() => onFocus(index)} + hasError={errors[index] && error} /> + onDelete(index)} /> ); }) From 0d612a533035ebb249fee2262f261d93ea585a9d Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 14:20:20 +0300 Subject: [PATCH 77/81] Web: Client: Settings: add learn more link in tooltip --- .../categories/security/StyledSecurity.js | 10 ++++++++++ .../categories/security/access-portal/index.js | 15 ++++++++++++--- .../security/access-portal/passwordStrength.js | 6 +----- .../categories/security/access-portal/tfa.js | 10 +--------- .../security/access-portal/trustedMail.js | 6 +----- .../security/sub-components/category-wrapper.js | 16 +++++++++++++--- 6 files changed, 38 insertions(+), 25 deletions(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js index 64246b3d37..cc21f96a08 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/StyledSecurity.js @@ -45,6 +45,12 @@ export const StyledCategoryWrapper = styled.div` align-items: center; `; +export const StyledTooltip = styled.div` + .subtitle { + margin-bottom: 10px; + } +`; + export const StyledMobileCategoryWrapper = styled.div` margin-bottom: 20px; @@ -115,4 +121,8 @@ export const LearnMoreWrapper = styled.div` flex-direction: column; margin-bottom: 20px; } + + .learn-subtitle { + margin-bottom: 10px; + } `; diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js index 732fb8cd3d..8c45a7ebde 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js @@ -10,6 +10,7 @@ import TrustedMailSection from "./trustedMail"; import MobileView from "./mobileView"; import CategoryWrapper from "../sub-components/category-wrapper"; import { size } from "@appserver/components/utils/device"; +import { getLanguage } from "@appserver/common/utils"; const AccessPortal = (props) => { const { t } = props; @@ -28,25 +29,33 @@ const AccessPortal = (props) => { : setIsMobileView(false); }; + const lng = getLanguage(localStorage.getItem("language") || "en"); + if (isMobileView) return ; return ( {t("PortalAccessSubTitle")}

diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js index dca0241e11..46ad5d89f4 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js @@ -20,10 +20,6 @@ import isEqual from "lodash/isEqual"; const MainContainer = styled.div` width: 100%; - .page-subtitle { - margin-bottom: 10px; - } - .password-slider { width: 160px; height: 8px; @@ -166,7 +162,7 @@ const PasswordStrength = (props) => { return ( - + {t("SettingPasswordStrengthHelper")} { @@ -117,7 +109,7 @@ const TwoFactorAuth = (props) => { return ( - {t("TwoFactorAuthHelper")} + {t("TwoFactorAuthHelper")} { return ( - {t("TrustedMailHelper")} + {t("TrustedMailHelper")} { - const { title, tooltipContent, theme } = props; + const { t, title, tooltipTitle, tooltipUrl, theme } = props; + + const tooltip = () => ( + + {tooltipTitle} + + {t("Common:LearnMore")} + + + ); return ( @@ -17,7 +27,7 @@ const CategoryWrapper = (props) => { displayType="dropdown" place="right" offsetRight={0} - tooltipContent={{tooltipContent}} + getContent={tooltip} tooltipColor={theme.studio.settings.security.owner.tooltipColor} /> From 0e4d12236e481c35ae7c8df159feac62d3d64bc0 Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 14:26:13 +0300 Subject: [PATCH 78/81] Web: Client: Settings: fix header title --- .../components/pages/Settings/Layout/Section/Header/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js index afa39d3d35..3bd814049f 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/Layout/Section/Header/index.js @@ -110,7 +110,7 @@ class SectionHeaderContent extends React.Component { const resultPath = locationPathname.slice(fullSettingsUrlLength + 1); const arrayOfParams = resultPath.split("/"); - const key = getKeyByLink(arrayOfParams, settingsTree); + const key = getKeyByLink(arrayOfParams, settingsTree)[0]; const header = getTKeyByKey(key, settingsTree); const isCategory = checkPropertyByLink( arrayOfParams, @@ -133,7 +133,7 @@ class SectionHeaderContent extends React.Component { componentDidUpdate() { const arrayOfParams = this.getArrayOfParams(); - const key = getKeyByLink(arrayOfParams, settingsTree); + const key = getKeyByLink(arrayOfParams, settingsTree)[0]; const header = getTKeyByKey(key, settingsTree); const isCategory = checkPropertyByLink( arrayOfParams, From eeac7377be864639bd92cf418a2db72ca8020cde Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 16:19:08 +0300 Subject: [PATCH 79/81] Web: Client: delete useless --- web/ASC.Web.Client/public/locales/en/Settings.json | 1 - web/ASC.Web.Client/public/locales/ru/Settings.json | 1 - .../categories/security/access-portal/trustedMail.js | 12 +----------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/web/ASC.Web.Client/public/locales/en/Settings.json b/web/ASC.Web.Client/public/locales/en/Settings.json index b88005ba60..82a33d9d45 100644 --- a/web/ASC.Web.Client/public/locales/en/Settings.json +++ b/web/ASC.Web.Client/public/locales/en/Settings.json @@ -147,7 +147,6 @@ "TrustedMail": "Trusted mail domain settings", "TrustedMailDescription": "Trusted Mail Domain Settings is a way to specify the mail servers used for user self-registration.", "TrustedMailHelper": "You can either check the Custom domains option and enter the trusted mail server in the field below so that a person who has an account at it will be able to register him(her)self by clicking the Join link on the Sign In page or disable this option.", - "TrustedMailWarningHelper": "Users with trusted email domains will automatically be listed in the Waiting Room section of the Address book.", "TwoFactorAuth": "Two-factor authentication", "TwoFactorAuthDescription": "Two-factor authentication provides a more secure way to log in. After entering the credentials, the user will have to enter a code from an SMS or the authentication app. ", "TwoFactorAuthHelper": "Note: SMS messages can be sent if you have a positive balance only. You can always check your current balance in your SMS provider account. Do not forget to replenish your balance in good time. ", diff --git a/web/ASC.Web.Client/public/locales/ru/Settings.json b/web/ASC.Web.Client/public/locales/ru/Settings.json index 2d1b9ad029..30ab5f716b 100644 --- a/web/ASC.Web.Client/public/locales/ru/Settings.json +++ b/web/ASC.Web.Client/public/locales/ru/Settings.json @@ -139,7 +139,6 @@ "TrustedMail": "Настройки доверенных почтовых доменов", "TrustedMailDescription": "Настройки доверенных почтовых доменов позволяют указать почтовые серверы, которые могут использовать пользователи при самостоятельной регистрации в ONLYOFFICE.", "TrustedMailHelper": "Можно отметить опцию Пользовательские домены и ввести доверенный почтовый сервер в поле ниже, чтобы любой сотрудник вашей компании, имеющий учетную запись на указанном почтовом сервере, смог зарегистрироваться самостоятельно, нажав ссылку Присоединиться на странице входа и введя адрес электронной почты с именем доверенного домена, который Вы добавили.", - "TrustedMailWarningHelper": "Пользователи с доверенными почтовыми доменами будут автоматически попадать в Waiting Room в разделе Address book.", "TwoFactorAuth": "Двухфакторная аутентификация", "TwoFactorAuthDescription": "Двухфакторная аутентификация обеспечивает более безопасный способ входа на портал. После ввода учетных данных пользователь должен будет ввести код из SMS или приложения для аутентификации.", "TwoFactorAuthHelper": "Обратите внимание: отправка SMS-сообщений осуществляется только при положительном балансе. Вы всегда можете проверить текущий баланс в учетной записи вашего SMS-провайдера. Не забывайте своевременно пополнять баланс. ", diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js index 85bdba7494..0e4462335e 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/trustedMail.js @@ -204,16 +204,6 @@ const TrustedMail = (props) => { /> )} - - {t("Common:Warning")}! - - {t("TrustedMailWarningHelper")} - { ); }; -export default inject(({ auth, setup }) => { +export default inject(({ auth }) => { const { trustedDomainsType, trustedDomains, From a97b34d144551f6e0bdbe31890ee17b82f712d9e Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 16:23:33 +0300 Subject: [PATCH 80/81] Web: Client: Settings: delete useless --- .../access-portal/passwordStrength.js | 3 +-- .../categories/security/access-portal/tfa.js | 2 -- .../security/sub-components/section-loader.js | 26 ------------------- 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/section-loader.js diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js index 46ad5d89f4..f77c7e56d0 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/passwordStrength.js @@ -8,7 +8,6 @@ import Text from "@appserver/components/text"; import Link from "@appserver/components/link"; import Slider from "@appserver/components/slider"; import Checkbox from "@appserver/components/checkbox"; -import SectionLoader from "../sub-components/section-loader"; import { getLanguage } from "@appserver/common/utils"; import { LearnMoreWrapper } from "../StyledSecurity"; import toastr from "@appserver/components/toast/toastr"; @@ -158,7 +157,7 @@ const PasswordStrength = (props) => { }; const lng = getLanguage(localStorage.getItem("language") || "en"); - if (!isLoading) return ; + return ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js index f7c1bb56c9..0a22c2ce4b 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/tfa.js @@ -7,7 +7,6 @@ import RadioButtonGroup from "@appserver/components/radio-button-group"; import Text from "@appserver/components/text"; import Link from "@appserver/components/link"; import toastr from "@appserver/components/toast/toastr"; -import SectionLoader from "../sub-components/section-loader"; import { getLanguage } from "@appserver/common/utils"; import Buttons from "../sub-components/buttons"; import { LearnMoreWrapper } from "../StyledSecurity"; @@ -105,7 +104,6 @@ const TwoFactorAuth = (props) => { }; const lng = getLanguage(localStorage.getItem("language") || "en"); - if (!isLoading) return ; return ( diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/section-loader.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/section-loader.js deleted file mode 100644 index 223763d718..0000000000 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/section-loader.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from "react"; -import styled from "styled-components"; -import Loaders from "@appserver/common/components/Loaders"; - -const StyledLoader = styled.div` - display: flex; - flex-direction: column; - gap: 8px; - width: 300px; - - @media (max-width: 375px) { - width: 100%; - } -`; - -const SectionLoader = () => { - return ( - - - - - - ); -}; - -export default SectionLoader; From c7a8ca73090d69cfcc2d0d47cf487f7bbefb3a36 Mon Sep 17 00:00:00 2001 From: Viktor Fomin Date: Thu, 7 Apr 2022 17:27:52 +0300 Subject: [PATCH 81/81] Web: Client: Settings: fix category wrapper --- .../categories/security/access-portal/index.js | 2 ++ .../security/sub-components/category-wrapper.js | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js index 6b2b1704e2..e23bdb157f 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/access-portal/index.js @@ -61,8 +61,10 @@ const AccessPortal = (props) => {
diff --git a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/category-wrapper.js b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/category-wrapper.js index 3f6bc63f74..2530ddbdf9 100644 --- a/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/category-wrapper.js +++ b/web/ASC.Web.Client/src/components/pages/Settings/categories/security/sub-components/category-wrapper.js @@ -10,10 +10,12 @@ const CategoryWrapper = (props) => { const tooltip = () => ( - {tooltipTitle} - - {t("Common:LearnMore")} - + {tooltipTitle} + {tooltipUrl && ( + + {t("Common:LearnMore")} + + )} );