Skip to content

Commit

Permalink
feat(next/antd): support search in readPretty, fix rowClick in readPr…
Browse files Browse the repository at this point in the history
…etty, fix search selected bug (#2920)
  • Loading branch information
ifblooms authored Mar 10, 2022
1 parent 83e6a35 commit addfcc0
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 61 deletions.
57 changes: 35 additions & 22 deletions packages/antd/src/select-table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { SearchProps } from 'antd/lib/input'
import { useFilterOptions } from './useFilterOptions'
import { useFlatOptions } from './useFlatOptions'
import { useSize } from './useSize'
import { useTitleAddon } from './useTitleAddon'
import { useCheckSlackly } from './useCheckSlackly'
import { getUISelected, getOutputData } from './utils'
import { usePrefixCls } from '../__builtins__'
Expand Down Expand Up @@ -115,19 +116,6 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
dataSource = isFn(rowKey)
? addPrimaryKey(dataSource, rowKey, primaryKey)
: dataSource
const flatDataSource = useFlatOptions(dataSource)

// selected keys for Table UI
const selected = getUISelected(
value,
flatDataSource,
primaryKey,
valueType,
optionAsValue,
mode,
rowSelection?.checkStrictly,
rowKey
)

// Filter dataSource By Search
const filteredDataSource = useFilterOptions(
Expand All @@ -144,13 +132,25 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
return [...filteredDataSource].sort((a, b) => filterSort(a, b))
}, [filteredDataSource, filterSort])

const flatDataSource = useFlatOptions(dataSource)

// selected keys for Table UI
const selected = getUISelected(
value,
flatDataSource,
primaryKey,
valueType,
optionAsValue,
mode,
rowSelection?.checkStrictly,
rowKey
)

