diff --git a/packages/pro/locales/src/langs/en-US.ts b/packages/pro/locales/src/langs/en-US.ts index 6c360ae04..5f9f8582b 100644 --- a/packages/pro/locales/src/langs/en-US.ts +++ b/packages/pro/locales/src/langs/en-US.ts @@ -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', diff --git a/packages/pro/locales/src/langs/zh-CN.ts b/packages/pro/locales/src/langs/zh-CN.ts index fc7b76f69..bf07c8d86 100644 --- a/packages/pro/locales/src/langs/zh-CN.ts +++ b/packages/pro/locales/src/langs/zh-CN.ts @@ -41,6 +41,7 @@ const zhCN: ProLocale = { ok: '确定', cancel: '取消', selectAll: '全选', + allSelected: '全部', placeholder: '点击选择筛选条件, 按回车键确认', switchToDatePanel: '切换日期选择', switchToTimePanel: '切换时间选择', diff --git a/packages/pro/locales/src/types.ts b/packages/pro/locales/src/types.ts index 1e2fe5ba2..35bf94456 100644 --- a/packages/pro/locales/src/types.ts +++ b/packages/pro/locales/src/types.ts @@ -37,6 +37,7 @@ export interface ProSearchLocale { ok: string cancel: string selectAll: string + allSelected: string placeholder: string switchToTimePanel: string switchToDatePanel: string diff --git a/packages/pro/search/demo/Basic.vue b/packages/pro/search/demo/Basic.vue index 5a12869fe..5f97e67e8 100644 --- a/packages/pro/search/demo/Basic.vue +++ b/packages/pro/search/demo/Basic.vue @@ -74,6 +74,8 @@ const searchFields: SearchField[] = [ fieldConfig: { multiple: true, searchable: true, + showSelectAll: true, + concludeAllSelected: true, dataSource: [ { key: 'fatal', diff --git a/packages/pro/search/demo/RemoteSearch.vue b/packages/pro/search/demo/RemoteSearch.vue index 9629f82fa..1e01c73c4 100644 --- a/packages/pro/search/demo/RemoteSearch.vue +++ b/packages/pro/search/demo/RemoteSearch.vue @@ -110,6 +110,8 @@ const searchFields = computed(() => [ fieldConfig: { multiple: true, searchable: true, + showSelectAll: true, + concludeAllSelected: true, dataSource: selectData.value, virtual: true, searchFn: () => true, diff --git a/packages/pro/search/docs/Api.zh.md b/packages/pro/search/docs/Api.zh.md index f361cfaf5..351505123 100644 --- a/packages/pro/search/docs/Api.zh.md +++ b/packages/pro/search/docs/Api.zh.md @@ -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)[]` | - | - | 在触发搜索值改变时执行 | diff --git a/packages/pro/search/src/ProSearch.tsx b/packages/pro/search/src/ProSearch.tsx index 74cc0948c..ae939429f 100644 --- a/packages/pro/search/src/ProSearch.tsx +++ b/packages/pro/search/src/ProSearch.tsx @@ -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 } = diff --git a/packages/pro/search/src/composables/useResolvedSearchFields.ts b/packages/pro/search/src/composables/useResolvedSearchFields.ts index 70b33f8b2..6c119d96e 100644 --- a/packages/pro/search/src/composables/useResolvedSearchFields.ts +++ b/packages/pro/search/src/composables/useResolvedSearchFields.ts @@ -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' @@ -29,6 +30,7 @@ export function useResolvedSearchFields( searchFields: ComputedRef, mergedPrefixCls: ComputedRef, dateConfig: DateConfig, + locale: ProSearchLocale, ): ResolvedSearchFieldsContext { const resolvedSearchFields = computed( () => @@ -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[], } }) ?? [], @@ -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), @@ -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': diff --git a/packages/pro/search/src/segments/CreateSelectSegment.tsx b/packages/pro/search/src/segments/CreateSelectSegment.tsx index 5013fa0b4..0a3b1377f 100644 --- a/packages/pro/search/src/segments/CreateSelectSegment.tsx +++ b/packages/pro/search/src/segments/CreateSelectSegment.tsx @@ -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' @@ -19,6 +20,7 @@ const defaultSeparator = '|' export function createSelectSegment( prefixCls: string, config: SelectSearchField['fieldConfig'], + locale: ProSearchLocale, ): Segment { const { dataSource, separator, searchable, showSelectAll, searchFn, multiple, virtual, onSearch } = config @@ -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} `) } diff --git a/packages/pro/search/src/types/searchFields.ts b/packages/pro/search/src/types/searchFields.ts index 28ee0d84c..77d521aec 100644 --- a/packages/pro/search/src/types/searchFields.ts +++ b/packages/pro/search/src/types/searchFields.ts @@ -52,6 +52,7 @@ interface ResolvedSearchFieldBase extends SearchFieldBase { interface SelectSearchFieldBase { type: 'select' fieldConfig: { + concludeAllSelected?: boolean dataSource: SelectPanelData[] multiple?: boolean searchable?: boolean diff --git a/packages/pro/search/src/useParser.ts b/packages/pro/search/src/useParser.ts index 7adec45d0..f30582e51 100644 --- a/packages/pro/search/src/useParser.ts +++ b/packages/pro/search/src/useParser.ts @@ -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' @@ -27,10 +28,12 @@ export interface ParserContext { export function useParser(searchFields: Ref | 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[]) => {