@vuu-ui/vuu-filters 0.7.0-debug → 0.7.1-debug
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/cjs/index.js +1765 -1310
- package/cjs/index.js.map +4 -4
- package/esm/index.js +1811 -1345
- package/esm/index.js.map +4 -4
- package/package.json +4 -4
- package/types/column-filter/ColumnFilter.d.ts +11 -0
- package/types/column-filter/ColumnListItem.d.ts +3 -0
- package/types/column-filter/RangeFilter.d.ts +14 -0
- package/types/column-filter/TypeaheadFilter.d.ts +9 -0
- package/types/column-filter/index.d.ts +1 -0
- package/types/column-filter/useColumnFilterStore.d.ts +12 -0
- package/types/column-filter/utils.d.ts +4 -0
- package/types/filter-input/useFilterSuggestionProvider.d.ts +3 -1
- package/types/filter-utils.d.ts +2 -1
- package/types/index.d.ts +1 -0
package/esm/index.js
CHANGED
|
@@ -93,1491 +93,1957 @@ var require_classnames = __commonJS({
|
|
|
93
93
|
}
|
|
94
94
|
});
|
|
95
95
|
|
|
96
|
-
// src/filter
|
|
97
|
-
import { Button } from "@salt-ds/core";
|
|
98
|
-
|
|
99
|
-
// src/filter-input/useCodeMirrorEditor.ts
|
|
100
|
-
var import_classnames = __toESM(require_classnames(), 1);
|
|
101
|
-
import {
|
|
102
|
-
autocompletion,
|
|
103
|
-
defaultKeymap,
|
|
104
|
-
EditorState as EditorState2,
|
|
105
|
-
EditorView as EditorView2,
|
|
106
|
-
ensureSyntaxTree,
|
|
107
|
-
keymap,
|
|
108
|
-
minimalSetup,
|
|
109
|
-
startCompletion
|
|
110
|
-
} from "@vuu-ui/vuu-codemirror";
|
|
111
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
112
|
-
|
|
113
|
-
// src/filter-input/filter-language-parser/FilterLanguage.ts
|
|
96
|
+
// src/column-filter/ColumnFilter.tsx
|
|
114
97
|
import {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
} from "@
|
|
98
|
+
Dropdown,
|
|
99
|
+
Toolbar,
|
|
100
|
+
ToolbarButton,
|
|
101
|
+
ToolbarField as ToolbarField2
|
|
102
|
+
} from "@heswell/salt-lab";
|
|
103
|
+
import { Text } from "@salt-ds/core";
|
|
120
104
|
|
|
121
|
-
//
|
|
122
|
-
import {
|
|
123
|
-
|
|
124
|
-
version: 14,
|
|
125
|
-
states: "%QOVQPOOOOQO'#C_'#C_O_QQO'#C^OOQO'#DO'#DOOvQQO'#C|OOQO'#DR'#DROVQPO'#CuOOQO'#C}'#C}QOQPOOOOQO'#C`'#C`O!UQQO,58xO!dQPO,59VOVQPO,59]OVQPO,59_O!iQPO,59hO!nQQO,59aOOQO'#DQ'#DQOOQO1G.d1G.dO!UQQO1G.qO!yQQO1G.wOOQO1G.y1G.yOOQO'#Cw'#CwOOQO1G/S1G/SOOQO1G.{1G.{O#[QPO'#CnO#dQPO7+$]O!UQQO'#CxO#iQPO,59YOOQO<<Gw<<GwOOQO,59d,59dOOQO-E6v-E6v",
|
|
126
|
-
stateData: "#q~OoOS~OsPOvUO~OTXOUXOVXOWXOXXOYXO`ZO~Of[Oh]Oj^OmpX~OZ`O[`O]`O^`O~OabO~OseO~Of[Oh]OwgO~Oh]Ofeijeimeiwei~OcjOdbX~OdlO~OcjOdba~O",
|
|
127
|
-
goto: "#YvPPw}!TPPPPPPPPPPwPP!WPP!ZP!ZP!aP!g!jPPP!p!s!aP#P!aXROU[]XQOU[]RYQRibXTOU[]XVOU[]Rf^QkhRnkRWOQSOQ_UQc[Rd]QaYQhbRmj",
|
|
128
|
-
nodeNames: "\u26A0 Filter ColumnValueExpression Column Operator Eq NotEq Gt Lt Starts Ends Number String True False ColumnSetExpression In LBrack Values Comma RBrack AndExpression And OrExpression Or ParenthesizedExpression As FilterName",
|
|
129
|
-
maxTerm: 39,
|
|
130
|
-
skippedNodes: [0],
|
|
131
|
-
repeatNodeCount: 1,
|
|
132
|
-
tokenData: "6p~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$j|}$o!O!P$t!Q![%S!^!_%_!_!`%d!`!a%i!c!}%n!}#O&V#P#Q&[#R#S%n#T#U&a#U#X%n#X#Y(w#Y#Z+]#Z#]%n#]#^.]#^#c%n#c#d/e#d#g%n#g#h0m#h#i4[#i#o%n~#USo~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOU~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_O[~~$bP;=`<%l#m~$jOv~~$oOw~~$tOc~~$wP!Q![$z~%PPZ~!Q![$z~%XQZ~!O!P$t!Q![%S~%dOW~~%iOT~~%nOV~P%sUsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n~&[Oa~~&aOd~R&fYsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c'U#c#g%n#g#h(^#h#o%nR'ZWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X's#X#o%nR'zUfQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(eUjQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c)f#c#o%nR)kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X*T#X#o%nR*YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h*r#h#o%nR*yUYQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR+bVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U+w#U#o%nR+|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#`%n#`#a,f#a#o%nR,kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h-T#h#o%nR-YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y-r#Y#o%nR-yU^QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR.bWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c.z#c#o%nR/RU`QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR/jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g0S#g#o%nR0ZUhQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR0rWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i1[#i#o%nR1aVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U1v#U#o%nR1{WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g2e#g#o%nR2jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i3S#i#o%nR3XWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h3q#h#o%nR3xUXQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR4aWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g4y#g#o%nR5OWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#i%n#i#j5h#j#o%nR5mWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y6V#Y#o%nR6^U]QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n",
|
|
133
|
-
tokenizers: [0, 1],
|
|
134
|
-
topRules: { "Filter": [0, 1] },
|
|
135
|
-
tokenPrec: 0
|
|
136
|
-
});
|
|
105
|
+
// ../../node_modules/@salt-ds/icons/dist-es/packages/icons/src/icon/Icon.js
|
|
106
|
+
import { jsx } from "react/jsx-runtime";
|
|
107
|
+
import { forwardRef } from "react";
|
|
137
108
|
|
|
138
|
-
//
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
109
|
+
// ../../node_modules/clsx/dist/clsx.m.js
|
|
110
|
+
function r(e) {
|
|
111
|
+
var t, f, n = "";
|
|
112
|
+
if ("string" == typeof e || "number" == typeof e)
|
|
113
|
+
n += e;
|
|
114
|
+
else if ("object" == typeof e)
|
|
115
|
+
if (Array.isArray(e))
|
|
116
|
+
for (t = 0; t < e.length; t++)
|
|
117
|
+
e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
118
|
+
else
|
|
119
|
+
for (t in e)
|
|
120
|
+
e[t] && (n && (n += " "), n += t);
|
|
121
|
+
return n;
|
|
122
|
+
}
|
|
123
|
+
function clsx() {
|
|
124
|
+
for (var e, t, f = 0, n = ""; f < arguments.length; )
|
|
125
|
+
(e = arguments[f++]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
126
|
+
return n;
|
|
127
|
+
}
|
|
155
128
|
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
var FilterExpression = class {
|
|
164
|
-
constructor() {
|
|
165
|
-
__privateAdd(this, _filter, void 0);
|
|
129
|
+
// ../../node_modules/@salt-ds/icons/dist-es/node_modules/style-inject/dist/style-inject.es.js
|
|
130
|
+
function styleInject(css, ref) {
|
|
131
|
+
if (ref === void 0)
|
|
132
|
+
ref = {};
|
|
133
|
+
var insertAt = ref.insertAt;
|
|
134
|
+
if (!css || typeof document === "undefined") {
|
|
135
|
+
return;
|
|
166
136
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
137
|
+
var head = document.head || document.getElementsByTagName("head")[0];
|
|
138
|
+
var style = document.createElement("style");
|
|
139
|
+
style.type = "text/css";
|
|
140
|
+
if (insertAt === "top") {
|
|
141
|
+
if (head.firstChild) {
|
|
142
|
+
head.insertBefore(style, head.firstChild);
|
|
170
143
|
} else {
|
|
171
|
-
|
|
172
|
-
op,
|
|
173
|
-
filters: [__privateGet(this, _filter)]
|
|
174
|
-
});
|
|
144
|
+
head.appendChild(style);
|
|
175
145
|
}
|
|
146
|
+
} else {
|
|
147
|
+
head.appendChild(style);
|
|
176
148
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
__privateGet(this, _filter).filters.push(filter);
|
|
182
|
-
} else {
|
|
183
|
-
throw Error(`Invalid filter passed to FilterExpression`);
|
|
184
|
-
}
|
|
149
|
+
if (style.styleSheet) {
|
|
150
|
+
style.styleSheet.cssText = css;
|
|
151
|
+
} else {
|
|
152
|
+
style.appendChild(document.createTextNode(css));
|
|
185
153
|
}
|
|
186
|
-
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ../../node_modules/@salt-ds/icons/dist-es/packages/icons/src/icon/Icon.css.js
|
|
157
|
+
var css_248z = "/* Style applied to the root element */\n.saltIcon {\n --icon-color: var(--saltIcon-color, var(--salt-text-secondary-foreground));\n --icon-size-multiplier: var(--saltIcon-size-multiplier, 1);\n --icon-base-size: var(--salt-size-icon-base, 12px);\n /**\n * Icon size will be the multiplier (an integer from the size prop) * the base size (set by the theme per density)\n * Icons should never be smaller than 12px for readability so we've added a max() to enforce this\n */\n --icon-size: max(calc(var(--icon-base-size) * var(--icon-size-multiplier)), 12px);\n}\n\n.saltIcon {\n fill: var(--saltIcon-color, var(--icon-color));\n display: inline-block;\n margin: var(--saltIcon-margin, 0);\n position: relative;\n width: var(--icon-size);\n height: var(--icon-size);\n min-width: var(--icon-size);\n min-height: var(--icon-size);\n}\n\n.saltIcon:hover {\n --icon-color: var(--saltIcon-color-hover, var(--salt-text-secondary-foreground));\n}\n\n.saltIcon:active {\n --icon-color: var(--saltIcon-color-active, var(--salt-text-secondary-foreground));\n}\n";
|
|
158
|
+
styleInject(css_248z);
|
|
159
|
+
|
|
160
|
+
// ../../node_modules/@salt-ds/icons/dist-es/packages/icons/src/icon/Icon.js
|
|
161
|
+
var makePrefixer = (prefix) => (...names) => [prefix, ...names].join("-");
|
|
162
|
+
var withBaseName = makePrefixer("saltIcon");
|
|
163
|
+
var DEFAULT_ICON_SIZE = 1;
|
|
164
|
+
var Icon = forwardRef(function Icon2({ children, className, size = DEFAULT_ICON_SIZE, style: styleProp, ...rest }, ref) {
|
|
165
|
+
const style = {
|
|
166
|
+
...styleProp,
|
|
167
|
+
"--saltIcon-size-multiplier": `${size}`
|
|
168
|
+
};
|
|
169
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
170
|
+
className: clsx(withBaseName(), className),
|
|
171
|
+
style,
|
|
172
|
+
role: "img",
|
|
173
|
+
...rest,
|
|
174
|
+
ref,
|
|
175
|
+
children: /* @__PURE__ */ jsx("g", {
|
|
176
|
+
"aria-hidden": true,
|
|
177
|
+
children
|
|
178
|
+
})
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// ../../node_modules/@salt-ds/icons/dist-es/packages/icons/src/components/Delete.js
|
|
183
|
+
import { jsxs, jsx as jsx2 } from "react/jsx-runtime";
|
|
184
|
+
import { forwardRef as forwardRef2 } from "react";
|
|
185
|
+
var DeleteIcon = forwardRef2(
|
|
186
|
+
function DeleteIcon2(props, ref) {
|
|
187
|
+
return /* @__PURE__ */ jsxs(Icon, {
|
|
188
|
+
"data-testid": "DeleteIcon",
|
|
189
|
+
"aria-label": "delete",
|
|
190
|
+
viewBox: "0 0 12 12",
|
|
191
|
+
ref,
|
|
192
|
+
...props,
|
|
193
|
+
children: [
|
|
194
|
+
/* @__PURE__ */ jsx2("path", {
|
|
195
|
+
d: "M5 4v6H4V4h1Zm2 0v6H6V4h1Z"
|
|
196
|
+
}),
|
|
197
|
+
/* @__PURE__ */ jsx2("path", {
|
|
198
|
+
fillRule: "evenodd",
|
|
199
|
+
d: "M4 0a1 1 0 0 0-1 1v1H0v1h1v7a2 2 0 0 0 2 2h5.25A1.75 1.75 0 0 0 10 10.25V3h1V2H8V1a1 1 0 0 0-1-1H4Zm5 3H2v7a1 1 0 0 0 1 1h5.25a.75.75 0 0 0 .75-.75V3ZM7 2H4v-.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5V2Z",
|
|
200
|
+
clipRule: "evenodd"
|
|
201
|
+
})
|
|
202
|
+
]
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
// src/column-filter/RangeFilter.tsx
|
|
208
|
+
import { Input, ToolbarField } from "@heswell/salt-lab";
|
|
209
|
+
|
|
210
|
+
// src/filter-utils.ts
|
|
211
|
+
import { extractFilterForColumn, partition } from "@vuu-ui/vuu-utils";
|
|
212
|
+
|
|
213
|
+
// src/filterTypes.ts
|
|
214
|
+
var singleValueFilterOps = /* @__PURE__ */ new Set([
|
|
215
|
+
"=",
|
|
216
|
+
"!=",
|
|
217
|
+
">",
|
|
218
|
+
">=",
|
|
219
|
+
"<",
|
|
220
|
+
"<=",
|
|
221
|
+
"starts",
|
|
222
|
+
"ends"
|
|
223
|
+
]);
|
|
224
|
+
var isNamedFilter = (f) => f !== void 0 && f.name !== void 0;
|
|
225
|
+
var isSingleValueFilter = (f) => f !== void 0 && singleValueFilterOps.has(f.op);
|
|
226
|
+
var isFilterClause = (f) => f !== void 0 && (isSingleValueFilter(f) || isMultiValueFilter(f));
|
|
227
|
+
var isMultiValueFilter = (f) => f !== void 0 && f.op === "in";
|
|
228
|
+
var isInFilter = (f) => f.op === "in";
|
|
229
|
+
var isAndFilter = (f) => f.op === "and";
|
|
230
|
+
var isOrFilter = (f) => f.op === "or";
|
|
231
|
+
function isMultiClauseFilter(f) {
|
|
232
|
+
return f !== void 0 && (f.op === "and" || f.op === "or");
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// src/filter-utils.ts
|
|
236
|
+
var AND = "and";
|
|
237
|
+
var EQUALS = "=";
|
|
238
|
+
var GREATER_THAN = ">";
|
|
239
|
+
var LESS_THAN = "<";
|
|
240
|
+
var OR = "or";
|
|
241
|
+
var STARTS_WITH = "starts";
|
|
242
|
+
var ENDS_WITH = "ends";
|
|
243
|
+
var IN = "in";
|
|
244
|
+
var filterClauses = (filter, clauses = []) => {
|
|
245
|
+
if (filter) {
|
|
187
246
|
if (isMultiClauseFilter(filter)) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
} else if (filter) {
|
|
193
|
-
filter.column = column;
|
|
247
|
+
filter.filters.forEach((f) => clauses.push(...filterClauses(f)));
|
|
248
|
+
} else {
|
|
249
|
+
clauses.push(filter);
|
|
194
250
|
}
|
|
195
251
|
}
|
|
196
|
-
|
|
252
|
+
return clauses;
|
|
253
|
+
};
|
|
254
|
+
var DEFAULT_ADD_FILTER_OPTS = {
|
|
255
|
+
combineWith: "and"
|
|
256
|
+
};
|
|
257
|
+
var addFilter = (existingFilter, filter, { combineWith = AND } = DEFAULT_ADD_FILTER_OPTS) => {
|
|
258
|
+
var _a;
|
|
259
|
+
if (includesNoValues(filter)) {
|
|
197
260
|
if (isMultiClauseFilter(filter)) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
}
|
|
202
|
-
} else if (filter) {
|
|
203
|
-
filter.op = value;
|
|
261
|
+
} else {
|
|
262
|
+
existingFilter = removeFilterForColumn(existingFilter, {
|
|
263
|
+
name: filter.column
|
|
264
|
+
});
|
|
204
265
|
}
|
|
205
|
-
}
|
|
206
|
-
setValue(value, filter = __privateGet(this, _filter)) {
|
|
207
|
-
var _a;
|
|
266
|
+
} else if (includesAllValues(filter)) {
|
|
208
267
|
if (isMultiClauseFilter(filter)) {
|
|
209
|
-
const target = filter.filters.at(-1);
|
|
210
|
-
if (target) {
|
|
211
|
-
this.setValue(value, target);
|
|
212
|
-
}
|
|
213
|
-
} else if (isMultiValueFilter(filter)) {
|
|
214
|
-
(_a = filter.values) != null ? _a : filter.values = [];
|
|
215
|
-
filter.values.push(value);
|
|
216
|
-
} else if (isSingleValueFilter(filter)) {
|
|
217
|
-
filter.value = value;
|
|
218
268
|
}
|
|
269
|
+
return removeFilterForColumn(existingFilter, { name: (_a = filter.column) != null ? _a : "" });
|
|
219
270
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
271
|
+
if (!existingFilter) {
|
|
272
|
+
return filter;
|
|
273
|
+
}
|
|
274
|
+
if (!filter) {
|
|
275
|
+
return existingFilter;
|
|
276
|
+
}
|
|
277
|
+
if (existingFilter.op === AND && filter.op === AND) {
|
|
278
|
+
return {
|
|
279
|
+
op: AND,
|
|
280
|
+
filters: combine(existingFilter.filters, filter.filters)
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
if (existingFilter.op === AND) {
|
|
284
|
+
const filters = replaceOrInsert(existingFilter.filters, filter);
|
|
285
|
+
return filters.length > 1 ? { op: AND, filters } : filters[0];
|
|
286
|
+
}
|
|
287
|
+
if (filter.op === AND) {
|
|
288
|
+
return { op: AND, filters: filter.filters.concat(existingFilter) };
|
|
289
|
+
}
|
|
290
|
+
if (filterEquals(existingFilter, filter, true)) {
|
|
291
|
+
return filter;
|
|
229
292
|
}
|
|
293
|
+
if (canMerge(existingFilter, filter)) {
|
|
294
|
+
return merge(existingFilter, filter);
|
|
295
|
+
}
|
|
296
|
+
return { op: combineWith, filters: [existingFilter, filter] };
|
|
230
297
|
};
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
filterExpression.add({});
|
|
240
|
-
break;
|
|
241
|
-
case "ColumnSetExpression":
|
|
242
|
-
filterExpression.add({ op: "in" });
|
|
243
|
-
break;
|
|
244
|
-
case "Or":
|
|
245
|
-
case "And":
|
|
246
|
-
filterExpression.setFilterCombinatorOp(source.substring(from, to));
|
|
247
|
-
break;
|
|
248
|
-
case "Column":
|
|
249
|
-
filterExpression.setColumn(source.substring(from, to));
|
|
250
|
-
break;
|
|
251
|
-
case "Operator":
|
|
252
|
-
filterExpression.setOp(source.substring(from, to));
|
|
253
|
-
break;
|
|
254
|
-
case "String":
|
|
255
|
-
filterExpression.setValue(source.substring(from + 1, to - 1));
|
|
256
|
-
break;
|
|
257
|
-
case "Number":
|
|
258
|
-
filterExpression.setValue(parseFloat(source.substring(from, to)));
|
|
259
|
-
break;
|
|
260
|
-
case "True":
|
|
261
|
-
filterExpression.setValue(true);
|
|
262
|
-
break;
|
|
263
|
-
case "False":
|
|
264
|
-
filterExpression.setValue(false);
|
|
265
|
-
break;
|
|
266
|
-
case "FilterName":
|
|
267
|
-
filterExpression.name = source.substring(from, to);
|
|
268
|
-
break;
|
|
269
|
-
default:
|
|
270
|
-
}
|
|
271
|
-
} while (cursor.next());
|
|
272
|
-
return filterExpression.toJSON();
|
|
298
|
+
var includesNoValues = (filter) => {
|
|
299
|
+
if (!filter) {
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
if (isInFilter(filter) && filter.values.length === 0) {
|
|
303
|
+
return true;
|
|
304
|
+
}
|
|
305
|
+
return isAndFilter(filter) && filter.filters.some((f) => includesNoValues(f));
|
|
273
306
|
};
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return filter;
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
// src/filter-input/highlighting.ts
|
|
284
|
-
import {
|
|
285
|
-
HighlightStyle,
|
|
286
|
-
syntaxHighlighting,
|
|
287
|
-
tags
|
|
288
|
-
} from "@vuu-ui/vuu-codemirror";
|
|
289
|
-
var myHighlightStyle = HighlightStyle.define([
|
|
290
|
-
{ tag: tags.variableName, color: "var(--vuuFilterEditor-variableColor)" },
|
|
291
|
-
{ tag: tags.comment, color: "green", fontStyle: "italic" }
|
|
292
|
-
]);
|
|
293
|
-
var vuuHighlighting = syntaxHighlighting(myHighlightStyle);
|
|
294
|
-
|
|
295
|
-
// src/filter-input/theme.ts
|
|
296
|
-
import { EditorView } from "@vuu-ui/vuu-codemirror";
|
|
297
|
-
var vuuTheme = EditorView.theme(
|
|
298
|
-
{
|
|
299
|
-
"&": {
|
|
300
|
-
color: "var(--vuuFilterEditor-color)",
|
|
301
|
-
backgroundColor: "var(--vuuFilterEditor-background)",
|
|
302
|
-
fontSize: "var(--vuuFilterEditor-fontSize)"
|
|
303
|
-
},
|
|
304
|
-
".cm-content": {
|
|
305
|
-
caretColor: "var(--vuuFilterEditor-cursorColor)",
|
|
306
|
-
padding: 0
|
|
307
|
-
},
|
|
308
|
-
".cm-line": {
|
|
309
|
-
lineHeight: "var(--vuuFilterEditor-lineHeight)"
|
|
310
|
-
},
|
|
311
|
-
"&.cm-focused .cm-cursor": {
|
|
312
|
-
borderLeftColor: "var(--vuuFilterEditor-cursorColor)"
|
|
313
|
-
},
|
|
314
|
-
"&.cm-focused .cm-selectionBackground, ::selection": {
|
|
315
|
-
backgroundColor: "var(--vuuFilterEditor-selectionBackground)"
|
|
316
|
-
},
|
|
317
|
-
".cm-selectionBackground, ::selection": {
|
|
318
|
-
backgroundColor: "var(--vuuFilterEditor-selectionBackground)"
|
|
319
|
-
},
|
|
320
|
-
".cm-scroller": {
|
|
321
|
-
fontFamily: "var(--vuuFilterEditor-fontFamily)"
|
|
322
|
-
},
|
|
323
|
-
".cm-tooltip": {
|
|
324
|
-
background: "var(--vuuFilterEditor-tooltipBackground)",
|
|
325
|
-
border: "var(--vuuFilterEditor-tooltipBorder)",
|
|
326
|
-
boxShadow: "var(--vuuFilterEditor-tooltipElevation)",
|
|
327
|
-
"&.cm-tooltip-autocomplete > ul": {
|
|
328
|
-
fontFamily: "var(--vuuFilterEditor-fontFamily)",
|
|
329
|
-
fontSize: "var(--vuuFilterEditor-fontSize)",
|
|
330
|
-
maxHeight: "240px"
|
|
331
|
-
},
|
|
332
|
-
"&.cm-tooltip-autocomplete > ul > li": {
|
|
333
|
-
alignItems: "center",
|
|
334
|
-
display: "flex",
|
|
335
|
-
height: "var(--vuuFilterEditor-suggestion-height)",
|
|
336
|
-
padding: "0 3px",
|
|
337
|
-
lineHeight: "var(--vuuFilterEditor-suggestion-height)"
|
|
338
|
-
},
|
|
339
|
-
"&.cm-tooltip-autocomplete li[aria-selected]": {
|
|
340
|
-
background: "var(--vuuFilterEditor-suggestion-selectedBackground)",
|
|
341
|
-
color: "var(--vuuFilterEditor-suggestion-selectedColor)"
|
|
342
|
-
}
|
|
343
|
-
},
|
|
344
|
-
".cm-completionIcon": {
|
|
345
|
-
height: "18px",
|
|
346
|
-
flex: "0 0 16px"
|
|
347
|
-
},
|
|
348
|
-
".cm-completionLabel": {
|
|
349
|
-
flex: "1 1 auto"
|
|
350
|
-
},
|
|
351
|
-
".cm-completionIcon-filter": {
|
|
352
|
-
position: "relative",
|
|
353
|
-
"&:after": {
|
|
354
|
-
background: "var(--salt-text-secondary-foreground)",
|
|
355
|
-
content: "''",
|
|
356
|
-
"-webkit-mask": "var(--svg-filter) center center/13px 13px",
|
|
357
|
-
"-webkit-mask-repeat": "no-repeat",
|
|
358
|
-
position: "absolute",
|
|
359
|
-
height: "18px",
|
|
360
|
-
left: "0px",
|
|
361
|
-
top: "0px",
|
|
362
|
-
width: "16px"
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
},
|
|
366
|
-
{ dark: false }
|
|
367
|
-
);
|
|
368
|
-
|
|
369
|
-
// src/filter-input/useFilterAutoComplete.ts
|
|
370
|
-
import {
|
|
371
|
-
getNodeByName,
|
|
372
|
-
getValue,
|
|
373
|
-
syntaxTree
|
|
374
|
-
} from "@vuu-ui/vuu-codemirror";
|
|
375
|
-
import { useCallback } from "react";
|
|
376
|
-
var getOperator = (node, state) => {
|
|
377
|
-
let maybeColumnNode = node.prevSibling || node.parent;
|
|
378
|
-
while (maybeColumnNode && !["Column", "Operator", "In"].includes(maybeColumnNode.name)) {
|
|
379
|
-
maybeColumnNode = maybeColumnNode.prevSibling || maybeColumnNode.parent;
|
|
380
|
-
}
|
|
381
|
-
if ((maybeColumnNode == null ? void 0 : maybeColumnNode.name) === "In" || (maybeColumnNode == null ? void 0 : maybeColumnNode.name) === "Operator") {
|
|
382
|
-
return getValue(maybeColumnNode, state);
|
|
307
|
+
var filterValue = (value) => typeof value === "string" ? `"${value}"` : value;
|
|
308
|
+
var filterAsQuery = (f) => {
|
|
309
|
+
if (isMultiClauseFilter(f)) {
|
|
310
|
+
return f.filters.map((filter) => filterAsQuery(filter)).join(` ${f.op} `);
|
|
311
|
+
} else if (isMultiValueFilter(f)) {
|
|
312
|
+
return `${f.column} ${f.op} [${f.values.join(",")}]`;
|
|
383
313
|
} else {
|
|
384
|
-
return
|
|
314
|
+
return `${f.column} ${f.op} ${filterValue(f.value)}`;
|
|
385
315
|
}
|
|
386
316
|
};
|
|
387
|
-
var
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
return;
|
|
317
|
+
var includesAllValues = (filter) => {
|
|
318
|
+
if (!filter) {
|
|
319
|
+
return false;
|
|
391
320
|
}
|
|
392
|
-
if (
|
|
393
|
-
|
|
394
|
-
)) {
|
|
395
|
-
return value;
|
|
396
|
-
} else {
|
|
397
|
-
return void 0;
|
|
321
|
+
if (filter.op === STARTS_WITH && filter.value === "") {
|
|
322
|
+
return true;
|
|
398
323
|
}
|
|
324
|
+
return filter.op === STARTS_WITH && filter.value === "";
|
|
399
325
|
};
|
|
400
|
-
var
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
if (
|
|
405
|
-
return
|
|
406
|
-
}
|
|
407
|
-
|
|
326
|
+
var replaceOrInsert = (filters, filter) => {
|
|
327
|
+
return filters.concat(filter);
|
|
328
|
+
};
|
|
329
|
+
var merge = (f1, f2) => {
|
|
330
|
+
if (includesNoValues(f2)) {
|
|
331
|
+
return f2;
|
|
332
|
+
}
|
|
333
|
+
if (isInFilter(f1) && isInFilter(f2)) {
|
|
334
|
+
return {
|
|
335
|
+
...f1,
|
|
336
|
+
values: [
|
|
337
|
+
...f1.values,
|
|
338
|
+
...f2.values.filter(
|
|
339
|
+
(v) => !f1.values.includes(v)
|
|
340
|
+
)
|
|
341
|
+
]
|
|
342
|
+
};
|
|
343
|
+
} else if (isInFilter(f1) && f2.op === EQUALS) {
|
|
344
|
+
return {
|
|
345
|
+
...f1,
|
|
346
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
values: f1.values.concat([f2.value])
|
|
349
|
+
};
|
|
350
|
+
} else if (f1.op === EQUALS && f2.op === EQUALS) {
|
|
351
|
+
return {
|
|
352
|
+
column: f1.column,
|
|
353
|
+
op: IN,
|
|
354
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
355
|
+
// @ts-ignore
|
|
356
|
+
values: [f1.value, f2.value]
|
|
357
|
+
};
|
|
408
358
|
}
|
|
359
|
+
return f2;
|
|
409
360
|
};
|
|
410
|
-
var
|
|
411
|
-
|
|
412
|
-
return
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
361
|
+
var combine = (existingFilters, replacementFilters) => {
|
|
362
|
+
const equivalentType = ({ op: t1 }, { op: t2 }) => {
|
|
363
|
+
return t1 === t2 || t1[0] === t2[0];
|
|
364
|
+
};
|
|
365
|
+
const replaces = (existingFilter, replacementFilter) => {
|
|
366
|
+
return existingFilter.column === replacementFilter.column && equivalentType(existingFilter, replacementFilter);
|
|
367
|
+
};
|
|
368
|
+
const stillApplicable = (existingFilter) => replacementFilters.some(
|
|
369
|
+
(replacementFilter) => replaces(existingFilter, replacementFilter)
|
|
370
|
+
) === false;
|
|
371
|
+
return existingFilters.filter(stillApplicable).concat(replacementFilters);
|
|
372
|
+
};
|
|
373
|
+
var removeColumnFromFilter = (column, filter) => {
|
|
374
|
+
if (isMultiClauseFilter(filter)) {
|
|
375
|
+
const [clause1, clause2] = filter.filters;
|
|
376
|
+
if (clause1.column === column.name) {
|
|
377
|
+
return [clause2, filterAsQuery(clause2)];
|
|
378
|
+
}
|
|
379
|
+
if (clause2.column === column.name) {
|
|
380
|
+
return [clause1, filterAsQuery(clause1)];
|
|
419
381
|
}
|
|
420
382
|
}
|
|
383
|
+
return [void 0, ""];
|
|
421
384
|
};
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
return getValue(prevNode, state);
|
|
426
|
-
} else if ((prevNode == null ? void 0 : prevNode.name) === "Operator") {
|
|
427
|
-
return getColumnName(prevNode, state);
|
|
385
|
+
var removeFilter = (sourceFilter, filterToRemove) => {
|
|
386
|
+
if (filterEquals(sourceFilter, filterToRemove, true)) {
|
|
387
|
+
return null;
|
|
428
388
|
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
if (value) {
|
|
436
|
-
values.push(value);
|
|
437
|
-
} else {
|
|
438
|
-
break;
|
|
439
|
-
}
|
|
440
|
-
maybeTargetNode = maybeTargetNode.prevSibling;
|
|
389
|
+
if (sourceFilter.op !== AND) {
|
|
390
|
+
throw Error(
|
|
391
|
+
`removeFilter cannot remove ${JSON.stringify(
|
|
392
|
+
filterToRemove
|
|
393
|
+
)} from ${JSON.stringify(sourceFilter)}`
|
|
394
|
+
);
|
|
441
395
|
}
|
|
442
|
-
|
|
396
|
+
const filters = sourceFilter.filters.filter(
|
|
397
|
+
(f) => !filterEquals(f, filterToRemove)
|
|
398
|
+
);
|
|
399
|
+
return filters.length > 0 ? { type: AND, filters } : null;
|
|
443
400
|
};
|
|
444
|
-
var
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
async (context) => {
|
|
458
|
-
var _a, _b;
|
|
459
|
-
const { state, pos } = context;
|
|
460
|
-
const word = (_a = context.matchBefore(/\w*/)) != null ? _a : {
|
|
461
|
-
from: 0,
|
|
462
|
-
to: 0,
|
|
463
|
-
text: void 0
|
|
464
|
-
};
|
|
465
|
-
const tree = syntaxTree(state);
|
|
466
|
-
const nodeBefore = tree.resolveInner(pos, -1);
|
|
467
|
-
console.log({ nodeBeforeName: nodeBefore.name });
|
|
468
|
-
switch (nodeBefore.name) {
|
|
469
|
-
case "Filter":
|
|
470
|
-
if (context.pos === 0) {
|
|
471
|
-
return makeSuggestions(context, "column");
|
|
472
|
-
} else {
|
|
473
|
-
const clauseOperator = getClauseOperator(nodeBefore, state);
|
|
474
|
-
if (clauseOperator === "as") {
|
|
475
|
-
return makeSuggestions(context, "name");
|
|
476
|
-
} else {
|
|
477
|
-
const filterName = getFilterName(nodeBefore, state);
|
|
478
|
-
return makeSuggestions(context, "save", {
|
|
479
|
-
onSubmit: onSubmit.current,
|
|
480
|
-
existingFilter,
|
|
481
|
-
filterName
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
case "String":
|
|
486
|
-
{
|
|
487
|
-
const operator = getOperator(nodeBefore, state);
|
|
488
|
-
const columnName = getColumnName(nodeBefore, state);
|
|
489
|
-
const { from, to } = nodeBefore;
|
|
490
|
-
if (to - from === 2 && context.pos === from + 1) {
|
|
491
|
-
if (columnName && operator) {
|
|
492
|
-
return makeSuggestions(context, "columnValue", {
|
|
493
|
-
columnName,
|
|
494
|
-
operator,
|
|
495
|
-
quoted: true,
|
|
496
|
-
startsWith: word.text
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
} else {
|
|
500
|
-
console.log(
|
|
501
|
-
`we have a string, column is ${columnName} ${from} ${to}`
|
|
502
|
-
);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
break;
|
|
506
|
-
case "As":
|
|
507
|
-
return makeSuggestions(context, "name");
|
|
508
|
-
case "FilterName":
|
|
509
|
-
return makeSuggestions(context, "save", {
|
|
510
|
-
onSubmit: onSubmit.current,
|
|
511
|
-
existingFilter,
|
|
512
|
-
filterName: getFilterName(nodeBefore, state)
|
|
513
|
-
});
|
|
514
|
-
case "Column": {
|
|
515
|
-
const columnName = getValue(nodeBefore, state);
|
|
516
|
-
const isPartialMatch = await suggestionProvider.isPartialMatch(
|
|
517
|
-
"column",
|
|
518
|
-
void 0,
|
|
519
|
-
columnName
|
|
520
|
-
);
|
|
521
|
-
if (isPartialMatch) {
|
|
522
|
-
return makeSuggestions(context, "column", {
|
|
523
|
-
startsWith: columnName
|
|
524
|
-
});
|
|
525
|
-
} else {
|
|
526
|
-
return makeSuggestions(context, "operator", { columnName });
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
case "\u26A0": {
|
|
530
|
-
const columnName = getNodeByName(nodeBefore, state);
|
|
531
|
-
const operator = getOperator(nodeBefore, state);
|
|
532
|
-
const partialOperator = operator ? void 0 : getPartialOperator(nodeBefore, state, columnName);
|
|
533
|
-
if (partialOperator) {
|
|
534
|
-
return makeSuggestions(context, "operator", {
|
|
535
|
-
columnName,
|
|
536
|
-
startsWith: partialOperator
|
|
537
|
-
});
|
|
538
|
-
} else {
|
|
539
|
-
return makeSuggestions(context, "columnValue", {
|
|
540
|
-
columnName,
|
|
541
|
-
operator,
|
|
542
|
-
startsWith: word.text
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
case "Identifier":
|
|
547
|
-
{
|
|
548
|
-
const clauseOperator = getClauseOperator(nodeBefore, state);
|
|
549
|
-
if (clauseOperator === "as") {
|
|
550
|
-
return {
|
|
551
|
-
from: context.pos,
|
|
552
|
-
options: [
|
|
553
|
-
{
|
|
554
|
-
label: "press ENTER to apply filter and save",
|
|
555
|
-
apply: () => onSubmit.current(),
|
|
556
|
-
boost: 5
|
|
557
|
-
}
|
|
558
|
-
]
|
|
559
|
-
};
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
break;
|
|
563
|
-
case "ColumnSetExpression":
|
|
564
|
-
case "Values": {
|
|
565
|
-
const columnName = getNodeByName(nodeBefore, state);
|
|
566
|
-
const selection = getSetValues(nodeBefore, state);
|
|
567
|
-
return makeSuggestions(context, "columnValue", {
|
|
568
|
-
columnName,
|
|
569
|
-
selection
|
|
570
|
-
});
|
|
571
|
-
}
|
|
572
|
-
case "Comma":
|
|
573
|
-
case "LBrack": {
|
|
574
|
-
const columnName = getNodeByName(nodeBefore, state);
|
|
575
|
-
return makeSuggestions(context, "columnValue", { columnName });
|
|
576
|
-
}
|
|
577
|
-
case "ColumnValueExpression":
|
|
578
|
-
{
|
|
579
|
-
const lastToken = (_b = nodeBefore.lastChild) == null ? void 0 : _b.prevSibling;
|
|
580
|
-
if ((lastToken == null ? void 0 : lastToken.name) === "Column") {
|
|
581
|
-
return makeSuggestions(context, "operator", {
|
|
582
|
-
columnName: getNodeByName(nodeBefore, state)
|
|
583
|
-
});
|
|
584
|
-
} else if ((lastToken == null ? void 0 : lastToken.name) === "Operator") {
|
|
585
|
-
return makeSuggestions(context, "columnValue", {
|
|
586
|
-
columnName: getNodeByName(lastToken, state),
|
|
587
|
-
operator: getValue(lastToken, state)
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
break;
|
|
592
|
-
case "In": {
|
|
593
|
-
return {
|
|
594
|
-
from: context.pos,
|
|
595
|
-
options: [{ label: "[", apply: " [", type: "text" }]
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
case "Eq": {
|
|
599
|
-
return makeSuggestions(context, "columnValue", {
|
|
600
|
-
columnName: getNodeByName(nodeBefore, state)
|
|
601
|
-
});
|
|
602
|
-
}
|
|
603
|
-
case "AndExpression":
|
|
604
|
-
case "OrExpression": {
|
|
605
|
-
return makeSuggestions(context, "column");
|
|
606
|
-
}
|
|
607
|
-
default:
|
|
608
|
-
}
|
|
609
|
-
},
|
|
610
|
-
[existingFilter, makeSuggestions, onSubmit, suggestionProvider]
|
|
401
|
+
var splitFilterOnColumn = (filter, columnName) => {
|
|
402
|
+
if (!filter) {
|
|
403
|
+
return [null, null];
|
|
404
|
+
}
|
|
405
|
+
if (filter.column === columnName) {
|
|
406
|
+
return [filter, null];
|
|
407
|
+
}
|
|
408
|
+
if (filter.op !== AND) {
|
|
409
|
+
return [null, filter];
|
|
410
|
+
}
|
|
411
|
+
const [[columnFilter = null], filters] = partition(
|
|
412
|
+
filter.filters,
|
|
413
|
+
(f) => f.column === columnName
|
|
611
414
|
);
|
|
415
|
+
return filters.length === 1 ? [columnFilter, filters[0]] : [columnFilter, { op: AND, filters }];
|
|
612
416
|
};
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
417
|
+
var overrideColName = (filter, column) => {
|
|
418
|
+
if (isMultiClauseFilter(filter)) {
|
|
419
|
+
return {
|
|
420
|
+
op: filter.op,
|
|
421
|
+
filters: filter.filters.map((f) => overrideColName(f, column))
|
|
422
|
+
};
|
|
618
423
|
}
|
|
619
|
-
return
|
|
424
|
+
return { ...filter, column };
|
|
620
425
|
};
|
|
621
|
-
var
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
}
|
|
426
|
+
var filterIncludesColumn = (filter, column) => {
|
|
427
|
+
if (!filter) {
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
const { op, column: filterColName } = filter;
|
|
431
|
+
switch (op) {
|
|
432
|
+
case AND:
|
|
433
|
+
case OR:
|
|
434
|
+
return filter.filters != null && filter.filters.some((f) => filterIncludesColumn(f, column));
|
|
435
|
+
default:
|
|
436
|
+
return filterColName === column.name;
|
|
437
|
+
}
|
|
625
438
|
};
|
|
626
|
-
var
|
|
627
|
-
const
|
|
628
|
-
if (
|
|
629
|
-
return
|
|
630
|
-
}
|
|
631
|
-
|
|
439
|
+
var removeFilterForColumn = (sourceFilter, column) => {
|
|
440
|
+
const colName = column.name;
|
|
441
|
+
if (!sourceFilter) {
|
|
442
|
+
return void 0;
|
|
443
|
+
}
|
|
444
|
+
if (sourceFilter.column === colName) {
|
|
445
|
+
return void 0;
|
|
632
446
|
}
|
|
447
|
+
if (isAndFilter(sourceFilter) || isOrFilter(sourceFilter)) {
|
|
448
|
+
const { op } = sourceFilter;
|
|
449
|
+
const filters = sourceFilter.filters;
|
|
450
|
+
const otherColFilters = filters.filter((f) => f.column !== colName);
|
|
451
|
+
switch (otherColFilters.length) {
|
|
452
|
+
case 0:
|
|
453
|
+
return void 0;
|
|
454
|
+
case 1:
|
|
455
|
+
return otherColFilters[0];
|
|
456
|
+
default:
|
|
457
|
+
return { op, filters: otherColFilters };
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
return sourceFilter;
|
|
633
461
|
};
|
|
634
|
-
var
|
|
635
|
-
var
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
)
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
462
|
+
var canMerge = (f1, f2) => f1.column === f2.column && (f1.op === "=" || f1.op === "in") && (f2.op === "=" || f2.op === "in");
|
|
463
|
+
var sameValues = (arr1, arr2) => {
|
|
464
|
+
if (arr1 === arr2) {
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
if (arr1.length === arr2.length) {
|
|
468
|
+
const a = arr1.slice().sort();
|
|
469
|
+
const b = arr2.slice().sort();
|
|
470
|
+
return a.join("|") === b.join("|");
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
};
|
|
474
|
+
var filterEquals = (f1, f2, strict = false) => {
|
|
475
|
+
if (!strict) {
|
|
476
|
+
return true;
|
|
477
|
+
}
|
|
478
|
+
if (f1 && f2 && canMerge(f1, f2)) {
|
|
479
|
+
return f1.op === f2.op && (isSingleValueFilter(f1) && isSingleValueFilter(f2) && f1.value === f2.value || isMultiValueFilter(f1) && isMultiValueFilter(f2) && sameValues(f1.values, f2.values));
|
|
480
|
+
}
|
|
481
|
+
return false;
|
|
482
|
+
};
|
|
483
|
+
var updateFilter = (filter, newFilter, mode) => {
|
|
484
|
+
if (filter && newFilter) {
|
|
485
|
+
if (mode === "replace") {
|
|
486
|
+
return newFilter;
|
|
487
|
+
}
|
|
488
|
+
if (filter.op === "and") {
|
|
489
|
+
return {
|
|
490
|
+
...filter,
|
|
491
|
+
filters: filter.filters.concat(newFilter)
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
const { column: columnName } = newFilter;
|
|
495
|
+
if (columnName) {
|
|
496
|
+
const existingClause = newFilter.column ? extractFilterForColumn(filter, columnName) : void 0;
|
|
497
|
+
if (existingClause && columnName) {
|
|
498
|
+
const result = removeFilterForColumn(filter, { name: columnName });
|
|
499
|
+
return updateFilter(result, newFilter, "add");
|
|
658
500
|
}
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
op: "and",
|
|
504
|
+
filters: [filter, newFilter]
|
|
659
505
|
};
|
|
660
|
-
|
|
661
|
-
|
|
506
|
+
}
|
|
507
|
+
if (newFilter) {
|
|
508
|
+
return newFilter;
|
|
509
|
+
}
|
|
510
|
+
return filter;
|
|
511
|
+
};
|
|
512
|
+
|
|
513
|
+
// src/column-filter/utils.ts
|
|
514
|
+
var isStartsWithValue = (value) => /\.\.\.$/.test(value);
|
|
515
|
+
var getTypeaheadFilter = (column, filterValues, isStartsWithFilter) => {
|
|
516
|
+
if (filterValues.length === 0) {
|
|
517
|
+
return void 0;
|
|
518
|
+
}
|
|
519
|
+
if (isStartsWithFilter) {
|
|
520
|
+
const startsWith = filterValues[0].substring(0, filterValues[0].length - 3);
|
|
521
|
+
return {
|
|
522
|
+
column,
|
|
523
|
+
op: "starts",
|
|
524
|
+
value: `"${startsWith}"`
|
|
662
525
|
};
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
526
|
+
}
|
|
527
|
+
return {
|
|
528
|
+
column,
|
|
529
|
+
op: "in",
|
|
530
|
+
values: filterValues.map((value) => `"${value}"`)
|
|
531
|
+
};
|
|
532
|
+
};
|
|
533
|
+
var getRangeFilter = (column, startValue, endValue) => {
|
|
534
|
+
const startFilter = startValue === void 0 ? void 0 : { column, op: ">", value: startValue - 1 };
|
|
535
|
+
const endFilter = endValue === void 0 ? void 0 : { column, op: "<", value: endValue + 1 };
|
|
536
|
+
if (endFilter === void 0)
|
|
537
|
+
return startFilter;
|
|
538
|
+
return addFilter(startFilter, endFilter, { combineWith: "and" });
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
// src/column-filter/RangeFilter.tsx
|
|
542
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
543
|
+
var RangeFilter = ({
|
|
544
|
+
defaultTypeaheadParams,
|
|
545
|
+
filterValues,
|
|
546
|
+
onChange
|
|
547
|
+
}) => {
|
|
548
|
+
var _a, _b;
|
|
549
|
+
const columnName = defaultTypeaheadParams[1];
|
|
550
|
+
const startChangeHandler = (e) => {
|
|
551
|
+
const value = parseFloat(e.target.value);
|
|
552
|
+
const newRange = {
|
|
553
|
+
start: isNaN(value) ? void 0 : value,
|
|
554
|
+
end: filterValues == null ? void 0 : filterValues.end
|
|
667
555
|
};
|
|
668
|
-
const
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
}
|
|
677
|
-
]);
|
|
556
|
+
const filter = getRangeFilter(columnName, newRange.start, newRange.end);
|
|
557
|
+
onChange(newRange, filter);
|
|
558
|
+
};
|
|
559
|
+
const endChangeHandler = (e) => {
|
|
560
|
+
const value = parseFloat(e.target.value);
|
|
561
|
+
const newRange = {
|
|
562
|
+
start: filterValues == null ? void 0 : filterValues.start,
|
|
563
|
+
end: isNaN(value) ? void 0 : value
|
|
678
564
|
};
|
|
679
|
-
const
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
565
|
+
const filter = getRangeFilter(columnName, newRange.start, newRange.end);
|
|
566
|
+
onChange(newRange, filter);
|
|
567
|
+
};
|
|
568
|
+
return /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "row" }, children: [
|
|
569
|
+
/* @__PURE__ */ jsx3(ToolbarField, { label: "From", children: /* @__PURE__ */ jsx3(
|
|
570
|
+
Input,
|
|
571
|
+
{
|
|
572
|
+
onChange: startChangeHandler,
|
|
573
|
+
value: ((_a = filterValues == null ? void 0 : filterValues.start) == null ? void 0 : _a.toString()) || "",
|
|
574
|
+
type: "number"
|
|
575
|
+
}
|
|
576
|
+
) }),
|
|
577
|
+
/* @__PURE__ */ jsx3(ToolbarField, { label: "To", children: /* @__PURE__ */ jsx3(
|
|
578
|
+
Input,
|
|
579
|
+
{
|
|
580
|
+
onChange: endChangeHandler,
|
|
581
|
+
value: ((_b = filterValues == null ? void 0 : filterValues.end) == null ? void 0 : _b.toString()) || "",
|
|
582
|
+
type: "number"
|
|
583
|
+
}
|
|
584
|
+
) })
|
|
585
|
+
] });
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
// src/column-filter/TypeaheadFilter.tsx
|
|
589
|
+
import { useCallback, useEffect, useState } from "react";
|
|
590
|
+
import { useTypeaheadSuggestions } from "@vuu-ui/vuu-data";
|
|
591
|
+
import { ComboBoxDeprecated } from "@heswell/salt-lab";
|
|
592
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
593
|
+
var TypeaheadFilter = ({
|
|
594
|
+
defaultTypeaheadParams,
|
|
595
|
+
filterValues = [],
|
|
596
|
+
onChange: onFilterChange
|
|
597
|
+
}) => {
|
|
598
|
+
const [tableName, columnName] = defaultTypeaheadParams;
|
|
599
|
+
const [searchValue, setSearchValue] = useState("");
|
|
600
|
+
const [typeaheadValues, setTypeaheadValues] = useState([]);
|
|
601
|
+
const getSuggestions = useTypeaheadSuggestions();
|
|
602
|
+
useEffect(() => {
|
|
603
|
+
const params = searchValue ? [tableName, columnName, searchValue] : defaultTypeaheadParams;
|
|
604
|
+
let isSubscribed = true;
|
|
605
|
+
getSuggestions(params).then((options) => {
|
|
606
|
+
if (!isSubscribed) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (isStartsWithValue(filterValues[0])) {
|
|
610
|
+
options.unshift(filterValues[0]);
|
|
611
|
+
}
|
|
612
|
+
if (searchValue) {
|
|
613
|
+
options.unshift(`${searchValue}...`);
|
|
614
|
+
}
|
|
615
|
+
options.concat(filterValues);
|
|
616
|
+
setTypeaheadValues(options);
|
|
617
|
+
});
|
|
618
|
+
return () => {
|
|
619
|
+
isSubscribed = false;
|
|
689
620
|
};
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
621
|
+
}, [
|
|
622
|
+
filterValues,
|
|
623
|
+
searchValue,
|
|
624
|
+
columnName,
|
|
625
|
+
tableName,
|
|
626
|
+
getSuggestions,
|
|
627
|
+
defaultTypeaheadParams
|
|
628
|
+
]);
|
|
629
|
+
const onInputChange = useCallback(
|
|
630
|
+
(evt) => {
|
|
631
|
+
const value = evt.target.value;
|
|
632
|
+
setSearchValue(value);
|
|
633
|
+
},
|
|
634
|
+
[]
|
|
635
|
+
);
|
|
636
|
+
const onSelectionChange = useCallback(
|
|
637
|
+
(_evt, selected) => {
|
|
638
|
+
setSearchValue("");
|
|
639
|
+
if (selected === null)
|
|
640
|
+
return;
|
|
641
|
+
if (selected.some(isStartsWithValue)) {
|
|
642
|
+
selected = selected.filter(isStartsWithValue).slice(-1);
|
|
643
|
+
}
|
|
644
|
+
const filter = getTypeaheadFilter(
|
|
645
|
+
columnName,
|
|
646
|
+
selected,
|
|
647
|
+
isStartsWithValue(selected[0])
|
|
648
|
+
);
|
|
649
|
+
onFilterChange(selected, filter);
|
|
650
|
+
},
|
|
651
|
+
[columnName, onFilterChange]
|
|
652
|
+
);
|
|
653
|
+
return /* @__PURE__ */ jsx4(
|
|
654
|
+
ComboBoxDeprecated,
|
|
655
|
+
{
|
|
656
|
+
multiSelect: true,
|
|
657
|
+
onInputChange,
|
|
658
|
+
onChange: onSelectionChange,
|
|
659
|
+
source: typeaheadValues,
|
|
660
|
+
style: { minWidth: 200 },
|
|
661
|
+
inputValue: searchValue,
|
|
662
|
+
selectedItem: filterValues
|
|
663
|
+
},
|
|
664
|
+
columnName
|
|
665
|
+
);
|
|
666
|
+
};
|
|
667
|
+
|
|
668
|
+
// src/column-filter/ColumnListItem.tsx
|
|
669
|
+
import { memo } from "react";
|
|
670
|
+
import {
|
|
671
|
+
Highlighter,
|
|
672
|
+
ListItem
|
|
673
|
+
} from "@heswell/salt-lab";
|
|
674
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
675
|
+
var ColumnListItem = (props) => {
|
|
676
|
+
return /* @__PURE__ */ jsx5(MemoColumnItem, { ...props });
|
|
677
|
+
};
|
|
678
|
+
var MemoColumnItem = memo(function MemoizedItem({
|
|
679
|
+
item,
|
|
680
|
+
itemTextHighlightPattern,
|
|
681
|
+
...restProps
|
|
682
|
+
}) {
|
|
683
|
+
return /* @__PURE__ */ jsx5(ListItem, { ...restProps, children: /* @__PURE__ */ jsx5("span", { style: { marginLeft: 10 }, children: /* @__PURE__ */ jsx5(
|
|
684
|
+
Highlighter,
|
|
685
|
+
{
|
|
686
|
+
matchPattern: itemTextHighlightPattern,
|
|
687
|
+
text: item == null ? void 0 : item.name
|
|
688
|
+
}
|
|
689
|
+
) }) });
|
|
690
|
+
});
|
|
691
|
+
|
|
692
|
+
// src/column-filter/useColumnFilterStore.ts
|
|
693
|
+
import { useCallback as useCallback2, useState as useState2 } from "react";
|
|
694
|
+
var addOrReplace = (array, newValue, key) => array.filter((oldValue) => oldValue[key] !== newValue[key]).concat(newValue);
|
|
695
|
+
var useColumnFilterStore = (onFilterSubmit) => {
|
|
696
|
+
var _a, _b;
|
|
697
|
+
const [selectedColumnName, setSelectedColumnName] = useState2("");
|
|
698
|
+
const [savedFilters, setSavedFilters] = useState2([]);
|
|
699
|
+
const [rangeValues, setRangeValues] = useState2([]);
|
|
700
|
+
const [typeaheadValues, setTypeaheadValues] = useState2([]);
|
|
701
|
+
const clear = () => {
|
|
702
|
+
setSelectedColumnName("");
|
|
703
|
+
setRangeValues([]);
|
|
704
|
+
setTypeaheadValues([]);
|
|
705
|
+
setSavedFilters([]);
|
|
706
|
+
onFilterSubmit("");
|
|
707
|
+
};
|
|
708
|
+
const updateFilters = useCallback2(
|
|
709
|
+
(newFilter) => {
|
|
710
|
+
const newSavedFilters = addOrReplace(
|
|
711
|
+
savedFilters,
|
|
712
|
+
{ column: selectedColumnName, filter: newFilter },
|
|
713
|
+
"column"
|
|
714
|
+
);
|
|
715
|
+
setSavedFilters(newSavedFilters);
|
|
716
|
+
const combinedFilter = newSavedFilters.map((x) => x.filter).reduce((prev, filter) => {
|
|
717
|
+
if (filter === void 0)
|
|
718
|
+
return prev;
|
|
719
|
+
return addFilter(prev, filter, { combineWith: AND });
|
|
720
|
+
}, void 0);
|
|
721
|
+
const query = combinedFilter === void 0 ? "" : filterAsQuery(combinedFilter);
|
|
722
|
+
onFilterSubmit(query, combinedFilter);
|
|
723
|
+
},
|
|
724
|
+
[selectedColumnName, onFilterSubmit, savedFilters]
|
|
725
|
+
);
|
|
726
|
+
const onTypeaheadChange = useCallback2(
|
|
727
|
+
(newValues, newFilter) => {
|
|
728
|
+
setTypeaheadValues(
|
|
729
|
+
addOrReplace(
|
|
730
|
+
typeaheadValues,
|
|
731
|
+
{ column: selectedColumnName, value: newValues },
|
|
732
|
+
"column"
|
|
733
|
+
)
|
|
734
|
+
);
|
|
735
|
+
updateFilters(newFilter);
|
|
736
|
+
},
|
|
737
|
+
[selectedColumnName, typeaheadValues, updateFilters]
|
|
738
|
+
);
|
|
739
|
+
const onRangeChange = useCallback2(
|
|
740
|
+
(newValues, newFilter) => {
|
|
741
|
+
setRangeValues(
|
|
742
|
+
addOrReplace(
|
|
743
|
+
rangeValues,
|
|
744
|
+
{ column: selectedColumnName, value: newValues },
|
|
745
|
+
"column"
|
|
746
|
+
)
|
|
747
|
+
);
|
|
748
|
+
updateFilters(newFilter);
|
|
749
|
+
},
|
|
750
|
+
[selectedColumnName, rangeValues, updateFilters]
|
|
751
|
+
);
|
|
752
|
+
const onSelectedColumnChange = useCallback2(
|
|
753
|
+
(column) => setSelectedColumnName((column == null ? void 0 : column.name) || ""),
|
|
754
|
+
[]
|
|
755
|
+
);
|
|
756
|
+
const rangeValue = (_a = rangeValues.filter(
|
|
757
|
+
(v) => v.column === selectedColumnName
|
|
758
|
+
)[0]) == null ? void 0 : _a.value;
|
|
759
|
+
const typeaheadValue = (_b = typeaheadValues.filter(
|
|
760
|
+
(v) => v.column === selectedColumnName
|
|
761
|
+
)[0]) == null ? void 0 : _b.value;
|
|
762
|
+
return {
|
|
763
|
+
clear,
|
|
764
|
+
selectedColumnName,
|
|
765
|
+
rangeValue,
|
|
766
|
+
typeaheadValue,
|
|
767
|
+
onSelectedColumnChange,
|
|
768
|
+
onRangeChange,
|
|
769
|
+
onTypeaheadChange
|
|
770
|
+
};
|
|
771
|
+
};
|
|
772
|
+
|
|
773
|
+
// src/column-filter/ColumnFilter.tsx
|
|
774
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
775
|
+
var ColumnFilter = ({
|
|
776
|
+
className,
|
|
777
|
+
table,
|
|
778
|
+
columns,
|
|
779
|
+
onFilterSubmit,
|
|
780
|
+
...htmlAttributes
|
|
781
|
+
}) => {
|
|
782
|
+
const {
|
|
783
|
+
clear,
|
|
784
|
+
onTypeaheadChange,
|
|
785
|
+
onRangeChange,
|
|
786
|
+
onSelectedColumnChange,
|
|
787
|
+
selectedColumnName,
|
|
788
|
+
rangeValue,
|
|
789
|
+
typeaheadValue
|
|
790
|
+
} = useColumnFilterStore(onFilterSubmit);
|
|
791
|
+
const getFilterComponent = () => {
|
|
792
|
+
var _a;
|
|
793
|
+
const defaultTypeaheadParams = [table, selectedColumnName];
|
|
794
|
+
const selectedColumnType = (_a = columns.find(
|
|
795
|
+
(column) => column.name === selectedColumnName
|
|
796
|
+
)) == null ? void 0 : _a.serverDataType;
|
|
797
|
+
switch (selectedColumnType) {
|
|
798
|
+
case "string":
|
|
799
|
+
case "char":
|
|
800
|
+
return /* @__PURE__ */ jsx6(
|
|
801
|
+
ToolbarField2,
|
|
802
|
+
{
|
|
803
|
+
label: "Start typing to select a filter",
|
|
804
|
+
labelPlacement: "top",
|
|
805
|
+
children: /* @__PURE__ */ jsx6(
|
|
806
|
+
TypeaheadFilter,
|
|
807
|
+
{
|
|
808
|
+
defaultTypeaheadParams,
|
|
809
|
+
filterValues: typeaheadValue,
|
|
810
|
+
onChange: onTypeaheadChange
|
|
811
|
+
}
|
|
812
|
+
)
|
|
813
|
+
}
|
|
814
|
+
);
|
|
815
|
+
case "int":
|
|
816
|
+
case "long":
|
|
817
|
+
case "double":
|
|
818
|
+
return /* @__PURE__ */ jsx6(ToolbarField2, { label: "Select a range", labelPlacement: "top", children: /* @__PURE__ */ jsx6(
|
|
819
|
+
RangeFilter,
|
|
820
|
+
{
|
|
821
|
+
defaultTypeaheadParams,
|
|
822
|
+
filterValues: rangeValue,
|
|
823
|
+
onChange: onRangeChange
|
|
824
|
+
}
|
|
825
|
+
) });
|
|
826
|
+
default:
|
|
827
|
+
return /* @__PURE__ */ jsx6(ToolbarField2, { children: /* @__PURE__ */ jsx6(Text, { children: "Data type unsupported" }) });
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
return /* @__PURE__ */ jsxs3(
|
|
831
|
+
Toolbar,
|
|
832
|
+
{
|
|
833
|
+
...htmlAttributes,
|
|
834
|
+
style: { alignItems: "center", height: "36px" },
|
|
835
|
+
children: [
|
|
836
|
+
/* @__PURE__ */ jsx6(
|
|
837
|
+
ToolbarField2,
|
|
838
|
+
{
|
|
839
|
+
label: "Select a column to filter",
|
|
840
|
+
labelPlacement: "top",
|
|
841
|
+
style: { width: 180 },
|
|
842
|
+
children: /* @__PURE__ */ jsx6(
|
|
843
|
+
Dropdown,
|
|
844
|
+
{
|
|
845
|
+
source: columns,
|
|
846
|
+
ListItem: ColumnListItem,
|
|
847
|
+
itemToString: (column) => column.name,
|
|
848
|
+
onSelectionChange: (_evt, column) => onSelectedColumnChange(column)
|
|
849
|
+
}
|
|
850
|
+
)
|
|
706
851
|
}
|
|
707
|
-
}),
|
|
708
|
-
EditorState2.transactionFilter.of(
|
|
709
|
-
(tr) => tr.newDoc.lines > 1 ? [] : tr
|
|
710
852
|
),
|
|
711
|
-
|
|
712
|
-
|
|
853
|
+
selectedColumnName && getFilterComponent(),
|
|
854
|
+
/* @__PURE__ */ jsx6(ToolbarButton, { onClick: clear, children: /* @__PURE__ */ jsx6(DeleteIcon, {}) })
|
|
713
855
|
]
|
|
714
|
-
});
|
|
715
|
-
onSubmit.current = (mode) => {
|
|
716
|
-
submitFilterAndClearInput(mode);
|
|
717
|
-
setTimeout(() => {
|
|
718
|
-
getView(viewRef).focus();
|
|
719
|
-
}, 100);
|
|
720
|
-
};
|
|
721
|
-
return [createState2, clearInput2];
|
|
722
|
-
}, [completionFn, onSubmitFilter]);
|
|
723
|
-
useEffect(() => {
|
|
724
|
-
if (!editorRef.current) {
|
|
725
|
-
throw Error("editor not in dom");
|
|
726
856
|
}
|
|
727
|
-
|
|
728
|
-
state: createState(),
|
|
729
|
-
parent: editorRef.current
|
|
730
|
-
});
|
|
731
|
-
return () => {
|
|
732
|
-
var _a;
|
|
733
|
-
(_a = viewRef.current) == null ? void 0 : _a.destroy();
|
|
734
|
-
};
|
|
735
|
-
}, [completionFn, createState]);
|
|
736
|
-
return { editorRef, clearInput };
|
|
857
|
+
);
|
|
737
858
|
};
|
|
738
859
|
|
|
739
860
|
// src/filter-input/FilterInput.tsx
|
|
740
|
-
import {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
861
|
+
import { Button } from "@salt-ds/core";
|
|
862
|
+
|
|
863
|
+
// src/filter-input/useCodeMirrorEditor.ts
|
|
864
|
+
var import_classnames = __toESM(require_classnames(), 1);
|
|
865
|
+
import {
|
|
866
|
+
autocompletion,
|
|
867
|
+
defaultKeymap,
|
|
868
|
+
EditorState as EditorState2,
|
|
869
|
+
EditorView as EditorView2,
|
|
870
|
+
ensureSyntaxTree,
|
|
871
|
+
keymap,
|
|
872
|
+
minimalSetup,
|
|
873
|
+
startCompletion
|
|
874
|
+
} from "@vuu-ui/vuu-codemirror";
|
|
875
|
+
import { useEffect as useEffect2, useMemo, useRef } from "react";
|
|
876
|
+
|
|
877
|
+
// src/filter-input/filter-language-parser/FilterLanguage.ts
|
|
878
|
+
import {
|
|
879
|
+
LanguageSupport,
|
|
880
|
+
LRLanguage,
|
|
881
|
+
styleTags,
|
|
882
|
+
tags as tag
|
|
883
|
+
} from "@vuu-ui/vuu-codemirror";
|
|
884
|
+
|
|
885
|
+
// src/filter-input/filter-language-parser/generated/filter-parser.js
|
|
886
|
+
import { LRParser } from "@vuu-ui/vuu-codemirror";
|
|
887
|
+
var parser = LRParser.deserialize({
|
|
888
|
+
version: 14,
|
|
889
|
+
states: "%QOVQPOOOOQO'#C_'#C_O_QQO'#C^OOQO'#DO'#DOOvQQO'#C|OOQO'#DR'#DROVQPO'#CuOOQO'#C}'#C}QOQPOOOOQO'#C`'#C`O!UQQO,58xO!dQPO,59VOVQPO,59]OVQPO,59_O!iQPO,59hO!nQQO,59aOOQO'#DQ'#DQOOQO1G.d1G.dO!UQQO1G.qO!yQQO1G.wOOQO1G.y1G.yOOQO'#Cw'#CwOOQO1G/S1G/SOOQO1G.{1G.{O#[QPO'#CnO#dQPO7+$]O!UQQO'#CxO#iQPO,59YOOQO<<Gw<<GwOOQO,59d,59dOOQO-E6v-E6v",
|
|
890
|
+
stateData: "#q~OoOS~OsPOvUO~OTXOUXOVXOWXOXXOYXO`ZO~Of[Oh]Oj^OmpX~OZ`O[`O]`O^`O~OabO~OseO~Of[Oh]OwgO~Oh]Ofeijeimeiwei~OcjOdbX~OdlO~OcjOdba~O",
|
|
891
|
+
goto: "#YvPPw}!TPPPPPPPPPPwPP!WPP!ZP!ZP!aP!g!jPPP!p!s!aP#P!aXROU[]XQOU[]RYQRibXTOU[]XVOU[]Rf^QkhRnkRWOQSOQ_UQc[Rd]QaYQhbRmj",
|
|
892
|
+
nodeNames: "\u26A0 Filter ColumnValueExpression Column Operator Eq NotEq Gt Lt Starts Ends Number String True False ColumnSetExpression In LBrack Values Comma RBrack AndExpression And OrExpression Or ParenthesizedExpression As FilterName",
|
|
893
|
+
maxTerm: 39,
|
|
894
|
+
skippedNodes: [0],
|
|
895
|
+
repeatNodeCount: 1,
|
|
896
|
+
tokenData: "6p~RnXY#PYZ#P]^#Ppq#Pqr#brs#mxy$eyz$j|}$o!O!P$t!Q![%S!^!_%_!_!`%d!`!a%i!c!}%n!}#O&V#P#Q&[#R#S%n#T#U&a#U#X%n#X#Y(w#Y#Z+]#Z#]%n#]#^.]#^#c%n#c#d/e#d#g%n#g#h0m#h#i4[#i#o%n~#USo~XY#PYZ#P]^#Ppq#P~#eP!_!`#h~#mOU~~#pWOX#mZ]#m^r#mrs$Ys#O#m#P;'S#m;'S;=`$_<%lO#m~$_O[~~$bP;=`<%l#m~$jOv~~$oOw~~$tOc~~$wP!Q![$z~%PPZ~!Q![$z~%XQZ~!O!P$t!Q![%S~%dOW~~%iOT~~%nOV~P%sUsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n~&[Oa~~&aOd~R&fYsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c'U#c#g%n#g#h(^#h#o%nR'ZWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X's#X#o%nR'zUfQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(eUjQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR(|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c)f#c#o%nR)kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#W%n#W#X*T#X#o%nR*YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h*r#h#o%nR*yUYQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR+bVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U+w#U#o%nR+|WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#`%n#`#a,f#a#o%nR,kWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h-T#h#o%nR-YWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y-r#Y#o%nR-yU^QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR.bWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#b%n#b#c.z#c#o%nR/RU`QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR/jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g0S#g#o%nR0ZUhQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR0rWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i1[#i#o%nR1aVsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#U1v#U#o%nR1{WsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g2e#g#o%nR2jWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#h%n#h#i3S#i#o%nR3XWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#g%n#g#h3q#h#o%nR3xUXQsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%nR4aWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#f%n#f#g4y#g#o%nR5OWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#i%n#i#j5h#j#o%nR5mWsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#X%n#X#Y6V#Y#o%nR6^U]QsP}!O%n!O!P%n!Q![%n!c!}%n#R#S%n#T#o%n",
|
|
897
|
+
tokenizers: [0, 1],
|
|
898
|
+
topRules: { "Filter": [0, 1] },
|
|
899
|
+
tokenPrec: 0
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
// src/filter-input/filter-language-parser/FilterLanguage.ts
|
|
903
|
+
var filterLanguage = LRLanguage.define({
|
|
904
|
+
name: "VuuFilterQuery",
|
|
905
|
+
parser: parser.configure({
|
|
906
|
+
props: [
|
|
907
|
+
styleTags({
|
|
908
|
+
Identifier: tag.variableName,
|
|
909
|
+
String: tag.string,
|
|
910
|
+
Or: tag.emphasis,
|
|
911
|
+
Operator: tag.operator
|
|
912
|
+
})
|
|
913
|
+
]
|
|
914
|
+
})
|
|
915
|
+
});
|
|
916
|
+
var filterLanguageSupport = () => {
|
|
917
|
+
return new LanguageSupport(filterLanguage);
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
// src/filter-input/filter-language-parser/FilterTreeWalker.ts
|
|
921
|
+
import {
|
|
922
|
+
isMultiClauseFilter as isMultiClauseFilter2,
|
|
923
|
+
isMultiValueFilter as isMultiValueFilter2,
|
|
924
|
+
isSingleValueFilter as isSingleValueFilter2
|
|
925
|
+
} from "@vuu-ui/vuu-utils";
|
|
926
|
+
var _filter;
|
|
927
|
+
var FilterExpression = class {
|
|
928
|
+
constructor() {
|
|
929
|
+
__privateAdd(this, _filter, void 0);
|
|
930
|
+
}
|
|
931
|
+
setFilterCombinatorOp(op, filter = __privateGet(this, _filter)) {
|
|
932
|
+
if (isMultiClauseFilter2(filter) && filter.op === op) {
|
|
933
|
+
return;
|
|
934
|
+
} else {
|
|
935
|
+
__privateSet(this, _filter, {
|
|
936
|
+
op,
|
|
937
|
+
filters: [__privateGet(this, _filter)]
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
add(filter) {
|
|
942
|
+
if (__privateGet(this, _filter) === void 0) {
|
|
943
|
+
__privateSet(this, _filter, filter);
|
|
944
|
+
} else if (isMultiClauseFilter2(__privateGet(this, _filter))) {
|
|
945
|
+
__privateGet(this, _filter).filters.push(filter);
|
|
946
|
+
} else {
|
|
947
|
+
throw Error(`Invalid filter passed to FilterExpression`);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
setColumn(column, filter = __privateGet(this, _filter)) {
|
|
951
|
+
if (isMultiClauseFilter2(filter)) {
|
|
952
|
+
const target = filter.filters.at(-1);
|
|
953
|
+
if (target) {
|
|
954
|
+
this.setColumn(column, target);
|
|
955
|
+
}
|
|
956
|
+
} else if (filter) {
|
|
957
|
+
filter.column = column;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
setOp(value, filter = __privateGet(this, _filter)) {
|
|
961
|
+
if (isMultiClauseFilter2(filter)) {
|
|
962
|
+
const target = filter.filters.at(-1);
|
|
963
|
+
if (target) {
|
|
964
|
+
this.setOp(value, target);
|
|
965
|
+
}
|
|
966
|
+
} else if (filter) {
|
|
967
|
+
filter.op = value;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
setValue(value, filter = __privateGet(this, _filter)) {
|
|
971
|
+
var _a;
|
|
972
|
+
if (isMultiClauseFilter2(filter)) {
|
|
973
|
+
const target = filter.filters.at(-1);
|
|
974
|
+
if (target) {
|
|
975
|
+
this.setValue(value, target);
|
|
976
|
+
}
|
|
977
|
+
} else if (isMultiValueFilter2(filter)) {
|
|
978
|
+
(_a = filter.values) != null ? _a : filter.values = [];
|
|
979
|
+
filter.values.push(value);
|
|
980
|
+
} else if (isSingleValueFilter2(filter)) {
|
|
981
|
+
filter.value = value;
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
toJSON(filter = __privateGet(this, _filter)) {
|
|
985
|
+
if (this.name) {
|
|
986
|
+
return {
|
|
987
|
+
...filter,
|
|
988
|
+
name: this.name
|
|
989
|
+
};
|
|
990
|
+
} else {
|
|
991
|
+
return filter;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
_filter = new WeakMap();
|
|
996
|
+
var walkTree = (tree, source) => {
|
|
997
|
+
const filterExpression = new FilterExpression();
|
|
998
|
+
const cursor = tree.cursor();
|
|
999
|
+
do {
|
|
1000
|
+
const { name, from, to } = cursor;
|
|
1001
|
+
switch (name) {
|
|
1002
|
+
case "ColumnValueExpression":
|
|
1003
|
+
filterExpression.add({});
|
|
1004
|
+
break;
|
|
1005
|
+
case "ColumnSetExpression":
|
|
1006
|
+
filterExpression.add({ op: "in" });
|
|
1007
|
+
break;
|
|
1008
|
+
case "Or":
|
|
1009
|
+
case "And":
|
|
1010
|
+
filterExpression.setFilterCombinatorOp(source.substring(from, to));
|
|
1011
|
+
break;
|
|
1012
|
+
case "Column":
|
|
1013
|
+
filterExpression.setColumn(source.substring(from, to));
|
|
1014
|
+
break;
|
|
1015
|
+
case "Operator":
|
|
1016
|
+
filterExpression.setOp(source.substring(from, to));
|
|
1017
|
+
break;
|
|
1018
|
+
case "String":
|
|
1019
|
+
filterExpression.setValue(source.substring(from + 1, to - 1));
|
|
1020
|
+
break;
|
|
1021
|
+
case "Number":
|
|
1022
|
+
filterExpression.setValue(parseFloat(source.substring(from, to)));
|
|
1023
|
+
break;
|
|
1024
|
+
case "True":
|
|
1025
|
+
filterExpression.setValue(true);
|
|
1026
|
+
break;
|
|
1027
|
+
case "False":
|
|
1028
|
+
filterExpression.setValue(false);
|
|
1029
|
+
break;
|
|
1030
|
+
case "FilterName":
|
|
1031
|
+
filterExpression.name = source.substring(from, to);
|
|
1032
|
+
break;
|
|
1033
|
+
default:
|
|
1034
|
+
}
|
|
1035
|
+
} while (cursor.next());
|
|
1036
|
+
return filterExpression.toJSON();
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
// src/filter-input/filter-language-parser/FilterParser.ts
|
|
1040
|
+
var strictParser = parser.configure({ strict: true });
|
|
1041
|
+
var parseFilter = (filterQuery) => {
|
|
1042
|
+
const parseTree = strictParser.parse(filterQuery);
|
|
1043
|
+
const filter = walkTree(parseTree, filterQuery);
|
|
1044
|
+
return filter;
|
|
1045
|
+
};
|
|
1046
|
+
|
|
1047
|
+
// src/filter-input/highlighting.ts
|
|
1048
|
+
import {
|
|
1049
|
+
HighlightStyle,
|
|
1050
|
+
syntaxHighlighting,
|
|
1051
|
+
tags
|
|
1052
|
+
} from "@vuu-ui/vuu-codemirror";
|
|
1053
|
+
var myHighlightStyle = HighlightStyle.define([
|
|
1054
|
+
{ tag: tags.variableName, color: "var(--vuuFilterEditor-variableColor)" },
|
|
1055
|
+
{ tag: tags.comment, color: "green", fontStyle: "italic" }
|
|
1056
|
+
]);
|
|
1057
|
+
var vuuHighlighting = syntaxHighlighting(myHighlightStyle);
|
|
1058
|
+
|
|
1059
|
+
// src/filter-input/theme.ts
|
|
1060
|
+
import { EditorView } from "@vuu-ui/vuu-codemirror";
|
|
1061
|
+
var vuuTheme = EditorView.theme(
|
|
1062
|
+
{
|
|
1063
|
+
"&": {
|
|
1064
|
+
color: "var(--vuuFilterEditor-color)",
|
|
1065
|
+
backgroundColor: "var(--vuuFilterEditor-background)",
|
|
1066
|
+
fontSize: "var(--vuuFilterEditor-fontSize)"
|
|
1067
|
+
},
|
|
1068
|
+
".cm-content": {
|
|
1069
|
+
caretColor: "var(--vuuFilterEditor-cursorColor)",
|
|
1070
|
+
padding: 0
|
|
1071
|
+
},
|
|
1072
|
+
".cm-line": {
|
|
1073
|
+
lineHeight: "var(--vuuFilterEditor-lineHeight)"
|
|
1074
|
+
},
|
|
1075
|
+
"&.cm-focused .cm-cursor": {
|
|
1076
|
+
borderLeftColor: "var(--vuuFilterEditor-cursorColor)"
|
|
1077
|
+
},
|
|
1078
|
+
"&.cm-focused .cm-selectionBackground, ::selection": {
|
|
1079
|
+
backgroundColor: "var(--vuuFilterEditor-selectionBackground)"
|
|
1080
|
+
},
|
|
1081
|
+
".cm-selectionBackground, ::selection": {
|
|
1082
|
+
backgroundColor: "var(--vuuFilterEditor-selectionBackground)"
|
|
1083
|
+
},
|
|
1084
|
+
".cm-scroller": {
|
|
1085
|
+
fontFamily: "var(--vuuFilterEditor-fontFamily)"
|
|
1086
|
+
},
|
|
1087
|
+
".cm-tooltip": {
|
|
1088
|
+
background: "var(--vuuFilterEditor-tooltipBackground)",
|
|
1089
|
+
border: "var(--vuuFilterEditor-tooltipBorder)",
|
|
1090
|
+
boxShadow: "var(--vuuFilterEditor-tooltipElevation)",
|
|
1091
|
+
"&.cm-tooltip-autocomplete > ul": {
|
|
1092
|
+
fontFamily: "var(--vuuFilterEditor-fontFamily)",
|
|
1093
|
+
fontSize: "var(--vuuFilterEditor-fontSize)",
|
|
1094
|
+
maxHeight: "240px"
|
|
1095
|
+
},
|
|
1096
|
+
"&.cm-tooltip-autocomplete > ul > li": {
|
|
1097
|
+
alignItems: "center",
|
|
1098
|
+
display: "flex",
|
|
1099
|
+
height: "var(--vuuFilterEditor-suggestion-height)",
|
|
1100
|
+
padding: "0 3px",
|
|
1101
|
+
lineHeight: "var(--vuuFilterEditor-suggestion-height)"
|
|
1102
|
+
},
|
|
1103
|
+
"&.cm-tooltip-autocomplete li[aria-selected]": {
|
|
1104
|
+
background: "var(--vuuFilterEditor-suggestion-selectedBackground)",
|
|
1105
|
+
color: "var(--vuuFilterEditor-suggestion-selectedColor)"
|
|
762
1106
|
}
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
1107
|
+
},
|
|
1108
|
+
".cm-completionIcon": {
|
|
1109
|
+
height: "18px",
|
|
1110
|
+
flex: "0 0 16px"
|
|
1111
|
+
},
|
|
1112
|
+
".cm-completionLabel": {
|
|
1113
|
+
flex: "1 1 auto"
|
|
1114
|
+
},
|
|
1115
|
+
".cm-completionIcon-filter": {
|
|
1116
|
+
position: "relative",
|
|
1117
|
+
"&:after": {
|
|
1118
|
+
background: "var(--salt-text-secondary-foreground)",
|
|
1119
|
+
content: "''",
|
|
1120
|
+
"-webkit-mask": "var(--svg-filter) center center/13px 13px",
|
|
1121
|
+
"-webkit-mask-repeat": "no-repeat",
|
|
1122
|
+
position: "absolute",
|
|
1123
|
+
height: "18px",
|
|
1124
|
+
left: "0px",
|
|
1125
|
+
top: "0px",
|
|
1126
|
+
width: "16px"
|
|
771
1127
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
}
|
|
1128
|
+
}
|
|
1129
|
+
},
|
|
1130
|
+
{ dark: false }
|
|
1131
|
+
);
|
|
775
1132
|
|
|
776
|
-
// src/filter-input/
|
|
1133
|
+
// src/filter-input/useFilterAutoComplete.ts
|
|
777
1134
|
import {
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
numericOperators,
|
|
782
|
-
stringOperators,
|
|
783
|
-
toSuggestions
|
|
1135
|
+
getNodeByName,
|
|
1136
|
+
getValue,
|
|
1137
|
+
syntaxTree
|
|
784
1138
|
} from "@vuu-ui/vuu-codemirror";
|
|
785
|
-
import {
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
rootElement.appendChild(headingElement);
|
|
797
|
-
rootElement.appendChild(child2);
|
|
798
|
-
return rootElement;
|
|
1139
|
+
import { useCallback as useCallback3 } from "react";
|
|
1140
|
+
var getOperator = (node, state) => {
|
|
1141
|
+
let maybeColumnNode = node.prevSibling || node.parent;
|
|
1142
|
+
while (maybeColumnNode && !["Column", "Operator", "In"].includes(maybeColumnNode.name)) {
|
|
1143
|
+
maybeColumnNode = maybeColumnNode.prevSibling || maybeColumnNode.parent;
|
|
1144
|
+
}
|
|
1145
|
+
if ((maybeColumnNode == null ? void 0 : maybeColumnNode.name) === "In" || (maybeColumnNode == null ? void 0 : maybeColumnNode.name) === "Operator") {
|
|
1146
|
+
return getValue(maybeColumnNode, state);
|
|
1147
|
+
} else {
|
|
1148
|
+
return void 0;
|
|
1149
|
+
}
|
|
799
1150
|
};
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
1151
|
+
var getPartialOperator = (maybeOperatorNode, state, columnName) => {
|
|
1152
|
+
const value = getValue(maybeOperatorNode, state);
|
|
1153
|
+
if (columnName === void 0 || value === columnName) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
if (["contains", "ends", "starts"].some(
|
|
1157
|
+
(val) => val.startsWith(value.toLowerCase())
|
|
1158
|
+
)) {
|
|
1159
|
+
return value;
|
|
1160
|
+
} else {
|
|
1161
|
+
return void 0;
|
|
809
1162
|
}
|
|
810
|
-
];
|
|
811
|
-
var makeSaveOrExtendSuggestions = (onSubmit, existingFilter, withJoinSuggestions = true) => {
|
|
812
|
-
const result = existingFilter ? [
|
|
813
|
-
{
|
|
814
|
-
label: "REPLACE existing filter",
|
|
815
|
-
apply: () => onSubmit("replace"),
|
|
816
|
-
boost: 8
|
|
817
|
-
},
|
|
818
|
-
{
|
|
819
|
-
label: "AND existing filter",
|
|
820
|
-
apply: () => onSubmit("and"),
|
|
821
|
-
boost: 7
|
|
822
|
-
},
|
|
823
|
-
{
|
|
824
|
-
label: "OR existing filter",
|
|
825
|
-
apply: () => onSubmit("or"),
|
|
826
|
-
boost: 7
|
|
827
|
-
}
|
|
828
|
-
] : [
|
|
829
|
-
{
|
|
830
|
-
label: "Press ENTER to submit",
|
|
831
|
-
apply: () => onSubmit(),
|
|
832
|
-
boost: 6
|
|
833
|
-
}
|
|
834
|
-
];
|
|
835
|
-
return withJoinSuggestions ? result.concat(booleanJoinSuggestions).concat(asNameSuggestion) : result;
|
|
836
1163
|
};
|
|
837
|
-
var
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
saveOptions
|
|
844
|
-
}) => {
|
|
845
|
-
const includeTabSuggestion = filterName && saveOptions.allowSaveAsTab;
|
|
846
|
-
const result = existingFilter ? promptToSaveOrExtend(onSubmit, existingFilter) : promptToSave(onSubmit);
|
|
847
|
-
if (includeTabSuggestion) {
|
|
848
|
-
return result.concat(saveAsTab(onSubmit));
|
|
1164
|
+
var getClauseOperator = (node, state) => {
|
|
1165
|
+
let maybeTargetNode = node.prevSibling || node.parent || node.lastChild;
|
|
1166
|
+
while (maybeTargetNode && maybeTargetNode.name === "\u26A0")
|
|
1167
|
+
maybeTargetNode = maybeTargetNode.prevSibling;
|
|
1168
|
+
if (maybeTargetNode && ["As", "Or", "And"].includes(maybeTargetNode.name)) {
|
|
1169
|
+
return getValue(maybeTargetNode, state);
|
|
849
1170
|
} else {
|
|
850
|
-
return
|
|
1171
|
+
return void 0;
|
|
851
1172
|
}
|
|
852
1173
|
};
|
|
853
|
-
var
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
apply: "] ",
|
|
865
|
-
type: "keyword",
|
|
866
|
-
boost: 10
|
|
1174
|
+
var getFilterName = (node, state) => {
|
|
1175
|
+
if (node.name === "FilterName") {
|
|
1176
|
+
return getValue(node, state);
|
|
1177
|
+
} else {
|
|
1178
|
+
let maybeTargetNode = node.prevSibling || node.parent || node.lastChild;
|
|
1179
|
+
while (maybeTargetNode && maybeTargetNode.name !== "FilterName")
|
|
1180
|
+
maybeTargetNode = maybeTargetNode.prevSibling;
|
|
1181
|
+
if (maybeTargetNode && maybeTargetNode.name === "FilterName") {
|
|
1182
|
+
return getValue(node, state);
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
867
1185
|
};
|
|
868
|
-
var
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
1186
|
+
var getColumnName = (node, state) => {
|
|
1187
|
+
const prevNode = node.prevSibling;
|
|
1188
|
+
if ((prevNode == null ? void 0 : prevNode.name) === "Column") {
|
|
1189
|
+
return getValue(prevNode, state);
|
|
1190
|
+
} else if ((prevNode == null ? void 0 : prevNode.name) === "Operator") {
|
|
1191
|
+
return getColumnName(prevNode, state);
|
|
1192
|
+
}
|
|
874
1193
|
};
|
|
875
|
-
var
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1194
|
+
var getSetValues = (node, state) => {
|
|
1195
|
+
let maybeTargetNode = node.lastChild;
|
|
1196
|
+
const values = [];
|
|
1197
|
+
while (maybeTargetNode && maybeTargetNode.name !== "In") {
|
|
1198
|
+
const value = getValue(maybeTargetNode, state);
|
|
1199
|
+
if (value) {
|
|
1200
|
+
values.push(value);
|
|
1201
|
+
} else {
|
|
1202
|
+
break;
|
|
1203
|
+
}
|
|
1204
|
+
maybeTargetNode = maybeTargetNode.prevSibling;
|
|
1205
|
+
}
|
|
1206
|
+
return values;
|
|
1207
|
+
};
|
|
1208
|
+
var useAutoComplete = (suggestionProvider, onSubmit, existingFilter) => {
|
|
1209
|
+
const makeSuggestions = useCallback3(
|
|
1210
|
+
async (context, suggestionType, optionalArgs = {}) => {
|
|
1211
|
+
const { startsWith = "" } = optionalArgs;
|
|
1212
|
+
const options = await suggestionProvider.getSuggestions(
|
|
1213
|
+
suggestionType,
|
|
1214
|
+
optionalArgs
|
|
1215
|
+
);
|
|
1216
|
+
return { from: context.pos - startsWith.length, options };
|
|
1217
|
+
},
|
|
1218
|
+
[suggestionProvider]
|
|
1219
|
+
);
|
|
1220
|
+
return useCallback3(
|
|
1221
|
+
async (context) => {
|
|
1222
|
+
var _a, _b;
|
|
1223
|
+
const { state, pos } = context;
|
|
1224
|
+
const word = (_a = context.matchBefore(/\w*/)) != null ? _a : {
|
|
1225
|
+
from: 0,
|
|
1226
|
+
to: 0,
|
|
1227
|
+
text: void 0
|
|
1228
|
+
};
|
|
1229
|
+
const tree = syntaxTree(state);
|
|
1230
|
+
const nodeBefore = tree.resolveInner(pos, -1);
|
|
1231
|
+
console.log({ nodeBeforeName: nodeBefore.name });
|
|
1232
|
+
switch (nodeBefore.name) {
|
|
1233
|
+
case "Filter":
|
|
1234
|
+
if (context.pos === 0) {
|
|
1235
|
+
return makeSuggestions(context, "column");
|
|
1236
|
+
} else {
|
|
1237
|
+
const clauseOperator = getClauseOperator(nodeBefore, state);
|
|
1238
|
+
if (clauseOperator === "as") {
|
|
1239
|
+
return makeSuggestions(context, "name");
|
|
1240
|
+
} else {
|
|
1241
|
+
const filterName = getFilterName(nodeBefore, state);
|
|
1242
|
+
return makeSuggestions(context, "save", {
|
|
1243
|
+
onSubmit: onSubmit.current,
|
|
1244
|
+
existingFilter,
|
|
1245
|
+
filterName
|
|
1246
|
+
});
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
case "String":
|
|
897
1250
|
{
|
|
898
|
-
const
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1251
|
+
const operator = getOperator(nodeBefore, state);
|
|
1252
|
+
const columnName = getColumnName(nodeBefore, state);
|
|
1253
|
+
const { from, to } = nodeBefore;
|
|
1254
|
+
if (to - from === 2 && context.pos === from + 1) {
|
|
1255
|
+
if (columnName && operator) {
|
|
1256
|
+
return makeSuggestions(context, "columnValue", {
|
|
1257
|
+
columnName,
|
|
1258
|
+
operator,
|
|
1259
|
+
quoted: true,
|
|
1260
|
+
startsWith: word.text
|
|
1261
|
+
});
|
|
908
1262
|
}
|
|
909
1263
|
} else {
|
|
910
|
-
console.
|
|
1264
|
+
console.log(
|
|
1265
|
+
`we have a string, column is ${columnName} ${from} ${to}`
|
|
1266
|
+
);
|
|
911
1267
|
}
|
|
912
1268
|
}
|
|
913
1269
|
break;
|
|
914
|
-
case "
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
return (
|
|
918
|
-
|
|
1270
|
+
case "As":
|
|
1271
|
+
return makeSuggestions(context, "name");
|
|
1272
|
+
case "FilterName":
|
|
1273
|
+
return makeSuggestions(context, "save", {
|
|
1274
|
+
onSubmit: onSubmit.current,
|
|
1275
|
+
existingFilter,
|
|
1276
|
+
filterName: getFilterName(nodeBefore, state)
|
|
1277
|
+
});
|
|
1278
|
+
case "Column": {
|
|
1279
|
+
const columnName = getValue(nodeBefore, state);
|
|
1280
|
+
const isPartialMatch = await suggestionProvider.isPartialMatch(
|
|
1281
|
+
"column",
|
|
1282
|
+
void 0,
|
|
1283
|
+
columnName
|
|
919
1284
|
);
|
|
1285
|
+
if (isPartialMatch) {
|
|
1286
|
+
return makeSuggestions(context, "column", {
|
|
1287
|
+
startsWith: columnName
|
|
1288
|
+
});
|
|
1289
|
+
} else {
|
|
1290
|
+
return makeSuggestions(context, "operator", { columnName });
|
|
1291
|
+
}
|
|
920
1292
|
}
|
|
921
|
-
case "
|
|
1293
|
+
case "\u26A0": {
|
|
1294
|
+
const columnName = getNodeByName(nodeBefore, state);
|
|
1295
|
+
const operator = getOperator(nodeBefore, state);
|
|
1296
|
+
const partialOperator = operator ? void 0 : getPartialOperator(nodeBefore, state, columnName);
|
|
1297
|
+
if (partialOperator) {
|
|
1298
|
+
return makeSuggestions(context, "operator", {
|
|
1299
|
+
columnName,
|
|
1300
|
+
startsWith: partialOperator
|
|
1301
|
+
});
|
|
1302
|
+
} else {
|
|
1303
|
+
return makeSuggestions(context, "columnValue", {
|
|
1304
|
+
columnName,
|
|
1305
|
+
operator,
|
|
1306
|
+
startsWith: word.text
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
case "Identifier":
|
|
922
1311
|
{
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
);
|
|
936
|
-
const suggestions = await getTypeaheadSuggestions(params);
|
|
937
|
-
const isIllustration = operator === "starts";
|
|
938
|
-
latestSuggestionsRef.current = toSuggestions(suggestions, {
|
|
939
|
-
moveCursorToEnd: autoQuoted,
|
|
940
|
-
quoted: (column == null ? void 0 : column.serverDataType) === "string" && !autoQuoted,
|
|
941
|
-
suffix: autoQuoted ? "" : " ",
|
|
942
|
-
prefix: isIllustration ? startsWith : prefix,
|
|
943
|
-
isIllustration
|
|
944
|
-
});
|
|
945
|
-
if (Array.isArray(selection) && (selection == null ? void 0 : selection.length) > 1) {
|
|
946
|
-
return [doneCommand, ...latestSuggestionsRef.current];
|
|
947
|
-
}
|
|
948
|
-
return latestSuggestionsRef.current;
|
|
1312
|
+
const clauseOperator = getClauseOperator(nodeBefore, state);
|
|
1313
|
+
if (clauseOperator === "as") {
|
|
1314
|
+
return {
|
|
1315
|
+
from: context.pos,
|
|
1316
|
+
options: [
|
|
1317
|
+
{
|
|
1318
|
+
label: "press ENTER to apply filter and save",
|
|
1319
|
+
apply: () => onSubmit.current(),
|
|
1320
|
+
boost: 5
|
|
1321
|
+
}
|
|
1322
|
+
]
|
|
1323
|
+
};
|
|
949
1324
|
}
|
|
950
1325
|
}
|
|
951
1326
|
break;
|
|
952
|
-
case "
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
existingFilter,
|
|
960
|
-
filterName,
|
|
961
|
-
onSubmit,
|
|
962
|
-
saveOptions
|
|
1327
|
+
case "ColumnSetExpression":
|
|
1328
|
+
case "Values": {
|
|
1329
|
+
const columnName = getNodeByName(nodeBefore, state);
|
|
1330
|
+
const selection = getSetValues(nodeBefore, state);
|
|
1331
|
+
return makeSuggestions(context, "columnValue", {
|
|
1332
|
+
columnName,
|
|
1333
|
+
selection
|
|
963
1334
|
});
|
|
964
1335
|
}
|
|
965
|
-
case "
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
return false;
|
|
984
|
-
} else if (option.label.startsWith(pattern)) {
|
|
985
|
-
return true;
|
|
1336
|
+
case "Comma":
|
|
1337
|
+
case "LBrack": {
|
|
1338
|
+
const columnName = getNodeByName(nodeBefore, state);
|
|
1339
|
+
return makeSuggestions(context, "columnValue", { columnName });
|
|
1340
|
+
}
|
|
1341
|
+
case "ColumnValueExpression":
|
|
1342
|
+
{
|
|
1343
|
+
const lastToken = (_b = nodeBefore.lastChild) == null ? void 0 : _b.prevSibling;
|
|
1344
|
+
if ((lastToken == null ? void 0 : lastToken.name) === "Column") {
|
|
1345
|
+
return makeSuggestions(context, "operator", {
|
|
1346
|
+
columnName: getNodeByName(nodeBefore, state)
|
|
1347
|
+
});
|
|
1348
|
+
} else if ((lastToken == null ? void 0 : lastToken.name) === "Operator") {
|
|
1349
|
+
return makeSuggestions(context, "columnValue", {
|
|
1350
|
+
columnName: getNodeByName(lastToken, state),
|
|
1351
|
+
operator: getValue(lastToken, state)
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
986
1354
|
}
|
|
1355
|
+
break;
|
|
1356
|
+
case "In": {
|
|
1357
|
+
return {
|
|
1358
|
+
from: context.pos,
|
|
1359
|
+
options: [{ label: "[", apply: " [", type: "text" }]
|
|
1360
|
+
};
|
|
987
1361
|
}
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
import { Toolbar } from "@heswell/salt-lab";
|
|
1002
|
-
|
|
1003
|
-
// src/filter-toolbar/useFilterToolbar.tsx
|
|
1004
|
-
import { ToggleButton, ToolbarField } from "@heswell/salt-lab";
|
|
1005
|
-
|
|
1006
|
-
// src/filter-toolbar/FilterDropdown.tsx
|
|
1007
|
-
import { Dropdown } from "@heswell/salt-lab";
|
|
1008
|
-
import { useCallback as useCallback3, useState } from "react";
|
|
1009
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1010
|
-
var isString = (s) => typeof s === "string";
|
|
1011
|
-
var stripQuotes = (selected) => {
|
|
1012
|
-
if (isString(selected)) {
|
|
1013
|
-
if (selected.startsWith('"') && selected.endsWith('"')) {
|
|
1014
|
-
return selected.slice(1, -1);
|
|
1015
|
-
} else {
|
|
1016
|
-
return selected;
|
|
1017
|
-
}
|
|
1018
|
-
} else {
|
|
1019
|
-
return selected.map(stripQuotes);
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
var FilterDropdown = ({
|
|
1023
|
-
column,
|
|
1024
|
-
selected: selectedProp,
|
|
1025
|
-
suggestionProvider,
|
|
1026
|
-
...props
|
|
1027
|
-
}) => {
|
|
1028
|
-
const selected = selectedProp != null ? stripQuotes(selectedProp) : void 0;
|
|
1029
|
-
const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
|
|
1030
|
-
const [values, setValues] = useState(initialValues);
|
|
1031
|
-
console.log({ initialValues });
|
|
1032
|
-
const handleOpenChange = useCallback3(
|
|
1033
|
-
async (isOpen) => {
|
|
1034
|
-
if (isOpen) {
|
|
1035
|
-
const values2 = await suggestionProvider.getSuggestions("columnValue", {
|
|
1036
|
-
columnName: column
|
|
1037
|
-
});
|
|
1038
|
-
console.log({ values: values2 });
|
|
1039
|
-
setValues(values2.map((suggestion) => suggestion.label));
|
|
1040
|
-
}
|
|
1041
|
-
},
|
|
1042
|
-
[column, suggestionProvider]
|
|
1043
|
-
);
|
|
1044
|
-
return /* @__PURE__ */ jsx2(
|
|
1045
|
-
Dropdown,
|
|
1046
|
-
{
|
|
1047
|
-
...props,
|
|
1048
|
-
onOpenChange: handleOpenChange,
|
|
1049
|
-
selected,
|
|
1050
|
-
source: values
|
|
1051
|
-
}
|
|
1362
|
+
case "Eq": {
|
|
1363
|
+
return makeSuggestions(context, "columnValue", {
|
|
1364
|
+
columnName: getNodeByName(nodeBefore, state)
|
|
1365
|
+
});
|
|
1366
|
+
}
|
|
1367
|
+
case "AndExpression":
|
|
1368
|
+
case "OrExpression": {
|
|
1369
|
+
return makeSuggestions(context, "column");
|
|
1370
|
+
}
|
|
1371
|
+
default:
|
|
1372
|
+
}
|
|
1373
|
+
},
|
|
1374
|
+
[existingFilter, makeSuggestions, onSubmit, suggestionProvider]
|
|
1052
1375
|
);
|
|
1053
1376
|
};
|
|
1054
1377
|
|
|
1055
|
-
// src/filter-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1378
|
+
// src/filter-input/useCodeMirrorEditor.ts
|
|
1379
|
+
var getView = (ref) => {
|
|
1380
|
+
if (ref.current == void 0) {
|
|
1381
|
+
throw Error("EditorView not defined");
|
|
1382
|
+
}
|
|
1383
|
+
return ref.current;
|
|
1384
|
+
};
|
|
1385
|
+
var getOptionClass = (completion) => {
|
|
1386
|
+
return (0, import_classnames.default)("vuuSuggestion", {
|
|
1387
|
+
vuuIllustration: completion.isIllustration
|
|
1388
|
+
});
|
|
1389
|
+
};
|
|
1390
|
+
var stripName = (filterQuery) => {
|
|
1391
|
+
const pos = filterQuery.lastIndexOf(" as ");
|
|
1392
|
+
if (pos !== -1) {
|
|
1393
|
+
return filterQuery.slice(0, pos);
|
|
1069
1394
|
} else {
|
|
1070
|
-
return
|
|
1395
|
+
return filterQuery;
|
|
1071
1396
|
}
|
|
1072
1397
|
};
|
|
1073
|
-
var
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1398
|
+
var noop = () => console.log("noooop");
|
|
1399
|
+
var useCodeMirrorEditor = ({
|
|
1400
|
+
existingFilter,
|
|
1401
|
+
onSubmitFilter,
|
|
1402
|
+
suggestionProvider
|
|
1078
1403
|
}) => {
|
|
1079
|
-
const
|
|
1080
|
-
const
|
|
1081
|
-
const
|
|
1082
|
-
const
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
columnName: column
|
|
1087
|
-
});
|
|
1088
|
-
console.log({ values: values2 });
|
|
1089
|
-
setValues(values2.map((suggestion) => suggestion.label));
|
|
1090
|
-
}
|
|
1091
|
-
},
|
|
1092
|
-
[column, suggestionProvider]
|
|
1404
|
+
const editorRef = useRef(null);
|
|
1405
|
+
const onSubmit = useRef(noop);
|
|
1406
|
+
const viewRef = useRef();
|
|
1407
|
+
const completionFn = useAutoComplete(
|
|
1408
|
+
suggestionProvider,
|
|
1409
|
+
onSubmit,
|
|
1410
|
+
existingFilter
|
|
1093
1411
|
);
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1412
|
+
const [createState, clearInput] = useMemo(() => {
|
|
1413
|
+
const parseFilter2 = () => {
|
|
1414
|
+
const view = getView(viewRef);
|
|
1415
|
+
const source = view.state.doc.toString();
|
|
1416
|
+
const tree = ensureSyntaxTree(view.state, view.state.doc.length, 5e3);
|
|
1417
|
+
if (tree) {
|
|
1418
|
+
const filter = walkTree(tree, source);
|
|
1419
|
+
return [filter, stripName(source), filter.name];
|
|
1420
|
+
} else {
|
|
1421
|
+
return [void 0, "", void 0];
|
|
1422
|
+
}
|
|
1423
|
+
};
|
|
1424
|
+
const clearInput2 = () => {
|
|
1425
|
+
getView(viewRef).setState(createState2());
|
|
1426
|
+
};
|
|
1427
|
+
const submitFilterAndClearInput = (mode) => {
|
|
1428
|
+
const [filter, filterQuery, filterName] = parseFilter2();
|
|
1429
|
+
onSubmitFilter == null ? void 0 : onSubmitFilter(filter, filterQuery, mode, filterName);
|
|
1430
|
+
clearInput2();
|
|
1431
|
+
};
|
|
1432
|
+
const submitFilter = (key) => {
|
|
1433
|
+
return keymap.of([
|
|
1434
|
+
{
|
|
1435
|
+
key,
|
|
1436
|
+
run() {
|
|
1437
|
+
submitFilterAndClearInput();
|
|
1438
|
+
return true;
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
]);
|
|
1442
|
+
};
|
|
1443
|
+
const showSuggestions = (key) => {
|
|
1444
|
+
return keymap.of([
|
|
1445
|
+
{
|
|
1446
|
+
key,
|
|
1447
|
+
run() {
|
|
1448
|
+
startCompletion(getView(viewRef));
|
|
1449
|
+
return true;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
]);
|
|
1453
|
+
};
|
|
1454
|
+
const createState2 = () => EditorState2.create({
|
|
1455
|
+
doc: "",
|
|
1456
|
+
extensions: [
|
|
1457
|
+
minimalSetup,
|
|
1458
|
+
autocompletion({
|
|
1459
|
+
override: [completionFn],
|
|
1460
|
+
optionClass: getOptionClass
|
|
1461
|
+
}),
|
|
1462
|
+
filterLanguageSupport(),
|
|
1463
|
+
keymap.of(defaultKeymap),
|
|
1464
|
+
submitFilter("Ctrl-Enter"),
|
|
1465
|
+
showSuggestions("ArrowDown"),
|
|
1466
|
+
EditorView2.updateListener.of((v) => {
|
|
1467
|
+
const view = getView(viewRef);
|
|
1468
|
+
if (v.docChanged) {
|
|
1469
|
+
startCompletion(view);
|
|
1470
|
+
}
|
|
1471
|
+
}),
|
|
1472
|
+
EditorState2.transactionFilter.of(
|
|
1473
|
+
(tr) => tr.newDoc.lines > 1 ? [] : tr
|
|
1474
|
+
),
|
|
1475
|
+
vuuTheme,
|
|
1476
|
+
vuuHighlighting
|
|
1477
|
+
]
|
|
1478
|
+
});
|
|
1479
|
+
onSubmit.current = (mode) => {
|
|
1480
|
+
submitFilterAndClearInput(mode);
|
|
1481
|
+
setTimeout(() => {
|
|
1482
|
+
getView(viewRef).focus();
|
|
1483
|
+
}, 100);
|
|
1484
|
+
};
|
|
1485
|
+
return [createState2, clearInput2];
|
|
1486
|
+
}, [completionFn, onSubmitFilter]);
|
|
1487
|
+
useEffect2(() => {
|
|
1488
|
+
if (!editorRef.current) {
|
|
1489
|
+
throw Error("editor not in dom");
|
|
1102
1490
|
}
|
|
1103
|
-
|
|
1491
|
+
viewRef.current = new EditorView2({
|
|
1492
|
+
state: createState(),
|
|
1493
|
+
parent: editorRef.current
|
|
1494
|
+
});
|
|
1495
|
+
return () => {
|
|
1496
|
+
var _a;
|
|
1497
|
+
(_a = viewRef.current) == null ? void 0 : _a.destroy();
|
|
1498
|
+
};
|
|
1499
|
+
}, [completionFn, createState]);
|
|
1500
|
+
return { editorRef, clearInput };
|
|
1104
1501
|
};
|
|
1105
1502
|
|
|
1106
|
-
// src/filter-
|
|
1107
|
-
import { jsx as
|
|
1108
|
-
var
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1503
|
+
// src/filter-input/FilterInput.tsx
|
|
1504
|
+
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1505
|
+
var classBase = "vuuFilterInput";
|
|
1506
|
+
var FilterInput = ({
|
|
1507
|
+
existingFilter,
|
|
1508
|
+
iconName = "filter",
|
|
1509
|
+
namedFilters,
|
|
1510
|
+
onSubmitFilter,
|
|
1511
|
+
suggestionProvider,
|
|
1512
|
+
...props
|
|
1513
|
+
}) => {
|
|
1514
|
+
const { editorRef, clearInput } = useCodeMirrorEditor({
|
|
1515
|
+
existingFilter,
|
|
1516
|
+
onSubmitFilter,
|
|
1517
|
+
suggestionProvider
|
|
1518
|
+
});
|
|
1519
|
+
return /* @__PURE__ */ jsxs4("div", { ...props, className: classBase, children: [
|
|
1520
|
+
/* @__PURE__ */ jsx7(
|
|
1521
|
+
Button,
|
|
1112
1522
|
{
|
|
1113
|
-
className:
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
children: filter.name
|
|
1523
|
+
className: `${classBase}-FilterButton`,
|
|
1524
|
+
"data-icon": iconName,
|
|
1525
|
+
tabIndex: -1
|
|
1117
1526
|
}
|
|
1118
|
-
)
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
return /* @__PURE__ */ jsx4(
|
|
1123
|
-
ToolbarField,
|
|
1124
|
-
{
|
|
1125
|
-
className: "vuuFilterDropdown",
|
|
1126
|
-
label: column,
|
|
1127
|
-
labelPlacement: "top",
|
|
1128
|
-
children: /* @__PURE__ */ jsx4(
|
|
1129
|
-
FilterDropdown,
|
|
1130
|
-
{
|
|
1131
|
-
column,
|
|
1132
|
-
selected: value.toString(),
|
|
1133
|
-
selectionStrategy: "default",
|
|
1134
|
-
source: [value.toString()],
|
|
1135
|
-
suggestionProvider,
|
|
1136
|
-
style: { width: 100 }
|
|
1137
|
-
}
|
|
1138
|
-
)
|
|
1139
|
-
},
|
|
1140
|
-
column
|
|
1141
|
-
);
|
|
1142
|
-
}
|
|
1143
|
-
if (isMultiValueFilter2(filter)) {
|
|
1144
|
-
const values = filter.values.map((v) => v.toString());
|
|
1145
|
-
return /* @__PURE__ */ jsx4(
|
|
1146
|
-
ToolbarField,
|
|
1527
|
+
),
|
|
1528
|
+
/* @__PURE__ */ jsx7("div", { className: `${classBase}-Editor`, ref: editorRef }),
|
|
1529
|
+
/* @__PURE__ */ jsx7(
|
|
1530
|
+
Button,
|
|
1147
1531
|
{
|
|
1148
|
-
className:
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
column: filter.column,
|
|
1155
|
-
selected: values,
|
|
1156
|
-
source: values,
|
|
1157
|
-
suggestionProvider,
|
|
1158
|
-
style: { width: 100 }
|
|
1159
|
-
}
|
|
1160
|
-
)
|
|
1161
|
-
},
|
|
1162
|
-
filter.column
|
|
1163
|
-
);
|
|
1164
|
-
}
|
|
1165
|
-
return filter.filters.map(
|
|
1166
|
-
(filter2) => filterToControl(filter2, suggestionProvider)
|
|
1167
|
-
);
|
|
1168
|
-
};
|
|
1169
|
-
var useFilterToolbar = ({
|
|
1170
|
-
filter,
|
|
1171
|
-
suggestionProvider
|
|
1172
|
-
}) => {
|
|
1173
|
-
if (filter) {
|
|
1174
|
-
return filterToControl(filter, suggestionProvider);
|
|
1175
|
-
}
|
|
1176
|
-
return [];
|
|
1532
|
+
className: `${classBase}-ClearButton`,
|
|
1533
|
+
"data-icon": "close-circle",
|
|
1534
|
+
onClick: clearInput
|
|
1535
|
+
}
|
|
1536
|
+
)
|
|
1537
|
+
] });
|
|
1177
1538
|
};
|
|
1178
1539
|
|
|
1179
|
-
// src/filter-
|
|
1180
|
-
import {
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1540
|
+
// src/filter-input/useFilterSuggestionProvider.ts
|
|
1541
|
+
import {
|
|
1542
|
+
asNameSuggestion,
|
|
1543
|
+
booleanJoinSuggestions,
|
|
1544
|
+
getNamePrompt,
|
|
1545
|
+
numericOperators,
|
|
1546
|
+
stringOperators,
|
|
1547
|
+
toSuggestions
|
|
1548
|
+
} from "@vuu-ui/vuu-codemirror";
|
|
1549
|
+
import {
|
|
1550
|
+
getTypeaheadParams,
|
|
1551
|
+
useTypeaheadSuggestions as useTypeaheadSuggestions2
|
|
1552
|
+
} from "@vuu-ui/vuu-data";
|
|
1553
|
+
import { useCallback as useCallback4, useRef as useRef2 } from "react";
|
|
1554
|
+
|
|
1555
|
+
// src/filter-input/filterInfo.ts
|
|
1556
|
+
import { createEl } from "@vuu-ui/vuu-utils";
|
|
1557
|
+
var filterInfo = (filterName, filterQuery) => {
|
|
1558
|
+
const rootElement = createEl("div", "vuuFunctionDoc");
|
|
1559
|
+
const headingElement = createEl("div", "function-heading");
|
|
1560
|
+
const nameElement = createEl("span", "function-name", filterName);
|
|
1561
|
+
headingElement.appendChild(nameElement);
|
|
1562
|
+
const child2 = createEl("p", void 0, filterQuery);
|
|
1563
|
+
rootElement.appendChild(headingElement);
|
|
1564
|
+
rootElement.appendChild(child2);
|
|
1565
|
+
return rootElement;
|
|
1190
1566
|
};
|
|
1191
1567
|
|
|
1192
|
-
// src/filter-
|
|
1193
|
-
var
|
|
1194
|
-
var
|
|
1195
|
-
var
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
try {
|
|
1201
|
-
const filter = parseFilter(filterQuery);
|
|
1202
|
-
predicate = filterPredicate(columnMap, filter);
|
|
1203
|
-
filterPredicateMap.set(filterQuery, predicate);
|
|
1204
|
-
return predicate;
|
|
1205
|
-
} catch (err) {
|
|
1206
|
-
console.warn(
|
|
1207
|
-
`filter-evaluation-utils, failed to parse filter "${filterQuery}"`
|
|
1208
|
-
);
|
|
1209
|
-
return filterReject;
|
|
1568
|
+
// src/filter-input/useFilterSuggestionProvider.ts
|
|
1569
|
+
var NO_NAMED_FILTERS = [];
|
|
1570
|
+
var NONE = {};
|
|
1571
|
+
var saveAsTab = (onSubmit) => [
|
|
1572
|
+
{
|
|
1573
|
+
label: "Press ENTER to create TAB",
|
|
1574
|
+
apply: () => onSubmit("tab"),
|
|
1575
|
+
boost: 6
|
|
1210
1576
|
}
|
|
1577
|
+
];
|
|
1578
|
+
var makeSaveOrExtendSuggestions = (onSubmit, existingFilter, withJoinSuggestions = true) => {
|
|
1579
|
+
const result = existingFilter ? [
|
|
1580
|
+
{
|
|
1581
|
+
label: "REPLACE existing filter",
|
|
1582
|
+
apply: () => onSubmit("replace"),
|
|
1583
|
+
boost: 8
|
|
1584
|
+
},
|
|
1585
|
+
{
|
|
1586
|
+
label: "AND existing filter",
|
|
1587
|
+
apply: () => onSubmit("and"),
|
|
1588
|
+
boost: 7
|
|
1589
|
+
},
|
|
1590
|
+
{
|
|
1591
|
+
label: "OR existing filter",
|
|
1592
|
+
apply: () => onSubmit("or"),
|
|
1593
|
+
boost: 7
|
|
1594
|
+
}
|
|
1595
|
+
] : [
|
|
1596
|
+
{
|
|
1597
|
+
label: "Press ENTER to submit",
|
|
1598
|
+
apply: () => onSubmit(),
|
|
1599
|
+
boost: 6
|
|
1600
|
+
}
|
|
1601
|
+
];
|
|
1602
|
+
return withJoinSuggestions ? result.concat(booleanJoinSuggestions).concat(asNameSuggestion) : result;
|
|
1211
1603
|
};
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
case "starts":
|
|
1227
|
-
return testSW(columnMap, filter);
|
|
1228
|
-
case "and":
|
|
1229
|
-
return testAND(columnMap, filter);
|
|
1230
|
-
case "or":
|
|
1231
|
-
return testOR(columnMap, filter);
|
|
1232
|
-
default:
|
|
1233
|
-
console.log(`unrecognized filter type ${filter.op}`);
|
|
1234
|
-
return () => true;
|
|
1604
|
+
var promptToSaveOrExtend = (onSubmit, existingFilter) => makeSaveOrExtendSuggestions(onSubmit, existingFilter, true);
|
|
1605
|
+
var promptToSave = (onSubmit) => makeSaveOrExtendSuggestions(onSubmit, void 0);
|
|
1606
|
+
var getSaveSuggestions = ({
|
|
1607
|
+
existingFilter,
|
|
1608
|
+
filterName,
|
|
1609
|
+
onSubmit,
|
|
1610
|
+
saveOptions
|
|
1611
|
+
}) => {
|
|
1612
|
+
const includeTabSuggestion = filterName && saveOptions.allowSaveAsTab;
|
|
1613
|
+
const result = existingFilter ? promptToSaveOrExtend(onSubmit, existingFilter) : promptToSave(onSubmit);
|
|
1614
|
+
if (includeTabSuggestion) {
|
|
1615
|
+
return result.concat(saveAsTab(onSubmit));
|
|
1616
|
+
} else {
|
|
1617
|
+
return result;
|
|
1235
1618
|
}
|
|
1236
|
-
}
|
|
1237
|
-
var testInclude = (columnMap, filter) => {
|
|
1238
|
-
return (row) => filter.values.indexOf(row[columnMap[filter.column]]) !== -1;
|
|
1239
|
-
};
|
|
1240
|
-
var testEQ = (columnMap, filter) => {
|
|
1241
|
-
return (row) => row[columnMap[filter.column]] === filter.value;
|
|
1242
|
-
};
|
|
1243
|
-
var testGT = (columnMap, filter) => {
|
|
1244
|
-
return (row) => row[columnMap[filter.column]] > filter.value;
|
|
1245
|
-
};
|
|
1246
|
-
var testGE = (columnMap, filter) => {
|
|
1247
|
-
return (row) => row[columnMap[filter.column]] >= filter.value;
|
|
1248
1619
|
};
|
|
1249
|
-
var
|
|
1250
|
-
|
|
1620
|
+
var suggestColumns = (columns) => columns.map((column) => ({
|
|
1621
|
+
boost: 5,
|
|
1622
|
+
label: column.name
|
|
1623
|
+
}));
|
|
1624
|
+
var suggestNamedFilters = (namedFilters) => namedFilters ? Array.from(namedFilters.entries()).map(([filterName, filterQuery]) => ({
|
|
1625
|
+
info: () => filterInfo(filterName, filterQuery),
|
|
1626
|
+
label: filterName,
|
|
1627
|
+
type: "filter"
|
|
1628
|
+
})) : NO_NAMED_FILTERS;
|
|
1629
|
+
var doneCommand = {
|
|
1630
|
+
label: "Done",
|
|
1631
|
+
apply: "] ",
|
|
1632
|
+
type: "keyword",
|
|
1633
|
+
boost: 10
|
|
1251
1634
|
};
|
|
1252
|
-
var
|
|
1253
|
-
|
|
1635
|
+
var withApplySpace = (suggestions, startsWith = "") => suggestions.filter((sugg) => startsWith === "" || sugg.label.startsWith(startsWith)).map((suggestion) => ({
|
|
1636
|
+
...suggestion,
|
|
1637
|
+
apply: suggestion.label + " "
|
|
1638
|
+
}));
|
|
1639
|
+
var defaultSaveOptions = {
|
|
1640
|
+
allowReplace: true
|
|
1254
1641
|
};
|
|
1255
|
-
var
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1642
|
+
var useFilterSuggestionProvider = ({
|
|
1643
|
+
columns,
|
|
1644
|
+
namedFilters,
|
|
1645
|
+
saveOptions = defaultSaveOptions,
|
|
1646
|
+
table,
|
|
1647
|
+
typeaheadHook: useTypeahead = useTypeaheadSuggestions2
|
|
1648
|
+
}) => {
|
|
1649
|
+
const latestSuggestionsRef = useRef2();
|
|
1650
|
+
const getTypeaheadSuggestions = useTypeahead();
|
|
1651
|
+
const getSuggestions = useCallback4(
|
|
1652
|
+
async (suggestionType, options = NONE) => {
|
|
1653
|
+
const {
|
|
1654
|
+
columnName,
|
|
1655
|
+
existingFilter,
|
|
1656
|
+
filterName,
|
|
1657
|
+
operator,
|
|
1658
|
+
quoted: autoQuoted,
|
|
1659
|
+
onSubmit,
|
|
1660
|
+
startsWith,
|
|
1661
|
+
selection
|
|
1662
|
+
} = options;
|
|
1663
|
+
switch (suggestionType) {
|
|
1664
|
+
case "operator":
|
|
1665
|
+
{
|
|
1666
|
+
const column = columns.find((col) => col.name === columnName);
|
|
1667
|
+
if (column) {
|
|
1668
|
+
switch (column.serverDataType) {
|
|
1669
|
+
case "string":
|
|
1670
|
+
case "char":
|
|
1671
|
+
return withApplySpace(stringOperators, startsWith);
|
|
1672
|
+
case "int":
|
|
1673
|
+
case "long":
|
|
1674
|
+
case "double":
|
|
1675
|
+
return withApplySpace(numericOperators);
|
|
1676
|
+
}
|
|
1677
|
+
} else {
|
|
1678
|
+
console.warn(`'${columnName}' does not match any column name`);
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
break;
|
|
1682
|
+
case "column": {
|
|
1683
|
+
const columnSuggestions = await suggestColumns(columns);
|
|
1684
|
+
const filterSuggestions = await suggestNamedFilters(namedFilters);
|
|
1685
|
+
return (latestSuggestionsRef.current = withApplySpace(columnSuggestions)).concat(
|
|
1686
|
+
withApplySpace(filterSuggestions)
|
|
1687
|
+
);
|
|
1688
|
+
}
|
|
1689
|
+
case "columnValue":
|
|
1690
|
+
{
|
|
1691
|
+
if (columnName) {
|
|
1692
|
+
const column = columns.find((col) => col.name === columnName);
|
|
1693
|
+
if (!column) {
|
|
1694
|
+
throw Error(
|
|
1695
|
+
`useFilterSUggestionProvider no column ${columnName}`
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1698
|
+
const prefix = Array.isArray(selection) ? selection.length === 0 ? "[" : "," : "";
|
|
1699
|
+
const params = getTypeaheadParams(
|
|
1700
|
+
table,
|
|
1701
|
+
columnName,
|
|
1702
|
+
startsWith
|
|
1703
|
+
);
|
|
1704
|
+
const suggestions = await getTypeaheadSuggestions(params);
|
|
1705
|
+
const isIllustration = operator === "starts";
|
|
1706
|
+
latestSuggestionsRef.current = toSuggestions(suggestions, {
|
|
1707
|
+
moveCursorToEnd: autoQuoted,
|
|
1708
|
+
quoted: (column == null ? void 0 : column.serverDataType) === "string" && !autoQuoted,
|
|
1709
|
+
suffix: autoQuoted ? "" : " ",
|
|
1710
|
+
prefix: isIllustration ? startsWith : prefix,
|
|
1711
|
+
isIllustration
|
|
1712
|
+
});
|
|
1713
|
+
if (Array.isArray(selection) && (selection == null ? void 0 : selection.length) > 1) {
|
|
1714
|
+
return [doneCommand, ...latestSuggestionsRef.current];
|
|
1715
|
+
}
|
|
1716
|
+
return latestSuggestionsRef.current;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
break;
|
|
1720
|
+
case "save": {
|
|
1721
|
+
if (typeof onSubmit !== "function") {
|
|
1722
|
+
throw Error(
|
|
1723
|
+
"useFilterSuggestionProvider, onSubmit must be supplied for 'save' suggestions"
|
|
1724
|
+
);
|
|
1725
|
+
}
|
|
1726
|
+
return await getSaveSuggestions({
|
|
1727
|
+
existingFilter,
|
|
1728
|
+
filterName,
|
|
1729
|
+
onSubmit,
|
|
1730
|
+
saveOptions
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
case "name":
|
|
1734
|
+
return await getNamePrompt("filter");
|
|
1735
|
+
default:
|
|
1736
|
+
}
|
|
1737
|
+
return [];
|
|
1738
|
+
},
|
|
1739
|
+
[columns, getTypeaheadSuggestions, namedFilters, saveOptions, table]
|
|
1740
|
+
);
|
|
1741
|
+
const isPartialMatch = useCallback4(
|
|
1742
|
+
async (valueType, columnName, pattern) => {
|
|
1743
|
+
const suggestions = (
|
|
1744
|
+
// latestSuggestions && latestSuggestions.length > 0
|
|
1745
|
+
// ? latestSuggestions
|
|
1746
|
+
await getSuggestions(valueType, { columnName })
|
|
1747
|
+
);
|
|
1748
|
+
if (pattern && suggestions) {
|
|
1749
|
+
for (const option of suggestions) {
|
|
1750
|
+
if (option.label === pattern) {
|
|
1751
|
+
return false;
|
|
1752
|
+
} else if (option.label.startsWith(pattern)) {
|
|
1753
|
+
return true;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
}
|
|
1757
|
+
return false;
|
|
1758
|
+
},
|
|
1759
|
+
[getSuggestions]
|
|
1760
|
+
);
|
|
1761
|
+
return {
|
|
1762
|
+
getSuggestions,
|
|
1763
|
+
isPartialMatch
|
|
1266
1764
|
};
|
|
1267
1765
|
};
|
|
1268
|
-
var testAND = (columnMap, filter) => {
|
|
1269
|
-
const filters = filter.filters.map((f1) => filterPredicate(columnMap, f1));
|
|
1270
|
-
return (row) => filters.every((fn) => fn(row));
|
|
1271
|
-
};
|
|
1272
|
-
function testOR(columnMap, filter) {
|
|
1273
|
-
const filters = filter.filters.map((f1) => filterPredicate(columnMap, f1));
|
|
1274
|
-
return (row) => filters.some((fn) => fn(row));
|
|
1275
|
-
}
|
|
1276
1766
|
|
|
1277
|
-
// src/filter-
|
|
1278
|
-
|
|
1767
|
+
// src/filter-toolbar/FilterToolbar.tsx
|
|
1768
|
+
var import_classnames2 = __toESM(require_classnames(), 1);
|
|
1769
|
+
import { Toolbar as Toolbar2 } from "@heswell/salt-lab";
|
|
1279
1770
|
|
|
1280
|
-
// src/
|
|
1281
|
-
|
|
1282
|
-
"=",
|
|
1283
|
-
"!=",
|
|
1284
|
-
">",
|
|
1285
|
-
">=",
|
|
1286
|
-
"<",
|
|
1287
|
-
"<=",
|
|
1288
|
-
"starts",
|
|
1289
|
-
"ends"
|
|
1290
|
-
]);
|
|
1291
|
-
var isNamedFilter = (f) => f !== void 0 && f.name !== void 0;
|
|
1292
|
-
var isSingleValueFilter2 = (f) => f !== void 0 && singleValueFilterOps.has(f.op);
|
|
1293
|
-
var isFilterClause = (f) => f !== void 0 && (isSingleValueFilter2(f) || isMultiValueFilter2(f));
|
|
1294
|
-
var isMultiValueFilter2 = (f) => f !== void 0 && f.op === "in";
|
|
1295
|
-
var isInFilter = (f) => f.op === "in";
|
|
1296
|
-
var isAndFilter = (f) => f.op === "and";
|
|
1297
|
-
var isOrFilter = (f) => f.op === "or";
|
|
1298
|
-
function isMultiClauseFilter2(f) {
|
|
1299
|
-
return f !== void 0 && (f.op === "and" || f.op === "or");
|
|
1300
|
-
}
|
|
1771
|
+
// src/filter-toolbar/useFilterToolbar.tsx
|
|
1772
|
+
import { ToggleButton, ToolbarField as ToolbarField3 } from "@heswell/salt-lab";
|
|
1301
1773
|
|
|
1302
|
-
// src/filter-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
var
|
|
1307
|
-
var
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
var filterClauses = (filter, clauses = []) => {
|
|
1312
|
-
if (filter) {
|
|
1313
|
-
if (isMultiClauseFilter2(filter)) {
|
|
1314
|
-
filter.filters.forEach((f) => clauses.push(...filterClauses(f)));
|
|
1774
|
+
// src/filter-toolbar/FilterDropdown.tsx
|
|
1775
|
+
import { Dropdown as Dropdown2 } from "@heswell/salt-lab";
|
|
1776
|
+
import { useCallback as useCallback5, useState as useState3 } from "react";
|
|
1777
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1778
|
+
var isString = (s) => typeof s === "string";
|
|
1779
|
+
var stripQuotes = (selected) => {
|
|
1780
|
+
if (isString(selected)) {
|
|
1781
|
+
if (selected.startsWith('"') && selected.endsWith('"')) {
|
|
1782
|
+
return selected.slice(1, -1);
|
|
1315
1783
|
} else {
|
|
1316
|
-
|
|
1784
|
+
return selected;
|
|
1317
1785
|
}
|
|
1786
|
+
} else {
|
|
1787
|
+
return selected.map(stripQuotes);
|
|
1318
1788
|
}
|
|
1319
|
-
return clauses;
|
|
1320
1789
|
};
|
|
1321
|
-
var
|
|
1322
|
-
|
|
1790
|
+
var FilterDropdown = ({
|
|
1791
|
+
column,
|
|
1792
|
+
selected: selectedProp,
|
|
1793
|
+
suggestionProvider,
|
|
1794
|
+
...props
|
|
1795
|
+
}) => {
|
|
1796
|
+
const selected = selectedProp != null ? stripQuotes(selectedProp) : void 0;
|
|
1797
|
+
const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
|
|
1798
|
+
const [values, setValues] = useState3(initialValues);
|
|
1799
|
+
console.log({ initialValues });
|
|
1800
|
+
const handleOpenChange = useCallback5(
|
|
1801
|
+
async (isOpen) => {
|
|
1802
|
+
if (isOpen) {
|
|
1803
|
+
const values2 = await suggestionProvider.getSuggestions("columnValue", {
|
|
1804
|
+
columnName: column
|
|
1805
|
+
});
|
|
1806
|
+
console.log({ values: values2 });
|
|
1807
|
+
setValues(values2.map((suggestion) => suggestion.label));
|
|
1808
|
+
}
|
|
1809
|
+
},
|
|
1810
|
+
[column, suggestionProvider]
|
|
1811
|
+
);
|
|
1812
|
+
return /* @__PURE__ */ jsx8(
|
|
1813
|
+
Dropdown2,
|
|
1814
|
+
{
|
|
1815
|
+
...props,
|
|
1816
|
+
onOpenChange: handleOpenChange,
|
|
1817
|
+
selected,
|
|
1818
|
+
source: values
|
|
1819
|
+
}
|
|
1820
|
+
);
|
|
1323
1821
|
};
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1822
|
+
|
|
1823
|
+
// src/filter-toolbar/FilterDropdownMultiSelect.tsx
|
|
1824
|
+
import { Dropdown as Dropdown3 } from "@heswell/salt-lab";
|
|
1825
|
+
import { useCallback as useCallback6, useState as useState4 } from "react";
|
|
1826
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1827
|
+
var isString2 = (s) => typeof s === "string";
|
|
1828
|
+
var stripQuotes2 = (selected) => {
|
|
1829
|
+
if (selected === void 0) {
|
|
1830
|
+
return void 0;
|
|
1831
|
+
} else if (isString2(selected)) {
|
|
1832
|
+
if (selected.startsWith('"') && selected.endsWith('"')) {
|
|
1833
|
+
return selected.slice(1, -1);
|
|
1328
1834
|
} else {
|
|
1329
|
-
|
|
1330
|
-
name: filter.column
|
|
1331
|
-
});
|
|
1332
|
-
}
|
|
1333
|
-
} else if (includesAllValues(filter)) {
|
|
1334
|
-
if (isMultiClauseFilter2(filter)) {
|
|
1835
|
+
return selected;
|
|
1335
1836
|
}
|
|
1336
|
-
return removeFilterForColumn(existingFilter, { name: (_a = filter.column) != null ? _a : "" });
|
|
1337
|
-
}
|
|
1338
|
-
if (!existingFilter) {
|
|
1339
|
-
return filter;
|
|
1340
|
-
}
|
|
1341
|
-
if (!filter) {
|
|
1342
|
-
return existingFilter;
|
|
1343
|
-
}
|
|
1344
|
-
if (existingFilter.op === AND && filter.op === AND) {
|
|
1345
|
-
return {
|
|
1346
|
-
op: AND,
|
|
1347
|
-
filters: combine(existingFilter.filters, filter.filters)
|
|
1348
|
-
};
|
|
1349
|
-
}
|
|
1350
|
-
if (existingFilter.op === AND) {
|
|
1351
|
-
const filters = replaceOrInsert(existingFilter.filters, filter);
|
|
1352
|
-
return filters.length > 1 ? { op: AND, filters } : filters[0];
|
|
1353
|
-
}
|
|
1354
|
-
if (filter.op === AND) {
|
|
1355
|
-
return { op: AND, filters: filter.filters.concat(existingFilter) };
|
|
1356
|
-
}
|
|
1357
|
-
if (filterEquals(existingFilter, filter, true)) {
|
|
1358
|
-
return filter;
|
|
1359
|
-
}
|
|
1360
|
-
if (canMerge(existingFilter, filter)) {
|
|
1361
|
-
return merge(existingFilter, filter);
|
|
1362
|
-
}
|
|
1363
|
-
return { op: combineWith, filters: [existingFilter, filter] };
|
|
1364
|
-
};
|
|
1365
|
-
var includesNoValues = (filter) => {
|
|
1366
|
-
if (!filter) {
|
|
1367
|
-
return false;
|
|
1368
|
-
}
|
|
1369
|
-
if (isInFilter(filter) && filter.values.length === 0) {
|
|
1370
|
-
return true;
|
|
1371
|
-
}
|
|
1372
|
-
return isAndFilter(filter) && filter.filters.some((f) => includesNoValues(f));
|
|
1373
|
-
};
|
|
1374
|
-
var filterValue = (value) => typeof value === "string" ? `"${value}"` : value;
|
|
1375
|
-
var filterAsQuery = (f) => {
|
|
1376
|
-
if (isMultiClauseFilter2(f)) {
|
|
1377
|
-
return f.filters.map((filter) => filterAsQuery(filter)).join(` ${f.op} `);
|
|
1378
|
-
} else if (isMultiValueFilter2(f)) {
|
|
1379
|
-
return `${f.column} ${f.op} [${f.values.join(",")}]`;
|
|
1380
1837
|
} else {
|
|
1381
|
-
return
|
|
1382
|
-
}
|
|
1383
|
-
};
|
|
1384
|
-
var includesAllValues = (filter) => {
|
|
1385
|
-
if (!filter) {
|
|
1386
|
-
return false;
|
|
1387
|
-
}
|
|
1388
|
-
if (filter.op === STARTS_WITH && filter.value === "") {
|
|
1389
|
-
return true;
|
|
1390
|
-
}
|
|
1391
|
-
return filter.op === STARTS_WITH && filter.value === "";
|
|
1392
|
-
};
|
|
1393
|
-
var replaceOrInsert = (filters, filter) => {
|
|
1394
|
-
return filters.concat(filter);
|
|
1395
|
-
};
|
|
1396
|
-
var merge = (f1, f2) => {
|
|
1397
|
-
if (includesNoValues(f2)) {
|
|
1398
|
-
return f2;
|
|
1399
|
-
}
|
|
1400
|
-
if (isInFilter(f1) && isInFilter(f2)) {
|
|
1401
|
-
return {
|
|
1402
|
-
...f1,
|
|
1403
|
-
values: [
|
|
1404
|
-
...f1.values,
|
|
1405
|
-
...f2.values.filter(
|
|
1406
|
-
(v) => !f1.values.includes(v)
|
|
1407
|
-
)
|
|
1408
|
-
]
|
|
1409
|
-
};
|
|
1410
|
-
} else if (isInFilter(f1) && f2.op === EQUALS) {
|
|
1411
|
-
return {
|
|
1412
|
-
...f1,
|
|
1413
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1414
|
-
// @ts-ignore
|
|
1415
|
-
values: f1.values.concat([f2.value])
|
|
1416
|
-
};
|
|
1417
|
-
} else if (f1.op === EQUALS && f2.op === EQUALS) {
|
|
1418
|
-
return {
|
|
1419
|
-
column: f1.column,
|
|
1420
|
-
op: IN,
|
|
1421
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
1422
|
-
// @ts-ignore
|
|
1423
|
-
values: [f1.value, f2.value]
|
|
1424
|
-
};
|
|
1838
|
+
return selected.map(stripQuotes2);
|
|
1425
1839
|
}
|
|
1426
|
-
return f2;
|
|
1427
|
-
};
|
|
1428
|
-
var combine = (existingFilters, replacementFilters) => {
|
|
1429
|
-
const equivalentType = ({ op: t1 }, { op: t2 }) => {
|
|
1430
|
-
return t1 === t2 || t1[0] === t2[0];
|
|
1431
|
-
};
|
|
1432
|
-
const replaces = (existingFilter, replacementFilter) => {
|
|
1433
|
-
return existingFilter.column === replacementFilter.column && equivalentType(existingFilter, replacementFilter);
|
|
1434
|
-
};
|
|
1435
|
-
const stillApplicable = (existingFilter) => replacementFilters.some(
|
|
1436
|
-
(replacementFilter) => replaces(existingFilter, replacementFilter)
|
|
1437
|
-
) === false;
|
|
1438
|
-
return existingFilters.filter(stillApplicable).concat(replacementFilters);
|
|
1439
1840
|
};
|
|
1440
|
-
var
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1841
|
+
var FilterDropdownMultiSelect = ({
|
|
1842
|
+
column,
|
|
1843
|
+
selected: selectedProp,
|
|
1844
|
+
suggestionProvider,
|
|
1845
|
+
...props
|
|
1846
|
+
}) => {
|
|
1847
|
+
const selected = stripQuotes2(selectedProp);
|
|
1848
|
+
const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
|
|
1849
|
+
const [values, setValues] = useState4(initialValues);
|
|
1850
|
+
const handleOpenChange = useCallback6(
|
|
1851
|
+
async (isOpen) => {
|
|
1852
|
+
if (isOpen) {
|
|
1853
|
+
const values2 = await suggestionProvider.getSuggestions("columnValue", {
|
|
1854
|
+
columnName: column
|
|
1855
|
+
});
|
|
1856
|
+
console.log({ values: values2 });
|
|
1857
|
+
setValues(values2.map((suggestion) => suggestion.label));
|
|
1858
|
+
}
|
|
1859
|
+
},
|
|
1860
|
+
[column, suggestionProvider]
|
|
1861
|
+
);
|
|
1862
|
+
return /* @__PURE__ */ jsx9(
|
|
1863
|
+
Dropdown3,
|
|
1864
|
+
{
|
|
1865
|
+
...props,
|
|
1866
|
+
onOpenChange: handleOpenChange,
|
|
1867
|
+
selected,
|
|
1868
|
+
selectionStrategy: "multiple",
|
|
1869
|
+
source: values
|
|
1448
1870
|
}
|
|
1449
|
-
}
|
|
1450
|
-
return [void 0, ""];
|
|
1451
|
-
};
|
|
1452
|
-
var removeFilter = (sourceFilter, filterToRemove) => {
|
|
1453
|
-
if (filterEquals(sourceFilter, filterToRemove, true)) {
|
|
1454
|
-
return null;
|
|
1455
|
-
}
|
|
1456
|
-
if (sourceFilter.op !== AND) {
|
|
1457
|
-
throw Error(
|
|
1458
|
-
`removeFilter cannot remove ${JSON.stringify(
|
|
1459
|
-
filterToRemove
|
|
1460
|
-
)} from ${JSON.stringify(sourceFilter)}`
|
|
1461
|
-
);
|
|
1462
|
-
}
|
|
1463
|
-
const filters = sourceFilter.filters.filter(
|
|
1464
|
-
(f) => !filterEquals(f, filterToRemove)
|
|
1465
1871
|
);
|
|
1466
|
-
return filters.length > 0 ? { type: AND, filters } : null;
|
|
1467
1872
|
};
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1873
|
+
|
|
1874
|
+
// src/filter-toolbar/useFilterToolbar.tsx
|
|
1875
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
1876
|
+
var filterToControl = (filter, suggestionProvider) => {
|
|
1877
|
+
if (isNamedFilter(filter)) {
|
|
1878
|
+
return /* @__PURE__ */ jsx10(
|
|
1879
|
+
ToggleButton,
|
|
1880
|
+
{
|
|
1881
|
+
className: "vuuToggleButton",
|
|
1882
|
+
toggled: true,
|
|
1883
|
+
variant: "secondary",
|
|
1884
|
+
children: filter.name
|
|
1885
|
+
}
|
|
1886
|
+
);
|
|
1471
1887
|
}
|
|
1472
|
-
if (filter
|
|
1473
|
-
|
|
1888
|
+
if (isSingleValueFilter(filter)) {
|
|
1889
|
+
const { column, value } = filter;
|
|
1890
|
+
return /* @__PURE__ */ jsx10(
|
|
1891
|
+
ToolbarField3,
|
|
1892
|
+
{
|
|
1893
|
+
className: "vuuFilterDropdown",
|
|
1894
|
+
label: column,
|
|
1895
|
+
labelPlacement: "top",
|
|
1896
|
+
children: /* @__PURE__ */ jsx10(
|
|
1897
|
+
FilterDropdown,
|
|
1898
|
+
{
|
|
1899
|
+
column,
|
|
1900
|
+
selected: value.toString(),
|
|
1901
|
+
selectionStrategy: "default",
|
|
1902
|
+
source: [value.toString()],
|
|
1903
|
+
suggestionProvider,
|
|
1904
|
+
style: { width: 100 }
|
|
1905
|
+
}
|
|
1906
|
+
)
|
|
1907
|
+
},
|
|
1908
|
+
column
|
|
1909
|
+
);
|
|
1474
1910
|
}
|
|
1475
|
-
if (filter
|
|
1476
|
-
|
|
1911
|
+
if (isMultiValueFilter(filter)) {
|
|
1912
|
+
const values = filter.values.map((v) => v.toString());
|
|
1913
|
+
return /* @__PURE__ */ jsx10(
|
|
1914
|
+
ToolbarField3,
|
|
1915
|
+
{
|
|
1916
|
+
className: "vuuFilterDropdown",
|
|
1917
|
+
label: filter.column,
|
|
1918
|
+
labelPlacement: "top",
|
|
1919
|
+
children: /* @__PURE__ */ jsx10(
|
|
1920
|
+
FilterDropdownMultiSelect,
|
|
1921
|
+
{
|
|
1922
|
+
column: filter.column,
|
|
1923
|
+
selected: values,
|
|
1924
|
+
source: values,
|
|
1925
|
+
suggestionProvider,
|
|
1926
|
+
style: { width: 100 }
|
|
1927
|
+
}
|
|
1928
|
+
)
|
|
1929
|
+
},
|
|
1930
|
+
filter.column
|
|
1931
|
+
);
|
|
1477
1932
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
(f) => f.column === columnName
|
|
1933
|
+
return filter.filters.map(
|
|
1934
|
+
(filter2) => filterToControl(filter2, suggestionProvider)
|
|
1481
1935
|
);
|
|
1482
|
-
return filters.length === 1 ? [columnFilter, filters[0]] : [columnFilter, { op: AND, filters }];
|
|
1483
1936
|
};
|
|
1484
|
-
var
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1937
|
+
var useFilterToolbar = ({
|
|
1938
|
+
filter,
|
|
1939
|
+
suggestionProvider
|
|
1940
|
+
}) => {
|
|
1941
|
+
if (filter) {
|
|
1942
|
+
return filterToControl(filter, suggestionProvider);
|
|
1490
1943
|
}
|
|
1491
|
-
return
|
|
1944
|
+
return [];
|
|
1492
1945
|
};
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
}
|
|
1946
|
+
|
|
1947
|
+
// src/filter-toolbar/FilterToolbar.tsx
|
|
1948
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1949
|
+
var FilterToolbar = ({
|
|
1950
|
+
className,
|
|
1951
|
+
filter,
|
|
1952
|
+
suggestionProvider,
|
|
1953
|
+
...props
|
|
1954
|
+
}) => {
|
|
1955
|
+
console.log(`FilterToolbar ${JSON.stringify(filter, null, 2)}`);
|
|
1956
|
+
const toolbarItems = useFilterToolbar({ filter, suggestionProvider });
|
|
1957
|
+
return /* @__PURE__ */ jsx11(Toolbar2, { className: (0, import_classnames2.default)("vuuFilterToolbar", className), ...props, children: toolbarItems });
|
|
1505
1958
|
};
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1959
|
+
|
|
1960
|
+
// src/filter-evaluation-utils.ts
|
|
1961
|
+
var filterPredicateMap = /* @__PURE__ */ new Map();
|
|
1962
|
+
var filterReject = () => false;
|
|
1963
|
+
var getFilterPredicate = (columnMap, filterQuery) => {
|
|
1964
|
+
let predicate = filterPredicateMap.get(filterQuery);
|
|
1965
|
+
if (predicate) {
|
|
1966
|
+
return predicate;
|
|
1513
1967
|
}
|
|
1514
|
-
|
|
1515
|
-
const
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
return { op, filters: otherColFilters };
|
|
1525
|
-
}
|
|
1968
|
+
try {
|
|
1969
|
+
const filter = parseFilter(filterQuery);
|
|
1970
|
+
predicate = filterPredicate(columnMap, filter);
|
|
1971
|
+
filterPredicateMap.set(filterQuery, predicate);
|
|
1972
|
+
return predicate;
|
|
1973
|
+
} catch (err) {
|
|
1974
|
+
console.warn(
|
|
1975
|
+
`filter-evaluation-utils, failed to parse filter "${filterQuery}"`
|
|
1976
|
+
);
|
|
1977
|
+
return filterReject;
|
|
1526
1978
|
}
|
|
1527
|
-
return sourceFilter;
|
|
1528
1979
|
};
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1980
|
+
function filterPredicate(columnMap, filter) {
|
|
1981
|
+
switch (filter.op) {
|
|
1982
|
+
case "in":
|
|
1983
|
+
return testInclude(columnMap, filter);
|
|
1984
|
+
case "=":
|
|
1985
|
+
return testEQ(columnMap, filter);
|
|
1986
|
+
case ">":
|
|
1987
|
+
return testGT(columnMap, filter);
|
|
1988
|
+
case ">=":
|
|
1989
|
+
return testGE(columnMap, filter);
|
|
1990
|
+
case "<":
|
|
1991
|
+
return testLT(columnMap, filter);
|
|
1992
|
+
case "<=":
|
|
1993
|
+
return testLE(columnMap, filter);
|
|
1994
|
+
case "starts":
|
|
1995
|
+
return testSW(columnMap, filter);
|
|
1996
|
+
case "and":
|
|
1997
|
+
return testAND(columnMap, filter);
|
|
1998
|
+
case "or":
|
|
1999
|
+
return testOR(columnMap, filter);
|
|
2000
|
+
default:
|
|
2001
|
+
console.log(`unrecognized filter type ${filter.op}`);
|
|
2002
|
+
return () => true;
|
|
1538
2003
|
}
|
|
1539
|
-
|
|
2004
|
+
}
|
|
2005
|
+
var testInclude = (columnMap, filter) => {
|
|
2006
|
+
return (row) => filter.values.indexOf(row[columnMap[filter.column]]) !== -1;
|
|
1540
2007
|
};
|
|
1541
|
-
var
|
|
1542
|
-
|
|
1543
|
-
return true;
|
|
1544
|
-
}
|
|
1545
|
-
if (f1 && f2 && canMerge(f1, f2)) {
|
|
1546
|
-
return f1.op === f2.op && (isSingleValueFilter2(f1) && isSingleValueFilter2(f2) && f1.value === f2.value || isMultiValueFilter2(f1) && isMultiValueFilter2(f2) && sameValues(f1.values, f2.values));
|
|
1547
|
-
}
|
|
1548
|
-
return false;
|
|
2008
|
+
var testEQ = (columnMap, filter) => {
|
|
2009
|
+
return (row) => row[columnMap[filter.column]] === filter.value;
|
|
1549
2010
|
};
|
|
1550
|
-
var
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
return updateFilter(result, newFilter, "add");
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1569
|
-
return {
|
|
1570
|
-
op: "and",
|
|
1571
|
-
filters: [filter, newFilter]
|
|
1572
|
-
};
|
|
1573
|
-
}
|
|
1574
|
-
if (newFilter) {
|
|
1575
|
-
return newFilter;
|
|
2011
|
+
var testGT = (columnMap, filter) => {
|
|
2012
|
+
return (row) => row[columnMap[filter.column]] > filter.value;
|
|
2013
|
+
};
|
|
2014
|
+
var testGE = (columnMap, filter) => {
|
|
2015
|
+
return (row) => row[columnMap[filter.column]] >= filter.value;
|
|
2016
|
+
};
|
|
2017
|
+
var testLT = (columnMap, filter) => {
|
|
2018
|
+
return (row) => row[columnMap[filter.column]] < filter.value;
|
|
2019
|
+
};
|
|
2020
|
+
var testLE = (columnMap, filter) => {
|
|
2021
|
+
return (row) => row[columnMap[filter.column]] <= filter.value;
|
|
2022
|
+
};
|
|
2023
|
+
var testSW = (columnMap, filter) => {
|
|
2024
|
+
const filterValue2 = filter.value;
|
|
2025
|
+
if (typeof filterValue2 !== "string") {
|
|
2026
|
+
throw Error("string filter applied to value of wrong type");
|
|
1576
2027
|
}
|
|
1577
|
-
return
|
|
2028
|
+
return (row) => {
|
|
2029
|
+
const rowValue = row[columnMap[filter.column]];
|
|
2030
|
+
if (typeof rowValue !== "string") {
|
|
2031
|
+
throw Error("string filter applied to value of wrong type");
|
|
2032
|
+
}
|
|
2033
|
+
return rowValue.toLowerCase().startsWith(filterValue2.toLowerCase());
|
|
2034
|
+
};
|
|
2035
|
+
};
|
|
2036
|
+
var testAND = (columnMap, filter) => {
|
|
2037
|
+
const filters = filter.filters.map((f1) => filterPredicate(columnMap, f1));
|
|
2038
|
+
return (row) => filters.every((fn) => fn(row));
|
|
1578
2039
|
};
|
|
2040
|
+
function testOR(columnMap, filter) {
|
|
2041
|
+
const filters = filter.filters.map((f1) => filterPredicate(columnMap, f1));
|
|
2042
|
+
return (row) => filters.some((fn) => fn(row));
|
|
2043
|
+
}
|
|
1579
2044
|
export {
|
|
1580
2045
|
AND,
|
|
2046
|
+
ColumnFilter,
|
|
1581
2047
|
ENDS_WITH,
|
|
1582
2048
|
EQUALS,
|
|
1583
2049
|
FilterInput,
|
|
@@ -1597,11 +2063,11 @@ export {
|
|
|
1597
2063
|
isAndFilter,
|
|
1598
2064
|
isFilterClause,
|
|
1599
2065
|
isInFilter,
|
|
1600
|
-
|
|
1601
|
-
|
|
2066
|
+
isMultiClauseFilter,
|
|
2067
|
+
isMultiValueFilter,
|
|
1602
2068
|
isNamedFilter,
|
|
1603
2069
|
isOrFilter,
|
|
1604
|
-
|
|
2070
|
+
isSingleValueFilter,
|
|
1605
2071
|
overrideColName,
|
|
1606
2072
|
parseFilter,
|
|
1607
2073
|
removeColumnFromFilter,
|