diff --git a/web/ASC.Web.Components/src/components/advanced-selector/index.js b/web/ASC.Web.Components/src/components/advanced-selector/index.js index 56432a5ff2..4333c7c2a2 100644 --- a/web/ASC.Web.Components/src/components/advanced-selector/index.js +++ b/web/ASC.Web.Components/src/components/advanced-selector/index.js @@ -12,6 +12,8 @@ import { isArrayEqual } from "../../utils/array"; import findIndex from "lodash/findIndex"; import filter from "lodash/filter"; import DropDown from "../drop-down"; +import { handleAnyClick } from "../../utils/event"; +import isEmpty from 'lodash/isEmpty'; /* eslint-disable no-unused-vars */ /* eslint-disable react/prop-types */ @@ -32,16 +34,27 @@ const Container = ({ groups, selectedGroups, onChangeGroup, + isOpen, + isDropDown, + containerWidth, + containerHeight, ...props }) =>
; /* eslint-enable react/prop-types */ /* eslint-enable no-unused-vars */ const StyledContainer = styled(Container)` - ${props => (props.width ? `width: ${props.width}px;` : "")} + display: flex; + flex-direction: column; + + ${props => (props.containerWidth ? `width: ${props.containerWidth}px;` : "")} + ${props => + props.containerHeight + ? `height: ${props.containerHeight}px;` + : ""} .data_container { - margin: 16px; + margin: 16px 16px 0 16px; .options_searcher { margin-bottom: 12px; @@ -53,7 +66,7 @@ const StyledContainer = styled(Container)` .option_select_all_checkbox { margin-bottom: 12px; - margin-left: 8px; + /*margin-left: 8px;*/ } .options_list { @@ -62,33 +75,36 @@ const StyledContainer = styled(Container)` cursor: pointer; .option_checkbox { - margin-left: 8px; + /*margin-left: 8px;*/ } .option_link { padding-left: 8px; } - &:hover { + /*&:hover { background-color: #eceef1; - } + }*/ } } } .button_container { - border-top: 1px solid #eceef1; - .add_members_btn { - margin: 16px; - width: 293px; + border-top: 1px solid #eceef1; + display: flex; + + .add_members_btn { + margin: 16px; + } } - } `; class AdvancedSelector extends React.Component { constructor(props) { super(props); + this.ref = React.createRef(); + const groups = this.convertGroups(this.props.groups); const currentGroup = this.getCurrentGroup(groups); @@ -98,25 +114,53 @@ class AdvancedSelector extends React.Component { groups: groups, currentGroup: currentGroup }; + + if (props.isOpen) handleAnyClick(true, this.handleClick); + } + + handleClick = e => { + if (this.props.isOpen && !this.ref.current.contains(e.target)) { + this.props.onSelect && this.props.onSelect(this.state.selectedOptions); + } + }; + + componentWillUnmount() { + handleAnyClick(false, this.handleClick); } componentDidUpdate(prevProps) { + let newState = {}; + if (!isArrayEqual(this.props.selectedOptions, prevProps.selectedOptions)) { - this.setState({ selectedOptions: this.props.selectedOptions }); + newState = { selectedOptions: this.props.selectedOptions }; } if (this.props.isMultiSelect !== prevProps.isMultiSelect) { - this.setState({ selectedOptions: [] }); + newState = Object.assign({}, newState, { + selectedOptions: [] + }); } if (this.props.selectedAll !== prevProps.selectedAll) { - this.setState({ selectedAll: this.props.selectedAll }); + newState = Object.assign({}, newState, { + selectedAll: this.props.selectedAll + }); } if (!isArrayEqual(this.props.groups, prevProps.groups)) { const groups = this.convertGroups(this.props.groups); const currentGroup = this.getCurrentGroup(groups); - this.setState({ groups, currentGroup }); + newState = Object.assign({}, newState, { + groups, currentGroup + }); + } + + if(!isEmpty(newState)) { + this.setState({ ...this.state, ...newState }); + } + + if (this.props.isOpen !== prevProps.isOpen) { + handleAnyClick(this.props.isOpen, this.handleClick); } } @@ -215,7 +259,6 @@ class AdvancedSelector extends React.Component { const { value, placeholder, - maxHeight, isDisabled, onSearchChanged, options, @@ -225,9 +268,19 @@ class AdvancedSelector extends React.Component { } = this.props; const { selectedOptions, selectedAll, currentGroup, groups } = this.state; + + const containerHeight = !groups || !groups.length ? 336 : 545; + const containerWidth = !groups || !groups.length ? 325 : 690; + const listHeight = 176; + const itemHeight = 32; + return ( - -
+ +
{this.renderRow.bind(this)} @@ -310,8 +363,7 @@ AdvancedSelector.propTypes = { value: PropTypes.string, placeholder: PropTypes.string, isMultiSelect: PropTypes.bool, - mode: PropTypes.oneOf(["base", "compact"]), - width: PropTypes.number, + mode: PropTypes.oneOf(["compact", "full"]), maxHeight: PropTypes.number, isDisabled: PropTypes.bool, onSearchChanged: PropTypes.func, @@ -330,9 +382,7 @@ AdvancedSelector.propTypes = { AdvancedSelector.defaultProps = { isMultiSelect: false, - width: 325, - maxHeight: 545, - mode: "base", + mode: "compact", buttonLabel: "Add members", selectAllLabel: "Select all" }; diff --git a/web/ASC.Web.Components/src/components/examples/people.group-selector.stories.js b/web/ASC.Web.Components/src/components/examples/people.group-selector.stories.js new file mode 100644 index 0000000000..7ed7593a17 --- /dev/null +++ b/web/ASC.Web.Components/src/components/examples/people.group-selector.stories.js @@ -0,0 +1,98 @@ +import React from "react"; +import { storiesOf } from "@storybook/react"; +import { action } from "@storybook/addon-actions"; +import { withKnobs, text } from "@storybook/addon-knobs/react"; +import AdvancedSelector from "../advanced-selector"; +import Section from "../../../.storybook/decorators/section"; +import { boolean } from "@storybook/addon-knobs/dist/deprecated"; +import { ArrayValue, BooleanValue } from "react-values"; +import Button from "../button"; + +storiesOf("EXAMPLES|AdvancedSelector", module) + .addDecorator(withKnobs) + // To set a default viewport for all the stories for this component + .addParameters({ viewport: { defaultViewport: "responsive" } }) + .add("people group selector", () => { + const options = [ + { + key: "group-all", + label: "All groups", + total: 0 + }, + { + key: "group-dev", + label: "Development", + total: 0 + }, + { + key: "group-management", + label: "Management", + total: 0 + }, + { + key: "group-marketing", + label: "Marketing", + total: 0 + }, + { + key: "group-mobile", + label: "Mobile", + total: 0 + }, + { + key: "group-support", + label: "Support", + total: 0 + }, + { + key: "group-web", + label: "Web", + total: 0 + } + ]; + + return ( +
+ action("isOpen changed")} + > + {({ value: isOpen, toggle }) => ( +
+
+ )} +
+
+ ); + });