Commit 66972afa authored by Viacheslav Pavlov's avatar Viacheslav Pavlov Committed by Matija Obreza

Checkbox for NOT filter

- moved checkbox filters to new component

- removed innocent console.log

- fixed nullPtr issue

- fixed after update dependencies
parent 7a354846
......@@ -12,6 +12,7 @@ import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSea
import NumberFilter from 'ui/common/filter/NumberFilter';
import StringFilter from 'ui/common/filter/StringFilter';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
import AutocompleteFilter from 'ui/common/filter/AutocompleteFilter';
import Accession from 'model/accession/Accession';
import Crop from 'model/genesys/Crop';
......@@ -79,12 +80,13 @@ const AccessionFilters = ({handleSubmit, initialValues, initialize, filterCode,
<DateFilter name="lastModifiedDate" label={ t('common:f.lastModifiedDate') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('accessions.public.f.crop') }>
<StringArrFilter
<OptionsFilter
name="crop"
valueField="shortName"
labelField="name"
options={ crops }
terms={ terms && terms.get('crop.shortName') }
initialFormValues={ initialValues }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('accessions.common.taxonomy') }>
......@@ -129,7 +131,7 @@ const AccessionFilters = ({handleSubmit, initialValues, initialize, filterCode,
<NumberFilter name="geo.elevation" label={ t('accessions.public.f.elevation') } />
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('accessions.common.sampStat') }>
<StringArrFilter
<OptionsFilter
name="sampStat"
options={ Accession.SAMPSTAT }
byKey
......@@ -138,7 +140,7 @@ const AccessionFilters = ({handleSubmit, initialValues, initialize, filterCode,
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('accessions.common.storageType') }>
<StringArrFilter
<OptionsFilter
name="storage"
options={ Accession.STORAGE }
byKey
......
......@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import Crop from 'model/genesys/Crop';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
interface IProps extends React.ClassAttributes<any> {
crops: Crop[];
......@@ -14,7 +14,7 @@ class CropFilter extends React.Component<IProps, any> {
public render() {
const {crops} = this.props;
return (
<StringArrFilter name="crop" options={ crops && crops.sort((a, b) => a.name.localeCompare(b.name)) } valueField="shortName" labelField="name" { ...this.props }/>
<OptionsFilter name="crop" options={ crops && crops.sort((a, b) => a.name.localeCompare(b.name)) } valueField="shortName" labelField="name" { ...this.props }/>
);
}
}
......
......@@ -11,6 +11,7 @@ import FiltersBlock from 'ui/common/filter/FiltersBlock';
import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSearch';
import StringFilter from 'ui/common/filter/StringFilter';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
import TextFilter from 'ui/common/filter/TextFilter';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
import NumberFilter from 'ui/common/filter/NumberFilter';
......@@ -21,7 +22,7 @@ import InputAdornment from '@material-ui/core/InputAdornment';
// <StringArrFilter name="language" label="Language" placeholder="Language"/>
const DatasetFilters = ({ handleSubmit, initialize, t, terms, crops, ...other }:
const DatasetFilters = ({ handleSubmit, initialize, t, terms, crops, initialValues, ...other }:
WithTranslation & { handleSubmit: any, initialize: any, terms: any, crops: Crop[]} & any) => {
let sectionIndex: number = 0;
return (
......@@ -54,12 +55,13 @@ const DatasetFilters = ({ handleSubmit, initialize, t, terms, crops, ...other }:
<NumberFilter name="locations.decimalLongitude" label={ t('datasets.public.f.longitude') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('datasets.public.f.crop') }>
<StringArrFilter
<OptionsFilter
name="crops"
valueField="shortName"
labelField="name"
options={ crops }
terms={ terms && terms.get('crops') }
initialFormValues={ initialValues }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('datasets.public.f.accession') }>
......
......@@ -12,7 +12,7 @@ import Authorize from 'ui/common/authorized/Authorize';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
import StatusFilter from 'ui/catalog/dashboard/c/StatusFilter'; // move
const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
const DashboardFilters = ({ handleSubmit, initialize, initialValues, t, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
<FiltersBlock
title={ t('descriptors.dashboard.f.title') }
handleSubmit={ handleSubmit }
......@@ -20,7 +20,7 @@ const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTransla
{ ...other }
>
<CollapsibleComponentSearch title={ t('descriptors.dashboard.f.status') }>
<StatusFilter/>
<StatusFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('common:f.textSearch') }>
<TextFilter
......@@ -34,7 +34,7 @@ const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTransla
</CollapsibleComponentSearch>
</Authorize>
<CollapsibleComponentSearch title={ t('descriptors.dashboard.f.crop') }>
<CropFilter name="crops"/>
<CropFilter name="crops" initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
......@@ -15,10 +15,10 @@ import PartnerFilter from 'partners/ui/c/PartnerFilter';
import IconButton from '@material-ui/core/IconButton';
import HelpOutlineIcon from '@material-ui/icons/HelpOutline';
import InputAdornment from '@material-ui/core/InputAdornment';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
const DescriptorListFilters = ({ handleSubmit, initialize, t, terms, crops, ...other }:
const DescriptorListFilters = ({ handleSubmit, initialize, t, terms, crops, initialValues, ...other }:
WithTranslation & { handleSubmit?: any, initialize: any, terms: any, crops: Crop[] } & any) => {
let sectionIndex: number = 0;
return (
......@@ -44,12 +44,13 @@ const DescriptorListFilters = ({ handleSubmit, initialize, t, terms, crops, ...o
<PartnerFilter name="owner" label={ t('descriptorlists.public.common.partner') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('descriptorlists.public.common.crop') }>
<StringArrFilter
<OptionsFilter
name="crop"
valueField="shortName"
labelField="name"
options={ crops }
terms={ terms && terms.get('crop') }
initialFormValues={ initialValues }
/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('descriptorlists.public.common.publisher') }>
......
......@@ -5,6 +5,7 @@ import { WithTranslation, withTranslation } from 'react-i18next';
import FiltersBlock from 'ui/common/filter/FiltersBlock';
import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSearch';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
import BooleanFilter from 'ui/common/filter/BooleanFilter';
import TextFilter from 'ui/common/filter/TextFilter';
import CropFilter from 'crop/ui/c/CropFilter';
......@@ -13,7 +14,7 @@ import Descriptor from 'model/catalog/Descriptor';
import DescriptorListPicker from './DescriptorListPicker';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
const DescriptorFilters = ({ handleSubmit, initialize, t, ...other }:
const DescriptorFilters = ({ handleSubmit, initialize, t, initialValues, ...other }:
WithTranslation & { handleSubmit: any, initialize: any } & any) => {
let sectionIndex: number = 0;
return (
......@@ -32,10 +33,10 @@ const DescriptorFilters = ({ handleSubmit, initialize, t, ...other }:
<DescriptorListPicker name="descriptorLists.uuid" label={ t('descriptors.public.f.select') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('descriptors.public.f.crop') }>
<CropFilter/>
<CropFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('descriptors.public.f.category') }>
<StringArrFilter name="category" options={ Descriptor.CATEGORIES } byKey/>
<OptionsFilter name="category" options={ Descriptor.CATEGORIES } byKey initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('descriptors.public.f.tidbits') }>
<BooleanFilter name="used" label={ t('descriptors.public.f.isUsed') } notNull/>
......
......@@ -13,7 +13,7 @@ import Authorize from 'ui/common/authorized/Authorize';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
import StatusFilter from 'ui/catalog/dashboard/c/StatusFilter'; // move
const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
const DashboardFilters = ({ handleSubmit, initialize, t, initialValues, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
<FiltersBlock
title={ t('descriptors.dashboard.f.title') }
handleSubmit={ handleSubmit }
......@@ -21,7 +21,7 @@ const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTransla
{ ...other }
>
<CollapsibleComponentSearch title={ t('descriptors.dashboard.f.status') }>
<StatusFilter/>
<StatusFilter initialFormValues={ initialValues }/>
<BooleanFilter name="used" label={ t('descriptors.dashboard.f.descriptorInUse') } notNull/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('common:f.textSearch') }>
......@@ -36,7 +36,7 @@ const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTransla
</CollapsibleComponentSearch>
</Authorize>
<CollapsibleComponentSearch title={ t('descriptors.dashboard.f.crop') }>
<CropFilter/>
<CropFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
......@@ -18,7 +18,7 @@ const MaterialRequestFilters = ({handleSubmit, initialValues, initialize, ...oth
<StringArrFilter name="pid" label="requests.admin.f.pid" placeholder="ihope-youk-noww-hatyouredoing"/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title="common:label.status">
<StatusFilter isMaterialRequestFilter/>
<StatusFilter isMaterialRequestFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
......@@ -22,7 +22,7 @@ const MaterialSubRequestFilters = ({handleSubmit, initialValues, initialize, ...
<DateFilter name="lastReminderDate" label="common:f.lastReminderDate"/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title="common:label.status">
<StatusFilter isMaterialSubRequestFilter/>
<StatusFilter isMaterialSubRequestFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
......@@ -8,6 +8,7 @@ import FiltersBlock from 'ui/common/filter/FiltersBlock';
import CollapsibleComponentSearch from 'ui/common/filter/CollapsibleComponentSearch';
import StringFilter from 'ui/common/filter/StringFilter';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter from 'ui/common/filter/OptionsFilter';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
import TextFilter from 'ui/common/filter/TextFilter';
import IconButton from '@material-ui/core/IconButton';
......@@ -43,12 +44,13 @@ const SubsetFilters = ({handleSubmit, initialValues, initialize, t, terms, crops
<StringFilter name="description" searchType="contains" label={ t('subsets.public.f.description') } placeholder={ t('subsets.public.f.descriptionPlaceholder') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch sectionIndex={ sectionIndex++ } title={ t('subsets.public.f.crop') }>
<StringArrFilter
<OptionsFilter
name="crops"
valueField="shortName"
labelField="name"
options={ crops }
terms={ terms && terms.get('crops') }
initialFormValues={ initialValues }
/>
</CollapsibleComponentSearch>
</FiltersBlock>
......
......@@ -15,7 +15,7 @@ const SubsetFilters = ({handleSubmit, initialValues, initialize, t, ...other}) =
return (
<FiltersBlock title={ t('subsets.dashboard.f.filterTitle') } handleSubmit={ handleSubmit } initialize={ initialize } { ...other }>
<CollapsibleComponentSearch title={ t('common:label.status') }>
<StatusFilter/>
<StatusFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('subsets.public.f.partner') }>
<PartnerFilter name="owner" label="subsets.public.f.partner"/>
......@@ -28,7 +28,7 @@ const SubsetFilters = ({handleSubmit, initialValues, initialize, t, ...other}) =
<StringArrFilter name="publisher" label={ t('subsets.dashboard.f.publisher') } placeholder={ t('subsets.dashboard.f.publisherPlaceholder') }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('subsets.dashboard.f.crop') }>
<CropFilter name="crops" />
<CropFilter name="crops" initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
......@@ -12,10 +12,10 @@ import Authorize from 'ui/common/authorized/Authorize';
import PartnerFilter from 'partners/ui/c/PartnerFilter';
import StatusFilter from './StatusFilter';
const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
const DashboardFilters = ({ handleSubmit, initialize, initialValues, t, ...other }: WithTranslation & { handleSubmit, initialize } & any) => (
<FiltersBlock title={ t('common:label.filters') } handleSubmit={ handleSubmit } initialize={ initialize } { ...other }>
<CollapsibleComponentSearch title={ t('common:label.status') }>
<StatusFilter/>
<StatusFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
<CollapsibleComponentSearch title={ t('common:f.textSearch') }>
<TextFilter name="_text" label={ t('common:f.textSearch') } placeholder={ t('dashboard.f.keywordSearchPlaceholder') }/>
......@@ -26,7 +26,7 @@ const DashboardFilters = ({ handleSubmit, initialize, t, ...other }: WithTransla
</CollapsibleComponentSearch>
</Authorize>
<CollapsibleComponentSearch title={ t('crop.common.modelName') }>
<CropFilter/>
<CropFilter initialFormValues={ initialValues }/>
</CollapsibleComponentSearch>
</FiltersBlock>
);
......
import * as React from 'react';
import StringArrFilter from 'ui/common/filter/StringArrFilter';
import OptionsFilter, {IOptionsFilterProps} from 'ui/common/filter/OptionsFilter';
import { PublishState } from 'model/common.model';
interface IStatusFilter {
interface IStatusFilter extends Partial<IOptionsFilterProps> {
isMaterialRequestFilter?: boolean;
isMaterialSubRequestFilter?: boolean;
}
......@@ -29,7 +29,7 @@ class StatusFilter extends React.Component<IStatusFilter, any> {
public render() {
return (
<StringArrFilter name="state" options={ this.options } byKey/>
<OptionsFilter name="state" options={ this.options } byKey { ...this.props }/>
);
}
}
......
import * as React from 'react';
import { Checkbox } from '@material-ui/core';
interface IThreeStateCheckboxProps extends React.ClassAttributes<any> {
value?: number;
onPositiveChange?: () => void;
onNeutralChange?: () => void;
onNegativeChange?: () => void;
onChange?: (value: number) => void;
}
class ThreeStateCheckbox extends React.Component<IThreeStateCheckboxProps> {
public state = {
currentState: 0,
};
public componentDidMount(): void {
const {value} = this.props;
this.setState({currentState: value});
}
public componentWillReceiveProps(nextProps) {
const {value} = nextProps;
this.setState({currentState: value});
}
public render() {
const {currentState} = this.state;
return currentState === -1 ? (
<Checkbox
checked
indeterminate
onChange={ this.onNegativeChange }
/>
) : (
<Checkbox
checked={ !!currentState }
onChange={ this.onPositiveChange }
/>
);
}
protected onNegativeChange = () => {
const {onChange, onNeutralChange} = this.props;
if (onChange) {
onChange(0);
}
if (onNeutralChange) {
onNeutralChange();
}
return this.setState({currentState: 0});
}
protected onPositiveChange = (event, value) => {
const {onChange, onNegativeChange, onPositiveChange} = this.props;
if (value) {
if (onChange) {
onChange(1);
}
if (onPositiveChange) {
onPositiveChange();
}
return this.setState({currentState: 1});
} else {
if (onChange) {
onChange(-1);
}
if (onNegativeChange) {
onNegativeChange();
}
return this.setState({currentState: -1});
}
}
}
export default ThreeStateCheckbox;
import * as React from 'react';
import * as _ from 'lodash';
import {withTranslation, WithTranslation} from 'react-i18next';
import { Fields } from 'redux-form';
import FormControl from '@material-ui/core/FormControl';
import FormLabel from '@material-ui/core/FormLabel';
import FormGroup from '@material-ui/core/FormGroup';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import ThreeStateCheckbox from 'ui/common/checkbox/ThreeStateCheckbox';
import Number from 'ui/common/Number';
interface IOptionsFilterInternalProps extends React.ClassAttributes<any>, WithTranslation {
names: string[];
input: any;
label?: string;
labelField?: string;
valueField?: string;
options?: { [key: string]: any };
indented?: boolean;
t: any;
addToNotList: (item: any) => void;
notList: any[];
notIgnoredValues: any[];
byKey: boolean;
terms: any;
}
class OptionsFilterInternal extends React.Component<IOptionsFilterInternalProps, any> {
public constructor(props, context) {
super(props, context);
const input = _.get(props, `${ this.props.names[0] }.input`);
const value = typeof input.value[0] === 'number' ? input.value.map((key) => `${ key }`) : input.value;
const notInput = _.get(props, `${ this.props.names[1] }.input`);
const notValue = typeof notInput.value[0] === 'number' ? notInput.value.map((key) => `${ key }`) : notInput.value;
this.state = {
values: [...value],
notValues: [...notValue],
text: '',
error: null,
};
}
public componentWillMount() {
const input = _.get(this.props, `${ this.props.names[0] }.input`);
const value = typeof input.value[0] === 'number' ? input.value.map((key) => `${ key }`) : input.value;
const notInput = _.get(this.props, `${ this.props.names[1] }.input`);
const notValue = typeof notInput.value[0] === 'number' ? notInput.value.map((key) => `${ key }`) : notInput.value;
this.setState({
values: [...value],
notValues: [...notValue],
text: '',
error: null,
});
}
public componentWillReceiveProps(nextProps) {
const input = _.get(nextProps, `${ nextProps.names[0] }.input`);
const value = typeof input.value[0] === 'number' ? input.value.map((key) => `${ key }`) : input.value;
const notInput = _.get(nextProps, `${ nextProps.names[1] }.input`);
const notValue = typeof notInput.value[0] === 'number' ? notInput.value.map((key) => `${ key }`) : notInput.value;
this.setState({
values: [...value],
notValues: [...notValue],
text: '',
error: null,
});
}
public render() {
const { label, options, indented, t, terms, valueField, labelField } = this.props;
const { values, notValues } = this.state;
let tree;
if (indented && options) {
tree = new Map<string, number>();
this.buildMapOfCategories(tree, Object.keys(options), 0);
}
const filteredOptions = this.getFilteredOptions();
return (!filteredOptions || filteredOptions.length === 0 ?
(<div className="pl-15">{ t('common:f.noFilters') }</div>)
: (
<FormControl fullWidth component={ 'fieldset' as 'div' } className="full-width">
{ label && <FormLabel component="label">{ label }</FormLabel> }
<FormGroup>
{ filteredOptions.map((key) => (
<FormControlLabel
key={ valueField ? `${ key[valueField] }` : `${ key }` }
style={
(document && document.dir === 'rtl') ?
{paddingRight: `${ tree ? (tree.get(key) * 20) : 0 }px`} :
{paddingLeft: `${ tree ? (tree.get(key) * 20) : 0 }px`}
}
classes={ {label: 'full-width', root: 'mr-0'} }
label={
<span className="full-width" style={ {display: 'flex', justifyContent: 'space-between'} }>
{ `${ t(options[key]) || (labelField ? key[labelField] : key) }` }
{ terms &&
<span className="float-right">
<Number value={ terms.get(valueField ? `${ key[valueField] }` : `${ key }`) }/>
</span>
}
</span>
}
control={
<ThreeStateCheckbox
value={
values.indexOf(valueField ? `${ key[valueField] }` : `${ key }`) >= 0 ? 1 :
notValues.indexOf(valueField ? `${ key[valueField] }` : `${ key }`) >= 0 ? -1 : 0
}
onChange={ this.handleCheckbox(valueField ? `${ key[valueField] }` : key) }
/>
}
/>
)) }
</FormGroup>
</FormControl>
)
);
}
private getSubcategories = (value) => {
const myRegexp = /^([1-9]+)(0+)$/;
const match = myRegexp.exec(value);
const category = match ? match[1] : null;
const subCategories = [];
const filteredOptions = this.getFilteredOptions();
Object.keys(this.props.options).forEach((option) => {
if (category && option !== value && filteredOptions.indexOf(option) > 0 && option.startsWith(category)) {
subCategories.push(option);
}
});
return subCategories;
}
private getFilteredOptions = () => {
const { options, byKey, terms, valueField, notIgnoredValues} = this.props;
const fieldOptions = options && (byKey ? Object.keys(options) : options);
return terms ? (fieldOptions && fieldOptions.filter((opt) => terms.get(valueField ? opt[valueField] : `${opt}`) > 0 || notIgnoredValues.includes(valueField ? opt[valueField] : `${opt}`))) : fieldOptions;
}
private buildMapOfCategories = (map: Map<string, number>, options: string[], level: number) => {
options.forEach((option) => {
const subCategories = this.getSubcategories(option);
if (subCategories.length === 0) {
if (map.has(option)) {
const oldLevel = map.get(option);
if (oldLevel <= level) {
map.set(option, level);
}
} else {
map.set(option, level);
}
} else {
if (map.has(option)) {
const oldLevel = map.get(option);
if (oldLevel <= level) {
map.set(option, level);
this.buildMapOfCategories(map, subCategories, level + 1);
}
} else {
map.set(option, level);
this.buildMapOfCategories(map, subCategories, level + 1);
}
}
});
}
private maybeAdd = (...newValues: string[]) => {
const values = [...this.state.values];
const notValues = [...this.state.notValues];
newValues.forEach((text) => {
if (text && text.length > 0) {
if (values.indexOf(text) < 0 && notValues.indexOf(text) < 0) {
values.push(`${ text }`);
}
}
});
if (!_.isEqual(values, this.state.values)) {