@sentio/ui-dashboard 0.1.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/dist/index.mjs ADDED
@@ -0,0 +1,1022 @@
1
+ // src/timeseries/AggregateInput.tsx
2
+ import { useMemo } from "react";
3
+ import { capitalize } from "lodash";
4
+ import { produce } from "immer";
5
+ import { NewMultipleSelect } from "@sentio/ui-core";
6
+
7
+ // src/timeseries/labels.ts
8
+ import { getChainName } from "@sentio/chain";
9
+ var SystemLabels = [
10
+ {
11
+ field: "contract_name",
12
+ name: "contract",
13
+ getValues(metric) {
14
+ return (metric.contractName || []).map((name) => ({
15
+ value: name,
16
+ display: name
17
+ }));
18
+ }
19
+ },
20
+ {
21
+ field: "contract_address",
22
+ name: "address",
23
+ getValues(metric) {
24
+ return (metric.contractAddress || []).map((name) => ({
25
+ value: name,
26
+ display: name
27
+ }));
28
+ }
29
+ },
30
+ {
31
+ field: "chain",
32
+ name: "chain",
33
+ getValues(metric) {
34
+ return (metric.chainId || []).map((chainId) => {
35
+ return { value: chainId, display: getChainName(chainId) };
36
+ });
37
+ }
38
+ }
39
+ ];
40
+ function sortMetricByName(a, b) {
41
+ const aIsSystem = a.startsWith("system.");
42
+ const bIsSystem = b.startsWith("system.");
43
+ if (aIsSystem && !bIsSystem) {
44
+ return 1;
45
+ }
46
+ if (!aIsSystem && bIsSystem) {
47
+ return -1;
48
+ }
49
+ return a.localeCompare(b);
50
+ }
51
+
52
+ // src/timeseries/AggregateInput.tsx
53
+ import { jsx, jsxs } from "react/jsx-runtime";
54
+ var AggregateAggregateOps = [
55
+ "AVG",
56
+ "SUM",
57
+ "MIN",
58
+ "MAX",
59
+ "COUNT"
60
+ ];
61
+ function AggregateInput({ metric, value, onChange }) {
62
+ const { labels, selectedLabels } = useMemo(() => {
63
+ const labels2 = [];
64
+ for (const sl of SystemLabels) {
65
+ labels2.push({ label: sl.name, value: sl.field });
66
+ }
67
+ Object.keys(metric?.labels || {}).forEach((l) => {
68
+ labels2.push({ label: l, value: l });
69
+ });
70
+ const selectedLabels2 = [];
71
+ for (const l of value?.aggregate?.grouping || []) {
72
+ const label = labels2.find((lb) => lb.value === l);
73
+ if (label) {
74
+ selectedLabels2.push(label);
75
+ }
76
+ }
77
+ return { labels: labels2, selectedLabels: selectedLabels2 };
78
+ }, [metric, value]);
79
+ const onSelectLabel = (labels2) => {
80
+ onChange(
81
+ produce(value, (draft) => {
82
+ draft.aggregate = draft.aggregate || {};
83
+ draft.aggregate.grouping = labels2.map((l) => l.value);
84
+ })
85
+ );
86
+ };
87
+ const onSelectFunc = (f) => {
88
+ onChange(
89
+ produce(value, (draft) => {
90
+ if (f == "none") {
91
+ delete draft.aggregate;
92
+ } else {
93
+ const aggr = draft.aggregate || {};
94
+ aggr.op = f;
95
+ draft.aggregate = aggr;
96
+ }
97
+ })
98
+ );
99
+ };
100
+ return /* @__PURE__ */ jsxs("div", { className: "min-h-8 flex grow items-center justify-stretch", children: [
101
+ /* @__PURE__ */ jsxs(
102
+ "select",
103
+ {
104
+ value: value.aggregate?.op || "",
105
+ className: "sm:text-ilabel border-main text-text-foreground inline-flex h-8 items-center rounded-l-md border border-r-0 bg-gray-50 py-1 pl-4 pr-7 focus:border-0 focus:ring-inset",
106
+ onChange: (e) => onSelectFunc(e.target.value),
107
+ "aria-label": "aggregate",
108
+ children: [
109
+ /* @__PURE__ */ jsx("option", { value: "none", children: "No aggregate" }, ""),
110
+ AggregateAggregateOps.map((key) => {
111
+ return /* @__PURE__ */ jsxs("option", { value: key, children: [
112
+ capitalize(key),
113
+ " by"
114
+ ] }, key);
115
+ })
116
+ ]
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsx(
120
+ NewMultipleSelect,
121
+ {
122
+ disabled: !value.aggregate,
123
+ className: "border-main flex h-8 grow overflow-hidden rounded-r-md border",
124
+ options: labels || [],
125
+ value: selectedLabels,
126
+ onChange: onSelectLabel,
127
+ displayFn: (l) => l.label,
128
+ unSelectedText: "(everything)",
129
+ optionsClassName: "min-w-[200px]"
130
+ }
131
+ )
132
+ ] });
133
+ }
134
+
135
+ // src/timeseries/ArgumentInput.tsx
136
+ import { DurationInput, classNames } from "@sentio/ui-core";
137
+
138
+ // src/timeseries/functions.ts
139
+ var ArgumentType = /* @__PURE__ */ ((ArgumentType2) => {
140
+ ArgumentType2[ArgumentType2["String"] = 0] = "String";
141
+ ArgumentType2[ArgumentType2["Integer"] = 1] = "Integer";
142
+ ArgumentType2[ArgumentType2["Double"] = 2] = "Double";
143
+ ArgumentType2[ArgumentType2["Bool"] = 3] = "Bool";
144
+ ArgumentType2[ArgumentType2["Duration"] = 4] = "Duration";
145
+ return ArgumentType2;
146
+ })(ArgumentType || {});
147
+ var abs = {
148
+ name: "abs",
149
+ description: "Returns the absolute value.",
150
+ arguments: []
151
+ };
152
+ var ceil = {
153
+ name: "ceil",
154
+ description: "Returns the smallest integer greater than or equal to a number.",
155
+ arguments: []
156
+ };
157
+ var floor = {
158
+ name: "floor",
159
+ description: "Returns the largest integer less than or equal to a number.",
160
+ arguments: []
161
+ };
162
+ var round = {
163
+ name: "round",
164
+ description: "Returns the value of a number rounded to the nearest integer.",
165
+ arguments: []
166
+ };
167
+ var log2 = {
168
+ name: "log2",
169
+ description: "Returns the base 2 logarithm.",
170
+ arguments: []
171
+ };
172
+ var log10 = {
173
+ name: "log10",
174
+ description: "Returns the base 10 logarithm.",
175
+ arguments: []
176
+ };
177
+ var ln = {
178
+ name: "ln",
179
+ description: "Returns the natural logarithm.",
180
+ arguments: []
181
+ };
182
+ var aggregations = ["avg", "count", "last", "max", "min", "sum", "delta"];
183
+ var aggregationDescriptions = {
184
+ avg: "Calculates the sum of all values in the specified interval.",
185
+ count: "Calculates the number of values in the specified interval.",
186
+ last: "Calculates the last value in the specified interval.",
187
+ max: "Calculates the maximum of all values in the specified interval.",
188
+ min: "Calculates the minimum of all values in the specified interval.",
189
+ sum: "Calculates the sum of all values in the specified interval.",
190
+ delta: "Calculates the difference between the first and last value in the specified interval."
191
+ };
192
+ var aggregateOverTimeFunctions = aggregations.map(
193
+ (method) => ({
194
+ name: `${method}_over_time`,
195
+ description: aggregationDescriptions[method],
196
+ arguments: [
197
+ {
198
+ name: "interval",
199
+ type: 4 /* Duration */
200
+ }
201
+ ],
202
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }]
203
+ })
204
+ );
205
+ var rollupDescriptions = {
206
+ avg: "Roll up the metric by its average value over the specified time period.",
207
+ count: "Roll up the metric by its count value over the specified time period.",
208
+ last: "Roll up the metric by its last value over the specified time period.",
209
+ max: "Roll up the metric by its maximum value over the specified time period.",
210
+ min: "Roll up the metric by its minimum value over the specified time period.",
211
+ sum: "Roll up the metric by its sum value over the specified time period.",
212
+ delta: "Roll up the metric by its delta value over the specified time period."
213
+ };
214
+ var rollupFunctions = aggregations.map(
215
+ (method) => ({
216
+ name: `rollup_${method}`,
217
+ description: rollupDescriptions[method],
218
+ arguments: [
219
+ {
220
+ name: "interval",
221
+ type: 4 /* Duration */
222
+ }
223
+ ],
224
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }]
225
+ })
226
+ );
227
+ var rate = {
228
+ name: "rate",
229
+ description: "Calculates the per-second average rate of increase of the time series.",
230
+ arguments: [
231
+ {
232
+ name: "interval",
233
+ type: 4 /* Duration */
234
+ }
235
+ ],
236
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }]
237
+ };
238
+ var irate = {
239
+ name: "irate",
240
+ description: "Calculates the per-second instant rate of increase of the time series.",
241
+ arguments: [
242
+ {
243
+ name: "interval",
244
+ type: 4 /* Duration */
245
+ }
246
+ ],
247
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }]
248
+ };
249
+ var delta = {
250
+ name: "delta",
251
+ description: "Calculates the difference between the first and last value of each time series.",
252
+ arguments: [
253
+ {
254
+ name: "interval",
255
+ type: 4 /* Duration */
256
+ }
257
+ ],
258
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }],
259
+ deprecated: true
260
+ };
261
+ var moving_delta = {
262
+ name: "moving_delta",
263
+ description: "Calculates the difference between the first and last value of each time series. (continuously)",
264
+ arguments: [
265
+ {
266
+ name: "interval",
267
+ type: 4 /* Duration */
268
+ }
269
+ ],
270
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }],
271
+ deprecated: true
272
+ };
273
+ var topk = {
274
+ name: "topk",
275
+ description: "Returns the top k elements by sample value.",
276
+ arguments: [
277
+ {
278
+ name: "k",
279
+ type: 1 /* Integer */
280
+ }
281
+ ],
282
+ defaultArguments: [{ intValue: 1 }]
283
+ };
284
+ var bottomk = {
285
+ name: "bottomk",
286
+ description: "Returns the bottom k elements by sample value.",
287
+ arguments: [
288
+ {
289
+ name: "k",
290
+ type: 1 /* Integer */
291
+ }
292
+ ],
293
+ defaultArguments: [{ intValue: 1 }]
294
+ };
295
+ var timestamp = {
296
+ name: "timestamp",
297
+ description: "Returns the timestamp of each of the samples of the given vector as the number of seconds since January 1, 1970 UTC.",
298
+ arguments: []
299
+ };
300
+ var day_of_week = {
301
+ name: "day_of_week",
302
+ description: "Returns the day of the week for each of the given times. (needs timestamp)",
303
+ arguments: []
304
+ };
305
+ var day_of_month = {
306
+ name: "day_of_month",
307
+ description: "Returns the day of the month for each of the given times. (needs timestamp)",
308
+ arguments: []
309
+ };
310
+ var day_of_year = {
311
+ name: "day_of_year",
312
+ description: "Returns the day of the year for each of the given times. (needs timestamp)",
313
+ arguments: []
314
+ };
315
+ var month = {
316
+ name: "month",
317
+ description: "Returns the month of the given time. Returned values are from 1 to 12, where 1 means January etc. (needs timestamp)",
318
+ arguments: []
319
+ };
320
+ var year = {
321
+ name: "year",
322
+ description: "Returns the year of the given time. (needs timestamp)",
323
+ arguments: []
324
+ };
325
+ var hour = {
326
+ name: "hour",
327
+ description: "Returns the hour of the given time. Returned values are from 0 to 23. (needs timestamp)",
328
+ arguments: []
329
+ };
330
+ var minute = {
331
+ name: "minute",
332
+ description: "Returns the minute of the given time. Returned values are from 0 to 59. (needs timestamp)",
333
+ arguments: []
334
+ };
335
+ var before = {
336
+ name: "before",
337
+ displayName: "shift earlier",
338
+ description: "Shifts the vector back in time by the specified duration.",
339
+ arguments: [
340
+ {
341
+ name: "duration",
342
+ type: 4 /* Duration */
343
+ }
344
+ ],
345
+ defaultArguments: [{ durationValue: { value: 1, unit: "h" } }]
346
+ };
347
+ var after = {
348
+ name: "after",
349
+ displayName: "shift later",
350
+ description: "Shifts the vector forward in time by the specified duration.",
351
+ arguments: [
352
+ {
353
+ name: "duration",
354
+ type: 4 /* Duration */
355
+ }
356
+ ],
357
+ defaultArguments: [{ durationValue: { value: 1, unit: "h" } }]
358
+ };
359
+ var FunctionsCategories = {
360
+ Math: [abs, ceil, floor, round, log2, log10, ln],
361
+ Rollup: rollupFunctions,
362
+ "Aggregate Over Time": aggregateOverTimeFunctions,
363
+ Rate: [rate, irate, delta, moving_delta],
364
+ Rank: [topk, bottomk],
365
+ Time: [
366
+ timestamp,
367
+ day_of_year,
368
+ day_of_month,
369
+ day_of_week,
370
+ year,
371
+ month,
372
+ hour,
373
+ minute
374
+ ],
375
+ TimeShift: [before, after]
376
+ };
377
+ var FunctionMap = Object.values(
378
+ FunctionsCategories
379
+ ).reduce(
380
+ (acc, funcs) => {
381
+ funcs.forEach((f) => {
382
+ acc[f.name] = f;
383
+ });
384
+ return acc;
385
+ },
386
+ {}
387
+ );
388
+ function isAggrOrRollupFunction(name) {
389
+ const f = FunctionMap[name];
390
+ return f && (f.name.startsWith("rollup_") || f.name.endsWith("_over_time"));
391
+ }
392
+ var eventsDelta = {
393
+ name: "delta",
394
+ description: "Calculates the difference between the first and last value of each time series.",
395
+ arguments: [
396
+ {
397
+ name: "interval",
398
+ type: 4 /* Duration */
399
+ }
400
+ ],
401
+ defaultArguments: [{ durationValue: { value: 1, unit: "m" } }]
402
+ };
403
+ var EventsFunctionCategories = {
404
+ Rank: [topk, bottomk],
405
+ Delta: [eventsDelta]
406
+ };
407
+ var EventsFunctionMap = Object.values(
408
+ EventsFunctionCategories
409
+ ).reduce(
410
+ (acc, funcs) => {
411
+ funcs.forEach((f) => {
412
+ acc[f.name] = f;
413
+ });
414
+ return acc;
415
+ },
416
+ {}
417
+ );
418
+
419
+ // src/timeseries/ArgumentInput.tsx
420
+ import { jsx as jsx2 } from "react/jsx-runtime";
421
+ function ArgumentInput({ className, argument, value, onChange }) {
422
+ switch (argument.type) {
423
+ case 0 /* String */:
424
+ return /* @__PURE__ */ jsx2(
425
+ "input",
426
+ {
427
+ type: "text",
428
+ className: classNames(
429
+ className,
430
+ "hover:border-primary-600 focus:border-primary-600 focus:ring-3 focus:ring-primary-600/30 border border-transparent"
431
+ ),
432
+ value: value?.stringValue,
433
+ onChange: (v) => onChange && onChange({ stringValue: v.target.value })
434
+ }
435
+ );
436
+ case 2 /* Double */:
437
+ return /* @__PURE__ */ jsx2(
438
+ "input",
439
+ {
440
+ type: "number",
441
+ className: classNames(
442
+ className,
443
+ "hover:border-primary-600 focus:border-primary-600 focus:ring-3 focus:ring-primary-600/30 border border-transparent"
444
+ ),
445
+ value: value?.doubleValue,
446
+ step: "any",
447
+ onChange: (v) => onChange && onChange({ doubleValue: parseFloat(v.target.value) })
448
+ }
449
+ );
450
+ case 1 /* Integer */:
451
+ return /* @__PURE__ */ jsx2(
452
+ "input",
453
+ {
454
+ step: "1",
455
+ type: "number",
456
+ className: classNames(
457
+ className,
458
+ "hover:border-primary-600 focus:border-primary-600 focus:ring-3 focus:ring-primary-600/30 border border-transparent"
459
+ ),
460
+ value: value?.intValue,
461
+ onChange: (v) => onChange && onChange({ intValue: parseInt(v.target.value) })
462
+ }
463
+ );
464
+ case 3 /* Bool */:
465
+ return /* @__PURE__ */ jsx2(
466
+ "input",
467
+ {
468
+ type: "checkbox",
469
+ className: classNames(
470
+ className,
471
+ "hover:border-primary-600 focus:border-primary-600 focus:ring-3 focus:ring-primary-600/30 border border-transparent"
472
+ ),
473
+ checked: value?.boolValue,
474
+ onChange: (e) => onChange && onChange({ boolValue: e.target.value == "true" })
475
+ }
476
+ );
477
+ case 4 /* Duration */:
478
+ return /* @__PURE__ */ jsx2(
479
+ DurationInput,
480
+ {
481
+ className: "rounded-none! border-transparent! hover:border-primary-600! focus-within:border-primary-600!",
482
+ inputClassName: classNames(className),
483
+ value: value?.durationValue,
484
+ onChange: (e) => onChange && onChange({ durationValue: e }),
485
+ enableDays: true
486
+ }
487
+ );
488
+ }
489
+ }
490
+
491
+ // src/timeseries/FunctionInput.tsx
492
+ import { Popover } from "@headlessui/react";
493
+ import { LuX, LuChevronDown } from "react-icons/lu";
494
+ import { useFloating, autoPlacement } from "@floating-ui/react";
495
+ import { produce as produce2 } from "immer";
496
+ import isEqual from "lodash/isEqual";
497
+ import { HelpIcon, PopoverButton, classNames as classNames3 } from "@sentio/ui-core";
498
+
499
+ // src/timeseries/FunctionsPanel.tsx
500
+ import { Tab } from "@headlessui/react";
501
+ import { Fragment, useEffect, useRef, useState } from "react";
502
+ import { classNames as classNames2 } from "@sentio/ui-core";
503
+ import { BiCaretRight } from "react-icons/bi";
504
+ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
505
+ function FunctionsPanel({
506
+ onClick,
507
+ functionCategories = FunctionsCategories,
508
+ defaultFunc
509
+ }) {
510
+ const ulRef = useRef(null);
511
+ const [selectedIdx, setSelectedIdx] = useState(0);
512
+ useEffect(() => {
513
+ if (!defaultFunc) return;
514
+ let targetIndex = 0;
515
+ Object.keys(functionCategories).forEach((category, idx) => {
516
+ const func = functionCategories[category].find(
517
+ (f) => f.name === defaultFunc
518
+ );
519
+ if (func) {
520
+ targetIndex = idx;
521
+ }
522
+ });
523
+ setSelectedIdx(targetIndex);
524
+ setTimeout(() => {
525
+ const target = ulRef.current?.querySelector(
526
+ `li[data-name="${defaultFunc}"]`
527
+ );
528
+ if (target) {
529
+ target.scrollIntoView({ block: "center" });
530
+ }
531
+ }, 0);
532
+ }, [defaultFunc]);
533
+ return /* @__PURE__ */ jsx3("div", { className: "bg-default-bg flex h-full overflow-hidden rounded-md", children: /* @__PURE__ */ jsxs2(Tab.Group, { vertical: true, selectedIndex: selectedIdx, onChange: setSelectedIdx, children: [
534
+ /* @__PURE__ */ jsx3(
535
+ Tab.List,
536
+ {
537
+ as: "ul",
538
+ className: "native-scroller border-main flex w-44 shrink-0 flex-col flex-nowrap divide-y divide-gray-200 overflow-auto border-r",
539
+ children: Object.keys(functionCategories).map((category, idx) => /* @__PURE__ */ jsx3(Tab, { as: Fragment, children: ({ selected }) => /* @__PURE__ */ jsxs2(
540
+ "li",
541
+ {
542
+ onMouseOver: () => setSelectedIdx(idx),
543
+ className: classNames2(
544
+ selected ? "bg-primary-500 hover:bg-primary-600" : "bg-default-bg hover:bg-gray-50",
545
+ selected ? "text-white" : "text-foreground",
546
+ "flex cursor-pointer items-center justify-between p-2 text-sm font-medium"
547
+ ),
548
+ children: [
549
+ /* @__PURE__ */ jsx3(
550
+ "p",
551
+ {
552
+ className: classNames2(
553
+ "text-ilabel flex-1 truncate font-medium"
554
+ ),
555
+ children: category
556
+ }
557
+ ),
558
+ /* @__PURE__ */ jsx3(
559
+ BiCaretRight,
560
+ {
561
+ className: classNames2("h-3 w-3 shrink-0 self-center")
562
+ }
563
+ )
564
+ ]
565
+ }
566
+ ) }, category))
567
+ }
568
+ ),
569
+ /* @__PURE__ */ jsx3(Tab.Panels, { className: "flex-1", children: Object.keys(functionCategories).map((category) => /* @__PURE__ */ jsx3(
570
+ Tab.Panel,
571
+ {
572
+ as: "ul",
573
+ className: "h-full divide-y overflow-y-auto",
574
+ ref: ulRef,
575
+ children: functionCategories[category].filter((f) => !f.deprecated).map((func) => /* @__PURE__ */ jsxs2(
576
+ "li",
577
+ {
578
+ className: classNames2(
579
+ "group cursor-pointer space-y-1 px-2 py-1.5",
580
+ func.name === defaultFunc ? "bg-primary-600 dark:bg-primary-600 text-white" : "hover:bg-sentio-gray-100 dark:hover:bg-sentio-gray-400 text-text-foreground dark:hover:text-white"
581
+ ),
582
+ onClick: () => onClick(func),
583
+ "data-name": func.name,
584
+ children: [
585
+ /* @__PURE__ */ jsx3("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsx3("p", { className: "text-ilabel truncate font-medium", children: func.displayName || func.name }) }),
586
+ /* @__PURE__ */ jsx3("div", { className: "flex", children: /* @__PURE__ */ jsx3(
587
+ "div",
588
+ {
589
+ className: classNames2(
590
+ "text-icontent flex items-center",
591
+ func.name === defaultFunc ? "text-white/80" : "text-text-foreground-secondary"
592
+ ),
593
+ children: /* @__PURE__ */ jsx3("p", { children: func.description })
594
+ }
595
+ ) })
596
+ ]
597
+ },
598
+ func.name
599
+ ))
600
+ },
601
+ category
602
+ )) })
603
+ ] }) });
604
+ }
605
+
606
+ // src/timeseries/FunctionInput.tsx
607
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
608
+ function FunctionInput({ value, onChange }) {
609
+ const { x, y, refs, strategy } = useFloating({
610
+ middleware: [autoPlacement()]
611
+ });
612
+ const onSelectFunc = (f) => {
613
+ onChange(
614
+ produce2(value, (draft) => {
615
+ draft.functions = draft.functions || [];
616
+ draft.functions.push({
617
+ name: f.name,
618
+ arguments: f.defaultArguments || []
619
+ });
620
+ })
621
+ );
622
+ };
623
+ const remove = (f) => {
624
+ const idx = (value.functions || []).indexOf(f);
625
+ if (idx >= 0) {
626
+ onChange(
627
+ produce2(value, (draft) => {
628
+ draft.functions = draft.functions || [];
629
+ draft.functions.splice(idx, 1);
630
+ })
631
+ );
632
+ }
633
+ };
634
+ function changeArgument(fidx, aidx, v) {
635
+ onChange(
636
+ produce2(value, (draft) => {
637
+ draft.functions = draft.functions || [];
638
+ const f = draft.functions[fidx];
639
+ if (f) {
640
+ f.arguments = f.arguments || [];
641
+ f.arguments[aidx] = v;
642
+ }
643
+ })
644
+ );
645
+ }
646
+ function changeFunction(fidx, f) {
647
+ onChange(
648
+ produce2(value, (draft) => {
649
+ draft.functions = draft.functions || [];
650
+ const preFunc = draft.functions[fidx];
651
+ let resetArg = true;
652
+ if (preFunc.arguments?.length === f.defaultArguments?.length) {
653
+ const firstArg = preFunc.arguments?.[0];
654
+ const firstDefaultArg = f.defaultArguments?.[0];
655
+ if (firstArg && firstDefaultArg) {
656
+ resetArg = isEqual(
657
+ Object.keys(firstArg),
658
+ Object.keys(firstDefaultArg)
659
+ ) ? false : true;
660
+ }
661
+ }
662
+ draft.functions[fidx] = {
663
+ name: f.name,
664
+ arguments: resetArg ? f.defaultArguments || [] : preFunc.arguments
665
+ };
666
+ })
667
+ );
668
+ }
669
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
670
+ /* @__PURE__ */ jsx4(
671
+ Functions,
672
+ {
673
+ functions: value.functions || [],
674
+ onRemove: remove,
675
+ onChangeArgument: changeArgument,
676
+ onChangeFunction: changeFunction
677
+ }
678
+ ),
679
+ /* @__PURE__ */ jsxs3("div", { className: "inline-flex items-center", children: [
680
+ /* @__PURE__ */ jsx4("div", { className: "h-0.5 w-2.5 self-center bg-gray-300" }),
681
+ /* @__PURE__ */ jsx4(Popover, { className: "relative", children: ({ open }) => /* @__PURE__ */ jsxs3(Fragment2, { children: [
682
+ /* @__PURE__ */ jsxs3(
683
+ Popover.Button,
684
+ {
685
+ ref: refs.setReference,
686
+ "aria-label": "Add function",
687
+ className: classNames3(
688
+ "text-ilabel focus:border-primary-600 focus:ring-primary-600/30 focus:ring-3 relative -ml-px inline-flex h-8 items-center space-x-2 rounded-md",
689
+ "border-main hover:border-primary-600 border px-4 font-normal",
690
+ open ? "text-primary-600 ring-1" : "text-text-foreground-secondary hover:text-text-foreground"
691
+ ),
692
+ children: [
693
+ /* @__PURE__ */ jsx4("span", { className: "flex text-sm", children: "f(x)" }),
694
+ /* @__PURE__ */ jsx4(HelpIcon, { text: "Add functions to query." })
695
+ ]
696
+ }
697
+ ),
698
+ /* @__PURE__ */ jsx4(
699
+ Popover.Panel,
700
+ {
701
+ className: "shadow-xs border-main z-10 mt-3 h-56 w-96 rounded-md border px-2 sm:px-0 lg:max-w-3xl",
702
+ ref: refs.setFloating,
703
+ style: {
704
+ position: strategy,
705
+ top: y ?? 0,
706
+ left: x ?? 0
707
+ },
708
+ children: ({ close }) => /* @__PURE__ */ jsx4(
709
+ FunctionsPanel,
710
+ {
711
+ onClick: (f) => {
712
+ onSelectFunc(f);
713
+ close();
714
+ }
715
+ }
716
+ )
717
+ }
718
+ )
719
+ ] }) })
720
+ ] })
721
+ ] });
722
+ }
723
+ function Functions({
724
+ functions,
725
+ onRemove,
726
+ onChangeArgument,
727
+ onChangeFunction
728
+ }) {
729
+ if (functions.length == 0) {
730
+ return /* @__PURE__ */ jsx4(Fragment2, {});
731
+ }
732
+ return /* @__PURE__ */ jsx4(Fragment2, { children: functions.map((f, fi) => {
733
+ const def = FunctionMap[f.name];
734
+ return /* @__PURE__ */ jsxs3("div", { className: "inline-flex items-center", children: [
735
+ /* @__PURE__ */ jsx4("div", { className: "h-0.5 w-2.5 self-center bg-gray-300" }),
736
+ /* @__PURE__ */ jsxs3(
737
+ "div",
738
+ {
739
+ className: classNames3(
740
+ "text-ilabel focus:outline-hidden text-text-foreground-secondary relative inline-flex items-center pl-2 font-normal",
741
+ "border-main rounded-md border",
742
+ "h-8"
743
+ ),
744
+ children: [
745
+ /* @__PURE__ */ jsx4(
746
+ PopoverButton,
747
+ {
748
+ containerClassName: "h-full border-r border-light pr-2 inline-flex items-center bg-gray-50",
749
+ content: ({ close }) => /* @__PURE__ */ jsx4("div", { className: "z-10 h-56 w-96 px-2 sm:px-0 lg:max-w-3xl", children: /* @__PURE__ */ jsx4(
750
+ FunctionsPanel,
751
+ {
752
+ onClick: (f2) => {
753
+ onChangeFunction?.(fi, f2);
754
+ close();
755
+ },
756
+ defaultFunc: f.name
757
+ }
758
+ ) }),
759
+ children: /* @__PURE__ */ jsxs3("span", { className: "hover:text-primary-600 text-text-foreground inline-flex cursor-pointer flex-nowrap items-center gap-1", children: [
760
+ def.displayName || f.name,
761
+ /* @__PURE__ */ jsx4(LuChevronDown, { className: "h-4 w-4" })
762
+ ] })
763
+ }
764
+ ),
765
+ def.arguments.map((arg, i) => /* @__PURE__ */ jsx4(
766
+ ArgumentInput,
767
+ {
768
+ className: "sm:text-ilabel block w-full pl-4",
769
+ argument: arg,
770
+ value: f.arguments && f.arguments[i],
771
+ onChange: (v) => onChangeArgument(fi, i, v)
772
+ },
773
+ "arg_" + i
774
+ )),
775
+ /* @__PURE__ */ jsx4(
776
+ "button",
777
+ {
778
+ type: "button",
779
+ className: "text-text-foreground-disabled hover:text-text-foreground hover:bg-hover h-full rounded-r-md px-2",
780
+ "aria-label": "remove function",
781
+ onClick: () => onRemove(f),
782
+ children: /* @__PURE__ */ jsx4(LuX, { className: "h-3.5 w-3.5", "aria-hidden": "true" })
783
+ }
784
+ )
785
+ ]
786
+ }
787
+ )
788
+ ] }, f.name);
789
+ }) });
790
+ }
791
+
792
+ // src/timeseries/LabelsInput.tsx
793
+ import { useMemo as useMemo2, useState as useState3 } from "react";
794
+ import { produce as produce3 } from "immer";
795
+ import { isEqual as isEqual2, sortBy, sortedUniqBy } from "lodash";
796
+ import { LuCheck } from "react-icons/lu";
797
+ import { VscRegex } from "react-icons/vsc";
798
+ import { NewMultipleSelect as NewMultipleSelect2, classNames as classNames4 } from "@sentio/ui-core";
799
+
800
+ // src/timeseries/LabelSearchContext.tsx
801
+ import { createContext, useContext, useState as useState2 } from "react";
802
+ import { jsx as jsx5 } from "react/jsx-runtime";
803
+ var LabelSearchContext = createContext(
804
+ void 0
805
+ );
806
+ function LabelSearchProvider({ children }) {
807
+ const [labelSearchQuery, setLabelSearchQuery] = useState2("");
808
+ return /* @__PURE__ */ jsx5(
809
+ LabelSearchContext.Provider,
810
+ {
811
+ value: { labelSearchQuery, setLabelSearchQuery },
812
+ children
813
+ }
814
+ );
815
+ }
816
+ function useLabelSearchContext() {
817
+ return useContext(LabelSearchContext);
818
+ }
819
+ function useLabelSearch(defaultQuery) {
820
+ const context = useLabelSearchContext();
821
+ const [localQuery, setLocalQuery] = useState2(defaultQuery || "");
822
+ if (context) {
823
+ return context;
824
+ }
825
+ return {
826
+ labelSearchQuery: localQuery,
827
+ setLabelSearchQuery: setLocalQuery
828
+ };
829
+ }
830
+
831
+ // src/timeseries/LabelsInput.tsx
832
+ import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
833
+ function LabelsInput({
834
+ value,
835
+ metric,
836
+ variables,
837
+ onChange,
838
+ small,
839
+ useRegex
840
+ }) {
841
+ const [input, setInput] = useState3("");
842
+ const onSelectLabel = (labels) => {
843
+ const selector = {};
844
+ labels.forEach((label) => {
845
+ selector[label.key] = label.value;
846
+ });
847
+ onChange(
848
+ produce3(value, (draft) => {
849
+ draft.labelSelector = selector;
850
+ })
851
+ );
852
+ };
853
+ const { setLabelSearchQuery } = useLabelSearch();
854
+ const labelSelectors = useMemo2(() => {
855
+ const result = [];
856
+ if (metric) {
857
+ Object.entries(variables || {}).forEach(([name, variable]) => {
858
+ const varname = `$${name}`;
859
+ const labelSelector = {
860
+ display: variable.field == name ? varname : `${variable.field}: ${varname}`,
861
+ key: variable.field,
862
+ value: `${varname}`
863
+ };
864
+ if (metric.labels && metric.labels[variable.field]) {
865
+ result.push(labelSelector);
866
+ } else if (variable?.field && SystemLabels.map((l) => l.name).includes(variable?.field)) {
867
+ result.push(labelSelector);
868
+ }
869
+ });
870
+ for (const sl of SystemLabels) {
871
+ sl.getValues(metric).forEach(({ value: value2, display }) => {
872
+ result.push({
873
+ display: `${sl.name}: ${display}`,
874
+ key: sl.field,
875
+ value: value2
876
+ });
877
+ });
878
+ }
879
+ let inputLabel = "";
880
+ let inputValue = "";
881
+ if (input.includes(":")) {
882
+ ;
883
+ [inputLabel, inputValue] = input.split(":");
884
+ inputLabel = inputLabel.trim();
885
+ inputValue = inputValue.trim();
886
+ } else {
887
+ inputValue = input.trim();
888
+ }
889
+ Object.entries(metric?.labels || {}).forEach(([key, values]) => {
890
+ ;
891
+ (values.values || []).forEach((value2) => {
892
+ result.push({
893
+ display: `${key}:${value2}`,
894
+ key,
895
+ value: value2
896
+ });
897
+ });
898
+ if (!useRegex || inputValue && key.includes(inputLabel) === false || !inputValue) {
899
+ return;
900
+ }
901
+ result.push({
902
+ display: `${key}: <contains> ${inputValue}`,
903
+ key,
904
+ value: JSON.stringify({
905
+ operator: "contains",
906
+ value: inputValue,
907
+ ignoreCase: true
908
+ })
909
+ });
910
+ });
911
+ }
912
+ return sortedUniqBy(
913
+ sortBy(result, (r) => r.display),
914
+ (r) => r.display
915
+ );
916
+ }, [metric, variables, input, useRegex]);
917
+ const selectedLabels = useMemo2(() => {
918
+ const selector = value?.labelSelector || {};
919
+ return Object.entries(selector).map(([key, value2]) => {
920
+ return labelSelectors.find((ls) => ls.key == key && ls.value == value2) || {
921
+ display: `${key}:${value2}`,
922
+ key,
923
+ value: value2
924
+ };
925
+ });
926
+ }, [value?.labelSelector, labelSelectors]);
927
+ return /* @__PURE__ */ jsx6(
928
+ NewMultipleSelect2,
929
+ {
930
+ input,
931
+ onInputChange: setInput,
932
+ className: classNames4(
933
+ "border-main flex grow overflow-auto rounded-r-md border",
934
+ small ? "min-h-6" : "min-h-8"
935
+ ),
936
+ options: labelSelectors,
937
+ value: selectedLabels,
938
+ onChange: onSelectLabel,
939
+ displayFn: (o) => {
940
+ const { display, value: value2 } = o;
941
+ const isRegex = /^\{.*\}$/.test(value2);
942
+ if (isRegex) {
943
+ const valueObj = JSON.parse(value2);
944
+ return `${o.key}:<${valueObj?.opertaor ?? "contains"}> ${valueObj?.value ?? value2}`;
945
+ }
946
+ return display;
947
+ },
948
+ disabled: !value.query,
949
+ unSelectedText: "(everywhere)",
950
+ maxInputSize: 30,
951
+ displayIcon: (o) => {
952
+ const isRegex = /^\{.*\}$/.test(o.value);
953
+ return isRegex ? /* @__PURE__ */ jsx6(VscRegex, { className: "mr-1 inline-block h-3 w-3 align-top" }) : null;
954
+ },
955
+ renderOption: (v, _active, selected) => {
956
+ const text = v.display;
957
+ const isRegex = /^\{.*\}$/.test(v.value);
958
+ const title = `${text} ${isRegex ? " (case-sensitive regex matcher)" : ""}`;
959
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
960
+ /* @__PURE__ */ jsxs4(
961
+ "span",
962
+ {
963
+ title,
964
+ className: classNames4(
965
+ "block truncate",
966
+ selected && "font-medium"
967
+ ),
968
+ children: [
969
+ isRegex && /* @__PURE__ */ jsx6(VscRegex, { className: "mr-1 inline-block h-3 w-3 align-top" }),
970
+ text
971
+ ]
972
+ }
973
+ ),
974
+ selected && /* @__PURE__ */ jsx6(
975
+ "span",
976
+ {
977
+ className: classNames4(
978
+ "absolute inset-y-0 right-0 flex items-center pr-4"
979
+ ),
980
+ children: /* @__PURE__ */ jsx6(LuCheck, { className: "h-4 w-4", "aria-hidden": "true" })
981
+ }
982
+ )
983
+ ] });
984
+ },
985
+ filterFn: (option, input2) => {
986
+ const { display, value: value2 } = option;
987
+ const isRegex = /^\{.*\}$/.test(value2);
988
+ if (isRegex) {
989
+ return true;
990
+ }
991
+ return display.toLowerCase().includes(input2.toLowerCase());
992
+ },
993
+ validateFn: (option) => {
994
+ const isRegex = /^\{.*\}$/.test(option.value);
995
+ if (isRegex) {
996
+ return true;
997
+ }
998
+ return labelSelectors.some((o) => isEqual2(o, option));
999
+ },
1000
+ onFilterTextChange: setLabelSearchQuery
1001
+ }
1002
+ );
1003
+ }
1004
+ export {
1005
+ AggregateInput,
1006
+ ArgumentInput,
1007
+ ArgumentType,
1008
+ EventsFunctionCategories,
1009
+ EventsFunctionMap,
1010
+ FunctionInput,
1011
+ FunctionMap,
1012
+ FunctionsCategories,
1013
+ FunctionsPanel,
1014
+ LabelSearchProvider,
1015
+ LabelsInput,
1016
+ SystemLabels,
1017
+ isAggrOrRollupFunction,
1018
+ sortMetricByName,
1019
+ useLabelSearch,
1020
+ useLabelSearchContext
1021
+ };
1022
+ //# sourceMappingURL=index.mjs.map