@monolith-forensics/monolith-ui 1.2.61 → 1.2.63
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.
|
@@ -7,6 +7,7 @@ import { DefaultOperators } from "./DefaultOperators";
|
|
|
7
7
|
import Input from "../Input";
|
|
8
8
|
import DateInput from "../DateInput";
|
|
9
9
|
import { useDebouncedCallback } from "use-debounce";
|
|
10
|
+
import moment from "moment";
|
|
10
11
|
const StyledContainer = styled.div `
|
|
11
12
|
display: flex;
|
|
12
13
|
flex-direction: row;
|
|
@@ -34,6 +35,10 @@ const RuleContainer = styled(StyledContainer) `
|
|
|
34
35
|
const FilterContainer = styled(StyledContainer) `
|
|
35
36
|
gap: 10px;
|
|
36
37
|
flex-wrap: wrap;
|
|
38
|
+
|
|
39
|
+
button.mfui-DropDownMenu:hover {
|
|
40
|
+
border-color: ${({ theme }) => theme.palette.primary.main};
|
|
41
|
+
}
|
|
37
42
|
`;
|
|
38
43
|
const StyledButton = styled(Button) `
|
|
39
44
|
border-radius: 0;
|
|
@@ -104,6 +109,26 @@ const StyledDateInput = styled(DateInput) `
|
|
|
104
109
|
border-color: ${({ theme }) => theme.palette.primary.main};
|
|
105
110
|
}
|
|
106
111
|
`;
|
|
112
|
+
const dateFormatResolver = (resolution) => {
|
|
113
|
+
switch (resolution) {
|
|
114
|
+
case "day":
|
|
115
|
+
return "YYYY-MM-DD";
|
|
116
|
+
// case "month":
|
|
117
|
+
// return "YYYY-MM";
|
|
118
|
+
// case "year":
|
|
119
|
+
// return "YYYY";
|
|
120
|
+
// case "hour":
|
|
121
|
+
// return "YYYY-MM-DD HH";
|
|
122
|
+
// case "minute":
|
|
123
|
+
// return "YYYY-MM-DD HH:mm";
|
|
124
|
+
case "second":
|
|
125
|
+
return "YYYY-MM-DD HH:mm:ss";
|
|
126
|
+
case "millisecond":
|
|
127
|
+
return "YYYY-MM-DD HH:mm:ss.SSS";
|
|
128
|
+
default:
|
|
129
|
+
return "YYYY-MM-DD HH:mm:ss";
|
|
130
|
+
}
|
|
131
|
+
};
|
|
107
132
|
const ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
|
|
108
133
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
109
134
|
const theme = useTheme();
|
|
@@ -115,7 +140,24 @@ const ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
|
|
|
115
140
|
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: selected.map((s) => s.value) }));
|
|
116
141
|
}, 100);
|
|
117
142
|
const handleTimestampChange = useDebouncedCallback((timestamp) => {
|
|
118
|
-
|
|
143
|
+
let formattedValue = timestamp;
|
|
144
|
+
if (formattedValue && filterDef.resolution) {
|
|
145
|
+
const date = moment(formattedValue);
|
|
146
|
+
switch (filterDef.resolution) {
|
|
147
|
+
case "day":
|
|
148
|
+
date.set({ hour: 0, minute: 0, second: 0, millisecond: 0 });
|
|
149
|
+
break;
|
|
150
|
+
case "second":
|
|
151
|
+
date.set({ millisecond: 0 });
|
|
152
|
+
break;
|
|
153
|
+
case "millisecond":
|
|
154
|
+
break;
|
|
155
|
+
default:
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
formattedValue = date.format(dateFormatResolver(filterDef.resolution));
|
|
159
|
+
}
|
|
160
|
+
onChange === null || onChange === void 0 ? void 0 : onChange(Object.assign(Object.assign({}, rule), { value: formattedValue ? [formattedValue] : undefined }));
|
|
119
161
|
}, 100);
|
|
120
162
|
switch (inputType) {
|
|
121
163
|
case "text":
|
|
@@ -125,7 +167,7 @@ const ValueEditor = ({ rule, inputType, filterDef, onChange }) => {
|
|
|
125
167
|
case "date":
|
|
126
168
|
return (_jsx(StyledDateInput, { arrow: false, enableCalendar: true, format: "YYYY-MM-DD", defaultValue: ((_c = rule.value) === null || _c === void 0 ? void 0 : _c[0]) === "" ? undefined : (_d = rule.value) === null || _d === void 0 ? void 0 : _d[0], onChange: handleTimestampChange }));
|
|
127
169
|
case "datetime":
|
|
128
|
-
return (_jsx(StyledDateInput, { arrow: false, enableCalendar: true, format:
|
|
170
|
+
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 }));
|
|
129
171
|
case "multiselect":
|
|
130
172
|
let display = Array.isArray(rule.value) && rule.value.length > 0
|
|
131
173
|
? ((_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"
|
|
@@ -178,7 +220,7 @@ const ValueSelector = ({ rule, inputType, filterDef, onChange }) => {
|
|
|
178
220
|
var _a, _b;
|
|
179
221
|
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]) || ""] }));
|
|
180
222
|
};
|
|
181
|
-
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, onChange: handleSecondaryValueChange })] }))] }));
|
|
223
|
+
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 })] }))] }));
|
|
182
224
|
};
|
|
183
225
|
const CloseLabel = styled(StyledButton) `
|
|
184
226
|
padding: 2px;
|
|
@@ -189,12 +231,34 @@ const CloseLabel = styled(StyledButton) `
|
|
|
189
231
|
border-color: ${({ theme }) => theme.palette.primary.main};
|
|
190
232
|
}
|
|
191
233
|
`;
|
|
192
|
-
const Rules = ({ rules = [], combinator, showCombinator, filterDefinitions, onDelete, onUpdate, }) => {
|
|
234
|
+
const Rules = ({ rules = [], combinator, showCombinator, filterDefinitions, onDelete, onUpdate, onUpdateRootCombinator, }) => {
|
|
235
|
+
const handleCombinatorChange = (e) => {
|
|
236
|
+
onUpdateRootCombinator(e);
|
|
237
|
+
};
|
|
193
238
|
const handleOperatorChange = (rule, operator) => {
|
|
194
239
|
onUpdate(Object.assign(Object.assign({}, rule), { operator }));
|
|
195
240
|
};
|
|
196
|
-
return (_jsxs(_Fragment, { children: [showCombinator === true && (_jsx(
|
|
241
|
+
return (_jsxs(_Fragment, { children: [showCombinator === true && (_jsx(DropDownMenu, { variant: "outlined", data: [
|
|
242
|
+
{ label: "AND", value: "and" },
|
|
243
|
+
{ label: "OR", value: "or" },
|
|
244
|
+
],
|
|
245
|
+
// arrow={true}
|
|
246
|
+
size: "sm", buttonProps: {
|
|
247
|
+
title: "Chain these query filters together using AND | OR logic",
|
|
248
|
+
variant: "contained",
|
|
249
|
+
style: {
|
|
250
|
+
fontWeight: "normal",
|
|
251
|
+
fontSize: 12,
|
|
252
|
+
padding: "3px 5px",
|
|
253
|
+
height: 20,
|
|
254
|
+
borderRadius: 4,
|
|
255
|
+
},
|
|
256
|
+
}, onItemSelect: (e) => handleCombinatorChange(e.value), dropDownProps: {
|
|
257
|
+
style: { width: 175, maxWidth: 400 },
|
|
258
|
+
}, children: combinator.toUpperCase() })), rules.map((rule) => {
|
|
197
259
|
const filterDef = filterDefinitions.find((f) => f.dataField === rule.dataField);
|
|
260
|
+
if (!filterDef)
|
|
261
|
+
throw new Error(`Filter Definition not found for dataField: ${rule.dataField}`);
|
|
198
262
|
const operatorOptions = (filterDef === null || filterDef === void 0 ? void 0 : filterDef.operators) || DefaultOperators;
|
|
199
263
|
const inputType = (filterDef === null || filterDef === void 0 ? void 0 : filterDef.inputType) || "text";
|
|
200
264
|
return (_jsxs(RuleContainer, { "data-rule-id": rule.id, children: [_jsx(FieldLabel, { children: rule.label }), _jsx(DropDownMenu, { variant: "outlined", data: operatorOptions,
|
|
@@ -219,5 +283,5 @@ export const QueryFilter = ({ queryFilter, }) => {
|
|
|
219
283
|
const { filter, filterDefinitions, showCombinator } = queryFilter;
|
|
220
284
|
if (((_a = filter === null || filter === void 0 ? void 0 : filter.rules) === null || _a === void 0 ? void 0 : _a.length) == 0)
|
|
221
285
|
return null;
|
|
222
|
-
return (_jsx(FilterContainer, { className: "mfui-QueryFilter", children: _jsx(Rules, { rules: filter.rules, combinator: filter.combinator, showCombinator: showCombinator, filterDefinitions: filterDefinitions, onDelete: (rule) => queryFilter.removeRule(rule.id), onUpdate: (rule) => queryFilter.updateRule(rule) }) }));
|
|
286
|
+
return (_jsx(FilterContainer, { className: "mfui-QueryFilter", children: _jsx(Rules, { rules: filter.rules, combinator: filter.combinator, showCombinator: showCombinator, filterDefinitions: filterDefinitions, onDelete: (rule) => queryFilter.removeRule(rule.id), onUpdate: (rule) => queryFilter.updateRule(rule), onUpdateRootCombinator: (e) => queryFilter.updateRootCombinator(e) }) }));
|
|
223
287
|
};
|
|
@@ -12,6 +12,7 @@ export type QueryFilterType = {
|
|
|
12
12
|
addRule: (rule: Rule) => void;
|
|
13
13
|
removeRule: (id: string) => void;
|
|
14
14
|
updateRule: (rule: Rule) => void;
|
|
15
|
+
updateRootCombinator: (combinator: Combinator) => void;
|
|
15
16
|
};
|
|
16
17
|
export type UseQueryFilter = (args: UseQueryFilterProps) => QueryFilterType;
|
|
17
18
|
export type Combinator = "and" | "or";
|
|
@@ -26,6 +27,7 @@ export interface FilterDefinition {
|
|
|
26
27
|
pluralLabel?: string;
|
|
27
28
|
operators?: Operator[];
|
|
28
29
|
inputType?: HTMLInputElement["type"];
|
|
30
|
+
resolution?: "day" | "second" | "millisecond";
|
|
29
31
|
placeholder?: string;
|
|
30
32
|
selectOptions?: DropDownItem[];
|
|
31
33
|
editorType?: EditorType;
|
|
@@ -20,6 +20,9 @@ export const useQueryFilter = (args) => {
|
|
|
20
20
|
const rules = filter.rules.map((r) => (r.id === rule.id ? rule : r));
|
|
21
21
|
setFilter(Object.assign(Object.assign({}, filter), { rules }));
|
|
22
22
|
};
|
|
23
|
+
const updateRootCombinator = (combinator) => {
|
|
24
|
+
setFilter(Object.assign(Object.assign({}, filter), { combinator }));
|
|
25
|
+
};
|
|
23
26
|
useEffect(() => {
|
|
24
27
|
var _a;
|
|
25
28
|
(_a = args === null || args === void 0 ? void 0 : args.onFilterChange) === null || _a === void 0 ? void 0 : _a.call(args, filter);
|
|
@@ -28,6 +31,7 @@ export const useQueryFilter = (args) => {
|
|
|
28
31
|
filter,
|
|
29
32
|
filterDefinitions: args.filterDefinitions,
|
|
30
33
|
showCombinator: args.showCombinator,
|
|
34
|
+
updateRootCombinator,
|
|
31
35
|
addRule,
|
|
32
36
|
removeRule,
|
|
33
37
|
updateRule,
|
|
@@ -35,6 +35,7 @@ const TableMenu = () => {
|
|
|
35
35
|
const queryFilter = useQueryFilter({
|
|
36
36
|
defaultFilter: filterState,
|
|
37
37
|
filterDefinitions: (filterOptions === null || filterOptions === void 0 ? void 0 : filterOptions.filterDefinitions) || [],
|
|
38
|
+
showCombinator: true,
|
|
38
39
|
onFilterChange: (q) => {
|
|
39
40
|
var _a;
|
|
40
41
|
handleFilterChange(q);
|