mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
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']();
|
||||
case 'before':
|
||||
return t['com.affine.filter.before']();
|
||||
case 'last':
|
||||
return t['com.affine.filter.last']();
|
||||
case 'is':
|
||||
return t['com.affine.filter.is']();
|
||||
case 'is not empty':
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import type { LiteralValue, Tag } from '@affine/env/filter';
|
||||
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 { FilterTag } from './filter-tag-translation';
|
||||
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 type { TType } from './logical/typesystem';
|
||||
import { tArray, typesystem } from './logical/typesystem';
|
||||
@@ -21,6 +23,37 @@ export const literalMatcher = new Matcher<{
|
||||
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(), {
|
||||
render: ({ value, onChange }) => (
|
||||
<div
|
||||
|
||||
@@ -19,3 +19,7 @@ export const tTag = typesystem.defineData<{ tags: Tag[] }>({
|
||||
name: 'Tag',
|
||||
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 { FilterTag } from './filter-tag-translation';
|
||||
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 type { TFunction } from './logical/typesystem';
|
||||
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(
|
||||
tFunction({
|
||||
args: [tDate.create(), tDate.create()],
|
||||
|
||||
Reference in New Issue
Block a user