From 7ebabe1964fd4e4cbc5ee59a849aa838506f8aa7 Mon Sep 17 00:00:00 2001 From: maxin <48519459+nnmax@users.noreply.github.com> Date: Thu, 2 Dec 2021 19:07:04 +0800 Subject: [PATCH] feat(filterpicker): support i18n in the FilterPicker (#1592) Co-authored-by: maxin --- src/legacy/filter-picker/FilterPicker.tsx | 8 +- .../FilterCondition/FilterAttrOverlay.tsx | 39 ++- .../FilterCondition/attrSelect.less | 2 +- .../components/RelativeBetween.tsx | 94 +++++-- .../components/RelativeCurrent.tsx | 76 ++++-- .../components/NumberAttrSelect.tsx | 10 +- .../components/StringAttrSelect/InOrNotIn.tsx | 12 +- .../components/StringAttrSelect/index.tsx | 6 +- .../Expression/FilterCondition/index.tsx | 12 +- .../Expression/FilterCondition/interfaces.ts | 166 ++++++++++++ .../Expression/FilterCondition/utils/index.ts | 251 ++++++++++-------- .../FilterList/Expression/index.tsx | 11 +- .../components/FilterList/index.tsx | 16 +- .../components/FilterOverlay/index.tsx | 6 +- .../filter-picker/components/Footer/index.tsx | 8 +- src/legacy/filter-picker/filterMap.ts | 208 --------------- src/legacy/filter-picker/index.ts | 12 + src/legacy/filter-picker/locales/en-US.ts | 43 ++- src/legacy/filter-picker/locales/zh-CN.ts | 41 ++- 19 files changed, 612 insertions(+), 409 deletions(-) delete mode 100644 src/legacy/filter-picker/filterMap.ts diff --git a/src/legacy/filter-picker/FilterPicker.tsx b/src/legacy/filter-picker/FilterPicker.tsx index 863b997168..3f937e6117 100644 --- a/src/legacy/filter-picker/FilterPicker.tsx +++ b/src/legacy/filter-picker/FilterPicker.tsx @@ -8,11 +8,13 @@ import Dropdown from '../dropdown'; import defaultLocaleTextObject from './locales/zh-CN'; import './style'; +export type TextObject = typeof defaultLocaleTextObject & { code: 'zh-CN' | 'en-US' }; + export const FilterPickerContext = React.createContext< Pick & { - textObject: typeof defaultLocaleTextObject; + textObject: TextObject; } ->({ textObject: defaultLocaleTextObject }); +>({ textObject: { ...defaultLocaleTextObject, code: 'zh-CN' } }); const defaultOperationsOption: operationsOptionType = { string: ['=', '!=', 'in', 'not in', 'like', 'not like', 'hasValue', 'noValue'], @@ -41,7 +43,7 @@ const FilterPicker = (props: FilterPickerProps) => { disabled, } = props; - const localeTextObject: typeof defaultLocaleTextObject = useLocale('FilterPicker'); + const localeTextObject: TextObject = useLocale('FilterPicker'); const textObject = useMemo(() => ({ ...defaultLocaleTextObject, ...localeTextObject }), [localeTextObject]); const [localVisible, setLocalVisible] = useState(false); diff --git a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/FilterAttrOverlay.tsx b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/FilterAttrOverlay.tsx index ff84bb71cd..ae2048fb6e 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/FilterAttrOverlay.tsx +++ b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/FilterAttrOverlay.tsx @@ -1,15 +1,23 @@ -import React, { useEffect, useState } from 'react'; -import { titleMap, selectOptionMap, AttributeMap } from '../../../../filterMap'; +import React, { useContext, useEffect, useState } from 'react'; import NumberAttrSelect from './components/NumberAttrSelect'; import DateAttrSelect from './components/DateAttrSelect'; import StringAttrSelect from './components/StringAttrSelect/index'; import Footer from '../../../Footer'; import './attrSelect.less'; -import { attributeValue, StringValue, NumberValue, DateValue, FilterValueType } from './interfaces'; -import { operationsOptionType } from '../../../../interfaces'; +import { + attributeValue, + StringValue, + NumberValue, + DateValue, + FilterValueType, + useSelectOptions, + AttributeMap, +} from './interfaces'; +import { operationsOptionType, titleGroup } from '../../../../interfaces'; import Checkbox from '../../../../../../checkbox'; // new import Select from '../../../../../../select'; // new import Divider from '../../../../../../divider'; +import { FilterPickerContext } from '../../../../FilterPicker'; interface FilterAttrOverlayProps { valueType: attributeValue; @@ -24,15 +32,24 @@ interface FilterAttrOverlayProps { } function FilterAttrOverlay(props: FilterAttrOverlayProps) { + const { textObject: t } = useContext(FilterPickerContext); + const selectOptions = useSelectOptions(); const { valueType, onSubmit, onCancel, op, curryDimensionValueRequest, values, exprKey, operationsOption, numType } = props; const [operationValue, setOperationValue] = useState(op); const [attrValue, setAttrValue] = useState(values); const [checked, setChecked] = useState(valueType === 'date' && (op === '>=' || op === '<=')); + const titleMap: titleGroup = { + string: t.string, + STRING: t.string, + int: t.int, + date: t.date, + }; + useEffect(() => { if (valueType === 'date') { - // 此处是为了处理,日期类型时,包含当天,选项('>=', '<=')不在selectOptionMap里面 + // 此处是为了处理,日期类型时,包含当天,选项('>=', '<=')不在 selectOptions 里面 if (op === '>=') { setOperationValue('>'); } else if (op === '<=') { @@ -53,7 +70,7 @@ function FilterAttrOverlay(props: FilterAttrOverlayProps) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [op, valueType]); - const handleChange = (e: any) => { + const handleChange = (e: React.ChangeEvent) => { setChecked(e.target.checked); }; @@ -146,25 +163,25 @@ function FilterAttrOverlay(props: FilterAttrOverlayProps) { return (
-
{titleMap[valueType] || '字符串类型'}
+
{titleMap[valueType] || t.string}
+ +
{t.to}
+
+
+ +
{`${t.day}`}
+
+ + ); + } + return ( <>
+ + // eslint-disable-next-line camelcase + const zh_RelativeSelect = ( + <> + ) : ( + ) : ( + + +
{t.day}
+ + ); + + return ( +
+ {/* eslint-disable-next-line camelcase */} + {t.code === 'en-US' ? en_RelativeSelect : zh_RelativeSelect}
); } diff --git a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/NumberAttrSelect.tsx b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/NumberAttrSelect.tsx index 62d0fc7972..618e8cda95 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/NumberAttrSelect.tsx +++ b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/NumberAttrSelect.tsx @@ -1,5 +1,6 @@ -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useContext } from 'react'; import Input from '../../../../../../../input'; // new +import { FilterPickerContext } from '../../../../../FilterPicker'; interface NumberAttrSelectProps { attrSelect: string; @@ -8,6 +9,7 @@ interface NumberAttrSelectProps { type?: 'positivedecimal' | 'decimal'; } function NumberAttrSelect(props: NumberAttrSelectProps) { + const { textObject: t } = useContext(FilterPickerContext); const { attrSelect, attrChange, values, type } = props; const [value, setValue] = useState(values?.[0] ? parseFloat(values?.[0]) : 0); const [value1, setValue1] = useState(values?.[0] ? parseFloat(values?.[0]) : 0); @@ -92,9 +94,9 @@ function NumberAttrSelect(props: NumberAttrSelectProps) { case 'not between': return (
- -
- + +
{t.and}
+
); case 'hasValue': diff --git a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/StringAttrSelect/InOrNotIn.tsx b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/StringAttrSelect/InOrNotIn.tsx index 27f15c3d50..ad6776048c 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/StringAttrSelect/InOrNotIn.tsx +++ b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/components/StringAttrSelect/InOrNotIn.tsx @@ -1,8 +1,9 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import Input from '../../../../../../../../input'; // new import List from '../../../../../../../list-pro'; import Loading from '../../../../../../../../loading'; // new import { attributeValue } from '../../interfaces'; +import { FilterPickerContext } from '../../../../../../FilterPicker'; interface StringAttrSelectProps { valueType: attributeValue; @@ -21,6 +22,7 @@ type checkOptionsItem = { let timer: any = null; function StringAttrSelect(props: StringAttrSelectProps) { + const { textObject: t } = useContext(FilterPickerContext); const { valueType, curryDimensionValueRequest, attrChange, values = [], exprKey, attrSelect } = props; const [inputValue, setInputValue] = useState(''); const [checkValue, setCheckValue] = useState(values); @@ -56,7 +58,7 @@ function StringAttrSelect(props: StringAttrSelectProps) { setInputCheckList(checkList); setCheckOptions( checkList.map((ele: string) => ({ - label: `自由输入:${ele}`, + label: `${t.freeInput}${ele}`, value: ele, })) ); @@ -76,7 +78,7 @@ function StringAttrSelect(props: StringAttrSelectProps) { // 所有的自由输入选项 ...inputCheckList .filter((ele: string) => checkList.includes(ele)) - .map((ele: string) => ({ label: `自由输入:${ele}`, value: ele })), + .map((ele: string) => ({ label: `${t.freeInput}${ele}`, value: ele })), // 已选中的,过滤掉自由输入的选项 ...Array.from(new Set([...filterCheckedList, ...res])).map((ele: string) => ({ label: ele, value: ele })), ]); @@ -85,7 +87,7 @@ function StringAttrSelect(props: StringAttrSelectProps) { // 所有的自由输入选项 ...inputCheckList .filter((ele: string) => checkList.includes(ele)) - .map((ele: string) => ({ label: `自由输入:${ele}`, value: ele })), + .map((ele: string) => ({ label: `${t.freeInput}${ele}`, value: ele })), ]); } setLoadingStatue(false); @@ -123,7 +125,7 @@ function StringAttrSelect(props: StringAttrSelectProps) { return (
- + {loadingStatue ? (
(values.join(',')); const [listOptions, setListOptions] = useState([]); @@ -99,7 +101,7 @@ function StringAttrSelect(props: StringAttrSelectProps) { default: return (
- + {loadingStatue ? (
(() => parseValuesToText(valueType, op, values), [valueType, op, values]); + const { textObject: t } = useContext(FilterPickerContext); + const conditionText = useMemo( + () => parseValuesToText(valueType, op, values, textObject), + [valueType, op, values, textObject] + ); const visibleChange = (v: boolean) => { setVisible(v); }; @@ -76,7 +82,7 @@ function FilterCondition(props: FilterConditionProps) { document.body} placement="topLeft" > diff --git a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/interfaces.ts b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/interfaces.ts index d6dfaa35ef..4accfd83c8 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/interfaces.ts +++ b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/interfaces.ts @@ -1,3 +1,15 @@ +import { useContext, useMemo } from 'react'; +import { listFormat } from '../../../..'; +import { FilterPickerContext } from '../../../../FilterPicker'; +import { selectOption } from '../../../../interfaces'; + +export enum AttributeMap { + string = 'string', + int = 'int', + date = 'date', + STRING = 'STRING', +} + export type StringValue = '=' | '!=' | '<' | '>' | 'in' | 'not in' | 'like' | 'not like' | 'hasValue' | 'noValue'; export type NumberValue = '=' | '!=' | '>' | '>=' | '<' | '<=' | 'between' | 'hasValue'; export type DateValue = @@ -26,3 +38,157 @@ export type FilterValue = { op: string; exprs: FilterValueType[]; }; + +export const useSelectOptions = () => { + const { textObject: t } = useContext(FilterPickerContext); + return useMemo( + () => ({ + string: [ + { + value: '=', + label: t['='], + }, + { + value: '!=', + label: t['!='], + }, + { + value: 'in', + label: t.in('...'), + }, + { + value: 'not in', + label: t.notIn('...'), + }, + { + value: 'like', + label: t.like, + }, + { + value: 'not like', + label: t.notLike, + }, + { + value: 'hasValue', + label: t.hasValue, + }, + { + value: 'noValue', + label: t.noValue, + }, + ], + // Tag类型 + STRING: [ + { + value: '=', + label: t['='], + }, + { + value: '!=', + label: t['!='], + }, + { + value: 'in', + label: t.in('...'), + }, + { + value: 'not in', + label: t.notIn('...'), + }, + { + value: 'like', + label: t.like, + }, + { + value: 'not like', + label: t.notLike, + }, + ], + int: [ + { + value: '=', + label: t['='], + }, + { + value: '!=', + label: t['!='], + }, + { + value: '>', + label: t['>'], + }, + { + value: '>=', + label: t['>='], + }, + { + value: '<', + label: t['<'], + }, + { + value: '<=', + label: t['<='], + }, + { + value: 'between', + label: t.between(listFormat(['...', '...'], t.code)), + }, + { + value: 'not between', + label: t.notBetween(listFormat(['...', '...'], t.code)), + }, + { + value: 'hasValue', + label: t.hasValue, + }, + { + value: 'noValue', + label: t.noValue, + }, + ], + date: [ + { + value: '=', + label: t['='], + }, + { + value: '!=', + label: t['!='], + }, + { + value: '<', + label: t.somedayAgo(t.someday), + }, + { + value: '>', + label: t.somedayAfter(t.someday), + }, + { + value: 'between', + label: t.between(listFormat(['...', '...'], t.code)), + }, + { + value: 'not between', + label: t.notBetween(listFormat(['...', '...'], t.code)), + }, + { + value: 'relativeCurrent', + label: t.relativeCurrent, + }, + { + value: 'relativeBetween', + label: t.relativeBetween, + }, + { + value: 'hasValue', + label: t.hasValue, + }, + { + value: 'noValue', + label: t.noValue, + }, + ], + }), + [t] + ); +}; diff --git a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/utils/index.ts b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/utils/index.ts index 12db00f21e..1088cbd2b8 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/utils/index.ts +++ b/src/legacy/filter-picker/components/FilterList/Expression/FilterCondition/utils/index.ts @@ -1,204 +1,241 @@ import moment from 'moment'; +import { listFormat } from '../../../../..'; +import { TextObject } from '../../../../../FilterPicker'; import { attributeValue } from '../interfaces'; -interface operationMapType { - string: { [key: string]: string }; - int: { [key: string]: string }; - date: { [key: string]: string }; - STRING: { [key: string]: string }; -} - -const operationMap: operationMapType = { - string: { - '=': '等于', - '!=': '不等于', - in: '在,范围内', - 'not in': '不在,范围内', - like: '包含', - 'not like': '不包含', - hasValue: '有值', - noValue: '无值', - }, - STRING: { - '=': '等于', - '!=': '不等于', - in: '在,范围内', - 'not in': '不在,范围内', - like: '包含', - 'not like': '不包含', - }, - int: { - '=': '等于', - '!=': '不等于', - '>': '大于', - '>=': '大于等于', - '<': '小于', - '<=': '小于等于', - between: '在,与,之间', - 'not between': '不在,与,之间', - noValue: '无值', - hasValue: '有值', - }, - date: { - '=': '等于', - '!=': '不等于', - '>': '在,天之后', - '>=': '在,天之后包括当天', - '<': '在,天之前', - '<=': '在,天之前包括当天', - between: '在,与,之间', - 'not between': '不在,与,之间', - relativeCurrent: '相对现在', - relativeBetween: '相对区间', - hasValue: '有值', - }, -}; - -const parseStringValuesToText = (opMap: { [key: string]: string }, operation: string, value: string[]) => { +const parseStringValuesToText = (operation: string, value: string[], t: TextObject) => { + /** + * string: { + * '=': '等于', + * '!=': '不等于', + * in: '在,范围内', + * 'not in': '不在,范围内', + * like: '包含', + * 'not like': '不包含', + * hasValue: '有值', + * noValue: '无值', + * } + * STRING: { + * '=': '等于', + * '!=': '不等于', + * in: '在,范围内', + * 'not in': '不在,范围内', + * like: '包含', + * 'not like': '不包含', + * } + */ switch (operation) { // 判断当op : ”=“ 时,是否为无值状态,如果无值,返回’有值’ case '=': { if (value[0] === ' ') { - return '无值'; + return t.noValue; } - return opMap[operation] + value[0]; + return `${t['=']} ${value[0]}`; } // 判断当op : ”!=“ 时,是否为有值状态,如果有值,返回’无值‘ case '!=': { if (value[0] === ' ') { - return '有值'; + return t.hasValue; } - return opMap[operation] + value[0]; + return `${t['!=']} ${value[0]}`; } case 'in': - case 'not in': { - const textList = opMap[operation].split(','); - return textList[0] + value.join(',') + textList[1]; - } + return t.in(listFormat(value, t.code)); + case 'not in': + return t.notIn(listFormat(value, t.code)); + case 'like': + return `${t.like} ${value[0]}`; + case 'not like': + return `${t.notLike} ${value[0]}`; + case 'hasValue': + case 'noValue': + return `${t[operation]} ${value[0]}`; default: - return opMap[operation] + value[0]; + return value[0]; } }; -const parseIntValuesToText = (opMap: { [key: string]: string }, operation: string, value: string[]) => { +const parseIntValuesToText = (operation: string, value: string[], t: TextObject) => { + /** + * int: { + * '=': '等于', + * '!=': '不等于', + * '>': '大于', + * '>=': '大于等于', + * '<': '小于', + * '<=': '小于等于', + * between: '在,与,之间', + * 'not between': '不在,与,之间', + * noValue: '无值', + * hasValue: '有值', + * } + */ switch (operation) { // 判断当op : ”!=“ 时,是否为有值状态,如果有值,返回’有值‘ case '!=': { if (value[0] === ' ') { - return '有值'; + return t.hasValue; } - return opMap[operation] + value[0]; + return `${t['!=']} ${value[0]}`; } // 判断当op : ”=“ 时,是否为无值状态,如果无值,返回’无值‘ case '=': { if (value[0] === ' ') { - return '无值'; + return t.noValue; } - return opMap[operation] + value[0]; + return `${t['=']} ${value[0]}`; } + case '>': + case '>=': + case '<': + case '<=': + return `${t[operation]} ${value[0]}`; case 'between': + return t.between(listFormat(value, t.code)); case 'not between': { - const textList = opMap[operation].split(','); - // 返回 ------'在(value1)与(value2)之间' - return textList[0] + value[0] + textList[1] + value[1] + textList[2]; + return t.notBetween(listFormat(value, t.code)); } + case 'hasValue': + case 'noValue': + return `${t[operation]} ${value[0]}`; default: - return opMap[operation] + value[0]; + return value[0]; } }; -const parseDateValuesRelativeToText = (relativeTime: number[]) => { +const parseDateValuesRelativeToText = (relativeTime: number[], t: TextObject) => { if (relativeTime.length === 1) { const day = relativeTime[0]; if (day < 0) { - return `过去${Math.abs(day)}天前`; + // 过去 xxx 天前 + return t.beforeThePast(Math.abs(day)); } - return `未来${Math.abs(day)}天后`; + // 未来 xxx 天后 + return t.afterTheNext(Math.abs(day)); } if (relativeTime.includes(0)) { if (relativeTime[0]) { if (relativeTime[0] < 0) { - return `过去${Math.abs(relativeTime[0])}天内`; + // 过去 xxx 天前 + return t.withinThePast(Math.abs(relativeTime[0])); } - return `未来${Math.abs(relativeTime[0])}天内`; + // 未来 xxx 天之内 + return t.withinTheNext(Math.abs(relativeTime[0])); } if (relativeTime[1] < 0) { - return `过去${Math.abs(relativeTime[1])}天内`; + // 过去 xxx 天前 + return t.withinThePast(Math.abs(relativeTime[0])); } - return `未来${Math.abs(relativeTime[1])}天内`; + // 未来 xxx 天之内 + return t.withinTheNext(Math.abs(relativeTime[0])); } if (relativeTime[0] < 0) { - return `过去${Math.abs(relativeTime[0])}-${Math.abs(relativeTime[1])}天内`; + // 过去 xxx 天至 xxx 天之内 + return t.withinThePast(`${Math.abs(relativeTime[0])} ${t.to} ${Math.abs(relativeTime[1])}`); } - return `未来${Math.abs(relativeTime[0])}-${Math.abs(relativeTime[1])}天内`; + // 未来 xxx 天至 xxx 天之内 + return t.withinTheNext(`${Math.abs(relativeTime[0])} ${t.to} ${Math.abs(relativeTime[1])}`); }; -const parseDateValuesToText = (opMap: { [key: string]: string }, operation: string, value: string[]) => { +const parseDateValuesToText = (operation: string, value: string[], t: TextObject) => { + /** + * date: { + * '=': '等于', + * '!=': '不等于', + * '>': '在,天之后', + * '>=': '在,天之后包括当天', + * '<': '在,天之前', + * '<=': '在,天之前包括当天', + * between: '在,与,之间', + * 'not between': '不在,与,之间', + * relativeCurrent: '相对现在', + * relativeBetween: '相对区间', + * hasValue: '有值', + * } + */ switch (operation) { case '!=': { if (value[0] === ' ') { - return '有值'; + return t.hasValue; } - return opMap[operation] + moment(parseInt(value[0], 10)).format('YYYY-MM-DD'); + return `${t['!=']} ${moment(parseInt(value[0], 10)).format('YYYY-MM-DD')}`; } case '=': { if (value[0] === ' ') { - return '无值'; + return t.noValue; } - return opMap[operation] + moment(parseInt(value[0], 10)).format('YYYY-MM-DD'); + return `${t['=']} ${moment(parseInt(value[0], 10)).format('YYYY-MM-DD')}`; } case '>': + // 在 xxx 天之后 + return t.somedayAfter(moment(parseInt(value[0], 10)).format('YYYY-MM-DD')); case '>=': + // 在 xxx 天之后包括当天 + return t.somedayAfterInclude(moment(parseInt(value[0], 10)).format('YYYY-MM-DD')); case '<': - case '<=': { - const textList = opMap[operation].split(','); - return textList[0] + moment(parseInt(value[0], 10)).format('YYYY-MM-DD') + textList[1]; - } + // 在 xxx 天之前 + return t.somedayAgo(moment(parseInt(value[0], 10)).format('YYYY-MM-DD')); + // 在 xxx 天之前包括当天 + case '<=': + return t.somedayAgoInclude(moment(parseInt(value[0], 10)).format('YYYY-MM-DD')); // 判断,在。。。与。。。之间 // 返回字符串 ---- ‘在(date1)与(data2)之间’ case 'between': + if (value[0].includes('abs')) { + const abs = value?.[0].split(':')[1].split(','); + return t.between( + listFormat( + [moment(parseInt(abs[0], 10)).format('YYYY-MM-DD'), moment(parseInt(abs[1], 10)).format('YYYY-MM-DD')], + t.code + ) + ); + } + return ''; case 'not between': { - const textList = opMap[operation].split(','); if (value[0].includes('abs')) { const abs = value?.[0].split(':')[1].split(','); - return ( - textList[0] + - moment(parseInt(abs[0], 10)).format('YYYY-MM-DD') + - textList[1] + - moment(parseInt(abs[1], 10)).format('YYYY-MM-DD') + - textList[2] + return t.notBetween( + listFormat( + [moment(parseInt(abs[0], 10)).format('YYYY-MM-DD'), moment(parseInt(abs[1], 10)).format('YYYY-MM-DD')], + t.code + ) ); } - break; + return ''; } case 'relativeTime': { const relativeTime = value[0] .split(':')[1] .split(',') .map((ele: string) => parseInt(ele, 10)); - return parseDateValuesRelativeToText(relativeTime); + return parseDateValuesRelativeToText(relativeTime, t); } + case 'hasValue': + return `${t.hasValue} moment(value[0]).format('YYYY-MM-DD')`; default: - return opMap[operation] + moment(value[0]).format('YYYY-MM-DD'); + return moment(value[0]).format('YYYY-MM-DD'); } - return ''; }; // 对NumberAttrSelect,StringAttrSelect,DateAttrSelect返回的values值进行转换,生成属性选择框的属性规则展示文本 -export default function parseValuesToText(type: attributeValue, operation: string, value: string[]): string { - const opMap = operationMap[type]; +export default function parseValuesToText( + type: attributeValue, + operation: string, + value: string[], + t: TextObject +): string { if (value.length && !!value?.[0]) { if (type === 'string' || type === 'STRING') { // 字符串类型 - return parseStringValuesToText(opMap, operation, value); + return parseStringValuesToText(operation, value, t); } if (type === 'int') { - return parseIntValuesToText(opMap, operation, value); + return parseIntValuesToText(operation, value, t); } if (type === 'date') { - return parseDateValuesToText(opMap, operation, value); + return parseDateValuesToText(operation, value, t); } } - return '选择过滤条件'; + return t.selectFilter; } diff --git a/src/legacy/filter-picker/components/FilterList/Expression/index.tsx b/src/legacy/filter-picker/components/FilterList/Expression/index.tsx index 3d512992d2..f6dc034b81 100644 --- a/src/legacy/filter-picker/components/FilterList/Expression/index.tsx +++ b/src/legacy/filter-picker/components/FilterList/Expression/index.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useMemo } from 'react'; +import React, { useEffect, useState, useMemo, useContext } from 'react'; import { DeleteOutlined } from '@gio-design/icons'; import PropertySelector from '../../../../property-selector'; import FilterCondition from './FilterCondition'; @@ -20,6 +20,7 @@ interface ExpressionProps { recentlyStorePrefix: string; } function Expression(props: ExpressionProps) { + const { textObject } = useContext(FilterPickerContext); const { index = 0, filterItem, @@ -92,12 +93,10 @@ function Expression(props: ExpressionProps) { { - const inavailableOptions = exprs ? exprs.map((expr: any) => expr.key) : []; - return option.id === exprKey || inavailableOptions.indexOf(option.id) === -1; // && !(/like/.test(operator) && option.id === 'cs1')saas老逻辑,暂时不需要 - })} + dataSource={propertyOptions} + disabledValues={exprs.map((expr: any) => expr.key)} onChange={changePropertyPicker} recentlyStorePrefix={recentlyStorePrefix} fetchDetailData={fetchDetailData} diff --git a/src/legacy/filter-picker/components/FilterList/index.tsx b/src/legacy/filter-picker/components/FilterList/index.tsx index 6f849909ee..059c9ea779 100644 --- a/src/legacy/filter-picker/components/FilterList/index.tsx +++ b/src/legacy/filter-picker/components/FilterList/index.tsx @@ -1,11 +1,19 @@ -import React, { useEffect, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { PlusCircleFilled } from '@gio-design/icons'; import Expression from './Expression'; import './index.less'; import { FilterValueType } from '../../interfaces'; -import { defaultFilterItem } from '../../filterMap'; import Footer from '../Footer'; import Button from '../../../../button'; // new +import { FilterPickerContext } from '../../FilterPicker'; + +const defaultFilterItem: FilterValueType = { + op: '=', + values: [], + valueType: 'string', + name: '', + key: '', +}; interface FilterListProps { list: FilterValueType[]; @@ -30,6 +38,8 @@ function FilterList(props: FilterListProps) { } = props; const [filterList, setFilterList] = useState([...list]); + const { textObject: t } = useContext(FilterPickerContext); + useEffect(() => { if (!list.length) { setFilterList([defaultFilterItem]); @@ -90,7 +100,7 @@ function FilterList(props: FilterListProps) { disabled={filterList.length >= 5 || filterList.some((ele: FilterValueType) => !ele.values.length)} onClick={addFilter} > - 添加过滤条件 + {t.addFilter}