Web: added catalog layout and document catalog
This commit is contained in:
parent
b324f5fbf4
commit
a5c57fea52
@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import RectangleLoader from '../RectangleLoader';
|
||||
import { StyledContainer, StyledBlock } from './StyledDocumentCatalogFolderLoader';
|
||||
|
||||
const DocumentCatalogFolderLoader = ({ id, className, style, ...rest }) => {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<StyledBlock id={id} className={className} style={style}>
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
</StyledBlock>
|
||||
<StyledBlock>
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
</StyledBlock>
|
||||
<StyledBlock>
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
</StyledBlock>
|
||||
<StyledBlock>
|
||||
<RectangleLoader width="100%" height="36px" {...rest} />
|
||||
</StyledBlock>
|
||||
</StyledContainer>
|
||||
);
|
||||
};
|
||||
|
||||
DocumentCatalogFolderLoader.propTypes = {
|
||||
id: PropTypes.string,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
};
|
||||
|
||||
DocumentCatalogFolderLoader.defaultProps = {
|
||||
id: undefined,
|
||||
className: undefined,
|
||||
style: undefined,
|
||||
};
|
||||
|
||||
export default DocumentCatalogFolderLoader;
|
@ -0,0 +1,30 @@
|
||||
import styled from 'styled-components';
|
||||
import { tablet, mobile } from '@appserver/components/utils/device';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
width: 256px;
|
||||
padding: 0 20px;
|
||||
|
||||
@media ${tablet} {
|
||||
width: 52px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
width: 100%;
|
||||
padding: 0 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledBlock = styled.div`
|
||||
width: 100%;
|
||||
height: auto;
|
||||
|
||||
margin-bottom: 20px;
|
||||
|
||||
@media ${tablet} {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
`;
|
||||
|
||||
export { StyledBlock, StyledContainer };
|
@ -0,0 +1 @@
|
||||
export default from './DocumentCatalogFolderLoader';
|
@ -1,7 +1,7 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import StyledTreeSettingsLoader from "./StyledTreeSettingsLoader";
|
||||
import TreeNodeLoader from "../TreeNodeLoader";
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import StyledTreeSettingsLoader from './StyledTreeSettingsLoader';
|
||||
import TreeNodeLoader from '../TreeNodeLoader';
|
||||
|
||||
const TreeSettingsLoader = ({ id, className, style, ...rest }) => {
|
||||
return (
|
||||
|
@ -1,23 +1,24 @@
|
||||
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 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";
|
||||
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 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';
|
||||
import DocumentCatalogFolderLoader from './DocumentCatalogFolderLoader';
|
||||
|
||||
export default {
|
||||
Rectangle,
|
||||
@ -40,4 +41,5 @@ export default {
|
||||
DialogLoader,
|
||||
DialogAsideLoader,
|
||||
MainButton,
|
||||
DocumentCatalogFolderLoader,
|
||||
};
|
||||
|
@ -1,26 +1,31 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Backdrop from "@appserver/components/backdrop";
|
||||
import { size } from "@appserver/components/utils/device";
|
||||
import { Provider } from "@appserver/components/utils/context";
|
||||
import { isMobile } 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 { inject, observer } from "mobx-react";
|
||||
import Selecto from "react-selecto";
|
||||
import styled from "styled-components";
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Backdrop from '@appserver/components/backdrop';
|
||||
import { isTablet, isDesktop, size } from '@appserver/components/utils/device';
|
||||
import { Provider } from '@appserver/components/utils/context';
|
||||
import { isMobile } 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 { inject, observer } from 'mobx-react';
|
||||
import Selecto from 'react-selecto';
|
||||
import styled from 'styled-components';
|
||||
import Catalog from './sub-components/catalog';
|
||||
import SubCatalogBackdrop from './sub-components/catalog-backdrop';
|
||||
import SubCatalogHeader from './sub-components/catalog-header';
|
||||
import SubCatalogMainButton from './sub-components/catalog-main-button';
|
||||
import SubCatalogBody from './sub-components/catalog-body';
|
||||
|
||||
const StyledSelectoWrapper = styled.div`
|
||||
.selecto-selection {
|
||||
@ -28,42 +33,60 @@ const StyledSelectoWrapper = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
function CatalogHeader() {
|
||||
return null;
|
||||
}
|
||||
CatalogHeader.displayName = 'CatalogHeader';
|
||||
|
||||
function CatalogMainButton() {
|
||||
return null;
|
||||
}
|
||||
CatalogMainButton.displayName = 'CatalogMainButton';
|
||||
|
||||
function CatalogBody() {
|
||||
return null;
|
||||
}
|
||||
CatalogBody.displayName = 'CatalogBody';
|
||||
|
||||
function ArticleHeader() {
|
||||
return null;
|
||||
}
|
||||
ArticleHeader.displayName = "ArticleHeader";
|
||||
ArticleHeader.displayName = 'ArticleHeader';
|
||||
|
||||
function ArticleMainButton() {
|
||||
return null;
|
||||
}
|
||||
ArticleMainButton.displayName = "ArticleMainButton";
|
||||
ArticleMainButton.displayName = 'ArticleMainButton';
|
||||
|
||||
function ArticleBody() {
|
||||
return null;
|
||||
}
|
||||
ArticleBody.displayName = "ArticleBody";
|
||||
ArticleBody.displayName = 'ArticleBody';
|
||||
|
||||
function SectionHeader() {
|
||||
return null;
|
||||
}
|
||||
SectionHeader.displayName = "SectionHeader";
|
||||
SectionHeader.displayName = 'SectionHeader';
|
||||
|
||||
function SectionFilter() {
|
||||
return null;
|
||||
}
|
||||
SectionFilter.displayName = "SectionFilter";
|
||||
SectionFilter.displayName = 'SectionFilter';
|
||||
|
||||
function SectionBody() {
|
||||
return null;
|
||||
}
|
||||
SectionBody.displayName = "SectionBody";
|
||||
SectionBody.displayName = 'SectionBody';
|
||||
|
||||
function SectionPaging() {
|
||||
return null;
|
||||
}
|
||||
SectionPaging.displayName = "SectionPaging";
|
||||
SectionPaging.displayName = 'SectionPaging';
|
||||
|
||||
class PageLayout extends React.Component {
|
||||
static CatalogHeader = CatalogHeader;
|
||||
static CatalogMainButton = CatalogMainButton;
|
||||
static CatalogBody = CatalogBody;
|
||||
static ArticleHeader = ArticleHeader;
|
||||
static ArticleMainButton = ArticleMainButton;
|
||||
static ArticleBody = ArticleBody;
|
||||
@ -83,7 +106,7 @@ class PageLayout extends React.Component {
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!this.scroll) {
|
||||
this.scroll = document.getElementsByClassName("section-scroll")[0];
|
||||
this.scroll = document.getElementsByClassName('section-scroll')[0];
|
||||
}
|
||||
|
||||
if (
|
||||
@ -93,19 +116,25 @@ class PageLayout extends React.Component {
|
||||
) {
|
||||
this.backdropClick();
|
||||
}
|
||||
|
||||
if (isDesktop()) return this.props.setShowText(true);
|
||||
if (isTablet() && !this.props.userShowText) return this.props.setShowText(false);
|
||||
if (this.props.showText && isTablet() && !this.props.userShowText)
|
||||
return this.props.setShowText(false);
|
||||
if (this.props.showText && isMobile && !this.props.userShowText)
|
||||
return this.props.setShowText(false);
|
||||
if (!isTablet() && !isMobile && !this.props.showText && !this.props.userShowText)
|
||||
return this.props.setShowText(true);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener("orientationchange", this.orientationChangeHandler);
|
||||
window.addEventListener('orientationchange', this.orientationChangeHandler);
|
||||
|
||||
this.orientationChangeHandler();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener(
|
||||
"orientationchange",
|
||||
this.orientationChangeHandler
|
||||
);
|
||||
window.removeEventListener('orientationchange', this.orientationChangeHandler);
|
||||
|
||||
if (this.intervalHandler) clearInterval(this.intervalHandler);
|
||||
if (this.timeoutHandler) clearTimeout(this.timeoutHandler);
|
||||
@ -159,16 +188,12 @@ class PageLayout extends React.Component {
|
||||
|
||||
dragCondition = (e) => {
|
||||
const path = e.inputEvent.composedPath();
|
||||
const isBackdrop = path.some(
|
||||
(x) => x.classList && x.classList.contains("backdrop-active")
|
||||
);
|
||||
const isBackdrop = path.some((x) => x.classList && x.classList.contains('backdrop-active'));
|
||||
const notSelectablePath = path.some(
|
||||
(x) => x.classList && x.classList.contains("not-selectable")
|
||||
(x) => x.classList && x.classList.contains('not-selectable'),
|
||||
);
|
||||
|
||||
const isDraggable = path.some(
|
||||
(x) => x.classList && x.classList.contains("draggable")
|
||||
);
|
||||
const isDraggable = path.some((x) => x.classList && x.classList.contains('draggable'));
|
||||
|
||||
if (notSelectablePath || isBackdrop || isDraggable) {
|
||||
return false;
|
||||
@ -205,7 +230,13 @@ class PageLayout extends React.Component {
|
||||
isBackdropVisible,
|
||||
isArticlePinned,
|
||||
isDesktop,
|
||||
showText,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
} = this.props;
|
||||
let catalogHeaderContent = null;
|
||||
let catalogMainButtonContent = null;
|
||||
let catalogBodyContent = null;
|
||||
let articleHeaderContent = null;
|
||||
let articleMainButtonContent = null;
|
||||
let articleBodyContent = null;
|
||||
@ -213,12 +244,19 @@ class PageLayout extends React.Component {
|
||||
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);
|
||||
const childType = child && child.type && (child.type.displayName || child.type.name);
|
||||
|
||||
switch (childType) {
|
||||
case CatalogHeader.displayName:
|
||||
catalogHeaderContent = child;
|
||||
break;
|
||||
case CatalogMainButton.displayName:
|
||||
catalogMainButtonContent = child;
|
||||
break;
|
||||
case CatalogBody.displayName:
|
||||
catalogBodyContent = child;
|
||||
break;
|
||||
case ArticleHeader.displayName:
|
||||
articleHeaderContent = child;
|
||||
break;
|
||||
@ -249,59 +287,70 @@ class PageLayout extends React.Component {
|
||||
isArticleMainButtonAvailable = !!articleMainButtonContent,
|
||||
isArticleBodyAvailable = !!articleBodyContent,
|
||||
isArticleAvailable =
|
||||
isArticleHeaderAvailable ||
|
||||
isArticleMainButtonAvailable ||
|
||||
isArticleBodyAvailable,
|
||||
isArticleHeaderAvailable || isArticleMainButtonAvailable || isArticleBodyAvailable,
|
||||
isSectionHeaderAvailable = !!sectionHeaderContent,
|
||||
isSectionFilterAvailable = !!sectionFilterContent,
|
||||
isSectionPagingAvailable = !!sectionPagingContent,
|
||||
isSectionBodyAvailable =
|
||||
!!sectionBodyContent ||
|
||||
isSectionFilterAvailable ||
|
||||
isSectionPagingAvailable,
|
||||
!!sectionBodyContent || isSectionFilterAvailable || isSectionPagingAvailable,
|
||||
isSectionAvailable =
|
||||
isSectionHeaderAvailable ||
|
||||
isSectionFilterAvailable ||
|
||||
isSectionBodyAvailable ||
|
||||
isSectionPagingAvailable ||
|
||||
isArticleAvailable,
|
||||
isBackdropAvailable = isArticleAvailable;
|
||||
isBackdropAvailable = isArticleAvailable,
|
||||
isCatalogHeaderAvailable = !!catalogHeaderContent,
|
||||
isCatalogMainButtonAvailable = !!catalogMainButtonContent,
|
||||
isCatalogBodyAvailable = !!catalogBodyContent,
|
||||
isCatalogAvailable =
|
||||
isCatalogHeaderAvailable || isCatalogMainButtonAvailable || isCatalogBodyAvailable;
|
||||
|
||||
const renderPageLayout = () => {
|
||||
return (
|
||||
<>
|
||||
{isBackdropAvailable && (
|
||||
<Backdrop
|
||||
zIndex={400}
|
||||
visible={isBackdropVisible}
|
||||
onClick={this.backdropClick}
|
||||
/>
|
||||
{showCatalog && isCatalogAvailable && (
|
||||
<Catalog showText={showText}>
|
||||
{isCatalogHeaderAvailable && (
|
||||
<>
|
||||
<SubCatalogBackdrop showText={showText} onClick={toggleShowText} />
|
||||
<SubCatalogHeader showText={showText} onClick={toggleShowText}>
|
||||
{catalogHeaderContent ? catalogHeaderContent.props.children : null}
|
||||
</SubCatalogHeader>
|
||||
</>
|
||||
)}
|
||||
|
||||
{isCatalogMainButtonAvailable && (
|
||||
<SubCatalogMainButton showText={showText}>
|
||||
{catalogMainButtonContent ? catalogMainButtonContent.props.children : null}
|
||||
</SubCatalogMainButton>
|
||||
)}
|
||||
|
||||
{isCatalogBodyAvailable && (
|
||||
<SubCatalogBody showText={showText}>
|
||||
{catalogBodyContent ? catalogBodyContent.props.children : null}
|
||||
</SubCatalogBody>
|
||||
)}
|
||||
</Catalog>
|
||||
)}
|
||||
{isArticleAvailable && (
|
||||
<Article
|
||||
visible={isArticleVisible}
|
||||
pinned={isArticlePinned}
|
||||
firstLoad={firstLoad}
|
||||
>
|
||||
{!showCatalog && isBackdropAvailable && (
|
||||
<Backdrop zIndex={400} visible={isBackdropVisible} onClick={this.backdropClick} />
|
||||
)}
|
||||
{!showCatalog && isArticleAvailable && (
|
||||
<Article visible={isArticleVisible} pinned={isArticlePinned} firstLoad={firstLoad}>
|
||||
{isArticleHeaderAvailable && (
|
||||
<SubArticleHeader>
|
||||
{articleHeaderContent
|
||||
? articleHeaderContent.props.children
|
||||
: null}
|
||||
{articleHeaderContent ? articleHeaderContent.props.children : null}
|
||||
</SubArticleHeader>
|
||||
)}
|
||||
{isArticleMainButtonAvailable && (
|
||||
<SubArticleMainButton>
|
||||
{articleMainButtonContent
|
||||
? articleMainButtonContent.props.children
|
||||
: null}
|
||||
{articleMainButtonContent ? articleMainButtonContent.props.children : null}
|
||||
</SubArticleMainButton>
|
||||
)}
|
||||
{isArticleBodyAvailable && (
|
||||
<SubArticleBody pinned={isArticlePinned} isDesktop={isDesktop}>
|
||||
{articleBodyContent
|
||||
? articleBodyContent.props.children
|
||||
: null}
|
||||
{articleBodyContent ? articleBodyContent.props.children : null}
|
||||
</SubArticleBody>
|
||||
)}
|
||||
{isArticleBodyAvailable && (
|
||||
@ -317,28 +366,23 @@ class PageLayout extends React.Component {
|
||||
<ReactResizeDetector
|
||||
refreshRate={100}
|
||||
refreshMode="debounce"
|
||||
refreshOptions={{ trailing: true }}
|
||||
>
|
||||
refreshOptions={{ trailing: true }}>
|
||||
{({ width, height }) => (
|
||||
<Provider
|
||||
value={{
|
||||
sectionWidth: width,
|
||||
sectionHeight: height,
|
||||
}}
|
||||
>
|
||||
}}>
|
||||
<Section
|
||||
showText={showText}
|
||||
widthProp={width}
|
||||
unpinArticle={this.unpinArticle}
|
||||
pinned={isArticlePinned}
|
||||
>
|
||||
pinned={isArticlePinned}>
|
||||
{isSectionHeaderAvailable && (
|
||||
<SubSectionHeader
|
||||
isHeaderVisible={isHeaderVisible}
|
||||
isArticlePinned={isArticlePinned}
|
||||
>
|
||||
{sectionHeaderContent
|
||||
? sectionHeaderContent.props.children
|
||||
: null}
|
||||
isArticlePinned={isArticlePinned}>
|
||||
{sectionHeaderContent ? sectionHeaderContent.props.children : null}
|
||||
</SubSectionHeader>
|
||||
)}
|
||||
|
||||
@ -347,14 +391,11 @@ class PageLayout extends React.Component {
|
||||
<div
|
||||
id="main-bar"
|
||||
style={{
|
||||
display: "grid",
|
||||
paddingRight: "20px",
|
||||
}}
|
||||
></div>
|
||||
display: 'grid',
|
||||
paddingRight: '20px',
|
||||
}}></div>
|
||||
<SubSectionFilter className="section-header_filter">
|
||||
{sectionFilterContent
|
||||
? sectionFilterContent.props.children
|
||||
: null}
|
||||
{sectionFilterContent ? sectionFilterContent.props.children : null}
|
||||
</SubSectionFilter>
|
||||
</>
|
||||
)}
|
||||
@ -366,25 +407,18 @@ class PageLayout extends React.Component {
|
||||
withScroll={withBodyScroll}
|
||||
autoFocus={isMobile || isTabletView ? false : true}
|
||||
pinned={isArticlePinned}
|
||||
viewAs={viewAs}
|
||||
>
|
||||
viewAs={viewAs}>
|
||||
{isSectionFilterAvailable && (
|
||||
<SubSectionFilter className="section-body_filter">
|
||||
{sectionFilterContent
|
||||
? sectionFilterContent.props.children
|
||||
: null}
|
||||
{sectionFilterContent ? sectionFilterContent.props.children : null}
|
||||
</SubSectionFilter>
|
||||
)}
|
||||
<SubSectionBodyContent>
|
||||
{sectionBodyContent
|
||||
? sectionBodyContent.props.children
|
||||
: null}
|
||||
{sectionBodyContent ? sectionBodyContent.props.children : null}
|
||||
</SubSectionBodyContent>
|
||||
{isSectionPagingAvailable && (
|
||||
<SubSectionPaging>
|
||||
{sectionPagingContent
|
||||
? sectionPagingContent.props.children
|
||||
: null}
|
||||
{sectionPagingContent ? sectionPagingContent.props.children : null}
|
||||
</SubSectionPaging>
|
||||
)}
|
||||
</SubSectionBody>
|
||||
@ -426,11 +460,8 @@ class PageLayout extends React.Component {
|
||||
<></>
|
||||
)}
|
||||
|
||||
{isArticleAvailable && (
|
||||
<SectionToggler
|
||||
visible={!isArticleVisible}
|
||||
onClick={this.showArticle}
|
||||
/>
|
||||
{!showCatalog && isArticleAvailable && (
|
||||
<SectionToggler visible={!isArticleVisible} onClick={this.showArticle} />
|
||||
)}
|
||||
</Section>
|
||||
</Provider>
|
||||
@ -455,9 +486,9 @@ class PageLayout extends React.Component {
|
||||
{!isMobile && uploadFiles && !dragging && (
|
||||
<StyledSelectoWrapper>
|
||||
<Selecto
|
||||
boundContainer={".section-body"}
|
||||
dragContainer={".section-body"}
|
||||
selectableTargets={[".files-item"]}
|
||||
boundContainer={'.section-body'}
|
||||
dragContainer={'.section-body'}
|
||||
selectableTargets={['.files-item']}
|
||||
hitRate={0}
|
||||
selectByClick={false}
|
||||
selectFromInside={true}
|
||||
@ -498,6 +529,11 @@ PageLayout.propTypes = {
|
||||
isTabletView: PropTypes.bool,
|
||||
isHeaderVisible: PropTypes.bool,
|
||||
firstLoad: PropTypes.bool,
|
||||
showText: PropTypes.bool,
|
||||
userShowText: PropTypes.bool,
|
||||
setShowText: PropTypes.func,
|
||||
toggleShowText: PropTypes.func,
|
||||
showCatalog: PropTypes.bool,
|
||||
};
|
||||
|
||||
PageLayout.defaultProps = {
|
||||
@ -505,6 +541,8 @@ PageLayout.defaultProps = {
|
||||
withBodyAutoFocus: false,
|
||||
};
|
||||
|
||||
PageLayout.CatalogHeader = CatalogHeader;
|
||||
PageLayout.CatalogMainButton = CatalogMainButton;
|
||||
PageLayout.ArticleHeader = ArticleHeader;
|
||||
PageLayout.ArticleMainButton = ArticleMainButton;
|
||||
PageLayout.ArticleBody = ArticleBody;
|
||||
@ -526,6 +564,11 @@ export default inject(({ auth }) => {
|
||||
setIsArticleVisible,
|
||||
setIsBackdropVisible,
|
||||
isDesktopClient,
|
||||
showText,
|
||||
userShowText,
|
||||
setShowText,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
} = settingsStore;
|
||||
|
||||
return {
|
||||
@ -540,5 +583,10 @@ export default inject(({ auth }) => {
|
||||
isBackdropVisible,
|
||||
setIsBackdropVisible,
|
||||
isDesktop: isDesktopClient,
|
||||
showText,
|
||||
userShowText,
|
||||
setShowText,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
};
|
||||
})(observer(PageLayout));
|
||||
|
@ -0,0 +1,62 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import Backdrop from '@appserver/components/backdrop';
|
||||
import { mobile } from '@appserver/components/utils/device';
|
||||
import CrossIcon from '@appserver/components/public/static/images/cross.react.svg';
|
||||
|
||||
const StyledBackdrop = styled(Backdrop)`
|
||||
display: none;
|
||||
width: 100vw;
|
||||
height: 64px;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background: rgba(6, 22, 38, 0.15);
|
||||
backdrop-filter: blur(18px);
|
||||
cursor: initial;
|
||||
@media ${mobile} {
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledControlContainer = styled.div`
|
||||
background: #9a9ea3;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
right: 10px;
|
||||
border-radius: 100px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledCrossIcon = styled(CrossIcon)`
|
||||
width: 11.31px;
|
||||
height: 11.31px;
|
||||
path {
|
||||
fill: #ffffff;
|
||||
}
|
||||
`;
|
||||
|
||||
const CatalogBackdrop = (props) => {
|
||||
const { showText, onClick, ...rest } = props;
|
||||
|
||||
return (
|
||||
<StyledBackdrop visible={showText} {...rest}>
|
||||
<StyledControlContainer onClick={onClick}>
|
||||
<StyledCrossIcon />
|
||||
</StyledControlContainer>
|
||||
</StyledBackdrop>
|
||||
);
|
||||
};
|
||||
|
||||
CatalogBackdrop.propTypes = {
|
||||
showText: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
export default React.memo(CatalogBackdrop);
|
@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
const CatalogBody = (props) => {
|
||||
return <> {props.children}</>;
|
||||
};
|
||||
|
||||
CatalogBody.displayName = 'CatalogBody';
|
||||
|
||||
export default React.memo(CatalogBody);
|
@ -0,0 +1,85 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import Heading from '@appserver/components/heading';
|
||||
import Backdrop from '@appserver/components/backdrop';
|
||||
import { mobile, tablet } from '@appserver/components/utils/device';
|
||||
import MenuIcon from '@appserver/components/public/static/images/menu.react.svg';
|
||||
|
||||
const StyledCatalogHeader = styled.div`
|
||||
padding: 12px 20px 13px;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
@media ${tablet} {
|
||||
padding: 16px 20px 17px;
|
||||
justify-content: ${(props) => (props.showText ? 'flex-start' : 'center')};
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
border-bottom: 1px solid #eceef1;
|
||||
padding: 28px 20px 12px;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledHeading = styled(Heading)`
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
line-height: 28px;
|
||||
@media ${tablet} {
|
||||
display: ${(props) => (props.showText ? 'block' : 'none')};
|
||||
margin-left: ${(props) => props.showText && '12px'};
|
||||
}
|
||||
@media ${mobile} {
|
||||
margin-left: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledIconBox = styled.div`
|
||||
display: none;
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
|
||||
@media ${tablet} {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
display: none;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledMenuIcon = styled(MenuIcon)`
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: #657077;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const CatalogHeader = (props) => {
|
||||
const { showText, children, onClick, ...rest } = props;
|
||||
|
||||
return (
|
||||
<StyledCatalogHeader showText={showText} {...rest}>
|
||||
<StyledIconBox>
|
||||
<StyledMenuIcon onClick={onClick} />
|
||||
</StyledIconBox>
|
||||
|
||||
<StyledHeading showText={showText} color="#333333" size="large">
|
||||
{children}
|
||||
</StyledHeading>
|
||||
</StyledCatalogHeader>
|
||||
);
|
||||
};
|
||||
|
||||
CatalogHeader.propTypes = {
|
||||
children: PropTypes.any,
|
||||
showText: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
};
|
||||
|
||||
CatalogHeader.displayName = 'CatalogHeader';
|
||||
|
||||
export default React.memo(CatalogHeader);
|
@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { tablet, mobile } from '@appserver/components/utils/device';
|
||||
|
||||
const StyledCatalogMainButton = styled.div`
|
||||
padding: 0px 20px 16px;
|
||||
|
||||
@media ${tablet} {
|
||||
display: ${(props) => (props.showText ? 'block' : 'none')};
|
||||
padding: 0 20px 16px;
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
padding: 16px 20px 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
const CatalogMainButton = (props) => {
|
||||
return <StyledCatalogMainButton {...props} />;
|
||||
};
|
||||
|
||||
CatalogMainButton.displayName = 'CatalogMainButton';
|
||||
|
||||
export default CatalogMainButton;
|
@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Resizable } from 're-resizable';
|
||||
import { isMobile } from 'react-device-detect';
|
||||
import { mobile, tablet } from '@appserver/components/utils/device';
|
||||
|
||||
const StyledCatalog = styled.div`
|
||||
.resizable-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 256px;
|
||||
width: 256px;
|
||||
height: 100% !important;
|
||||
background: #f8f9f9;
|
||||
overflow: hidden;
|
||||
.resizable-border {
|
||||
div {
|
||||
cursor: ew-resize !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
min-width: ${(props) => (props.showText ? '240px' : '52px')};
|
||||
max-width: ${(props) => (props.showText ? '240px' : '52px')};
|
||||
.resizable-border {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (props.showText ? 'flex' : 'none')};
|
||||
min-width: 100vw;
|
||||
width: 100vw;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Catalog = (props) => {
|
||||
const { showText, children, ...rest } = props;
|
||||
|
||||
const enable = {
|
||||
top: false,
|
||||
right: !isMobile,
|
||||
bottom: false,
|
||||
left: false,
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledCatalog showText={showText} {...rest}>
|
||||
<Resizable
|
||||
enable={enable}
|
||||
className="resizable-block"
|
||||
handleWrapperClass="resizable-border not-selectable">
|
||||
{children}
|
||||
</Resizable>
|
||||
</StyledCatalog>
|
||||
);
|
||||
};
|
||||
|
||||
Catalog.propTypes = {
|
||||
showText: PropTypes.bool,
|
||||
children: PropTypes.any,
|
||||
};
|
||||
|
||||
export default Catalog;
|
@ -1,13 +1,7 @@
|
||||
import React from "react";
|
||||
import styled, { css } from "styled-components";
|
||||
import { tablet, size } from "@appserver/components/utils/device";
|
||||
import {
|
||||
isIOS,
|
||||
isTablet,
|
||||
isSafari,
|
||||
isChrome,
|
||||
isMobile,
|
||||
} from "react-device-detect";
|
||||
import React from 'react';
|
||||
import styled, { css } from 'styled-components';
|
||||
import { tablet, size, mobile } from '@appserver/components/utils/device';
|
||||
import { isIOS, isTablet, isSafari, isChrome, isMobile } from 'react-device-detect';
|
||||
|
||||
const tabletProps = css`
|
||||
.section-header_filter {
|
||||
@ -25,6 +19,9 @@ const StyledSection = styled.section`
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (!props.showText ? 'flex' : 'none')};
|
||||
}
|
||||
//width: ${(props) => `${props.widthProp}px`};
|
||||
.layout-progress-bar {
|
||||
position: fixed;
|
||||
@ -57,13 +54,11 @@ const StyledSection = styled.section`
|
||||
padding: 0 0 0 16px;
|
||||
${tabletProps};
|
||||
}
|
||||
${
|
||||
isMobile &&
|
||||
css`
|
||||
${tabletProps};
|
||||
min-width: 100px;
|
||||
`
|
||||
}
|
||||
${isMobile &&
|
||||
css`
|
||||
${tabletProps};
|
||||
min-width: 100px;
|
||||
`}
|
||||
`;
|
||||
|
||||
class Section extends React.Component {
|
||||
|
@ -1,55 +1,55 @@
|
||||
import { makeAutoObservable } from "mobx";
|
||||
import api from "../api";
|
||||
import { ARTICLE_PINNED_KEY, LANGUAGE } from "../constants";
|
||||
import { combineUrl } from "../utils";
|
||||
import FirebaseHelper from "../utils/firebase";
|
||||
import { AppServerConfig } from "../constants";
|
||||
import { makeAutoObservable } from 'mobx';
|
||||
import api from '../api';
|
||||
import { ARTICLE_PINNED_KEY, LANGUAGE } from '../constants';
|
||||
import { combineUrl } from '../utils';
|
||||
import FirebaseHelper from '../utils/firebase';
|
||||
import { AppServerConfig } from '../constants';
|
||||
const { proxyURL } = AppServerConfig;
|
||||
|
||||
class SettingsStore {
|
||||
isLoading = false;
|
||||
isLoaded = false;
|
||||
|
||||
currentProductId = "";
|
||||
culture = "en-US";
|
||||
currentProductId = '';
|
||||
culture = 'en-US';
|
||||
cultures = [];
|
||||
trustedDomains = [];
|
||||
trustedDomainsType = 0;
|
||||
trustedDomains = [];
|
||||
timezone = "UTC";
|
||||
timezone = 'UTC';
|
||||
timezones = [];
|
||||
utcOffset = "00:00:00";
|
||||
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";
|
||||
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",
|
||||
datePattern: 'mm/dd/yy',
|
||||
dateTimePattern: 'DD, mm dd, yy h:mm:ss tt',
|
||||
timePattern: 'h:mm tt',
|
||||
};
|
||||
organizationName = "ONLYOFFICE";
|
||||
greetingSettings = "Web Office Applications";
|
||||
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");
|
||||
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",
|
||||
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;
|
||||
isDesktopClient = window['AscDesktopEditor'] !== undefined;
|
||||
//isDesktopEncryption: desktopEncryption;
|
||||
isEncryptionSupport = false;
|
||||
encryptionKeys = null;
|
||||
@ -58,15 +58,17 @@ class SettingsStore {
|
||||
|
||||
isHeaderVisible = false;
|
||||
isTabletView = false;
|
||||
isArticlePinned =
|
||||
localStorage.getItem(ARTICLE_PINNED_KEY) === "true" || false;
|
||||
isArticlePinned = localStorage.getItem(ARTICLE_PINNED_KEY) === 'true' || false;
|
||||
isArticleVisible = false;
|
||||
isBackdropVisible = false;
|
||||
|
||||
isArticleVisibleOnUnpin = false;
|
||||
|
||||
showText = true;
|
||||
userShowText = false;
|
||||
showCatalog = true;
|
||||
|
||||
hashSettings = null;
|
||||
title = "";
|
||||
title = '';
|
||||
ownerId = null;
|
||||
nameSchemaId = null;
|
||||
owner = {};
|
||||
@ -76,23 +78,23 @@ class SettingsStore {
|
||||
|
||||
customSchemaList = [];
|
||||
firebase = {
|
||||
apiKey: "",
|
||||
authDomain: "",
|
||||
projectId: "",
|
||||
storageBucket: "",
|
||||
messagingSenderId: "",
|
||||
appId: "",
|
||||
measurementId: "",
|
||||
apiKey: '',
|
||||
authDomain: '',
|
||||
projectId: '',
|
||||
storageBucket: '',
|
||||
messagingSenderId: '',
|
||||
appId: '',
|
||||
measurementId: '',
|
||||
};
|
||||
version = "";
|
||||
version = '';
|
||||
|
||||
constructor() {
|
||||
makeAutoObservable(this);
|
||||
}
|
||||
|
||||
get urlAuthKeys() {
|
||||
const splitted = this.culture.split("-");
|
||||
const lang = splitted.length > 0 ? splitted[0] : "en";
|
||||
const splitted = this.culture.split('-');
|
||||
const lang = splitted.length > 0 ? splitted[0] : 'en';
|
||||
return `https://helpcenter.onlyoffice.com/${lang}/installation/groups-authorization-keys.aspx`;
|
||||
}
|
||||
|
||||
@ -101,8 +103,8 @@ class SettingsStore {
|
||||
}
|
||||
|
||||
get helpUrlCommonSettings() {
|
||||
const substring = this.culture.substring(0, this.culture.indexOf("-"));
|
||||
const lang = substring.length > 0 ? substring : "en";
|
||||
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`;
|
||||
}
|
||||
@ -131,8 +133,8 @@ class SettingsStore {
|
||||
getSettings = async () => {
|
||||
const newSettings = await api.settings.getSettings();
|
||||
|
||||
if (window["AscDesktopEditor"] !== undefined || this.personal) {
|
||||
const dp = combineUrl(proxyURL, "/products/files/");
|
||||
if (window['AscDesktopEditor'] !== undefined || this.personal) {
|
||||
const dp = combineUrl(proxyURL, '/products/files/');
|
||||
this.setDefaultPage(dp);
|
||||
}
|
||||
|
||||
@ -140,24 +142,22 @@ class SettingsStore {
|
||||
if (key in this) {
|
||||
this.setValue(
|
||||
key,
|
||||
key === "defaultPage"
|
||||
? combineUrl(proxyURL, newSettings[key])
|
||||
: newSettings[key]
|
||||
key === 'defaultPage' ? combineUrl(proxyURL, newSettings[key]) : newSettings[key],
|
||||
);
|
||||
if (key === "culture") {
|
||||
if (key === 'culture') {
|
||||
const language = localStorage.getItem(LANGUAGE);
|
||||
if (!language || language == "undefined") {
|
||||
if (!language || language == 'undefined') {
|
||||
localStorage.setItem(LANGUAGE, newSettings[key]);
|
||||
}
|
||||
}
|
||||
if (key === "personal") {
|
||||
if (key === 'personal') {
|
||||
window.AppServer = {
|
||||
...window.AppServer,
|
||||
personal: newSettings[key],
|
||||
};
|
||||
}
|
||||
} else if (key === "passwordHash") {
|
||||
this.setValue("hashSettings", newSettings[key]);
|
||||
} else if (key === 'passwordHash') {
|
||||
this.setValue('hashSettings', newSettings[key]);
|
||||
}
|
||||
});
|
||||
|
||||
@ -226,14 +226,14 @@ class SettingsStore {
|
||||
|
||||
getOAuthToken = (tokenGetterWin) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
localStorage.removeItem("code");
|
||||
localStorage.removeItem('code');
|
||||
let interval = null;
|
||||
interval = setInterval(() => {
|
||||
try {
|
||||
const code = localStorage.getItem("code");
|
||||
const code = localStorage.getItem('code');
|
||||
|
||||
if (code) {
|
||||
localStorage.removeItem("code");
|
||||
localStorage.removeItem('code');
|
||||
clearInterval(interval);
|
||||
resolve(code);
|
||||
} else if (tokenGetterWin && tokenGetterWin.closed) {
|
||||
@ -252,25 +252,24 @@ class SettingsStore {
|
||||
};
|
||||
|
||||
setModuleInfo = (homepage, productId) => {
|
||||
if (this.homepage === homepage || this.currentProductId === productId)
|
||||
return;
|
||||
if (this.homepage === homepage || this.currentProductId === productId) return;
|
||||
|
||||
console.log(`setModuleInfo('${homepage}', '${productId}')`);
|
||||
|
||||
this.homepage = homepage;
|
||||
this.setCurrentProductId(productId);
|
||||
|
||||
const baseElm = document.getElementsByTagName("base");
|
||||
const baseElm = document.getElementsByTagName('base');
|
||||
if (baseElm && baseElm.length === 1) {
|
||||
const baseUrl = homepage
|
||||
? homepage[homepage.length - 1] === "/"
|
||||
? homepage[homepage.length - 1] === '/'
|
||||
? homepage
|
||||
: `${homepage}/`
|
||||
: "/";
|
||||
: '/';
|
||||
|
||||
console.log("SET base URL", baseUrl);
|
||||
console.log('SET base URL', baseUrl);
|
||||
|
||||
baseElm[0].setAttribute("href", baseUrl);
|
||||
baseElm[0].setAttribute('href', baseUrl);
|
||||
}
|
||||
};
|
||||
|
||||
@ -325,6 +324,19 @@ class SettingsStore {
|
||||
this.isArticleVisibleOnUnpin = visible;
|
||||
};
|
||||
|
||||
setShowText = (showText) => {
|
||||
this.showText = showText;
|
||||
};
|
||||
|
||||
setUserShowText = (userShowText) => {
|
||||
this.userShowText = userShowText;
|
||||
};
|
||||
|
||||
toggleShowText = () => {
|
||||
this.showText = !this.showText;
|
||||
this.userShowText = true;
|
||||
};
|
||||
|
||||
get firebaseHelper() {
|
||||
window.firebaseHelper = new FirebaseHelper(this.firebase);
|
||||
return window.firebaseHelper;
|
||||
|
@ -27,6 +27,7 @@ Display catalog item. Can show only icon (showText property). If is it end of bl
|
||||
| `onClick` | `func` | - | - | - | What the catalog item will trigger when clicked |
|
||||
| `showInitial` | `bool` | - | - | `false` | Tells when the catalog item should display initial text(first symbol of text) |
|
||||
| `isEndOfBlock` | `bool` | - | - | `false` | Tells when the catalog item should be end of block (adding margin-bottom) |
|
||||
| `isActive` | `bool` | - | - | `false` | Tells when the catalog item should be active (adding background color) |
|
||||
| `showBadge` | `bool` | - | - | `false` | Tells when the catalog item should display badge |
|
||||
| `labelBadge` | `string` | - | - | - | Label for badge |
|
||||
| `iconBadge` | `string` | - | - | - | Icon for badge |
|
||||
|
@ -28,6 +28,7 @@ const CatalogItem = (props) => {
|
||||
showText,
|
||||
onClick,
|
||||
isEndOfBlock,
|
||||
isActive,
|
||||
showInitial,
|
||||
showBadge,
|
||||
labelBadge,
|
||||
@ -35,12 +36,13 @@ const CatalogItem = (props) => {
|
||||
onClickBadge,
|
||||
} = props;
|
||||
|
||||
const onClickAction = (e) => {
|
||||
onClick && onClick(e);
|
||||
const onClickAction = () => {
|
||||
onClick && onClick(id);
|
||||
};
|
||||
|
||||
const onClickBadgeAction = (e) => {
|
||||
onClickBadge && onClickBadge(e);
|
||||
e.stopPropagation();
|
||||
onClickBadge && onClickBadge(id);
|
||||
};
|
||||
|
||||
return (
|
||||
@ -52,6 +54,7 @@ const CatalogItem = (props) => {
|
||||
isEndOfBlock={isEndOfBlock}
|
||||
>
|
||||
<StyledCatalogItemSibling
|
||||
isActive={isActive}
|
||||
onClick={onClickAction}
|
||||
></StyledCatalogItemSibling>
|
||||
|
||||
@ -96,7 +99,7 @@ CatalogItem.propTypes = {
|
||||
/** Accepts className */
|
||||
className: PropTypes.string,
|
||||
/** Accepts id */
|
||||
id: PropTypes.string,
|
||||
id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
/** Accepts css style */
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
|
||||
/** Catalog item icon */
|
||||
@ -111,6 +114,8 @@ CatalogItem.propTypes = {
|
||||
showInitial: PropTypes.bool,
|
||||
/** Tells when the catalog item should be end of block */
|
||||
isEndOfBlock: PropTypes.bool,
|
||||
/** Tells when the catalog item should be active */
|
||||
isActive: PropTypes.bool,
|
||||
/** Tells when the catalog item should display badge */
|
||||
showBadge: PropTypes.bool,
|
||||
/** Label in catalog item badge */
|
||||
@ -124,6 +129,7 @@ CatalogItem.propTypes = {
|
||||
CatalogItem.defaultProps = {
|
||||
showText: false,
|
||||
showBadge: false,
|
||||
isActive: false,
|
||||
showInitial: false,
|
||||
isEndOfBlock: false,
|
||||
};
|
||||
|
@ -103,6 +103,9 @@ const StyledCatalogItemImg = styled.div`
|
||||
svg {
|
||||
width: ${(props) => props.theme.catalogItem.img.svg.width};
|
||||
height: ${(props) => props.theme.catalogItem.img.svg.height};
|
||||
path {
|
||||
fill: #657077 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media ${tablet} {
|
||||
@ -122,6 +125,9 @@ const StyledCatalogItemSibling = styled.div`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: ${(props) =>
|
||||
props.isActive && props.theme.catalogItem.sibling.hover.backgroundColor};
|
||||
|
||||
&:hover {
|
||||
background-color: ${(props) =>
|
||||
props.theme.catalogItem.sibling.hover.backgroundColor};
|
||||
@ -131,8 +137,6 @@ const StyledCatalogItemSibling = styled.div`
|
||||
StyledCatalogItemSibling.defaultProps = { theme: Base };
|
||||
|
||||
const StyledCatalogItemContainer = styled.div`
|
||||
background-color: ${(props) =>
|
||||
props.theme.catalogItem.container.backgroundColor};
|
||||
display: flex;
|
||||
justify-content: ${(props) => (props.showText ? "space-between" : "center")};
|
||||
align-items: center;
|
||||
|
@ -1630,7 +1630,6 @@ const Base = {
|
||||
height: "36px",
|
||||
padding: "0 20px",
|
||||
marginBottom: "20px",
|
||||
backgroundColor: grayLight,
|
||||
tablet: {
|
||||
height: "44px",
|
||||
padding: "0 16px",
|
||||
|
130
products/ASC.Files/Client/src/components/Catalog/Body/Banner.js
Normal file
130
products/ASC.Files/Client/src/components/Catalog/Body/Banner.js
Normal file
@ -0,0 +1,130 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import i18n from "i18next";
|
||||
import Backend from "i18next-http-backend";
|
||||
import { getLanguage } from "@appserver/common/utils";
|
||||
|
||||
import CampaignsBanner from "@appserver/components/campaigns-banner";
|
||||
import { ADS_TIMEOUT } from "../../../helpers/constants";
|
||||
import { LANGUAGE } from "@appserver/common/constants";
|
||||
|
||||
const i18nConfig = i18n.createInstance();
|
||||
|
||||
let translationUrl;
|
||||
|
||||
const loadLanguagePath = async () => {
|
||||
if (!window.firebaseHelper) return;
|
||||
|
||||
const lng = localStorage.getItem(LANGUAGE) || "en";
|
||||
const language = getLanguage(lng instanceof Array ? lng[0] : lng);
|
||||
|
||||
const campaigns = (localStorage.getItem("campaigns") || "")
|
||||
.split(",")
|
||||
.filter((campaign) => campaign.length > 0);
|
||||
const index = Number(localStorage.getItem("bannerIndex") || 0);
|
||||
const campaign = campaigns[index];
|
||||
|
||||
try {
|
||||
translationUrl = await window.firebaseHelper.getCampaignsTranslations(
|
||||
campaign,
|
||||
language
|
||||
);
|
||||
} catch (e) {
|
||||
translationUrl = await window.firebaseHelper.getCampaignsTranslations(
|
||||
campaign,
|
||||
"en"
|
||||
);
|
||||
//console.error(e);
|
||||
}
|
||||
return translationUrl;
|
||||
};
|
||||
|
||||
const bannerHOC = (WrappedComponent) => (props) => {
|
||||
const { FirebaseHelper } = props;
|
||||
|
||||
const campaigns = (localStorage.getItem("campaigns") || "")
|
||||
.split(",")
|
||||
.filter((campaign) => campaign.length > 0);
|
||||
|
||||
const [bannerImage, setBannerImage] = useState("");
|
||||
const [bannerTranslation, setBannerTranslation] = useState();
|
||||
|
||||
const updateBanner = async () => {
|
||||
let index = Number(localStorage.getItem("bannerIndex") || 0);
|
||||
const campaign = campaigns[index];
|
||||
|
||||
if (campaigns.length < 1 || index + 1 >= campaigns.length) {
|
||||
index = 0;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
|
||||
try {
|
||||
const translationUrl = await loadLanguagePath();
|
||||
setBannerTranslation(translationUrl);
|
||||
|
||||
i18nConfig.use(Backend).init({
|
||||
lng: localStorage.getItem(LANGUAGE) || "en",
|
||||
fallbackLng: "en",
|
||||
load: "all",
|
||||
debug: false,
|
||||
defaultNS: "",
|
||||
|
||||
backend: {
|
||||
loadPath: function () {
|
||||
return translationUrl;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const image = await FirebaseHelper.getCampaignsImages(
|
||||
campaign.toLowerCase()
|
||||
);
|
||||
setBannerImage(image);
|
||||
} catch (e) {
|
||||
updateBanner();
|
||||
//console.error(e);
|
||||
}
|
||||
|
||||
localStorage.setItem("bannerIndex", index);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateBanner();
|
||||
setInterval(updateBanner, ADS_TIMEOUT);
|
||||
}, []);
|
||||
|
||||
if (!bannerTranslation || !bannerImage) return <></>;
|
||||
|
||||
return <WrappedComponent bannerImage={bannerImage} {...props} />;
|
||||
};
|
||||
|
||||
const Banner = (props) => {
|
||||
//console.log("Banner render", props);
|
||||
const { t, tReady, bannerImage } = props;
|
||||
const campaigns = (localStorage.getItem("campaigns") || "")
|
||||
.split(",")
|
||||
.filter((campaign) => campaign.length > 0);
|
||||
|
||||
if (!campaigns.length || !tReady) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<CampaignsBanner
|
||||
headerLabel={t("Header")}
|
||||
subHeaderLabel={t("SubHeader")}
|
||||
img={bannerImage}
|
||||
btnLabel={t("ButtonLabel")}
|
||||
link={t("Link")}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const BannerWithTranslation = withTranslation()(Banner);
|
||||
|
||||
const WrapperBanner = (props) => (
|
||||
<BannerWithTranslation i18n={i18nConfig} useSuspense={false} {...props} />
|
||||
);
|
||||
|
||||
export default bannerHOC(WrapperBanner);
|
@ -0,0 +1,91 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import Text from "@appserver/components/text";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
|
||||
const StyledDownloadAppList = styled.div`
|
||||
margin-top: 20px;
|
||||
|
||||
.download-app-list {
|
||||
padding-top: 3px;
|
||||
display: flex;
|
||||
max-width: inherit;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
padding: 5px;
|
||||
}
|
||||
`;
|
||||
|
||||
const DownloadAppListContainer = ({ t }) => {
|
||||
const windowsLink =
|
||||
"https://www.onlyoffice.com/download-desktop.aspx#windows";
|
||||
const macLink = "https://www.onlyoffice.com/download-desktop.aspx#mac";
|
||||
const linuxLink = "https://www.onlyoffice.com/download-desktop.aspx#linux";
|
||||
const androidLink = "https://www.onlyoffice.com/office-for-android.aspx";
|
||||
const iosLink = "https://www.onlyoffice.com/office-for-ios.aspx";
|
||||
|
||||
return (
|
||||
<StyledDownloadAppList>
|
||||
<Text color="#83888d" fontSize="14px">
|
||||
{t("Translations:DownloadApps")}
|
||||
</Text>
|
||||
<div className="download-app-list">
|
||||
<IconButton
|
||||
onClick={() => window.open(windowsLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/windows.react.svg"
|
||||
size="25"
|
||||
isfill={true}
|
||||
color="#A3A9AE"
|
||||
hoverColor="#3785D3"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(macLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/macOS.react.svg"
|
||||
size="25"
|
||||
isfill={true}
|
||||
color="#A3A9AE"
|
||||
hoverColor="#000000"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(linuxLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/linux.react.svg"
|
||||
size="25"
|
||||
isfill={true}
|
||||
color="#A3A9AE"
|
||||
hoverColor="#FFB800"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(androidLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/android.react.svg"
|
||||
size="25"
|
||||
isfill={true}
|
||||
color="#A3A9AE"
|
||||
hoverColor="#9BD71C"
|
||||
/>
|
||||
<IconButton
|
||||
onClick={() => window.open(iosLink)}
|
||||
className="icon-button"
|
||||
iconName="/static/images/iOS.react.svg"
|
||||
size="25"
|
||||
isfill={true}
|
||||
color="#A3A9AE"
|
||||
hoverColor="#000000"
|
||||
/>
|
||||
</div>
|
||||
</StyledDownloadAppList>
|
||||
);
|
||||
};
|
||||
|
||||
const DownloadAppList = withTranslation(["Translations"])(
|
||||
withLoader(DownloadAppListContainer)(<></>)
|
||||
);
|
||||
|
||||
export default DownloadAppList;
|
138
products/ASC.Files/Client/src/components/Catalog/Body/Items.js
Normal file
138
products/ASC.Files/Client/src/components/Catalog/Body/Items.js
Normal file
@ -0,0 +1,138 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import CatalogItem from '@appserver/components/catalog-item';
|
||||
import { FolderType } from '@appserver/common/constants';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import withLoader from '../../../HOCs/withLoader';
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
|
||||
const Items = ({ data, showText, selectedTreeNode, onClick, onBadgeClick }) => {
|
||||
const isActive = (item) => {
|
||||
return `${item.id}` === selectedTreeNode[0];
|
||||
};
|
||||
const getEndOfBlock = (item) => {
|
||||
switch (item.key) {
|
||||
case '0-3':
|
||||
case '0-5':
|
||||
case '0-6':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const getFolderIcon = (item) => {
|
||||
let iconUrl = 'images/catalog.folder.react.svg';
|
||||
|
||||
switch (item.rootFolderType) {
|
||||
case FolderType.USER:
|
||||
iconUrl = '/static/images/catalog.user.react.svg';
|
||||
break;
|
||||
case FolderType.SHARE:
|
||||
iconUrl = '/static/images/catalog.shared.react.svg';
|
||||
break;
|
||||
case FolderType.COMMON:
|
||||
iconUrl = '/static/images/catalog.portfolio.react.svg';
|
||||
break;
|
||||
case FolderType.Favorites:
|
||||
iconUrl = '/static/images/catalog.favorites.react.svg';
|
||||
break;
|
||||
case FolderType.Recent:
|
||||
iconUrl = '/static/images/catalog.recent.react.svg';
|
||||
break;
|
||||
case FolderType.Privacy:
|
||||
iconUrl = '/static/images/catalog.private.react.svg';
|
||||
break;
|
||||
case FolderType.TRASH:
|
||||
iconUrl = '/static/images/catalog.trash.react.svg';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (item.providerKey) {
|
||||
case 'GoogleDrive':
|
||||
iconUrl = '/static/images/cloud.services.google.drive.react.svg';
|
||||
break;
|
||||
case 'Box':
|
||||
iconUrl = '/static/images/cloud.services.box.react.svg';
|
||||
break;
|
||||
case 'DropboxV2':
|
||||
iconUrl = '/static/images/cloud.services.dropbox.react.svg';
|
||||
break;
|
||||
case 'OneDrive':
|
||||
iconUrl = '/static/images/cloud.services.onedrive.react.svg';
|
||||
break;
|
||||
case 'SharePoint':
|
||||
iconUrl = '/static/images/cloud.services.onedrive.react.svg';
|
||||
break;
|
||||
case 'kDrive':
|
||||
iconUrl = '/static/images/catalog.folder.react.svg';
|
||||
break;
|
||||
case 'Yandex':
|
||||
iconUrl = '/static/images/catalog.folder.react.svg';
|
||||
break;
|
||||
case 'NextCloud':
|
||||
iconUrl = '/static/images/cloud.services.nextcloud.react.svg';
|
||||
break;
|
||||
case 'OwnCloud':
|
||||
iconUrl = '/static/images/catalog.folder.react.svg';
|
||||
break;
|
||||
case 'WebDav':
|
||||
iconUrl = '/static/images/catalog.folder.react.svg';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return iconUrl;
|
||||
};
|
||||
|
||||
const getItem = (data) => {
|
||||
const items = data.map((item) => {
|
||||
const showBadge = item.newItems ? item.newItems > 0 && true : false;
|
||||
|
||||
return (
|
||||
<CatalogItem
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
icon={getFolderIcon(item)}
|
||||
showText={showText}
|
||||
text={item.title}
|
||||
isActive={isActive(item)}
|
||||
onClick={onClick}
|
||||
isEndOfBlock={getEndOfBlock(item)}
|
||||
showBadge={showBadge}
|
||||
labelBadge={showBadge ? item.newItems : null}
|
||||
onClickBadge={onBadgeClick}
|
||||
/>
|
||||
);
|
||||
});
|
||||
return items;
|
||||
};
|
||||
|
||||
return <>{getItem(data)}</>;
|
||||
};
|
||||
|
||||
Items.propTypes = {
|
||||
data: PropTypes.array,
|
||||
showText: PropTypes.bool,
|
||||
selectedTreeNode: PropTypes.array,
|
||||
onClick: PropTypes.func,
|
||||
onClickBadge: PropTypes.func,
|
||||
};
|
||||
|
||||
export default inject(({ auth, treeFoldersStore }) => {
|
||||
const { treeFolders, selectedTreeNode } = treeFoldersStore;
|
||||
|
||||
return {
|
||||
showText: auth.settingsStore.showText,
|
||||
data: treeFolders,
|
||||
selectedTreeNode,
|
||||
};
|
||||
})(
|
||||
withTranslation(['Home', 'Common'])(
|
||||
withLoader(observer(Items))(<Loaders.DocumentCatalogFolderLoader />),
|
||||
),
|
||||
);
|
@ -0,0 +1,95 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router';
|
||||
import CatalogItem from '@appserver/components/catalog-item';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { combineUrl } from '@appserver/common/utils';
|
||||
import config from '../../../../package.json';
|
||||
import { AppServerConfig } from '@appserver/common/constants';
|
||||
import withLoader from '../../../HOCs/withLoader';
|
||||
import { isTablet } from '@appserver/components/utils/device';
|
||||
|
||||
const PureSettingsItems = ({
|
||||
match,
|
||||
expandedSetting,
|
||||
setSelectedNode,
|
||||
setExpandSettingsTree,
|
||||
setSelectedFolder,
|
||||
history,
|
||||
setIsLoading,
|
||||
t,
|
||||
showText,
|
||||
homepage,
|
||||
setShowText,
|
||||
}) => {
|
||||
const { setting } = match.params;
|
||||
const iconUrl = '/static/images/settings.react.svg';
|
||||
|
||||
React.useEffect(() => {
|
||||
setIsLoading(true);
|
||||
setSelectedNode([setting]);
|
||||
setIsLoading(false);
|
||||
}, [setting, setIsLoading, setSelectedNode]);
|
||||
|
||||
React.useEffect(() => {
|
||||
const { setting } = match.params;
|
||||
if (setting && !expandedSetting) setExpandSettingsTree(['settings']);
|
||||
}, [match, expandedSetting, setExpandSettingsTree]);
|
||||
|
||||
const onClick = () => {
|
||||
setSelectedFolder(null);
|
||||
|
||||
setSelectedNode(['common']);
|
||||
if (!expandedSetting || expandedSetting[0] !== 'settings') setExpandSettingsTree(`settings`);
|
||||
if (isTablet()) setShowText(false);
|
||||
return history.push(combineUrl(AppServerConfig.proxyURL, homepage, '/settings/common'));
|
||||
|
||||
// if (selectedTreeNode[0] !== path) {
|
||||
// setSelectedNode(section);
|
||||
// return history.push(
|
||||
// combineUrl(AppServerConfig.proxyURL, config.homepage, `/settings/${path}`),
|
||||
// );
|
||||
// }
|
||||
};
|
||||
|
||||
const isActive = () => {
|
||||
return window.location.pathname.indexOf('/settings') > 0;
|
||||
};
|
||||
|
||||
return (
|
||||
<CatalogItem
|
||||
id="settings"
|
||||
key="settings"
|
||||
text={t('Common:Settings')}
|
||||
icon={iconUrl}
|
||||
showText={showText}
|
||||
onClick={onClick}
|
||||
isActive={isActive()}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const SettingsItems = withTranslation(['Settings', 'Common'])(
|
||||
withRouter(withLoader(PureSettingsItems)(<></>)),
|
||||
);
|
||||
|
||||
export default inject(
|
||||
({ auth, filesStore, settingsStore, treeFoldersStore, selectedFolderStore }) => {
|
||||
const { setIsLoading } = filesStore;
|
||||
const { setSelectedFolder } = selectedFolderStore;
|
||||
const { selectedTreeNode, setSelectedNode } = treeFoldersStore;
|
||||
const { expandedSetting, setExpandSettingsTree } = settingsStore;
|
||||
return {
|
||||
selectedTreeNode,
|
||||
expandedSetting,
|
||||
setIsLoading,
|
||||
setSelectedFolder,
|
||||
setSelectedNode,
|
||||
setExpandSettingsTree,
|
||||
showText: auth.settingsStore.showText,
|
||||
setShowText: auth.settingsStore.setShowText,
|
||||
homepage: config.homepage,
|
||||
};
|
||||
},
|
||||
)(observer(SettingsItems));
|
@ -0,0 +1,276 @@
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import Link from "@appserver/components/link";
|
||||
import { withTranslation } from "react-i18next";
|
||||
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withRouter } from "react-router";
|
||||
import { combineUrl } from "@appserver/common/utils";
|
||||
import { AppServerConfig } from "@appserver/common/constants";
|
||||
import config from "../../../../package.json";
|
||||
import withLoader from "../../../HOCs/withLoader";
|
||||
import { useCallback } from "react";
|
||||
import IconButton from "@appserver/components/icon-button";
|
||||
import { connectedCloudsTitleTranslation } from "../../../helpers/utils";
|
||||
|
||||
const StyledThirdParty = styled.div`
|
||||
margin-top: 42px;
|
||||
|
||||
.tree-thirdparty-list {
|
||||
padding-top: 3px;
|
||||
display: flex;
|
||||
max-width: inherit;
|
||||
|
||||
.icon {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div {
|
||||
height: 25px;
|
||||
width: 25px;
|
||||
//background: #eceef1;
|
||||
//text-align: center;
|
||||
margin-right: 10px;
|
||||
color: #818b91;
|
||||
:first-of-type {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
:last-of-type {
|
||||
border-radius: 0 3px 3px 0;
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
height: 32px;
|
||||
|
||||
:first-of-type {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
:last-of-type {
|
||||
border-radius: 0 3px 3px 0;
|
||||
padding-right: 5px;
|
||||
|
||||
img {
|
||||
margin-top: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
padding: 7px 4px 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const iconButtonProps = {
|
||||
color: "#A3A9AE",
|
||||
hoverColor: "#818b91",
|
||||
size: 25,
|
||||
className: "icon",
|
||||
};
|
||||
|
||||
const ServiceItem = (props) => {
|
||||
const { capability, src, ...rest } = props;
|
||||
|
||||
const capabilityName = capability[0];
|
||||
const capabilityLink = capability.length > 1 ? capability[1] : "";
|
||||
|
||||
const dataProps = {
|
||||
"data-link": capabilityLink,
|
||||
"data-title": capabilityName,
|
||||
"data-key": capabilityName,
|
||||
};
|
||||
|
||||
return (
|
||||
<div {...dataProps} {...rest}>
|
||||
<IconButton iconName={src} {...iconButtonProps} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const PureThirdPartyListContainer = ({
|
||||
t,
|
||||
googleConnectItem,
|
||||
boxConnectItem,
|
||||
dropboxConnectItem,
|
||||
oneDriveConnectItem,
|
||||
nextCloudConnectItem,
|
||||
//webDavConnectItem,
|
||||
setConnectItem,
|
||||
setConnectDialogVisible,
|
||||
setSelectedNode,
|
||||
setSelectedFolder,
|
||||
getOAuthToken,
|
||||
openConnectWindow,
|
||||
setThirdPartyDialogVisible,
|
||||
history,
|
||||
}) => {
|
||||
const redirectAction = () => {
|
||||
const thirdPartyUrl = "/settings/thirdParty";
|
||||
if (history.location.pathname.indexOf(thirdPartyUrl) === -1) {
|
||||
setSelectedNode(["thirdParty"]);
|
||||
setSelectedFolder(null);
|
||||
return history.push(
|
||||
combineUrl(AppServerConfig.proxyURL, config.homepage, thirdPartyUrl)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const onConnect = (e) => {
|
||||
const data = e.currentTarget.dataset;
|
||||
|
||||
if (data.link) {
|
||||
let authModal = window.open(
|
||||
"",
|
||||
"Authorization",
|
||||
"height=600, width=1020"
|
||||
);
|
||||
openConnectWindow(data.title, authModal)
|
||||
.then(() => redirectAction())
|
||||
.then((modal) =>
|
||||
getOAuthToken(modal).then((token) => {
|
||||
authModal.close();
|
||||
const serviceData = {
|
||||
title: connectedCloudsTitleTranslation(data.title, t),
|
||||
provider_key: data.title,
|
||||
link: data.link,
|
||||
token,
|
||||
};
|
||||
setConnectItem(serviceData);
|
||||
setConnectDialogVisible(true);
|
||||
})
|
||||
)
|
||||
.catch((e) => console.error(e));
|
||||
} else {
|
||||
data.title = connectedCloudsTitleTranslation(data.title, t);
|
||||
setConnectItem(data);
|
||||
setConnectDialogVisible(true);
|
||||
redirectAction();
|
||||
}
|
||||
};
|
||||
|
||||
const onShowConnectPanel = useCallback(() => {
|
||||
setThirdPartyDialogVisible(true);
|
||||
redirectAction();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyledThirdParty>
|
||||
<Link
|
||||
color="#555F65"
|
||||
fontSize="14px"
|
||||
fontWeight={600}
|
||||
onClick={onShowConnectPanel}
|
||||
>
|
||||
{t("Translations:AddAccount")}
|
||||
</Link>
|
||||
<div className="tree-thirdparty-list">
|
||||
{googleConnectItem && (
|
||||
<ServiceItem
|
||||
capability={googleConnectItem}
|
||||
src="images/services/google_drive.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)}
|
||||
{boxConnectItem && (
|
||||
<ServiceItem
|
||||
capability={boxConnectItem}
|
||||
src="images/services/box.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)}
|
||||
{dropboxConnectItem && (
|
||||
<ServiceItem
|
||||
capability={dropboxConnectItem}
|
||||
src="images/services/dropbox.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)}
|
||||
{oneDriveConnectItem && (
|
||||
<ServiceItem
|
||||
capability={oneDriveConnectItem}
|
||||
src="images/services/onedrive.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)}
|
||||
{nextCloudConnectItem && (
|
||||
<ServiceItem
|
||||
capability={nextCloudConnectItem}
|
||||
src="images/services/nextcloud.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)}
|
||||
{/* {webDavConnectItem && (
|
||||
<ServiceItem
|
||||
capability={webDavConnectItem}
|
||||
src="images/services/more.svg"
|
||||
onClick={onConnect}
|
||||
/>
|
||||
)} */}
|
||||
|
||||
<IconButton
|
||||
iconName="images/services/more.svg"
|
||||
onClick={onShowConnectPanel}
|
||||
{...iconButtonProps}
|
||||
/>
|
||||
</div>
|
||||
</StyledThirdParty>
|
||||
);
|
||||
};
|
||||
|
||||
const ThirdPartyList = withTranslation(["Article", "Translations"])(
|
||||
withRouter(withLoader(PureThirdPartyListContainer)(<></>))
|
||||
);
|
||||
|
||||
export default inject(
|
||||
({
|
||||
filesStore,
|
||||
auth,
|
||||
settingsStore,
|
||||
treeFoldersStore,
|
||||
selectedFolderStore,
|
||||
dialogsStore,
|
||||
}) => {
|
||||
const { setIsLoading } = filesStore;
|
||||
const { setSelectedFolder } = selectedFolderStore;
|
||||
const { setSelectedNode } = treeFoldersStore;
|
||||
const {
|
||||
googleConnectItem,
|
||||
boxConnectItem,
|
||||
dropboxConnectItem,
|
||||
oneDriveConnectItem,
|
||||
nextCloudConnectItem,
|
||||
webDavConnectItem,
|
||||
openConnectWindow,
|
||||
} = settingsStore.thirdPartyStore;
|
||||
|
||||
const { getOAuthToken } = auth.settingsStore;
|
||||
|
||||
const {
|
||||
setConnectItem,
|
||||
setConnectDialogVisible,
|
||||
setThirdPartyDialogVisible,
|
||||
} = dialogsStore;
|
||||
return {
|
||||
googleConnectItem,
|
||||
boxConnectItem,
|
||||
dropboxConnectItem,
|
||||
oneDriveConnectItem,
|
||||
nextCloudConnectItem,
|
||||
webDavConnectItem,
|
||||
|
||||
setIsLoading,
|
||||
setSelectedFolder,
|
||||
setSelectedNode,
|
||||
setConnectItem,
|
||||
setConnectDialogVisible,
|
||||
getOAuthToken,
|
||||
openConnectWindow,
|
||||
setThirdPartyDialogVisible,
|
||||
};
|
||||
}
|
||||
)(observer(ThirdPartyList));
|
130
products/ASC.Files/Client/src/components/Catalog/Body/index.js
Normal file
130
products/ASC.Files/Client/src/components/Catalog/Body/index.js
Normal file
@ -0,0 +1,130 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { setDocumentTitle } from '../../../helpers/utils';
|
||||
import config from '../../../../package.json';
|
||||
import { AppServerConfig } from '@appserver/common/constants';
|
||||
import Items from './Items';
|
||||
import { tablet } from '@appserver/components/utils/device';
|
||||
import FilesFilter from '@appserver/common/api/files/filter';
|
||||
import SettingsItems from './SettingsItems';
|
||||
import { combineUrl } from '@appserver/common/utils';
|
||||
import { isDesktop, isTablet } from 'react-device-detect';
|
||||
import ThirdPartyList from './ThirdPartyList';
|
||||
import DownloadAppList from './DownloadAppList';
|
||||
import Banner from './Banner';
|
||||
|
||||
const StyledBlock = styled.div`
|
||||
padding: 0 20px;
|
||||
|
||||
@media ${tablet} {
|
||||
padding: ${(props) => (props.showText ? '0 16px' : 0)};
|
||||
}
|
||||
`;
|
||||
|
||||
const CatalogBodyContent = (props) => {
|
||||
const {
|
||||
personal,
|
||||
firstLoad,
|
||||
showText,
|
||||
isDesktopClient,
|
||||
enableThirdParty,
|
||||
isVisitor,
|
||||
campaigns,
|
||||
FirebaseHelper,
|
||||
} = props;
|
||||
const onClick = React.useCallback((data) => {
|
||||
const {
|
||||
setShowText,
|
||||
setIsLoading,
|
||||
setSelectedNode,
|
||||
fetchFiles,
|
||||
homepage,
|
||||
history,
|
||||
setFirstLoad,
|
||||
} = props;
|
||||
|
||||
setSelectedNode(data);
|
||||
setIsLoading(true);
|
||||
|
||||
if (window.location.pathname.indexOf('/filter') > 0) {
|
||||
fetchFiles(data, null, true, false)
|
||||
.then(() => !isDesktop && setShowText(false))
|
||||
.catch((err) => toastr.error(err))
|
||||
.finally(() => setIsLoading(false));
|
||||
} else {
|
||||
setFirstLoad(true);
|
||||
const filter = FilesFilter.getDefault();
|
||||
|
||||
filter.folder = data;
|
||||
|
||||
const urlFilter = filter.toUrlParams();
|
||||
|
||||
history.push(combineUrl(AppServerConfig.proxyURL, homepage, `/filter?${urlFilter}`));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onShowNewFilesPanel = React.useCallback((folderId) => {
|
||||
props.setNewFilesPanelVisible(true, [`${folderId}`]);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Items onClick={onClick} onBadgeClick={onShowNewFilesPanel} />
|
||||
{!personal && !firstLoad && <SettingsItems />}
|
||||
{!isDesktopClient && showText && (
|
||||
<StyledBlock showText={showText}>
|
||||
{enableThirdParty && !isVisitor && <ThirdPartyList />}
|
||||
<DownloadAppList />
|
||||
{(isDesktop || isTablet) && personal && !firstLoad && campaigns.length > 0 && (
|
||||
<Banner FirebaseHelper={FirebaseHelper} />
|
||||
)}
|
||||
</StyledBlock>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default inject(
|
||||
({ auth, filesStore, treeFoldersStore, selectedFolderStore, dialogsStore, settingsStore }) => {
|
||||
const { fetchFiles, setIsLoading, setFirstLoad, firstLoad } = filesStore;
|
||||
const { treeFolders, setSelectedNode, setTreeFolders } = treeFoldersStore;
|
||||
|
||||
const { setNewFilesPanelVisible } = dialogsStore;
|
||||
|
||||
const {
|
||||
showText,
|
||||
setShowText,
|
||||
personal,
|
||||
hideArticle,
|
||||
isDesktopClient,
|
||||
FirebaseHelper,
|
||||
} = auth.settingsStore;
|
||||
|
||||
const selectedFolderTitle = selectedFolderStore.title;
|
||||
|
||||
selectedFolderTitle ? setDocumentTitle(selectedFolderTitle) : setDocumentTitle();
|
||||
|
||||
return {
|
||||
treeFolders,
|
||||
showText,
|
||||
setShowText,
|
||||
enableThirdParty: settingsStore.enableThirdParty,
|
||||
isVisitor: auth.userStore.user.isVisitor,
|
||||
homepage: config.homepage,
|
||||
personal,
|
||||
|
||||
setIsLoading,
|
||||
setFirstLoad,
|
||||
fetchFiles,
|
||||
setSelectedNode,
|
||||
setTreeFolders,
|
||||
setNewFilesPanelVisible,
|
||||
hideArticle,
|
||||
firstLoad,
|
||||
isDesktopClient,
|
||||
FirebaseHelper,
|
||||
};
|
||||
},
|
||||
)(observer(withRouter(CatalogBodyContent)));
|
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
|
||||
const CatalogHeaderContent = ({ currentModuleName }) => {
|
||||
return currentModuleName ? <>{currentModuleName}</> : <Loaders.ArticleHeader />;
|
||||
};
|
||||
|
||||
export default inject(({ auth }) => {
|
||||
return {
|
||||
currentModuleName: (auth.product && auth.product.title) || '',
|
||||
};
|
||||
})(observer(CatalogHeaderContent));
|
@ -0,0 +1,167 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { withRouter } from 'react-router';
|
||||
import MainButton from '@appserver/components/main-button';
|
||||
import DropDownItem from '@appserver/components/drop-down-item';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { isMobile } from 'react-device-detect';
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import { FileAction, AppServerConfig } from '@appserver/common/constants';
|
||||
import { encryptionUploadDialog } from '../../../helpers/desktop';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import config from '../../../../package.json';
|
||||
import { combineUrl } from '@appserver/common/utils';
|
||||
import withLoader from '../../../HOCs/withLoader';
|
||||
|
||||
class CatalogMainButtonContent extends React.Component {
|
||||
onCreate = (e) => {
|
||||
// this.goToHomePage();
|
||||
const format = e.currentTarget.dataset.format || null;
|
||||
this.props.setAction({
|
||||
type: FileAction.Create,
|
||||
extension: format,
|
||||
id: -1,
|
||||
});
|
||||
};
|
||||
|
||||
onUploadFileClick = () => {
|
||||
if (this.props.isPrivacy) {
|
||||
encryptionUploadDialog((encryptedFile, encrypted) => {
|
||||
const { startUpload, t } = this.props;
|
||||
encryptedFile.encrypted = encrypted;
|
||||
this.goToHomePage();
|
||||
startUpload([encryptedFile], null, t);
|
||||
});
|
||||
} else {
|
||||
this.inputFilesElement.click();
|
||||
}
|
||||
};
|
||||
|
||||
onUploadFolderClick = () => this.inputFolderElement.click();
|
||||
|
||||
goToHomePage = () => {
|
||||
const { homepage, history, filter } = this.props;
|
||||
const urlFilter = filter.toUrlParams();
|
||||
history.push(combineUrl(AppServerConfig.proxyURL, homepage, `/filter?${urlFilter}`));
|
||||
};
|
||||
|
||||
onFileChange = (e) => {
|
||||
const { startUpload, t } = this.props;
|
||||
//this.goToHomePage();
|
||||
startUpload(e.target.files, null, t);
|
||||
};
|
||||
|
||||
onInputClick = (e) => (e.target.value = null);
|
||||
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
// return (
|
||||
// nextProps.canCreate !== this.props.canCreate ||
|
||||
// nextProps.firstLoad !== this.props.firstLoad ||
|
||||
// nextProps.isPrivacy !== this.props.isPrivacy
|
||||
// );
|
||||
// }
|
||||
|
||||
render() {
|
||||
//console.log("Files ArticleMainButtonContent render");
|
||||
const { t, tReady, canCreate, isDisabled, firstLoad, isPrivacy } = this.props;
|
||||
|
||||
return (
|
||||
<MainButton
|
||||
isDisabled={isDisabled ? isDisabled : !canCreate}
|
||||
isDropdown={true}
|
||||
text={t('Common:Actions')}>
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/actions.documents.react.svg"
|
||||
label={t('NewDocument')}
|
||||
onClick={this.onCreate}
|
||||
data-format="docx"
|
||||
/>
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/spreadsheet.react.svg"
|
||||
label={t('NewSpreadsheet')}
|
||||
onClick={this.onCreate}
|
||||
data-format="xlsx"
|
||||
/>
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/actions.presentation.react.svg"
|
||||
label={t('NewPresentation')}
|
||||
onClick={this.onCreate}
|
||||
data-format="pptx"
|
||||
/>
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/catalog.folder.react.svg"
|
||||
label={t('NewFolder')}
|
||||
onClick={this.onCreate}
|
||||
/>
|
||||
<DropDownItem isSeparator />
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/actions.upload.react.svg"
|
||||
label={t('UploadFiles')}
|
||||
onClick={this.onUploadFileClick}
|
||||
/>
|
||||
{!isMobile && (
|
||||
<DropDownItem
|
||||
className="main-button_drop-down"
|
||||
icon="images/actions.upload.react.svg"
|
||||
label={t('UploadFolder')}
|
||||
disabled={isPrivacy}
|
||||
onClick={this.onUploadFolderClick}
|
||||
/>
|
||||
)}
|
||||
<input
|
||||
id="customFileInput"
|
||||
className="custom-file-input"
|
||||
multiple
|
||||
type="file"
|
||||
onChange={this.onFileChange}
|
||||
onClick={this.onInputClick}
|
||||
ref={(input) => (this.inputFilesElement = input)}
|
||||
style={{ display: 'none' }}
|
||||
/>
|
||||
<input
|
||||
id="customFolderInput"
|
||||
className="custom-file-input"
|
||||
webkitdirectory=""
|
||||
mozdirectory=""
|
||||
type="file"
|
||||
onChange={this.onFileChange}
|
||||
onClick={this.onInputClick}
|
||||
ref={(input) => (this.inputFolderElement = input)}
|
||||
style={{ display: 'none' }}
|
||||
/>
|
||||
</MainButton>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
CatalogMainButtonContent.propTypes = {
|
||||
history: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default inject(({ filesStore, uploadDataStore, treeFoldersStore }) => {
|
||||
const { firstLoad, fileActionStore, filter, canCreate } = filesStore;
|
||||
const { isPrivacyFolder } = treeFoldersStore;
|
||||
const { startUpload } = uploadDataStore;
|
||||
|
||||
return {
|
||||
homepage: config.homepage,
|
||||
firstLoad,
|
||||
isPrivacy: isPrivacyFolder,
|
||||
filter,
|
||||
canCreate,
|
||||
|
||||
setAction: fileActionStore.setAction,
|
||||
startUpload,
|
||||
};
|
||||
})(
|
||||
withRouter(
|
||||
withTranslation(['Article', 'Common'])(
|
||||
withLoader(observer(CatalogMainButtonContent))(<Loaders.MainButton />),
|
||||
),
|
||||
),
|
||||
);
|
@ -0,0 +1,3 @@
|
||||
export { default as CatalogHeaderContent } from './Header';
|
||||
export { default as CatalogBodyContent } from './Body';
|
||||
export { default as CatalogMainButtonContent } from './MainButton';
|
@ -1,32 +1,38 @@
|
||||
import React from "react";
|
||||
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 "studio/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 { withRouter } from 'react-router';
|
||||
import { isMobile } from 'react-device-detect';
|
||||
import axios from 'axios';
|
||||
import toastr from 'studio/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";
|
||||
} from '../../components/Article';
|
||||
import {
|
||||
CatalogBodyContent,
|
||||
CatalogHeaderContent,
|
||||
CatalogMainButtonContent,
|
||||
} from '../../components/Catalog';
|
||||
|
||||
import {
|
||||
SectionBodyContent,
|
||||
SectionFilterContent,
|
||||
SectionHeaderContent,
|
||||
SectionPagingContent,
|
||||
} from "./Section";
|
||||
} from './Section';
|
||||
|
||||
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 { 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';
|
||||
|
||||
class PureHome extends React.Component {
|
||||
componentDidMount() {
|
||||
@ -42,19 +48,17 @@ class PureHome extends React.Component {
|
||||
getFileInfo,
|
||||
} = this.props;
|
||||
|
||||
const reg = new RegExp(`${homepage}((/?)$|/filter)`, "gm"); //TODO: Always find?
|
||||
const reg = new RegExp(`${homepage}((/?)$|/filter)`, 'gm'); //TODO: Always find?
|
||||
const match = window.location.pathname.match(reg);
|
||||
let filterObj = null;
|
||||
|
||||
if (window.location.href.indexOf("/files/#preview") > 1) {
|
||||
if (window.location.href.indexOf('/files/#preview') > 1) {
|
||||
const pathname = window.location.href;
|
||||
const fileId = pathname.slice(pathname.indexOf("#preview") + 9);
|
||||
const fileId = pathname.slice(pathname.indexOf('#preview') + 9);
|
||||
|
||||
getFileInfo(fileId)
|
||||
.then((data) => {
|
||||
const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage(
|
||||
data.fileExst
|
||||
);
|
||||
const canOpenPlayer = mediaViewersFormatsStore.isMediaOrImage(data.fileExst);
|
||||
const file = { ...data, canOpenPlayer };
|
||||
setToPreviewFile(file, true);
|
||||
})
|
||||
@ -83,7 +87,7 @@ class PureHome extends React.Component {
|
||||
|
||||
if (filterObj && filterObj.authorType) {
|
||||
const authorType = filterObj.authorType;
|
||||
const indexOfUnderscore = authorType.indexOf("_");
|
||||
const indexOfUnderscore = authorType.indexOf('_');
|
||||
const type = authorType.slice(0, indexOfUnderscore);
|
||||
const itemId = authorType.slice(indexOfUnderscore + 1);
|
||||
|
||||
@ -105,9 +109,9 @@ class PureHome extends React.Component {
|
||||
const newFilter = filter ? filter.clone() : FilesFilter.getDefault();
|
||||
const requests = [Promise.resolve(newFilter)];
|
||||
|
||||
if (type === "group") {
|
||||
if (type === 'group') {
|
||||
requests.push(getGroup(itemId));
|
||||
} else if (type === "user") {
|
||||
} else if (type === 'user') {
|
||||
requests.push(getUserById(itemId));
|
||||
}
|
||||
|
||||
@ -117,16 +121,16 @@ class PureHome extends React.Component {
|
||||
.all(requests)
|
||||
.catch((err) => {
|
||||
Promise.resolve(FilesFilter.getDefault());
|
||||
console.warn("Filter restored by default", err);
|
||||
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 type = result.displayName ? 'user' : 'group';
|
||||
const selectedItem = {
|
||||
key: result.id,
|
||||
label: type === "user" ? result.displayName : result.name,
|
||||
label: type === 'user' ? result.displayName : result.name,
|
||||
type,
|
||||
};
|
||||
filter.selectedItem = selectedItem;
|
||||
@ -154,7 +158,7 @@ class PureHome extends React.Component {
|
||||
fetchDefaultFiles = () => {
|
||||
const { isVisitor, fetchFiles, setIsLoading, setFirstLoad } = this.props;
|
||||
const filterObj = FilesFilter.getDefault();
|
||||
const folderId = isVisitor ? "@common" : filterObj.folder;
|
||||
const folderId = isVisitor ? '@common' : filterObj.folder;
|
||||
|
||||
fetchFiles(folderId).finally(() => {
|
||||
setIsLoading(false);
|
||||
@ -171,31 +175,31 @@ class PureHome extends React.Component {
|
||||
showOperationToast = (type, qty, title) => {
|
||||
const { t } = this.props;
|
||||
switch (type) {
|
||||
case "move":
|
||||
case 'move':
|
||||
if (qty > 1) {
|
||||
return toastr.success(
|
||||
<Trans t={t} i18nKey="MoveItems" ns="Home">
|
||||
{{ qty }} elements has been moved
|
||||
</Trans>
|
||||
</Trans>,
|
||||
);
|
||||
}
|
||||
return toastr.success(
|
||||
<Trans t={t} i18nKey="MoveItem" ns="Home">
|
||||
{{ title }} moved
|
||||
</Trans>
|
||||
</Trans>,
|
||||
);
|
||||
case "duplicate":
|
||||
case 'duplicate':
|
||||
if (qty > 1) {
|
||||
return toastr.success(
|
||||
<Trans t={t} i18nKey="CopyItems" ns="Home">
|
||||
{{ qty }} elements copied
|
||||
</Trans>
|
||||
</Trans>,
|
||||
);
|
||||
}
|
||||
return toastr.success(
|
||||
<Trans t={t} i18nKey="CopyItem" ns="Home">
|
||||
{{ title }} copied
|
||||
</Trans>
|
||||
</Trans>,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
@ -213,8 +217,7 @@ class PureHome extends React.Component {
|
||||
} = this.props;
|
||||
setUploadPanelVisible(!uploadPanelVisible);
|
||||
|
||||
if (primaryProgressDataVisible && uploaded && converted)
|
||||
clearPrimaryProgressData();
|
||||
if (primaryProgressDataVisible && uploaded && converted) clearPrimaryProgressData();
|
||||
};
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
@ -227,15 +230,8 @@ class PureHome extends React.Component {
|
||||
if (this.props.isHeaderVisible !== prevProps.isHeaderVisible) {
|
||||
this.props.setHeaderVisible(this.props.isHeaderVisible);
|
||||
}
|
||||
if (
|
||||
isProgressFinished &&
|
||||
isProgressFinished !== prevProps.isProgressFinished
|
||||
) {
|
||||
this.showOperationToast(
|
||||
secondaryProgressDataStoreIcon,
|
||||
selectionLength,
|
||||
selectionTitle
|
||||
);
|
||||
if (isProgressFinished && isProgressFinished !== prevProps.isProgressFinished) {
|
||||
this.showOperationToast(secondaryProgressDataStoreIcon, selectionLength, selectionTitle);
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,6 +257,8 @@ class PureHome extends React.Component {
|
||||
|
||||
dragging,
|
||||
tReady,
|
||||
|
||||
showCatalog,
|
||||
} = this.props;
|
||||
return (
|
||||
<>
|
||||
@ -283,27 +281,33 @@ class PureHome extends React.Component {
|
||||
showSecondaryButtonAlert={secondaryProgressDataStoreAlert}
|
||||
viewAs={viewAs}
|
||||
hideAside={
|
||||
!!fileActionId ||
|
||||
primaryProgressDataVisible ||
|
||||
secondaryProgressDataStoreVisible
|
||||
!!fileActionId || primaryProgressDataVisible || secondaryProgressDataStoreVisible
|
||||
}
|
||||
isLoaded={!firstLoad}
|
||||
isHeaderVisible={isHeaderVisible}
|
||||
onOpenUploadPanel={this.showUploadPanel}
|
||||
firstLoad={firstLoad}
|
||||
dragging={dragging}
|
||||
>
|
||||
dragging={dragging}>
|
||||
<PageLayout.ArticleHeader>
|
||||
<ArticleHeaderContent />
|
||||
</PageLayout.ArticleHeader>
|
||||
|
||||
<PageLayout.ArticleMainButton>
|
||||
<ArticleMainButtonContent />
|
||||
</PageLayout.ArticleMainButton>
|
||||
|
||||
<PageLayout.ArticleBody>
|
||||
<ArticleBodyContent onTreeDrop={this.onDrop} />
|
||||
</PageLayout.ArticleBody>
|
||||
|
||||
<PageLayout.CatalogHeader>
|
||||
<CatalogHeaderContent />
|
||||
</PageLayout.CatalogHeader>
|
||||
<PageLayout.CatalogMainButton>
|
||||
<CatalogMainButtonContent />
|
||||
</PageLayout.CatalogMainButton>
|
||||
<PageLayout.CatalogBody>
|
||||
<CatalogBodyContent />
|
||||
</PageLayout.CatalogBody>
|
||||
|
||||
<PageLayout.SectionHeader>
|
||||
<SectionHeaderContent />
|
||||
</PageLayout.SectionHeader>
|
||||
@ -325,21 +329,11 @@ class PureHome extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
const Home = withTranslation("Home")(PureHome);
|
||||
const Home = withTranslation('Home')(PureHome);
|
||||
|
||||
export default inject(
|
||||
({
|
||||
auth,
|
||||
filesStore,
|
||||
uploadDataStore,
|
||||
treeFoldersStore,
|
||||
mediaViewerDataStore,
|
||||
formatsStore,
|
||||
}) => {
|
||||
const {
|
||||
secondaryProgressDataStore,
|
||||
primaryProgressDataStore,
|
||||
} = uploadDataStore;
|
||||
({ auth, filesStore, uploadDataStore, treeFoldersStore, mediaViewerDataStore, formatsStore }) => {
|
||||
const { secondaryProgressDataStore, primaryProgressDataStore } = uploadDataStore;
|
||||
const {
|
||||
firstLoad,
|
||||
setFirstLoad,
|
||||
@ -358,12 +352,7 @@ export default inject(
|
||||
const { mediaViewersFormatsStore } = formatsStore;
|
||||
|
||||
const { id } = fileActionStore;
|
||||
const {
|
||||
isRecycleBinFolder,
|
||||
isPrivacyFolder,
|
||||
expandedKeys,
|
||||
setExpandedKeys,
|
||||
} = treeFoldersStore;
|
||||
const { isRecycleBinFolder, isPrivacyFolder, expandedKeys, setExpandedKeys } = treeFoldersStore;
|
||||
|
||||
const {
|
||||
visible: primaryProgressDataVisible,
|
||||
@ -381,17 +370,10 @@ export default inject(
|
||||
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 selectionTitle = isProgressFinished ? filesStore.selectionTitle : null;
|
||||
|
||||
const { setToPreviewFile } = mediaViewerDataStore;
|
||||
if (!firstLoad) {
|
||||
@ -443,6 +425,7 @@ export default inject(
|
||||
setToPreviewFile,
|
||||
mediaViewersFormatsStore,
|
||||
getFileInfo,
|
||||
showCatalog: auth.settingsStore.showCatalog,
|
||||
};
|
||||
}
|
||||
},
|
||||
)(withRouter(observer(Home)));
|
||||
|
@ -1,27 +1,25 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { withRouter } from "react-router";
|
||||
import PageLayout from "@appserver/common/components/PageLayout";
|
||||
import Loaders from "@appserver/common/components/Loaders";
|
||||
import { showLoader, hideLoader } from "@appserver/common/utils";
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { withRouter } from 'react-router';
|
||||
import PageLayout from '@appserver/common/components/PageLayout';
|
||||
import Loaders from '@appserver/common/components/Loaders';
|
||||
import { showLoader, hideLoader } from '@appserver/common/utils';
|
||||
import {
|
||||
ArticleHeaderContent,
|
||||
ArticleBodyContent,
|
||||
ArticleMainButtonContent,
|
||||
} from "../../components/Article";
|
||||
import { SectionHeaderContent, SectionBodyContent } from "./Section";
|
||||
import { withTranslation } from "react-i18next";
|
||||
import { setDocumentTitle } from "../../helpers/utils";
|
||||
import { inject, observer } from "mobx-react";
|
||||
} from '../../components/Article';
|
||||
import {
|
||||
CatalogBodyContent,
|
||||
CatalogHeaderContent,
|
||||
CatalogMainButtonContent,
|
||||
} from '../../components/Catalog';
|
||||
import { SectionHeaderContent, SectionBodyContent } from './Section';
|
||||
import { withTranslation } from 'react-i18next';
|
||||
import { setDocumentTitle } from '../../helpers/utils';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
|
||||
const PureSettings = ({
|
||||
match,
|
||||
t,
|
||||
isLoading,
|
||||
isLoadedSettingsTree,
|
||||
setFirstLoad,
|
||||
tReady,
|
||||
}) => {
|
||||
const [title, setTitle] = useState("");
|
||||
const PureSettings = ({ match, t, isLoading, isLoadedSettingsTree, setFirstLoad, tReady }) => {
|
||||
const [title, setTitle] = useState('');
|
||||
const { setting } = match.params;
|
||||
|
||||
useEffect(() => {
|
||||
@ -30,17 +28,17 @@ const PureSettings = ({
|
||||
|
||||
useEffect(() => {
|
||||
switch (setting) {
|
||||
case "common":
|
||||
setTitle(t("CommonSettings"));
|
||||
case 'common':
|
||||
setTitle(t('CommonSettings'));
|
||||
break;
|
||||
case "admin":
|
||||
setTitle(t("Common:AdminSettings"));
|
||||
case 'admin':
|
||||
setTitle(t('Common:AdminSettings'));
|
||||
break;
|
||||
case "thirdParty":
|
||||
setTitle(t("ThirdPartySettings"));
|
||||
case 'thirdParty':
|
||||
setTitle(t('ThirdPartySettings'));
|
||||
break;
|
||||
default:
|
||||
setTitle(t("CommonSettings"));
|
||||
setTitle(t('CommonSettings'));
|
||||
break;
|
||||
}
|
||||
}, [setting, t, tReady]);
|
||||
@ -74,6 +72,16 @@ const PureSettings = ({
|
||||
<ArticleBodyContent />
|
||||
</PageLayout.ArticleBody>
|
||||
|
||||
<PageLayout.CatalogHeader>
|
||||
<CatalogHeaderContent />
|
||||
</PageLayout.CatalogHeader>
|
||||
<PageLayout.CatalogMainButton>
|
||||
<CatalogMainButtonContent />
|
||||
</PageLayout.CatalogMainButton>
|
||||
<PageLayout.CatalogBody>
|
||||
<CatalogBodyContent />
|
||||
</PageLayout.CatalogBody>
|
||||
|
||||
<PageLayout.SectionHeader>
|
||||
{(!isLoadedSettingsTree && isLoading) || isLoading || !tReady ? (
|
||||
<Loaders.SectionHeader />
|
||||
@ -84,7 +92,7 @@ const PureSettings = ({
|
||||
|
||||
<PageLayout.SectionBody>
|
||||
{(!isLoadedSettingsTree && isLoading) || isLoading || !tReady ? (
|
||||
setting === "thirdParty" ? (
|
||||
setting === 'thirdParty' ? (
|
||||
<Loaders.Rows />
|
||||
) : (
|
||||
<Loaders.SettingsFiles />
|
||||
@ -98,7 +106,7 @@ const PureSettings = ({
|
||||
);
|
||||
};
|
||||
|
||||
const Settings = withTranslation(["Settings", "Common"])(PureSettings);
|
||||
const Settings = withTranslation(['Settings', 'Common'])(PureSettings);
|
||||
|
||||
export default inject(({ filesStore, settingsStore, treeFoldersStore }) => {
|
||||
const { setFirstLoad, isLoading } = filesStore;
|
||||
|
@ -0,0 +1,39 @@
|
||||
import React from 'react';
|
||||
import styled from 'styled-components';
|
||||
import PropTypes from 'prop-types';
|
||||
import { mobile } from '@appserver/components/utils/device';
|
||||
import MenuIcon from '@appserver/components/public/static/images/menu.react.svg';
|
||||
|
||||
const StyledIconBox = styled.div`
|
||||
display: none;
|
||||
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (props.isProduct && props.showCatalog ? 'flex' : 'none')};
|
||||
align-items: center;
|
||||
}
|
||||
`;
|
||||
|
||||
const StyledMenuIcon = styled(MenuIcon)`
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
fill: #657077;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
const HeaderCatalogBurger = (props) => {
|
||||
const { isProduct, showCatalog, onClick, ...rest } = props;
|
||||
|
||||
return (
|
||||
<StyledIconBox isProduct={isProduct} showCatalog={showCatalog} onClick={onClick} {...rest}>
|
||||
<StyledMenuIcon />
|
||||
</StyledIconBox>
|
||||
);
|
||||
};
|
||||
|
||||
HeaderCatalogBurger.propTypes = {
|
||||
isProduct: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
showCatalog: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default React.memo(HeaderCatalogBurger);
|
@ -1,28 +1,26 @@
|
||||
import React, { useCallback, useState } from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import styled from "styled-components";
|
||||
import NavItem from "./nav-item";
|
||||
import ProfileActions from "./profile-actions";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { tablet } from "@appserver/components/utils/device";
|
||||
import { combineUrl, deleteCookie } from "@appserver/common/utils";
|
||||
import { inject, observer } from "mobx-react";
|
||||
import { withRouter } from "react-router";
|
||||
import { AppServerConfig } from "@appserver/common/constants";
|
||||
import config from "../../../../package.json";
|
||||
import { isDesktop } from "react-device-detect";
|
||||
import AboutDialog from "../../pages/About/AboutDialog";
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import NavItem from './nav-item';
|
||||
import ProfileActions from './profile-actions';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { tablet } from '@appserver/components/utils/device';
|
||||
import { combineUrl, deleteCookie } from '@appserver/common/utils';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { withRouter } from 'react-router';
|
||||
import { AppServerConfig } from '@appserver/common/constants';
|
||||
import config from '../../../../package.json';
|
||||
import { isDesktop, isMobile } from 'react-device-detect';
|
||||
import AboutDialog from '../../pages/About/AboutDialog';
|
||||
import HeaderCatalogBurger from './header-catalog-burger';
|
||||
|
||||
const { proxyURL } = AppServerConfig;
|
||||
const homepage = config.homepage;
|
||||
|
||||
const PROXY_HOMEPAGE_URL = combineUrl(proxyURL, homepage);
|
||||
const ABOUT_URL = combineUrl(PROXY_HOMEPAGE_URL, "/about");
|
||||
const PROFILE_SELF_URL = combineUrl(
|
||||
PROXY_HOMEPAGE_URL,
|
||||
"/products/people/view/@self"
|
||||
);
|
||||
const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, "/my");
|
||||
const ABOUT_URL = combineUrl(PROXY_HOMEPAGE_URL, '/about');
|
||||
const PROFILE_SELF_URL = combineUrl(PROXY_HOMEPAGE_URL, '/products/people/view/@self');
|
||||
const PROFILE_MY_URL = combineUrl(PROXY_HOMEPAGE_URL, '/my');
|
||||
|
||||
const StyledNav = styled.nav`
|
||||
display: flex;
|
||||
@ -66,14 +64,15 @@ const HeaderNav = ({
|
||||
versionAppServer,
|
||||
userIsUpdate,
|
||||
setUserIsUpdate,
|
||||
currentProductId,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
}) => {
|
||||
const { t } = useTranslation(["NavMenu", "Common", "About"]);
|
||||
const { t } = useTranslation(['NavMenu', 'Common', 'About']);
|
||||
const [visibleDialog, setVisibleDialog] = useState(false);
|
||||
|
||||
const onProfileClick = useCallback(() => {
|
||||
peopleAvailable
|
||||
? history.push(PROFILE_SELF_URL)
|
||||
: history.push(PROFILE_MY_URL);
|
||||
peopleAvailable ? history.push(PROFILE_SELF_URL) : history.push(PROFILE_MY_URL);
|
||||
}, []);
|
||||
|
||||
const onAboutClick = useCallback(() => {
|
||||
@ -87,13 +86,8 @@ const HeaderNav = ({
|
||||
const onCloseDialog = () => setVisibleDialog(false);
|
||||
|
||||
const onSwitchToDesktopClick = useCallback(() => {
|
||||
deleteCookie("desktop_view");
|
||||
window.open(
|
||||
`${window.location.origin}?desktop_view=true`,
|
||||
"_self",
|
||||
"",
|
||||
true
|
||||
);
|
||||
deleteCookie('desktop_view');
|
||||
window.open(`${window.location.origin}?desktop_view=true`, '_self', '', true);
|
||||
}, []);
|
||||
|
||||
const onLogoutClick = useCallback(() => logout && logout(), [logout]);
|
||||
@ -101,34 +95,33 @@ const HeaderNav = ({
|
||||
const getCurrentUserActions = useCallback(() => {
|
||||
return [
|
||||
{
|
||||
key: "ProfileBtn",
|
||||
label: t("Common:Profile"),
|
||||
key: 'ProfileBtn',
|
||||
label: t('Common:Profile'),
|
||||
onClick: onProfileClick,
|
||||
url: peopleAvailable ? PROFILE_SELF_URL : PROFILE_MY_URL,
|
||||
},
|
||||
{
|
||||
key: "SwitchToBtn",
|
||||
key: 'SwitchToBtn',
|
||||
...(!isPersonal && {
|
||||
label: t("TurnOnDesktopVersion"),
|
||||
label: t('TurnOnDesktopVersion'),
|
||||
onClick: onSwitchToDesktopClick,
|
||||
url: `${window.location.origin}?desktop_view=true`,
|
||||
target: "_self",
|
||||
target: '_self',
|
||||
}),
|
||||
},
|
||||
{
|
||||
key: "AboutBtn",
|
||||
label: t("AboutCompanyTitle"),
|
||||
key: 'AboutBtn',
|
||||
label: t('AboutCompanyTitle'),
|
||||
onClick: onAboutClick,
|
||||
url: ABOUT_URL,
|
||||
},
|
||||
{
|
||||
key: "LogoutBtn",
|
||||
label: t("LogoutButton"),
|
||||
key: 'LogoutBtn',
|
||||
label: t('LogoutButton'),
|
||||
onClick: onLogoutClick,
|
||||
},
|
||||
];
|
||||
}, [onProfileClick, onAboutClick, onLogoutClick]);
|
||||
|
||||
//console.log("HeaderNav render");
|
||||
return (
|
||||
<StyledNav className="profileMenuIcon hidingHeader">
|
||||
@ -145,17 +138,26 @@ const HeaderNav = ({
|
||||
history.push(m.link);
|
||||
e.preventDefault();
|
||||
}}
|
||||
onBadgeClick={(e) => console.log(m.iconName + "Badge Clicked", e)}
|
||||
onBadgeClick={(e) => console.log(m.iconName + 'Badge Clicked', e)}
|
||||
noHover={true}
|
||||
/>
|
||||
))}
|
||||
{isAuthenticated && user ? (
|
||||
<ProfileActions
|
||||
userActions={getCurrentUserActions()}
|
||||
user={user}
|
||||
userIsUpdate={userIsUpdate}
|
||||
setUserIsUpdate={setUserIsUpdate}
|
||||
/>
|
||||
<>
|
||||
<ProfileActions
|
||||
userActions={getCurrentUserActions()}
|
||||
user={user}
|
||||
userIsUpdate={userIsUpdate}
|
||||
setUserIsUpdate={setUserIsUpdate}
|
||||
isProduct={currentProductId !== 'home'}
|
||||
showCatalog={showCatalog}
|
||||
/>
|
||||
<HeaderCatalogBurger
|
||||
isProduct={currentProductId !== 'home'}
|
||||
showCatalog={showCatalog}
|
||||
onClick={toggleShowText}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
@ -171,7 +173,7 @@ const HeaderNav = ({
|
||||
);
|
||||
};
|
||||
|
||||
HeaderNav.displayName = "HeaderNav";
|
||||
HeaderNav.displayName = 'HeaderNav';
|
||||
|
||||
HeaderNav.propTypes = {
|
||||
history: PropTypes.object,
|
||||
@ -180,22 +182,20 @@ HeaderNav.propTypes = {
|
||||
logout: PropTypes.func,
|
||||
isAuthenticated: PropTypes.bool,
|
||||
isLoaded: PropTypes.bool,
|
||||
currentProductId: PropTypes.string,
|
||||
toggleShowText: PropTypes.func,
|
||||
};
|
||||
|
||||
export default withRouter(
|
||||
inject(({ auth }) => {
|
||||
const {
|
||||
settingsStore,
|
||||
userStore,
|
||||
isAuthenticated,
|
||||
isLoaded,
|
||||
language,
|
||||
logout,
|
||||
} = auth;
|
||||
const { settingsStore, userStore, isAuthenticated, isLoaded, language, logout } = auth;
|
||||
const {
|
||||
defaultPage,
|
||||
personal: isPersonal,
|
||||
version: versionAppServer,
|
||||
currentProductId,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
} = settingsStore;
|
||||
const { user, userIsUpdate, setUserIsUpdate } = userStore;
|
||||
const modules = auth.availableModules;
|
||||
@ -205,13 +205,16 @@ export default withRouter(
|
||||
isAuthenticated,
|
||||
isLoaded,
|
||||
language,
|
||||
defaultPage: defaultPage || "/",
|
||||
defaultPage: defaultPage || '/',
|
||||
modules,
|
||||
logout,
|
||||
peopleAvailable: modules.some((m) => m.appName === "people"),
|
||||
peopleAvailable: modules.some((m) => m.appName === 'people'),
|
||||
versionAppServer,
|
||||
userIsUpdate,
|
||||
setUserIsUpdate,
|
||||
currentProductId,
|
||||
toggleShowText,
|
||||
showCatalog,
|
||||
};
|
||||
})(observer(HeaderNav))
|
||||
})(observer(HeaderNav)),
|
||||
);
|
||||
|
@ -1,10 +1,18 @@
|
||||
import React from "react";
|
||||
import PropTypes from "prop-types";
|
||||
import Avatar from "@appserver/components/avatar";
|
||||
import DropDownItem from "@appserver/components/drop-down-item";
|
||||
import Link from "@appserver/components/link";
|
||||
import ProfileMenu from "./profile-menu";
|
||||
import api from "@appserver/common/api";
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styled from 'styled-components';
|
||||
import Avatar from '@appserver/components/avatar';
|
||||
import DropDownItem from '@appserver/components/drop-down-item';
|
||||
import Link from '@appserver/components/link';
|
||||
import ProfileMenu from './profile-menu';
|
||||
import api from '@appserver/common/api';
|
||||
import { mobile } from '@appserver/components/utils/device';
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
@media ${mobile} {
|
||||
display: ${(props) => (props.isProduct && props.showCatalog ? 'none' : 'block')};
|
||||
}
|
||||
`;
|
||||
class ProfileActions extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@ -14,7 +22,7 @@ class ProfileActions extends React.PureComponent {
|
||||
this.state = {
|
||||
opened: props.opened,
|
||||
user: props.user,
|
||||
avatar: "",
|
||||
avatar: '',
|
||||
};
|
||||
}
|
||||
|
||||
@ -44,10 +52,10 @@ class ProfileActions extends React.PureComponent {
|
||||
getUserRole = (user) => {
|
||||
let isModuleAdmin = user.listAdminModules && user.listAdminModules.length;
|
||||
|
||||
if (user.isOwner) return "owner";
|
||||
if (user.isAdmin || isModuleAdmin) return "admin";
|
||||
if (user.isVisitor) return "guest";
|
||||
return "user";
|
||||
if (user.isOwner) return 'owner';
|
||||
if (user.isAdmin || isModuleAdmin) return 'admin';
|
||||
if (user.isVisitor) return 'guest';
|
||||
return 'user';
|
||||
};
|
||||
|
||||
onClose = (e) => {
|
||||
@ -82,7 +90,10 @@ class ProfileActions extends React.PureComponent {
|
||||
const userRole = this.getUserRole(user);
|
||||
|
||||
return (
|
||||
<div ref={this.ref}>
|
||||
<StyledDiv
|
||||
isProduct={this.props.isProduct}
|
||||
showCatalog={this.props.showCatalog}
|
||||
ref={this.ref}>
|
||||
<Avatar
|
||||
onClick={this.onClick}
|
||||
role={userRole}
|
||||
@ -98,22 +109,20 @@ class ProfileActions extends React.PureComponent {
|
||||
displayName={user.displayName}
|
||||
email={user.email}
|
||||
open={opened}
|
||||
clickOutsideAction={this.onClose}
|
||||
>
|
||||
<div style={{ paddingTop: "8px" }}>
|
||||
clickOutsideAction={this.onClose}>
|
||||
<div style={{ paddingTop: '8px' }}>
|
||||
{this.props.userActions.map((action) => (
|
||||
<Link
|
||||
noHover={true}
|
||||
key={action.key}
|
||||
href={action.url}
|
||||
onClick={this.onClickItemLink}
|
||||
>
|
||||
onClick={this.onClickItemLink}>
|
||||
<DropDownItem {...action} />
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</ProfileMenu>
|
||||
</div>
|
||||
</StyledDiv>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -124,6 +133,8 @@ ProfileActions.propTypes = {
|
||||
userActions: PropTypes.array,
|
||||
userIsUpdate: PropTypes.bool,
|
||||
setUserIsUpdate: PropTypes.func,
|
||||
isProduct: PropTypes.bool,
|
||||
showCatalog: PropTypes.bool,
|
||||
};
|
||||
|
||||
ProfileActions.defaultProps = {
|
||||
@ -131,6 +142,7 @@ ProfileActions.defaultProps = {
|
||||
user: {},
|
||||
userActions: [],
|
||||
userIsUpdate: false,
|
||||
isProduct: false,
|
||||
};
|
||||
|
||||
export default ProfileActions;
|
||||
|
Loading…
Reference in New Issue
Block a user