This commit is contained in:
rickcole 2020-04-20 14:10:40 +08:00
parent b29b54cb1a
commit 57427f0c47
2 changed files with 31 additions and 54 deletions

View File

@ -6,14 +6,10 @@ import Checkbox from '../../components/Checkbox';
import PopOver from '../../components/PopOver'; import PopOver from '../../components/PopOver';
import {RootCloseWrapper} from 'react-overlays'; import {RootCloseWrapper} from 'react-overlays';
import {Icon} from '../../components/icons'; import {Icon} from '../../components/icons';
import { import {autobind, flattenTree, isEmpty, filterTree} from '../../utils/helper';
autobind,
flattenTree,
isEmpty,
filterTreeWithChildren
} from '../../utils/helper';
import {dataMapping} from '../../utils/tpl-builtin'; import {dataMapping} from '../../utils/tpl-builtin';
import {OptionsControl, OptionsControlProps, Option} from '../Form/Options'; import {OptionsControl, OptionsControlProps} from '../Form/Options';
import {Option, Options} from '../../components/Select';
import Input from '../../components/Input'; import Input from '../../components/Input';
import {findDOMNode} from 'react-dom'; import {findDOMNode} from 'react-dom';
@ -26,7 +22,7 @@ export interface NestedSelectState {
isOpened?: boolean; isOpened?: boolean;
isFocused?: boolean; isFocused?: boolean;
inputValue?: string; inputValue?: string;
stack?: Array<any>; stack: Array<Array<Option>>;
} }
export default class NestedSelectControl extends React.Component< export default class NestedSelectControl extends React.Component<
@ -40,8 +36,7 @@ export default class NestedSelectControl extends React.Component<
}; };
target: any; target: any;
input: HTMLInputElement; input: HTMLInputElement;
alteredOptions: any; state: NestedSelectState = {
state = {
isOpened: false, isOpened: false,
isFocused: false, isFocused: false,
inputValue: '', inputValue: '',
@ -141,7 +136,7 @@ export default class NestedSelectControl extends React.Component<
!multiple && this.close(); !multiple && this.close();
} }
handleCheck(option: any | Array<any>, index?: number) { handleCheck(option: Option | Options, index?: number) {
const { const {
onChange, onChange,
selectedOptions, selectedOptions,
@ -156,11 +151,14 @@ export default class NestedSelectControl extends React.Component<
const {stack} = this.state; const {stack} = this.state;
if ( if (
!Array.isArray(option) &&
option.children && option.children &&
option.children.length && option.children.length &&
typeof index === 'number' typeof index === 'number'
) { ) {
const checked = selectedOptions.some(o => o.value == option.value); const checked = selectedOptions.some(
o => o.value == (option as Option).value
);
const uncheckable = cascade const uncheckable = cascade
? false ? false
: option.uncheckable || (multiple && !checked); : option.uncheckable || (multiple && !checked);
@ -173,7 +171,7 @@ export default class NestedSelectControl extends React.Component<
} }
const items = selectedOptions.concat(); const items = selectedOptions.concat();
let newValue; let newValue: Option | Options | string;
// 三种情况: // 三种情况:
// 1.全选option为数组 // 1.全选option为数组
@ -189,14 +187,17 @@ export default class NestedSelectControl extends React.Component<
} else if (withChildren) { } else if (withChildren) {
option = flattenTree([option]); option = flattenTree([option]);
const fn = option.every( const fn = option.every(
(opt: any) => !!~items.findIndex(item => item.value === opt.value) (opt: Option) => !!~items.findIndex(item => item.value === opt.value)
) )
? xorBy ? xorBy
: unionBy; : unionBy;
newValue = fn(items, option, valueField || 'value'); newValue = fn(items, [option], valueField || 'value');
} else { } else {
newValue = items.filter( newValue = items.filter(
item => !~flattenTree([option], i => i.value).indexOf(item.value) item =>
!~flattenTree([option], i => (i as Option).value).indexOf(
item.value
)
); );
!~items.map(item => item.value).indexOf(option.value) && !~items.map(item => item.value).indexOf(option.value) &&
newValue.push(option); newValue.push(option);
@ -206,19 +207,19 @@ export default class NestedSelectControl extends React.Component<
} }
if (joinValues) { if (joinValues) {
newValue = newValue newValue = (newValue as Options)
.map((item: any) => item[valueField || 'value']) .map(item => item[valueField || 'value'])
.join(delimiter || ','); .join(delimiter || ',');
} else if (extractValue) { } else if (extractValue) {
newValue = newValue.map((item: any) => item[valueField || 'value']); newValue = (newValue as Options).map(item => item[valueField || 'value']);
} }
onChange(newValue); onChange(newValue);
} }
allChecked(options: Array<any>): boolean { allChecked(options: Options): boolean {
const {selectedOptions, withChildren} = this.props; const {selectedOptions, withChildren} = this.props;
return options.every((option: any) => { return options.every(option => {
if (withChildren && option.children) { if (withChildren && option.children) {
return this.allChecked(option.children); return this.allChecked(option.children);
} }
@ -228,9 +229,9 @@ export default class NestedSelectControl extends React.Component<
}); });
} }
partialChecked(options: Array<any>): boolean { partialChecked(options: Options): boolean {
const {selectedOptions, withChildren} = this.props; const {selectedOptions, withChildren} = this.props;
return options.some((option: any) => { return options.some(option => {
if (withChildren && option.children) { if (withChildren && option.children) {
return this.partialChecked(option.children); return this.partialChecked(option.children);
} }
@ -302,11 +303,12 @@ export default class NestedSelectControl extends React.Component<
let filtedOptions = let filtedOptions =
inputValue && this.state.isOpened inputValue && this.state.isOpened
? filterTreeWithChildren(options, option => { ? filterTree(options, option => {
const reg = new RegExp(`${inputValue}`, 'i'); const reg = new RegExp(`${inputValue}`, 'i');
return ( return (
reg.test(option[labelField || 'label']) || reg.test(option[labelField || 'label']) ||
reg.test(option[valueField || 'value']) reg.test(option[valueField || 'value']) ||
option.children
); );
}) })
: options.concat(); : options.concat();
@ -317,7 +319,7 @@ export default class NestedSelectControl extends React.Component<
}); });
} }
renderOptions(): any { renderOptions() {
const { const {
multiple, multiple,
selectedOptions, selectedOptions,
@ -370,7 +372,7 @@ export default class NestedSelectControl extends React.Component<
</div> </div>
) : null} ) : null}
{options.map((option, idx) => { {options.map((option: Option, idx: number) => {
const checked = selectedOptions.some( const checked = selectedOptions.some(
o => o.value == option.value o => o.value == option.value
); );

View File

@ -834,39 +834,14 @@ export function filterTree<T extends TreeItem>(
tree: Array<T>, tree: Array<T>,
iterator: (item: T, key: number, level: number) => boolean, iterator: (item: T, key: number, level: number) => boolean,
level: number = 1 level: number = 1
) {
return tree.filter((item, index) => {
if (!iterator(item, index, level)) {
return false;
}
if (item.children && item.children.splice) {
item.children = filterTree(item.children, iterator, level + 1);
}
return true;
});
}
/**
* filterTree children
*
* @param tree
* @param iterator
* @param level
*/
export function filterTreeWithChildren<T extends TreeItem>(
tree: Array<T>,
iterator: (item: T, key: number, level: number) => boolean,
level: number = 1
) { ) {
return tree return tree
.filter((item, index) => iterator(item, index, level) || item.children) .filter((item, index) => iterator(item, index, level))
.map(item => { .map(item => {
if (item.children && item.children.splice) { if (item.children && item.children.splice) {
item = { item = {
...item, ...item,
children: filterTreeWithChildren(item.children, iterator, level + 1) children: filterTree(item.children, iterator, level + 1)
}; };
} }
return item; return item;