@tcn/ui-table 2.3.7 → 2.3.9
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/dist/components/table_filter_panel/field_filters/clear_button.d.ts +5 -0
- package/dist/components/table_filter_panel/field_filters/clear_button.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/clear_button.js +15 -0
- package/dist/components/table_filter_panel/field_filters/clear_button.js.map +1 -0
- package/dist/components/table_filter_panel/field_filters/clearable_field.d.ts +9 -0
- package/dist/components/table_filter_panel/field_filters/clearable_field.d.ts.map +1 -0
- package/dist/components/table_filter_panel/field_filters/clearable_field.js +28 -0
- package/dist/components/table_filter_panel/field_filters/clearable_field.js.map +1 -0
- package/dist/components/table_filter_panel/field_filters/date_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/date_field_filter.js +45 -54
- package/dist/components/table_filter_panel/field_filters/date_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js +25 -28
- package/dist/components/table_filter_panel/field_filters/mulit_select_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_field_filter.js +37 -44
- package/dist/components/table_filter_panel/field_filters/number_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js +46 -55
- package/dist/components/table_filter_panel/field_filters/number_range_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/select_field_filter.js +19 -22
- package/dist/components/table_filter_panel/field_filters/select_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter.d.ts.map +1 -1
- package/dist/components/table_filter_panel/field_filters/string_field_filter.js +45 -53
- package/dist/components/table_filter_panel/field_filters/string_field_filter.js.map +1 -1
- package/dist/components/table_filter_panel/table_filter_panel.d.ts +4 -3
- package/dist/components/table_filter_panel/table_filter_panel.d.ts.map +1 -1
- package/dist/components/table_filter_panel/table_filter_panel.js +38 -10
- package/dist/components/table_filter_panel/table_filter_panel.js.map +1 -1
- package/dist/table_filter_panel.css +1 -0
- package/package.json +4 -4
- package/src/__stories__/table.stories.tsx +5 -2
- package/src/components/table_filter_panel/field_filters/clear_button.tsx +17 -0
- package/src/components/table_filter_panel/field_filters/clearable_field.tsx +33 -0
- package/src/components/table_filter_panel/field_filters/date_field_filter.tsx +26 -50
- package/src/components/table_filter_panel/field_filters/mulit_select_field_filter.tsx +3 -9
- package/src/components/table_filter_panel/field_filters/number_field_filter.tsx +10 -20
- package/src/components/table_filter_panel/field_filters/number_range_field_filter.tsx +29 -48
- package/src/components/table_filter_panel/field_filters/select_field_filter.tsx +3 -9
- package/src/components/table_filter_panel/field_filters/string_field_filter.tsx +10 -21
- package/src/components/table_filter_panel/table_filter_panel.module.css +11 -0
- package/src/components/table_filter_panel/table_filter_panel.tsx +33 -4
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
import { jsxs as i, jsx as l } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const t = g(F, n), a = s(t.broadcasts.value), c = r.find((e) => e.value === a)?.label ?? "";
|
|
2
|
+
import { useSignalValue as d } from "@tcn/state";
|
|
3
|
+
import { Select as s, Option as f } from "@tcn/ui/inputs";
|
|
4
|
+
import { VStack as b, Box as h, HStack as p } from "@tcn/ui/stacks";
|
|
5
|
+
import { Title as v } from "@tcn/ui/typography";
|
|
6
|
+
import { SelectFieldFilterPresenter as S } from "./select_field_filter_presenter.js";
|
|
7
|
+
import { useFieldFilterStrategy as x } from "./use_field_filter_strategy.js";
|
|
8
|
+
import { ClearFilterButton as F } from "./clear_button.js";
|
|
9
|
+
function z({ fieldName: n, label: u, options: r }) {
|
|
10
|
+
const t = x(S, n), a = d(t.broadcasts.value), o = r.find((e) => e.value === a)?.label ?? "";
|
|
12
11
|
return /* @__PURE__ */ i(b, { gap: "4px", children: [
|
|
13
|
-
/* @__PURE__ */ l(
|
|
14
|
-
/* @__PURE__ */ i(
|
|
12
|
+
/* @__PURE__ */ l(h, { width: "flex", children: /* @__PURE__ */ l(v, { size: "md", children: u }) }),
|
|
13
|
+
/* @__PURE__ */ i(p, { children: [
|
|
15
14
|
/* @__PURE__ */ l(
|
|
16
|
-
|
|
15
|
+
s,
|
|
17
16
|
{
|
|
18
|
-
value:
|
|
17
|
+
value: o,
|
|
19
18
|
onChange: (e) => {
|
|
20
|
-
const
|
|
21
|
-
t.setValue(
|
|
19
|
+
const c = r.find((m) => m.label === e)?.value;
|
|
20
|
+
t.setValue(c ?? null);
|
|
22
21
|
},
|
|
23
22
|
width: "flex",
|
|
24
23
|
children: r.map((e) => /* @__PURE__ */ l(
|
|
25
|
-
|
|
24
|
+
f,
|
|
26
25
|
{
|
|
27
26
|
value: e.label,
|
|
28
27
|
label: e.label,
|
|
@@ -33,18 +32,16 @@ function I({ fieldName: n, label: o, options: r }) {
|
|
|
33
32
|
}
|
|
34
33
|
),
|
|
35
34
|
/* @__PURE__ */ l(
|
|
36
|
-
|
|
35
|
+
F,
|
|
37
36
|
{
|
|
38
37
|
onClick: () => t.setValue(null),
|
|
39
|
-
|
|
40
|
-
disabled: a == null,
|
|
41
|
-
children: /* @__PURE__ */ l(d, {})
|
|
38
|
+
disabled: a == null
|
|
42
39
|
}
|
|
43
40
|
)
|
|
44
41
|
] })
|
|
45
42
|
] });
|
|
46
43
|
}
|
|
47
44
|
export {
|
|
48
|
-
|
|
45
|
+
z as SelectFieldFilter
|
|
49
46
|
};
|
|
50
47
|
//# sourceMappingURL=select_field_filter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select_field_filter.js","sources":["../../../../src/components/table_filter_panel/field_filters/select_field_filter.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"select_field_filter.js","sources":["../../../../src/components/table_filter_panel/field_filters/select_field_filter.tsx"],"sourcesContent":["import { useSignalValue } from '@tcn/state';\nimport { Option, Select } from '@tcn/ui/inputs';\nimport { Box, HStack, VStack } from '@tcn/ui/stacks';\nimport { Title } from '@tcn/ui/typography';\nimport { FieldFilterProps } from './field_filter_props.js';\nimport { SelectFieldFilterPresenter } from './select_field_filter_presenter.js';\nimport { useFieldFilterStrategy } from './use_field_filter_strategy.js';\nimport { ClearFilterButton } from './clear_button.js';\n\nexport type SelectFieldFilterProps = FieldFilterProps & {\n options: { label: string; value: string | boolean | number }[];\n};\n\nexport function SelectFieldFilter({ fieldName, label, options }: SelectFieldFilterProps) {\n const presenter = useFieldFilterStrategy(SelectFieldFilterPresenter, fieldName);\n\n const value = useSignalValue(presenter.broadcasts.value);\n const valueLabel = options.find(option => option.value === value)?.label ?? '';\n\n return (\n <VStack gap=\"4px\">\n <Box width=\"flex\">\n <Title size=\"md\">{label}</Title>\n </Box>\n <HStack>\n <Select\n value={valueLabel}\n onChange={value => {\n const realValue = options.find(option => option.label === value)?.value;\n presenter.setValue(realValue ?? null);\n }}\n width=\"flex\"\n >\n {options.map(option => (\n <Option\n key={option.value.toString()}\n value={option.label}\n label={option.label}\n >\n {option.label}\n </Option>\n ))}\n </Select>\n <ClearFilterButton\n onClick={() => presenter.setValue(null)}\n disabled={value == null}\n />\n </HStack>\n </VStack>\n );\n}\n"],"names":["SelectFieldFilter","fieldName","label","options","presenter","useFieldFilterStrategy","SelectFieldFilterPresenter","value","useSignalValue","valueLabel","option","jsxs","VStack","jsx","Box","Title","HStack","Select","realValue","Option","ClearFilterButton"],"mappings":";;;;;;;;AAaO,SAASA,EAAkB,EAAE,WAAAC,GAAW,OAAAC,GAAO,SAAAC,KAAmC;AACvF,QAAMC,IAAYC,EAAuBC,GAA4BL,CAAS,GAExEM,IAAQC,EAAeJ,EAAU,WAAW,KAAK,GACjDK,IAAaN,EAAQ,KAAK,CAAAO,MAAUA,EAAO,UAAUH,CAAK,GAAG,SAAS;AAE5E,SACE,gBAAAI,EAACC,GAAA,EAAO,KAAI,OACV,UAAA;AAAA,IAAA,gBAAAC,EAACC,GAAA,EAAI,OAAM,QACT,UAAA,gBAAAD,EAACE,KAAM,MAAK,MAAM,aAAM,EAAA,CAC1B;AAAA,sBACCC,GAAA,EACC,UAAA;AAAA,MAAA,gBAAAH;AAAA,QAACI;AAAA,QAAA;AAAA,UACC,OAAOR;AAAA,UACP,UAAU,CAAAF,MAAS;AACjB,kBAAMW,IAAYf,EAAQ,KAAK,OAAUO,EAAO,UAAUH,CAAK,GAAG;AAClE,YAAAH,EAAU,SAASc,KAAa,IAAI;AAAA,UACtC;AAAA,UACA,OAAM;AAAA,UAEL,UAAAf,EAAQ,IAAI,CAAAO,MACX,gBAAAG;AAAA,YAACM;AAAA,YAAA;AAAA,cAEC,OAAOT,EAAO;AAAA,cACd,OAAOA,EAAO;AAAA,cAEb,UAAAA,EAAO;AAAA,YAAA;AAAA,YAJHA,EAAO,MAAM,SAAA;AAAA,UAAS,CAM9B;AAAA,QAAA;AAAA,MAAA;AAAA,MAEH,gBAAAG;AAAA,QAACO;AAAA,QAAA;AAAA,UACC,SAAS,MAAMhB,EAAU,SAAS,IAAI;AAAA,UACtC,UAAUG,KAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IACrB,EAAA,CACF;AAAA,EAAA,GACF;AAEJ;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string_field_filter.d.ts","sourceRoot":"","sources":["../../../../src/components/table_filter_panel/field_filters/string_field_filter.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"string_field_filter.d.ts","sourceRoot":"","sources":["../../../../src/components/table_filter_panel/field_filters/string_field_filter.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAmB3D,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CAsClF"}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import { StringFieldFilterPresenter as v } from "./string_field_filter_presenter.js";
|
|
9
|
-
import { useFieldFilterStrategy as y } from "./use_field_filter_strategy.js";
|
|
10
|
-
const F = ["is", "isNot", "has"], C = {
|
|
1
|
+
import { jsx as r, jsxs as c } from "react/jsx-runtime";
|
|
2
|
+
import { useSignalValue as o } from "@tcn/state";
|
|
3
|
+
import { InputGroup as m, Select as d, Option as h, Input as b } from "@tcn/ui/inputs";
|
|
4
|
+
import { StringFieldFilterPresenter as f } from "./string_field_filter_presenter.js";
|
|
5
|
+
import { useFieldFilterStrategy as F } from "./use_field_filter_strategy.js";
|
|
6
|
+
import { ClearableField as g } from "./clearable_field.js";
|
|
7
|
+
const v = ["is", "isNot", "has"], S = {
|
|
11
8
|
is: "=",
|
|
12
9
|
isNot: "!=",
|
|
13
10
|
has: ":"
|
|
@@ -16,50 +13,45 @@ const F = ["is", "isNot", "has"], C = {
|
|
|
16
13
|
isNot: "is not",
|
|
17
14
|
has: "has"
|
|
18
15
|
};
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
return /* @__PURE__ */
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
children: /* @__PURE__ */ e(m, {})
|
|
57
|
-
}
|
|
58
|
-
)
|
|
59
|
-
] })
|
|
60
|
-
] });
|
|
16
|
+
function j({ fieldName: a, label: i, operators: n }) {
|
|
17
|
+
const t = F(f, a), l = o(t.broadcasts.value), p = o(t.broadcasts.operator), u = n || v;
|
|
18
|
+
return /* @__PURE__ */ r(
|
|
19
|
+
g,
|
|
20
|
+
{
|
|
21
|
+
label: i,
|
|
22
|
+
onClear: () => t.setValue(null),
|
|
23
|
+
isClearable: l == null,
|
|
24
|
+
children: /* @__PURE__ */ c(m, { children: [
|
|
25
|
+
/* @__PURE__ */ r(
|
|
26
|
+
d,
|
|
27
|
+
{
|
|
28
|
+
value: p,
|
|
29
|
+
onChange: (e) => t.setOperator(e),
|
|
30
|
+
width: "65px",
|
|
31
|
+
children: u.map((e) => /* @__PURE__ */ r(
|
|
32
|
+
h,
|
|
33
|
+
{
|
|
34
|
+
value: S[e],
|
|
35
|
+
label: s[e],
|
|
36
|
+
children: s[e]
|
|
37
|
+
},
|
|
38
|
+
e
|
|
39
|
+
))
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ r(
|
|
43
|
+
b,
|
|
44
|
+
{
|
|
45
|
+
type: "text",
|
|
46
|
+
value: l ?? "",
|
|
47
|
+
onChange: (e) => t.setValue(e)
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
] })
|
|
51
|
+
}
|
|
52
|
+
);
|
|
61
53
|
}
|
|
62
54
|
export {
|
|
63
|
-
|
|
55
|
+
j as StringFieldFilter
|
|
64
56
|
};
|
|
65
57
|
//# sourceMappingURL=string_field_filter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string_field_filter.js","sources":["../../../../src/components/table_filter_panel/field_filters/string_field_filter.tsx"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"string_field_filter.js","sources":["../../../../src/components/table_filter_panel/field_filters/string_field_filter.tsx"],"sourcesContent":["import { useSignalValue } from '@tcn/state';\nimport { Input, Option, Select, InputGroup } from '@tcn/ui/inputs';\nimport { FieldFilterProps } from './field_filter_props.js';\nimport { StringFieldFilterPresenter } from './string_field_filter_presenter.js';\nimport { ComparisonOperator } from '../types.js';\n\nimport { useFieldFilterStrategy } from './use_field_filter_strategy.js';\nimport { ClearableField } from './clearable_field.js';\n\nconst allOperators: ('is' | 'isNot' | 'has')[] = ['is', 'isNot', 'has'];\nconst operatorSymbols: Record<'is' | 'isNot' | 'has', string> = {\n is: '=',\n isNot: '!=',\n has: ':',\n};\nconst operatorLabels: Record<'is' | 'isNot' | 'has', string> = {\n is: 'is',\n isNot: 'is not',\n has: 'has',\n};\n\nexport function StringFieldFilter({ fieldName, label, operators }: FieldFilterProps) {\n const presenter = useFieldFilterStrategy(StringFieldFilterPresenter, fieldName);\n\n const value = useSignalValue(presenter.broadcasts.value);\n const operator = useSignalValue(presenter.broadcasts.operator);\n\n const availableOperators = operators || allOperators;\n\n return (\n <ClearableField\n label={label}\n onClear={() => presenter.setValue(null)}\n isClearable={value == null}\n >\n <InputGroup>\n <Select\n value={operator}\n onChange={value => presenter.setOperator(value as ComparisonOperator)}\n width=\"65px\"\n >\n {availableOperators.map(operator => (\n <Option\n key={operator}\n value={operatorSymbols[operator]}\n label={operatorLabels[operator]}\n >\n {operatorLabels[operator]}\n </Option>\n ))}\n </Select>\n <Input\n type=\"text\"\n value={value ?? ''}\n onChange={value => presenter.setValue(value)}\n />\n </InputGroup>\n </ClearableField>\n );\n}\n"],"names":["allOperators","operatorSymbols","operatorLabels","StringFieldFilter","fieldName","label","operators","presenter","useFieldFilterStrategy","StringFieldFilterPresenter","value","useSignalValue","operator","availableOperators","jsx","ClearableField","InputGroup","Select","Option","Input"],"mappings":";;;;;;AASA,MAAMA,IAA2C,CAAC,MAAM,SAAS,KAAK,GAChEC,IAA0D;AAAA,EAC9D,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AACP,GACMC,IAAyD;AAAA,EAC7D,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AACP;AAEO,SAASC,EAAkB,EAAE,WAAAC,GAAW,OAAAC,GAAO,WAAAC,KAA+B;AACnF,QAAMC,IAAYC,EAAuBC,GAA4BL,CAAS,GAExEM,IAAQC,EAAeJ,EAAU,WAAW,KAAK,GACjDK,IAAWD,EAAeJ,EAAU,WAAW,QAAQ,GAEvDM,IAAqBP,KAAaN;AAExC,SACE,gBAAAc;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,OAAAV;AAAA,MACA,SAAS,MAAME,EAAU,SAAS,IAAI;AAAA,MACtC,aAAaG,KAAS;AAAA,MAEtB,4BAACM,GAAA,EACC,UAAA;AAAA,QAAA,gBAAAF;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,OAAOL;AAAA,YACP,UAAU,CAAAF,MAASH,EAAU,YAAYG,CAA2B;AAAA,YACpE,OAAM;AAAA,YAEL,UAAAG,EAAmB,IAAI,CAAAD,MACtB,gBAAAE;AAAA,cAACI;AAAA,cAAA;AAAA,gBAEC,OAAOjB,EAAgBW,CAAQ;AAAA,gBAC/B,OAAOV,EAAeU,CAAQ;AAAA,gBAE7B,YAAeA,CAAQ;AAAA,cAAA;AAAA,cAJnBA;AAAAA,YAAA,CAMR;AAAA,UAAA;AAAA,QAAA;AAAA,QAEH,gBAAAE;AAAA,UAACK;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,OAAOT,KAAS;AAAA,YAChB,UAAU,CAAAA,MAASH,EAAU,SAASG,CAAK;AAAA,UAAA;AAAA,QAAA;AAAA,MAC7C,EAAA,CACF;AAAA,IAAA;AAAA,EAAA;AAGN;"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { DataSource } from '@tcn/resource-store';
|
|
2
|
-
import {
|
|
2
|
+
import { ReactElement } from 'react';
|
|
3
3
|
import { FieldFilterProps } from './field_filters/field_filter_props.js';
|
|
4
4
|
import { TableFilterPanelPresenter } from './table_filter_panel_presenter.js';
|
|
5
5
|
export type TableFilterPanelProps = {
|
|
6
6
|
children: ReactElement<FieldFilterProps>[] | ReactElement<FieldFilterProps>;
|
|
7
7
|
dataSource: DataSource<any>;
|
|
8
|
+
onClose?: () => void;
|
|
8
9
|
};
|
|
9
|
-
export declare function TableFilterPanel({ children, dataSource }: TableFilterPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
export declare const TableFilterPanelContext:
|
|
10
|
+
export declare function TableFilterPanel({ children, dataSource, onClose, }: TableFilterPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const TableFilterPanelContext: import('react').Context<TableFilterPanelPresenter<unknown> | null>;
|
|
11
12
|
//# sourceMappingURL=table_filter_panel.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table_filter_panel.d.ts","sourceRoot":"","sources":["../../../src/components/table_filter_panel/table_filter_panel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"table_filter_panel.d.ts","sourceRoot":"","sources":["../../../src/components/table_filter_panel/table_filter_panel.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,YAAY,EAA2B,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAQ9E,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,YAAY,CAAC,gBAAgB,CAAC,EAAE,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;IAC5E,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,UAAU,EACV,OAAO,GACR,EAAE,qBAAqB,2CA6BvB;AAED,eAAO,MAAM,uBAAuB,oEAEnC,CAAC"}
|
|
@@ -1,16 +1,44 @@
|
|
|
1
|
-
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { jsx as e, jsxs as r } from "react/jsx-runtime";
|
|
2
|
+
import { createContext as o, useState as c } from "react";
|
|
3
|
+
import { TableFilterPanelPresenter as s } from "./table_filter_panel_presenter.js";
|
|
4
|
+
import { Panel as b } from "@tcn/ui/surfaces";
|
|
5
|
+
import { Header as p, VBody as f, Section as m } from "@tcn/ui/layouts";
|
|
6
|
+
import { Spacer as d } from "@tcn/ui/stacks";
|
|
7
|
+
import { Button as y } from "@tcn/ui/actions";
|
|
8
|
+
import { CrossIcon as u } from "@tcn/icons/cross_icon.js";
|
|
9
|
+
import '../../table_filter_panel.css';const P = "_table-filter-panel_124e30e", h = "_table-filter-panel-body_c016eb0", F = "_table-filter-panel-section_cfd2eb9", t = { "table-filter-panel": P, "table-filter-panel-body": h, "table-filter-panel-section": F };
|
|
10
|
+
function v({
|
|
11
|
+
children: a,
|
|
12
|
+
dataSource: n,
|
|
13
|
+
onClose: l
|
|
14
|
+
}) {
|
|
15
|
+
const [i] = c(() => new s(n));
|
|
16
|
+
return /* @__PURE__ */ e(_.Provider, { value: i, children: /* @__PURE__ */ r(b, { className: `${t["table-filter-panel"]} tcn-table-filter-panel`, children: [
|
|
17
|
+
/* @__PURE__ */ r(p, { children: [
|
|
18
|
+
"Table Filters",
|
|
19
|
+
/* @__PURE__ */ e(d, {}),
|
|
20
|
+
l && /* @__PURE__ */ e(y, { utility: !0, hierarchy: "tertiary", onClick: l, children: /* @__PURE__ */ e(u, {}) })
|
|
21
|
+
] }),
|
|
22
|
+
/* @__PURE__ */ e(
|
|
23
|
+
f,
|
|
24
|
+
{
|
|
25
|
+
className: `${t["table-filter-panel-body"]} tcn-table-filter-panel-body`,
|
|
26
|
+
children: /* @__PURE__ */ e(
|
|
27
|
+
m,
|
|
28
|
+
{
|
|
29
|
+
className: `${t["table-filter-panel-section"]} tcn-table-filter-panel-section`,
|
|
30
|
+
children: a
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
] }) });
|
|
8
36
|
}
|
|
9
|
-
const
|
|
37
|
+
const _ = o(
|
|
10
38
|
null
|
|
11
39
|
);
|
|
12
40
|
export {
|
|
13
|
-
|
|
14
|
-
|
|
41
|
+
v as TableFilterPanel,
|
|
42
|
+
_ as TableFilterPanelContext
|
|
15
43
|
};
|
|
16
44
|
//# sourceMappingURL=table_filter_panel.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table_filter_panel.js","sources":["../../../src/components/table_filter_panel/table_filter_panel.tsx"],"sourcesContent":["import { DataSource } from '@tcn/resource-store';\nimport {
|
|
1
|
+
{"version":3,"file":"table_filter_panel.js","sources":["../../../src/components/table_filter_panel/table_filter_panel.tsx"],"sourcesContent":["import { DataSource } from '@tcn/resource-store';\nimport { ReactElement, useState, createContext } from 'react';\nimport { FieldFilterProps } from './field_filters/field_filter_props.js';\nimport { TableFilterPanelPresenter } from './table_filter_panel_presenter.js';\nimport { Panel } from '@tcn/ui/surfaces';\nimport { Header, Section, VBody } from '@tcn/ui/layouts';\nimport styles from './table_filter_panel.module.css';\nimport { Spacer } from '@tcn/ui/stacks';\nimport { Button } from '@tcn/ui/actions';\nimport { CrossIcon } from '@tcn/icons/cross_icon.js';\n\nexport type TableFilterPanelProps = {\n children: ReactElement<FieldFilterProps>[] | ReactElement<FieldFilterProps>;\n dataSource: DataSource<any>;\n onClose?: () => void;\n};\n\nexport function TableFilterPanel({\n children,\n dataSource,\n onClose,\n}: TableFilterPanelProps) {\n const [presenter] = useState(() => {\n return new TableFilterPanelPresenter(dataSource);\n });\n\n return (\n <TableFilterPanelContext.Provider value={presenter}>\n <Panel className={`${styles['table-filter-panel']} tcn-table-filter-panel`}>\n <Header>\n Table Filters\n <Spacer />\n {onClose && (\n <Button utility hierarchy=\"tertiary\" onClick={onClose}>\n <CrossIcon />\n </Button>\n )}\n </Header>\n <VBody\n className={`${styles['table-filter-panel-body']} tcn-table-filter-panel-body`}\n >\n <Section\n className={`${styles['table-filter-panel-section']} tcn-table-filter-panel-section`}\n >\n {children}\n </Section>\n </VBody>\n </Panel>\n </TableFilterPanelContext.Provider>\n );\n}\n\nexport const TableFilterPanelContext = createContext<TableFilterPanelPresenter | null>(\n null\n);\n"],"names":["TableFilterPanel","children","dataSource","onClose","presenter","useState","TableFilterPanelPresenter","jsx","TableFilterPanelContext","jsxs","Panel","styles","Header","Spacer","Button","CrossIcon","VBody","Section","createContext"],"mappings":";;;;;;;;;AAiBO,SAASA,EAAiB;AAAA,EAC/B,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,SAAAC;AACF,GAA0B;AACxB,QAAM,CAACC,CAAS,IAAIC,EAAS,MACpB,IAAIC,EAA0BJ,CAAU,CAChD;AAED,SACE,gBAAAK,EAACC,EAAwB,UAAxB,EAAiC,OAAOJ,GACvC,UAAA,gBAAAK,EAACC,GAAA,EAAM,WAAW,GAAGC,EAAO,oBAAoB,CAAC,2BAC/C,UAAA;AAAA,IAAA,gBAAAF,EAACG,GAAA,EAAO,UAAA;AAAA,MAAA;AAAA,wBAELC,GAAA,EAAO;AAAA,MACPV,KACC,gBAAAI,EAACO,GAAA,EAAO,SAAO,IAAC,WAAU,YAAW,SAASX,GAC5C,UAAA,gBAAAI,EAACQ,GAAA,CAAA,CAAU,EAAA,CACb;AAAA,IAAA,GAEJ;AAAA,IACA,gBAAAR;AAAA,MAACS;AAAA,MAAA;AAAA,QACC,WAAW,GAAGL,EAAO,yBAAyB,CAAC;AAAA,QAE/C,UAAA,gBAAAJ;AAAA,UAACU;AAAA,UAAA;AAAA,YACC,WAAW,GAAGN,EAAO,4BAA4B,CAAC;AAAA,YAEjD,UAAAV;AAAA,UAAA;AAAA,QAAA;AAAA,MACH;AAAA,IAAA;AAAA,EACF,EAAA,CACF,EAAA,CACF;AAEJ;AAEO,MAAMO,IAA0BU;AAAA,EACrC;AACF;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
._table-filter-panel_124e30e{--material: #fafafa;background:var(--material)}._table-filter-panel-body_c016eb0{padding-block:8px}._table-filter-panel-body_c016eb0 ._table-filter-panel-section_cfd2eb9{gap:8px}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tcn/ui-table",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.9",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "React table component library",
|
|
6
6
|
"author": "TCN",
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"clarity-pattern-parser": "^11.5.4",
|
|
42
|
+
"@tcn/icons": "2.3.0",
|
|
42
43
|
"@tcn/aip-160": "1.2.5",
|
|
43
|
-
"@tcn/icons": "2.2.1",
|
|
44
44
|
"@tcn/state": "1.2.0",
|
|
45
|
-
"@tcn/
|
|
46
|
-
"@tcn/
|
|
45
|
+
"@tcn/resource-store": "2.5.1",
|
|
46
|
+
"@tcn/ui": "0.12.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"react": "^18.2.0",
|
|
@@ -413,7 +413,7 @@ export function WithFilterPanel() {
|
|
|
413
413
|
<Header>The Table</Header>
|
|
414
414
|
<VBody>
|
|
415
415
|
<Rail>
|
|
416
|
-
<Side>
|
|
416
|
+
<Side padding="0px">
|
|
417
417
|
<Box
|
|
418
418
|
minWidth="300px"
|
|
419
419
|
enableResizeOnEnd
|
|
@@ -423,7 +423,10 @@ export function WithFilterPanel() {
|
|
|
423
423
|
scrollbarGutter: 'stable', // Not sure if there is a better way to prevent the scrollbar appearing causing a horizontal scroll - to to resizing, we fix the width of the content, so adding a vertical scrollbar causing a horizontal overflow.
|
|
424
424
|
}}
|
|
425
425
|
>
|
|
426
|
-
<TableFilterPanel
|
|
426
|
+
<TableFilterPanel
|
|
427
|
+
dataSource={source}
|
|
428
|
+
onClose={() => window.alert('Closed')}
|
|
429
|
+
>
|
|
427
430
|
<StringFieldFilter fieldName="name" label="Name (string)" />
|
|
428
431
|
<NumberFieldFilter fieldName="age" label="Age (number)" />
|
|
429
432
|
<DateFieldFilter fieldName="birthdate" label="Birthdate (date range)" />
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
|
|
2
|
+
import { Button, type ButtonProps } from '@tcn/ui/actions';
|
|
3
|
+
|
|
4
|
+
export interface ClearFilterButtonProps extends Omit<ButtonProps, 'children'> {}
|
|
5
|
+
|
|
6
|
+
export function ClearFilterButton({
|
|
7
|
+
onClick,
|
|
8
|
+
hierarchy = 'tertiary',
|
|
9
|
+
utility = true,
|
|
10
|
+
...props
|
|
11
|
+
}: ClearFilterButtonProps) {
|
|
12
|
+
return (
|
|
13
|
+
<Button utility={utility} onClick={onClick} hierarchy={hierarchy} {...props}>
|
|
14
|
+
<CrossCircleIcon />
|
|
15
|
+
</Button>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { HStack, VStack, type VStackProps } from '@tcn/ui/stacks';
|
|
2
|
+
import { ClearFilterButton } from './clear_button.js';
|
|
3
|
+
import { FieldLabel } from '@tcn/ui/form';
|
|
4
|
+
|
|
5
|
+
export interface ClearableFieldProps extends VStackProps {
|
|
6
|
+
label?: string;
|
|
7
|
+
onClear?: () => void;
|
|
8
|
+
isClearable?: boolean;
|
|
9
|
+
inline?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function ClearableField({
|
|
13
|
+
children,
|
|
14
|
+
label,
|
|
15
|
+
onClear,
|
|
16
|
+
isClearable,
|
|
17
|
+
vAlign = 'start',
|
|
18
|
+
hAlign = 'start',
|
|
19
|
+
gap = '4px',
|
|
20
|
+
inline = false,
|
|
21
|
+
...props
|
|
22
|
+
}: ClearableFieldProps) {
|
|
23
|
+
return (
|
|
24
|
+
<VStack vAlign={vAlign} hAlign={hAlign} gap={gap} {...props}>
|
|
25
|
+
{!inline && <FieldLabel>{label}</FieldLabel>}
|
|
26
|
+
<HStack width="flex" gap="4px">
|
|
27
|
+
{inline && <FieldLabel>{label}</FieldLabel>}
|
|
28
|
+
<HStack width="flex">{children}</HStack>
|
|
29
|
+
<ClearFilterButton onClick={onClear} disabled={isClearable} />
|
|
30
|
+
</HStack>
|
|
31
|
+
</VStack>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
|
|
2
1
|
import { useSignalValue } from '@tcn/state';
|
|
3
|
-
import { Button } from '@tcn/ui/actions';
|
|
4
2
|
import { DatePickerInput } from '@tcn/ui/inputs';
|
|
5
|
-
import { Box, HStack, VStack } from '@tcn/ui/stacks';
|
|
6
|
-
import { BodyText, Title } from '@tcn/ui/typography';
|
|
7
|
-
import React from 'react';
|
|
8
3
|
import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
|
|
9
4
|
import { DateFieldFilterPresenter } from './date_field_filter_presenter.js';
|
|
5
|
+
import { ClearableField } from './clearable_field.js';
|
|
6
|
+
import { FieldSet } from '@tcn/ui/form';
|
|
10
7
|
|
|
11
8
|
export function DateFieldFilter({
|
|
12
9
|
fieldName,
|
|
@@ -21,50 +18,29 @@ export function DateFieldFilter({
|
|
|
21
18
|
const endDate = useSignalValue(presenter.broadcasts.endDate);
|
|
22
19
|
|
|
23
20
|
return (
|
|
24
|
-
<
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
<HStack gap="4px">
|
|
49
|
-
<Box width="auto">
|
|
50
|
-
<BodyText size="lg">End</BodyText>
|
|
51
|
-
</Box>
|
|
52
|
-
<Box width="flex">
|
|
53
|
-
<DatePickerInput
|
|
54
|
-
value={endDate}
|
|
55
|
-
onChange={value => presenter.setEndDate(value)}
|
|
56
|
-
/>
|
|
57
|
-
</Box>
|
|
58
|
-
<Box width="auto">
|
|
59
|
-
<Button
|
|
60
|
-
onClick={() => presenter.setEndDate(null)}
|
|
61
|
-
hierarchy="tertiary"
|
|
62
|
-
disabled={endDate == null}
|
|
63
|
-
>
|
|
64
|
-
<CrossCircleIcon />
|
|
65
|
-
</Button>
|
|
66
|
-
</Box>
|
|
67
|
-
</HStack>
|
|
68
|
-
</VStack>
|
|
21
|
+
<FieldSet legend={label} gap="4px">
|
|
22
|
+
<ClearableField
|
|
23
|
+
inline
|
|
24
|
+
label="Start"
|
|
25
|
+
onClear={() => presenter.setStartDate(null)}
|
|
26
|
+
isClearable={startDate == null}
|
|
27
|
+
>
|
|
28
|
+
<DatePickerInput
|
|
29
|
+
value={startDate}
|
|
30
|
+
onChange={value => presenter.setStartDate(value)}
|
|
31
|
+
/>
|
|
32
|
+
</ClearableField>
|
|
33
|
+
<ClearableField
|
|
34
|
+
inline
|
|
35
|
+
label="End"
|
|
36
|
+
onClear={() => presenter.setEndDate(null)}
|
|
37
|
+
isClearable={endDate == null}
|
|
38
|
+
>
|
|
39
|
+
<DatePickerInput
|
|
40
|
+
value={endDate}
|
|
41
|
+
onChange={value => presenter.setEndDate(value)}
|
|
42
|
+
/>
|
|
43
|
+
</ClearableField>
|
|
44
|
+
</FieldSet>
|
|
69
45
|
);
|
|
70
46
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
|
|
4
1
|
import { useSignalValue } from '@tcn/state';
|
|
5
|
-
import { Button } from '@tcn/ui/actions';
|
|
6
2
|
import { Multiselect, Option } from '@tcn/ui/inputs';
|
|
7
3
|
import { Box, HStack, VStack } from '@tcn/ui/stacks';
|
|
8
4
|
import { Title } from '@tcn/ui/typography';
|
|
9
5
|
import { FieldFilterProps } from './field_filter_props.js';
|
|
10
6
|
import { MultiSelectFieldFilterPresenter } from './multi_select_field_filter_presenter.js';
|
|
11
7
|
import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
|
|
8
|
+
import { ClearFilterButton } from './clear_button.js';
|
|
12
9
|
|
|
13
10
|
export type MulitSelectFieldFilterProps = FieldFilterProps & {
|
|
14
11
|
options: { label: string; value: string | boolean | number }[];
|
|
@@ -55,13 +52,10 @@ export function MulitSelectFieldFilter({
|
|
|
55
52
|
))}
|
|
56
53
|
</Multiselect>
|
|
57
54
|
</Box>
|
|
58
|
-
<
|
|
55
|
+
<ClearFilterButton
|
|
59
56
|
onClick={() => presenter.setValue(null)}
|
|
60
|
-
hierarchy="tertiary"
|
|
61
57
|
disabled={values == null || values.length === 0}
|
|
62
|
-
|
|
63
|
-
<CrossCircleIcon />
|
|
64
|
-
</Button>
|
|
58
|
+
/>
|
|
65
59
|
</HStack>
|
|
66
60
|
</VStack>
|
|
67
61
|
);
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { CrossCircleIcon } from '@tcn/icons/cross_circle_icon.js';
|
|
2
1
|
import { useSignalValue } from '@tcn/state';
|
|
3
|
-
import {
|
|
4
|
-
import { Input, Option, Select } from '@tcn/ui/inputs';
|
|
5
|
-
import { Box, HStack, VStack } from '@tcn/ui/stacks';
|
|
6
|
-
import { Title } from '@tcn/ui/typography';
|
|
7
|
-
import React from 'react';
|
|
2
|
+
import { Input, Option, Select, InputGroup } from '@tcn/ui/inputs';
|
|
8
3
|
import { FieldFilterProps } from './field_filter_props.js';
|
|
9
4
|
import { NumberFieldFilterPresenter } from './number_field_filter_presenter.js';
|
|
10
5
|
import { useFieldFilterStrategy } from './use_field_filter_strategy.js';
|
|
11
6
|
import { ComparisonOperator } from '../types.js';
|
|
7
|
+
import { ClearableField } from './clearable_field.js';
|
|
12
8
|
|
|
13
9
|
const operators: ComparisonOperator[] = ['>=', '>', '<=', '<', '=', '!='];
|
|
14
10
|
|
|
@@ -19,11 +15,12 @@ export function NumberFieldFilter({ fieldName, label }: FieldFilterProps) {
|
|
|
19
15
|
const operator = useSignalValue(presenter.broadcasts.operator);
|
|
20
16
|
|
|
21
17
|
return (
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
<ClearableField
|
|
19
|
+
label={label}
|
|
20
|
+
onClear={() => presenter.setValue(null)}
|
|
21
|
+
isClearable={value == null}
|
|
22
|
+
>
|
|
23
|
+
<InputGroup>
|
|
27
24
|
<Select
|
|
28
25
|
value={operator}
|
|
29
26
|
onChange={value => presenter.setOperator(value as ComparisonOperator)}
|
|
@@ -40,14 +37,7 @@ export function NumberFieldFilter({ fieldName, label }: FieldFilterProps) {
|
|
|
40
37
|
value={String(value ?? '')}
|
|
41
38
|
onChange={value => presenter.setValue(Number(value))}
|
|
42
39
|
/>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
hierarchy="tertiary"
|
|
46
|
-
disabled={value == null}
|
|
47
|
-
>
|
|
48
|
-
<CrossCircleIcon />
|
|
49
|
-
</Button>
|
|
50
|
-
</HStack>
|
|
51
|
-
</VStack>
|
|
40
|
+
</InputGroup>
|
|
41
|
+
</ClearableField>
|
|
52
42
|
);
|
|
53
43
|
}
|