Skip to content

Commit

Permalink
feat(pro:search): support concludeAllSelected for select field (#1726)
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 committed Oct 30, 2023
1 parent 8120fdf commit 5e4c7e1
Show file tree
Hide file tree
Showing 11 changed files with 54 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/pro/locales/src/langs/en-US.ts
Expand Up @@ -41,6 +41,7 @@ const enUS: ProLocale = {
ok: 'OK',
cancel: 'Cancel',
selectAll: 'Select All',
allSelected: 'All',
placeholder: 'Select filters and press Enter',
switchToDatePanel: 'Select Date',
switchToTimePanel: 'Select Time',
Expand Down
1 change: 1 addition & 0 deletions packages/pro/locales/src/langs/zh-CN.ts
Expand Up @@ -41,6 +41,7 @@ const zhCN: ProLocale = {
ok: '确定',
cancel: '取消',
selectAll: '全选',
allSelected: '全部',
placeholder: '点击选择筛选条件, 按回车键确认',
switchToDatePanel: '切换日期选择',
switchToTimePanel: '切换时间选择',
Expand Down
1 change: 1 addition & 0 deletions packages/pro/locales/src/types.ts
Expand Up @@ -37,6 +37,7 @@ export interface ProSearchLocale {
ok: string
cancel: string
selectAll: string
allSelected: string
placeholder: string
switchToTimePanel: string
switchToDatePanel: string
Expand Down
2 changes: 2 additions & 0 deletions packages/pro/search/demo/Basic.vue
Expand Up @@ -74,6 +74,8 @@ const searchFields: SearchField[] = [
fieldConfig: {
multiple: true,
searchable: true,
showSelectAll: true,
concludeAllSelected: true,
dataSource: [
{
key: 'fatal',
Expand Down
2 changes: 2 additions & 0 deletions packages/pro/search/demo/RemoteSearch.vue
Expand Up @@ -110,6 +110,8 @@ const searchFields = computed<SearchField[]>(() => [
fieldConfig: {
multiple: true,
searchable: true,
showSelectAll: true,
concludeAllSelected: true,
dataSource: selectData.value,
virtual: true,
searchFn: () => true,
Expand Down
1 change: 1 addition & 0 deletions packages/pro/search/docs/Api.zh.md
Expand Up @@ -119,6 +119,7 @@ SelectSearchFieldConfig
| `searchFn` | 搜索函数 | `(data: SelectPanelData, searchText: string) => boolean` | - | - | 默认模糊匹配 |
| `separator` | 多选分隔符 | `string` | `'|'` | - | - |
| `showSelectAll` | 是否支持全选 | `boolean` | `true` | - | - |
| `concludeAllSelected` | 是否在值被全选时显示 "全部" | `boolean` | - | - | - |
| `virtual` | 是否支持虚拟滚动 | `boolean` | `false` | - | 默认不支持 |
| `onSearch` | 搜索回调函数 | `(searchValue: string) => void | ((searchValue: string) => void)[]` | - | - | 在触发搜索值改变时执行 |

Expand Down
7 changes: 6 additions & 1 deletion packages/pro/search/src/ProSearch.tsx
Expand Up @@ -55,7 +55,12 @@ export default defineComponent({

const searchValueContext = useSearchValues(props)
const { searchValues } = searchValueContext
const resolvedSearchFieldsContext = useResolvedSearchFields(searchFields, mergedPrefixCls, dateConfig)
const resolvedSearchFieldsContext = useResolvedSearchFields(
searchFields,
mergedPrefixCls,
dateConfig,
locale.search,
)
const { fieldKeyMap } = resolvedSearchFieldsContext
const searchStateContext = useSearchStates(props, fieldKeyMap, searchValueContext)
const { searchStates, initSearchStates, clearSearchState, updateSearchValues, isSegmentVisible } =
Expand Down
13 changes: 10 additions & 3 deletions packages/pro/search/src/composables/useResolvedSearchFields.ts
Expand Up @@ -8,6 +8,7 @@
import type { ResolvedSearchField, SearchField, Segment } from '../types'
import type { VKey } from '@idux/cdk/utils'
import type { DateConfig } from '@idux/components/config'
import type { ProSearchLocale } from '@idux/pro/locales'

import { type ComputedRef, computed } from 'vue'

Expand All @@ -29,6 +30,7 @@ export function useResolvedSearchFields(
searchFields: ComputedRef<SearchField[]>,
mergedPrefixCls: ComputedRef<string>,
dateConfig: DateConfig,
locale: ProSearchLocale,
): ResolvedSearchFieldsContext {
const resolvedSearchFields = computed(
() =>
Expand All @@ -37,7 +39,7 @@ export function useResolvedSearchFields(
...searchField,
segments: [
createOperatorSegment(mergedPrefixCls.value, searchField),
...createSearchItemContentSegments(mergedPrefixCls.value, searchField, dateConfig),
...createSearchItemContentSegments(mergedPrefixCls.value, searchField, dateConfig, locale),
].filter(Boolean) as Segment[],
}
}) ?? [],
Expand All @@ -58,7 +60,12 @@ export function useResolvedSearchFields(
}
}

function createSearchItemContentSegments(prefixCls: string, searchField: SearchField, dateConfig: DateConfig) {
function createSearchItemContentSegments(
prefixCls: string,
searchField: SearchField,
dateConfig: DateConfig,
locale: ProSearchLocale,
) {
if (searchField.type === 'multiSegment') {
return searchField.fieldConfig.segments.map(segmentConfig =>
createCustomSegment(prefixCls, dateConfig, segmentConfig),
Expand All @@ -68,7 +75,7 @@ function createSearchItemContentSegments(prefixCls: string, searchField: SearchF
const segment = (() => {
switch (searchField.type) {
case 'select':
return createSelectSegment(prefixCls, searchField.fieldConfig)
return createSelectSegment(prefixCls, searchField.fieldConfig, locale)
case 'treeSelect':
return createTreeSelectSegment(prefixCls, searchField.fieldConfig)
case 'cascader':
Expand Down
33 changes: 26 additions & 7 deletions packages/pro/search/src/segments/CreateSelectSegment.tsx
Expand Up @@ -6,6 +6,7 @@
*/

import type { PanelRenderContext, Segment, SelectPanelData, SelectSearchField } from '../types'
import type { ProSearchLocale } from '@idux/pro/locales'

import { isNil, toString } from 'lodash-es'

Expand All @@ -19,6 +20,7 @@ const defaultSeparator = '|'
export function createSelectSegment(
prefixCls: string,
config: SelectSearchField['fieldConfig'],
locale: ProSearchLocale,
): Segment<VKey | VKey[] | undefined> {
const { dataSource, separator, searchable, showSelectAll, searchFn, multiple, virtual, onSearch } = config

Expand Down Expand Up @@ -64,27 +66,44 @@ export function createSelectSegment(
name: 'select',
inputClassName: [`${prefixCls}-select-segment-input`],
containerClassName: [`${prefixCls}-select-segment-container`],
parse: input => parseInput(input, config),
format: value => formatValue(value, config),
parse: input => parseInput(input, config, locale.allSelected),
format: value => formatValue(value, config, locale.allSelected),
panelRenderer,
}
}

function parseInput(input: string, config: SelectSearchField['fieldConfig']): VKey | VKey[] | undefined {
const { separator, dataSource, multiple } = config
function parseInput(
input: string,
config: SelectSearchField['fieldConfig'],
allSelected: string,
): VKey | VKey[] | undefined {
const { concludeAllSelected, separator, dataSource, multiple } = config
const trimedInput = input.trim()

const keys = getKeyByLabels(dataSource, trimedInput.split(separator ?? defaultSeparator))
const keys =
concludeAllSelected && trimedInput === allSelected
? dataSource.map(data => data.key)
: getKeyByLabels(dataSource, trimedInput.split(separator ?? defaultSeparator))

return multiple ? (keys.length > 0 ? keys : undefined) : keys[0]
}

function formatValue(value: VKey | VKey[] | undefined, config: SelectSearchField['fieldConfig']): string {
const { dataSource, separator } = config
function formatValue(
value: VKey | VKey[] | undefined,
config: SelectSearchField['fieldConfig'],
allSelected: string,
): string {
const { concludeAllSelected, dataSource, separator } = config
if (isNil(value)) {
return ''
}

const values = convertArray(value)

if (concludeAllSelected && values.length > 0 && values.length >= dataSource.length) {
return allSelected
}

return getLabelByKeys(dataSource, convertArray(value)).join(` ${separator ?? defaultSeparator} `)
}

Expand Down
1 change: 1 addition & 0 deletions packages/pro/search/src/types/searchFields.ts
Expand Up @@ -52,6 +52,7 @@ interface ResolvedSearchFieldBase<V = unknown> extends SearchFieldBase<V> {
interface SelectSearchFieldBase {
type: 'select'
fieldConfig: {
concludeAllSelected?: boolean
dataSource: SelectPanelData[]
multiple?: boolean
searchable?: boolean
Expand Down
3 changes: 3 additions & 0 deletions packages/pro/search/src/useParser.ts
Expand Up @@ -11,6 +11,7 @@ import type { VKey } from '@idux/cdk/utils'
import { type Ref, computed } from 'vue'

import { useDateConfig } from '@idux/components/config'
import { useGlobalConfig } from '@idux/pro/config'

import { useResolvedSearchFields } from './composables/useResolvedSearchFields'
import { generateSegmentStates } from './utils'
Expand All @@ -27,10 +28,12 @@ export interface ParserContext {

export function useParser(searchFields: Ref<SearchField[]> | SearchField[]): ParserContext {
const dateConfig = useDateConfig()
const locales = useGlobalConfig('locale')
const { fieldKeyMap } = useResolvedSearchFields(
computed(() => ('value' in searchFields ? searchFields.value : searchFields)),
computed(() => '__pro-search-parser__'),
dateConfig,
locales.search,
)

const parse = (searchValues: SearchValue[]) => {
Expand Down

0 comments on commit 5e4c7e1

Please sign in to comment.