@monolith-forensics/monolith-ui 1.3.16 → 1.3.17
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/Button/Button.js +1 -1
- package/dist/DropDownMenu/DropDownMenu.js +7 -12
- package/dist/DropDownMenu/components/MenuItem.js +1 -1
- package/dist/DropDownMenu/components/MenuItemList.d.ts +6 -2
- package/dist/DropDownMenu/components/MenuItemList.js +97 -28
- package/dist/DropDownMenu/types.d.ts +16 -1
- package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +8 -0
- package/dist/QueryFilter/QueryFilter.js +47 -39
- package/dist/QueryFilter/index.d.ts +0 -1
- package/dist/QueryFilter/index.js +0 -1
- package/dist/QueryFilter/types.d.ts +3 -5
- package/dist/theme/variants.js +10 -0
- package/package.json +1 -1
- package/dist/QueryFilter/useFilterHelper.d.ts +0 -20
- package/dist/QueryFilter/useFilterHelper.js +0 -61
package/dist/Button/Button.js
CHANGED
|
@@ -103,7 +103,7 @@ const StyledButton = styled.button `
|
|
|
103
103
|
if (variant === "filled")
|
|
104
104
|
return "white";
|
|
105
105
|
if (color) {
|
|
106
|
-
return (((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.button) === null || _a === void 0 ? void 0 : _a.
|
|
106
|
+
return (((_b = (_a = theme === null || theme === void 0 ? void 0 : theme.button) === null || _a === void 0 ? void 0 : _a.text) === null || _b === void 0 ? void 0 : _b[color]) ||
|
|
107
107
|
colors[color] ||
|
|
108
108
|
theme.palette.text.primary);
|
|
109
109
|
}
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, size, searchable, loading, onScroll, multiselect, renderOption, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, }) => {
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
import { Menu, MenuItemList, StyledInnerItemContainer } from "./components";
|
|
4
|
+
export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, size, searchable, loading, onScroll, onScrollToTop, onScrollToBottom, onSearch, manualSearch, multiselect, renderOption, onItemSelect, onChange, buttonProps, TooltipContent, dropDownProps, query, }) => {
|
|
6
5
|
var _a;
|
|
7
6
|
const isObjectArray = (_a = Object.keys((data === null || data === void 0 ? void 0 : data[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
|
|
8
7
|
const [selected, setSelected] = useState(defaultValue || []);
|
|
9
|
-
const [searchValue, setSearchValue] = useState("");
|
|
10
|
-
const searchInputRef = useRef(null);
|
|
11
|
-
const handleSearch = useDebouncedCallback((e) => {
|
|
12
|
-
setSearchValue(e.target.value);
|
|
13
|
-
}, 150);
|
|
14
8
|
const handleAddItem = (item) => {
|
|
15
9
|
setSelected((prev) => {
|
|
16
10
|
let newSelected = [...prev, item];
|
|
@@ -27,8 +21,9 @@ export const DropDownMenu = ({ data, children, defaultValue, variant, arrow, siz
|
|
|
27
21
|
return newSelected;
|
|
28
22
|
});
|
|
29
23
|
};
|
|
30
|
-
const handleMenuClose = () => {
|
|
31
|
-
|
|
24
|
+
const handleMenuClose = () => { };
|
|
25
|
+
const handleScrollToBottom = (e) => {
|
|
26
|
+
onScrollToBottom === null || onScrollToBottom === void 0 ? void 0 : onScrollToBottom(e);
|
|
32
27
|
};
|
|
33
|
-
return (_jsx(Menu, { label: children, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }),
|
|
28
|
+
return (_jsx(Menu, { label: children, arrow: arrow, buttonSize: size, variant: variant, multiselect: multiselect, buttonProps: buttonProps, onMenuClose: handleMenuClose, dropDownProps: dropDownProps, children: _jsxs(StyledInnerItemContainer, { children: [loading && _jsx("div", { children: "Loading..." }), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, onSearch: onSearch, manualSearch: manualSearch, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll, onScrollToTop: onScrollToTop, onScrollToBottom: handleScrollToBottom, query: query }))] }) }));
|
|
34
29
|
};
|
|
@@ -25,7 +25,7 @@ export const MenuItem = styled(forwardRef((_a, forwardedRef) => {
|
|
|
25
25
|
return (_jsx(Tooltip, { content: TooltipContent ? _jsx(TooltipContent, { data: itemData }) : null, side: "left", children: _jsx(Button, Object.assign({}, props, { ref: useMergeRefs([
|
|
26
26
|
item.ref,
|
|
27
27
|
forwardedRef,
|
|
28
|
-
]), type: "button", role: "menuitem", tabIndex: isActive ? 0 : -1, disabled: disabled, justify: "start" }, menu.getItemProps({
|
|
28
|
+
]), type: "button", role: "menuitem", tabIndex: isActive ? 0 : -1, disabled: disabled, justify: "start", color: props.color }, menu.getItemProps({
|
|
29
29
|
onClick(event) {
|
|
30
30
|
var _a;
|
|
31
31
|
(_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { ComponentType } from "react";
|
|
2
2
|
import { Size } from "../../core";
|
|
3
|
-
import { DropDownItem } from "../types";
|
|
3
|
+
import { DropDownItem, DropDownMenuProps } from "../types";
|
|
4
4
|
export declare const MenuItemList: React.FC<{
|
|
5
5
|
menuItems: DropDownItem[];
|
|
6
6
|
searchable?: boolean;
|
|
7
7
|
searchValue?: string;
|
|
8
|
-
|
|
8
|
+
onSearch?: (value: string) => void;
|
|
9
|
+
manualSearch?: boolean;
|
|
9
10
|
selected?: DropDownItem[];
|
|
10
11
|
TooltipContent?: ComponentType<any>;
|
|
11
12
|
multiselect?: boolean;
|
|
@@ -15,4 +16,7 @@ export declare const MenuItemList: React.FC<{
|
|
|
15
16
|
onItemSelect?: (item: DropDownItem) => void;
|
|
16
17
|
renderOption?: (item: DropDownItem) => React.ReactNode;
|
|
17
18
|
onScroll?: (e: Event) => void;
|
|
19
|
+
onScrollToTop?: (e: Event) => void;
|
|
20
|
+
onScrollToBottom?: (e: Event) => void;
|
|
21
|
+
query?: DropDownMenuProps["query"];
|
|
18
22
|
}>;
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
13
|
import { useLayoutEffect, useRef, useState } from "react";
|
|
3
14
|
import styled from "styled-components";
|
|
4
15
|
import { FixedSizeList } from "react-window";
|
|
5
16
|
import CheckBox from "../../CheckBox";
|
|
6
17
|
import { DropDownMenu } from "../DropDownMenu";
|
|
7
18
|
import { MenuItem } from "./MenuItem";
|
|
19
|
+
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
20
|
+
import { useDebouncedCallback } from "use-debounce";
|
|
21
|
+
import { SearchInput } from "./SearchInput";
|
|
22
|
+
import Loader from "../../Loader";
|
|
8
23
|
const filterMenuItems = (menuItems, searchValue) => {
|
|
9
24
|
return menuItems.filter((item) => {
|
|
10
25
|
var _a, _b, _c;
|
|
@@ -19,7 +34,10 @@ const ListViewPort = styled.div.attrs({ className: "ListViewPort" }) `
|
|
|
19
34
|
display: flex;
|
|
20
35
|
flex-direction: column;
|
|
21
36
|
`;
|
|
22
|
-
export const MenuItemList = ({ menuItems, searchable,
|
|
37
|
+
export const MenuItemList = ({ menuItems, searchable, onSearch, manualSearch, selected, TooltipContent, multiselect, size, handleAddItem, handleRemoveItem, onItemSelect, renderOption, onScroll, onScrollToTop, onScrollToBottom, query, }) => {
|
|
38
|
+
var _a;
|
|
39
|
+
const [searchValue, setSearchValue] = useState("");
|
|
40
|
+
const _b = query !== null && query !== void 0 ? query : {}, { queryKey, queryFn, getNextPageParam, initialPageParam } = _b, rest = __rest(_b, ["queryKey", "queryFn", "getNextPageParam", "initialPageParam"]);
|
|
23
41
|
const abortController = new AbortController();
|
|
24
42
|
const targetElm = useRef(null);
|
|
25
43
|
const listElm = useRef(null);
|
|
@@ -27,6 +45,18 @@ export const MenuItemList = ({ menuItems, searchable, searchValue = "", isObject
|
|
|
27
45
|
width: 0,
|
|
28
46
|
height: 0,
|
|
29
47
|
});
|
|
48
|
+
const { data: infiniteQueryResult, isLoading: isLoadingInfiniteQuery, fetchNextPage, } = useInfiniteQuery(Object.assign({ queryKey: (queryKey === null || queryKey === void 0 ? void 0 : queryKey({ search: searchValue })) || [], queryFn: queryFn, getNextPageParam: (query === null || query === void 0 ? void 0 : query.getNextPageParam) || (() => undefined), initialPageParam: (query === null || query === void 0 ? void 0 : query.initialPageParam) || 1, enabled: !!query }, rest));
|
|
49
|
+
const infinteOptionsData = infiniteQueryResult;
|
|
50
|
+
const infiniteSelectOptions = infinteOptionsData || [];
|
|
51
|
+
const _options = !!query ? infiniteSelectOptions : menuItems;
|
|
52
|
+
const debouncedFetchNextPage = useDebouncedCallback(() => {
|
|
53
|
+
if (!isLoading && !!query) {
|
|
54
|
+
fetchNextPage();
|
|
55
|
+
}
|
|
56
|
+
}, 50);
|
|
57
|
+
const handleSearch = useDebouncedCallback((e) => {
|
|
58
|
+
setSearchValue(e.target.value);
|
|
59
|
+
}, 150);
|
|
30
60
|
const handleItemClick = (item, isSelected) => {
|
|
31
61
|
var _a;
|
|
32
62
|
if (multiselect) {
|
|
@@ -35,21 +65,43 @@ export const MenuItemList = ({ menuItems, searchable, searchValue = "", isObject
|
|
|
35
65
|
onItemSelect === null || onItemSelect === void 0 ? void 0 : onItemSelect(item);
|
|
36
66
|
(_a = item === null || item === void 0 ? void 0 : item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, item);
|
|
37
67
|
};
|
|
38
|
-
const visibleItems =
|
|
68
|
+
const visibleItems = _options.filter((item) => item.visible !== false);
|
|
39
69
|
const filteredItems = searchable
|
|
40
70
|
? filterMenuItems(visibleItems, searchValue)
|
|
41
71
|
: visibleItems;
|
|
72
|
+
const isObjectArray = (_a = Object.keys((visibleItems === null || visibleItems === void 0 ? void 0 : visibleItems[0]) || {})) === null || _a === void 0 ? void 0 : _a.includes("label");
|
|
73
|
+
const isLoading = isLoadingInfiniteQuery;
|
|
74
|
+
const handleOnScroll = (event) => {
|
|
75
|
+
const scrollTolerance = 15;
|
|
76
|
+
onScroll === null || onScroll === void 0 ? void 0 : onScroll(event);
|
|
77
|
+
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
|
|
78
|
+
// scroll to top
|
|
79
|
+
if (scrollTop <= scrollTolerance) {
|
|
80
|
+
onScrollToTop === null || onScrollToTop === void 0 ? void 0 : onScrollToTop(event);
|
|
81
|
+
}
|
|
82
|
+
// Scroll to bottom
|
|
83
|
+
if (scrollHeight - scrollTop <= clientHeight + scrollTolerance) {
|
|
84
|
+
onScrollToBottom === null || onScrollToBottom === void 0 ? void 0 : onScrollToBottom(event);
|
|
85
|
+
debouncedFetchNextPage();
|
|
86
|
+
}
|
|
87
|
+
};
|
|
42
88
|
useLayoutEffect(() => {
|
|
43
89
|
if (listElm.current) {
|
|
44
|
-
|
|
45
|
-
listElm.current.addEventListener("scroll", (e) => onScroll === null || onScroll === void 0 ? void 0 : onScroll(e));
|
|
46
|
-
}
|
|
90
|
+
listElm.current.addEventListener("scroll", (e) => handleOnScroll(e));
|
|
47
91
|
}
|
|
48
92
|
// Event cleanup
|
|
49
93
|
return () => {
|
|
50
94
|
abortController.abort();
|
|
51
95
|
};
|
|
52
|
-
}, [
|
|
96
|
+
}, [
|
|
97
|
+
filteredItems,
|
|
98
|
+
listElm.current,
|
|
99
|
+
isLoading,
|
|
100
|
+
onScroll,
|
|
101
|
+
onScrollToTop,
|
|
102
|
+
onScrollToBottom,
|
|
103
|
+
handleOnScroll,
|
|
104
|
+
]);
|
|
53
105
|
useLayoutEffect(() => {
|
|
54
106
|
var _a;
|
|
55
107
|
if (targetElm.current) {
|
|
@@ -59,7 +111,7 @@ export const MenuItemList = ({ menuItems, searchable, searchValue = "", isObject
|
|
|
59
111
|
height: viewPortDimensions.height,
|
|
60
112
|
});
|
|
61
113
|
}
|
|
62
|
-
}, [targetElm.current]);
|
|
114
|
+
}, [targetElm.current, isLoading]);
|
|
63
115
|
const overscanCount = 10;
|
|
64
116
|
const itemHeight = 25;
|
|
65
117
|
const itemCount = (filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.length) || 0;
|
|
@@ -69,24 +121,41 @@ export const MenuItemList = ({ menuItems, searchable, searchValue = "", isObject
|
|
|
69
121
|
? itemCount * itemHeight
|
|
70
122
|
: 200;
|
|
71
123
|
const width = viewPortDimensions.width || 188;
|
|
72
|
-
return (
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
124
|
+
return (_jsxs("div", { children: [searchable && (_jsx(SearchInput, { variant: "outlined", size: size, placeholder: "Search", defaultValue: searchValue, onChange: (e) => {
|
|
125
|
+
if (!manualSearch) {
|
|
126
|
+
handleSearch(e);
|
|
127
|
+
}
|
|
128
|
+
onSearch === null || onSearch === void 0 ? void 0 : onSearch(e.target.value);
|
|
129
|
+
} })), isLoading && (_jsxs("div", { style: {
|
|
130
|
+
display: "flex",
|
|
131
|
+
flexDirection: "column",
|
|
132
|
+
gap: "10px",
|
|
133
|
+
justifyContent: "center",
|
|
134
|
+
alignItems: "center",
|
|
135
|
+
height: "100%",
|
|
136
|
+
padding: "10px 0",
|
|
137
|
+
}, children: [_jsx("div", { style: { fontSize: "12px" }, children: "Loading..." }), _jsx(Loader, {})] })), !isLoading && (_jsx(ListViewPort, { ref: targetElm, children: _jsx(FixedSizeList, { itemData: filteredItems, overscanCount: overscanCount, height: height, width: width, itemCount: itemCount, itemSize: itemHeight, outerRef: listElm, children: ({ data, index, style }) => {
|
|
138
|
+
const item = (data === null || data === void 0 ? void 0 : data[index]) || {};
|
|
139
|
+
const isSelected = !!(selected === null || selected === void 0 ? void 0 : selected.find((s) => {
|
|
140
|
+
return isObjectArray ? (s === null || s === void 0 ? void 0 : s.value) === (item === null || item === void 0 ? void 0 : item.value) : s === item;
|
|
141
|
+
}));
|
|
142
|
+
if (item.items) {
|
|
143
|
+
return (_jsx(DropDownMenu, { data: item.items, size: size, buttonProps: { style }, disabled: item.disabled, children: item.label }));
|
|
144
|
+
}
|
|
145
|
+
return (_jsx(MenuItem, { className: "MenuItem", itemData: item, TooltipContent: TooltipContent, "data-selected": isSelected, "data-disabled": item.disabled, disabled: item.disabled, leftSection: multiselect ? (_jsxs(_Fragment, { children: [_jsx(CheckBox, { value: isSelected, size: size, onChange: (newValue) => {
|
|
146
|
+
var _a;
|
|
147
|
+
newValue
|
|
148
|
+
? handleAddItem(item)
|
|
149
|
+
: handleRemoveItem(item);
|
|
150
|
+
(_a = item === null || item === void 0 ? void 0 : item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, item);
|
|
151
|
+
} }), (item === null || item === void 0 ? void 0 : item.leftSection) || null] })) : ((item === null || item === void 0 ? void 0 : item.leftSection) || null), rightSection: item === null || item === void 0 ? void 0 : item.rightSection, multiselect: multiselect, size: size, title: !TooltipContent ? item === null || item === void 0 ? void 0 : item.label : undefined, onClick: (e) => {
|
|
152
|
+
e.preventDefault();
|
|
153
|
+
e.stopPropagation();
|
|
154
|
+
handleItemClick(item, isSelected);
|
|
155
|
+
}, style: style, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) ||
|
|
156
|
+
(item === null || item === void 0 ? void 0 : item.label) ||
|
|
157
|
+
(typeof item === "string" || typeof item === "number"
|
|
158
|
+
? item
|
|
159
|
+
: null) }, index));
|
|
160
|
+
} }) }))] }));
|
|
92
161
|
};
|
|
@@ -3,6 +3,7 @@ import { Size, Variant } from "../core";
|
|
|
3
3
|
import Input from "../Input";
|
|
4
4
|
import { ButtonProps } from "../Button";
|
|
5
5
|
import { StyledContent } from "./components";
|
|
6
|
+
import { InfiniteData, UseInfiniteQueryOptions } from "@tanstack/react-query";
|
|
6
7
|
export type DropDownItem = {
|
|
7
8
|
toLowerCase?: () => string;
|
|
8
9
|
label: string;
|
|
@@ -27,6 +28,7 @@ export type DropDownMenuProps = {
|
|
|
27
28
|
data: DropDownItem[];
|
|
28
29
|
variant?: Variant;
|
|
29
30
|
defaultValue?: DropDownItem[];
|
|
31
|
+
value?: DropDownItem[];
|
|
30
32
|
multiselect?: boolean;
|
|
31
33
|
size?: Size;
|
|
32
34
|
title?: string;
|
|
@@ -35,13 +37,26 @@ export type DropDownMenuProps = {
|
|
|
35
37
|
onChange?: (selected: DropDownItem[], diff: DropDownItem[]) => void;
|
|
36
38
|
onItemSelect?: (item: DropDownItem) => void;
|
|
37
39
|
onScroll?: (e: Event) => void;
|
|
40
|
+
onScrollToTop?: (e: Event) => void;
|
|
41
|
+
onScrollToBottom?: (e: Event) => void;
|
|
42
|
+
onSearch?: (value: string) => void;
|
|
43
|
+
searchable?: boolean;
|
|
44
|
+
manualSearch?: boolean;
|
|
38
45
|
loading?: boolean;
|
|
39
46
|
arrow?: boolean;
|
|
40
|
-
searchable?: boolean;
|
|
41
47
|
dropDownProps?: ComponentPropsWithoutRef<typeof StyledContent>;
|
|
42
48
|
buttonRender?: (props: any) => ReactElement;
|
|
43
49
|
buttonProps?: ButtonProps;
|
|
44
50
|
disabled?: boolean;
|
|
51
|
+
query?: Omit<UseInfiniteQueryOptions, "select" | "queryKey" | "queryFn" | "getNextPageParam" | "initialPageParam"> & {
|
|
52
|
+
select: (data: InfiniteData<unknown>) => DropDownItem[];
|
|
53
|
+
queryKey: (args: {
|
|
54
|
+
search?: string;
|
|
55
|
+
}) => UseInfiniteQueryOptions["queryKey"];
|
|
56
|
+
queryFn: UseInfiniteQueryOptions["queryFn"];
|
|
57
|
+
getNextPageParam: UseInfiniteQueryOptions["getNextPageParam"];
|
|
58
|
+
initialPageParam: UseInfiniteQueryOptions["initialPageParam"];
|
|
59
|
+
};
|
|
45
60
|
};
|
|
46
61
|
export type MenuProps = {
|
|
47
62
|
label?: any;
|
|
@@ -132,6 +132,14 @@ export interface MonolithDefaultTheme {
|
|
|
132
132
|
default: string;
|
|
133
133
|
primary: string;
|
|
134
134
|
secondary: string;
|
|
135
|
+
alternate: string;
|
|
136
|
+
error: string;
|
|
137
|
+
};
|
|
138
|
+
text: {
|
|
139
|
+
default: string;
|
|
140
|
+
primary: string;
|
|
141
|
+
secondary: string;
|
|
142
|
+
alternate: string;
|
|
135
143
|
error: string;
|
|
136
144
|
};
|
|
137
145
|
};
|
|
@@ -61,7 +61,7 @@ const BaseLabel = styled.div `
|
|
|
61
61
|
|
|
62
62
|
border: 1px solid transparent;
|
|
63
63
|
|
|
64
|
-
background-color: ${({ theme }) => theme.
|
|
64
|
+
background-color: ${({ theme }) => theme.button.background.alternate};
|
|
65
65
|
|
|
66
66
|
font-size: 12px;
|
|
67
67
|
|
|
@@ -133,15 +133,44 @@ const dateFormatResolver = (resolution) => {
|
|
|
133
133
|
return "YYYY-MM-DD HH:mm:ss";
|
|
134
134
|
}
|
|
135
135
|
};
|
|
136
|
-
const
|
|
137
|
-
var _a, _b, _c
|
|
136
|
+
const MultiSelectEditor = ({ rule, filterDef, onChange }) => {
|
|
137
|
+
var _a, _b, _c;
|
|
138
138
|
const theme = useTheme();
|
|
139
|
+
const handleChange = (selected, diff) => {
|
|
140
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(selected, diff);
|
|
141
|
+
};
|
|
142
|
+
const selected = (_a = rule.options) === null || _a === void 0 ? void 0 : _a.filter((o) => { var _a; return (_a = rule.value) === null || _a === void 0 ? void 0 : _a.includes(o.value); });
|
|
143
|
+
let display = ((_b = rule.options) === null || _b === void 0 ? void 0 : _b.map((o) => o.label).join(", ")) || "Select Value";
|
|
144
|
+
if (Array.isArray(rule.value) && rule.value.length > 1) {
|
|
145
|
+
display = `${rule.value.length} ${(filterDef === null || filterDef === void 0 ? void 0 : filterDef.pluralLabel) || "Values"}`;
|
|
146
|
+
}
|
|
147
|
+
return (_jsx(DropDownMenu, { data: (filterDef === null || filterDef === void 0 ? void 0 : filterDef.selectOptions) || [], variant: "outlined", multiselect: true, searchable: true, size: "xs", buttonProps: {
|
|
148
|
+
title: "Select Value",
|
|
149
|
+
variant: "contained",
|
|
150
|
+
size: "xxs",
|
|
151
|
+
style: {
|
|
152
|
+
padding: "0px 4px",
|
|
153
|
+
height: 20,
|
|
154
|
+
borderRadius: 0,
|
|
155
|
+
backgroundColor: theme.button.background.alternate,
|
|
156
|
+
fontSize: 11,
|
|
157
|
+
fontWeight: "normal",
|
|
158
|
+
color: !!rule.value && Array.isArray(rule.value) && rule.value.length > 0
|
|
159
|
+
? theme.palette.text.primary
|
|
160
|
+
: theme.palette.text.secondary,
|
|
161
|
+
},
|
|
162
|
+
}, dropDownProps: {
|
|
163
|
+
style: Object.assign({ width: 200, maxWidth: 400 }, (_c = filterDef === null || filterDef === void 0 ? void 0 : filterDef.dropDownOptions) === null || _c === void 0 ? void 0 : _c.style),
|
|
164
|
+
}, defaultValue: selected || [], onChange: handleChange, query: filterDef === null || filterDef === void 0 ? void 0 : filterDef.query, children: display }));
|
|
165
|
+
};
|
|
166
|
+
const ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
|
|
167
|
+
var _a, _b, _c, _d, _e, _f;
|
|
139
168
|
const handleInputChange = useDebouncedCallback((e) => {
|
|
140
169
|
const value = e.target.value;
|
|
141
170
|
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: value ? [value] : undefined }));
|
|
142
171
|
}, 250);
|
|
143
172
|
const handleMultiSelectChange = useDebouncedCallback((selected) => {
|
|
144
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: selected.map((s) => s.value) }));
|
|
173
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: selected.map((s) => s.value), options: selected }));
|
|
145
174
|
}, 100);
|
|
146
175
|
const handleTimestampChange = useDebouncedCallback((timestamp) => {
|
|
147
176
|
let formattedValue = timestamp;
|
|
@@ -175,34 +204,7 @@ const ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
|
|
|
175
204
|
case "datetime":
|
|
176
205
|
return (_jsx(StyledDateInput, { arrow: false, enableCalendar: true, format: dateFormatResolver(filterDef === null || filterDef === void 0 ? void 0 : filterDef.resolution), defaultValue: ((_e = rule.value) === null || _e === void 0 ? void 0 : _e[0]) === "" ? undefined : (_f = rule.value) === null || _f === void 0 ? void 0 : _f[0], onChange: handleTimestampChange }));
|
|
177
206
|
case "multiselect":
|
|
178
|
-
|
|
179
|
-
? ((_h = (_g = filterDef === null || filterDef === void 0 ? void 0 : filterDef.selectOptions) === null || _g === void 0 ? void 0 : _g.filter((o) => rule.value.includes(o.value))) === null || _h === void 0 ? void 0 : _h.map((o) => o.label).join(", ")) || "Select Value"
|
|
180
|
-
: "Select Value";
|
|
181
|
-
if (Array.isArray(rule.value) && rule.value.length > 1) {
|
|
182
|
-
display = `${rule.value.length} ${(filterDef === null || filterDef === void 0 ? void 0 : filterDef.pluralLabel) || "Values"}`;
|
|
183
|
-
}
|
|
184
|
-
if (!(filterDef === null || filterDef === void 0 ? void 0 : filterDef.selectOptions)) {
|
|
185
|
-
return _jsx(FieldLabel, { children: "Loading..." });
|
|
186
|
-
}
|
|
187
|
-
return (_jsx(DropDownMenu, { data: (filterDef === null || filterDef === void 0 ? void 0 : filterDef.selectOptions) || [], variant: "outlined", multiselect: true, searchable: true, buttonProps: {
|
|
188
|
-
size: "xxs",
|
|
189
|
-
style: {
|
|
190
|
-
padding: "0px 4px",
|
|
191
|
-
height: 20,
|
|
192
|
-
borderRadius: 0,
|
|
193
|
-
backgroundColor: theme.palette.background.secondary,
|
|
194
|
-
fontSize: 11,
|
|
195
|
-
fontWeight: "normal",
|
|
196
|
-
color: !!rule.value &&
|
|
197
|
-
Array.isArray(rule.value) &&
|
|
198
|
-
rule.value.length > 0
|
|
199
|
-
? theme.palette.text.primary
|
|
200
|
-
: theme.palette.text.secondary,
|
|
201
|
-
},
|
|
202
|
-
}, dropDownProps: {
|
|
203
|
-
style: Object.assign({ width: 200, maxWidth: 400 }, (_j = filterDef === null || filterDef === void 0 ? void 0 : filterDef.dropDownOptions) === null || _j === void 0 ? void 0 : _j.style),
|
|
204
|
-
}, defaultValue: (_k = filterDef === null || filterDef === void 0 ? void 0 : filterDef.selectOptions) === null || _k === void 0 ? void 0 : _k.filter((o) => Array.isArray(rule.value) &&
|
|
205
|
-
!!rule.value.find((v) => v == o.value)), onChange: handleMultiSelectChange, children: display }));
|
|
207
|
+
return (_jsx(MultiSelectEditor, { rule: rule, filterDef: filterDef, onChange: handleMultiSelectChange }));
|
|
206
208
|
default:
|
|
207
209
|
return (_jsx(StyledInput, { placeholder: "Enter Value...", onChange: handleInputChange }));
|
|
208
210
|
}
|
|
@@ -220,24 +222,26 @@ const ValueSelector = ({ rule, inputType, filterDef, onChange }) => {
|
|
|
220
222
|
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: newValue }));
|
|
221
223
|
return;
|
|
222
224
|
}
|
|
223
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: e.value }));
|
|
225
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: e.value, options: e.options }));
|
|
224
226
|
};
|
|
225
227
|
const handleSecondaryValueChange = (e) => {
|
|
226
228
|
var _a, _b;
|
|
227
|
-
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: [((_a = rule === null || rule === void 0 ? void 0 : rule.value) === null || _a === void 0 ? void 0 : _a[0]) || "", ((_b = e.value) === null || _b === void 0 ? void 0 : _b[0]) || ""] }));
|
|
229
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: [((_a = rule === null || rule === void 0 ? void 0 : rule.value) === null || _a === void 0 ? void 0 : _a[0]) || "", ((_b = e.value) === null || _b === void 0 ? void 0 : _b[0]) || ""], options: e.options }));
|
|
228
230
|
};
|
|
229
231
|
return (_jsxs(_Fragment, { children: [_jsx(ValueEditor, { rule: rule, inputType: inputType, filterDef: filterDef, onChange: handleValueChange }), isBetween && (_jsxs(_Fragment, { children: [_jsx(FieldLabel, { children: "and" }), _jsx(ValueEditor, { rule: Object.assign(Object.assign({}, rule), { value: [((_a = rule === null || rule === void 0 ? void 0 : rule.value) === null || _a === void 0 ? void 0 : _a[1]) || ""] }), inputType: inputType, filterDef: filterDef, onChange: handleSecondaryValueChange })] }))] }));
|
|
230
232
|
};
|
|
231
233
|
const CloseLabel = styled(StyledButton) `
|
|
232
234
|
padding: 2px;
|
|
233
235
|
|
|
234
|
-
color: ${({ theme }) => theme.
|
|
236
|
+
background-color: ${({ theme }) => theme.button.background.alternate};
|
|
237
|
+
color: ${({ theme }) => theme.button.text.alternate};
|
|
235
238
|
|
|
236
239
|
&:hover {
|
|
237
240
|
border-color: ${({ theme }) => theme.palette.primary.main};
|
|
238
241
|
}
|
|
239
242
|
`;
|
|
240
243
|
const Rules = ({ rules = [], combinator, showCombinator, filterDefinitions, onDelete, onUpdate, onUpdateRootCombinator, }) => {
|
|
244
|
+
const theme = useTheme();
|
|
241
245
|
const handleCombinatorChange = (e) => {
|
|
242
246
|
onUpdateRootCombinator(e);
|
|
243
247
|
};
|
|
@@ -256,17 +260,18 @@ const Rules = ({ rules = [], combinator, showCombinator, filterDefinitions, onDe
|
|
|
256
260
|
return (_jsxs(_Fragment, { children: [showCombinator === true && (_jsx(DropDownMenu, { variant: "outlined", data: [
|
|
257
261
|
{ label: "AND", value: "and" },
|
|
258
262
|
{ label: "OR", value: "or" },
|
|
259
|
-
],
|
|
260
|
-
// arrow={true}
|
|
261
|
-
size: "sm", buttonProps: {
|
|
263
|
+
], size: "xs", buttonProps: {
|
|
262
264
|
title: "Chain these query filters together using AND | OR logic",
|
|
263
265
|
variant: "contained",
|
|
266
|
+
color: "secondary",
|
|
264
267
|
style: {
|
|
265
268
|
fontWeight: "normal",
|
|
266
269
|
fontSize: 12,
|
|
267
270
|
padding: "3px 5px",
|
|
268
271
|
height: 20,
|
|
269
272
|
borderRadius: 4,
|
|
273
|
+
backgroundColor: theme.button.background.alternate,
|
|
274
|
+
color: theme.button.text.alternate,
|
|
270
275
|
},
|
|
271
276
|
}, onItemSelect: (e) => handleCombinatorChange(e.value), dropDownProps: {
|
|
272
277
|
style: { width: 175, maxWidth: 400 },
|
|
@@ -276,15 +281,18 @@ const Rules = ({ rules = [], combinator, showCombinator, filterDefinitions, onDe
|
|
|
276
281
|
throw new Error(`Filter Definition not found for dataField: ${rule.dataField}`);
|
|
277
282
|
const operatorOptions = (filterDef === null || filterDef === void 0 ? void 0 : filterDef.operators) || DefaultOperators;
|
|
278
283
|
const inputType = (filterDef === null || filterDef === void 0 ? void 0 : filterDef.inputType) || "text";
|
|
279
|
-
return (_jsxs(RuleContainer, { "data-rule-id": rule.id, children: [_jsx(FieldLabel, { children: rule.label }), _jsx(DropDownMenu, { variant: "outlined", data: operatorOptions, size: "
|
|
284
|
+
return (_jsxs(RuleContainer, { "data-rule-id": rule.id, children: [_jsx(FieldLabel, { children: rule.label }), _jsx(DropDownMenu, { variant: "outlined", data: operatorOptions, size: "xs", buttonProps: {
|
|
280
285
|
title: "Select Operator",
|
|
281
286
|
variant: "contained",
|
|
287
|
+
color: "secondary",
|
|
282
288
|
style: {
|
|
283
289
|
fontWeight: "normal",
|
|
284
290
|
fontSize: 12,
|
|
285
291
|
padding: "3px 5px",
|
|
286
292
|
height: 20,
|
|
287
293
|
borderRadius: 0,
|
|
294
|
+
backgroundColor: theme.button.background.alternate,
|
|
295
|
+
color: theme.button.text.alternate,
|
|
288
296
|
},
|
|
289
297
|
}, onItemSelect: (e) => handleOperatorChange(rule, e), dropDownProps: {
|
|
290
298
|
style: { width: 175, maxWidth: 400 },
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DropDownItem } from "../DropDownMenu";
|
|
1
|
+
import { DropDownItem, DropDownMenuProps } from "../DropDownMenu";
|
|
3
2
|
export interface UseQueryFilterProps {
|
|
4
3
|
defaultFilter?: Query | null;
|
|
5
4
|
filterDefinitions: FilterDefinition[];
|
|
@@ -36,14 +35,13 @@ export interface FilterDefinition {
|
|
|
36
35
|
style?: React.CSSProperties;
|
|
37
36
|
};
|
|
38
37
|
editorType?: EditorType;
|
|
39
|
-
query?:
|
|
40
|
-
select: (data: unknown) => DropDownItem[];
|
|
41
|
-
};
|
|
38
|
+
query?: DropDownMenuProps["query"];
|
|
42
39
|
}
|
|
43
40
|
export interface Rule {
|
|
44
41
|
id?: string;
|
|
45
42
|
dataField: string;
|
|
46
43
|
value?: string[];
|
|
44
|
+
options?: DropDownItem[];
|
|
47
45
|
operator: Operator;
|
|
48
46
|
label: string;
|
|
49
47
|
}
|
package/dist/theme/variants.js
CHANGED
|
@@ -173,8 +173,16 @@ const lightVariant = {
|
|
|
173
173
|
default: "transparent",
|
|
174
174
|
primary: customBlue[500],
|
|
175
175
|
secondary: "#a1a1a1",
|
|
176
|
+
alternate: "#f0f0f0",
|
|
176
177
|
error: "#f44336",
|
|
177
178
|
},
|
|
179
|
+
text: {
|
|
180
|
+
default: "#FFF",
|
|
181
|
+
primary: "#FFF",
|
|
182
|
+
secondary: "#000",
|
|
183
|
+
alternate: "#000",
|
|
184
|
+
error: "#FFF",
|
|
185
|
+
},
|
|
178
186
|
},
|
|
179
187
|
};
|
|
180
188
|
const darkVariant = merge(lightVariant, {
|
|
@@ -282,11 +290,13 @@ const darkVariant = merge(lightVariant, {
|
|
|
282
290
|
default: "transparent",
|
|
283
291
|
primary: customBlue[500],
|
|
284
292
|
secondary: "#3f3f3f",
|
|
293
|
+
alternate: "#3f3f3f",
|
|
285
294
|
error: "#f44336",
|
|
286
295
|
},
|
|
287
296
|
text: {
|
|
288
297
|
primary: "rgba(255, 255, 255, 0.95)",
|
|
289
298
|
secondary: "rgba(255, 255, 255, 0.6)",
|
|
299
|
+
alternate: "rgba(255, 255, 255, 0.6)",
|
|
290
300
|
},
|
|
291
301
|
},
|
|
292
302
|
});
|
package/package.json
CHANGED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { UseQueryOptions } from "@tanstack/react-query";
|
|
2
|
-
import { FilterDefinition } from "./types";
|
|
3
|
-
import { DropDownItem } from "../DropDownMenu";
|
|
4
|
-
/** Override Filters Type
|
|
5
|
-
* some properties have been overridden to allow for partial overrides
|
|
6
|
-
*/
|
|
7
|
-
type FilterDefinitionOverride = Partial<Omit<FilterDefinition, "query" | "dataField">> & {
|
|
8
|
-
dataField: string;
|
|
9
|
-
query?: Omit<Partial<UseQueryOptions>, "select" | "queryKey"> & {
|
|
10
|
-
select?: (data: unknown) => DropDownItem[];
|
|
11
|
-
queryKey?: UseQueryOptions["queryKey"];
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
export interface UseFilterHelperParams {
|
|
15
|
-
filterDef: FilterDefinition[];
|
|
16
|
-
overrides?: FilterDefinitionOverride[];
|
|
17
|
-
}
|
|
18
|
-
export type UseFilterHelperType = (p: UseFilterHelperParams) => FilterDefinition[];
|
|
19
|
-
export declare const useFilterHelper: UseFilterHelperType;
|
|
20
|
-
export {};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
-
var t = {};
|
|
3
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
-
t[p] = s[p];
|
|
5
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
-
t[p[i]] = s[p[i]];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
import { useQueries } from "@tanstack/react-query";
|
|
13
|
-
const mergeOverrides = (filterDef, overrides) => {
|
|
14
|
-
return filterDef.map((f) => {
|
|
15
|
-
var _a, _b, _c;
|
|
16
|
-
const override = overrides.find((o) => o.dataField === f.dataField);
|
|
17
|
-
if (!override) {
|
|
18
|
-
return f;
|
|
19
|
-
}
|
|
20
|
-
const { query, dropDownOptions } = override, rest = __rest(override, ["query", "dropDownOptions"]);
|
|
21
|
-
// Handle merge directly on query and dropDownOptions
|
|
22
|
-
// prevents overriding the entire query object
|
|
23
|
-
// allows user to override specific properties
|
|
24
|
-
if (query) {
|
|
25
|
-
f.query = Object.assign(Object.assign(Object.assign({}, f.query), query), { queryFn: query.queryFn || ((_a = f === null || f === void 0 ? void 0 : f.query) === null || _a === void 0 ? void 0 : _a.queryFn) || (() => { }), queryKey: query.queryKey || ((_b = f === null || f === void 0 ? void 0 : f.query) === null || _b === void 0 ? void 0 : _b.queryKey) || [], select: query.select || ((_c = f === null || f === void 0 ? void 0 : f.query) === null || _c === void 0 ? void 0 : _c.select) || (() => []) });
|
|
26
|
-
}
|
|
27
|
-
if (dropDownOptions) {
|
|
28
|
-
f.dropDownOptions = Object.assign(Object.assign({}, f.dropDownOptions), dropDownOptions);
|
|
29
|
-
}
|
|
30
|
-
// Merge override with original filter def
|
|
31
|
-
return Object.assign(Object.assign({}, f), rest);
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
export const useFilterHelper = ({ filterDef, overrides, }) => {
|
|
35
|
-
let _filterDef = filterDef;
|
|
36
|
-
if (!!overrides) {
|
|
37
|
-
_filterDef = mergeOverrides(filterDef, overrides);
|
|
38
|
-
}
|
|
39
|
-
// Keeps track of filters that have queries
|
|
40
|
-
const queryIndex = [];
|
|
41
|
-
// Get query options from filter defs
|
|
42
|
-
const queries = filterDef
|
|
43
|
-
.filter((f, i) => {
|
|
44
|
-
// Track array index of filter def that has a query
|
|
45
|
-
const hasQuery = f.query !== undefined;
|
|
46
|
-
hasQuery && queryIndex.push(i);
|
|
47
|
-
return hasQuery;
|
|
48
|
-
})
|
|
49
|
-
.map((filter) => filter.query);
|
|
50
|
-
// run queries from filter defs
|
|
51
|
-
const result = useQueries({
|
|
52
|
-
queries,
|
|
53
|
-
});
|
|
54
|
-
// Add useQueries result data to filter def as options
|
|
55
|
-
queryIndex.forEach((index, i) => {
|
|
56
|
-
var _a;
|
|
57
|
-
// User query index to add useQueries result data to filter def as options
|
|
58
|
-
filterDef[index].selectOptions = (_a = result[i]) === null || _a === void 0 ? void 0 : _a.data;
|
|
59
|
-
});
|
|
60
|
-
return filterDef;
|
|
61
|
-
};
|