@vuu-ui/vuu-filters 0.7.0-debug → 0.7.0

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/esm/index.js CHANGED
@@ -1,1616 +1,4 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __commonJS = (cb, mod) => function __require() {
8
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
- // If the importer is in node compatibility mode or this is not an ESM
20
- // file that has been converted to a CommonJS file using a Babel-
21
- // compatible transform (i.e. "__esModule" has not been set), then set
22
- // "default" to the CommonJS "module.exports" for node compatibility.
23
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
- mod
25
- ));
26
- var __accessCheck = (obj, member, msg) => {
27
- if (!member.has(obj))
28
- throw TypeError("Cannot " + msg);
29
- };
30
- var __privateGet = (obj, member, getter) => {
31
- __accessCheck(obj, member, "read from private field");
32
- return getter ? getter.call(obj) : member.get(obj);
33
- };
34
- var __privateAdd = (obj, member, value) => {
35
- if (member.has(obj))
36
- throw TypeError("Cannot add the same private member more than once");
37
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
38
- };
39
- var __privateSet = (obj, member, value, setter) => {
40
- __accessCheck(obj, member, "write to private field");
41
- setter ? setter.call(obj, value) : member.set(obj, value);
42
- return value;
43
- };
44
-
45
- // ../../node_modules/classnames/index.js
46
- var require_classnames = __commonJS({
47
- "../../node_modules/classnames/index.js"(exports, module) {
48
- (function() {
49
- "use strict";
50
- var hasOwn = {}.hasOwnProperty;
51
- var nativeCodeString = "[native code]";
52
- function classNames() {
53
- var classes = [];
54
- for (var i = 0; i < arguments.length; i++) {
55
- var arg = arguments[i];
56
- if (!arg)
57
- continue;
58
- var argType = typeof arg;
59
- if (argType === "string" || argType === "number") {
60
- classes.push(arg);
61
- } else if (Array.isArray(arg)) {
62
- if (arg.length) {
63
- var inner = classNames.apply(null, arg);
64
- if (inner) {
65
- classes.push(inner);
66
- }
67
- }
68
- } else if (argType === "object") {
69
- if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) {
70
- classes.push(arg.toString());
71
- continue;
72
- }
73
- for (var key in arg) {
74
- if (hasOwn.call(arg, key) && arg[key]) {
75
- classes.push(key);
76
- }
77
- }
78
- }
79
- }
80
- return classes.join(" ");
81
- }
82
- if (typeof module !== "undefined" && module.exports) {
83
- classNames.default = classNames;
84
- module.exports = classNames;
85
- } else if (typeof define === "function" && typeof define.amd === "object" && define.amd) {
86
- define("classnames", [], function() {
87
- return classNames;
88
- });
89
- } else {
90
- window.classNames = classNames;
91
- }
92
- })();
93
- }
94
- });
95
-
96
- // src/filter-input/FilterInput.tsx
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
114
- import {
115
- LanguageSupport,
116
- LRLanguage,
117
- styleTags,
118
- tags as tag
119
- } from "@vuu-ui/vuu-codemirror";
120
-
121
- // src/filter-input/filter-language-parser/generated/filter-parser.js
122
- import { LRParser } from "@vuu-ui/vuu-codemirror";
123
- var parser = LRParser.deserialize({
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
- });
137
-
138
- // src/filter-input/filter-language-parser/FilterLanguage.ts
139
- var filterLanguage = LRLanguage.define({
140
- name: "VuuFilterQuery",
141
- parser: parser.configure({
142
- props: [
143
- styleTags({
144
- Identifier: tag.variableName,
145
- String: tag.string,
146
- Or: tag.emphasis,
147
- Operator: tag.operator
148
- })
149
- ]
150
- })
151
- });
152
- var filterLanguageSupport = () => {
153
- return new LanguageSupport(filterLanguage);
154
- };
155
-
156
- // src/filter-input/filter-language-parser/FilterTreeWalker.ts
157
- import {
158
- isMultiClauseFilter,
159
- isMultiValueFilter,
160
- isSingleValueFilter
161
- } from "@vuu-ui/vuu-utils";
162
- var _filter;
163
- var FilterExpression = class {
164
- constructor() {
165
- __privateAdd(this, _filter, void 0);
166
- }
167
- setFilterCombinatorOp(op, filter = __privateGet(this, _filter)) {
168
- if (isMultiClauseFilter(filter) && filter.op === op) {
169
- return;
170
- } else {
171
- __privateSet(this, _filter, {
172
- op,
173
- filters: [__privateGet(this, _filter)]
174
- });
175
- }
176
- }
177
- add(filter) {
178
- if (__privateGet(this, _filter) === void 0) {
179
- __privateSet(this, _filter, filter);
180
- } else if (isMultiClauseFilter(__privateGet(this, _filter))) {
181
- __privateGet(this, _filter).filters.push(filter);
182
- } else {
183
- throw Error(`Invalid filter passed to FilterExpression`);
184
- }
185
- }
186
- setColumn(column, filter = __privateGet(this, _filter)) {
187
- if (isMultiClauseFilter(filter)) {
188
- const target = filter.filters.at(-1);
189
- if (target) {
190
- this.setColumn(column, target);
191
- }
192
- } else if (filter) {
193
- filter.column = column;
194
- }
195
- }
196
- setOp(value, filter = __privateGet(this, _filter)) {
197
- if (isMultiClauseFilter(filter)) {
198
- const target = filter.filters.at(-1);
199
- if (target) {
200
- this.setOp(value, target);
201
- }
202
- } else if (filter) {
203
- filter.op = value;
204
- }
205
- }
206
- setValue(value, filter = __privateGet(this, _filter)) {
207
- var _a;
208
- 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
- }
219
- }
220
- toJSON(filter = __privateGet(this, _filter)) {
221
- if (this.name) {
222
- return {
223
- ...filter,
224
- name: this.name
225
- };
226
- } else {
227
- return filter;
228
- }
229
- }
230
- };
231
- _filter = new WeakMap();
232
- var walkTree = (tree, source) => {
233
- const filterExpression = new FilterExpression();
234
- const cursor = tree.cursor();
235
- do {
236
- const { name, from, to } = cursor;
237
- switch (name) {
238
- case "ColumnValueExpression":
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();
273
- };
274
-
275
- // src/filter-input/filter-language-parser/FilterParser.ts
276
- var strictParser = parser.configure({ strict: true });
277
- var parseFilter = (filterQuery) => {
278
- const parseTree = strictParser.parse(filterQuery);
279
- const filter = walkTree(parseTree, filterQuery);
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);
383
- } else {
384
- return void 0;
385
- }
386
- };
387
- var getPartialOperator = (maybeOperatorNode, state, columnName) => {
388
- const value = getValue(maybeOperatorNode, state);
389
- if (columnName === void 0 || value === columnName) {
390
- return;
391
- }
392
- if (["contains", "ends", "starts"].some(
393
- (val) => val.startsWith(value.toLowerCase())
394
- )) {
395
- return value;
396
- } else {
397
- return void 0;
398
- }
399
- };
400
- var getClauseOperator = (node, state) => {
401
- let maybeTargetNode = node.prevSibling || node.parent || node.lastChild;
402
- while (maybeTargetNode && maybeTargetNode.name === "\u26A0")
403
- maybeTargetNode = maybeTargetNode.prevSibling;
404
- if (maybeTargetNode && ["As", "Or", "And"].includes(maybeTargetNode.name)) {
405
- return getValue(maybeTargetNode, state);
406
- } else {
407
- return void 0;
408
- }
409
- };
410
- var getFilterName = (node, state) => {
411
- if (node.name === "FilterName") {
412
- return getValue(node, state);
413
- } else {
414
- let maybeTargetNode = node.prevSibling || node.parent || node.lastChild;
415
- while (maybeTargetNode && maybeTargetNode.name !== "FilterName")
416
- maybeTargetNode = maybeTargetNode.prevSibling;
417
- if (maybeTargetNode && maybeTargetNode.name === "FilterName") {
418
- return getValue(node, state);
419
- }
420
- }
421
- };
422
- var getColumnName = (node, state) => {
423
- const prevNode = node.prevSibling;
424
- if ((prevNode == null ? void 0 : prevNode.name) === "Column") {
425
- return getValue(prevNode, state);
426
- } else if ((prevNode == null ? void 0 : prevNode.name) === "Operator") {
427
- return getColumnName(prevNode, state);
428
- }
429
- };
430
- var getSetValues = (node, state) => {
431
- let maybeTargetNode = node.lastChild;
432
- const values = [];
433
- while (maybeTargetNode && maybeTargetNode.name !== "In") {
434
- const value = getValue(maybeTargetNode, state);
435
- if (value) {
436
- values.push(value);
437
- } else {
438
- break;
439
- }
440
- maybeTargetNode = maybeTargetNode.prevSibling;
441
- }
442
- return values;
443
- };
444
- var useAutoComplete = (suggestionProvider, onSubmit, existingFilter) => {
445
- const makeSuggestions = useCallback(
446
- async (context, suggestionType, optionalArgs = {}) => {
447
- const { startsWith = "" } = optionalArgs;
448
- const options = await suggestionProvider.getSuggestions(
449
- suggestionType,
450
- optionalArgs
451
- );
452
- return { from: context.pos - startsWith.length, options };
453
- },
454
- [suggestionProvider]
455
- );
456
- return useCallback(
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]
611
- );
612
- };
613
-
614
- // src/filter-input/useCodeMirrorEditor.ts
615
- var getView = (ref) => {
616
- if (ref.current == void 0) {
617
- throw Error("EditorView not defined");
618
- }
619
- return ref.current;
620
- };
621
- var getOptionClass = (completion) => {
622
- return (0, import_classnames.default)("vuuSuggestion", {
623
- vuuIllustration: completion.isIllustration
624
- });
625
- };
626
- var stripName = (filterQuery) => {
627
- const pos = filterQuery.lastIndexOf(" as ");
628
- if (pos !== -1) {
629
- return filterQuery.slice(0, pos);
630
- } else {
631
- return filterQuery;
632
- }
633
- };
634
- var noop = () => console.log("noooop");
635
- var useCodeMirrorEditor = ({
636
- existingFilter,
637
- onSubmitFilter,
638
- suggestionProvider
639
- }) => {
640
- const editorRef = useRef(null);
641
- const onSubmit = useRef(noop);
642
- const viewRef = useRef();
643
- const completionFn = useAutoComplete(
644
- suggestionProvider,
645
- onSubmit,
646
- existingFilter
647
- );
648
- const [createState, clearInput] = useMemo(() => {
649
- const parseFilter2 = () => {
650
- const view = getView(viewRef);
651
- const source = view.state.doc.toString();
652
- const tree = ensureSyntaxTree(view.state, view.state.doc.length, 5e3);
653
- if (tree) {
654
- const filter = walkTree(tree, source);
655
- return [filter, stripName(source), filter.name];
656
- } else {
657
- return [void 0, "", void 0];
658
- }
659
- };
660
- const clearInput2 = () => {
661
- getView(viewRef).setState(createState2());
662
- };
663
- const submitFilterAndClearInput = (mode) => {
664
- const [filter, filterQuery, filterName] = parseFilter2();
665
- onSubmitFilter == null ? void 0 : onSubmitFilter(filter, filterQuery, mode, filterName);
666
- clearInput2();
667
- };
668
- const submitFilter = (key) => {
669
- return keymap.of([
670
- {
671
- key,
672
- run() {
673
- submitFilterAndClearInput();
674
- return true;
675
- }
676
- }
677
- ]);
678
- };
679
- const showSuggestions = (key) => {
680
- return keymap.of([
681
- {
682
- key,
683
- run() {
684
- startCompletion(getView(viewRef));
685
- return true;
686
- }
687
- }
688
- ]);
689
- };
690
- const createState2 = () => EditorState2.create({
691
- doc: "",
692
- extensions: [
693
- minimalSetup,
694
- autocompletion({
695
- override: [completionFn],
696
- optionClass: getOptionClass
697
- }),
698
- filterLanguageSupport(),
699
- keymap.of(defaultKeymap),
700
- submitFilter("Ctrl-Enter"),
701
- showSuggestions("ArrowDown"),
702
- EditorView2.updateListener.of((v) => {
703
- const view = getView(viewRef);
704
- if (v.docChanged) {
705
- startCompletion(view);
706
- }
707
- }),
708
- EditorState2.transactionFilter.of(
709
- (tr) => tr.newDoc.lines > 1 ? [] : tr
710
- ),
711
- vuuTheme,
712
- vuuHighlighting
713
- ]
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
- }
727
- viewRef.current = new EditorView2({
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 };
737
- };
738
-
739
- // src/filter-input/FilterInput.tsx
740
- import { jsx, jsxs } from "react/jsx-runtime";
741
- var classBase = "vuuFilterInput";
742
- var FilterInput = ({
743
- existingFilter,
744
- iconName = "filter",
745
- namedFilters,
746
- onSubmitFilter,
747
- suggestionProvider,
748
- ...props
749
- }) => {
750
- const { editorRef, clearInput } = useCodeMirrorEditor({
751
- existingFilter,
752
- onSubmitFilter,
753
- suggestionProvider
754
- });
755
- return /* @__PURE__ */ jsxs("div", { ...props, className: classBase, children: [
756
- /* @__PURE__ */ jsx(
757
- Button,
758
- {
759
- className: `${classBase}-FilterButton`,
760
- "data-icon": iconName,
761
- tabIndex: -1
762
- }
763
- ),
764
- /* @__PURE__ */ jsx("div", { className: `${classBase}-Editor`, ref: editorRef }),
765
- /* @__PURE__ */ jsx(
766
- Button,
767
- {
768
- className: `${classBase}-ClearButton`,
769
- "data-icon": "close-circle",
770
- onClick: clearInput
771
- }
772
- )
773
- ] });
774
- };
775
-
776
- // src/filter-input/useFilterSuggestionProvider.ts
777
- import {
778
- asNameSuggestion,
779
- booleanJoinSuggestions,
780
- getNamePrompt,
781
- numericOperators,
782
- stringOperators,
783
- toSuggestions
784
- } from "@vuu-ui/vuu-codemirror";
785
- import { getTypeaheadParams, useTypeaheadSuggestions } from "@vuu-ui/vuu-data";
786
- import { useCallback as useCallback2, useRef as useRef2 } from "react";
787
-
788
- // src/filter-input/filterInfo.ts
789
- import { createEl } from "@vuu-ui/vuu-utils";
790
- var filterInfo = (filterName, filterQuery) => {
791
- const rootElement = createEl("div", "vuuFunctionDoc");
792
- const headingElement = createEl("div", "function-heading");
793
- const nameElement = createEl("span", "function-name", filterName);
794
- headingElement.appendChild(nameElement);
795
- const child2 = createEl("p", void 0, filterQuery);
796
- rootElement.appendChild(headingElement);
797
- rootElement.appendChild(child2);
798
- return rootElement;
799
- };
800
-
801
- // src/filter-input/useFilterSuggestionProvider.ts
802
- var NO_NAMED_FILTERS = [];
803
- var NONE = {};
804
- var saveAsTab = (onSubmit) => [
805
- {
806
- label: "Press ENTER to create TAB",
807
- apply: () => onSubmit("tab"),
808
- boost: 6
809
- }
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
- };
837
- var promptToSaveOrExtend = (onSubmit, existingFilter) => makeSaveOrExtendSuggestions(onSubmit, existingFilter, true);
838
- var promptToSave = (onSubmit) => makeSaveOrExtendSuggestions(onSubmit, void 0);
839
- var getSaveSuggestions = ({
840
- existingFilter,
841
- filterName,
842
- onSubmit,
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));
849
- } else {
850
- return result;
851
- }
852
- };
853
- var suggestColumns = (columns) => columns.map((column) => ({
854
- boost: 5,
855
- label: column.name
856
- }));
857
- var suggestNamedFilters = (namedFilters) => namedFilters ? Array.from(namedFilters.entries()).map(([filterName, filterQuery]) => ({
858
- info: () => filterInfo(filterName, filterQuery),
859
- label: filterName,
860
- type: "filter"
861
- })) : NO_NAMED_FILTERS;
862
- var doneCommand = {
863
- label: "Done",
864
- apply: "] ",
865
- type: "keyword",
866
- boost: 10
867
- };
868
- var withApplySpace = (suggestions, startsWith = "") => suggestions.filter((sugg) => startsWith === "" || sugg.label.startsWith(startsWith)).map((suggestion) => ({
869
- ...suggestion,
870
- apply: suggestion.label + " "
871
- }));
872
- var defaultSaveOptions = {
873
- allowReplace: true
874
- };
875
- var useFilterSuggestionProvider = ({
876
- columns,
877
- namedFilters,
878
- saveOptions = defaultSaveOptions,
879
- table
880
- }) => {
881
- const latestSuggestionsRef = useRef2();
882
- const getTypeaheadSuggestions = useTypeaheadSuggestions();
883
- const getSuggestions = useCallback2(
884
- async (suggestionType, options = NONE) => {
885
- const {
886
- columnName,
887
- existingFilter,
888
- filterName,
889
- operator,
890
- quoted: autoQuoted,
891
- onSubmit,
892
- startsWith,
893
- selection
894
- } = options;
895
- switch (suggestionType) {
896
- case "operator":
897
- {
898
- const column = columns.find((col) => col.name === columnName);
899
- if (column) {
900
- switch (column.serverDataType) {
901
- case "string":
902
- case "char":
903
- return withApplySpace(stringOperators, startsWith);
904
- case "int":
905
- case "long":
906
- case "double":
907
- return withApplySpace(numericOperators);
908
- }
909
- } else {
910
- console.warn(`'${columnName}' does not match any column name`);
911
- }
912
- }
913
- break;
914
- case "column": {
915
- const columnSuggestions = await suggestColumns(columns);
916
- const filterSuggestions = await suggestNamedFilters(namedFilters);
917
- return (latestSuggestionsRef.current = withApplySpace(columnSuggestions)).concat(
918
- withApplySpace(filterSuggestions)
919
- );
920
- }
921
- case "columnValue":
922
- {
923
- if (columnName) {
924
- const column = columns.find((col) => col.name === columnName);
925
- if (!column) {
926
- throw Error(
927
- `useFilterSUggestionProvider no column ${columnName}`
928
- );
929
- }
930
- const prefix = Array.isArray(selection) ? selection.length === 0 ? "[" : "," : "";
931
- const params = getTypeaheadParams(
932
- table,
933
- columnName,
934
- startsWith
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;
949
- }
950
- }
951
- break;
952
- case "save": {
953
- if (typeof onSubmit !== "function") {
954
- throw Error(
955
- "useFilterSuggestionProvider, onSubmit must be supplied for 'save' suggestions"
956
- );
957
- }
958
- return await getSaveSuggestions({
959
- existingFilter,
960
- filterName,
961
- onSubmit,
962
- saveOptions
963
- });
964
- }
965
- case "name":
966
- return await getNamePrompt("filter");
967
- default:
968
- }
969
- return [];
970
- },
971
- [columns, getTypeaheadSuggestions, namedFilters, saveOptions, table]
972
- );
973
- const isPartialMatch = useCallback2(
974
- async (valueType, columnName, pattern) => {
975
- const suggestions = (
976
- // latestSuggestions && latestSuggestions.length > 0
977
- // ? latestSuggestions
978
- await getSuggestions(valueType, { columnName })
979
- );
980
- if (pattern && suggestions) {
981
- for (const option of suggestions) {
982
- if (option.label === pattern) {
983
- return false;
984
- } else if (option.label.startsWith(pattern)) {
985
- return true;
986
- }
987
- }
988
- }
989
- return false;
990
- },
991
- [getSuggestions]
992
- );
993
- return {
994
- getSuggestions,
995
- isPartialMatch
996
- };
997
- };
998
-
999
- // src/filter-toolbar/FilterToolbar.tsx
1000
- var import_classnames2 = __toESM(require_classnames(), 1);
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
- }
1052
- );
1053
- };
1054
-
1055
- // src/filter-toolbar/FilterDropdownMultiSelect.tsx
1056
- import { Dropdown as Dropdown2 } from "@heswell/salt-lab";
1057
- import { useCallback as useCallback4, useState as useState2 } from "react";
1058
- import { jsx as jsx3 } from "react/jsx-runtime";
1059
- var isString2 = (s) => typeof s === "string";
1060
- var stripQuotes2 = (selected) => {
1061
- if (selected === void 0) {
1062
- return void 0;
1063
- } else if (isString2(selected)) {
1064
- if (selected.startsWith('"') && selected.endsWith('"')) {
1065
- return selected.slice(1, -1);
1066
- } else {
1067
- return selected;
1068
- }
1069
- } else {
1070
- return selected.map(stripQuotes2);
1071
- }
1072
- };
1073
- var FilterDropdownMultiSelect = ({
1074
- column,
1075
- selected: selectedProp,
1076
- suggestionProvider,
1077
- ...props
1078
- }) => {
1079
- const selected = stripQuotes2(selectedProp);
1080
- const initialValues = Array.isArray(selected) ? selected : selected != null ? [selected] : [];
1081
- const [values, setValues] = useState2(initialValues);
1082
- const handleOpenChange = useCallback4(
1083
- async (isOpen) => {
1084
- if (isOpen) {
1085
- const values2 = await suggestionProvider.getSuggestions("columnValue", {
1086
- columnName: column
1087
- });
1088
- console.log({ values: values2 });
1089
- setValues(values2.map((suggestion) => suggestion.label));
1090
- }
1091
- },
1092
- [column, suggestionProvider]
1093
- );
1094
- return /* @__PURE__ */ jsx3(
1095
- Dropdown2,
1096
- {
1097
- ...props,
1098
- onOpenChange: handleOpenChange,
1099
- selected,
1100
- selectionStrategy: "multiple",
1101
- source: values
1102
- }
1103
- );
1104
- };
1105
-
1106
- // src/filter-toolbar/useFilterToolbar.tsx
1107
- import { jsx as jsx4 } from "react/jsx-runtime";
1108
- var filterToControl = (filter, suggestionProvider) => {
1109
- if (isNamedFilter(filter)) {
1110
- return /* @__PURE__ */ jsx4(
1111
- ToggleButton,
1112
- {
1113
- className: "vuuToggleButton",
1114
- toggled: true,
1115
- variant: "secondary",
1116
- children: filter.name
1117
- }
1118
- );
1119
- }
1120
- if (isSingleValueFilter2(filter)) {
1121
- const { column, value } = filter;
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,
1147
- {
1148
- className: "vuuFilterDropdown",
1149
- label: filter.column,
1150
- labelPlacement: "top",
1151
- children: /* @__PURE__ */ jsx4(
1152
- FilterDropdownMultiSelect,
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 [];
1177
- };
1178
-
1179
- // src/filter-toolbar/FilterToolbar.tsx
1180
- import { jsx as jsx5 } from "react/jsx-runtime";
1181
- var FilterToolbar = ({
1182
- className,
1183
- filter,
1184
- suggestionProvider,
1185
- ...props
1186
- }) => {
1187
- console.log(`FilterToolbar ${JSON.stringify(filter, null, 2)}`);
1188
- const toolbarItems = useFilterToolbar({ filter, suggestionProvider });
1189
- return /* @__PURE__ */ jsx5(Toolbar, { className: (0, import_classnames2.default)("vuuFilterToolbar", className), ...props, children: toolbarItems });
1190
- };
1191
-
1192
- // src/filter-evaluation-utils.ts
1193
- var filterPredicateMap = /* @__PURE__ */ new Map();
1194
- var filterReject = () => false;
1195
- var getFilterPredicate = (columnMap, filterQuery) => {
1196
- let predicate = filterPredicateMap.get(filterQuery);
1197
- if (predicate) {
1198
- return predicate;
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;
1210
- }
1211
- };
1212
- function filterPredicate(columnMap, filter) {
1213
- switch (filter.op) {
1214
- case "in":
1215
- return testInclude(columnMap, filter);
1216
- case "=":
1217
- return testEQ(columnMap, filter);
1218
- case ">":
1219
- return testGT(columnMap, filter);
1220
- case ">=":
1221
- return testGE(columnMap, filter);
1222
- case "<":
1223
- return testLT(columnMap, filter);
1224
- case "<=":
1225
- return testLE(columnMap, filter);
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;
1235
- }
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
- };
1249
- var testLT = (columnMap, filter) => {
1250
- return (row) => row[columnMap[filter.column]] < filter.value;
1251
- };
1252
- var testLE = (columnMap, filter) => {
1253
- return (row) => row[columnMap[filter.column]] <= filter.value;
1254
- };
1255
- var testSW = (columnMap, filter) => {
1256
- const filterValue2 = filter.value;
1257
- if (typeof filterValue2 !== "string") {
1258
- throw Error("string filter applied to value of wrong type");
1259
- }
1260
- return (row) => {
1261
- const rowValue = row[columnMap[filter.column]];
1262
- if (typeof rowValue !== "string") {
1263
- throw Error("string filter applied to value of wrong type");
1264
- }
1265
- return rowValue.toLowerCase().startsWith(filterValue2.toLowerCase());
1266
- };
1267
- };
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
-
1277
- // src/filter-utils.ts
1278
- import { extractFilterForColumn, partition } from "@vuu-ui/vuu-utils";
1279
-
1280
- // src/filterTypes.ts
1281
- var singleValueFilterOps = /* @__PURE__ */ new Set([
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
- }
1301
-
1302
- // src/filter-utils.ts
1303
- var AND = "and";
1304
- var EQUALS = "=";
1305
- var GREATER_THAN = ">";
1306
- var LESS_THAN = "<";
1307
- var OR = "or";
1308
- var STARTS_WITH = "starts";
1309
- var ENDS_WITH = "ends";
1310
- var IN = "in";
1311
- var filterClauses = (filter, clauses = []) => {
1312
- if (filter) {
1313
- if (isMultiClauseFilter2(filter)) {
1314
- filter.filters.forEach((f) => clauses.push(...filterClauses(f)));
1315
- } else {
1316
- clauses.push(filter);
1317
- }
1318
- }
1319
- return clauses;
1320
- };
1321
- var DEFAULT_ADD_FILTER_OPTS = {
1322
- combineWith: "and"
1323
- };
1324
- var addFilter = (existingFilter, filter, { combineWith = AND } = DEFAULT_ADD_FILTER_OPTS) => {
1325
- var _a;
1326
- if (includesNoValues(filter)) {
1327
- if (isMultiClauseFilter2(filter)) {
1328
- } else {
1329
- existingFilter = removeFilterForColumn(existingFilter, {
1330
- name: filter.column
1331
- });
1332
- }
1333
- } else if (includesAllValues(filter)) {
1334
- if (isMultiClauseFilter2(filter)) {
1335
- }
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
- } else {
1381
- return `${f.column} ${f.op} ${filterValue(f.value)}`;
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
- };
1425
- }
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
- };
1440
- var removeColumnFromFilter = (column, filter) => {
1441
- if (isMultiClauseFilter2(filter)) {
1442
- const [clause1, clause2] = filter.filters;
1443
- if (clause1.column === column.name) {
1444
- return [clause2, filterAsQuery(clause2)];
1445
- }
1446
- if (clause2.column === column.name) {
1447
- return [clause1, filterAsQuery(clause1)];
1448
- }
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
- );
1466
- return filters.length > 0 ? { type: AND, filters } : null;
1467
- };
1468
- var splitFilterOnColumn = (filter, columnName) => {
1469
- if (!filter) {
1470
- return [null, null];
1471
- }
1472
- if (filter.column === columnName) {
1473
- return [filter, null];
1474
- }
1475
- if (filter.op !== AND) {
1476
- return [null, filter];
1477
- }
1478
- const [[columnFilter = null], filters] = partition(
1479
- filter.filters,
1480
- (f) => f.column === columnName
1481
- );
1482
- return filters.length === 1 ? [columnFilter, filters[0]] : [columnFilter, { op: AND, filters }];
1483
- };
1484
- var overrideColName = (filter, column) => {
1485
- if (isMultiClauseFilter2(filter)) {
1486
- return {
1487
- op: filter.op,
1488
- filters: filter.filters.map((f) => overrideColName(f, column))
1489
- };
1490
- }
1491
- return { ...filter, column };
1492
- };
1493
- var filterIncludesColumn = (filter, column) => {
1494
- if (!filter) {
1495
- return false;
1496
- }
1497
- const { op, column: filterColName } = filter;
1498
- switch (op) {
1499
- case AND:
1500
- case OR:
1501
- return filter.filters != null && filter.filters.some((f) => filterIncludesColumn(f, column));
1502
- default:
1503
- return filterColName === column.name;
1504
- }
1505
- };
1506
- var removeFilterForColumn = (sourceFilter, column) => {
1507
- const colName = column.name;
1508
- if (!sourceFilter) {
1509
- return void 0;
1510
- }
1511
- if (sourceFilter.column === colName) {
1512
- return void 0;
1513
- }
1514
- if (isAndFilter(sourceFilter) || isOrFilter(sourceFilter)) {
1515
- const { op } = sourceFilter;
1516
- const filters = sourceFilter.filters;
1517
- const otherColFilters = filters.filter((f) => f.column !== colName);
1518
- switch (otherColFilters.length) {
1519
- case 0:
1520
- return void 0;
1521
- case 1:
1522
- return otherColFilters[0];
1523
- default:
1524
- return { op, filters: otherColFilters };
1525
- }
1526
- }
1527
- return sourceFilter;
1528
- };
1529
- var canMerge = (f1, f2) => f1.column === f2.column && (f1.op === "=" || f1.op === "in") && (f2.op === "=" || f2.op === "in");
1530
- var sameValues = (arr1, arr2) => {
1531
- if (arr1 === arr2) {
1532
- return true;
1533
- }
1534
- if (arr1.length === arr2.length) {
1535
- const a = arr1.slice().sort();
1536
- const b = arr2.slice().sort();
1537
- return a.join("|") === b.join("|");
1538
- }
1539
- return false;
1540
- };
1541
- var filterEquals = (f1, f2, strict = false) => {
1542
- if (!strict) {
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;
1549
- };
1550
- var updateFilter = (filter, newFilter, mode) => {
1551
- if (filter && newFilter) {
1552
- if (mode === "replace") {
1553
- return newFilter;
1554
- }
1555
- if (filter.op === "and") {
1556
- return {
1557
- ...filter,
1558
- filters: filter.filters.concat(newFilter)
1559
- };
1560
- }
1561
- const { column: columnName } = newFilter;
1562
- if (columnName) {
1563
- const existingClause = newFilter.column ? extractFilterForColumn(filter, columnName) : void 0;
1564
- if (existingClause && columnName) {
1565
- const result = removeFilterForColumn(filter, { name: columnName });
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;
1576
- }
1577
- return filter;
1578
- };
1579
- export {
1580
- AND,
1581
- ENDS_WITH,
1582
- EQUALS,
1583
- FilterInput,
1584
- FilterToolbar,
1585
- GREATER_THAN,
1586
- IN,
1587
- LESS_THAN,
1588
- OR,
1589
- STARTS_WITH,
1590
- addFilter,
1591
- filterAsQuery,
1592
- filterClauses,
1593
- filterEquals,
1594
- filterIncludesColumn,
1595
- filterPredicate,
1596
- getFilterPredicate,
1597
- isAndFilter,
1598
- isFilterClause,
1599
- isInFilter,
1600
- isMultiClauseFilter2 as isMultiClauseFilter,
1601
- isMultiValueFilter2 as isMultiValueFilter,
1602
- isNamedFilter,
1603
- isOrFilter,
1604
- isSingleValueFilter2 as isSingleValueFilter,
1605
- overrideColName,
1606
- parseFilter,
1607
- removeColumnFromFilter,
1608
- removeFilter,
1609
- splitFilterOnColumn,
1610
- updateFilter,
1611
- useCodeMirrorEditor,
1612
- useFilterSuggestionProvider
1613
- };
1
+ var $e=Object.create;var ee=Object.defineProperty;var Ue=Object.getOwnPropertyDescriptor;var Xe=Object.getOwnPropertyNames;var Le=Object.getPrototypeOf,He=Object.prototype.hasOwnProperty;var Be=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var _e=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Xe(t))!He.call(e,o)&&o!==r&&ee(e,o,{get:()=>t[o],enumerable:!(n=Ue(t,o))||n.enumerable});return e};var te=(e,t,r)=>(r=e!=null?$e(Le(e)):{},_e(t||!e||!e.__esModule?ee(r,"default",{value:e,enumerable:!0}):r,e));var re=(e,t,r)=>{if(!t.has(e))throw TypeError("Cannot "+r)};var P=(e,t,r)=>(re(e,t,"read from private field"),r?r.call(e):t.get(e)),ne=(e,t,r)=>{if(t.has(e))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(e):t.set(e,r)},U=(e,t,r,n)=>(re(e,t,"write to private field"),n?n.call(e,r):t.set(e,r),r);var X=Be((br,V)=>{(function(){"use strict";var e={}.hasOwnProperty,t="[native code]";function r(){for(var n=[],o=0;o<arguments.length;o++){var i=arguments[o];if(i){var s=typeof i;if(s==="string"||s==="number")n.push(i);else if(Array.isArray(i)){if(i.length){var c=r.apply(null,i);c&&n.push(c)}}else if(s==="object"){if(i.toString!==Object.prototype.toString&&!i.toString.toString().includes("[native code]")){n.push(i.toString());continue}for(var m in i)e.call(i,m)&&i[m]&&n.push(m)}}}return n.join(" ")}typeof V<"u"&&V.exports?(r.default=r,V.exports=r):typeof define=="function"&&typeof define.amd=="object"&&define.amd?define("classnames",[],function(){return r}):window.classNames=r})()});import{Button as ve}from"@salt-ds/core";var Fe=te(X(),1);import{autocompletion as lt,defaultKeymap as at,EditorState as ge,EditorView as fe,ensureSyntaxTree as ut,keymap as H,minimalSetup as pt,startCompletion as Oe}from"@vuu-ui/vuu-codemirror";import{useEffect as ct,useMemo as mt,useRef as B}from"react";import{LanguageSupport as Ye,LRLanguage as qe,styleTags as Ge,tags as k}from"@vuu-ui/vuu-codemirror";import{LRParser as je}from"@vuu-ui/vuu-codemirror";var A=je.deserialize({version:14,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",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",goto:"#YvPPw}!TPPPPPPPPPPwPP!WPP!ZP!ZP!aP!g!jPPP!p!s!aP#P!aXROU[]XQOU[]RYQRibXTOU[]XVOU[]Rf^QkhRnkRWOQSOQ_UQc[Rd]QaYQhbRmj",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",maxTerm:39,skippedNodes:[0],repeatNodeCount:1,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",tokenizers:[0,1],topRules:{Filter:[0,1]},tokenPrec:0});var ze=qe.define({name:"VuuFilterQuery",parser:A.configure({props:[Ge({Identifier:k.variableName,String:k.string,Or:k.emphasis,Operator:k.operator})]})}),oe=()=>new Ye(ze);import{isMultiClauseFilter as w,isMultiValueFilter as Ze,isSingleValueFilter as Je}from"@vuu-ui/vuu-utils";var O,L=class{constructor(){ne(this,O,void 0)}setFilterCombinatorOp(t,r=P(this,O)){w(r)&&r.op===t||U(this,O,{op:t,filters:[P(this,O)]})}add(t){if(P(this,O)===void 0)U(this,O,t);else if(w(P(this,O)))P(this,O).filters.push(t);else throw Error("Invalid filter passed to FilterExpression")}setColumn(t,r=P(this,O)){if(w(r)){let n=r.filters.at(-1);n&&this.setColumn(t,n)}else r&&(r.column=t)}setOp(t,r=P(this,O)){if(w(r)){let n=r.filters.at(-1);n&&this.setOp(t,n)}else r&&(r.op=t)}setValue(t,r=P(this,O)){var n;if(w(r)){let o=r.filters.at(-1);o&&this.setValue(t,o)}else Ze(r)?((n=r.values)!=null||(r.values=[]),r.values.push(t)):Je(r)&&(r.value=t)}toJSON(t=P(this,O)){return this.name?{...t,name:this.name}:t}};O=new WeakMap;var M=(e,t)=>{let r=new L,n=e.cursor();do{let{name:o,from:i,to:s}=n;switch(o){case"ColumnValueExpression":r.add({});break;case"ColumnSetExpression":r.add({op:"in"});break;case"Or":case"And":r.setFilterCombinatorOp(t.substring(i,s));break;case"Column":r.setColumn(t.substring(i,s));break;case"Operator":r.setOp(t.substring(i,s));break;case"String":r.setValue(t.substring(i+1,s-1));break;case"Number":r.setValue(parseFloat(t.substring(i,s)));break;case"True":r.setValue(!0);break;case"False":r.setValue(!1);break;case"FilterName":r.name=t.substring(i,s);break;default:}}while(n.next());return r.toJSON()};var Ke=A.configure({strict:!0}),I=e=>{let t=Ke.parse(e);return M(t,e)};import{HighlightStyle as et,syntaxHighlighting as tt,tags as ie}from"@vuu-ui/vuu-codemirror";var rt=et.define([{tag:ie.variableName,color:"var(--vuuFilterEditor-variableColor)"},{tag:ie.comment,color:"green",fontStyle:"italic"}]),se=tt(rt);import{EditorView as nt}from"@vuu-ui/vuu-codemirror";var le=nt.theme({"&":{color:"var(--vuuFilterEditor-color)",backgroundColor:"var(--vuuFilterEditor-background)",fontSize:"var(--vuuFilterEditor-fontSize)"},".cm-content":{caretColor:"var(--vuuFilterEditor-cursorColor)",padding:0},".cm-line":{lineHeight:"var(--vuuFilterEditor-lineHeight)"},"&.cm-focused .cm-cursor":{borderLeftColor:"var(--vuuFilterEditor-cursorColor)"},"&.cm-focused .cm-selectionBackground, ::selection":{backgroundColor:"var(--vuuFilterEditor-selectionBackground)"},".cm-selectionBackground, ::selection":{backgroundColor:"var(--vuuFilterEditor-selectionBackground)"},".cm-scroller":{fontFamily:"var(--vuuFilterEditor-fontFamily)"},".cm-tooltip":{background:"var(--vuuFilterEditor-tooltipBackground)",border:"var(--vuuFilterEditor-tooltipBorder)",boxShadow:"var(--vuuFilterEditor-tooltipElevation)","&.cm-tooltip-autocomplete > ul":{fontFamily:"var(--vuuFilterEditor-fontFamily)",fontSize:"var(--vuuFilterEditor-fontSize)",maxHeight:"240px"},"&.cm-tooltip-autocomplete > ul > li":{alignItems:"center",display:"flex",height:"var(--vuuFilterEditor-suggestion-height)",padding:"0 3px",lineHeight:"var(--vuuFilterEditor-suggestion-height)"},"&.cm-tooltip-autocomplete li[aria-selected]":{background:"var(--vuuFilterEditor-suggestion-selectedBackground)",color:"var(--vuuFilterEditor-suggestion-selectedColor)"}},".cm-completionIcon":{height:"18px",flex:"0 0 16px"},".cm-completionLabel":{flex:"1 1 auto"},".cm-completionIcon-filter":{position:"relative","&:after":{background:"var(--salt-text-secondary-foreground)",content:"''","-webkit-mask":"var(--svg-filter) center center/13px 13px","-webkit-mask-repeat":"no-repeat",position:"absolute",height:"18px",left:"0px",top:"0px",width:"16px"}}},{dark:!1});import{getNodeByName as T,getValue as b,syntaxTree as ot}from"@vuu-ui/vuu-codemirror";import{useCallback as ae}from"react";var ue=(e,t)=>{let r=e.prevSibling||e.parent;for(;r&&!["Column","Operator","In"].includes(r.name);)r=r.prevSibling||r.parent;if((r==null?void 0:r.name)==="In"||(r==null?void 0:r.name)==="Operator")return b(r,t)},it=(e,t,r)=>{let n=b(e,t);if(!(r===void 0||n===r)&&["contains","ends","starts"].some(o=>o.startsWith(n.toLowerCase())))return n},pe=(e,t)=>{let r=e.prevSibling||e.parent||e.lastChild;for(;r&&r.name==="\u26A0";)r=r.prevSibling;if(r&&["As","Or","And"].includes(r.name))return b(r,t)},ce=(e,t)=>{if(e.name==="FilterName")return b(e,t);{let r=e.prevSibling||e.parent||e.lastChild;for(;r&&r.name!=="FilterName";)r=r.prevSibling;if(r&&r.name==="FilterName")return b(e,t)}},me=(e,t)=>{let r=e.prevSibling;if((r==null?void 0:r.name)==="Column")return b(r,t);if((r==null?void 0:r.name)==="Operator")return me(r,t)},st=(e,t)=>{let r=e.lastChild,n=[];for(;r&&r.name!=="In";){let o=b(r,t);if(o)n.push(o);else break;r=r.prevSibling}return n};var de=(e,t,r)=>{let n=ae(async(o,i,s={})=>{let{startsWith:c=""}=s,m=await e.getSuggestions(i,s);return{from:o.pos-c.length,options:m}},[e]);return ae(async o=>{var u,g;let{state:i,pos:s}=o,c=(u=o.matchBefore(/\w*/))!=null?u:{from:0,to:0,text:void 0},l=ot(i).resolveInner(s,-1);switch(console.log({nodeBeforeName:l.name}),l.name){case"Filter":if(o.pos===0)return n(o,"column");if(pe(l,i)==="as")return n(o,"name");{let d=ce(l,i);return n(o,"save",{onSubmit:t.current,existingFilter:r,filterName:d})}case"String":{let a=ue(l,i),d=me(l,i),{from:F,to:p}=l;if(p-F===2&&o.pos===F+1){if(d&&a)return n(o,"columnValue",{columnName:d,operator:a,quoted:!0,startsWith:c.text})}else console.log(`we have a string, column is ${d} ${F} ${p}`)}break;case"As":return n(o,"name");case"FilterName":return n(o,"save",{onSubmit:t.current,existingFilter:r,filterName:ce(l,i)});case"Column":{let a=b(l,i);return await e.isPartialMatch("column",void 0,a)?n(o,"column",{startsWith:a}):n(o,"operator",{columnName:a})}case"\u26A0":{let a=T(l,i),d=ue(l,i),F=d?void 0:it(l,i,a);return F?n(o,"operator",{columnName:a,startsWith:F}):n(o,"columnValue",{columnName:a,operator:d,startsWith:c.text})}case"Identifier":if(pe(l,i)==="as")return{from:o.pos,options:[{label:"press ENTER to apply filter and save",apply:()=>t.current(),boost:5}]};break;case"ColumnSetExpression":case"Values":{let a=T(l,i),d=st(l,i);return n(o,"columnValue",{columnName:a,selection:d})}case"Comma":case"LBrack":{let a=T(l,i);return n(o,"columnValue",{columnName:a})}case"ColumnValueExpression":{let a=(g=l.lastChild)==null?void 0:g.prevSibling;if((a==null?void 0:a.name)==="Column")return n(o,"operator",{columnName:T(l,i)});if((a==null?void 0:a.name)==="Operator")return n(o,"columnValue",{columnName:T(a,i),operator:b(a,i)})}break;case"In":return{from:o.pos,options:[{label:"[",apply:" [",type:"text"}]};case"Eq":return n(o,"columnValue",{columnName:T(l,i)});case"AndExpression":case"OrExpression":return n(o,"column");default:}},[r,n,t,e])};var R=e=>{if(e.current==null)throw Error("EditorView not defined");return e.current},dt=e=>(0,Fe.default)("vuuSuggestion",{vuuIllustration:e.isIllustration}),gt=e=>{let t=e.lastIndexOf(" as ");return t!==-1?e.slice(0,t):e},ft=()=>console.log("noooop"),Se=({existingFilter:e,onSubmitFilter:t,suggestionProvider:r})=>{let n=B(null),o=B(ft),i=B(),s=de(r,o,e),[c,m]=mt(()=>{let l=()=>{let p=R(i),C=p.state.doc.toString(),v=ut(p.state,p.state.doc.length,5e3);if(v){let f=M(v,C);return[f,gt(C),f.name]}else return[void 0,"",void 0]},u=()=>{R(i).setState(F())},g=p=>{let[C,v,f]=l();t==null||t(C,v,p,f),u()},a=p=>H.of([{key:p,run(){return g(),!0}}]),d=p=>H.of([{key:p,run(){return Oe(R(i)),!0}}]),F=()=>ge.create({doc:"",extensions:[pt,lt({override:[s],optionClass:dt}),oe(),H.of(at),a("Ctrl-Enter"),d("ArrowDown"),fe.updateListener.of(p=>{let C=R(i);p.docChanged&&Oe(C)}),ge.transactionFilter.of(p=>p.newDoc.lines>1?[]:p),le,se]});return o.current=p=>{g(p),setTimeout(()=>{R(i).focus()},100)},[F,u]},[s,t]);return ct(()=>{if(!n.current)throw Error("editor not in dom");return i.current=new fe({state:c(),parent:n.current}),()=>{var l;(l=i.current)==null||l.destroy()}},[s,c]),{editorRef:n,clearInput:m}};import{jsx as _,jsxs as Ot}from"react/jsx-runtime";var D="vuuFilterInput",fn=({existingFilter:e,iconName:t="filter",namedFilters:r,onSubmitFilter:n,suggestionProvider:o,...i})=>{let{editorRef:s,clearInput:c}=Se({existingFilter:e,onSubmitFilter:n,suggestionProvider:o});return Ot("div",{...i,className:D,children:[_(ve,{className:`${D}-FilterButton`,"data-icon":t,tabIndex:-1}),_("div",{className:`${D}-Editor`,ref:s}),_(ve,{className:`${D}-ClearButton`,"data-icon":"close-circle",onClick:c})]})};import{asNameSuggestion as Ft,booleanJoinSuggestions as St,getNamePrompt as vt,numericOperators as Ct,stringOperators as Pt,toSuggestions as bt}from"@vuu-ui/vuu-codemirror";import{getTypeaheadParams as ht,useTypeaheadSuggestions as yt}from"@vuu-ui/vuu-data";import{useCallback as Pe,useRef as Tt}from"react";import{createEl as W}from"@vuu-ui/vuu-utils";var Ce=(e,t)=>{let r=W("div","vuuFunctionDoc"),n=W("div","function-heading"),o=W("span","function-name",e);n.appendChild(o);let i=W("p",void 0,t);return r.appendChild(n),r.appendChild(i),r};var xt=[],Et={},wt=e=>[{label:"Press ENTER to create TAB",apply:()=>e("tab"),boost:6}],be=(e,t,r=!0)=>{let n=t?[{label:"REPLACE existing filter",apply:()=>e("replace"),boost:8},{label:"AND existing filter",apply:()=>e("and"),boost:7},{label:"OR existing filter",apply:()=>e("or"),boost:7}]:[{label:"Press ENTER to submit",apply:()=>e(),boost:6}];return r?n.concat(St).concat(Ft):n},Rt=(e,t)=>be(e,t,!0),Qt=e=>be(e,void 0),Nt=({existingFilter:e,filterName:t,onSubmit:r,saveOptions:n})=>{let o=t&&n.allowSaveAsTab,i=e?Rt(r,e):Qt(r);return o?i.concat(wt(r)):i},Vt=e=>e.map(t=>({boost:5,label:t.name})),At=e=>e?Array.from(e.entries()).map(([t,r])=>({info:()=>Ce(t,r),label:t,type:"filter"})):xt,kt={label:"Done",apply:"] ",type:"keyword",boost:10},$=(e,t="")=>e.filter(r=>t===""||r.label.startsWith(t)).map(r=>({...r,apply:r.label+" "})),Mt={allowReplace:!0},Tn=({columns:e,namedFilters:t,saveOptions:r=Mt,table:n})=>{let o=Tt(),i=yt(),s=Pe(async(m,l=Et)=>{let{columnName:u,existingFilter:g,filterName:a,operator:d,quoted:F,onSubmit:p,startsWith:C,selection:v}=l;switch(m){case"operator":{let f=e.find(E=>E.name===u);if(f)switch(f.serverDataType){case"string":case"char":return $(Pt,C);case"int":case"long":case"double":return $(Ct)}else console.warn(`'${u}' does not match any column name`)}break;case"column":{let f=await Vt(e),E=await At(t);return(o.current=$(f)).concat($(E))}case"columnValue":if(u){let f=e.find(We=>We.name===u);if(!f)throw Error(`useFilterSUggestionProvider no column ${u}`);let E=Array.isArray(v)?v.length===0?"[":",":"",Ie=ht(n,u,C),De=await i(Ie),K=d==="starts";return o.current=bt(De,{moveCursorToEnd:F,quoted:(f==null?void 0:f.serverDataType)==="string"&&!F,suffix:F?"":" ",prefix:K?C:E,isIllustration:K}),Array.isArray(v)&&(v==null?void 0:v.length)>1?[kt,...o.current]:o.current}break;case"save":{if(typeof p!="function")throw Error("useFilterSuggestionProvider, onSubmit must be supplied for 'save' suggestions");return await Nt({existingFilter:g,filterName:a,onSubmit:p,saveOptions:r})}case"name":return await vt("filter");default:}return[]},[e,i,t,r,n]),c=Pe(async(m,l,u)=>{let g=await s(m,{columnName:l});if(u&&g)for(let a of g){if(a.label===u)return!1;if(a.label.startsWith(u))return!0}return!1},[s]);return{getSuggestions:s,isPartialMatch:c}};var Ne=te(X(),1);import{Toolbar as Yt}from"@heswell/salt-lab";import{ToggleButton as jt,ToolbarField as Ee}from"@heswell/salt-lab";import{Dropdown as It}from"@heswell/salt-lab";import{useCallback as Dt,useState as Wt}from"react";import{jsx as Ut}from"react/jsx-runtime";var $t=e=>typeof e=="string",he=e=>$t(e)?e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e:e.map(he),ye=({column:e,selected:t,suggestionProvider:r,...n})=>{let o=t!=null?he(t):void 0,i=Array.isArray(o)?o:o!=null?[o]:[],[s,c]=Wt(i);console.log({initialValues:i});let m=Dt(async l=>{if(l){let u=await r.getSuggestions("columnValue",{columnName:e});console.log({values:u}),c(u.map(g=>g.label))}},[e,r]);return Ut(It,{...n,onOpenChange:m,selected:o,source:s})};import{Dropdown as Xt}from"@heswell/salt-lab";import{useCallback as Lt,useState as Ht}from"react";import{jsx as _t}from"react/jsx-runtime";var Bt=e=>typeof e=="string",Te=e=>{if(e!==void 0)return Bt(e)?e.startsWith('"')&&e.endsWith('"')?e.slice(1,-1):e:e.map(Te)},xe=({column:e,selected:t,suggestionProvider:r,...n})=>{let o=Te(t),i=Array.isArray(o)?o:o!=null?[o]:[],[s,c]=Ht(i),m=Lt(async l=>{if(l){let u=await r.getSuggestions("columnValue",{columnName:e});console.log({values:u}),c(u.map(g=>g.label))}},[e,r]);return _t(Xt,{...n,onOpenChange:m,selected:o,selectionStrategy:"multiple",source:s})};import{jsx as Q}from"react/jsx-runtime";var we=(e,t)=>{if(Qe(e))return Q(jt,{className:"vuuToggleButton",toggled:!0,variant:"secondary",children:e.name});if(x(e)){let{column:r,value:n}=e;return Q(Ee,{className:"vuuFilterDropdown",label:r,labelPlacement:"top",children:Q(ye,{column:r,selected:n.toString(),selectionStrategy:"default",source:[n.toString()],suggestionProvider:t,style:{width:100}})},r)}if(h(e)){let r=e.values.map(n=>n.toString());return Q(Ee,{className:"vuuFilterDropdown",label:e.column,labelPlacement:"top",children:Q(xe,{column:e.column,selected:r,source:r,suggestionProvider:t,style:{width:100}})},e.column)}return e.filters.map(r=>we(r,t))},Re=({filter:e,suggestionProvider:t})=>e?we(e,t):[];import{jsx as qt}from"react/jsx-runtime";var ro=({className:e,filter:t,suggestionProvider:r,...n})=>{console.log(`FilterToolbar ${JSON.stringify(t,null,2)}`);let o=Re({filter:t,suggestionProvider:r});return qt(Yt,{className:(0,Ne.default)("vuuFilterToolbar",e),...n,children:o})};var Ve=new Map,Gt=()=>!1,ao=(e,t)=>{let r=Ve.get(t);if(r)return r;try{let n=I(t);return r=j(e,n),Ve.set(t,r),r}catch{return console.warn(`filter-evaluation-utils, failed to parse filter "${t}"`),Gt}};function j(e,t){switch(t.op){case"in":return zt(e,t);case"=":return Zt(e,t);case">":return Jt(e,t);case">=":return Kt(e,t);case"<":return er(e,t);case"<=":return tr(e,t);case"starts":return rr(e,t);case"and":return nr(e,t);case"or":return or(e,t);default:return console.log(`unrecognized filter type ${t.op}`),()=>!0}}var zt=(e,t)=>r=>t.values.indexOf(r[e[t.column]])!==-1,Zt=(e,t)=>r=>r[e[t.column]]===t.value,Jt=(e,t)=>r=>r[e[t.column]]>t.value,Kt=(e,t)=>r=>r[e[t.column]]>=t.value,er=(e,t)=>r=>r[e[t.column]]<t.value,tr=(e,t)=>r=>r[e[t.column]]<=t.value,rr=(e,t)=>{let r=t.value;if(typeof r!="string")throw Error("string filter applied to value of wrong type");return n=>{let o=n[e[t.column]];if(typeof o!="string")throw Error("string filter applied to value of wrong type");return o.toLowerCase().startsWith(r.toLowerCase())}},nr=(e,t)=>{let r=t.filters.map(n=>j(e,n));return n=>r.every(o=>o(n))};function or(e,t){let r=t.filters.map(n=>j(e,n));return n=>r.some(o=>o(n))}import{extractFilterForColumn as sr,partition as lr}from"@vuu-ui/vuu-utils";var ir=new Set(["=","!=",">",">=","<","<=","starts","ends"]),Qe=e=>e!==void 0&&e.name!==void 0,x=e=>e!==void 0&&ir.has(e.op),po=e=>e!==void 0&&(x(e)||h(e)),h=e=>e!==void 0&&e.op==="in",N=e=>e.op==="in",Y=e=>e.op==="and",Ae=e=>e.op==="or";function y(e){return e!==void 0&&(e.op==="and"||e.op==="or")}var S="and",q="=",fo=">",Oo="<",ar="or",ke="starts",Fo="ends",ur="in",pr=(e,t=[])=>(e&&(y(e)?e.filters.forEach(r=>t.push(...pr(r))):t.push(e)),t),cr={combineWith:"and"},So=(e,t,{combineWith:r=S}=cr)=>{var n;if(J(t))y(t)||(e=z(e,{name:t.column}));else if(dr(t))return y(t),z(e,{name:(n=t.column)!=null?n:""});if(!e)return t;if(!t)return e;if(e.op===S&&t.op===S)return{op:S,filters:Or(e.filters,t.filters)};if(e.op===S){let o=gr(e.filters,t);return o.length>1?{op:S,filters:o}:o[0]}return t.op===S?{op:S,filters:t.filters.concat(e)}:Z(e,t,!0)?t:Me(e,t)?fr(e,t):{op:r,filters:[e,t]}},J=e=>e?N(e)&&e.values.length===0?!0:Y(e)&&e.filters.some(t=>J(t)):!1,mr=e=>typeof e=="string"?`"${e}"`:e,G=e=>y(e)?e.filters.map(t=>G(t)).join(` ${e.op} `):h(e)?`${e.column} ${e.op} [${e.values.join(",")}]`:`${e.column} ${e.op} ${mr(e.value)}`,dr=e=>e?e.op===ke&&e.value===""?!0:e.op===ke&&e.value==="":!1,gr=(e,t)=>e.concat(t),fr=(e,t)=>J(t)?t:N(e)&&N(t)?{...e,values:[...e.values,...t.values.filter(r=>!e.values.includes(r))]}:N(e)&&t.op===q?{...e,values:e.values.concat([t.value])}:e.op===q&&t.op===q?{column:e.column,op:ur,values:[e.value,t.value]}:t,Or=(e,t)=>{let r=({op:i},{op:s})=>i===s||i[0]===s[0],n=(i,s)=>i.column===s.column&&r(i,s),o=i=>t.some(s=>n(i,s))===!1;return e.filter(o).concat(t)},vo=(e,t)=>{if(y(t)){let[r,n]=t.filters;if(r.column===e.name)return[n,G(n)];if(n.column===e.name)return[r,G(r)]}return[void 0,""]},Co=(e,t)=>{if(Z(e,t,!0))return null;if(e.op!==S)throw Error(`removeFilter cannot remove ${JSON.stringify(t)} from ${JSON.stringify(e)}`);let r=e.filters.filter(n=>!Z(n,t));return r.length>0?{type:S,filters:r}:null},Po=(e,t)=>{if(!e)return[null,null];if(e.column===t)return[e,null];if(e.op!==S)return[null,e];let[[r=null],n]=lr(e.filters,o=>o.column===t);return n.length===1?[r,n[0]]:[r,{op:S,filters:n}]},Fr=(e,t)=>y(e)?{op:e.op,filters:e.filters.map(r=>Fr(r,t))}:{...e,column:t},Sr=(e,t)=>{if(!e)return!1;let{op:r,column:n}=e;switch(r){case S:case ar:return e.filters!=null&&e.filters.some(o=>Sr(o,t));default:return n===t.name}},z=(e,t)=>{let r=t.name;if(e&&e.column!==r){if(Y(e)||Ae(e)){let{op:n}=e,i=e.filters.filter(s=>s.column!==r);switch(i.length){case 0:return;case 1:return i[0];default:return{op:n,filters:i}}}return e}},Me=(e,t)=>e.column===t.column&&(e.op==="="||e.op==="in")&&(t.op==="="||t.op==="in"),vr=(e,t)=>{if(e===t)return!0;if(e.length===t.length){let r=e.slice().sort(),n=t.slice().sort();return r.join("|")===n.join("|")}return!1},Z=(e,t,r=!1)=>r?e&&t&&Me(e,t)?e.op===t.op&&(x(e)&&x(t)&&e.value===t.value||h(e)&&h(t)&&vr(e.values,t.values)):!1:!0,Cr=(e,t,r)=>{if(e&&t){if(r==="replace")return t;if(e.op==="and")return{...e,filters:e.filters.concat(t)};let{column:n}=t;if(n&&(t.column?sr(e,n):void 0)&&n){let i=z(e,{name:n});return Cr(i,t,"add")}return{op:"and",filters:[e,t]}}return t||e};export{S as AND,Fo as ENDS_WITH,q as EQUALS,fn as FilterInput,ro as FilterToolbar,fo as GREATER_THAN,ur as IN,Oo as LESS_THAN,ar as OR,ke as STARTS_WITH,So as addFilter,G as filterAsQuery,pr as filterClauses,Z as filterEquals,Sr as filterIncludesColumn,j as filterPredicate,ao as getFilterPredicate,Y as isAndFilter,po as isFilterClause,N as isInFilter,y as isMultiClauseFilter,h as isMultiValueFilter,Qe as isNamedFilter,Ae as isOrFilter,x as isSingleValueFilter,Fr as overrideColName,I as parseFilter,vo as removeColumnFromFilter,Co as removeFilter,Po as splitFilterOnColumn,Cr as updateFilter,Se as useCodeMirrorEditor,Tn as useFilterSuggestionProvider};
1614
2
  /*! Bundled license information:
1615
3
 
1616
4
  classnames/index.js: