2020-08-25 13:28:14 +00:00
|
|
|
import React, { useEffect } from "react";
|
2019-09-12 12:15:22 +00:00
|
|
|
import PropTypes from "prop-types";
|
2020-09-17 12:52:07 +00:00
|
|
|
import { Backdrop, ProgressBar, utils } from "asc-web-components";
|
2020-08-25 13:28:14 +00:00
|
|
|
import { withTranslation } from "react-i18next";
|
|
|
|
import i18n from "./i18n";
|
2020-01-24 11:59:55 +00:00
|
|
|
import { ARTICLE_PINNED_KEY } from "../../constants";
|
2019-09-12 12:15:22 +00:00
|
|
|
|
2019-09-12 12:28:13 +00:00
|
|
|
import Article from "./sub-components/article";
|
2020-08-11 12:34:00 +00:00
|
|
|
import SubArticleHeader from "./sub-components/article-header";
|
|
|
|
import SubArticleMainButton from "./sub-components/article-main-button";
|
|
|
|
import SubArticleBody from "./sub-components/article-body";
|
2019-09-12 12:28:13 +00:00
|
|
|
import ArticlePinPanel from "./sub-components/article-pin-panel";
|
|
|
|
import Section from "./sub-components/section";
|
2020-08-11 12:34:00 +00:00
|
|
|
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";
|
2019-09-12 12:28:13 +00:00
|
|
|
import SectionToggler from "./sub-components/section-toggler";
|
2020-08-11 12:34:00 +00:00
|
|
|
import { changeLanguage } from "../../utils";
|
2020-08-31 07:03:19 +00:00
|
|
|
import ReactResizeDetector from "react-resize-detector";
|
2020-08-11 12:34:00 +00:00
|
|
|
|
2020-09-17 12:52:07 +00:00
|
|
|
const { size } = utils.device;
|
|
|
|
|
2020-08-11 12:34:00 +00:00
|
|
|
function ArticleHeader() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ArticleHeader.displayName = "ArticleHeader";
|
|
|
|
|
|
|
|
function ArticleMainButton() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ArticleMainButton.displayName = "ArticleMainButton";
|
|
|
|
|
|
|
|
function ArticleBody() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
ArticleBody.displayName = "ArticleBody";
|
|
|
|
|
|
|
|
function SectionHeader() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
SectionHeader.displayName = "SectionHeader";
|
|
|
|
|
|
|
|
function SectionFilter() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
SectionFilter.displayName = "SectionFilter";
|
|
|
|
|
|
|
|
function SectionBody() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
SectionBody.displayName = "SectionBody";
|
|
|
|
|
|
|
|
function SectionPaging() {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
SectionPaging.displayName = "SectionPaging";
|
|
|
|
|
|
|
|
class PageLayoutComponent extends React.Component {
|
|
|
|
static ArticleHeader = ArticleHeader;
|
|
|
|
static ArticleMainButton = ArticleMainButton;
|
|
|
|
static ArticleBody = ArticleBody;
|
|
|
|
static SectionHeader = SectionHeader;
|
|
|
|
static SectionFilter = SectionFilter;
|
|
|
|
static SectionBody = SectionBody;
|
|
|
|
static SectionPaging = SectionPaging;
|
2019-07-11 11:43:07 +00:00
|
|
|
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
2020-08-11 12:34:00 +00:00
|
|
|
|
|
|
|
const isArticleVisibleAndPinned = !!localStorage.getItem(
|
|
|
|
ARTICLE_PINNED_KEY
|
|
|
|
);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
isBackdropVisible: false,
|
|
|
|
isArticleVisible: isArticleVisibleAndPinned,
|
|
|
|
isArticlePinned: isArticleVisibleAndPinned
|
|
|
|
};
|
2019-09-10 07:03:36 +00:00
|
|
|
}
|
2019-07-15 10:35:10 +00:00
|
|
|
|
2020-02-11 08:11:34 +00:00
|
|
|
componentDidMount() {
|
2020-02-07 16:49:31 +00:00
|
|
|
window.addEventListener("orientationchange", this.orientationChangeHandler);
|
2020-09-17 12:52:07 +00:00
|
|
|
this.orientationChangeHandler();
|
2020-02-07 16:49:31 +00:00
|
|
|
}
|
|
|
|
|
2020-02-11 08:11:34 +00:00
|
|
|
componentWillUnmount() {
|
2020-08-25 13:28:14 +00:00
|
|
|
window.removeEventListener(
|
|
|
|
"orientationchange",
|
|
|
|
this.orientationChangeHandler
|
|
|
|
);
|
2020-02-07 16:49:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
orientationChangeHandler = () => {
|
|
|
|
const isValueExist = !!localStorage.getItem(ARTICLE_PINNED_KEY);
|
2020-09-17 12:52:07 +00:00
|
|
|
const isEnoughWidth = screen.availWidth > size.smallTablet;
|
2020-02-07 16:49:31 +00:00
|
|
|
|
2020-09-17 12:52:07 +00:00
|
|
|
if (!isEnoughWidth && isValueExist) {
|
2020-02-07 16:49:31 +00:00
|
|
|
this.backdropClick();
|
|
|
|
}
|
2020-09-17 12:52:07 +00:00
|
|
|
if (isEnoughWidth && isValueExist) {
|
2020-02-07 16:49:31 +00:00
|
|
|
this.pinArticle();
|
|
|
|
}
|
2020-08-25 13:28:14 +00:00
|
|
|
};
|
2020-02-07 16:49:31 +00:00
|
|
|
|
2019-07-11 11:43:07 +00:00
|
|
|
backdropClick = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: false,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: false,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
pinArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: false,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: true,
|
2019-09-12 12:15:22 +00:00
|
|
|
isArticleVisible: true
|
2019-07-11 11:43:07 +00:00
|
|
|
});
|
2020-01-24 11:59:55 +00:00
|
|
|
|
|
|
|
localStorage.setItem(ARTICLE_PINNED_KEY, true);
|
2019-07-11 11:43:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
unpinArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: true,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false,
|
2019-09-12 12:15:22 +00:00
|
|
|
isArticleVisible: true
|
2019-07-11 11:43:07 +00:00
|
|
|
});
|
2020-01-24 11:59:55 +00:00
|
|
|
|
|
|
|
localStorage.removeItem(ARTICLE_PINNED_KEY);
|
2019-07-11 11:43:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
showArticle = () => {
|
|
|
|
this.setState({
|
2019-07-11 13:21:39 +00:00
|
|
|
isBackdropVisible: true,
|
2019-07-11 14:40:55 +00:00
|
|
|
isArticleVisible: true,
|
2019-07-11 11:43:07 +00:00
|
|
|
isArticlePinned: false
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-08-31 07:03:19 +00:00
|
|
|
onResize = (width, height) => {
|
|
|
|
//console.log(`onResize height: ${height}, width: ${width}`);
|
2020-09-17 12:52:07 +00:00
|
|
|
};
|
2020-08-31 07:03:19 +00:00
|
|
|
|
2019-07-11 11:43:07 +00:00
|
|
|
render() {
|
2020-08-11 12:34:00 +00:00
|
|
|
const {
|
|
|
|
onDrop,
|
|
|
|
progressBarDropDownContent,
|
|
|
|
progressBarLabel,
|
|
|
|
progressBarValue,
|
|
|
|
setSelections,
|
|
|
|
showProgressBar,
|
|
|
|
uploadFiles,
|
|
|
|
viewAs,
|
|
|
|
withBodyAutoFocus,
|
|
|
|
withBodyScroll,
|
|
|
|
children
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
let articleHeaderContent = null;
|
|
|
|
let articleMainButtonContent = null;
|
|
|
|
let articleBodyContent = null;
|
|
|
|
let sectionHeaderContent = null;
|
|
|
|
let sectionFilterContent = null;
|
|
|
|
let sectionPagingContent = null;
|
|
|
|
let sectionBodyContent = null;
|
|
|
|
|
|
|
|
React.Children.forEach(children, child => {
|
|
|
|
const childType =
|
|
|
|
child && child.type && (child.type.displayName || child.type.name);
|
|
|
|
|
|
|
|
switch (childType) {
|
|
|
|
case ArticleHeader.displayName:
|
|
|
|
articleHeaderContent = child;
|
|
|
|
break;
|
|
|
|
case ArticleMainButton.displayName:
|
|
|
|
articleMainButtonContent = child;
|
|
|
|
break;
|
|
|
|
case ArticleBody.displayName:
|
|
|
|
articleBodyContent = child;
|
|
|
|
break;
|
|
|
|
case SectionHeader.displayName:
|
|
|
|
sectionHeaderContent = child;
|
|
|
|
break;
|
|
|
|
case SectionFilter.displayName:
|
|
|
|
sectionFilterContent = child;
|
|
|
|
break;
|
|
|
|
case SectionPaging.displayName:
|
|
|
|
sectionPagingContent = child;
|
|
|
|
break;
|
|
|
|
case SectionBody.displayName:
|
|
|
|
sectionBodyContent = child;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const isArticleHeaderAvailable = !!articleHeaderContent,
|
|
|
|
isArticleMainButtonAvailable = !!articleMainButtonContent,
|
|
|
|
isArticleBodyAvailable = !!articleBodyContent,
|
|
|
|
isArticleAvailable =
|
|
|
|
isArticleHeaderAvailable ||
|
|
|
|
isArticleMainButtonAvailable ||
|
|
|
|
isArticleBodyAvailable,
|
|
|
|
isSectionHeaderAvailable = !!sectionHeaderContent,
|
|
|
|
isSectionFilterAvailable = !!sectionFilterContent,
|
|
|
|
isSectionPagingAvailable = !!sectionPagingContent,
|
|
|
|
isSectionBodyAvailable =
|
|
|
|
!!sectionBodyContent ||
|
|
|
|
isSectionFilterAvailable ||
|
|
|
|
isSectionPagingAvailable,
|
|
|
|
isSectionAvailable =
|
|
|
|
isSectionHeaderAvailable ||
|
|
|
|
isSectionFilterAvailable ||
|
|
|
|
isSectionBodyAvailable ||
|
|
|
|
isSectionPagingAvailable ||
|
|
|
|
isArticleAvailable,
|
|
|
|
isBackdropAvailable = isArticleAvailable;
|
|
|
|
|
2019-07-11 11:43:07 +00:00
|
|
|
return (
|
|
|
|
<>
|
2020-08-11 12:34:00 +00:00
|
|
|
{isBackdropAvailable && (
|
2019-09-12 12:15:22 +00:00
|
|
|
<Backdrop
|
|
|
|
zIndex={400}
|
|
|
|
visible={this.state.isBackdropVisible}
|
|
|
|
onClick={this.backdropClick}
|
|
|
|
/>
|
|
|
|
)}
|
2020-08-11 12:34:00 +00:00
|
|
|
{isArticleAvailable && (
|
2019-09-12 12:15:22 +00:00
|
|
|
<Article
|
|
|
|
visible={this.state.isArticleVisible}
|
|
|
|
pinned={this.state.isArticlePinned}
|
|
|
|
>
|
2020-08-11 12:34:00 +00:00
|
|
|
{isArticleHeaderAvailable && (
|
|
|
|
<SubArticleHeader>
|
|
|
|
{articleHeaderContent
|
|
|
|
? articleHeaderContent.props.children
|
|
|
|
: null}
|
|
|
|
</SubArticleHeader>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2020-08-11 12:34:00 +00:00
|
|
|
{isArticleMainButtonAvailable && (
|
|
|
|
<SubArticleMainButton>
|
|
|
|
{articleMainButtonContent
|
|
|
|
? articleMainButtonContent.props.children
|
|
|
|
: null}
|
|
|
|
</SubArticleMainButton>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2020-08-11 12:34:00 +00:00
|
|
|
{isArticleBodyAvailable && (
|
|
|
|
<SubArticleBody>
|
|
|
|
{articleBodyContent ? articleBodyContent.props.children : null}
|
|
|
|
</SubArticleBody>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2020-08-11 12:34:00 +00:00
|
|
|
{isArticleBodyAvailable && (
|
2019-09-12 12:15:22 +00:00
|
|
|
<ArticlePinPanel
|
|
|
|
pinned={this.state.isArticlePinned}
|
2020-08-11 12:34:00 +00:00
|
|
|
pinText={this.props.t("Pin")}
|
2019-09-12 12:15:22 +00:00
|
|
|
onPin={this.pinArticle}
|
2020-08-11 12:34:00 +00:00
|
|
|
unpinText={this.props.t("Unpin")}
|
2019-09-12 12:15:22 +00:00
|
|
|
onUnpin={this.unpinArticle}
|
|
|
|
/>
|
|
|
|
)}
|
2019-07-20 09:48:29 +00:00
|
|
|
</Article>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2020-08-11 12:34:00 +00:00
|
|
|
{isSectionAvailable && (
|
2020-09-17 12:52:07 +00:00
|
|
|
<ReactResizeDetector
|
2020-09-01 13:07:07 +00:00
|
|
|
onResize={this.onResize}
|
|
|
|
refreshRate={200}
|
2020-09-17 12:52:07 +00:00
|
|
|
refreshMode="debounce"
|
2020-09-01 13:07:07 +00:00
|
|
|
>
|
2020-08-31 07:03:19 +00:00
|
|
|
{({ width }) => (
|
|
|
|
<Section widthProp={width}>
|
|
|
|
{isSectionHeaderAvailable && (
|
|
|
|
<SubSectionHeader
|
|
|
|
isArticlePinned={this.state.isArticlePinned}
|
|
|
|
>
|
|
|
|
{sectionHeaderContent
|
|
|
|
? sectionHeaderContent.props.children
|
2020-08-11 12:34:00 +00:00
|
|
|
: null}
|
2020-08-31 07:03:19 +00:00
|
|
|
</SubSectionHeader>
|
|
|
|
)}
|
|
|
|
{isSectionFilterAvailable && (
|
|
|
|
<SubSectionFilter className="section-header_filter">
|
|
|
|
{sectionFilterContent
|
|
|
|
? sectionFilterContent.props.children
|
|
|
|
: null}
|
|
|
|
</SubSectionFilter>
|
|
|
|
)}
|
|
|
|
{isSectionBodyAvailable && (
|
|
|
|
<>
|
|
|
|
<SubSectionBody
|
|
|
|
onDrop={onDrop}
|
|
|
|
uploadFiles={uploadFiles}
|
|
|
|
setSelections={setSelections}
|
|
|
|
withScroll={withBodyScroll}
|
|
|
|
autoFocus={withBodyAutoFocus}
|
|
|
|
pinned={this.state.isArticlePinned}
|
|
|
|
viewAs={viewAs}
|
|
|
|
>
|
|
|
|
{isSectionFilterAvailable && (
|
|
|
|
<SubSectionFilter className="section-body_filter">
|
|
|
|
{sectionFilterContent
|
|
|
|
? sectionFilterContent.props.children
|
|
|
|
: null}
|
|
|
|
</SubSectionFilter>
|
|
|
|
)}
|
|
|
|
<SubSectionBodyContent>
|
|
|
|
{sectionBodyContent
|
|
|
|
? React.cloneElement(
|
|
|
|
sectionBodyContent.props.children,
|
|
|
|
{ widthProp: width }
|
|
|
|
)
|
2020-08-31 14:35:39 +00:00
|
|
|
: null}
|
2020-08-31 07:03:19 +00:00
|
|
|
</SubSectionBodyContent>
|
|
|
|
{isSectionPagingAvailable && (
|
|
|
|
<SubSectionPaging>
|
|
|
|
{sectionPagingContent
|
|
|
|
? sectionPagingContent.props.children
|
|
|
|
: null}
|
|
|
|
</SubSectionPaging>
|
|
|
|
)}
|
|
|
|
</SubSectionBody>
|
|
|
|
{showProgressBar && (
|
|
|
|
<ProgressBar
|
|
|
|
className="layout-progress-bar"
|
|
|
|
label={progressBarLabel}
|
|
|
|
percent={progressBarValue}
|
|
|
|
dropDownContent={progressBarDropDownContent}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</>
|
2019-11-14 12:13:54 +00:00
|
|
|
)}
|
|
|
|
|
2020-08-31 07:03:19 +00:00
|
|
|
{isArticleAvailable && (
|
|
|
|
<SectionToggler
|
|
|
|
visible={!this.state.isArticleVisible}
|
|
|
|
onClick={this.showArticle}
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</Section>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2020-08-31 07:03:19 +00:00
|
|
|
</ReactResizeDetector>
|
2019-09-12 12:15:22 +00:00
|
|
|
)}
|
2019-07-11 11:43:07 +00:00
|
|
|
</>
|
2019-09-12 12:15:22 +00:00
|
|
|
);
|
2019-07-11 11:43:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-20 08:34:49 +00:00
|
|
|
PageLayoutComponent.propTypes = {
|
2020-08-11 12:34:00 +00:00
|
|
|
children: PropTypes.any,
|
2019-12-20 08:34:49 +00:00
|
|
|
withBodyScroll: PropTypes.bool,
|
2020-01-24 08:23:12 +00:00
|
|
|
withBodyAutoFocus: PropTypes.bool,
|
2019-12-20 08:34:49 +00:00
|
|
|
t: PropTypes.func,
|
2020-03-11 14:18:47 +00:00
|
|
|
|
|
|
|
showProgressBar: PropTypes.bool,
|
|
|
|
progressBarValue: PropTypes.number,
|
|
|
|
progressBarDropDownContent: PropTypes.any,
|
2020-05-29 06:25:28 +00:00
|
|
|
progressBarLabel: PropTypes.string,
|
|
|
|
onDrop: PropTypes.func,
|
2020-06-09 07:02:13 +00:00
|
|
|
setSelections: PropTypes.func,
|
2020-08-11 12:34:00 +00:00
|
|
|
uploadFiles: PropTypes.bool
|
2019-09-12 12:15:22 +00:00
|
|
|
};
|
2019-07-11 11:43:07 +00:00
|
|
|
|
2019-12-20 08:34:49 +00:00
|
|
|
PageLayoutComponent.defaultProps = {
|
2020-01-24 08:23:12 +00:00
|
|
|
withBodyScroll: true,
|
|
|
|
withBodyAutoFocus: false
|
2019-09-12 12:15:22 +00:00
|
|
|
};
|
2019-07-11 11:43:07 +00:00
|
|
|
|
2020-08-11 12:34:00 +00:00
|
|
|
const PageLayoutTranslated = withTranslation()(PageLayoutComponent);
|
|
|
|
|
|
|
|
const PageLayout = props => {
|
2020-08-25 13:28:14 +00:00
|
|
|
useEffect(() => {
|
|
|
|
changeLanguage(i18n);
|
|
|
|
}, []);
|
2020-08-11 12:34:00 +00:00
|
|
|
|
2020-08-25 13:28:14 +00:00
|
|
|
return <PageLayoutTranslated i18n={i18n} {...props} />;
|
|
|
|
};
|
2020-08-11 12:34:00 +00:00
|
|
|
|
|
|
|
PageLayout.ArticleHeader = ArticleHeader;
|
|
|
|
PageLayout.ArticleMainButton = ArticleMainButton;
|
|
|
|
PageLayout.ArticleBody = ArticleBody;
|
|
|
|
PageLayout.SectionHeader = SectionHeader;
|
|
|
|
PageLayout.SectionFilter = SectionFilter;
|
|
|
|
PageLayout.SectionBody = SectionBody;
|
|
|
|
PageLayout.SectionPaging = SectionPaging;
|
|
|
|
|
|
|
|
PageLayout.propTypes = {
|
|
|
|
language: PropTypes.string,
|
|
|
|
children: PropTypes.any
|
2020-08-25 13:28:14 +00:00
|
|
|
};
|
2019-12-20 08:34:49 +00:00
|
|
|
|
2020-01-28 06:23:58 +00:00
|
|
|
export default PageLayout;
|