-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: condition-builder支持selectMode为chained的选项层级显示 (#7120)
* feat: condition-builder支持selectMode为chained的选项层级显示
- Loading branch information
Showing
14 changed files
with
625 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"status": 0, | ||
"msg": "", | ||
"data": { | ||
"fields": [ | ||
{ | ||
"label": "文本", | ||
"type": "text", | ||
"name": "text" | ||
}, | ||
{ | ||
"label": "数字", | ||
"type": "number", | ||
"name": "number" | ||
}, | ||
{ | ||
"label": "布尔", | ||
"type": "boolean", | ||
"name": "boolean" | ||
}, | ||
{ | ||
"label": "日期", | ||
"name": "date", | ||
"children": [ | ||
{ | ||
"label": "日期1", | ||
"type": "date", | ||
"name": "date1" | ||
}, | ||
{ | ||
"label": "时间2", | ||
"type": "time", | ||
"name": "time2" | ||
}, | ||
{ | ||
"label": "日期时间3", | ||
"type": "datetime", | ||
"name": "datetime" | ||
} | ||
] | ||
} | ||
] | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
141 changes: 141 additions & 0 deletions
141
packages/amis-ui/src/components/ChainedDropdownSelection.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
import React from 'react'; | ||
import omit from 'lodash/omit'; | ||
import { | ||
uncontrollable, | ||
autobind, | ||
ThemeProps, | ||
themeable, | ||
localeable, | ||
LocaleProps | ||
} from 'amis-core'; | ||
|
||
import {Options} from './Select'; | ||
import {BaseSelection, BaseSelectionProps} from './Selection'; | ||
|
||
import DropDownSelection from './DropDownSelection'; | ||
|
||
export interface ChainedDropDownSelectionProps | ||
extends ThemeProps, | ||
LocaleProps, | ||
BaseSelectionProps { | ||
options: Array<any>; | ||
value: any; | ||
onChange: (value: any) => void; | ||
disabled?: boolean; | ||
searchable?: boolean; | ||
popOverContainer?: any; | ||
} | ||
|
||
interface ChainedDropdownSelectionState { | ||
stacks: Array<Options>; | ||
values: Array<string>; | ||
} | ||
|
||
export class ChainedDropdownSelection extends BaseSelection< | ||
ChainedDropDownSelectionProps, | ||
ChainedDropdownSelectionState | ||
> { | ||
constructor(props: ChainedDropDownSelectionProps) { | ||
super(props); | ||
|
||
this.state = this.computed(props.value, props.options); | ||
} | ||
|
||
componentDidUpdate(prevProps: ChainedDropDownSelectionProps) { | ||
const {options, value} = this.props; | ||
if (options !== prevProps.options || prevProps.value !== value) { | ||
this.setState(this.computed(value, options)); | ||
} | ||
} | ||
|
||
computed(value: string, options: Options) { | ||
const {valueField} = this.props; | ||
let values: Array<string> = []; | ||
const getValues = (opts: Options, arr: Array<string> = []) => { | ||
opts.forEach(item => { | ||
const cValue = valueField ? item[valueField] : item?.value ?? ''; | ||
if (cValue === value) { | ||
values = [...arr, cValue]; | ||
} else if (item.children) { | ||
getValues(item.children, [...arr, cValue]); | ||
} | ||
}); | ||
}; | ||
getValues(options); | ||
return { | ||
values, | ||
stacks: this.computedStask(values) | ||
}; | ||
} | ||
|
||
getFlatOptions(options: Options) { | ||
return options.map(item => omit(item, 'children')); | ||
} | ||
|
||
@autobind | ||
handleSelect(index: number, value: string) { | ||
// 当前层级点击时,需要重新设置下values的值,以及重新计算stacks列表 | ||
const {values} = this.state; | ||
values.splice(index, values.length - index); | ||
value && values.push(value); | ||
const stacks = this.computedStask(values); | ||
this.setState( | ||
{ | ||
stacks, | ||
values | ||
}, | ||
() => { | ||
this.props?.onChange?.(value); | ||
} | ||
); | ||
} | ||
|
||
// 根据树结构层级,寻找最后一层 | ||
computedStask(values: string[]) { | ||
const {options, valueField} = this.props; | ||
const getDeep = (opts: Options, index: number, tems: Array<Options>) => { | ||
tems.push(this.getFlatOptions(opts)); | ||
opts.forEach(op => { | ||
const cValue = valueField ? op[valueField] : op?.value ?? ''; | ||
if ( | ||
cValue === values[index] && | ||
op.children && | ||
values.length - 1 >= index | ||
) { | ||
getDeep(op.children, index + 1, tems); | ||
} | ||
}); | ||
return tems; | ||
}; | ||
|
||
return getDeep(options, 0, []); | ||
} | ||
|
||
render() { | ||
const {stacks, values} = this.state; | ||
const {className, classnames: cx} = this.props; | ||
|
||
return ( | ||
<div className={cx('ChainedDropdownSelection', className)}> | ||
{stacks.map((item, index) => ( | ||
<div className={cx('ChainedDropdownSelection-item')} key={index}> | ||
<DropDownSelection | ||
{...this.props} | ||
value={values[index]} | ||
options={item} | ||
onChange={value => this.handleSelect(index, value)} | ||
/> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default themeable( | ||
localeable( | ||
uncontrollable(ChainedDropdownSelection, { | ||
value: 'onChange' | ||
}) | ||
) | ||
); |
Oops, something went wrong.