DocSpace-client/packages/asc-web-common/components/Section/index.js

595 lines
18 KiB
JavaScript
Raw Normal View History

2022-03-03 11:25:10 +00:00
import React from "react";
import PropTypes from "prop-types";
import {
desktop,
size,
tablet,
mobile,
isMobile as isMobileUtils,
isTablet as isTabletUtils,
} from "@appserver/components/utils/device";
2022-03-03 11:25:10 +00:00
import { Provider } from "@appserver/components/utils/context";
import { isMobile, isFirefox, isMobileOnly } from "react-device-detect";
import SectionContainer from "./sub-components/section-container";
2022-03-03 11:25:10 +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 SubSectionBar from "./sub-components/section-bar";
import SubSectionPaging from "./sub-components/section-paging";
2022-03-21 08:13:56 +00:00
//import SectionToggler from "./sub-components/section-toggler";
2022-03-03 11:25:10 +00:00
import InfoPanel from "./sub-components/info-panel";
import SubInfoPanelBody from "./sub-components/info-panel-body";
import SubInfoPanelHeader from "./sub-components/info-panel-header";
2022-03-03 11:25:10 +00:00
import ReactResizeDetector from "react-resize-detector";
import FloatingButton from "../FloatingButton";
import { inject, observer } from "mobx-react";
import Selecto from "react-selecto";
import styled, { css } from "styled-components";
2021-04-13 09:43:17 +00:00
const StyledSelectoWrapper = styled.div`
2022-03-03 10:43:43 +00:00
.selecto-selection {
z-index: 200;
}
2021-04-13 09:43:17 +00:00
`;
2021-11-22 12:01:33 +00:00
const StyledMainBar = styled.div`
2022-03-03 10:43:43 +00:00
box-sizing: border-box;
margin-left: -20px;
/* width: calc(100vw - 256px);
max-width: calc(100vw - 256px); */
width: ${(props) =>
props.infoPanelIsVisible ? "calc(100vw - 657px)" : "calc(100vw - 256px)"};
max-width: ${(props) =>
props.infoPanelIsVisible ? "calc(100vw - 657px)" : "calc(100vw - 256px)"};
2022-03-03 10:43:43 +00:00
#bar-banner {
margin-bottom: -3px;
}
#bar-frame {
min-width: 100%;
max-width: 100%;
}
@media ${tablet} {
width: ${(props) =>
props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"};
max-width: ${(props) =>
props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"};
margin-left: -16px;
}
${isMobile &&
css`
width: ${(props) =>
props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"} !important;
max-width: ${(props) =>
props.showText ? "calc(100vw - 240px)" : "calc(100vw - 52px)"} !important;
margin-left: -16px;
`}
@media ${mobile} {
width: 100vw !important;
max-width: 100vw !important;
}
${isMobileOnly &&
css`
width: 100vw !important;
max-width: 100vw !important;
#bar-frame {
min-width: 100vw;
}
`}
${(props) =>
!props.isSectionHeaderAvailable &&
css`
width: 100vw !important;
max-width: 100vw !important;
${isMobile &&
css`
position: fixed;
top: 48px;
left: 0;
margin-left: 0 !important;
box-sizing: border-box;
2022-03-03 10:43:43 +00:00
`}
`}
2021-11-22 12:01:33 +00:00
`;
function SectionHeader() {
2022-03-03 10:43:43 +00:00
return null;
}
SectionHeader.displayName = "SectionHeader";
function SectionBar() {
return null;
}
SectionBar.displayName = "SectionBar";
function SectionFilter() {
2022-03-03 10:43:43 +00:00
return null;
}
SectionFilter.displayName = "SectionFilter";
function SectionBody() {
2022-03-03 10:43:43 +00:00
return null;
}
SectionBody.displayName = "SectionBody";
function SectionPaging() {
2022-03-03 10:43:43 +00:00
return null;
}
SectionPaging.displayName = "SectionPaging";
2022-02-11 14:35:18 +00:00
function InfoPanelBody() {
2022-03-03 10:43:43 +00:00
return null;
2022-02-08 12:11:31 +00:00
}
2022-02-11 14:35:18 +00:00
InfoPanelBody.displayName = "InfoPanelBody";
2022-02-09 09:13:16 +00:00
2022-02-11 14:35:18 +00:00
function InfoPanelHeader() {
2022-03-03 10:43:43 +00:00
return null;
2022-02-09 09:13:16 +00:00
}
2022-02-11 14:35:18 +00:00
InfoPanelHeader.displayName = "InfoPanelHeader";
2022-02-08 12:11:31 +00:00
class Section extends React.Component {
2022-03-03 10:43:43 +00:00
static SectionHeader = SectionHeader;
static SectionFilter = SectionFilter;
static SectionBody = SectionBody;
static SectionBar = SectionBar;
2022-03-03 10:43:43 +00:00
static SectionPaging = SectionPaging;
static InfoPanelBody = InfoPanelBody;
static InfoPanelHeader = InfoPanelHeader;
constructor(props) {
super(props);
this.timeoutHandler = null;
this.intervalHandler = null;
this.scroll = null;
}
componentDidUpdate(prevProps) {
if (!this.scroll) {
this.scroll = document.getElementsByClassName("section-scroll")[0];
}
2022-03-03 10:43:43 +00:00
}
componentDidMount() {}
2022-03-03 10:43:43 +00:00
componentWillUnmount() {
if (this.intervalHandler) clearInterval(this.intervalHandler);
if (this.timeoutHandler) clearTimeout(this.timeoutHandler);
}
onSelect = (e) => {
if (this.props.dragging) return;
const items = e.selected;
this.props.setSelections(items);
};
dragCondition = (e) => {
const path = e.inputEvent.composedPath();
const isBackdrop = path.some(
(x) => x.classList && x.classList.contains("backdrop-active")
);
const notSelectablePath = path.some(
(x) => x.classList && x.classList.contains("not-selectable")
);
const isDraggable = path.some(
(x) => x.classList && x.classList.contains("draggable")
);
if (notSelectablePath || isBackdrop || isDraggable) {
return false;
} else return true;
};
onScroll = (e) => {
this.scroll.scrollBy(e.direction[0] * 10, e.direction[1] * 10);
};
render() {
const {
onDrop,
showPrimaryProgressBar,
primaryProgressBarIcon,
primaryProgressBarValue,
showPrimaryButtonAlert,
showSecondaryProgressBar,
secondaryProgressBarValue,
secondaryProgressBarIcon,
showSecondaryButtonAlert,
uploadFiles,
viewAs,
//withBodyAutoFocus,
withBodyScroll,
children,
isHeaderVisible,
//headerBorderBottom,
onOpenUploadPanel,
isTabletView,
firstLoad,
dragging,
isDesktop,
isHomepage,
maintenanceExist,
setMaintenanceExist,
snackbarExist,
showText,
infoPanelIsVisible,
isInfoPanelAvailable,
2022-03-03 10:43:43 +00:00
} = this.props;
2022-03-03 10:43:43 +00:00
let sectionHeaderContent = null;
let sectionBarContent = null;
2022-03-03 10:43:43 +00:00
let sectionFilterContent = null;
let sectionPagingContent = null;
let sectionBodyContent = null;
let infoPanelBodyContent = null;
let infoPanelHeaderContent = null;
React.Children.forEach(children, (child) => {
const childType =
child && child.type && (child.type.displayName || child.type.name);
switch (childType) {
case SectionHeader.displayName:
sectionHeaderContent = child;
break;
case SectionFilter.displayName:
sectionFilterContent = child;
break;
case SectionBar.displayName:
sectionBarContent = child;
break;
2022-03-03 10:43:43 +00:00
case SectionPaging.displayName:
sectionPagingContent = child;
break;
case SectionBody.displayName:
sectionBodyContent = child;
break;
case InfoPanelBody.displayName:
infoPanelBodyContent = child;
break;
case InfoPanelHeader.displayName:
infoPanelHeaderContent = child;
break;
default:
break;
}
});
const isSectionHeaderAvailable = !!sectionHeaderContent,
2022-03-03 10:43:43 +00:00
isSectionFilterAvailable = !!sectionFilterContent,
isSectionPagingAvailable = !!sectionPagingContent,
isSectionBodyAvailable =
!!sectionBodyContent ||
isSectionFilterAvailable ||
isSectionPagingAvailable,
isSectionBarAvailable = !!sectionBarContent,
2022-03-03 10:43:43 +00:00
isSectionAvailable =
isSectionHeaderAvailable ||
isSectionFilterAvailable ||
isSectionBodyAvailable ||
isSectionPagingAvailable;
const renderSection = () => {
2022-03-03 10:43:43 +00:00
return (
<>
{isSectionAvailable && (
<ReactResizeDetector
refreshRate={100}
refreshMode="debounce"
refreshOptions={{ trailing: true }}
>
{({ width, height }) => (
<Provider
value={{
sectionWidth: width,
sectionHeight: height,
}}
>
<SectionContainer
widthProp={width}
showText={showText}
viewAs={viewAs}
maintenanceExist={maintenanceExist}
isSectionBarAvailable={isSectionBarAvailable}
isSectionHeaderAvailable={isSectionHeaderAvailable}
infoPanelIsVisible={infoPanelIsVisible}
>
{!isMobile && (
<StyledMainBar
width={width}
id="main-bar"
className={"main-bar"}
showText={showText}
isSectionHeaderAvailable={isSectionHeaderAvailable}
infoPanelIsVisible={infoPanelIsVisible}
>
<SubSectionBar
setMaintenanceExist={setMaintenanceExist}
>
{sectionBarContent
? sectionBarContent.props.children
: null}
</SubSectionBar>
</StyledMainBar>
)}
{isSectionHeaderAvailable && !isMobile && (
2022-03-03 10:43:43 +00:00
<SubSectionHeader
maintenanceExist={maintenanceExist}
snackbarExist={snackbarExist}
className="section-header_header"
2022-03-03 10:43:43 +00:00
isHeaderVisible={isHeaderVisible}
infoPanelIsVisible={infoPanelIsVisible}
2022-03-03 10:43:43 +00:00
viewAs={viewAs}
showText={showText}
2022-03-03 10:43:43 +00:00
>
{sectionHeaderContent
? sectionHeaderContent.props.children
: null}
</SubSectionHeader>
2021-04-13 06:35:07 +00:00
)}
{isSectionFilterAvailable && !isMobile && (
2022-03-03 10:43:43 +00:00
<>
<SubSectionFilter
className="section-header_filter"
viewAs={viewAs}
2022-02-08 12:11:31 +00:00
>
2022-03-03 10:43:43 +00:00
{sectionFilterContent
? sectionFilterContent.props.children
: null}
</SubSectionFilter>
</>
2021-04-13 06:35:07 +00:00
)}
2022-03-03 10:43:43 +00:00
{isSectionBodyAvailable && (
<>
<SubSectionBody
onDrop={onDrop}
uploadFiles={uploadFiles}
withScroll={withBodyScroll}
autoFocus={isMobile || isTabletView ? false : true}
viewAs={viewAs}
isHomepage={isHomepage}
2022-02-08 12:11:31 +00:00
>
{isMobile && (
<StyledMainBar
width={width}
id="main-bar"
className={"main-bar"}
showText={showText}
isSectionHeaderAvailable={
isSectionHeaderAvailable
}
infoPanelIsVisible={infoPanelIsVisible}
>
<SubSectionBar
setMaintenanceExist={setMaintenanceExist}
>
{sectionBarContent
? sectionBarContent.props.children
: null}
</SubSectionBar>
</StyledMainBar>
)}
{isSectionHeaderAvailable && isMobile && (
<SubSectionHeader
className="section-body_header"
isHeaderVisible={isHeaderVisible}
viewAs={viewAs}
showText={showText}
infoPanelIsVisible={infoPanelIsVisible}
>
{sectionHeaderContent
? sectionHeaderContent.props.children
: null}
</SubSectionHeader>
)}
{isSectionFilterAvailable && isMobile && (
2022-03-03 10:43:43 +00:00
<SubSectionFilter className="section-body_filter">
{sectionFilterContent
? sectionFilterContent.props.children
: null}
</SubSectionFilter>
)}
2022-03-21 08:13:56 +00:00
2022-03-03 10:43:43 +00:00
<SubSectionBodyContent>
{sectionBodyContent
? sectionBodyContent.props.children
: null}
</SubSectionBodyContent>
2022-03-21 08:13:56 +00:00
2022-03-03 10:43:43 +00:00
{isSectionPagingAvailable && (
<SubSectionPaging>
{sectionPagingContent
? sectionPagingContent.props.children
: null}
</SubSectionPaging>
)}
</SubSectionBody>
</>
2022-02-08 12:11:31 +00:00
)}
2022-03-21 08:13:56 +00:00
{!(isMobile || isMobileUtils() || isTabletUtils()) ? (
showPrimaryProgressBar && showSecondaryProgressBar ? (
<>
<FloatingButton
className="layout-progress-bar"
icon={primaryProgressBarIcon}
percent={primaryProgressBarValue}
alert={showPrimaryButtonAlert}
onClick={onOpenUploadPanel}
/>
<FloatingButton
className="layout-progress-second-bar"
icon={secondaryProgressBarIcon}
percent={secondaryProgressBarValue}
alert={showSecondaryButtonAlert}
/>
</>
) : showPrimaryProgressBar &&
!showSecondaryProgressBar ? (
2022-03-03 10:43:43 +00:00
<FloatingButton
className="layout-progress-bar"
icon={primaryProgressBarIcon}
percent={primaryProgressBarValue}
alert={showPrimaryButtonAlert}
onClick={onOpenUploadPanel}
2022-02-08 12:11:31 +00:00
/>
) : !showPrimaryProgressBar &&
showSecondaryProgressBar ? (
2022-03-03 10:43:43 +00:00
<FloatingButton
className="layout-progress-bar"
2022-03-03 10:43:43 +00:00
icon={secondaryProgressBarIcon}
percent={secondaryProgressBarValue}
alert={showSecondaryButtonAlert}
/>
) : (
<></>
)
2022-03-03 10:43:43 +00:00
) : (
<></>
)}
</SectionContainer>
{isInfoPanelAvailable && (
<InfoPanel>
<SubInfoPanelHeader>
{infoPanelHeaderContent}
</SubInfoPanelHeader>
<SubInfoPanelBody>
{infoPanelBodyContent}
</SubInfoPanelBody>
</InfoPanel>
)}
2022-03-03 10:43:43 +00:00
</Provider>
)}
</ReactResizeDetector>
)}
</>
);
};
const scrollOptions = this.scroll
? {
container: this.scroll,
throttleTime: 0,
threshold: 100,
}
: {};
return (
<>
{renderSection()}
2022-03-03 10:43:43 +00:00
{!isMobile && uploadFiles && !dragging && (
<StyledSelectoWrapper>
<Selecto
boundContainer={".section-wrapper"}
dragContainer={".section-body"}
selectableTargets={[".files-item"]}
hitRate={0}
selectByClick={false}
selectFromInside={true}
ratio={0}
continueSelect={false}
onSelect={this.onSelect}
dragCondition={this.dragCondition}
scrollOptions={scrollOptions}
onScroll={this.onScroll}
/>
</StyledSelectoWrapper>
)}
</>
);
}
}
Section.propTypes = {
2022-03-03 10:43:43 +00:00
children: PropTypes.any,
withBodyScroll: PropTypes.bool,
withBodyAutoFocus: PropTypes.bool,
showPrimaryProgressBar: PropTypes.bool,
primaryProgressBarValue: PropTypes.number,
showPrimaryButtonAlert: PropTypes.bool,
progressBarDropDownContent: PropTypes.any,
primaryProgressBarIcon: PropTypes.string,
showSecondaryProgressBar: PropTypes.bool,
secondaryProgressBarValue: PropTypes.number,
secondaryProgressBarIcon: PropTypes.string,
showSecondaryButtonAlert: PropTypes.bool,
onDrop: PropTypes.func,
setSelections: PropTypes.func,
uploadFiles: PropTypes.bool,
hideAside: PropTypes.bool,
viewAs: PropTypes.string,
uploadPanelVisible: PropTypes.bool,
onOpenUploadPanel: PropTypes.func,
isTabletView: PropTypes.bool,
isHeaderVisible: PropTypes.bool,
firstLoad: PropTypes.bool,
isHomepage: PropTypes.bool,
isInfoPanelAvailable: PropTypes.bool,
};
Section.defaultProps = {
2022-03-03 10:43:43 +00:00
withBodyScroll: true,
withBodyAutoFocus: false,
isInfoPanelAvailable: true,
};
2022-03-21 08:13:56 +00:00
Section.InfoPanelHeader = InfoPanelHeader;
Section.InfoPanelBody = InfoPanelBody;
Section.SectionHeader = SectionHeader;
Section.SectionFilter = SectionFilter;
Section.SectionBody = SectionBody;
Section.SectionPaging = SectionPaging;
export default inject(({ auth, infoPanelStore }) => {
2022-03-03 10:43:43 +00:00
const { isLoaded, settingsStore } = auth;
const {
isHeaderVisible,
isTabletView,
2022-03-03 10:43:43 +00:00
isDesktopClient,
maintenanceExist,
snackbarExist,
setMaintenanceExist,
showText,
2022-03-03 10:43:43 +00:00
} = settingsStore;
let infoPanelIsVisible = false;
if (infoPanelStore) infoPanelIsVisible = infoPanelStore.isVisible;
2022-03-03 10:43:43 +00:00
return {
isLoaded,
isTabletView,
isHeaderVisible,
maintenanceExist,
snackbarExist,
setMaintenanceExist,
2022-03-03 10:43:43 +00:00
isDesktop: isDesktopClient,
showText,
infoPanelIsVisible: infoPanelIsVisible,
2022-03-03 10:43:43 +00:00
};
})(observer(Section));