feat(core): added new filter for last n days (#5167)
Co-authored-by: rakhee28 <rakhee@strings.ai> Co-authored-by: EYHN <cneyhn@gmail.com>
This commit is contained in:
@@ -19,6 +19,8 @@ const useFilterTag = ({ name }: FilterTagProps) => {
|
|||||||
return t['com.affine.filter.after']();
|
return t['com.affine.filter.after']();
|
||||||
case 'before':
|
case 'before':
|
||||||
return t['com.affine.filter.before']();
|
return t['com.affine.filter.before']();
|
||||||
|
case 'last':
|
||||||
|
return t['com.affine.filter.last']();
|
||||||
case 'is':
|
case 'is':
|
||||||
return t['com.affine.filter.is']();
|
return t['com.affine.filter.is']();
|
||||||
case 'is not empty':
|
case 'is not empty':
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import type { LiteralValue, Tag } from '@affine/env/filter';
|
import type { LiteralValue, Tag } from '@affine/env/filter';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import type { ReactNode } from 'react';
|
import { type ReactNode } from 'react';
|
||||||
|
|
||||||
|
import Input from '../../../ui/input';
|
||||||
|
import { Menu, MenuItem } from '../../../ui/menu';
|
||||||
import { AFFiNEDatePicker } from '../../date-picker';
|
import { AFFiNEDatePicker } from '../../date-picker';
|
||||||
import { FilterTag } from './filter-tag-translation';
|
import { FilterTag } from './filter-tag-translation';
|
||||||
import { inputStyle } from './index.css';
|
import { inputStyle } from './index.css';
|
||||||
import { tBoolean, tDate, tTag } from './logical/custom-type';
|
import { tBoolean, tDate, tDateRange, tTag } from './logical/custom-type';
|
||||||
import { Matcher } from './logical/matcher';
|
import { Matcher } from './logical/matcher';
|
||||||
import type { TType } from './logical/typesystem';
|
import type { TType } from './logical/typesystem';
|
||||||
import { tArray, typesystem } from './logical/typesystem';
|
import { tArray, typesystem } from './logical/typesystem';
|
||||||
@@ -21,6 +23,37 @@ export const literalMatcher = new Matcher<{
|
|||||||
return typesystem.isSubtype(type, target);
|
return typesystem.isSubtype(type, target);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
literalMatcher.register(tDateRange.create(), {
|
||||||
|
render: ({ value, onChange }) => (
|
||||||
|
<Menu
|
||||||
|
items={
|
||||||
|
<div>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
// Handle the input change and update the value accordingly
|
||||||
|
onChange={i => (i ? onChange(parseInt(i)) : onChange(0))}
|
||||||
|
/>
|
||||||
|
{[1, 2, 3, 7, 14, 30].map(i => (
|
||||||
|
<MenuItem
|
||||||
|
key={i}
|
||||||
|
onClick={() => {
|
||||||
|
// Handle the menu item click and update the value accordingly
|
||||||
|
onChange(i);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i} {i > 1 ? 'days' : 'day'}
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span>{value.toString()}</span> {(value as number) > 1 ? 'days' : 'day'}
|
||||||
|
</div>
|
||||||
|
</Menu>
|
||||||
|
),
|
||||||
|
});
|
||||||
|
|
||||||
literalMatcher.register(tBoolean.create(), {
|
literalMatcher.register(tBoolean.create(), {
|
||||||
render: ({ value, onChange }) => (
|
render: ({ value, onChange }) => (
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -19,3 +19,7 @@ export const tTag = typesystem.defineData<{ tags: Tag[] }>({
|
|||||||
name: 'Tag',
|
name: 'Tag',
|
||||||
supers: [],
|
supers: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const tDateRange = typesystem.defineData(
|
||||||
|
DataHelper.create<{ value: number }>('DateRange')
|
||||||
|
);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import type { ReactNode } from 'react';
|
|||||||
import { MenuIcon, MenuItem, MenuSeparator } from '../../../ui/menu';
|
import { MenuIcon, MenuItem, MenuSeparator } from '../../../ui/menu';
|
||||||
import { FilterTag } from './filter-tag-translation';
|
import { FilterTag } from './filter-tag-translation';
|
||||||
import * as styles from './index.css';
|
import * as styles from './index.css';
|
||||||
import { tBoolean, tDate, tTag } from './logical/custom-type';
|
import { tBoolean, tDate, tDateRange, tTag } from './logical/custom-type';
|
||||||
import { Matcher } from './logical/matcher';
|
import { Matcher } from './logical/matcher';
|
||||||
import type { TFunction } from './logical/typesystem';
|
import type { TFunction } from './logical/typesystem';
|
||||||
import {
|
import {
|
||||||
@@ -161,6 +161,24 @@ filterMatcher.register(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
filterMatcher.register(
|
||||||
|
tFunction({
|
||||||
|
args: [tDate.create(), tDateRange.create()],
|
||||||
|
rt: tBoolean.create(),
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
name: 'last',
|
||||||
|
defaultArgs: () => [30], // Default to the last 30 days
|
||||||
|
impl: (date, n) => {
|
||||||
|
if (typeof date !== 'number' || typeof n !== 'number') {
|
||||||
|
throw new Error('Argument type error: date and n must be numbers');
|
||||||
|
}
|
||||||
|
const startDate = dayjs().subtract(n, 'day').startOf('day').valueOf();
|
||||||
|
return date > startDate;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
filterMatcher.register(
|
filterMatcher.register(
|
||||||
tFunction({
|
tFunction({
|
||||||
args: [tDate.create(), tDate.create()],
|
args: [tDate.create(), tDate.create()],
|
||||||
|
|||||||
@@ -608,6 +608,7 @@
|
|||||||
"com.affine.filter": "Filter",
|
"com.affine.filter": "Filter",
|
||||||
"com.affine.filter.after": "after",
|
"com.affine.filter.after": "after",
|
||||||
"com.affine.filter.before": "before",
|
"com.affine.filter.before": "before",
|
||||||
|
"com.affine.filter.last": "last",
|
||||||
"com.affine.filter.contains all": "contains all",
|
"com.affine.filter.contains all": "contains all",
|
||||||
"com.affine.filter.contains one of": "contains one of",
|
"com.affine.filter.contains one of": "contains one of",
|
||||||
"com.affine.filter.does not contains all": "does not contains all",
|
"com.affine.filter.does not contains all": "does not contains all",
|
||||||
|
|||||||
@@ -593,6 +593,7 @@
|
|||||||
"com.affine.filter": "筛选",
|
"com.affine.filter": "筛选",
|
||||||
"com.affine.filter.after": "晚于",
|
"com.affine.filter.after": "晚于",
|
||||||
"com.affine.filter.before": "早于",
|
"com.affine.filter.before": "早于",
|
||||||
|
"com.affine.filter.last": "最近",
|
||||||
"com.affine.filter.contains all": "包含以下所有",
|
"com.affine.filter.contains all": "包含以下所有",
|
||||||
"com.affine.filter.contains one of": "包含以下之一",
|
"com.affine.filter.contains one of": "包含以下之一",
|
||||||
"com.affine.filter.does not contains all": "不包含以下所有",
|
"com.affine.filter.does not contains all": "不包含以下所有",
|
||||||
|
|||||||
Reference in New Issue
Block a user