Merge branch 'master' of github.com:ONLYOFFICE/CommunityServer-AspNetCore
This commit is contained in:
commit
12f95379d1
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "asc-web-components",
|
"name": "asc-web-components",
|
||||||
"version": "1.0.10",
|
"version": "1.0.11",
|
||||||
"description": "Ascensio System SIA component library",
|
"description": "Ascensio System SIA component library",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"main": "dist/asc-web-components.cjs.js",
|
"main": "dist/asc-web-components.cjs.js",
|
||||||
|
@ -9,7 +9,7 @@ const StyledCloseButton = styled.div`
|
|||||||
const CloseButton = props => {
|
const CloseButton = props => {
|
||||||
//console.log("CloseButton render");
|
//console.log("CloseButton render");
|
||||||
return (
|
return (
|
||||||
<StyledCloseButton>
|
<StyledCloseButton className={props.className}>
|
||||||
<IconButton
|
<IconButton
|
||||||
color={"#D8D8D8"}
|
color={"#D8D8D8"}
|
||||||
hoverColor={"#333"}
|
hoverColor={"#333"}
|
||||||
@ -21,7 +21,6 @@ const CloseButton = props => {
|
|||||||
onClick={!props.isDisabled ? ((e) => props.onClick()) : undefined}
|
onClick={!props.isDisabled ? ((e) => props.onClick()) : undefined}
|
||||||
/>
|
/>
|
||||||
</StyledCloseButton>
|
</StyledCloseButton>
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -0,0 +1,223 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import FilterButton from './filter-button';
|
||||||
|
import HideFilter from './hide-filter';
|
||||||
|
import ComboBox from '../combobox';
|
||||||
|
import CloseButton from './close-button';
|
||||||
|
import isEqual from 'lodash/isEqual';
|
||||||
|
|
||||||
|
const StyledFilterBlock = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledFilterItem = styled.div`
|
||||||
|
display: ${props => props.block ? 'block' : 'inline-block'};
|
||||||
|
margin-bottom: ${props => props.block ? '3px' : '0'};
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
padding: 3px 44px 3px 7px;
|
||||||
|
margin-right: 2px;
|
||||||
|
border: 1px solid #ECEEF1;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #F8F9F9;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 15px;
|
||||||
|
|
||||||
|
&:last-child{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
const StyledCloseButtonBlock = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 25px;
|
||||||
|
border-left: 1px solid #ECEEF1;
|
||||||
|
right: 0;
|
||||||
|
top: 1px;
|
||||||
|
`;
|
||||||
|
const StyledComboBox = styled(ComboBox)`
|
||||||
|
display: inline-block;
|
||||||
|
background: transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: -10px;
|
||||||
|
`;
|
||||||
|
const StyledFilterName = styled.span`
|
||||||
|
line-height: 18px;
|
||||||
|
margin-left: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
class FilterItem extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
id: this.props.id
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onSelect = this.onSelect.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelect(option) {
|
||||||
|
this.props.onSelectFilterItem(null, {
|
||||||
|
key: option.group + "_" + option.key,
|
||||||
|
label: option.label,
|
||||||
|
group: option.group,
|
||||||
|
inSubgroup: !!option.inSubgroup
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<StyledFilterItem key={this.state.id} id={this.state.id} block={this.props.block} >
|
||||||
|
{this.props.groupLabel}:
|
||||||
|
{this.props.groupItems.length > 1 ?
|
||||||
|
<StyledComboBox
|
||||||
|
options={this.props.groupItems}
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
|
onSelect={this.onSelect}
|
||||||
|
selectedOption={{
|
||||||
|
key: this.state.id,
|
||||||
|
label: this.props.label
|
||||||
|
}}
|
||||||
|
size='content'
|
||||||
|
scaled={false}
|
||||||
|
noBorder={true}
|
||||||
|
opened={this.props.opened}
|
||||||
|
></StyledComboBox>
|
||||||
|
: <StyledFilterName>{this.props.label}</StyledFilterName>
|
||||||
|
}
|
||||||
|
|
||||||
|
<StyledCloseButtonBlock>
|
||||||
|
<CloseButton
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
|
onClick={!this.props.isDisabled ? ((e) => this.props.onClose(e, this.props.id)) : undefined}
|
||||||
|
/>
|
||||||
|
</StyledCloseButtonBlock>
|
||||||
|
</StyledFilterItem>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FilterBlock extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
hideFilterItems: this.props.hideFilterItems || [],
|
||||||
|
openFilterItems: this.props.openFilterItems || []
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getData = this.getData.bind(this);
|
||||||
|
this.getFilterItems = this.getFilterItems.bind(this);
|
||||||
|
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
onDeleteFilterItem(e, key){
|
||||||
|
this.props.onDeleteFilterItem(key);
|
||||||
|
}
|
||||||
|
getFilterItems() {
|
||||||
|
const _this = this;
|
||||||
|
let result = [];
|
||||||
|
let openItems = [];
|
||||||
|
let hideItems = [];
|
||||||
|
if (this.state.openFilterItems.length > 0) {
|
||||||
|
openItems = this.state.openFilterItems.map(function (item) {
|
||||||
|
return <FilterItem
|
||||||
|
block={false}
|
||||||
|
isDisabled={_this.props.isDisabled}
|
||||||
|
key={item.key}
|
||||||
|
groupItems={_this.props.getFilterData().filter(function (t) {
|
||||||
|
return (t.group == item.group && t.group != t.key);
|
||||||
|
})}
|
||||||
|
onSelectFilterItem={_this.props.onClickFilterItem}
|
||||||
|
id={item.key}
|
||||||
|
groupLabel={item.groupLabel}
|
||||||
|
label={item.label}
|
||||||
|
opened={item.key.indexOf('_-1') == -1 ? false : true}
|
||||||
|
onClose={_this.onDeleteFilterItem}>
|
||||||
|
</FilterItem>
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (this.state.hideFilterItems.length > 0) {
|
||||||
|
hideItems.push(
|
||||||
|
<HideFilter key="hide-filter" count={this.state.hideFilterItems.length} isDisabled={this.props.isDisabled}>
|
||||||
|
{
|
||||||
|
this.state.hideFilterItems.map(function (item) {
|
||||||
|
return <FilterItem
|
||||||
|
block={true}
|
||||||
|
isDisabled={_this.props.isDisabled}
|
||||||
|
key={item.key}
|
||||||
|
groupItems={_this.props.getFilterData().filter(function (t) {
|
||||||
|
return (t.group == item.group && t.group != t.key);
|
||||||
|
})}
|
||||||
|
onSelectFilterItem={_this.props.onClickFilterItem}
|
||||||
|
id={item.key}
|
||||||
|
groupLabel={item.groupLabel}
|
||||||
|
opened={false}
|
||||||
|
label={item.label}
|
||||||
|
onClose={_this.onDeleteFilterItem}>
|
||||||
|
</FilterItem>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</HideFilter>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
result = hideItems.concat(openItems);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
getData() {
|
||||||
|
const _this = this;
|
||||||
|
const d = this.props.getFilterData();
|
||||||
|
let result = [];
|
||||||
|
d.forEach(element => {
|
||||||
|
if (!element.inSubgroup) {
|
||||||
|
element.onClick = !element.isSeparator && !element.isHeader && !element.disabled ? ((e) => _this.props.onClickFilterItem(e, element)) : undefined;
|
||||||
|
element.key = element.group != element.key ? element.group + "_" + element.key : element.key;
|
||||||
|
if (element.subgroup != undefined) {
|
||||||
|
if (d.findIndex(x => x.group === element.subgroup) == -1) element.disabled = true;
|
||||||
|
}
|
||||||
|
result.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
componentDidUpdate() {
|
||||||
|
this.props.onRender();
|
||||||
|
}
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
|
||||||
|
if(!isEqual(this.props, nextProps)){
|
||||||
|
if (!isEqual(this.props.hideFilterItems, nextProps.hideFilterItems) || !isEqual(this.props.openFilterItems, nextProps.openFilterItems)) {
|
||||||
|
this.setState({
|
||||||
|
hideFilterItems: nextProps.hideFilterItems,
|
||||||
|
openFilterItems: nextProps.openFilterItems
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(this.props.isResizeUpdate){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return !isEqual(this.state, nextState);
|
||||||
|
}
|
||||||
|
render(){
|
||||||
|
const _this = this;
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<StyledFilterBlock ref={this.filterWrapper} id='filter-items-container'>
|
||||||
|
{this.getFilterItems()}
|
||||||
|
</StyledFilterBlock>
|
||||||
|
<FilterButton id='filter-button' iconSize={this.props.iconSize} getData={_this.getData} isDisabled={this.props.isDisabled} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default FilterBlock;
|
@ -6,14 +6,14 @@ class FilterButton extends React.PureComponent{
|
|||||||
//console.log('render FilterButton)
|
//console.log('render FilterButton)
|
||||||
return(
|
return(
|
||||||
<ContextMenuButton
|
<ContextMenuButton
|
||||||
title={'Actions'}
|
title='Actions'
|
||||||
iconName={'RectangleFilterIcon'}
|
iconName='RectangleFilterIcon'
|
||||||
color='#A3A9AE'
|
color='#A3A9AE'
|
||||||
size={this.props.iconSize}
|
size={this.props.iconSize}
|
||||||
isDisabled={this.props.isDisabled}
|
isDisabled={this.props.isDisabled}
|
||||||
getData={this.props.getData}
|
getData={this.props.getData}
|
||||||
iconHoverName={'RectangleFilterHoverIcon'}
|
iconHoverName='RectangleFilterHoverIcon'
|
||||||
iconClickName={'RectangleFilterClickIcon'}
|
iconClickName='RectangleFilterClickIcon'
|
||||||
></ContextMenuButton>
|
></ContextMenuButton>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -35,6 +35,7 @@ const StyledHideFilterButton = styled.div`
|
|||||||
`;
|
`;
|
||||||
const StyledHideFilter = styled.div`
|
const StyledHideFilter = styled.div`
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
`;
|
`;
|
||||||
const StyledPopoverBody = styled(PopoverBody)`
|
const StyledPopoverBody = styled(PopoverBody)`
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
@ -2,91 +2,147 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import SearchInput from '../search-input';
|
import SearchInput from '../search-input';
|
||||||
import ComboBox from '../combobox'
|
|
||||||
import IconButton from '../icon-button';
|
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
import throttle from 'lodash/throttle';
|
||||||
|
import FilterBlock from './filter-block';
|
||||||
|
import SortComboBox from './sort-combobox';
|
||||||
|
|
||||||
const StyledFilterInput = styled.div`
|
const StyledFilterInput = styled.div`
|
||||||
min-width: 380px;
|
min-width: 380px;
|
||||||
`;
|
`;
|
||||||
const StyledIconButton = styled.div`
|
|
||||||
transform: ${state => state.sortDirection ? 'scale(1, -1)' : 'scale(1)'};
|
|
||||||
`;
|
|
||||||
const StyledSearchInput = styled.div`
|
const StyledSearchInput = styled.div`
|
||||||
display: block;
|
display: block;
|
||||||
float: left;
|
float: left;
|
||||||
width: calc(80% - 8px);
|
width: calc(80% - 8px);
|
||||||
`;
|
`;
|
||||||
|
const StyledFilterBlock = styled.div`
|
||||||
const StyledComboBox = styled(ComboBox)`
|
display: flex;
|
||||||
display: block;
|
|
||||||
float: left;
|
|
||||||
width: 20%;
|
|
||||||
margin-left: 8px;
|
|
||||||
`;
|
`;
|
||||||
|
const cloneObjectsArray = function (props) {
|
||||||
|
return _.map(props, _.clone);;
|
||||||
|
}
|
||||||
|
const convertToInternalData = function (fullDataArray, inputDataArray) {
|
||||||
|
const filterItems = [];
|
||||||
|
for (let i = 0; i < inputDataArray.length; i++) {
|
||||||
|
const filterValue = fullDataArray.find(x => ((x.key === inputDataArray[i].key.replace(inputDataArray[i].group + "_", '')) && x.group === inputDataArray[i].group && !x.inSubgroup));
|
||||||
|
if (filterValue) {
|
||||||
|
inputDataArray[i].key = inputDataArray[i].group + "_" + inputDataArray[i].key;
|
||||||
|
inputDataArray[i].label = filterValue.label;
|
||||||
|
inputDataArray[i].groupLabel = !fullDataArray.inSubgroup ? fullDataArray.find(x => (x.group === inputDataArray[i].group)).label : inputDataArray[i].groupLabel;
|
||||||
|
filterItems.push(inputDataArray[i]);
|
||||||
|
} else {
|
||||||
|
filterValue = fullDataArray.find(x => ((x.key === inputDataArray[i].key.replace(inputDataArray[i].group + "_", '')) && x.group === inputDataArray[i].group && x.inSubgroup));
|
||||||
|
if (filterValue) {
|
||||||
|
inputDataArray[i].key = inputDataArray[i].group + "_" + inputDataArray[i].key;
|
||||||
|
inputDataArray[i].label = filterValue.label;
|
||||||
|
inputDataArray[i].groupLabel = fullDataArray.find(x => (x.subgroup === inputDataArray[i].group)).label;
|
||||||
|
filterItems.push(inputDataArray[i]);
|
||||||
|
} else {
|
||||||
|
filterValue = fullDataArray.find(x => ((x.subgroup === inputDataArray[i].group)));
|
||||||
|
if (filterValue) {
|
||||||
|
const subgroupItems = fullDataArray.filter(t => t.group === filterValue.subgroup);
|
||||||
|
if (subgroupItems.length > 1) {
|
||||||
|
inputDataArray[i].key = inputDataArray[i].group + "_-1";
|
||||||
|
inputDataArray[i].label = filterValue.defaultSelectLabel;
|
||||||
|
inputDataArray[i].groupLabel = fullDataArray.find(x => (x.subgroup === inputDataArray[i].group)).label;
|
||||||
|
filterItems.push(inputDataArray[i]);
|
||||||
|
} else if (subgroupItems.length === 1) {
|
||||||
|
|
||||||
class SortComboBox extends React.Component {
|
const selectFilterItem = {
|
||||||
constructor(props) {
|
key: subgroupItems[0].group + "_" + subgroupItems[0].key,
|
||||||
super(props);
|
group: subgroupItems[0].group,
|
||||||
this.onSelect = this.onSelect.bind(this);
|
label: subgroupItems[0].label,
|
||||||
|
groupLabel: fullDataArray.find(x => x.subgroup === subgroupItems[0].group).label,
|
||||||
|
inSubgroup: true
|
||||||
|
};
|
||||||
|
filterItems.push(selectFilterItem);
|
||||||
}
|
}
|
||||||
onSelect(item) {
|
|
||||||
this.props.onSelect(item);
|
|
||||||
}
|
}
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
|
||||||
return !isEqual(this.props, nextProps);
|
|
||||||
}
|
}
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<StyledComboBox
|
|
||||||
options={this.props.options}
|
|
||||||
isDisabled={this.props.isDisabled}
|
|
||||||
onSelect={this.onSelect}
|
|
||||||
selectedOption={this.props.selectedOption}
|
|
||||||
>
|
|
||||||
<StyledIconButton sortDirection={this.props.sortDirection}>
|
|
||||||
<IconButton
|
|
||||||
color={"#D8D8D8"}
|
|
||||||
hoverColor={"#333"}
|
|
||||||
clickColor={"#333"}
|
|
||||||
size={10}
|
|
||||||
iconName={'ZASortingIcon'}
|
|
||||||
isFill={true}
|
|
||||||
isDisabled={this.props.isDisabled}
|
|
||||||
onClick={this.props.onButtonClick}
|
|
||||||
/>
|
|
||||||
</StyledIconButton>
|
|
||||||
</StyledComboBox>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return filterItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
class FilterInput extends React.Component {
|
class FilterInput extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.isResizeUpdate = false;
|
||||||
|
this.minWidth = 190;
|
||||||
|
|
||||||
|
function getDefaultFilterData() {
|
||||||
|
const filterData = props.getFilterData();
|
||||||
|
const filterItems = [];
|
||||||
|
const selectedFilterData = cloneObjectsArray(props.selectedFilterData.filterValues);
|
||||||
|
selectedFilterData.forEach(defaultFilterValue => {
|
||||||
|
const filterValue = filterData.find(x => ((x.key === defaultFilterValue.key.replace(defaultFilterValue.group + "_", '')) && x.group === defaultFilterValue.group));
|
||||||
|
let groupLabel = '';
|
||||||
|
|
||||||
|
const groupFilterItem = filterData.find(x => (x.key === defaultFilterValue.group));
|
||||||
|
if (groupFilterItem != undefined) {
|
||||||
|
groupLabel = groupFilterItem.label;
|
||||||
|
} else {
|
||||||
|
const subgroupFilterItem = filterData.find(x => (x.subgroup === defaultFilterValue.group))
|
||||||
|
if (subgroupFilterItem != undefined) {
|
||||||
|
groupLabel = subgroupFilterItem.label;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterValue != undefined) {
|
||||||
|
defaultFilterValue.key = defaultFilterValue.group + "_" + defaultFilterValue.key;
|
||||||
|
defaultFilterValue.label = filterValue.label;
|
||||||
|
defaultFilterValue.groupLabel = groupLabel;
|
||||||
|
filterItems.push(defaultFilterValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return filterItems;
|
||||||
|
}
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
sortDirection: props.selectedFilterData.sortDirection == "asc" ? true : false,
|
sortDirection: props.selectedFilterData.sortDirection === "asc" ? true : false,
|
||||||
sortId: props.getSortData().findIndex(x => x.key === props.selectedFilterData.sortId) != -1 ? props.selectedFilterData.sortId : props.getSortData().length > 0 ? props.getSortData()[0].key : "",
|
sortId: props.getSortData().findIndex(x => x.key === props.selectedFilterData.sortId) != -1 ? props.selectedFilterData.sortId : props.getSortData().length > 0 ? props.getSortData()[0].key : "",
|
||||||
filterValues: props.selectedFilterData.filterValues,
|
searchText: props.selectedFilterData.inputValue || props.value,
|
||||||
searchText: props.selectedFilterData.inputValue || props.value
|
|
||||||
|
filterValues: props.selectedFilterData ? getDefaultFilterData() : [],
|
||||||
|
openFilterItems: [],
|
||||||
|
hideFilterItems: []
|
||||||
};
|
};
|
||||||
|
|
||||||
this.timerId = null;
|
this.searchWrapper = React.createRef();
|
||||||
|
this.filterWrapper = React.createRef();
|
||||||
|
|
||||||
this.onClickSortItem = this.onClickSortItem.bind(this);
|
this.onClickSortItem = this.onClickSortItem.bind(this);
|
||||||
this.onSortDirectionClick = this.onSortDirectionClick.bind(this);
|
this.onSortDirectionClick = this.onSortDirectionClick.bind(this);
|
||||||
this.onSearch = this.onSearch.bind(this);
|
this.onSearch = this.onSearch.bind(this);
|
||||||
this.onChangeFilter = this.onChangeFilter.bind(this);
|
this.onChangeFilter = this.onChangeFilter.bind(this);
|
||||||
this.setFilterTimer = this.setFilterTimer.bind(this);
|
|
||||||
this.onSearchChanged = this.onSearchChanged.bind(this);
|
this.onSearchChanged = this.onSearchChanged.bind(this);
|
||||||
|
|
||||||
this.getDefaultSelectedIndex = this.getDefaultSelectedIndex.bind(this);
|
this.getDefaultSelectedIndex = this.getDefaultSelectedIndex.bind(this);
|
||||||
|
|
||||||
|
this.updateFilter = this.updateFilter.bind(this);
|
||||||
|
this.onClickFilterItem = this.onClickFilterItem.bind(this);
|
||||||
|
this.getFilterData = this.getFilterData.bind(this);
|
||||||
|
this.onFilterRender = this.onFilterRender.bind(this);
|
||||||
|
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
|
||||||
|
this.clearFilter = this.clearFilter.bind(this);
|
||||||
|
|
||||||
|
this.throttledResize = throttle(this.resize, 300);
|
||||||
|
|
||||||
|
}
|
||||||
|
resize = () => {
|
||||||
|
this.isResizeUpdate = true;
|
||||||
|
this.setState({
|
||||||
|
filterValues: this.state.filterValues,
|
||||||
|
openFilterItems: this.state.filterValues,
|
||||||
|
hideFilterItems: []
|
||||||
|
})
|
||||||
}
|
}
|
||||||
getDefaultSelectedIndex() {
|
getDefaultSelectedIndex() {
|
||||||
const sortData = this.props.getSortData();
|
const sortData = this.props.getSortData();
|
||||||
if (sortData.length > 0) {
|
if (sortData.length > 0) {
|
||||||
let defaultIndex = sortData.findIndex(x => x.key === this.state.sortId);
|
const defaultIndex = sortData.findIndex(x => x.key === this.state.sortId);
|
||||||
return defaultIndex != -1 ? defaultIndex : 0;
|
return defaultIndex != -1 ? defaultIndex : 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -95,10 +151,117 @@ class FilterInput extends React.Component {
|
|||||||
this.setState({ sortId: item.key });
|
this.setState({ sortId: item.key });
|
||||||
this.onFilter(this.state.filterValues, item.key, this.state.sortDirection ? "asc" : "desc");
|
this.onFilter(this.state.filterValues, item.key, this.state.sortDirection ? "asc" : "desc");
|
||||||
}
|
}
|
||||||
onSortDirectionClick(e) {
|
onSortDirectionClick() {
|
||||||
|
|
||||||
this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "asc" : "desc");
|
this.onFilter(this.state.filterValues, this.state.sortId, !this.state.sortDirection ? "asc" : "desc");
|
||||||
this.setState({ sortDirection: !this.state.sortDirection });
|
this.setState({ sortDirection: !this.state.sortDirection });
|
||||||
}
|
}
|
||||||
|
onSearchChanged(value) {
|
||||||
|
this.setState({ searchText: value });
|
||||||
|
this.onFilter(this.state.filterValues, this.state.sortId, this.state.sortDirection ? "asc" : "desc",value);
|
||||||
|
}
|
||||||
|
onSearch(result) {
|
||||||
|
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "asc" : "desc");
|
||||||
|
}
|
||||||
|
getFilterData() {
|
||||||
|
const _this = this;
|
||||||
|
const d = this.props.getFilterData();
|
||||||
|
const result = [];
|
||||||
|
d.forEach(element => {
|
||||||
|
if (!element.inSubgroup) {
|
||||||
|
element.onClick = !element.isSeparator && !element.isHeader && !element.disabled ? ((e) => _this.props.onClickFilterItem(e, element)) : undefined;
|
||||||
|
element.key = element.group != element.key ? element.group + "_" + element.key : element.key;
|
||||||
|
if (element.subgroup != undefined) {
|
||||||
|
if (d.findIndex(x => x.group === element.subgroup) === -1) element.disabled = true;
|
||||||
|
}
|
||||||
|
result.push(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
clearFilter() {
|
||||||
|
this.setState({
|
||||||
|
searchText:'',
|
||||||
|
filterValues: [],
|
||||||
|
openFilterItems: [],
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
this.onFilter([], this.state.sortId, this.state.sortDirection ? "asc" : "desc", '');
|
||||||
|
}
|
||||||
|
updateFilter(inputFilterItems) {
|
||||||
|
const currentFilterItems = inputFilterItems || cloneObjectsArray(this.state.filterValues);
|
||||||
|
const fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
||||||
|
const filterWidth = this.filterWrapper.current.getBoundingClientRect().width;
|
||||||
|
const filterArr = Array.from(Array.from(this.filterWrapper.current.children).find(x => x.id === 'filter-items-container').children);
|
||||||
|
const filterButton = Array.from(Array.from(this.filterWrapper.current.children).find(x => x.id != 'filter-items-container').children)[0];
|
||||||
|
|
||||||
|
if (fullWidth <= this.minWidth) {
|
||||||
|
this.setState({
|
||||||
|
openFilterItems: [],
|
||||||
|
hideFilterItems: cloneObjectsArray(currentFilterItems)
|
||||||
|
});
|
||||||
|
} else if (filterWidth > fullWidth / 2) {
|
||||||
|
let newOpenFilterItems = cloneObjectsArray(currentFilterItems);
|
||||||
|
let newHideFilterItems = [];
|
||||||
|
|
||||||
|
let elementsWidth = 0;
|
||||||
|
Array.from(filterArr).forEach(element => {
|
||||||
|
elementsWidth = elementsWidth + element.getBoundingClientRect().width;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (elementsWidth >= (fullWidth / 3) - filterButton.getBoundingClientRect().width) {
|
||||||
|
for (let i = 0; i < filterArr.length; i++) {
|
||||||
|
if (elementsWidth > (fullWidth / 3) - filterButton.getBoundingClientRect().width) {
|
||||||
|
elementsWidth = elementsWidth - filterArr[i].getBoundingClientRect().width;
|
||||||
|
const hiddenItem = currentFilterItems.find(x => x.key === filterArr[i].getAttribute('id'));
|
||||||
|
if (hiddenItem) newHideFilterItems.push(hiddenItem);
|
||||||
|
newOpenFilterItems.splice(newOpenFilterItems.findIndex(x => x.key === filterArr[i].getAttribute('id')), 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
openFilterItems: newOpenFilterItems,
|
||||||
|
hideFilterItems: newHideFilterItems
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.setState({
|
||||||
|
openFilterItems: currentFilterItems.slice(),
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onDeleteFilterItem(key) {
|
||||||
|
const currentFilterItems = this.state.filterValues.slice();
|
||||||
|
const indexFilterItem = currentFilterItems.findIndex(x => x.key === key);
|
||||||
|
if (indexFilterItem != -1) {
|
||||||
|
currentFilterItems.splice(indexFilterItem, 1);
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
filterValues: currentFilterItems,
|
||||||
|
openFilterItems: currentFilterItems,
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
let filterValues = cloneObjectsArray(currentFilterItems);
|
||||||
|
filterValues = filterValues.map(function (item) {
|
||||||
|
item.key = item.key.replace(item.group + "_", '');
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
this.onFilter(filterValues.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "asc" : "desc");
|
||||||
|
}
|
||||||
|
onFilter(filterValues, sortId, sortDirection, searchText) {
|
||||||
|
let cloneFilterValues = cloneObjectsArray(filterValues);
|
||||||
|
cloneFilterValues = cloneFilterValues.map(function (item) {
|
||||||
|
item.key = item.key.replace(item.group + "_", '');
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
this.props.onFilter({
|
||||||
|
inputValue: searchText != undefined ? searchText : this.state.searchText,
|
||||||
|
filterValues: cloneFilterValues.filter(item => item.key != '-1'),
|
||||||
|
sortId: sortId,
|
||||||
|
sortDirection: sortDirection
|
||||||
|
});
|
||||||
|
}
|
||||||
onChangeFilter(result) {
|
onChangeFilter(result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
searchText: result.inputValue,
|
searchText: result.inputValue,
|
||||||
@ -106,43 +269,118 @@ class FilterInput extends React.Component {
|
|||||||
});
|
});
|
||||||
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "asc" : "desc", result.inputValue);
|
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "asc" : "desc", result.inputValue);
|
||||||
}
|
}
|
||||||
onSearch(result) {
|
onFilterRender() {
|
||||||
this.onFilter(result.filterValues, this.state.sortId, this.state.sortDirection ? "asc" : "desc");
|
if (this.isResizeUpdate) {
|
||||||
|
this.isResizeUpdate = false;
|
||||||
}
|
}
|
||||||
|
const fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
||||||
|
const filterWidth = this.filterWrapper.current.getBoundingClientRect().width;
|
||||||
|
if (fullWidth <= this.minWidth || filterWidth > fullWidth / 2) this.updateFilter();
|
||||||
|
}
|
||||||
|
onClickFilterItem(event, filterItem) {
|
||||||
|
const currentFilterItems = cloneObjectsArray(this.state.filterValues);
|
||||||
|
|
||||||
onFilter(filterValues, sortId, sortDirection, searchText) {
|
if (!!filterItem.subgroup) {
|
||||||
let result = {
|
const indexFilterItem = currentFilterItems.findIndex(x => x.group === filterItem.subgroup);
|
||||||
inputValue: searchText != undefined ? searchText : this.state.searchText,
|
if (indexFilterItem != -1) {
|
||||||
filterValues: filterValues,
|
currentFilterItems.splice(indexFilterItem, 1);
|
||||||
sortId: sortId,
|
}
|
||||||
sortDirection: sortDirection
|
const subgroupItems = this.props.getFilterData().filter(t => t.group === filterItem.subgroup);
|
||||||
|
if (subgroupItems.length > 1) {
|
||||||
|
const selectFilterItem = {
|
||||||
|
key: filterItem.subgroup + "_-1",
|
||||||
|
group: filterItem.subgroup,
|
||||||
|
label: filterItem.defaultSelectLabel,
|
||||||
|
groupLabel: filterItem.label,
|
||||||
|
inSubgroup: true
|
||||||
};
|
};
|
||||||
this.props.onFilter(result);
|
if (indexFilterItem != -1)
|
||||||
|
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
||||||
|
else
|
||||||
|
currentFilterItems.push(selectFilterItem);
|
||||||
|
this.setState({
|
||||||
|
filterValues: currentFilterItems,
|
||||||
|
openFilterItems: currentFilterItems,
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
} else if (subgroupItems.length === 1) {
|
||||||
|
|
||||||
|
const selectFilterItem = {
|
||||||
|
key: subgroupItems[0].group + "_" + subgroupItems[0].key,
|
||||||
|
group: subgroupItems[0].group,
|
||||||
|
label: subgroupItems[0].label,
|
||||||
|
groupLabel: this.props.getFilterData().find(x => x.subgroup === subgroupItems[0].group).label,
|
||||||
|
inSubgroup: true
|
||||||
|
};
|
||||||
|
if (indexFilterItem != -1)
|
||||||
|
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
||||||
|
else
|
||||||
|
currentFilterItems.push(selectFilterItem);
|
||||||
|
|
||||||
|
const clone = cloneObjectsArray(currentFilterItems.filter(item => item.key != '-1'));
|
||||||
|
clone.map(function (item) {
|
||||||
|
item.key = item.key.replace(item.group + "_", '');
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "asc" : "desc");
|
||||||
|
this.setState({
|
||||||
|
filterValues: currentFilterItems,
|
||||||
|
openFilterItems: currentFilterItems,
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const filterItems = this.getFilterData();
|
||||||
|
|
||||||
|
const indexFilterItem = currentFilterItems.findIndex(x => x.group === filterItem.group);
|
||||||
|
if (indexFilterItem != -1) {
|
||||||
|
currentFilterItems.splice(indexFilterItem, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
setFilterTimer() {
|
const selectFilterItem = {
|
||||||
this.timerId && clearTimeout(this.timerId);
|
key: filterItem.key,
|
||||||
this.timerId = null;
|
group: filterItem.group,
|
||||||
this.timerId = setTimeout(() => {
|
label: filterItem.label,
|
||||||
this.onSearch({ filterValues: this.state.filterValues });
|
groupLabel: filterItem.inSubgroup ? filterItems.find(x => x.subgroup === filterItem.group).label : filterItems.find(x => x.key === filterItem.group).label
|
||||||
clearTimeout(this.timerId);
|
};
|
||||||
this.timerId = null;
|
if (indexFilterItem != -1)
|
||||||
}, this.props.refreshTimeout);
|
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
||||||
|
else
|
||||||
|
currentFilterItems.push(selectFilterItem);
|
||||||
|
this.setState({
|
||||||
|
filterValues: currentFilterItems,
|
||||||
|
openFilterItems: currentFilterItems,
|
||||||
|
hideFilterItems: []
|
||||||
|
});
|
||||||
|
|
||||||
|
const clone = cloneObjectsArray(currentFilterItems.filter(item => item.key != '-1'));
|
||||||
|
clone.map(function (item) {
|
||||||
|
item.key = item.key.replace(item.group + "_", '');
|
||||||
|
return item;
|
||||||
|
})
|
||||||
|
this.onFilter(clone.filter(item => item.key != '-1'), this.state.sortId, this.state.sortDirection ? "asc" : "desc");
|
||||||
}
|
}
|
||||||
|
|
||||||
onSearchChanged(e) {
|
}
|
||||||
this.setState({ searchText: e.target.value });
|
|
||||||
|
|
||||||
if (this.props.autoRefresh)
|
componentDidMount() {
|
||||||
this.setFilterTimer();
|
window.addEventListener('resize', this.throttledResize);
|
||||||
|
}
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('resize', this.throttledResize);
|
||||||
}
|
}
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
if (!isEqual(this.props.selectedFilterData, nextProps.selectedFilterData)) {
|
if (!isEqual(this.props.selectedFilterData, nextProps.selectedFilterData)) {
|
||||||
|
let internalFilterData = cloneObjectsArray(this.state.filterValues);
|
||||||
|
if (!!nextProps.selectedFilterData.filterValues) {
|
||||||
|
internalFilterData = convertToInternalData(this.props.getFilterData(), cloneObjectsArray(nextProps.selectedFilterData.filterValues));
|
||||||
|
this.updateFilter(internalFilterData);
|
||||||
|
}
|
||||||
this.setState(
|
this.setState(
|
||||||
{
|
{
|
||||||
sortDirection: nextProps.selectedFilterData.sortDirection === "asc" ? true : false,
|
sortDirection: nextProps.selectedFilterData.sortDirection === "asc" ? true : false,
|
||||||
sortId: this.props.getSortData().findIndex(x => x.key === nextProps.selectedFilterData.sortId) != -1 ? nextProps.selectedFilterData.sortId : "",
|
sortId: this.props.getSortData().findIndex(x => x.key === nextProps.selectedFilterData.sortId) != -1 ? nextProps.selectedFilterData.sortId : "",
|
||||||
filterValues: nextProps.selectedFilterData.filterValues || this.state.filterValues,
|
filterValues: internalFilterData,
|
||||||
searchText: nextProps.selectedFilterData.inputValue || this.props.value
|
searchText: nextProps.selectedFilterData.inputValue || this.props.value
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -155,15 +393,29 @@ class FilterInput extends React.Component {
|
|||||||
this.props.value != nextProps.value)
|
this.props.value != nextProps.value)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
if (this.isResizeUpdate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return !isEqual(this.state, nextState);
|
return !isEqual(this.state, nextState);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
//console.log("FilterInput render");
|
//console.log("FilterInput render");
|
||||||
|
let iconSize = 32;
|
||||||
|
switch (this.props.size) {
|
||||||
|
case 'base':
|
||||||
|
iconSize = 32;
|
||||||
|
break;
|
||||||
|
case 'middle':
|
||||||
|
case 'big':
|
||||||
|
case 'huge':
|
||||||
|
iconSize = 41;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<StyledFilterInput>
|
<StyledFilterInput className={this.props.className}>
|
||||||
<StyledSearchInput>
|
<StyledSearchInput ref={this.searchWrapper}>
|
||||||
<SearchInput
|
<SearchInput
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
isDisabled={this.props.isDisabled}
|
isDisabled={this.props.isDisabled}
|
||||||
@ -176,8 +428,25 @@ class FilterInput extends React.Component {
|
|||||||
onChangeFilter={this.onChangeFilter}
|
onChangeFilter={this.onChangeFilter}
|
||||||
value={this.state.searchText}
|
value={this.state.searchText}
|
||||||
selectedFilterData={this.state.filterValues}
|
selectedFilterData={this.state.filterValues}
|
||||||
|
showClearButton={this.state.filterValues.length > 0}
|
||||||
|
onClearSearch={this.clearFilter}
|
||||||
onChange={this.onSearchChanged}
|
onChange={this.onSearchChanged}
|
||||||
|
>
|
||||||
|
<StyledFilterBlock ref={this.filterWrapper}>
|
||||||
|
<FilterBlock
|
||||||
|
openFilterItems={this.state.openFilterItems}
|
||||||
|
hideFilterItems={this.state.hideFilterItems}
|
||||||
|
iconSize={iconSize}
|
||||||
|
getFilterData={this.props.getFilterData}
|
||||||
|
onClickFilterItem={this.onClickFilterItem}
|
||||||
|
onDeleteFilterItem={this.onDeleteFilterItem}
|
||||||
|
isResizeUpdate={this.isResizeUpdate}
|
||||||
|
onRender={this.onFilterRender}
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
/>
|
/>
|
||||||
|
</StyledFilterBlock>
|
||||||
|
|
||||||
|
</SearchInput>
|
||||||
</StyledSearchInput>
|
</StyledSearchInput>
|
||||||
|
|
||||||
<SortComboBox
|
<SortComboBox
|
||||||
@ -196,13 +465,11 @@ class FilterInput extends React.Component {
|
|||||||
|
|
||||||
FilterInput.protoTypes = {
|
FilterInput.protoTypes = {
|
||||||
autoRefresh: PropTypes.bool,
|
autoRefresh: PropTypes.bool,
|
||||||
refreshTimeout: PropTypes.number,
|
|
||||||
selectedFilterData: PropTypes.object,
|
selectedFilterData: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterInput.defaultProps = {
|
FilterInput.defaultProps = {
|
||||||
autoRefresh: true,
|
autoRefresh: true,
|
||||||
refreshTimeout: 1000,
|
|
||||||
selectedFilterData: {
|
selectedFilterData: {
|
||||||
sortDirection: false,
|
sortDirection: false,
|
||||||
sortId: '',
|
sortId: '',
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import isEqual from 'lodash/isEqual';
|
||||||
|
import ComboBox from '../combobox'
|
||||||
|
import IconButton from '../icon-button';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
const StyledIconButton = styled.div`
|
||||||
|
transform: ${state => state.sortDirection ? 'scale(1, -1)' : 'scale(1)'};
|
||||||
|
`;
|
||||||
|
const StyledComboBox = styled(ComboBox)`
|
||||||
|
display: block;
|
||||||
|
float: left;
|
||||||
|
width: 20%;
|
||||||
|
margin-left: 8px;
|
||||||
|
`;
|
||||||
|
class SortComboBox extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.onSelect = this.onSelect.bind(this);
|
||||||
|
}
|
||||||
|
onSelect(item) {
|
||||||
|
this.props.onSelect(item);
|
||||||
|
}
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
return !isEqual(this.props, nextProps);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<StyledComboBox
|
||||||
|
options={this.props.options}
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
|
onSelect={this.onSelect}
|
||||||
|
selectedOption={this.props.selectedOption}
|
||||||
|
>
|
||||||
|
<StyledIconButton sortDirection={this.props.sortDirection}>
|
||||||
|
<IconButton
|
||||||
|
color={"#D8D8D8"}
|
||||||
|
hoverColor={"#333"}
|
||||||
|
clickColor={"#333"}
|
||||||
|
size={10}
|
||||||
|
iconName={'ZASortingIcon'}
|
||||||
|
isFill={true}
|
||||||
|
isDisabled={this.props.isDisabled}
|
||||||
|
onClick={this.props.onButtonClick}
|
||||||
|
/>
|
||||||
|
</StyledIconButton>
|
||||||
|
</StyledComboBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SortComboBox;
|
@ -2,571 +2,104 @@ import React from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import InputBlock from '../input-block';
|
import InputBlock from '../input-block';
|
||||||
import ComboBox from '../combobox';
|
|
||||||
|
|
||||||
import FilterButton from './filter-button';
|
|
||||||
import HideFilter from './hide-filter';
|
|
||||||
import CloseButton from './close-button';
|
|
||||||
|
|
||||||
import isEqual from 'lodash/isEqual';
|
import isEqual from 'lodash/isEqual';
|
||||||
|
|
||||||
const StyledSearchInput = styled.div`
|
const StyledSearchInput = styled.div`
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
font-family: Open Sans;
|
font-family: Open Sans;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
`;
|
`;
|
||||||
const StyledFilterBlock = styled.div`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
`;
|
|
||||||
const StyledFilterItem = styled.div`
|
|
||||||
display: ${props => props.block ? 'block' : 'inline-block'};
|
|
||||||
margin-bottom: ${props => props.block ? '3px' : '0'};
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
padding: 3px 44px 3px 7px;
|
|
||||||
margin-right: 2px;
|
|
||||||
border: 1px solid #ECEEF1;
|
|
||||||
border-radius: 3px;
|
|
||||||
background-color: #F8F9F9;
|
|
||||||
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 15px;
|
|
||||||
|
|
||||||
&:last-child{
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
const StyledCloseButtonBlock = styled.div`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 25px;
|
|
||||||
border-left: 1px solid #ECEEF1;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
`;
|
|
||||||
const StyledComboBox = styled(ComboBox)`
|
|
||||||
display: inline-block;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-left: -10px;
|
|
||||||
`;
|
|
||||||
const StyledFilterName = styled.span`
|
|
||||||
line-height: 18px;
|
|
||||||
margin-left: 5px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
class FilterItem extends React.Component {
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
id: this.props.id
|
|
||||||
};
|
|
||||||
|
|
||||||
this.onSelect = this.onSelect.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
onSelect(option) {
|
|
||||||
this.props.onSelectFilterItem(null, {
|
|
||||||
key: option.group + "_" + option.key,
|
|
||||||
label: option.label,
|
|
||||||
group: option.group,
|
|
||||||
inSubgroup: !!option.inSubgroup
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<StyledFilterItem key={this.state.id} id={this.state.id} block={this.props.block} >
|
|
||||||
{this.props.groupLabel}:
|
|
||||||
{this.props.groupItems.length > 1 ?
|
|
||||||
<StyledComboBox
|
|
||||||
options={this.props.groupItems}
|
|
||||||
isDisabled={this.props.isDisabled}
|
|
||||||
onSelect={this.onSelect}
|
|
||||||
selectedOption={{
|
|
||||||
key: this.state.id,
|
|
||||||
label: this.props.label
|
|
||||||
}}
|
|
||||||
size='content'
|
|
||||||
scaled={false}
|
|
||||||
noBorder={true}
|
|
||||||
opened={this.props.opened}
|
|
||||||
></StyledComboBox>
|
|
||||||
: <StyledFilterName>{this.props.label}</StyledFilterName>
|
|
||||||
}
|
|
||||||
|
|
||||||
<StyledCloseButtonBlock>
|
|
||||||
<CloseButton
|
|
||||||
isDisabled={this.props.isDisabled}
|
|
||||||
onClick={!this.props.isDisabled ? ((e) => this.props.onClose(e, this.props.id)) : undefined}
|
|
||||||
/>
|
|
||||||
</StyledCloseButtonBlock>
|
|
||||||
</StyledFilterItem>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const cloneObjectsArray = function (props) {
|
|
||||||
return _.map(props, _.clone);;
|
|
||||||
}
|
|
||||||
|
|
||||||
const convertToInternalData = function (fullDataArray, inputDataArray) {
|
|
||||||
let filterItems = [];
|
|
||||||
for (let i = 0; i < inputDataArray.length; i++) {
|
|
||||||
let filterValue = fullDataArray.find(x => ((x.key === inputDataArray[i].key.replace(inputDataArray[i].group + "_", '')) && x.group === inputDataArray[i].group && !x.inSubgroup));
|
|
||||||
if (filterValue) {
|
|
||||||
inputDataArray[i].key = inputDataArray[i].group + "_" + inputDataArray[i].key;
|
|
||||||
inputDataArray[i].label = filterValue.label;
|
|
||||||
inputDataArray[i].groupLabel = !fullDataArray.inSubgroup ? fullDataArray.find(x => (x.group === inputDataArray[i].group)).label : inputDataArray[i].groupLabel;
|
|
||||||
filterItems.push(inputDataArray[i]);
|
|
||||||
} else {
|
|
||||||
filterValue = fullDataArray.find(x => ((x.key === inputDataArray[i].key.replace(inputDataArray[i].group + "_", '')) && x.group === inputDataArray[i].group && x.inSubgroup));
|
|
||||||
if (filterValue) {
|
|
||||||
inputDataArray[i].key = inputDataArray[i].group + "_" + inputDataArray[i].key;
|
|
||||||
inputDataArray[i].label = filterValue.label;
|
|
||||||
inputDataArray[i].groupLabel = fullDataArray.find(x => (x.subgroup === inputDataArray[i].group)).label;
|
|
||||||
filterItems.push(inputDataArray[i]);
|
|
||||||
} else {
|
|
||||||
filterValue = fullDataArray.find(x => ((x.subgroup === inputDataArray[i].group)));
|
|
||||||
if (filterValue) {
|
|
||||||
let subgroupItems = fullDataArray.filter(function (t) {
|
|
||||||
return (t.group == filterValue.subgroup);
|
|
||||||
});
|
|
||||||
if (subgroupItems.length > 1) {
|
|
||||||
inputDataArray[i].key = inputDataArray[i].group + "_-1";
|
|
||||||
inputDataArray[i].label = filterValue.defaultSelectLabel;
|
|
||||||
inputDataArray[i].groupLabel = fullDataArray.find(x => (x.subgroup === inputDataArray[i].group)).label;
|
|
||||||
filterItems.push(inputDataArray[i]);
|
|
||||||
} else if (subgroupItems.length == 1) {
|
|
||||||
|
|
||||||
let selectFilterItem = {
|
|
||||||
key: subgroupItems[0].group + "_" + subgroupItems[0].key,
|
|
||||||
group: subgroupItems[0].group,
|
|
||||||
label: subgroupItems[0].label,
|
|
||||||
groupLabel: fullDataArray.find(x => x.subgroup === subgroupItems[0].group).label,
|
|
||||||
inSubgroup: true
|
|
||||||
};
|
|
||||||
filterItems.push(selectFilterItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return filterItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
class SearchInput extends React.Component {
|
class SearchInput extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.input = React.createRef();
|
this.input = React.createRef();
|
||||||
|
this.timerId = null;
|
||||||
|
|
||||||
function getDefaultFilterData() {
|
|
||||||
let filterData = props.getFilterData();
|
|
||||||
let filterItems = [];
|
|
||||||
let selectedFilterData = cloneObjectsArray(props.selectedFilterData);
|
|
||||||
selectedFilterData.forEach(defaultFilterValue => {
|
|
||||||
let filterValue = filterData.find(x => ((x.key === defaultFilterValue.key.replace(defaultFilterValue.group + "_", '')) && x.group === defaultFilterValue.group));
|
|
||||||
let groupLabel = '';
|
|
||||||
|
|
||||||
let groupFilterItem = filterData.find(x => (x.key === defaultFilterValue.group));
|
|
||||||
if (groupFilterItem != undefined) {
|
|
||||||
groupLabel = groupFilterItem.label;
|
|
||||||
} else {
|
|
||||||
let subgroupFilterItem = filterData.find(x => (x.subgroup === defaultFilterValue.group))
|
|
||||||
if (subgroupFilterItem != undefined) {
|
|
||||||
groupLabel = subgroupFilterItem.label;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filterValue != undefined) {
|
|
||||||
defaultFilterValue.key = defaultFilterValue.group + "_" + defaultFilterValue.key;
|
|
||||||
defaultFilterValue.label = filterValue.label;
|
|
||||||
defaultFilterValue.groupLabel = groupLabel;
|
|
||||||
filterItems.push(defaultFilterValue);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return filterItems;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.minWidth = 190;
|
|
||||||
this.isResizeUpdate = false;
|
|
||||||
this.state = {
|
this.state = {
|
||||||
inputValue: props.value,
|
inputValue: props.value,
|
||||||
filterItems: props.selectedFilterData && props.isNeedFilter ? getDefaultFilterData() : [],
|
|
||||||
openFilterItems: [],
|
|
||||||
hideFilterItems: []
|
|
||||||
};
|
};
|
||||||
this.searchWrapper = React.createRef();
|
|
||||||
this.filterWrapper = React.createRef();
|
|
||||||
|
|
||||||
this.onClickDropDownItem = this.onClickDropDownItem.bind(this);
|
this.clearSearch = this.clearSearch.bind(this);
|
||||||
this.getData = this.getData.bind(this);
|
|
||||||
this.clearFilter = this.clearFilter.bind(this);
|
|
||||||
this.onDeleteFilterItem = this.onDeleteFilterItem.bind(this);
|
|
||||||
this.getFilterItems = this.getFilterItems.bind(this);
|
|
||||||
this.updateFilter = this.updateFilter.bind(this);
|
|
||||||
this.onInputChange = this.onInputChange.bind(this);
|
this.onInputChange = this.onInputChange.bind(this);
|
||||||
|
this.setSearchTimer = this.setSearchTimer.bind(this);
|
||||||
this.resize = this.resize.bind(this);
|
|
||||||
|
|
||||||
this.throttledResize = _.throttle(this.resize, 300);
|
|
||||||
}
|
|
||||||
|
|
||||||
onClickDropDownItem(event, filterItem) {
|
|
||||||
let currentFilterItems = cloneObjectsArray(this.state.filterItems);
|
|
||||||
|
|
||||||
if (!!filterItem.subgroup) {
|
|
||||||
let indexFilterItem = currentFilterItems.findIndex(x => x.group === filterItem.subgroup);
|
|
||||||
if (indexFilterItem != -1) {
|
|
||||||
currentFilterItems.splice(indexFilterItem, 1);
|
|
||||||
}
|
|
||||||
let subgroupItems = this.props.getFilterData().filter(function (t) {
|
|
||||||
return (t.group == filterItem.subgroup);
|
|
||||||
});
|
|
||||||
if (subgroupItems.length > 1) {
|
|
||||||
let selectFilterItem = {
|
|
||||||
key: filterItem.subgroup + "_-1",
|
|
||||||
group: filterItem.subgroup,
|
|
||||||
label: filterItem.defaultSelectLabel,
|
|
||||||
groupLabel: filterItem.label,
|
|
||||||
inSubgroup: true
|
|
||||||
};
|
|
||||||
if (indexFilterItem != -1)
|
|
||||||
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
|
||||||
else
|
|
||||||
currentFilterItems.push(selectFilterItem);
|
|
||||||
this.setState({ filterItems: currentFilterItems });
|
|
||||||
this.updateFilter(currentFilterItems);
|
|
||||||
} else if (subgroupItems.length == 1) {
|
|
||||||
|
|
||||||
let selectFilterItem = {
|
|
||||||
key: subgroupItems[0].group + "_" + subgroupItems[0].key,
|
|
||||||
group: subgroupItems[0].group,
|
|
||||||
label: subgroupItems[0].label,
|
|
||||||
groupLabel: this.props.getFilterData().find(x => x.subgroup === subgroupItems[0].group).label,
|
|
||||||
inSubgroup: true
|
|
||||||
};
|
|
||||||
if (indexFilterItem != -1)
|
|
||||||
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
|
||||||
else
|
|
||||||
currentFilterItems.push(selectFilterItem);
|
|
||||||
let clone = cloneObjectsArray(currentFilterItems.filter(function (item) {
|
|
||||||
return item.key != '-1';
|
|
||||||
}));
|
|
||||||
clone.map(function (item) {
|
|
||||||
item.key = item.key.replace(item.group + "_", '');
|
|
||||||
return item;
|
|
||||||
})
|
|
||||||
if (typeof this.props.onChangeFilter === "function")
|
|
||||||
this.props.onChangeFilter({
|
|
||||||
inputValue: this.state.inputValue,
|
|
||||||
filterValues: this.props.isNeedFilter ?
|
|
||||||
clone.filter(function (item) {
|
|
||||||
return item.key != '-1';
|
|
||||||
}) :
|
|
||||||
null
|
|
||||||
});
|
|
||||||
this.setState({ filterItems: currentFilterItems });
|
|
||||||
this.updateFilter(currentFilterItems);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} else {
|
clearSearch(){
|
||||||
let filterItems = this.getData();
|
|
||||||
|
|
||||||
let indexFilterItem = currentFilterItems.findIndex(x => x.group === filterItem.group);
|
|
||||||
if (indexFilterItem != -1) {
|
|
||||||
currentFilterItems.splice(indexFilterItem, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
let selectFilterItem = {
|
|
||||||
key: filterItem.key,
|
|
||||||
group: filterItem.group,
|
|
||||||
label: filterItem.label,
|
|
||||||
groupLabel: filterItem.inSubgroup ? filterItems.find(x => x.subgroup === filterItem.group).label : filterItems.find(x => x.key === filterItem.group).label
|
|
||||||
};
|
|
||||||
if (indexFilterItem != -1)
|
|
||||||
currentFilterItems.splice(indexFilterItem, 0, selectFilterItem);
|
|
||||||
else
|
|
||||||
currentFilterItems.push(selectFilterItem);
|
|
||||||
this.setState({ filterItems: currentFilterItems });
|
|
||||||
this.updateFilter(currentFilterItems);
|
|
||||||
|
|
||||||
let clone = cloneObjectsArray(currentFilterItems.filter(function (item) {
|
|
||||||
return item.key != '-1';
|
|
||||||
}));
|
|
||||||
clone.map(function (item) {
|
|
||||||
item.key = item.key.replace(item.group + "_", '');
|
|
||||||
return item;
|
|
||||||
})
|
|
||||||
if (typeof this.props.onChangeFilter === "function")
|
|
||||||
this.props.onChangeFilter({
|
|
||||||
inputValue: this.state.inputValue,
|
|
||||||
filterValues: this.props.isNeedFilter ?
|
|
||||||
clone.filter(function (item) {
|
|
||||||
return item.key != '-1';
|
|
||||||
}) :
|
|
||||||
null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getData() {
|
|
||||||
let _this = this;
|
|
||||||
let d = this.props.getFilterData();
|
|
||||||
let result = [];
|
|
||||||
d.forEach(element => {
|
|
||||||
if (!element.inSubgroup) {
|
|
||||||
element.onClick = !element.isSeparator && !element.isHeader && !element.disabled ? ((e) => _this.onClickDropDownItem(e, element)) : undefined;
|
|
||||||
element.key = element.group != element.key ? element.group + "_" + element.key : element.key;
|
|
||||||
if (element.subgroup != undefined) {
|
|
||||||
if (d.findIndex(x => x.group === element.subgroup) == -1) element.disabled = true;
|
|
||||||
}
|
|
||||||
result.push(element);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
clearFilter() {
|
|
||||||
if (this.input.current) this.input.current.clearInput();
|
if (this.input.current) this.input.current.clearInput();
|
||||||
this.setState({
|
this.setState({
|
||||||
inputValue: '',
|
inputValue: ''
|
||||||
filterItems: [],
|
|
||||||
openFilterItems: [],
|
|
||||||
hideFilterItems: []
|
|
||||||
});
|
});
|
||||||
this.props.onChangeFilter({
|
if(typeof this.props.onClearSearch === 'function') this.props.onClearSearch();
|
||||||
inputValue: '',
|
|
||||||
filterValues: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onDeleteFilterItem(e, key) {
|
|
||||||
|
|
||||||
let currentFilterItems = this.state.filterItems.slice();
|
|
||||||
let indexFilterItem = currentFilterItems.findIndex(x => x.key === key);
|
|
||||||
if (indexFilterItem != -1) {
|
|
||||||
currentFilterItems.splice(indexFilterItem, 1);
|
|
||||||
}
|
|
||||||
this.setState({ filterItems: currentFilterItems });
|
|
||||||
this.updateFilter(currentFilterItems);
|
|
||||||
let filterValues = cloneObjectsArray(currentFilterItems);
|
|
||||||
filterValues = filterValues.map(function (item) {
|
|
||||||
item.key = item.key.replace(item.group + "_", '');
|
|
||||||
return item;
|
|
||||||
})
|
|
||||||
if (typeof this.props.onChangeFilter === "function")
|
|
||||||
this.props.onChangeFilter({
|
|
||||||
inputValue: this.state.inputValue,
|
|
||||||
filterValues: this.props.isNeedFilter ?
|
|
||||||
filterValues.filter(function (item) {
|
|
||||||
return item.key != '-1';
|
|
||||||
}) : null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getFilterItems() {
|
|
||||||
let _this = this;
|
|
||||||
let result = [];
|
|
||||||
let openItems = [];
|
|
||||||
let hideItems = [];
|
|
||||||
if ((this.state.filterItems.length > 0 && this.state.hideFilterItems.length === 0 && this.state.openFilterItems.length === 0) || this.state.openFilterItems.length > 0) {
|
|
||||||
const filterItemsArray = this.state.openFilterItems.length > 0 ? this.state.openFilterItems : this.state.filterItems;
|
|
||||||
openItems = filterItemsArray.map(function (item) {
|
|
||||||
return <FilterItem
|
|
||||||
isDisabled={_this.props.isDisabled}
|
|
||||||
key={item.key}
|
|
||||||
groupItems={_this.props.getFilterData().filter(function (t) {
|
|
||||||
return (t.group == item.group && t.group != t.key);
|
|
||||||
})}
|
|
||||||
onSelectFilterItem={_this.onClickDropDownItem}
|
|
||||||
id={item.key}
|
|
||||||
groupLabel={item.groupLabel}
|
|
||||||
label={item.label}
|
|
||||||
opened={item.key.indexOf('_-1') == -1 ? false : true}
|
|
||||||
onClose={_this.onDeleteFilterItem}>
|
|
||||||
</FilterItem>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.state.hideFilterItems.length > 0) {
|
|
||||||
hideItems.push(
|
|
||||||
<HideFilter key="hide-filter" count={this.state.hideFilterItems.length} isDisabled={this.props.isDisabled}>
|
|
||||||
{
|
|
||||||
this.state.hideFilterItems.map(function (item) {
|
|
||||||
return <FilterItem
|
|
||||||
block={true}
|
|
||||||
isDisabled={_this.props.isDisabled}
|
|
||||||
key={item.key}
|
|
||||||
groupItems={_this.props.getFilterData().filter(function (t) {
|
|
||||||
return (t.group == item.group && t.group != t.key);
|
|
||||||
})}
|
|
||||||
onSelectFilterItem={_this.onClickDropDownItem}
|
|
||||||
id={item.key}
|
|
||||||
groupLabel={item.groupLabel}
|
|
||||||
opened={false}
|
|
||||||
label={item.label}
|
|
||||||
onClose={_this.onDeleteFilterItem}>
|
|
||||||
</FilterItem>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</HideFilter>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
result = hideItems.concat(openItems);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
updateFilter(inputFilterItems) {
|
|
||||||
|
|
||||||
const currentFilterItems = inputFilterItems || cloneObjectsArray(this.state.filterItems);
|
|
||||||
let fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
|
||||||
let filterWidth = this.filterWrapper.current.getBoundingClientRect().width;
|
|
||||||
|
|
||||||
if (fullWidth <= this.minWidth) {
|
|
||||||
this.setState({ openFilterItems: [] });
|
|
||||||
this.setState({ hideFilterItems: currentFilterItems.slice() });
|
|
||||||
} else if (filterWidth > fullWidth / 2) {
|
|
||||||
let newOpenFilterItems = cloneObjectsArray(currentFilterItems);
|
|
||||||
let newHideFilterItems = [];
|
|
||||||
|
|
||||||
let elementsWidth = 0;
|
|
||||||
Array.from(this.filterWrapper.current.children).forEach(element => {
|
|
||||||
elementsWidth = elementsWidth + element.getBoundingClientRect().width;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (elementsWidth >= fullWidth / 3) {
|
|
||||||
let filterArr = Array.from(this.filterWrapper.current.children);
|
|
||||||
for (let i = 0; i < filterArr.length; i++) {
|
|
||||||
if (elementsWidth > fullWidth / 3) {
|
|
||||||
elementsWidth = elementsWidth - filterArr[i].getBoundingClientRect().width;
|
|
||||||
newHideFilterItems.push(currentFilterItems.find(x => x.key === filterArr[i].getAttribute('id')));
|
|
||||||
newOpenFilterItems.splice(newOpenFilterItems.findIndex(x => x.key === filterArr[i].getAttribute('id')), 1);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
this.setState({ openFilterItems: newOpenFilterItems });
|
|
||||||
this.setState({ hideFilterItems: newHideFilterItems });
|
|
||||||
} else {
|
|
||||||
this.setState({ openFilterItems: currentFilterItems.slice() });
|
|
||||||
this.setState({ hideFilterItems: [] });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onInputChange(e) {
|
onInputChange(e) {
|
||||||
this.setState({
|
this.setState({
|
||||||
inputValue: e.target.value
|
inputValue: e.target.value
|
||||||
});
|
});
|
||||||
this.props.onChange(e)
|
if (this.props.autoRefresh)
|
||||||
|
this.setSearchTimer(e.target.value);
|
||||||
|
}
|
||||||
|
setSearchTimer(value) {
|
||||||
|
this.timerId && clearTimeout(this.timerId);
|
||||||
|
this.timerId = null;
|
||||||
|
this.timerId = setTimeout(() => {
|
||||||
|
this.props.onChange(value);
|
||||||
|
clearTimeout(this.timerId);
|
||||||
|
this.timerId = null;
|
||||||
|
}, this.props.refreshTimeout);
|
||||||
|
}
|
||||||
|
shouldComponentUpdate(nextProps, nextState) {
|
||||||
|
if (this.props.value != nextProps.value) {
|
||||||
|
this.setState({ inputValue: nextProps.value });
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
resize() {
|
return (!isEqual(this.state, nextState) || !isEqual(this.props, nextProps));
|
||||||
this.isResizeUpdate = true;
|
|
||||||
//this.forceUpdate();
|
|
||||||
this.setState({
|
|
||||||
openFilterItems: this.state.filterItems,
|
|
||||||
hideFilterItems: []
|
|
||||||
})
|
|
||||||
}
|
|
||||||
componentDidUpdate() {
|
|
||||||
if (this.props.isNeedFilter) {
|
|
||||||
const fullWidth = this.searchWrapper.current.getBoundingClientRect().width;
|
|
||||||
const filterWidth = this.filterWrapper.current.getBoundingClientRect().width;
|
|
||||||
if (fullWidth <= this.minWidth || filterWidth > fullWidth / 2) this.updateFilter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
componentDidMount() {
|
|
||||||
window.addEventListener('resize', this.throttledResize);
|
|
||||||
if (this.props.isNeedFilter) this.updateFilter();
|
|
||||||
}
|
|
||||||
componentWillUnmount(){
|
|
||||||
window.removeEventListener('resize', this.throttledResize);
|
|
||||||
}
|
|
||||||
shouldComponentUpdate(nextProps, nextState) {
|
|
||||||
if (this.props.value != nextProps.value || !isEqual(this.props.selectedFilterData, nextProps.selectedFilterData)) {
|
|
||||||
if (this.props.value != nextProps.value) {
|
|
||||||
this.setState({ inputValue: nextProps.value })
|
|
||||||
}
|
|
||||||
if (!isEqual(this.props.selectedFilterData, nextProps.selectedFilterData) && this.props.isNeedFilter) {
|
|
||||||
const internalFilterData = convertToInternalData(this.props.getFilterData(), cloneObjectsArray(nextProps.selectedFilterData));
|
|
||||||
this.setState({ filterItems: internalFilterData });
|
|
||||||
this.updateFilter(internalFilterData);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.props.id != nextProps.id ||
|
|
||||||
this.props.isDisabled != nextProps.isDisabled ||
|
|
||||||
this.props.size != nextProps.size ||
|
|
||||||
this.props.placeholder != nextProps.placeholder ||
|
|
||||||
this.props.isNeedFilter != nextProps.isNeedFilter
|
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (this.isResizeUpdate) {
|
|
||||||
this.isResizeUpdate = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return !isEqual(this.state, nextState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
//console.log("Search input render");
|
//console.log("Search input render");
|
||||||
let _this = this;
|
|
||||||
let iconSize = 32;
|
|
||||||
let clearButtonSize = 15;
|
let clearButtonSize = 15;
|
||||||
switch (this.props.size) {
|
switch (this.props.size) {
|
||||||
case 'base':
|
case 'base':
|
||||||
iconSize = 32;
|
clearButtonSize = !!this.state.inputValue || this.props.showClearButton > 0 ? 12 : 15;
|
||||||
clearButtonSize = !!this.state.inputValue || this.state.filterItems.length > 0 ? 12 : 15;
|
|
||||||
break;
|
break;
|
||||||
case 'middle':
|
case 'middle':
|
||||||
iconSize = 41;
|
clearButtonSize = !!this.state.inputValue || this.props.showClearButton > 0 ? 16 : 18;
|
||||||
clearButtonSize = !!this.state.inputValue || this.state.filterItems.length > 0 ? 16 : 18;
|
|
||||||
break;
|
break;
|
||||||
case 'big':
|
case 'big':
|
||||||
iconSize = 41;
|
clearButtonSize = !!this.state.inputValue || this.props.showClearButton > 0 ? 19 : 21;
|
||||||
clearButtonSize = !!this.state.inputValue || this.state.filterItems.length > 0 ? 19 : 21;
|
|
||||||
break;
|
break;
|
||||||
case 'huge':
|
case 'huge':
|
||||||
iconSize = 41;
|
clearButtonSize = !!this.state.inputValue || this.props.showClearButton > 0 ? 22 : 24;
|
||||||
clearButtonSize = !!this.state.inputValue || this.state.filterItems.length > 0 ? 22 : 24;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledSearchInput className={this.props.className} ref={this.searchWrapper}>
|
<StyledSearchInput className={this.props.className}>
|
||||||
<InputBlock
|
<InputBlock
|
||||||
ref={this.input}
|
ref={this.input}
|
||||||
id={this.props.id}
|
id={this.props.id}
|
||||||
|
name={this.props.name}
|
||||||
isDisabled={this.props.isDisabled}
|
isDisabled={this.props.isDisabled}
|
||||||
iconName={!!this.state.inputValue || this.state.filterItems.length > 0 ? "CrossIcon" : "SearchIcon"}
|
iconName={!!this.state.inputValue || this.props.showClearButton > 0 ? "CrossIcon" : "SearchIcon"}
|
||||||
isIconFill={true}
|
isIconFill={true}
|
||||||
iconSize={clearButtonSize}
|
iconSize={clearButtonSize}
|
||||||
iconColor={"#A3A9AE"}
|
iconColor={"#A3A9AE"}
|
||||||
onIconClick={!!this.state.inputValue || this.state.filterItems.length > 0 ? this.clearFilter : undefined}
|
onIconClick={!!this.state.inputValue || this.props.showClearButton ? this.clearSearch : undefined}
|
||||||
size={this.props.size}
|
size={this.props.size}
|
||||||
scale={true}
|
scale={true}
|
||||||
value={this.state.inputValue}
|
value={this.state.inputValue}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
onChange={this.onInputChange}
|
onChange={this.onInputChange}
|
||||||
>
|
>
|
||||||
{this.props.isNeedFilter &&
|
{this.props.children}
|
||||||
<StyledFilterBlock ref={this.filterWrapper}>
|
|
||||||
{this.getFilterItems()}
|
|
||||||
</StyledFilterBlock>
|
|
||||||
}
|
|
||||||
|
|
||||||
{this.props.isNeedFilter &&
|
|
||||||
<FilterButton iconSize={iconSize} getData={_this.getData} isDisabled={this.props.isDisabled} />
|
|
||||||
}
|
|
||||||
</InputBlock>
|
</InputBlock>
|
||||||
</StyledSearchInput>
|
</StyledSearchInput>
|
||||||
);
|
);
|
||||||
@ -580,19 +113,20 @@ SearchInput.propTypes = {
|
|||||||
scale: PropTypes.bool,
|
scale: PropTypes.bool,
|
||||||
placeholder: PropTypes.string,
|
placeholder: PropTypes.string,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
getFilterData: PropTypes.func,
|
|
||||||
isNeedFilter: PropTypes.bool,
|
|
||||||
isDisabled: PropTypes.bool,
|
isDisabled: PropTypes.bool,
|
||||||
selectedFilterData: PropTypes.array
|
showClearButton: PropTypes.bool,
|
||||||
|
refreshTimeout: PropTypes.number,
|
||||||
|
autoRefresh: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
SearchInput.defaultProps = {
|
SearchInput.defaultProps = {
|
||||||
|
autoRefresh: true,
|
||||||
size: 'base',
|
size: 'base',
|
||||||
value: '',
|
value: '',
|
||||||
scale: false,
|
scale: false,
|
||||||
isNeedFilter: false,
|
|
||||||
isDisabled: false,
|
isDisabled: false,
|
||||||
selectedFilterData: []
|
refreshTimeout: 1000,
|
||||||
|
showClearButton: false
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SearchInput;
|
export default SearchInput;
|
@ -18,6 +18,9 @@ function getData() {
|
|||||||
{ key: 'filter-type', group: 'filter-type', label: 'Type', isHeader: true },
|
{ key: 'filter-type', group: 'filter-type', label: 'Type', isHeader: true },
|
||||||
{ key: '0', group: 'filter-type', label: 'Folders' },
|
{ key: '0', group: 'filter-type', label: 'Folders' },
|
||||||
{ key: '1', group: 'filter-type', label: 'Employee' },
|
{ key: '1', group: 'filter-type', label: 'Employee' },
|
||||||
|
{ key: 'filter-test', group: 'filter-test', label: 'Test', isHeader: true },
|
||||||
|
{ key: '0', group: 'filter-test', label: 'test1' },
|
||||||
|
{ key: '1', group: 'filter-test', label: 'test2' },
|
||||||
{ key: 'filter-other', group: 'filter-other', label: 'Other', isHeader: true },
|
{ key: 'filter-other', group: 'filter-other', label: 'Other', isHeader: true },
|
||||||
{ key: '0', group: 'filter-other', subgroup: 'filter-groups', defaultSelectLabel: 'Select', label: 'Groups' },
|
{ key: '0', group: 'filter-other', subgroup: 'filter-groups', defaultSelectLabel: 'Select', label: 'Groups' },
|
||||||
{ key: '0', inSubgroup: true, group: 'filter-groups', label: 'Administration'},
|
{ key: '0', inSubgroup: true, group: 'filter-groups', label: 'Administration'},
|
||||||
|
@ -46,8 +46,8 @@ class SearchStory extends React.Component {
|
|||||||
return(
|
return(
|
||||||
<Section>
|
<Section>
|
||||||
<StringValue
|
<StringValue
|
||||||
onChange={e => {
|
onChange={value => {
|
||||||
action('onChange')(e);
|
action('onChange')(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@ -64,14 +64,10 @@ class SearchStory extends React.Component {
|
|||||||
isDisabled={boolean('isDisabled', false)}
|
isDisabled={boolean('isDisabled', false)}
|
||||||
size={select('size', sizeOptions, 'base')}
|
size={select('size', sizeOptions, 'base')}
|
||||||
scale={boolean('scale', false)}
|
scale={boolean('scale', false)}
|
||||||
isNeedFilter={boolean('isNeedFilter', true)}
|
|
||||||
getFilterData={getData}
|
|
||||||
selectedFilterData={this.state.selectedFilterData}
|
|
||||||
placeholder={text('placeholder', 'Search')}
|
placeholder={text('placeholder', 'Search')}
|
||||||
onChangeFilter={(result) => {console.log(result)}}
|
|
||||||
value={value}
|
value={value}
|
||||||
onChange={e => {
|
onChange={value => {
|
||||||
set(e.target.value);
|
set(value);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Section>
|
</Section>
|
||||||
|
Loading…
Reference in New Issue
Block a user