diff --git a/products/ASC.People/Client/package.json b/products/ASC.People/Client/package.json
index a9c3f0beb9..3db9a987e4 100644
--- a/products/ASC.People/Client/package.json
+++ b/products/ASC.People/Client/package.json
@@ -26,6 +26,8 @@
"react-router": "5.0.1",
"react-router-dom": "5.0.1",
"react-scripts": "3.0.1",
+ "react-virtualized-auto-sizer": "^1.0.2",
+ "react-window": "^1.8.5",
"reactstrap": "8.0.0",
"redux": "4.0.1",
"redux-form": "^8.2.4",
diff --git a/products/ASC.People/Client/src/components/pages/Home/Section/Body/index.js b/products/ASC.People/Client/src/components/pages/Home/Section/Body/index.js
index 18c4140b7f..4f3c0a9b7a 100644
--- a/products/ASC.People/Client/src/components/pages/Home/Section/Body/index.js
+++ b/products/ASC.People/Client/src/components/pages/Home/Section/Body/index.js
@@ -1,76 +1,151 @@
-import React from "react";
+import React, { memo, useCallback } from "react";
import { withRouter } from "react-router";
import { connect } from "react-redux";
-import { ContentRow, toastr } from "asc-web-components";
+import { ContentRow, toastr, Scrollbar } from "asc-web-components";
import UserContent from "./userContent";
//import config from "../../../../../../package.json";
-import { selectUser, deselectUser, setSelection } from "../../../../../store/people/actions";
-import { isUserSelected, getUserStatus, getUserRole, isUserDisabled } from '../../../../../store/people/selectors';
-import { isAdmin } from '../../../../../store/auth/selectors';
+import {
+ selectUser,
+ deselectUser,
+ setSelection
+} from "../../../../../store/people/actions";
+import {
+ isUserSelected,
+ getUserStatus,
+ getUserRole,
+ isUserDisabled
+} from "../../../../../store/people/selectors";
+import { isAdmin } from "../../../../../store/auth/selectors";
+import { FixedSizeList as List, areEqual } from "react-window";
+import AutoSizer from "react-virtualized-auto-sizer";
+
+
+const CustomScrollbars = ({ onScroll, forwardedRef, style, children }) => {
+ const refSetter = useCallback(scrollbarsRef => {
+ if (scrollbarsRef) {
+ forwardedRef(scrollbarsRef.view);
+ } else {
+ forwardedRef(null);
+ }
+ }, [forwardedRef]);
+
+ return (
+
+ {children}
+
+ );
+};
+
+const CustomScrollbarsVirtualList = React.forwardRef((props, ref) => (
+
+));
+
+const Row = memo(
+ ({
+ data,
+ index,
+ style,
+ onContentRowSelect,
+ history,
+ settings,
+ selection,
+ getUserContextOptions
+ }) => {
+ // Data passed to List as "itemData" is available as props.data
+ const user = data[index];
+
+ // console.log("Row user", user);
+ const contextOptions = getUserContextOptions(user);
+
+ return (
+
+
+
+ );
+ },
+ areEqual
+);
class SectionBodyContent extends React.PureComponent {
-
onEmailSentClick = () => {
toastr.success("Context action: Send e-mail");
- }
+ };
onSendMessageClick = () => {
toastr.success("Context action: Send message");
- }
+ };
- onEditClick = (user) => {
+ onEditClick = user => {
const { history, settings } = this.props;
history.push(`${settings.homepage}/edit/${user.userName}`);
- }
+ };
onChangePasswordClick = () => {
toastr.success("Context action: Change password");
- }
+ };
onChangeEmailClick = () => {
toastr.success("Context action: Change e-mail");
- }
+ };
onDisableClick = () => {
toastr.success("Context action: Disable");
- }
+ };
- getUserContextOptions = (user) => {
-
- const options = [{
- key: "key1",
- label: "Send e-mail",
- onClick: this.onEmailSentClick
+ getUserContextOptions = user => {
+ const options = [
+ {
+ key: "key1",
+ label: "Send e-mail",
+ onClick: this.onEmailSentClick
},
{
- key: "key2",
- label: "Send message",
- onClick: this.onSendMessageClick
+ key: "key2",
+ label: "Send message",
+ onClick: this.onSendMessageClick
},
{ key: "key3", isSeparator: true },
{
- key: "key4",
- label: "Edit",
- onClick: this.onEditClick.bind(this, user)
+ key: "key4",
+ label: "Edit",
+ onClick: this.onEditClick.bind(this, user)
},
{
- key: "key5",
- label: "Change password",
- onClick: this.onChangePasswordClick
+ key: "key5",
+ label: "Change password",
+ onClick: this.onChangePasswordClick
},
{
- key: "key6",
- label: "Change e-mail",
- onClick: this.onChangeEmailClick
- }];
+ key: "key6",
+ label: "Change e-mail",
+ onClick: this.onChangeEmailClick
+ }
+ ];
- return [...options,
- !isUserDisabled(user)
+ return [
+ ...options,
+ !isUserDisabled(user)
? {
key: "key7",
label: "Disable",
onClick: this.onDisableClick
- }
+ }
: {}
];
};
@@ -79,58 +154,46 @@ class SectionBodyContent extends React.PureComponent {
console.log("ContentRow onSelect", checked, user);
if (checked) {
this.props.selectUser(user);
- }
- else {
+ } else {
this.props.deselectUser(user);
}
- }
+ };
render() {
console.log("Home SectionBodyContent render()");
- const { users, isAdmin, selection, history, settings} = this.props;
+ const { users, isAdmin, selection, history, settings } = this.props;
return (
- <>
- {users.map(user => {
- const contextOptions = this.getUserContextOptions(user);
- return isAdmin ? (
-
-
+ {({ height, width }) => (
+
+ {({ data, index, style }) => (
+
-
- ) : (
-
-
-
- );
- })}
- >
+ )}
+
+ )}
+
);
}
-};
+}
const mapStateToProps = state => {
return {
diff --git a/products/ASC.People/Client/src/components/pages/Home/index.js b/products/ASC.People/Client/src/components/pages/Home/index.js
index 8cf452bf91..6f0895e1db 100644
--- a/products/ASC.People/Client/src/components/pages/Home/index.js
+++ b/products/ASC.People/Client/src/components/pages/Home/index.js
@@ -110,6 +110,7 @@ class Home extends React.Component {
fontColor={"#999"}
/>
}
articleMainButtonContent={}
articleBodyContent={}
diff --git a/products/ASC.People/Client/yarn.lock b/products/ASC.People/Client/yarn.lock
index 52917118d9..afc25a66d6 100644
--- a/products/ASC.People/Client/yarn.lock
+++ b/products/ASC.People/Client/yarn.lock
@@ -6653,7 +6653,7 @@ mem@^4.0.0:
mimic-fn "^2.0.0"
p-is-promise "^2.0.0"
-memoize-one@^5.0.0:
+"memoize-one@>=3.1.1 <6", memoize-one@^5.0.0:
version "5.0.5"
resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e"
integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ==
@@ -8942,6 +8942,19 @@ react-transition-group@^2.3.1, react-transition-group@^2.6.1:
prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4"
+react-virtualized-auto-sizer@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.2.tgz#a61dd4f756458bbf63bd895a92379f9b70f803bd"
+ integrity sha512-MYXhTY1BZpdJFjUovvYHVBmkq79szK/k7V3MO+36gJkWGkrXKtyr4vCPtpphaTLRAdDNoYEYFZWE8LjN+PIHNg==
+
+react-window@^1.8.5:
+ version "1.8.5"
+ resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.5.tgz#a56b39307e79979721021f5d06a67742ecca52d1"
+ integrity sha512-HeTwlNa37AFa8MDZFZOKcNEkuF2YflA0hpGPiTT9vR7OawEt+GZbfM6wqkBahD3D3pUjIabQYzsnY/BSJbgq6Q==
+ dependencies:
+ "@babel/runtime" "^7.0.0"
+ memoize-one ">=3.1.1 <6"
+
react@^16.8.6:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe"
diff --git a/web/ASC.Web.Components/src/components/page-layout/index.js b/web/ASC.Web.Components/src/components/page-layout/index.js
index 48b433ffa6..44ae96afb2 100644
--- a/web/ASC.Web.Components/src/components/page-layout/index.js
+++ b/web/ASC.Web.Components/src/components/page-layout/index.js
@@ -149,7 +149,7 @@ class PageLayout extends React.PureComponent {
}
{
this.state.isSectionBodyAvailable &&
- {this.state.sectionBodyContent}
+ {this.state.sectionBodyContent}
}
{
this.state.isSectionPagingAvailable &&
@@ -177,13 +177,16 @@ PageLayout.propTypes = {
sectionHeaderContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
sectionFilterContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
sectionBodyContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
- sectionPagingContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node])
+ sectionPagingContent: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
+
+ withBodyScroll: PropTypes.bool
}
PageLayout.defaultProps = {
isBackdropVisible: false,
isArticleVisible: false,
- isArticlePinned: false
+ isArticlePinned: false,
+ withBodyScroll: true
}
export default PageLayout
\ No newline at end of file
diff --git a/web/ASC.Web.Components/src/components/page-layout/sub-comoponents/section-body.js b/web/ASC.Web.Components/src/components/page-layout/sub-comoponents/section-body.js
index 4ccd05ca57..75703a634d 100644
--- a/web/ASC.Web.Components/src/components/page-layout/sub-comoponents/section-body.js
+++ b/web/ASC.Web.Components/src/components/page-layout/sub-comoponents/section-body.js
@@ -1,6 +1,7 @@
-import React from 'react'
-import styled from 'styled-components'
-import Scrollbar from '../../scrollbar'
+import React from "react";
+import PropTypes from "prop-types";
+import styled from "styled-components";
+import Scrollbar from "../../scrollbar";
const StyledSectionBody = styled.div`
margin: 16px 0;
@@ -8,17 +9,26 @@ const StyledSectionBody = styled.div`
flex-grow: 1;
`;
-const SectionBody = React.memo(props => {
+const SectionBody = React.memo(props => {
console.log("PageLayout SectionBody render");
- const { children } = props;
+ const { children, withScroll } = props;
return (
-
- {children}
-
+ {withScroll
+ ? {children}
+ : <>{children}>
+ }
);
});
-export default SectionBody;
\ No newline at end of file
+SectionBody.propTypes = {
+ withScroll: PropTypes.bool
+};
+
+SectionBody.defaultProps = {
+ withScroll: true
+};
+
+export default SectionBody;
diff --git a/web/ASC.Web.Components/src/components/scrollbar/index.js b/web/ASC.Web.Components/src/components/scrollbar/index.js
index c40ddfd4a6..d1752b0bba 100644
--- a/web/ASC.Web.Components/src/components/scrollbar/index.js
+++ b/web/ASC.Web.Components/src/components/scrollbar/index.js
@@ -2,7 +2,7 @@ import React from 'react'
import { Scrollbars } from 'react-custom-scrollbars';
-const Scrollbar = (props) => {
+const Scrollbar = React.forwardRef((props, ref) => {
//console.log("Scrollbar render");
const scrollbarType = {
smallWhite: {
@@ -37,9 +37,9 @@ const Scrollbar = (props) => {
);
return (
-
+
);
-}
+});
Scrollbar.defaultProps = {
stype: "smallBlack"