Skip to content

Commit

Permalink
feat(filterpicker): support i18n in the FilterPicker (#1592)
Browse files Browse the repository at this point in the history
Co-authored-by: maxin <maxin@growingio.com>
  • Loading branch information
nnmax and maxin committed Dec 2, 2021
1 parent 17e367c commit 7ebabe1
Show file tree
Hide file tree
Showing 19 changed files with 612 additions and 409 deletions.
8 changes: 5 additions & 3 deletions src/legacy/filter-picker/FilterPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<FilterPickerProps, 'fetchDetailData' | 'operationsOption'> & {
textObject: typeof defaultLocaleTextObject;
textObject: TextObject;
}
>({ textObject: defaultLocaleTextObject });
>({ textObject: { ...defaultLocaleTextObject, code: 'zh-CN' } });

const defaultOperationsOption: operationsOptionType = {
string: ['=', '!=', 'in', 'not in', 'like', 'not like', 'hasValue', 'noValue'],
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<StringValue | NumberValue | DateValue>(op);
const [attrValue, setAttrValue] = useState<string[]>(values);
const [checked, setChecked] = useState<boolean>(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 === '<=') {
Expand All @@ -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<HTMLInputElement>) => {
setChecked(e.target.checked);
};

Expand Down Expand Up @@ -146,25 +163,25 @@ function FilterAttrOverlay(props: FilterAttrOverlayProps) {
return (
<div className="filter-attr_select-box">
<div>
<div className="filter-attr_select-title">{titleMap[valueType] || '字符串类型'}</div>
<div className="filter-attr_select-title">{titleMap[valueType] || t.string}</div>
<Select
options={
operationsOption
? selectOptionMap?.[valueType]?.filter((opItem) =>
? selectOptions?.[valueType]?.filter((opItem) =>
operationsOption?.[valueType].includes(opItem.value as any)
)
: selectOptionMap?.[valueType]
: selectOptions?.[valueType]
}
value={operationValue}
style={{ marginTop: '16px', width: '100%' }}
placeholder="请选择"
placeholder={t.select}
onChange={selectChange}
/>
<Divider style={{ margin: '14px 0 16px' }} />
{getAttrSelect(valueType, operationValue)}
{valueType === AttributeMap.date && (operationValue === '>' || operationValue === '<') && (
<Checkbox checked={checked} onChange={handleChange} style={{ marginTop: 16 }}>
包含当日
{t.includeToday}
</Checkbox>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
flex-direction: column;
justify-content: space-between;
box-sizing: border-box;
width: 325px;
width: 380px;
height: 520px;
padding: 16px;
background-color: #fff;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import React, { useContext, useEffect, useState } from 'react';
import Input from '../../../../../../../../../input'; // new
import Select from '../../../../../../../../../select'; // new
import { FilterPickerContext } from '../../../../../../../FilterPicker';

interface RelativeBetweenProps {
onChange: (v: string) => void;
Expand All @@ -9,9 +10,10 @@ interface RelativeBetweenProps {
}
function RelativeBetween(props: RelativeBetweenProps) {
const { onChange, attrSelect, values } = props;
const [nowOrFuturevalue, setValue] = useState('-1');
const [nowOrFutureValue, setValue] = useState('-1');
const [value1, setValue1] = useState<number>(1);
const [value2, setValue2] = useState<number>(1);
const { textObject: t } = useContext(FilterPickerContext);
// 解析初始values值
useEffect(() => {
if (values.length && typeof values[0] === 'string') {
Expand All @@ -26,44 +28,34 @@ function RelativeBetween(props: RelativeBetweenProps) {
}
}, [values]);
const createAttrValue = (v1: number, v2: number, nowOrFuture: string) => {
let t = '';
let time = '';
if (nowOrFuture === '-1') {
t = `relativeTime:-${v1},-${v2}`;
time = `relativeTime:-${v1},-${v2}`;
} else {
t = `relativeTime:${v1},${v2}`;
time = `relativeTime:${v1},${v2}`;
}
onChange(t);
onChange(time);
};
const setInputValue1 = (event: React.ChangeEvent<HTMLInputElement>) => {
const v = Number.parseInt(event.target.value, 10);
if (v && /^\d+$/.test(`${v}`)) {
setValue1(v);
createAttrValue(v, value2, nowOrFuturevalue);
createAttrValue(v, value2, nowOrFutureValue);
} else if (!v) {
setValue1(v);
createAttrValue(0, value2, nowOrFuturevalue);
createAttrValue(0, value2, nowOrFutureValue);
}
};
const setInputValue2 = (event: React.ChangeEvent<HTMLInputElement>) => {
const v = Number.parseInt(event.target.value, 10);
if (v && /^\d+$/.test(`${v}`)) {
setValue2(v);
createAttrValue(value1, v, nowOrFuturevalue);
createAttrValue(value1, v, nowOrFutureValue);
} else if (!v) {
setValue2(v);
createAttrValue(value1, 0, nowOrFuturevalue);
createAttrValue(value1, 0, nowOrFutureValue);
}
};
const selectOptions = [
{
value: '-1',
label: '过去',
},
{
value: '1',
label: '未来',
},
];

const selectChange = (v: string) => {
setValue(v);
Expand All @@ -73,26 +65,76 @@ function RelativeBetween(props: RelativeBetweenProps) {
useEffect(() => {
// values值的初始化设置
if (!values.length) {
createAttrValue(value1, value2, nowOrFuturevalue);
createAttrValue(value1, value2, nowOrFutureValue);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [attrSelect]);

if (t.code === 'en-US') {
return (
<>
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
<Select
value={nowOrFutureValue}
options={[
{
value: '-1',
label: `${t.within} ${t.past}`,
},
{
value: '1',
label: `${t.within} ${t.future}`,
},
]}
onChange={selectChange}
style={{ marginRight: '4px' }}
/>
<Input.InputNumber
value={value1}
onChange={setInputValue1}
style={{ width: '150px', margin: '0 4px' }}
min={1}
/>
<div style={{ whiteSpace: 'nowrap', margin: '0 4px' }}>{t.to}</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
<Input.InputNumber
value={value2}
onChange={setInputValue2}
style={{ width: '150px', margin: '0 4px 0 0' }}
min={1}
/>
<div style={{ whiteSpace: 'nowrap', margin: '16px 4px' }}>{`${t.day}`}</div>
</div>
</>
);
}

return (
<>
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
<Select
value={nowOrFuturevalue}
options={selectOptions}
value={nowOrFutureValue}
options={[
{
value: '-1',
label: t.past,
},
{
value: '1',
label: t.future,
},
]}
onChange={selectChange}
style={{ marginRight: '4px', width: '120px' }}
style={{ marginRight: '4px' }}
/>
<Input.InputNumber
value={value1}
onChange={setInputValue1}
style={{ width: '150px', margin: '0 4px' }}
min={1}
/>
<div style={{ whiteSpace: 'nowrap', margin: '0 4px' }}>天至</div>
<div style={{ whiteSpace: 'nowrap', margin: '0 4px' }}>{t.to}</div>
</div>
<div style={{ display: 'flex', alignItems: 'center', flexWrap: 'wrap' }}>
<Input.InputNumber
Expand All @@ -101,7 +143,7 @@ function RelativeBetween(props: RelativeBetweenProps) {
style={{ width: '150px', margin: '0 4px 0 0' }}
min={1}
/>
<div style={{ whiteSpace: 'nowrap', margin: '16px 4px' }}>天之内</div>
<div style={{ whiteSpace: 'nowrap', margin: '16px 4px' }}>{`${t.day} ${t.within}`}</div>
</div>
</>
);
Expand Down

1 comment on commit 7ebabe1

@vercel
Copy link

@vercel vercel bot commented on 7ebabe1 Dec 2, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.