// readPretty Value
const readPrettyDataSource = useMemo(
() =>
orderedFilteredDataSource?.filter((item) =>
selected?.includes(item?.[primaryKey])
),
[orderedFilteredDataSource, selected, primaryKey]
const readPrettyDataSource = useFilterOptions(
orderedFilteredDataSource,
selected,
(value, item) => value.includes(item[primaryKey])
)

const onInnerSearch = (searchText) => {
Expand All @@ -177,7 +177,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
}

const onRowClick = (record) => {
if (disabled || readOnly || record?.disabled) {
if (readPretty || disabled || readOnly || record?.disabled) {
return
}
const selectedRowKey = record?.[primaryKey]
Expand All @@ -204,7 +204,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
}
}

// Antd TreeData SlacklyChange for onRowClick
// TreeData SlacklyChange
const onSlacklyChange = (currentSelected: any[]) => {
let { selectedRowKeys, records } = useCheckSlackly(
currentSelected,
Expand All @@ -215,12 +215,23 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
onInnerChange(selectedRowKeys, records)
}

// Table All Checkbox
const titleAddon = useTitleAddon(
selected,
useFlatOptions(filteredDataSource),
primaryKey,
mode,
disabled,
readOnly,
onInnerChange
)

// Antd rowSelection type
const modeAsType: any = { multiple: 'checkbox', single: 'radio' }?.[mode]

return (
<div className={prefixCls}>
{showSearch && !readPretty ? (
{showSearch ? (
<Search
{...searchProps}
className={cls(`${prefixCls}-search`, searchProps?.className)}
Expand All @@ -244,6 +255,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
? undefined
: {
...rowSelection,
...titleAddon,
getCheckboxProps: (record) => ({
...(rowSelection?.getCheckboxProps?.(record) as any),
disabled: disabled || record?.disabled,
Expand Down Expand Up @@ -281,6 +293,7 @@ SelectTable.Column = TableColumn

SelectTable.defaultProps = {
showSearch: false,
valueType: 'all',
primaryKey: 'key',
mode: 'multiple',
}
Expand Down
8 changes: 5 additions & 3 deletions packages/antd/src/select-table/useFilterOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ function includesOption(option: any, search: string) {
const _includesOption = (option: any) => {
const keys = Object.keys(option || {})
return keys.some((key) => {
if (key === '__level') {
return false
}
const value = option[key]
if (React.isValidElement(value)) return false
if (key !== 'children' && !searched.has(value)) {
Expand All @@ -36,17 +39,16 @@ function toArray<T>(value: T | T[]): T[] {

const useFilterOptions = (
options: any[],
searchValue?: string,
searchValue?: string | string[],
filterOption?: IFilterOption
) =>
React.useMemo(() => {
if (!searchValue || filterOption === false) {
return options
}
const upperSearch = searchValue.toUpperCase()
const filterFunc = isFn(filterOption)
? filterOption
: (_: string, option: any) => includesOption(option, upperSearch)
: (value: any, option: any) => includesOption(option, value.toUpperCase())

const doFilter = (arr: any[]) => {
const filterArr: any[] = []
Expand Down
71 changes: 71 additions & 0 deletions packages/antd/src/select-table/useTitleAddon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react'
import { Checkbox } from 'antd'

// 重写表格表头Checkbox
const newCheckbox =
(
selected,
filteredFlatDataSource,
primaryKey,
disabled,
readOnly,
onChange
) =>
() => {
const currentDataSource = filteredFlatDataSource.filter(
(item) => !item.disabled
)
const currentDataSourceKeys = currentDataSource.map(
(item) => item?.[primaryKey]
)
const currentSelected = selected.filter((item) =>
currentDataSourceKeys.includes(item)
)
const indeterminate = !!(
currentSelected?.length &&
currentSelected.length !== currentDataSource.length
)
return (
<Checkbox
key="titleAddons"
checked={!!currentSelected?.length}
disabled={disabled}
indeterminate={indeterminate}
onChange={(e) => {
if (!readOnly) {
if (e.target.checked || indeterminate) {
onChange?.(currentDataSourceKeys, currentDataSource)
} else {
onChange?.([], [])
}
}
}}
/>
)
}

const useTitleAddon = (
selected: any[],
filteredFlatDataSource: any[],
primaryKey: string,
mode: string,
disabled: boolean,
readOnly: boolean,
onChange: (selectedRowKeys: any[], record: any[]) => any
) => {
if (mode === 'single') {
return {}
}
return {
columnTitle: newCheckbox(
selected,
filteredFlatDataSource,
primaryKey,
disabled,
readOnly,
onChange
),
}
}

export { useTitleAddon }
49 changes: 24 additions & 25 deletions packages/next/src/select-table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,19 +118,6 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
dataSource = isFn(rowKey)
? addPrimaryKey(dataSource, rowKey, primaryKey)
: dataSource
const flatDataSource = useFlatOptions(dataSource)

// selected keys for Table UI
const selected = getUISelected(
value,
flatDataSource,
primaryKey,
valueType,
optionAsValue,
mode,
rowSelection?.checkStrictly,
rowKey
)

// Filter dataSource By Search
const filteredDataSource = useFilterOptions(
Expand All @@ -147,13 +134,25 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
return [...filteredDataSource].sort((a, b) => filterSort(a, b))
}, [filteredDataSource, filterSort])

const flatDataSource = useFlatOptions(dataSource)

// selected keys for Table UI
const selected = getUISelected(
value,
flatDataSource,
primaryKey,
valueType,
optionAsValue,
mode,
rowSelection?.checkStrictly,
rowKey
)

// readPretty Value
const readPrettyDataSource = useMemo(
() =>
orderedFilteredDataSource?.filter((item) =>
selected?.includes(item?.[primaryKey])
),
[orderedFilteredDataSource, selected, primaryKey]
const readPrettyDataSource = useFilterOptions(
orderedFilteredDataSource,
selected,
(value, item) => value.includes(item[primaryKey])
)

const onInnerSearch = (searchText) => {
Expand All @@ -180,7 +179,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
}

const onRowClick = (record) => {
if (disabled || readOnly || record?.disabled) {
if (readPretty || disabled || readOnly || record?.disabled) {
return
}
const selectedRowKey = record?.[primaryKey]
Expand All @@ -207,7 +206,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
}
}

// Fusion TreeData SlacklyChange
// TreeData SlacklyChange
const onSlacklyChange = (currentSelected: any[]) => {
let { selectedRowKeys, records } = useCheckSlackly(
currentSelected,
Expand All @@ -218,10 +217,10 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
onInnerChange(selectedRowKeys, records)
}

// Fusion Table Checkbox
// Table All Checkbox
const titleAddon = useTitleAddon(
selected,
flatDataSource,
useFlatOptions(filteredDataSource),
primaryKey,
mode,
disabled,
Expand All @@ -231,7 +230,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {

return (
<div className={prefixCls}>
{showSearch && !readPretty ? (
{showSearch ? (
<Search
{...searchProps}
className={cls(`${prefixCls}-search`, searchProps?.className)}
Expand All @@ -255,6 +254,7 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
? undefined
: {
...rowSelection,
...titleAddon,
getProps: (record, index) => ({
...(rowSelection?.getProps?.(record, index) as any),
indeterminate: getIndeterminate(record, selected, primaryKey), // 父子关联模式indeterminate值
Expand All @@ -266,7 +266,6 @@ export const SelectTable: ComposedSelectTable = observer((props) => {
? onInnerChange
: onSlacklyChange,
mode,
...titleAddon,
}
}
columns={props.columns || columns}
Expand Down
9 changes: 6 additions & 3 deletions packages/next/src/select-table/useFilterOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ function includesOption(option: any, search: string) {
const _includesOption = (option: any) => {
const keys = Object.keys(option || {})
return keys.some((key) => {
if (key === '__level') {
return false
}
const value = option[key]
if (React.isValidElement(value)) return false
if (key !== 'children' && !searched.has(value)) {
Expand All @@ -21,6 +24,7 @@ function includesOption(option: any, search: string) {
}
return includes(value, search)
}
return false
})
}
return _includesOption(option)
Expand All @@ -35,17 +39,16 @@ function toArray<T>(value: T | T[]): T[] {

const useFilterOptions = (
options: any[],
searchValue?: string,
searchValue?: string | string[],
filterOption?: IFilterOption
) =>
React.useMemo(() => {
if (!searchValue || filterOption === false) {
return options
}
const upperSearch = searchValue.toUpperCase()
const filterFunc = isFn(filterOption)
? filterOption
: (_: string, option: any) => includesOption(option, upperSearch)
: (value: any, option: any) => includesOption(option, value.toUpperCase())

const doFilter = (arr: any[]) => {
const filterArr: any[] = []
Expand Down
Loading

0 comments on commit addfcc0

Please sign in to comment.