@gravitee/gamma-lib-observability 4.0.3 → 4.1.0-fix-obs-53-scope-ceiling-data-source-boundary.6da6f59

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/QUERYING.md CHANGED
@@ -302,6 +302,15 @@ condition at all, because a value-less condition is dropped before the request a
302
302
  query unscoped. Only ceilings whose operator is `eq` or `in` are enforced this way. See
303
303
  `clampToScope` in `src/filters/scope-ceiling.ts`.
304
304
 
305
+ The clamp happens at the data source, not at each call site. `useMetricsDataSource`,
306
+ `useLogsDataSource` and their `useOptional*` variants return a source that clamps the top-level
307
+ `filters` of every request against the context filters before delegating to the one the host
308
+ mounted, so a component that queries the source directly, or merges a filter after its own clamp,
309
+ still cannot step outside the scope. The query hooks clamp as well, because their cache keys are
310
+ derived from the filters actually sent; clamping twice changes nothing. Per-metric `filters` are
311
+ not clamped (the server ANDs them under the top-level ones), and neither is the `apiId` passed to
312
+ `getById`. See `src/providers/clamped-data-sources.ts`.
313
+
305
314
  Within a dashboard, a definition filter is locked or re-valuable (`editable`); see
306
315
  `resolveDashboardFilters` for how a reader's URL filters are reconciled with it.
307
316
 
@@ -49,7 +49,7 @@ function g(e) {
49
49
  a
50
50
  ].every((e) => Number.isFinite(e)) ? t === void 0 && n + i > m ? "current-unmarked" : "legacy" : "unreadable";
51
51
  }
