@tcn/ui-table 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cell.css +1 -0
- package/dist/cell.module-WpHnQBVu.js +5 -0
- package/dist/cell.module-WpHnQBVu.js.map +1 -0
- package/dist/components/cells/data_cell.d.ts +3 -2
- package/dist/components/cells/data_cell.d.ts.map +1 -0
- package/dist/components/cells/data_cell.js +18 -10
- package/dist/components/cells/data_cell.js.map +1 -1
- package/dist/components/cells/footer_cell.d.ts +3 -2
- package/dist/components/cells/footer_cell.d.ts.map +1 -0
- package/dist/components/cells/footer_cell.js +18 -10
- package/dist/components/cells/footer_cell.js.map +1 -1
- package/dist/components/cells/header_cell.d.ts +3 -2
- package/dist/components/cells/header_cell.d.ts.map +1 -0
- package/dist/components/cells/header_cell.js +52 -18
- package/dist/components/cells/header_cell.js.map +1 -1
- package/dist/components/cells/sticky_row_data_cell.d.ts +3 -2
- package/dist/components/cells/sticky_row_data_cell.d.ts.map +1 -0
- package/dist/components/cells/sticky_row_data_cell.js +26 -11
- package/dist/components/cells/sticky_row_data_cell.js.map +1 -1
- package/dist/components/cells/sticky_row_fill_cell.d.ts +2 -2
- package/dist/components/cells/sticky_row_fill_cell.d.ts.map +1 -0
- package/dist/components/cells/sticky_row_fill_cell.js +15 -5
- package/dist/components/cells/sticky_row_fill_cell.js.map +1 -1
- package/dist/components/global_search.d.ts +2 -2
- package/dist/components/global_search.d.ts.map +1 -0
- package/dist/components/global_search.js +26 -9
- package/dist/components/global_search.js.map +1 -1
- package/dist/components/global_search_presenter.d.ts +2 -1
- package/dist/components/global_search_presenter.d.ts.map +1 -0
- package/dist/components/global_search_presenter.js +20 -18
- package/dist/components/global_search_presenter.js.map +1 -1
- package/dist/components/table/table.d.ts +3 -2
- package/dist/components/table/table.d.ts.map +1 -0
- package/dist/components/table/table.js +140 -77
- package/dist/components/table/table.js.map +1 -1
- package/dist/components/table/table_column.d.ts +1 -1
- package/dist/components/table/table_column.d.ts.map +1 -0
- package/dist/components/table/table_column.js +6 -5
- package/dist/components/table/table_column.js.map +1 -1
- package/dist/components/table/table_presenter.d.ts +3 -2
- package/dist/components/table/table_presenter.d.ts.map +1 -0
- package/dist/components/table/table_presenter.js +45 -62
- package/dist/components/table/table_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/date_field_filter.d.ts +2 -2
- package/dist/components/table_filter_panel/field_filters/date_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/date_field_filter.js +59 -33
- package/dist/components/table_filter_panel/field_filters/date_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.d.ts +4 -3
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.js +57 -91
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/field_filter_props.d.ts +1 -0
- package/dist/components/table_filter_panel/field_filters/field_filter_props.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/field_filter_strategy.d.ts +1 -0
- package/dist/components/table_filter_panel/field_filters/field_filter_strategy.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.d.ts +3 -3
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js +52 -29
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.d.ts +3 -2
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.js +53 -70
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter.d.ts +3 -3
- package/dist/components/table_filter_panel/field_filters/number_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/number_field_filter.js +47 -23
- package/dist/components/table_filter_panel/field_filters/number_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.d.ts +5 -4
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.js +53 -58
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.d.ts +2 -2
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js +61 -31
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.d.ts +4 -3
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.js +57 -91
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter.d.ts +3 -3
- package/dist/components/table_filter_panel/field_filters/select_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/select_field_filter.js +49 -24
- package/dist/components/table_filter_panel/field_filters/select_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.d.ts +3 -2
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.js +49 -53
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter.d.ts +3 -3
- package/dist/components/table_filter_panel/field_filters/string_field_filter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/string_field_filter.js +62 -33
- package/dist/components/table_filter_panel/field_filters/string_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.d.ts +5 -4
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.js +54 -59
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/use_field_filter_strategy.d.ts +2 -1
- package/dist/components/table_filter_panel/field_filters/use_field_filter_strategy.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/use_field_filter_strategy.js +13 -19
- package/dist/components/table_filter_panel/field_filters/use_field_filter_strategy.js.map +1 -1
- package/dist/components/table_filter_panel/table_filter_panel.d.ts +5 -4
- package/dist/components/table_filter_panel/table_filter_panel.d.ts.map +1 -0
- package/dist/components/table_filter_panel/table_filter_panel.js +15 -11
- package/dist/components/table_filter_panel/table_filter_panel.js.map +1 -1
- package/dist/components/table_filter_panel/table_filter_panel_presenter.d.ts +2 -2
- package/dist/components/table_filter_panel/table_filter_panel_presenter.d.ts.map +1 -0
- package/dist/components/table_filter_panel/table_filter_panel_presenter.js +45 -62
- package/dist/components/table_filter_panel/table_filter_panel_presenter.js.map +1 -1
- package/dist/components/table_filter_panel/types.d.ts +1 -0
- package/dist/components/table_filter_panel/types.d.ts.map +1 -0
- package/dist/components/table_filter_panel/types.js +5 -2
- package/dist/components/table_filter_panel/types.js.map +1 -1
- package/dist/components/table_pager.d.ts +2 -2
- package/dist/components/table_pager.d.ts.map +1 -0
- package/dist/components/table_pager.js +22 -20
- package/dist/components/table_pager.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -13
- package/dist/index.js.map +1 -1
- package/dist/table.css +1 -0
- package/dist/table_pager.css +1 -0
- package/package.json +61 -61
- package/src/__stories__/aip_table.stories.tsx +190 -0
- package/src/__stories__/auth_provider.tsx +14 -0
- package/src/__stories__/demo.stories.tsx +137 -0
- package/src/__stories__/sample_data.ts +1398 -0
- package/src/__stories__/table.stories.tsx +423 -0
- package/src/__tests__/sanity.test.ts +7 -0
- package/src/components/cells/data_cell.tsx +25 -0
- package/src/components/cells/footer_cell.tsx +25 -0
- package/src/components/cells/header_cell.tsx +77 -0
- package/src/components/cells/sticky_row_data_cell.tsx +31 -0
- package/src/components/cells/sticky_row_fill_cell.tsx +16 -0
- package/src/components/global_search.tsx +33 -0
- package/src/components/global_search_presenter.ts +24 -0
- package/{dist → src}/components/table/table.module.css +3 -2
- package/src/components/table/table.tsx +183 -0
- package/src/components/table/table_column.tsx +27 -0
- package/src/components/table/table_presenter.test.ts +161 -0
- package/src/components/table/table_presenter.ts +103 -0
- package/src/components/table_filter_panel/field_filters/date_field_filter.tsx +70 -0
- package/src/components/table_filter_panel/field_filters/date_field_filter_presenter.test.ts +583 -0
- package/src/components/table_filter_panel/field_filters/date_field_filter_presenter.ts +110 -0
- package/src/components/table_filter_panel/field_filters/field_filter_props.ts +5 -0
- package/src/components/table_filter_panel/field_filters/field_filter_strategy.ts +14 -0
- package/src/components/table_filter_panel/field_filters/mulit_select_field_filter.tsx +68 -0
- package/src/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.test.ts +444 -0
- package/src/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.ts +90 -0
- package/src/components/table_filter_panel/field_filters/number_field_filter.tsx +53 -0
- package/src/components/table_filter_panel/field_filters/number_field_filter_presenter.test.ts +431 -0
- package/src/components/table_filter_panel/field_filters/number_field_filter_presenter.ts +80 -0
- package/src/components/table_filter_panel/field_filters/number_range_field_filter.tsx +68 -0
- package/src/components/table_filter_panel/field_filters/number_range_field_filter_presenter.test.ts +582 -0
- package/src/components/table_filter_panel/field_filters/number_range_field_filter_presenter.ts +110 -0
- package/src/components/table_filter_panel/field_filters/select_field_filter.tsx +57 -0
- package/src/components/table_filter_panel/field_filters/select_field_filter_presenter.test.ts +365 -0
- package/src/components/table_filter_panel/field_filters/select_field_filter_presenter.ts +74 -0
- package/src/components/table_filter_panel/field_filters/string_field_filter.tsx +70 -0
- package/src/components/table_filter_panel/field_filters/string_field_filter_presenter.test.ts +296 -0
- package/src/components/table_filter_panel/field_filters/string_field_filter_presenter.ts +81 -0
- package/src/components/table_filter_panel/field_filters/use_field_filter_strategy.tsx +30 -0
- package/src/components/table_filter_panel/table_filter_panel.stories.tsx +46 -0
- package/src/components/table_filter_panel/table_filter_panel.tsx +26 -0
- package/src/components/table_filter_panel/table_filter_panel_presenter.ts +77 -0
- package/src/components/table_filter_panel/types.ts +3 -0
- package/src/components/table_pager.tsx +39 -0
- package/src/index.ts +16 -0
- package/tsconfig.json +36 -0
- package/types/file_types.d.ts +54 -0
- package/types/react_color.d.ts +61 -0
- package/dist/__stories__/aip_table.stories.d.ts +0 -5
- package/dist/__stories__/aip_table.stories.js +0 -96
- package/dist/__stories__/aip_table.stories.js.map +0 -1
- package/dist/__stories__/auth_provider.d.ts +0 -4
- package/dist/__stories__/auth_provider.js +0 -10
- package/dist/__stories__/auth_provider.js.map +0 -1
- package/dist/__stories__/demo.stories.d.ts +0 -6
- package/dist/__stories__/demo.stories.js +0 -94
- package/dist/__stories__/demo.stories.js.map +0 -1
- package/dist/__stories__/sample_data.d.ts +0 -36
- package/dist/__stories__/sample_data.js +0 -1385
- package/dist/__stories__/sample_data.js.map +0 -1
- package/dist/__stories__/table.stories.d.ts +0 -12
- package/dist/__stories__/table.stories.js +0 -272
- package/dist/__stories__/table.stories.js.map +0 -1
- package/dist/components/table/table_presenter.test.d.ts +0 -1
- package/dist/components/table/table_presenter.test.js +0 -125
- package/dist/components/table/table_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.test.js +0 -434
- package/dist/components/table_filter_panel/field_filters/date_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/field_filter_props.js +0 -2
- package/dist/components/table_filter_panel/field_filters/field_filter_props.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/field_filter_strategy.js +0 -2
- package/dist/components/table_filter_panel/field_filters/field_filter_strategy.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.test.js +0 -332
- package/dist/components/table_filter_panel/field_filters/multi_select_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.test.js +0 -347
- package/dist/components/table_filter_panel/field_filters/number_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.test.js +0 -452
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.test.js +0 -285
- package/dist/components/table_filter_panel/field_filters/select_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.test.d.ts +0 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.test.js +0 -232
- package/dist/components/table_filter_panel/field_filters/string_field_filter_presenter.test.js.map +0 -1
- package/dist/components/table_filter_panel/table_filter_panel.stories.d.ts +0 -6
- package/dist/components/table_filter_panel/table_filter_panel.stories.js +0 -25
- package/dist/components/table_filter_panel/table_filter_panel.stories.js.map +0 -1
- /package/{dist → src}/__stories__/table.module.css +0 -0
- /package/{dist → src}/components/cells/cell.module.css +0 -0
- /package/{dist → src}/components/table_pager.module.css +0 -0
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
import { Node } from 'clarity-pattern-parser';
|
|
2
|
+
import { DateFieldFilterPresenter } from './date_field_filter_presenter.js';
|
|
3
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
|
|
5
|
+
describe('DateFieldFilterPresenter', () => {
|
|
6
|
+
let presenter: DateFieldFilterPresenter;
|
|
7
|
+
let mockFieldRegistry: any;
|
|
8
|
+
let testStartDate: Date;
|
|
9
|
+
let testEndDate: Date;
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
presenter = new DateFieldFilterPresenter('test_field');
|
|
13
|
+
mockFieldRegistry = {
|
|
14
|
+
registerFieldFilter: vi.fn(),
|
|
15
|
+
unregisterFieldFilter: vi.fn(),
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Create fixed test dates for consistent testing
|
|
19
|
+
testStartDate = new Date('2023-01-01T00:00:00.000Z');
|
|
20
|
+
testEndDate = new Date('2023-12-31T23:59:59.999Z');
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('constructor', () => {
|
|
24
|
+
it('should initialize with the correct field name', () => {
|
|
25
|
+
const presenter = new DateFieldFilterPresenter('custom_field');
|
|
26
|
+
expect(presenter.getFilterString()).toBe('');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should initialize with default values', () => {
|
|
30
|
+
expect(presenter.getFilterString()).toBe('');
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe('setStartDate', () => {
|
|
35
|
+
it('should set the start date when setStartDate is called with a Date', () => {
|
|
36
|
+
presenter.setStartDate(testStartDate);
|
|
37
|
+
expect(presenter.getFilterString()).toBe(
|
|
38
|
+
`test_field >= '${testStartDate.toISOString()}'`
|
|
39
|
+
);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should set the start date when setStartDate is called with null', () => {
|
|
43
|
+
presenter.setStartDate(testStartDate);
|
|
44
|
+
presenter.setStartDate(null);
|
|
45
|
+
expect(presenter.getFilterString()).toBe('');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should handle epoch date', () => {
|
|
49
|
+
const epochDate = new Date(0);
|
|
50
|
+
presenter.setStartDate(epochDate);
|
|
51
|
+
expect(presenter.getFilterString()).toBe(
|
|
52
|
+
`test_field >= '${epochDate.toISOString()}'`
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should handle future date', () => {
|
|
57
|
+
const futureDate = new Date('2030-01-01T00:00:00.000Z');
|
|
58
|
+
presenter.setStartDate(futureDate);
|
|
59
|
+
expect(presenter.getFilterString()).toBe(
|
|
60
|
+
`test_field >= '${futureDate.toISOString()}'`
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should handle past date', () => {
|
|
65
|
+
const pastDate = new Date('1990-01-01T00:00:00.000Z');
|
|
66
|
+
presenter.setStartDate(pastDate);
|
|
67
|
+
expect(presenter.getFilterString()).toBe(
|
|
68
|
+
`test_field >= '${pastDate.toISOString()}'`
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should trigger onChange handlers when start date is set', () => {
|
|
73
|
+
const onChangeHandler = vi.fn();
|
|
74
|
+
presenter.onChange(onChangeHandler);
|
|
75
|
+
|
|
76
|
+
presenter.setStartDate(testStartDate);
|
|
77
|
+
|
|
78
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe('setEndDate', () => {
|
|
83
|
+
it('should set the end date when setEndDate is called with a Date', () => {
|
|
84
|
+
presenter.setEndDate(testEndDate);
|
|
85
|
+
expect(presenter.getFilterString()).toBe(
|
|
86
|
+
`test_field <= '${testEndDate.toISOString()}'`
|
|
87
|
+
);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should set the end date when setEndDate is called with null', () => {
|
|
91
|
+
presenter.setEndDate(testEndDate);
|
|
92
|
+
presenter.setEndDate(null);
|
|
93
|
+
expect(presenter.getFilterString()).toBe('');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should handle epoch date', () => {
|
|
97
|
+
const epochDate = new Date(0);
|
|
98
|
+
presenter.setEndDate(epochDate);
|
|
99
|
+
expect(presenter.getFilterString()).toBe(
|
|
100
|
+
`test_field <= '${epochDate.toISOString()}'`
|
|
101
|
+
);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('should handle future date', () => {
|
|
105
|
+
const futureDate = new Date('2030-01-01T00:00:00.000Z');
|
|
106
|
+
presenter.setEndDate(futureDate);
|
|
107
|
+
expect(presenter.getFilterString()).toBe(
|
|
108
|
+
`test_field <= '${futureDate.toISOString()}'`
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('should handle past date', () => {
|
|
113
|
+
const pastDate = new Date('1990-01-01T00:00:00.000Z');
|
|
114
|
+
presenter.setEndDate(pastDate);
|
|
115
|
+
expect(presenter.getFilterString()).toBe(
|
|
116
|
+
`test_field <= '${pastDate.toISOString()}'`
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should trigger onChange handlers when end date is set', () => {
|
|
121
|
+
const onChangeHandler = vi.fn();
|
|
122
|
+
presenter.onChange(onChangeHandler);
|
|
123
|
+
|
|
124
|
+
presenter.setEndDate(testEndDate);
|
|
125
|
+
|
|
126
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
describe('getFilterString', () => {
|
|
131
|
+
it('should return empty string when both dates are null', () => {
|
|
132
|
+
expect(presenter.getFilterString()).toBe('');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should return start date filter when only start date is set', () => {
|
|
136
|
+
presenter.setStartDate(testStartDate);
|
|
137
|
+
expect(presenter.getFilterString()).toBe(
|
|
138
|
+
`test_field >= '${testStartDate.toISOString()}'`
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it('should return end date filter when only end date is set', () => {
|
|
143
|
+
presenter.setEndDate(testEndDate);
|
|
144
|
+
expect(presenter.getFilterString()).toBe(
|
|
145
|
+
`test_field <= '${testEndDate.toISOString()}'`
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should return range filter when both dates are set', () => {
|
|
150
|
+
presenter.setStartDate(testStartDate);
|
|
151
|
+
presenter.setEndDate(testEndDate);
|
|
152
|
+
expect(presenter.getFilterString()).toBe(
|
|
153
|
+
`(test_field >= '${testStartDate.toISOString()}' AND test_field <= '${testEndDate.toISOString()}')`
|
|
154
|
+
);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('should handle same start and end date', () => {
|
|
158
|
+
const sameDate = new Date('2023-06-15T12:00:00.000Z');
|
|
159
|
+
presenter.setStartDate(sameDate);
|
|
160
|
+
presenter.setEndDate(sameDate);
|
|
161
|
+
expect(presenter.getFilterString()).toBe(
|
|
162
|
+
`(test_field >= '${sameDate.toISOString()}' AND test_field <= '${sameDate.toISOString()}')`
|
|
163
|
+
);
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
it('should handle dates with milliseconds', () => {
|
|
167
|
+
const dateWithMs = new Date('2023-06-15T12:30:45.123Z');
|
|
168
|
+
presenter.setStartDate(dateWithMs);
|
|
169
|
+
presenter.setEndDate(dateWithMs);
|
|
170
|
+
expect(presenter.getFilterString()).toBe(
|
|
171
|
+
`(test_field >= '${dateWithMs.toISOString()}' AND test_field <= '${dateWithMs.toISOString()}')`
|
|
172
|
+
);
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('should handle dates with different timezones (converted to UTC)', () => {
|
|
176
|
+
const localDate = new Date('2023-06-15T12:00:00');
|
|
177
|
+
presenter.setStartDate(localDate);
|
|
178
|
+
presenter.setEndDate(localDate);
|
|
179
|
+
expect(presenter.getFilterString()).toBe(
|
|
180
|
+
`(test_field >= '${localDate.toISOString()}' AND test_field <= '${localDate.toISOString()}')`
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('onChange', () => {
|
|
186
|
+
it('should register onChange handler and return unsubscribe function', () => {
|
|
187
|
+
const onChangeHandler = vi.fn();
|
|
188
|
+
const unsubscribe = presenter.onChange(onChangeHandler);
|
|
189
|
+
|
|
190
|
+
presenter.setStartDate(testStartDate);
|
|
191
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(1);
|
|
192
|
+
|
|
193
|
+
unsubscribe();
|
|
194
|
+
presenter.setEndDate(testEndDate);
|
|
195
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(1); // Should not be called again
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should handle multiple onChange handlers', () => {
|
|
199
|
+
const handler1 = vi.fn();
|
|
200
|
+
const handler2 = vi.fn();
|
|
201
|
+
|
|
202
|
+
presenter.onChange(handler1);
|
|
203
|
+
presenter.onChange(handler2);
|
|
204
|
+
|
|
205
|
+
presenter.setStartDate(testStartDate);
|
|
206
|
+
|
|
207
|
+
expect(handler1).toHaveBeenCalledTimes(1);
|
|
208
|
+
expect(handler2).toHaveBeenCalledTimes(1);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('should handle removing onChange handlers', () => {
|
|
212
|
+
const handler1 = vi.fn();
|
|
213
|
+
const handler2 = vi.fn();
|
|
214
|
+
|
|
215
|
+
const unsubscribe1 = presenter.onChange(handler1);
|
|
216
|
+
presenter.onChange(handler2);
|
|
217
|
+
|
|
218
|
+
unsubscribe1();
|
|
219
|
+
presenter.setEndDate(testEndDate);
|
|
220
|
+
|
|
221
|
+
expect(handler1).not.toHaveBeenCalled();
|
|
222
|
+
expect(handler2).toHaveBeenCalledTimes(1);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it('should trigger handlers for both start and end date changes', () => {
|
|
226
|
+
const onChangeHandler = vi.fn();
|
|
227
|
+
presenter.onChange(onChangeHandler);
|
|
228
|
+
|
|
229
|
+
presenter.setStartDate(testStartDate);
|
|
230
|
+
presenter.setEndDate(testEndDate);
|
|
231
|
+
|
|
232
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(2);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
describe('setFieldRegistry', () => {
|
|
237
|
+
it('should register the field filter with the registry', () => {
|
|
238
|
+
presenter.setFieldRegistry(mockFieldRegistry);
|
|
239
|
+
|
|
240
|
+
expect(mockFieldRegistry.registerFieldFilter).toHaveBeenCalledWith(
|
|
241
|
+
'test_field',
|
|
242
|
+
presenter
|
|
243
|
+
);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('should store the field registry reference', () => {
|
|
247
|
+
presenter.setFieldRegistry(mockFieldRegistry);
|
|
248
|
+
|
|
249
|
+
// Test that dispose can call unregisterFieldFilter
|
|
250
|
+
presenter.dispose();
|
|
251
|
+
expect(mockFieldRegistry.unregisterFieldFilter).toHaveBeenCalledWith('test_field');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe('setFilterState', () => {
|
|
256
|
+
it('should parse single start date filter from AST', () => {
|
|
257
|
+
const mockAst = {
|
|
258
|
+
findAll: vi.fn().mockReturnValue([
|
|
259
|
+
{
|
|
260
|
+
name: 'plain-field',
|
|
261
|
+
value: 'test_field',
|
|
262
|
+
parent: {
|
|
263
|
+
name: 'infix-expression',
|
|
264
|
+
children: [
|
|
265
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
266
|
+
{ name: 'operator', value: '>=' },
|
|
267
|
+
{ name: 'string', value: '"2023-01-01T00:00:00.000Z"' },
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
]),
|
|
272
|
+
} as unknown as Node;
|
|
273
|
+
|
|
274
|
+
presenter.setFilterState(mockAst);
|
|
275
|
+
|
|
276
|
+
expect(presenter.getFilterString()).toBe(
|
|
277
|
+
`test_field >= '${testStartDate.toISOString()}'`
|
|
278
|
+
);
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it('should parse single end date filter from AST', () => {
|
|
282
|
+
const mockAst = {
|
|
283
|
+
findAll: vi.fn().mockReturnValue([
|
|
284
|
+
{
|
|
285
|
+
name: 'plain-field',
|
|
286
|
+
value: 'test_field',
|
|
287
|
+
parent: {
|
|
288
|
+
name: 'infix-expression',
|
|
289
|
+
children: [
|
|
290
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
291
|
+
{ name: 'operator', value: '<=' },
|
|
292
|
+
{ name: 'string', value: '"2023-12-31T23:59:59.999Z"' },
|
|
293
|
+
],
|
|
294
|
+
},
|
|
295
|
+
},
|
|
296
|
+
]),
|
|
297
|
+
} as unknown as Node;
|
|
298
|
+
|
|
299
|
+
presenter.setFilterState(mockAst);
|
|
300
|
+
|
|
301
|
+
expect(presenter.getFilterString()).toBe(
|
|
302
|
+
`test_field <= '${testEndDate.toISOString()}'`
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('should parse range filter with start >= and end <= from AST', () => {
|
|
307
|
+
const mockAst = {
|
|
308
|
+
findAll: vi.fn().mockReturnValue([
|
|
309
|
+
{
|
|
310
|
+
name: 'plain-field',
|
|
311
|
+
value: 'test_field',
|
|
312
|
+
parent: {
|
|
313
|
+
name: 'infix-expression',
|
|
314
|
+
children: [
|
|
315
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
316
|
+
{ name: 'operator', value: '>=' },
|
|
317
|
+
{ name: 'string', value: '"2023-01-01T00:00:00.000Z"' },
|
|
318
|
+
],
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
name: 'plain-field',
|
|
323
|
+
value: 'test_field',
|
|
324
|
+
parent: {
|
|
325
|
+
name: 'infix-expression',
|
|
326
|
+
children: [
|
|
327
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
328
|
+
{ name: 'operator', value: '<=' },
|
|
329
|
+
{ name: 'string', value: '"2023-12-31T23:59:59.999Z"' },
|
|
330
|
+
],
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
]),
|
|
334
|
+
} as unknown as Node;
|
|
335
|
+
|
|
336
|
+
presenter.setFilterState(mockAst);
|
|
337
|
+
|
|
338
|
+
expect(presenter.getFilterString()).toBe(
|
|
339
|
+
`(test_field >= '${testStartDate.toISOString()}' AND test_field <= '${testEndDate.toISOString()}')`
|
|
340
|
+
);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('should parse range filter with end <= and start >= from AST (reversed order)', () => {
|
|
344
|
+
const mockAst = {
|
|
345
|
+
findAll: vi.fn().mockReturnValue([
|
|
346
|
+
{
|
|
347
|
+
name: 'plain-field',
|
|
348
|
+
value: 'test_field',
|
|
349
|
+
parent: {
|
|
350
|
+
name: 'infix-expression',
|
|
351
|
+
children: [
|
|
352
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
353
|
+
{ name: 'operator', value: '<=' },
|
|
354
|
+
{ name: 'string', value: '"2023-12-31T23:59:59.999Z"' },
|
|
355
|
+
],
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
name: 'plain-field',
|
|
360
|
+
value: 'test_field',
|
|
361
|
+
parent: {
|
|
362
|
+
name: 'infix-expression',
|
|
363
|
+
children: [
|
|
364
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
365
|
+
{ name: 'operator', value: '>=' },
|
|
366
|
+
{ name: 'string', value: '"2023-01-01T00:00:00.000Z"' },
|
|
367
|
+
],
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
]),
|
|
371
|
+
} as unknown as Node;
|
|
372
|
+
|
|
373
|
+
presenter.setFilterState(mockAst);
|
|
374
|
+
|
|
375
|
+
expect(presenter.getFilterString()).toBe(
|
|
376
|
+
`(test_field >= '${testStartDate.toISOString()}' AND test_field <= '${testEndDate.toISOString()}')`
|
|
377
|
+
);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
it('should handle case when field is not found in AST', () => {
|
|
381
|
+
const mockAst = {
|
|
382
|
+
findAll: vi.fn().mockReturnValue([]),
|
|
383
|
+
} as unknown as Node;
|
|
384
|
+
|
|
385
|
+
presenter.setStartDate(testStartDate);
|
|
386
|
+
presenter.setEndDate(testEndDate);
|
|
387
|
+
|
|
388
|
+
presenter.setFilterState(mockAst);
|
|
389
|
+
|
|
390
|
+
// Should not change existing state
|
|
391
|
+
expect(presenter.getFilterString()).toBe(
|
|
392
|
+
`(test_field >= '${testStartDate.toISOString()}' AND test_field <= '${testEndDate.toISOString()}')`
|
|
393
|
+
);
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
it('should handle case when field node has no parent', () => {
|
|
397
|
+
const mockAst = {
|
|
398
|
+
findAll: vi.fn().mockReturnValue([
|
|
399
|
+
{
|
|
400
|
+
name: 'plain-field',
|
|
401
|
+
value: 'test_field',
|
|
402
|
+
parent: null,
|
|
403
|
+
},
|
|
404
|
+
]),
|
|
405
|
+
} as unknown as Node;
|
|
406
|
+
|
|
407
|
+
presenter.setStartDate(testStartDate);
|
|
408
|
+
presenter.setEndDate(testEndDate);
|
|
409
|
+
|
|
410
|
+
presenter.setFilterState(mockAst);
|
|
411
|
+
|
|
412
|
+
// Should not change existing state
|
|
413
|
+
expect(presenter.getFilterString()).toBe(
|
|
414
|
+
`(test_field >= '${testStartDate.toISOString()}' AND test_field <= '${testEndDate.toISOString()}')`
|
|
415
|
+
);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
it('should parse dates with milliseconds from AST', () => {
|
|
419
|
+
const dateWithMs = new Date('2023-06-15T12:30:45.123Z');
|
|
420
|
+
const mockAst = {
|
|
421
|
+
findAll: vi.fn().mockReturnValue([
|
|
422
|
+
{
|
|
423
|
+
name: 'plain-field',
|
|
424
|
+
value: 'test_field',
|
|
425
|
+
parent: {
|
|
426
|
+
name: 'infix-expression',
|
|
427
|
+
children: [
|
|
428
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
429
|
+
{ name: 'operator', value: '>=' },
|
|
430
|
+
{ name: 'string', value: `"${dateWithMs.toISOString()}"` },
|
|
431
|
+
],
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
name: 'plain-field',
|
|
436
|
+
value: 'test_field',
|
|
437
|
+
parent: {
|
|
438
|
+
name: 'infix-expression',
|
|
439
|
+
children: [
|
|
440
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
441
|
+
{ name: 'operator', value: '<=' },
|
|
442
|
+
{ name: 'string', value: `"${dateWithMs.toISOString()}"` },
|
|
443
|
+
],
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
]),
|
|
447
|
+
} as unknown as Node;
|
|
448
|
+
|
|
449
|
+
presenter.setFilterState(mockAst);
|
|
450
|
+
|
|
451
|
+
expect(presenter.getFilterString()).toBe(
|
|
452
|
+
`(test_field >= '${dateWithMs.toISOString()}' AND test_field <= '${dateWithMs.toISOString()}')`
|
|
453
|
+
);
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
it('should ignore non-range operators', () => {
|
|
457
|
+
const mockAst = {
|
|
458
|
+
findAll: vi.fn().mockReturnValue([
|
|
459
|
+
{
|
|
460
|
+
name: 'plain-field',
|
|
461
|
+
value: 'test_field',
|
|
462
|
+
parent: {
|
|
463
|
+
name: 'infix-expression',
|
|
464
|
+
children: [
|
|
465
|
+
{ name: 'plain-field', value: 'test_field' },
|
|
466
|
+
{ name: 'operator', value: '=' },
|
|
467
|
+
{ name: 'string', value: '"2023-06-15T12:00:00.000Z"' },
|
|
468
|
+
],
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
]),
|
|
472
|
+
} as unknown as Node;
|
|
473
|
+
|
|
474
|
+
presenter.setFilterState(mockAst);
|
|
475
|
+
|
|
476
|
+
// Should not change existing state
|
|
477
|
+
expect(presenter.getFilterString()).toBe('');
|
|
478
|
+
});
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
describe('dispose', () => {
|
|
482
|
+
it('should unregister field filter from registry when registry is set', () => {
|
|
483
|
+
presenter.setFieldRegistry(mockFieldRegistry);
|
|
484
|
+
presenter.dispose();
|
|
485
|
+
|
|
486
|
+
expect(mockFieldRegistry.unregisterFieldFilter).toHaveBeenCalledWith('test_field');
|
|
487
|
+
});
|
|
488
|
+
|
|
489
|
+
it('should not call unregisterFieldFilter when no registry is set', () => {
|
|
490
|
+
presenter.dispose();
|
|
491
|
+
|
|
492
|
+
expect(mockFieldRegistry.unregisterFieldFilter).not.toHaveBeenCalled();
|
|
493
|
+
});
|
|
494
|
+
|
|
495
|
+
it('should clear onChange handlers', () => {
|
|
496
|
+
const onChangeHandler = vi.fn();
|
|
497
|
+
presenter.onChange(onChangeHandler);
|
|
498
|
+
|
|
499
|
+
presenter.dispose();
|
|
500
|
+
presenter.setStartDate(testStartDate);
|
|
501
|
+
|
|
502
|
+
expect(onChangeHandler).not.toHaveBeenCalled();
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
it('should clear field registry reference', () => {
|
|
506
|
+
presenter.setFieldRegistry(mockFieldRegistry);
|
|
507
|
+
presenter.dispose();
|
|
508
|
+
|
|
509
|
+
// Should not call unregisterFieldFilter again
|
|
510
|
+
presenter.dispose();
|
|
511
|
+
expect(mockFieldRegistry.unregisterFieldFilter).toHaveBeenCalledTimes(1);
|
|
512
|
+
});
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
describe('edge cases and error handling', () => {
|
|
516
|
+
it('should handle rapid successive date changes', () => {
|
|
517
|
+
const onChangeHandler = vi.fn();
|
|
518
|
+
presenter.onChange(onChangeHandler);
|
|
519
|
+
|
|
520
|
+
const date1 = new Date('2023-01-01T00:00:00.000Z');
|
|
521
|
+
const date2 = new Date('2023-06-15T12:00:00.000Z');
|
|
522
|
+
const date3 = new Date('2023-12-31T23:59:59.999Z');
|
|
523
|
+
|
|
524
|
+
presenter.setStartDate(date1);
|
|
525
|
+
presenter.setEndDate(date3);
|
|
526
|
+
presenter.setStartDate(date2);
|
|
527
|
+
presenter.setEndDate(date3);
|
|
528
|
+
|
|
529
|
+
expect(onChangeHandler).toHaveBeenCalledTimes(4);
|
|
530
|
+
expect(presenter.getFilterString()).toBe(
|
|
531
|
+
`(test_field >= '${date2.toISOString()}' AND test_field <= '${date3.toISOString()}')`
|
|
532
|
+
);
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
it('should handle very old dates', () => {
|
|
536
|
+
const oldDate = new Date('1900-01-01T00:00:00.000Z');
|
|
537
|
+
presenter.setStartDate(oldDate);
|
|
538
|
+
presenter.setEndDate(oldDate);
|
|
539
|
+
expect(presenter.getFilterString()).toBe(
|
|
540
|
+
`(test_field >= '${oldDate.toISOString()}' AND test_field <= '${oldDate.toISOString()}')`
|
|
541
|
+
);
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
it('should handle very future dates', () => {
|
|
545
|
+
const futureDate = new Date('2100-01-01T00:00:00.000Z');
|
|
546
|
+
presenter.setStartDate(futureDate);
|
|
547
|
+
presenter.setEndDate(futureDate);
|
|
548
|
+
expect(presenter.getFilterString()).toBe(
|
|
549
|
+
`(test_field >= '${futureDate.toISOString()}' AND test_field <= '${futureDate.toISOString()}')`
|
|
550
|
+
);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it('should handle dates with different timezones', () => {
|
|
554
|
+
const utcDate = new Date('2023-06-15T12:00:00.000Z');
|
|
555
|
+
const localDate = new Date('2023-06-15T12:00:00');
|
|
556
|
+
|
|
557
|
+
presenter.setStartDate(utcDate);
|
|
558
|
+
presenter.setEndDate(localDate);
|
|
559
|
+
|
|
560
|
+
expect(presenter.getFilterString()).toBe(
|
|
561
|
+
`(test_field >= '${utcDate.toISOString()}' AND test_field <= '${localDate.toISOString()}')`
|
|
562
|
+
);
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
it('should handle leap year dates', () => {
|
|
566
|
+
const leapYearDate = new Date('2024-02-29T12:00:00.000Z');
|
|
567
|
+
presenter.setStartDate(leapYearDate);
|
|
568
|
+
presenter.setEndDate(leapYearDate);
|
|
569
|
+
expect(presenter.getFilterString()).toBe(
|
|
570
|
+
`(test_field >= '${leapYearDate.toISOString()}' AND test_field <= '${leapYearDate.toISOString()}')`
|
|
571
|
+
);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
it('should handle daylight saving time transitions', () => {
|
|
575
|
+
const dstDate = new Date('2023-03-12T02:00:00.000Z');
|
|
576
|
+
presenter.setStartDate(dstDate);
|
|
577
|
+
presenter.setEndDate(dstDate);
|
|
578
|
+
expect(presenter.getFilterString()).toBe(
|
|
579
|
+
`(test_field >= '${dstDate.toISOString()}' AND test_field <= '${dstDate.toISOString()}')`
|
|
580
|
+
);
|
|
581
|
+
});
|
|
582
|
+
});
|
|
583
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Signal } from '@tcn/state';
|
|
2
|
+
import { Node } from 'clarity-pattern-parser';
|
|
3
|
+
import { FieldFilterRegistry, FieldFilterStrategy } from './field_filter_strategy.js';
|
|
4
|
+
|
|
5
|
+
export class DateFieldFilterPresenter implements FieldFilterStrategy {
|
|
6
|
+
private _fieldName: string;
|
|
7
|
+
private _fieldFilterRegistry: FieldFilterRegistry | null = null;
|
|
8
|
+
private _startDate = new Signal<Date | null>(null);
|
|
9
|
+
private _endDate = new Signal<Date | null>(null);
|
|
10
|
+
private _onChangeHandlers = new Set<() => void>();
|
|
11
|
+
|
|
12
|
+
private _broadcasts = {
|
|
13
|
+
startDate: this._startDate.broadcast,
|
|
14
|
+
endDate: this._endDate.broadcast,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
constructor(fieldName: string) {
|
|
18
|
+
this._fieldName = fieldName;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get broadcasts() {
|
|
22
|
+
return this._broadcasts;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
getFilterString() {
|
|
26
|
+
const startDate = this._startDate.get();
|
|
27
|
+
const endDate = this._endDate.get();
|
|
28
|
+
if (startDate && endDate) {
|
|
29
|
+
return `(${this._fieldName} >= '${startDate.toISOString()}' AND ${this._fieldName} <= '${endDate.toISOString()}')`;
|
|
30
|
+
} else if (startDate) {
|
|
31
|
+
return `${this._fieldName} >= '${startDate.toISOString()}'`;
|
|
32
|
+
} else if (endDate) {
|
|
33
|
+
return `${this._fieldName} <= '${endDate.toISOString()}'`;
|
|
34
|
+
}
|
|
35
|
+
return '';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
onChange(handler: () => void) {
|
|
39
|
+
this._onChangeHandlers.add(handler);
|
|
40
|
+
return () => {
|
|
41
|
+
this._onChangeHandlers.delete(handler);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setStartDate(startDate: Date | null) {
|
|
46
|
+
this._startDate.set(startDate);
|
|
47
|
+
this._onChangeHandlers.forEach(handler => handler());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setEndDate(endDate: Date | null) {
|
|
51
|
+
this._endDate.set(endDate);
|
|
52
|
+
this._onChangeHandlers.forEach(handler => handler());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
setFieldRegistry(fieldFilterRegistry: FieldFilterRegistry) {
|
|
56
|
+
this._fieldFilterRegistry = fieldFilterRegistry;
|
|
57
|
+
fieldFilterRegistry.registerFieldFilter(this._fieldName, this);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
setFilterState(filterAst: Node) {
|
|
61
|
+
const fieldNodes = filterAst.findAll(
|
|
62
|
+
(n: Node) => n.name === 'plain-field' && n.value === this._fieldName
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
if (fieldNodes.length === 0) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (fieldNodes.length === 1) {
|
|
70
|
+
const operatorNode = fieldNodes[0].parent?.children[1];
|
|
71
|
+
const valueNode = fieldNodes[0].parent?.children[2];
|
|
72
|
+
if (operatorNode?.value === '>=' && valueNode != null) {
|
|
73
|
+
this.setStartDate(new Date(valueNode?.value.slice(1, -1)));
|
|
74
|
+
} else if (operatorNode?.value === '<=' && valueNode != null) {
|
|
75
|
+
this.setEndDate(new Date(valueNode?.value.slice(1, -1)));
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (fieldNodes.length === 2) {
|
|
81
|
+
const operatorOneNode = fieldNodes[0].parent?.children[1];
|
|
82
|
+
const operatorTwoNode = fieldNodes[1].parent?.children[1];
|
|
83
|
+
const valueOneNode = fieldNodes[0].parent?.children[2];
|
|
84
|
+
const valueTwoNode = fieldNodes[1].parent?.children[2];
|
|
85
|
+
if (
|
|
86
|
+
operatorOneNode?.value === '>=' &&
|
|
87
|
+
operatorTwoNode?.value === '<=' &&
|
|
88
|
+
valueOneNode != null &&
|
|
89
|
+
valueTwoNode != null
|
|
90
|
+
) {
|
|
91
|
+
this.setStartDate(new Date(valueOneNode?.value.slice(1, -1)));
|
|
92
|
+
this.setEndDate(new Date(valueTwoNode?.value.slice(1, -1)));
|
|
93
|
+
} else if (
|
|
94
|
+
operatorOneNode?.value === '<=' &&
|
|
95
|
+
operatorTwoNode?.value === '>=' &&
|
|
96
|
+
valueOneNode != null &&
|
|
97
|
+
valueTwoNode != null
|
|
98
|
+
) {
|
|
99
|
+
this.setEndDate(new Date(valueOneNode?.value.slice(1, -1)));
|
|
100
|
+
this.setStartDate(new Date(valueTwoNode?.value.slice(1, -1)));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
dispose() {
|
|
106
|
+
this._fieldFilterRegistry?.unregisterFieldFilter(this._fieldName);
|
|
107
|
+
this._fieldFilterRegistry = null;
|
|
108
|
+
this._onChangeHandlers.clear();
|
|
109
|
+
}
|
|
110
|
+
}
|