@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.
@@ -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.background) === null || _b === void 0 ? void 0 : _b[color]) ||
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 { useRef, useState } from "react";
3
- import { useDebouncedCallback } from "use-debounce";
4
- import { Menu, MenuItemList, SearchInput, StyledInnerItemContainer, } from "./components";
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
- setSearchValue("");
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..." }), searchable && (_jsx(SearchInput, { ref: searchInputRef, variant: "outlined", size: size, placeholder: "Search", defaultValue: searchValue, onChange: handleSearch })), !loading && (_jsx(MenuItemList, { menuItems: data, searchable: searchable, searchValue: searchValue, isObjectArray: isObjectArray, selected: selected, TooltipContent: TooltipContent, multiselect: multiselect, size: size, handleAddItem: handleAddItem, handleRemoveItem: handleRemoveItem, onItemSelect: onItemSelect, renderOption: renderOption, onScroll: onScroll }))] }) }));
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
- isObjectArray?: boolean;
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
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
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, searchValue = "", isObjectArray, selected, TooltipContent, multiselect, size, handleAddItem, handleRemoveItem, onItemSelect, renderOption, onScroll, }) => {
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 = menuItems.filter((item) => item.visible !== false);
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
- if (onScroll) {
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
- }, [filteredItems, listElm.current, onScroll]);
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 (_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 }) => {
73
- const item = (data === null || data === void 0 ? void 0 : data[index]) || {};
74
- const isSelected = !!(selected === null || selected === void 0 ? void 0 : selected.find((s) => isObjectArray ? (s === null || s === void 0 ? void 0 : s.value) === (item === null || item === void 0 ? void 0 : item.value) : s === item));
75
- if (item.items) {
76
- return (_jsx(DropDownMenu, { data: item.items, size: size, buttonProps: { style }, disabled: item.disabled, children: item.label }));
77
- }
78
- 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) => {
79
- var _a;
80
- newValue ? handleAddItem(item) : handleRemoveItem(item);
81
- (_a = item === null || item === void 0 ? void 0 : item.onClick) === null || _a === void 0 ? void 0 : _a.call(item, item);
82
- } }), (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) => {
83
- e.preventDefault();
84
- e.stopPropagation();
85
- handleItemClick(item, isSelected);
86
- }, style: style, children: (renderOption === null || renderOption === void 0 ? void 0 : renderOption(item)) ||
87
- (item === null || item === void 0 ? void 0 : item.label) ||
88
- (typeof item === "string" || typeof item === "number"
89
- ? item
90
- : null) }, index));
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.palette.background.secondary};
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 ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
137
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
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
- let display = Array.isArray(rule.value) && rule.value.length > 0
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.palette.text.secondary};
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: "sm", buttonProps: {
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 },
@@ -2,4 +2,3 @@ export * from "./useQueryFilter";
2
2
  export * from "./QueryFilter";
3
3
  export * from "./types";
4
4
  export * from "./DefaultOperators";
5
- export * from "./useFilterHelper";
@@ -2,4 +2,3 @@ export * from "./useQueryFilter";
2
2
  export * from "./QueryFilter";
3
3
  export * from "./types";
4
4
  export * from "./DefaultOperators";
5
- export * from "./useFilterHelper";
@@ -1,5 +1,4 @@
1
- import { UseQueryOptions } from "@tanstack/react-query";
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?: Omit<UseQueryOptions, "select"> & {
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
  }
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.3.16",
3
+ "version": "1.3.17",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",
@@ -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
- };