52
- function _(e) {
52
+ function ee(e) {
53
53
  switch (g(e)) {
54
54
  case "legacy": return {
55
55
  x: e.x * h,
@@ -68,10 +68,10 @@ function _(e) {
68
68
  case "unreadable": return e;
69
69
  }
70
70
  }
71
- function v(e) {
71
+ function _(e) {
72
72
  if (!e || !Array.isArray(e.widgets)) return e;
73
73
  let t = !1, n = e.widgets.map((e) => {
74
- let n = _(e.layout);
74
+ let n = ee(e.layout);
75
75
  return n === e.layout ? e : (t = !0, {
76
76
  ...e,
77
77
  layout: n
@@ -84,46 +84,46 @@ function v(e) {
84
84
  }
85
85
  //#endregion
86
86
  //#region src/data-sources/dashboard-errors.ts
87
- var y = class extends Error {
87
+ var v = class extends Error {
88
88
  status;
89
89
  constructor(e, t) {
90
90
  super(t), this.name = "DashboardPersistenceError", this.status = e;
91
91
  }
92
- }, b = class extends y {
92
+ }, y = class extends v {
93
93
  constructor(e) {
94
94
  super(403, e), this.name = "DashboardForbiddenError";
95
95
  }
96
- }, x = class extends y {
96
+ }, b = class extends v {
97
97
  dashboardId;
98
98
  constructor(e, t) {
99
99
  super(404, t), this.name = "DashboardNotFoundError", this.dashboardId = e;
100
100
  }
101
- }, S = class extends y {
101
+ }, x = class extends v {
102
102
  currentVersion;
103
103
  currentDashboard;
104
104
  constructor(e, t, n) {
105
105
  super(412, e), this.name = "DashboardConflictError", this.currentDashboard = t, this.currentVersion = n;
106
106
  }
107
107
  };
108
+ function S(e) {
109
+ return w(e) === 404;
110
+ }
108
111
  function C(e) {
109
- return T(e) === 404;
112
+ return w(e) === 403;
110
113
  }
111
114
  function w(e) {
112
- return T(e) === 403;
113
- }
114
- function T(e) {
115
- if (e instanceof y) return e.status;
115
+ if (e instanceof v) return e.status;
116
116
  if (typeof e != "object" || !e || !("status" in e)) return;
117
117
  let { status: t } = e;
118
118
  return typeof t == "number" ? t : void 0;
119
119
  }
120
120
  //#endregion
121
121
  //#region src/data-sources/with-grid-migration.ts
122
- function E(e) {
123
- let t = (e) => Promise.resolve(e).then(v, D);
122
+ function T(e) {
123
+ let t = (e) => Promise.resolve(e).then(_, E);
124
124
  return {
125
- fetchDashboard: (t, n) => Promise.resolve(e.fetchDashboard(t, n)).then(v),
126
- fetchDashboards: (t) => Promise.resolve(e.fetchDashboards(t)).then((e) => Array.isArray(e) ? e.map(v) : e),
125
+ fetchDashboard: (t, n) => Promise.resolve(e.fetchDashboard(t, n)).then(_),
126
+ fetchDashboards: (t) => Promise.resolve(e.fetchDashboards(t)).then((e) => Array.isArray(e) ? e.map(_) : e),
127
127
  createDashboard: (n, r) => t(e.createDashboard(n, r)),
128
128
  updateDashboard: (n, r, i) => t(e.updateDashboard(n, r, i)),
129
129
  deleteDashboard: (t, n) => e.deleteDashboard(t, n),
@@ -131,12 +131,12 @@ function E(e) {
131
131
  ...e.takeReadRevision && { takeReadRevision: (t) => e.takeReadRevision?.(t) }
132
132
  };
133
133
  }
134
- function D(e) {
135
- if (!(e instanceof S)) throw e;
136
- let t = v(e.currentDashboard);
137
- throw t === e.currentDashboard ? e : O(e, t);
134
+ function E(e) {
135
+ if (!(e instanceof x)) throw e;
136
+ let t = _(e.currentDashboard);
137
+ throw t === e.currentDashboard ? e : te(e, t);
138
138
  }
139
- function O(e, t) {
139
+ function te(e, t) {
140
140
  return Object.create(Object.getPrototypeOf(e), {
141
141
  ...Object.getOwnPropertyDescriptors(e),
142
142
  stack: {
@@ -155,101 +155,186 @@ function O(e, t) {
155
155
  }
156
156
  //#endregion
157
157
  //#region src/providers/dashboard-persistence-provider.tsx
158
- var k = e(null);
159
- function A({ persistence: e, children: t }) {
160
- let n = r(() => E(e), [e]);
161
- return /* @__PURE__ */ a(k.Provider, {
158
+ var D = e(null);
159
+ function ne({ persistence: e, children: t }) {
160
+ let n = r(() => T(e), [e]);
161
+ return /* @__PURE__ */ a(D.Provider, {
162
162
  value: n,
163
163
  children: t
164
164
  });
165
165
  }
166
- function j() {
167
- return n(k);
166
+ function re() {
167
+ return n(D);
168
168
  }
169
- function M() {
170
- let e = n(k);
169
+ function ie() {
170
+ let e = n(D);
171
171
  if (!e) throw Error("[gamma-lib-observability] useDashboardPersistence must be used within a <DashboardPersistenceProvider>. Wrap your component tree with <DashboardPersistenceProvider persistence={yourImpl}>.");
172
172
  return e;
173
173
  }
174
174
  //#endregion
175
+ //#region src/providers/ContextFiltersProvider.tsx
176
+ var O = e([]);
177
+ function k({ filters: e, children: t }) {
178
+ let n = r(() => e, [JSON.stringify(e)]);
179
+ return /* @__PURE__ */ a(O.Provider, {
180
+ value: n,
181
+ children: t
182
+ });
183
+ }
184
+ function A() {
185
+ return n(O);
186
+ }
187
+ //#endregion
188
+ //#region src/dashboards/merge-filters.ts
189
+ var j = new Set(["gte", "lte"]);
190
+ function M(e) {
191
+ return j.has(e.operator);
192
+ }
193
+ function N(...e) {
194
+ let t = /* @__PURE__ */ new Map();
195
+ for (let n of e) if (n) for (let [e, r] of P(n)) t.set(e, F(r));
196
+ return Array.from(t.values()).flat();
197
+ }
198
+ function P(e) {
199
+ let t = /* @__PURE__ */ new Map();
200
+ for (let n of e) t.set(n.field, [...t.get(n.field) ?? [], n]);
201
+ return t;
202
+ }
203
+ function F(e) {
204
+ return e.every(M) ? e.filter((t, n) => e.slice(n + 1).every((e) => e.operator !== t.operator)) : [e[e.length - 1]];
205
+ }
206
+ //#endregion
207
+ //#region src/filters/scope-ceiling.ts
208
+ var I = new Set(["eq", "in"]);
209
+ function L(e, t) {
210
+ let n = N(e, t), r = new Map(e.filter((e) => I.has(e.operator) && e.value.length > 0).map((e) => [e.field, e]));
211
+ if (r.size === 0) return n;
212
+ let i = /* @__PURE__ */ new Set();
213
+ return n.flatMap((e) => {
214
+ let t = r.get(e.field);
215
+ if (!t || e === t) return [e];
216
+ let n = R(e, t);
217
+ return n === t ? i.has(e.field) ? [] : (i.add(e.field), [t]) : [n];
218
+ });
219
+ }
220
+ function R(e, t) {
221
+ if (!I.has(e.operator)) return t;
222
+ let n = new Set(t.value), r = e.value.map((e, t) => n.has(e) ? t : -1).filter((e) => e >= 0);
223
+ return r.length === 0 ? t : r.length === e.value.length ? e : {
224
+ ...e,
225
+ value: r.map((t) => e.value[t]),
226
+ ...e.valueLabels ? { valueLabels: r.map((t) => e.valueLabels[t] ?? e.value[t]) } : {}
227
+ };
228
+ }
229
+ //#endregion
230
+ //#region src/providers/clamped-data-sources.ts
231
+ function z(e, t) {
232
+ return {
233
+ fetchTimeSeries: (n) => e.fetchTimeSeries({
234
+ ...n,
235
+ filters: L(t, n.filters)
236
+ }),
237
+ fetchFacets: (n) => e.fetchFacets({
238
+ ...n,
239
+ filters: L(t, n.filters)
240
+ }),
241
+ fetchMeasures: (n) => e.fetchMeasures({
242
+ ...n,
243
+ filters: L(t, n.filters)
244
+ })
245
+ };
246
+ }
247
+ function B(e, t) {
248
+ let n = e.getById;
249
+ return {
250
+ fetchLogs: (n) => e.fetchLogs({
251
+ ...n,
252
+ filters: L(t, n.filters)
253
+ }),
254
+ ...n ? { getById: (t, r, i) => n.call(e, t, r, i) } : {}
255
+ };
256
+ }
257
+ //#endregion
175
258
  //#region src/providers/logs-data-source-provider.tsx
176
- var N = e(null);
177
- function P({ dataSource: e, children: t }) {
178
- return /* @__PURE__ */ a(N.Provider, {
259
+ var V = e(null);
260
+ function H({ dataSource: e, children: t }) {
261
+ return /* @__PURE__ */ a(V.Provider, {
179
262
  value: e,
180
263
  children: t
181
264
  });
182
265
  }
183
- function F() {
184
- let e = n(N);
266
+ function U() {
267
+ let e = W();
185
268
  if (!e) throw Error("[gamma-lib-observability] useLogsDataSource must be used within a <LogsDataSourceProvider>. Wrap your component tree with <LogsDataSourceProvider dataSource={yourImpl}>.");
186
269
  return e;
187
270
  }
188
- function I() {
189
- return n(N);
271
+ function W() {
272
+ let e = n(V), t = A();
273
+ return r(() => e ? B(e, t) : null, [e, t]);
190
274
  }
191
275
  //#endregion
192
276
  //#region src/providers/metrics-data-source-provider.tsx
193
- var L = e(null);
194
- function R({ dataSource: e, children: t }) {
195
- return /* @__PURE__ */ a(L.Provider, {
277
+ var G = e(null);
278
+ function K({ dataSource: e, children: t }) {
279
+ return /* @__PURE__ */ a(G.Provider, {
196
280
  value: e,
197
281
  children: t
198
282
  });
199
283
  }
200
- function z() {
201
- let e = n(L);
284
+ function q() {
285
+ let e = J();
202
286
  if (!e) throw Error("[gamma-lib-observability] useMetricsDataSource must be used within a <MetricsDataSourceProvider>. Wrap your component tree with <MetricsDataSourceProvider dataSource={yourImpl}>.");
203
287
  return e;
204
288
  }
205
- function B() {
206
- return n(L);
289
+ function J() {
290
+ let e = n(G), t = A();
291
+ return r(() => e ? z(e, t) : null, [e, t]);
207
292
  }
208
293
  //#endregion
209
294
  //#region src/providers/traces-data-source-provider.tsx
210
- var V = e(null);
211
- function H({ dataSource: e, children: t }) {
212
- return /* @__PURE__ */ a(V.Provider, {
295
+ var Y = e(null);
296
+ function ae({ dataSource: e, children: t }) {
297
+ return /* @__PURE__ */ a(Y.Provider, {
213
298
  value: e,
214
299
  children: t
215
300
  });
216
301
  }
217
- function U() {
218
- let e = n(V);
302
+ function oe() {
303
+ let e = n(Y);
219
304
  if (!e) throw Error("[gamma-lib-observability] useTracesDataSource must be used within a <TracesDataSourceProvider>. Wrap your component tree with <TracesDataSourceProvider dataSource={yourImpl}>.");
220
305
  return e;
221
306
  }
222
- function W() {
223
- return n(V);
307
+ function se() {
308
+ return n(Y);
224
309
  }
225
310
  //#endregion
226
311
  //#region src/filters/filter-providers-context.tsx
227
- var G = e(null);
228
- function K({ providers: e, children: t }) {
312
+ var X = e(null);
313
+ function ce({ providers: e, children: t }) {
229
314
  let n = r(() => e, [e]);
230
- return /* @__PURE__ */ a(G.Provider, {
315
+ return /* @__PURE__ */ a(X.Provider, {
231
316
  value: n,
232
317
  children: t
233
318
  });
234
319
  }
235
- function q() {
236
- let e = n(G);
320
+ function Z() {
321
+ let e = n(X);
237
322
  if (!e) throw Error("[gamma-lib-observability] useFilterProviders must be used within a <FilterProvidersProvider>. Wrap your component tree with <FilterProvidersProvider providers={[...]}>.");
238
323
  return e;
239
324
  }
240
- function J(e) {
241
- let t = q();
325
+ function le(e) {
326
+ let t = Z();
242
327
  if (e) return t.find((t) => t.field === e);
243
328
  }
244
329
  //#endregion
245
330
  //#region src/providers/dashboard-access-provider.tsx
246
- var Y = e({
331
+ var Q = e({
247
332
  readRefused: !1,
248
333
  writeRefused: !1,
249
334
  reportRefused: () => {},
250
335
  reportGranted: () => {}
251
336
  });
252
- function X({ children: e }) {
337
+ function $({ children: e }) {
253
338
  let [n, o] = i({
254
339
  read: !1,
255
340
  write: !1
@@ -274,13 +359,13 @@ function X({ children: e }) {
274
359
  s,
275
360
  c
276
361
  ]);
277
- return /* @__PURE__ */ a(Y.Provider, {
362
+ return /* @__PURE__ */ a(Q.Provider, {
278
363
  value: l,
279
364
  children: e
280
365
  });
281
366
  }
282
- function Z() {
283
- return n(Y);
367
+ function ue() {
368
+ return n(Q);
284
369
  }
285
370
  //#endregion
286
- export { s as A, C, l as D, v as E, u as O, w as S, p as T, j as _, q as a, x as b, U as c, B as d, P as f, M as g, A as h, J as i, o as j, d as k, R as l, I as m, Z as n, H as o, F as p, K as r, W as s, X as t, z as u, S as v, f as w, y as x, b as y };
371
+ export { p as A, x as C, C as D, v as E, s as F, o as I, l as M, u as N, S as O, d as P, re as S, b as T, N as _, Z as a, ne as b, oe as c, J as d, H as f, M as g, L as h, le as i, _ as j, f as k, K as l, W as m, ue as n, ae as o, U as p, ce as r, se as s, $ as t, q as u, k as v, y as w, ie as x, A as y };
@@ -1 +1 @@
1
- {"version":3,"file":"WidgetConfigForm.d.ts","sourceRoot":"","sources":["../../../src/dashboards/editor/WidgetConfigForm.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAKV,MAAM,EAEP,MAAM,oBAAoB,CAAC;AAiB5B,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAYD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,qBAAqB,2CAqE3E"}
1
+ {"version":3,"file":"WidgetConfigForm.d.ts","sourceRoot":"","sources":["../../../src/dashboards/editor/WidgetConfigForm.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAKV,MAAM,EAEP,MAAM,oBAAoB,CAAC;AAiB5B,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C;AAYD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,qBAAqB,2CAsE3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-json.d.ts","sourceRoot":"","sources":["../../../src/dashboards/editor/dashboard-json.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAY1F,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAO/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAoC1E"}
1
+ {"version":3,"file":"dashboard-json.d.ts","sourceRoot":"","sources":["../../../src/dashboards/editor/dashboard-json.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,SAAS,EAKf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAY1F,MAAM,MAAM,wBAAwB,GAChC;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GAC/D;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAE/D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAO/D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB,CAoC1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"CartesianWidgetRenderer.d.ts","sourceRoot":"","sources":["../../../src/dashboards/renderers/CartesianWidgetRenderer.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAQ5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGvE,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,SAAS,EACT,OAAO,EACP,eAAe,GAChB,EAAE,mBAAmB,CAAC,eAAe,CAAC,2CAuHtC"}
1
+ {"version":3,"file":"CartesianWidgetRenderer.d.ts","sourceRoot":"","sources":["../../../src/dashboards/renderers/CartesianWidgetRenderer.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAoB,MAAM,oBAAoB,CAAC;AAQ5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAGvE,wBAAgB,uBAAuB,CAAC,EACtC,MAAM,EACN,SAAS,EACT,OAAO,EACP,eAAe,GAChB,EAAE,mBAAmB,CAAC,eAAe,CAAC,2CAwHtC"}
@@ -1 +1 @@
1
- {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/filters/FilterBar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASvD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAcD,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,eAAe,EACf,QAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,SAAS,GACV,EAAE,cAAc,2CA+KhB"}
1
+ {"version":3,"file":"FilterBar.d.ts","sourceRoot":"","sources":["../../src/filters/FilterBar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAUvD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,eAAe,EAAE,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAClC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAsBD,wBAAgB,SAAS,CAAC,EACxB,OAAO,EACP,eAAe,EACf,QAAe,EACf,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,YAAY,EACZ,SAAS,GACV,EAAE,cAAc,2CA4MhB"}
@@ -2,6 +2,11 @@ import { ReactNode } from 'react';
2
2
  import { FilterCondition } from '../types/domain';
3
3
  export interface FilterChipProps {
4
4
  readonly condition: FilterCondition;
5
+ /**
6
+ * The upper bound when the chip shows a range: `condition` is then the lower
7
+ * bound (`gte`) and this one the `lte`, rendered together as `10 – 40`.
8
+ */
9
+ readonly upperBound?: FilterCondition;
5
10
  readonly onEdit?: () => void;
6
11
  readonly onRemove?: () => void;
7
12
  readonly editable?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"FilterChip.d.ts","sourceRoot":"","sources":["../../src/filters/FilterChip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACxG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAKvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAWD,eAAO,MAAM,UAAU,wGAyItB,CAAC"}
1
+ {"version":3,"file":"FilterChip.d.ts","sourceRoot":"","sources":["../../src/filters/FilterChip.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAmE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACxG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAUvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAWD,eAAO,MAAM,UAAU,wGA8ItB,CAAC"}
@@ -40,6 +40,17 @@ export interface FilterPopoverFormProps {
40
40
  * the pair would match nothing.
41
41
  */
42
42
  readonly otherConditions?: readonly FilterCondition[];
43
+ /**
44
+ * Offers a "Between" operator on fields that accept both `≥` and `≤`, and
45
+ * receives what it produces: the `gte` and `lte` bounds, or just one of them
46
+ * for an open range. Without it the form edits one condition, as before.
47
+ */
48
+ readonly onApplyRange?: (bounds: FilterCondition[]) => void;
49
+ /** The range being edited, when the chip that opened the form shows one. */
50
+ readonly existingRange?: {
51
+ readonly lower: FilterCondition;
52
+ readonly upper: FilterCondition;
53
+ };
43
54
  }
44
- export declare function FilterPopoverForm({ existingCondition, onApply, onCancel, providers: providersProp, activeApiTypes, allowEmptyValue, footer, onRemove, otherConditions, }: FilterPopoverFormProps): import("react/jsx-runtime").JSX.Element;
55
+ export declare function FilterPopoverForm({ existingCondition, onApply, onCancel, providers: providersProp, activeApiTypes, allowEmptyValue, footer, onRemove, otherConditions, onApplyRange, existingRange, }: FilterPopoverFormProps): import("react/jsx-runtime").JSX.Element;
45
56
  //# sourceMappingURL=FilterPopoverForm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FilterPopoverForm.d.ts","sourceRoot":"","sources":["../../src/filters/FilterPopoverForm.tsx"],"names":[],"mappings":"AAUA,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAGvE,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAY3E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,KAAK,SAAS,CAAC;IAClE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;CACvD;AAED,wBAAgB,iBAAiB,CAAC,EAChC,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,SAAS,EAAE,aAAa,EACxB,cAAc,EACd,eAAuB,EACvB,MAAM,EACN,QAAQ,EACR,eAAe,GAChB,EAAE,sBAAsB,2CAuMxB"}
1
+ {"version":3,"file":"FilterPopoverForm.d.ts","sourceRoot":"","sources":["../../src/filters/FilterPopoverForm.tsx"],"names":[],"mappings":"AAWA,OAAO,EAAwD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,iBAAiB,CAAC;AAGvE,OAAO,KAAK,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AAY3E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAC;IAC7C,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,gGAAgG;IAChG,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;OAGG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,YAAY,EAAE,OAAO,CAAA;KAAE,KAAK,SAAS,CAAC;IAClE;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,eAAe,EAAE,CAAC;IACtD;;;;OAIG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,EAAE,KAAK,IAAI,CAAC;IAC5D,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAA;KAAE,CAAC;CAC/F;AAKD,wBAAgB,iBAAiB,CAAC,EAChC,iBAAiB,EACjB,OAAO,EACP,QAAQ,EACR,SAAS,EAAE,aAAa,EACxB,cAAc,EACd,eAAuB,EACvB,MAAM,EACN,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,aAAa,GACd,EAAE,sBAAsB,2CAyRxB"}
@@ -9,4 +9,7 @@ export interface ChipLabelParts {
9
9
  }
10
10
  export declare function buildChipLabelParts(condition: FilterCondition): ChipLabelParts;
11
11
  export declare function buildChipTooltip(condition: FilterCondition): string;
12
+ /** A range chip shows its two bounds as one span: `Response time 10 – 40`. */
13
+ export declare function buildRangeChipLabelParts(lower: FilterCondition, upper: FilterCondition): ChipLabelParts;
14
+ export declare function buildRangeChipTooltip(lower: FilterCondition, upper: FilterCondition): string;
12
15
  //# sourceMappingURL=filter-display.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filter-display.d.ts","sourceRoot":"","sources":["../../../src/filters/utils/filter-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,oBAAoB,CAAC;AAG1E,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7F;AAyBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAKjE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,cAAc,CAc9E;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAQnE"}
1
+ {"version":3,"file":"filter-display.d.ts","sourceRoot":"","sources":["../../../src/filters/utils/filter-display.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,oBAAoB,CAAC;AAG1E,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7F;AAyBD,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAKjE;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,cAAc,CAc9E;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,eAAe,GAAG,MAAM,CAQnE;AAED,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,cAAc,CAOvG;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM,CAE5F"}
@@ -29,4 +29,16 @@ export declare function resolveFilterAddition(filters: readonly FilterCondition[
29
29
  * neighbours are removed the same way an addition removes them.
30
30
  */
31
31
  export declare function resolveFilterEdit(filters: readonly FilterCondition[], index: number, edited: FilterCondition): FilterCondition[];
32
+ /**
33
+ * Resolves the full filter list after a range is applied from the filter form.
34
+ * A range states the whole constraint on its field, so it replaces every
35
+ * condition on that field, open sides included: a range with no maximum drops
36
+ * an earlier `lte`.
37
+ *
38
+ * `edited` are the indexes of the chip being edited (one condition, or both
39
+ * bounds of a range chip). They are removed even when the field changed, and
40
+ * the range takes their place; without them it takes the place of the field's
41
+ * first condition, or is appended.
42
+ */
43
+ export declare function resolveRangeApplication(filters: readonly FilterCondition[], bounds: readonly FilterCondition[], edited?: readonly number[]): FilterCondition[];
32
44
  //# sourceMappingURL=merge-conditions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merge-conditions.d.ts","sourceRoot":"","sources":["../../../src/filters/utils/merge-conditions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAczD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,OAAO,CAKtF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,cAAc,GACvB,eAAe,GAAG,IAAI,CAiCxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,cAAc,GAAG,SAAS,GACnC,eAAe,EAAE,CAcnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,eAAe,GACtB,eAAe,EAAE,CAEnB"}
1
+ {"version":3,"file":"merge-conditions.d.ts","sourceRoot":"","sources":["../../../src/filters/utils/merge-conditions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAczD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,OAAO,CAKtF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,cAAc,GACvB,eAAe,GAAG,IAAI,CAiCxB;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,cAAc,GAAG,SAAS,GACnC,eAAe,EAAE,CAcnB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,eAAe,GACtB,eAAe,EAAE,CAEnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,MAAM,GAAE,SAAS,MAAM,EAAO,GAC7B,eAAe,EAAE,CAUnB"}
@@ -0,0 +1,24 @@
1
+ import { FilterCondition } from '../../types/domain';
2
+ /** One chip of the filter bar: a single condition, or the two bounds of a range shown together. */
3
+ export type FilterBarItem = {
4
+ readonly kind: 'single';
5
+ readonly indexes: readonly [number];
6
+ readonly condition: FilterCondition;
7
+ } | {
8
+ readonly kind: 'range';
9
+ readonly indexes: readonly [number, number];
10
+ readonly lower: FilterCondition;
11
+ readonly upper: FilterCondition;
12
+ };
13
+ /**
14
+ * Groups a field holding exactly one `gte` and one `lte`, and nothing else,
15
+ * into one range chip placed where its first bound stands. The conditions are
16
+ * not changed: the range is a way of showing them, and the URL, the saved
17
+ * dashboard and the request still carry the two bounds.
18
+ *
19
+ * A field with any other mix (a single bound, or a bound beside an exact
20
+ * value) keeps one chip per condition, so nothing is hidden inside a chip that
21
+ * does not describe it.
22
+ */
23
+ export declare function groupRangeChips(filters: readonly FilterCondition[]): FilterBarItem[];
24
+ //# sourceMappingURL=range-chips.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-chips.d.ts","sourceRoot":"","sources":["../../../src/filters/utils/range-chips.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,mGAAmG;AACnG,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAA;CAAE,GACrG;IACE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;IAChC,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC;CACjC,CAAC;AAEN;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,GAAG,aAAa,EAAE,CAuBpF"}