@quillsql/react 2.16.49 → 2.16.50

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.cjs CHANGED
@@ -33,6 +33,89 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
33
  ));
34
34
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
35
 
36
+ // src/utils/textProcessing.ts
37
+ function capitalize(text) {
38
+ return text.charAt(0).toUpperCase() + text.slice(1);
39
+ }
40
+ function matchCasing(text, template) {
41
+ if (!text || !template) {
42
+ return text ?? "";
43
+ }
44
+ const isTitleCase = (str) => /^[A-Z][a-z]*([A-Z][a-z]*)*$/.test(str);
45
+ const isCamelCase = (str) => /^[a-z]+([A-Z][a-z]*)*$/.test(str);
46
+ const isSnakeCase = (str) => /^[a-z0-9]+(_[a-z0-9]+)*$/.test(str);
47
+ const isAllLowerCase = (str) => /^[a-z]+$/.test(str);
48
+ const isAllUpperCase = (str) => /^[A-Z]+$/.test(str);
49
+ const isCapitalized = (str) => /^[A-Z][a-z]*$/.test(str);
50
+ const isScreamingSnakeCase = (str) => /^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$/.test(str);
51
+ const toTitleCase = (str) => str.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
52
+ const toCamelCase = (str) => str.replace(/_./g, (match) => match.charAt(1).toUpperCase()).toLowerCase();
53
+ const toSnakeCase = (str) => str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
54
+ const toLowerCase = (str) => str.toLowerCase();
55
+ const toUpperCase = (str) => str.toUpperCase();
56
+ const toCapitalized = (str) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
57
+ const toScreamingSnakeCase = (str) => str.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toUpperCase();
58
+ if (isTitleCase(template)) {
59
+ return toTitleCase(text);
60
+ } else if (isCamelCase(template)) {
61
+ return toCamelCase(text);
62
+ } else if (isSnakeCase(template)) {
63
+ return toSnakeCase(text);
64
+ } else if (isAllLowerCase(template)) {
65
+ return toLowerCase(text);
66
+ } else if (isAllUpperCase(template)) {
67
+ return toUpperCase(text);
68
+ } else if (isCapitalized(template)) {
69
+ return toCapitalized(text);
70
+ } else if (isScreamingSnakeCase(template)) {
71
+ return toScreamingSnakeCase(text);
72
+ } else {
73
+ return text;
74
+ }
75
+ }
76
+ function snakeCaseToTitleCase(str) {
77
+ if (!str) {
78
+ return str;
79
+ }
80
+ return str.toString().split(/_| /).map(
81
+ (word) => word === "id" ? "ID" : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
82
+ ).join(" ");
83
+ }
84
+ function snakeAndCamelCaseToTitleCase(str) {
85
+ if (!str || typeof str !== "string") {
86
+ return str;
87
+ }
88
+ if (str.includes("_")) {
89
+ return str.split(/_| /).map((word) => word === "id" ? "ID" : capitalize(word)).join(" ");
90
+ } else {
91
+ const text = str.replace(/([a-z])([A-Z])/g, "$1 $2");
92
+ const newText = text.split(" ").map((word) => word === "Id" || word === "id" ? "ID" : capitalize(word)).join(" ");
93
+ return newText;
94
+ }
95
+ }
96
+ function formatIdentifierLabel(str) {
97
+ if (!str || typeof str !== "string") {
98
+ return str;
99
+ }
100
+ const hasUnderscore = str.includes("_");
101
+ const hasCamelCaseBoundary = /[a-z0-9][A-Z]/.test(str);
102
+ if (hasUnderscore || hasCamelCaseBoundary) {
103
+ return snakeAndCamelCaseToTitleCase(str);
104
+ }
105
+ return str;
106
+ }
107
+ function removeDoubleQuotes(str) {
108
+ if (!str) {
109
+ return str;
110
+ }
111
+ return str.replace(/"/g, "");
112
+ }
113
+ var init_textProcessing = __esm({
114
+ "src/utils/textProcessing.ts"() {
115
+ "use strict";
116
+ }
117
+ });
118
+
36
119
  // src/utils/valueFormatter.ts
37
120
  function parseNumber(value) {
38
121
  if (typeof value === "number") return value;
@@ -59,6 +142,7 @@ var init_valueFormatter = __esm({
59
142
  "use strict";
60
143
  import_date_fns = require("date-fns");
61
144
  import_date_fns_tz = require("date-fns-tz");
145
+ init_textProcessing();
62
146
  DATE_FORMAT_TYPES = [
63
147
  "yyyy",
64
148
  "MMM_yyyy",
@@ -221,7 +305,7 @@ var init_valueFormatter = __esm({
221
305
  if (typeof value === "object") {
222
306
  return JSON.stringify(value);
223
307
  }
224
- return value.toString();
308
+ return formatIdentifierLabel(value.toString());
225
309
  };
226
310
  formatterDollar = new Intl.NumberFormat("en-US", {
227
311
  style: "currency",
@@ -494,78 +578,6 @@ var init_ast = __esm({
494
578
  }
495
579
  });
496
580
 
497
- // src/utils/textProcessing.ts
498
- function capitalize(text) {
499
- return text.charAt(0).toUpperCase() + text.slice(1);
500
- }
501
- function matchCasing(text, template) {
502
- if (!text || !template) {
503
- return text ?? "";
504
- }
505
- const isTitleCase = (str) => /^[A-Z][a-z]*([A-Z][a-z]*)*$/.test(str);
506
- const isCamelCase = (str) => /^[a-z]+([A-Z][a-z]*)*$/.test(str);
507
- const isSnakeCase = (str) => /^[a-z0-9]+(_[a-z0-9]+)*$/.test(str);
508
- const isAllLowerCase = (str) => /^[a-z]+$/.test(str);
509
- const isAllUpperCase = (str) => /^[A-Z]+$/.test(str);
510
- const isCapitalized = (str) => /^[A-Z][a-z]*$/.test(str);
511
- const isScreamingSnakeCase = (str) => /^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$/.test(str);
512
- const toTitleCase = (str) => str.toLowerCase().replace(/\b\w/g, (char) => char.toUpperCase());
513
- const toCamelCase = (str) => str.replace(/_./g, (match) => match.charAt(1).toUpperCase()).toLowerCase();
514
- const toSnakeCase = (str) => str.replace(/[A-Z]/g, (match) => `_${match.toLowerCase()}`);
515
- const toLowerCase = (str) => str.toLowerCase();
516
- const toUpperCase = (str) => str.toUpperCase();
517
- const toCapitalized = (str) => str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
518
- const toScreamingSnakeCase = (str) => str.replace(/([A-Z])/g, "_$1").replace(/^_/, "").toUpperCase();
519
- if (isTitleCase(template)) {
520
- return toTitleCase(text);
521
- } else if (isCamelCase(template)) {
522
- return toCamelCase(text);
523
- } else if (isSnakeCase(template)) {
524
- return toSnakeCase(text);
525
- } else if (isAllLowerCase(template)) {
526
- return toLowerCase(text);
527
- } else if (isAllUpperCase(template)) {
528
- return toUpperCase(text);
529
- } else if (isCapitalized(template)) {
530
- return toCapitalized(text);
531
- } else if (isScreamingSnakeCase(template)) {
532
- return toScreamingSnakeCase(text);
533
- } else {
534
- return text;
535
- }
536
- }
537
- function snakeCaseToTitleCase(str) {
538
- if (!str) {
539
- return str;
540
- }
541
- return str.toString().split(/_| /).map(
542
- (word) => word === "id" ? "ID" : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
543
- ).join(" ");
544
- }
545
- function snakeAndCamelCaseToTitleCase(str) {
546
- if (!str || typeof str !== "string") {
547
- return str;
548
- }
549
- if (str.includes("_")) {
550
- return str.split(/_| /).map((word) => word === "id" ? "ID" : capitalize(word)).join(" ");
551
- } else {
552
- const text = str.replace(/([a-z])([A-Z])/g, "$1 $2");
553
- const newText = text.split(" ").map((word) => word === "Id" || word === "id" ? "ID" : capitalize(word)).join(" ");
554
- return newText;
555
- }
556
- }
557
- function removeDoubleQuotes(str) {
558
- if (!str) {
559
- return str;
560
- }
561
- return str.replace(/"/g, "");
562
- }
563
- var init_textProcessing = __esm({
564
- "src/utils/textProcessing.ts"() {
565
- "use strict";
566
- }
567
- });
568
-
569
581
  // src/components/ReportBuilder/bigDateMap.ts
570
582
  function cleanDateFieldName(fieldName) {
571
583
  if (!fieldName) return void 0;
@@ -15085,6 +15097,63 @@ function getDateString(value, dateRange, dateBucket, databaseType) {
15085
15097
  function isDateField(fieldType) {
15086
15098
  return fieldType === "date" || fieldType === "datetime" || fieldType === "timestamp" || fieldType === "timestamptz" || fieldType === "yyyy" || fieldType === "MMM_yyyy" || fieldType === "MMM_dd" || fieldType === "MMM_dd_yyyy" || fieldType === "MMM_dd_hh:mm_ap_pm" || fieldType === "hh_ap_pm";
15087
15099
  }
15100
+ function getExclusiveDateBucketRange(startInput, bucket) {
15101
+ const parsed = startInput instanceof Date ? startInput : new Date(startInput);
15102
+ if (Number.isNaN(parsed.getTime())) {
15103
+ throw new Error(`Invalid bucket start date: ${String(startInput)}`);
15104
+ }
15105
+ let start;
15106
+ let endExclusive;
15107
+ switch (bucket) {
15108
+ case "day": {
15109
+ start = new Date(
15110
+ Date.UTC(
15111
+ parsed.getUTCFullYear(),
15112
+ parsed.getUTCMonth(),
15113
+ parsed.getUTCDate()
15114
+ )
15115
+ );
15116
+ endExclusive = new Date(start);
15117
+ endExclusive.setUTCDate(endExclusive.getUTCDate() + 1);
15118
+ break;
15119
+ }
15120
+ case "week": {
15121
+ const day = parsed.getUTCDay();
15122
+ start = new Date(
15123
+ Date.UTC(
15124
+ parsed.getUTCFullYear(),
15125
+ parsed.getUTCMonth(),
15126
+ parsed.getUTCDate() - (day + 6) % 7
15127
+ )
15128
+ );
15129
+ endExclusive = new Date(start);
15130
+ endExclusive.setUTCDate(endExclusive.getUTCDate() + 7);
15131
+ break;
15132
+ }
15133
+ case "month": {
15134
+ start = new Date(
15135
+ Date.UTC(parsed.getUTCFullYear(), parsed.getUTCMonth(), 1)
15136
+ );
15137
+ endExclusive = new Date(
15138
+ Date.UTC(parsed.getUTCFullYear(), parsed.getUTCMonth() + 1, 1)
15139
+ );
15140
+ break;
15141
+ }
15142
+ case "year": {
15143
+ start = new Date(Date.UTC(parsed.getUTCFullYear(), 0, 1));
15144
+ endExclusive = new Date(Date.UTC(parsed.getUTCFullYear() + 1, 0, 1));
15145
+ break;
15146
+ }
15147
+ default: {
15148
+ const _exhaustive = bucket;
15149
+ throw new Error(`Unsupported date bucket: ${String(_exhaustive)}`);
15150
+ }
15151
+ }
15152
+ return {
15153
+ start: start.toISOString(),
15154
+ endExclusive: endExclusive.toISOString()
15155
+ };
15156
+ }
15088
15157
  var import_date_fns5;
15089
15158
  var init_dates = __esm({
15090
15159
  "src/utils/dates.ts"() {
@@ -17206,7 +17275,7 @@ async function generatePivotWithSQL({
17206
17275
  client,
17207
17276
  task: "pivot-template",
17208
17277
  metadata: {
17209
- clientId: client.clientId,
17278
+ clientId: client.id,
17210
17279
  pivot: pivotConfig,
17211
17280
  reportId: report?.id !== "__quillTempReport" ? report?.id : void 0,
17212
17281
  itemQuery: reportBuilderState ? void 0 : report?.queryString,
@@ -19032,7 +19101,7 @@ var init_tableProcessing = __esm({
19032
19101
  metadata: {
19033
19102
  reportBuilderState,
19034
19103
  stringColumns: stringColumns.map((col) => col.field),
19035
- clientId: client.clientId,
19104
+ clientId: client.id,
19036
19105
  databaseType: client.databaseType?.toLowerCase() || "postgresql",
19037
19106
  customFields,
19038
19107
  filters: void 0,
@@ -19223,7 +19292,7 @@ var init_tableProcessing = __esm({
19223
19292
  metadata: {
19224
19293
  reportBuilderState,
19225
19294
  columns: stringNames,
19226
- clientId: client.publicKey,
19295
+ clientId: client.id,
19227
19296
  databaseType: client.databaseType,
19228
19297
  customFieldsByTable: customFields,
19229
19298
  useNewNodeSql: true,
@@ -19238,7 +19307,7 @@ var init_tableProcessing = __esm({
19238
19307
  task: "query",
19239
19308
  metadata: {
19240
19309
  query: countQuery,
19241
- clientId: client.publicKey,
19310
+ clientId: client.id,
19242
19311
  databaseType: client.databaseType,
19243
19312
  customFieldsByTable: customFields,
19244
19313
  useNewNodeSql: true,
@@ -19298,7 +19367,7 @@ var init_tableProcessing = __esm({
19298
19367
  metadata: {
19299
19368
  reportBuilderState,
19300
19369
  stringColumns: columns,
19301
- clientId: client.clientId,
19370
+ clientId: client.id,
19302
19371
  databaseType: client.databaseType?.toLowerCase() || "postgresql",
19303
19372
  customFields,
19304
19373
  filters,
@@ -19348,7 +19417,7 @@ var init_tableProcessing = __esm({
19348
19417
  task: "query",
19349
19418
  metadata: {
19350
19419
  query,
19351
- clientId: client.publicKey,
19420
+ clientId: client.id,
19352
19421
  databaseType: client.databaseType,
19353
19422
  customFieldsByTable: customFields,
19354
19423
  useNewNodeSql: true,
@@ -19460,7 +19529,7 @@ var init_tableProcessing = __esm({
19460
19529
  task: "query",
19461
19530
  metadata: {
19462
19531
  query,
19463
- clientId: client.publicKey,
19532
+ clientId: client.id,
19464
19533
  databaseType: client.databaseType,
19465
19534
  customFieldsByTable: customFields,
19466
19535
  useNewNodeSql: true,
@@ -19589,7 +19658,7 @@ var init_tableProcessing = __esm({
19589
19658
  metadata: {
19590
19659
  query,
19591
19660
  filterMap,
19592
- clientId: client.publicKey,
19661
+ clientId: client.id,
19593
19662
  databaseType: client?.databaseType,
19594
19663
  customFieldsByTable: customFields,
19595
19664
  additionalProcessing: processing,
@@ -19624,7 +19693,7 @@ var init_tableProcessing = __esm({
19624
19693
  task: "log-broken-query",
19625
19694
  metadata: {
19626
19695
  query,
19627
- clientId: client.clientId,
19696
+ clientId: client.id,
19628
19697
  error: parsingError
19629
19698
  },
19630
19699
  getToken
@@ -19735,7 +19804,7 @@ var init_tableProcessing = __esm({
19735
19804
  metadata: {
19736
19805
  dashboardItemId: reportId,
19737
19806
  filters: minimalFilters,
19738
- clientId: client?.publicKey,
19807
+ clientId: client?.id,
19739
19808
  databaseType: client?.databaseType,
19740
19809
  additionalProcessing: updatedProcessing,
19741
19810
  forcePagination: true,
@@ -19808,7 +19877,7 @@ var init_tableProcessing = __esm({
19808
19877
  rowCountOnly,
19809
19878
  customFields,
19810
19879
  tenants,
19811
- clientId: client.clientId,
19880
+ clientId: client.id,
19812
19881
  databaseType: client.databaseType?.toLowerCase() || "postgresql",
19813
19882
  dashboardName,
19814
19883
  ...reportId ? {
@@ -19979,7 +20048,7 @@ async function testSqlViewState(client, referencedTables, getToken) {
19979
20048
  task: "test-view",
19980
20049
  metadata: {
19981
20050
  tables: [table],
19982
- clientId: client.clientId
20051
+ clientId: client.id
19983
20052
  },
19984
20053
  getToken
19985
20054
  });
@@ -19988,7 +20057,7 @@ async function testSqlViewState(client, referencedTables, getToken) {
19988
20057
  metadata: {
19989
20058
  table,
19990
20059
  task: "set-broken-view",
19991
- clientId: client.clientId
20060
+ clientId: client.id
19992
20061
  }
19993
20062
  };
19994
20063
  quillFetch({
@@ -20098,7 +20167,7 @@ async function* quillStream({
20098
20167
  body: JSON.stringify({
20099
20168
  metadata: {
20100
20169
  task,
20101
- clientId: client.clientId,
20170
+ clientId: client.id,
20102
20171
  ...metadata
20103
20172
  }
20104
20173
  }),
@@ -20327,7 +20396,7 @@ async function getData(client, cloudQueryEndpoint, noCred, hostedRequestBody, cl
20327
20396
  body: method === "POST" ? JSON.stringify({
20328
20397
  ...cloudRequestBody,
20329
20398
  ...{
20330
- publicKey: client?.publicKey
20399
+ publicKey: client?.id
20331
20400
  }
20332
20401
  }) : null,
20333
20402
  signal: abortSignal
@@ -20356,7 +20425,7 @@ async function fetchSqlQuery(ast, client, getToken, formData) {
20356
20425
  client,
20357
20426
  task: "sqlify",
20358
20427
  metadata: {
20359
- clientId: client.clientId,
20428
+ clientId: client.id,
20360
20429
  useNewNodeSql: true,
20361
20430
  ast: { ...ast, where }
20362
20431
  },
@@ -20377,7 +20446,7 @@ async function fetchSqlQueryFromState(reportBuilderState, client, getToken, data
20377
20446
  client,
20378
20447
  task: "sqlify",
20379
20448
  metadata: {
20380
- clientId: client.clientId,
20449
+ clientId: client.id,
20381
20450
  useNewNodeSql: true,
20382
20451
  ast
20383
20452
  },
@@ -20394,7 +20463,7 @@ async function fetchQueryDateRangesFromState(reportBuilderState, columns, client
20394
20463
  client,
20395
20464
  task: "report-builder-date-ranges",
20396
20465
  metadata: {
20397
- clientId: client.clientId,
20466
+ clientId: client.id,
20398
20467
  reportBuilderState,
20399
20468
  dateColumns: columns,
20400
20469
  databaseType: databaseType || "postgresql",
@@ -20512,7 +20581,7 @@ var init_dataFetcher = __esm({
20512
20581
  body: JSON.stringify({
20513
20582
  metadata: {
20514
20583
  task,
20515
- clientId: client.clientId,
20584
+ clientId: client.id ?? client.clientId,
20516
20585
  ...metadata
20517
20586
  }
20518
20587
  }),
@@ -21030,6 +21099,7 @@ __export(index_exports, {
21030
21099
  isQueryBuilderDisplayRule: () => isQueryBuilderDisplayRule,
21031
21100
  normalizeRelativeDateRules: () => normalizeRelativeDateRules,
21032
21101
  prepareQueryBuilderFiltersForSet: () => prepareQueryBuilderFiltersForSet,
21102
+ queryBuilderFiltersForEditor: () => queryBuilderFiltersForEditor,
21033
21103
  quillFetch: () => quillFetch,
21034
21104
  stripQueryBuilderTransientFields: () => stripQueryBuilderTransientFields,
21035
21105
  tableColumnFormatFromUiSelection: () => tableColumnFormatFromUiSelection,
@@ -21530,7 +21600,7 @@ async function getDashboard(dashboardName, client, getToken, tenants, flags) {
21530
21600
  task: "dashboard",
21531
21601
  metadata: {
21532
21602
  name: dashboardName,
21533
- clientId: client.publicKey,
21603
+ clientId: client.id,
21534
21604
  databaseType: client.databaseType,
21535
21605
  useNewNodeSql: true,
21536
21606
  tenants,
@@ -21905,7 +21975,7 @@ function createPivotTemplateMetadata({
21905
21975
  reportId,
21906
21976
  dashboardItemId: reportId,
21907
21977
  ...draftSessionId ? { draftSessionId: String(draftSessionId).trim() } : {},
21908
- clientId: client.publicKey,
21978
+ clientId: client.id,
21909
21979
  databaseType: client.databaseType,
21910
21980
  filters: removeFilterOptions(filters),
21911
21981
  additionalProcessing: normalizedAdditionalProcessing,
@@ -22222,7 +22292,7 @@ async function fetchReportRows({
22222
22292
  task: "report",
22223
22293
  metadata: {
22224
22294
  reportId,
22225
- clientId: client.publicKey,
22295
+ clientId: client.id,
22226
22296
  databaseType: client.databaseType,
22227
22297
  filters: filters.map((filter) => ({ ...filter, options: void 0 })),
22228
22298
  useNewNodeSql: true,
@@ -22292,7 +22362,7 @@ async function fetchReport({
22292
22362
  reportId,
22293
22363
  dashboardItemId: reportId,
22294
22364
  ...draftSessionId ? { draftSessionId: String(draftSessionId).trim() } : {},
22295
- clientId: client.publicKey,
22365
+ clientId: client.id,
22296
22366
  databaseType: client.databaseType,
22297
22367
  filters: filters.map((filter) => ({ ...filter, options: void 0 })),
22298
22368
  customFields,
@@ -22429,7 +22499,7 @@ async function fetchReportName({
22429
22499
  task: "report-name",
22430
22500
  metadata: {
22431
22501
  reportId,
22432
- clientId: client.publicKey,
22502
+ clientId: client.id,
22433
22503
  databaseType: client.databaseType,
22434
22504
  tenants
22435
22505
  },
@@ -22453,7 +22523,7 @@ async function fetchReportRowCount(reportId, client, getToken, tenants, flags, u
22453
22523
  metadata: {
22454
22524
  reportId,
22455
22525
  dashboardItemId: reportId,
22456
- clientId: client.publicKey,
22526
+ clientId: client.id,
22457
22527
  databaseType: client.databaseType,
22458
22528
  filters: filters.map((filter) => ({ ...filter, options: void 0 })),
22459
22529
  customFields,
@@ -22483,7 +22553,7 @@ async function saveReport({
22483
22553
  tenants,
22484
22554
  draftSessionId
22485
22555
  }) {
22486
- const { publicKey, databaseType } = client;
22556
+ const { id, databaseType } = client;
22487
22557
  const {
22488
22558
  reportBuilderState,
22489
22559
  queryString,
@@ -22523,7 +22593,7 @@ async function saveReport({
22523
22593
  ...dashboardItemId ? { reportId: dashboardItemId } : {},
22524
22594
  ...draftSessionId ? { draftSessionId: String(draftSessionId).trim() } : {},
22525
22595
  // Remove useNewNodeSql since backend will handle conversion
22526
- clientId: publicKey,
22596
+ clientId: id,
22527
22597
  tenants,
22528
22598
  // Only include adminMode for 'create' task, not 'create-report'
22529
22599
  ...isCreateTask && { adminMode },
@@ -23337,7 +23407,6 @@ var getSchemaInfo = async ({
23337
23407
  getToken,
23338
23408
  eventTracking
23339
23409
  }) => {
23340
- const { publicKey } = client;
23341
23410
  let customFieldsByTableUnique = null;
23342
23411
  if (client.featureFlags?.customFieldsEnabled && tenants && tenants[0] !== "QUILL_ALL_TENANTS" && tenants.length === 1 && (typeof tenants[0] !== "object" || tenants[0].tenantIds?.[0] !== "QUILL_ALL_TENANTS" && tenants[0].tenantIds?.length === 1)) {
23343
23412
  try {
@@ -23356,13 +23425,13 @@ var getSchemaInfo = async ({
23356
23425
  client,
23357
23426
  task: "schema",
23358
23427
  metadata: {
23359
- clientId: publicKey,
23428
+ clientId: client.id,
23360
23429
  removeCustomerField: true,
23361
23430
  removeCustomFieldRef: true,
23362
23431
  tableIds,
23363
23432
  customFieldsByTable: customFieldsByTableUnique,
23364
23433
  useNewCustomFields: true,
23365
- gatherSchemaData: "665610862cf7a3000be66453" === publicKey ? true : false,
23434
+ gatherSchemaData: "665610862cf7a3000be66453" === client.id ? true : false,
23366
23435
  // TODO: this should be a feature flag on the client
23367
23436
  tenants
23368
23437
  },
@@ -24461,7 +24530,7 @@ var CacheCab = class {
24461
24530
  task: "report",
24462
24531
  metadata: {
24463
24532
  reportId,
24464
- clientId: client.publicKey,
24533
+ clientId: client.id,
24465
24534
  databaseType: client.databaseType,
24466
24535
  filters: adjusted,
24467
24536
  additionalProcessing: { page: { rowsPerPage: 1e3, rowsPerRequest: 1e5 } },
@@ -24600,7 +24669,7 @@ var CacheCab = class {
24600
24669
  );
24601
24670
  const keyParts = [
24602
24671
  reportId,
24603
- client.publicKey,
24672
+ client.id,
24604
24673
  client.databaseType,
24605
24674
  hashString(stableStringify(canonicalizeForKey(tenants ?? null))),
24606
24675
  hashString(stableStringify(canonicalizeForKey(flags ?? null))),
@@ -25238,12 +25307,11 @@ var ContextProvider = ({
25238
25307
  typeof window !== "undefined" && sessionStorage ? JSON.parse(sessionStorage.getItem("quill-client") ?? "null") : null
25239
25308
  );
25240
25309
  const populatedClient = (0, import_react.useMemo)(() => {
25241
- if (!client || client.clientId !== publicKey) return null;
25310
+ if (!client || client.id !== publicKey) return null;
25242
25311
  return {
25243
25312
  ...client,
25244
- publicKey,
25245
- _id: publicKey,
25246
25313
  id: publicKey,
25314
+ clientId: publicKey,
25247
25315
  queryHeaders,
25248
25316
  queryEndpoint,
25249
25317
  streamEndpoint,
@@ -25406,7 +25474,7 @@ var ContextProvider = ({
25406
25474
  try {
25407
25475
  const result = await quillFetch({
25408
25476
  client: {
25409
- clientId: publicKey,
25477
+ id: publicKey,
25410
25478
  queryEndpoint,
25411
25479
  queryHeaders,
25412
25480
  withCredentials: !!withCredentials
@@ -25528,7 +25596,7 @@ var ContextProvider = ({
25528
25596
  try {
25529
25597
  const resp = await quillFetch({
25530
25598
  client: {
25531
- clientId: publicKey,
25599
+ id: publicKey,
25532
25600
  queryEndpoint,
25533
25601
  queryHeaders,
25534
25602
  withCredentials: !!withCredentials
@@ -25536,7 +25604,7 @@ var ContextProvider = ({
25536
25604
  task: fetchRows ? "report" : "report-info",
25537
25605
  metadata: {
25538
25606
  reportId,
25539
- clientId: populatedClient.publicKey,
25607
+ clientId: populatedClient.id,
25540
25608
  useNewNodeSql: true,
25541
25609
  filters: filters?.map((f) => ({ ...f, options: void 0 })),
25542
25610
  additionalProcessing,
@@ -25719,7 +25787,7 @@ var ContextProvider = ({
25719
25787
  try {
25720
25788
  const result = await quillFetch({
25721
25789
  client: {
25722
- clientId: publicKey,
25790
+ id: publicKey,
25723
25791
  queryEndpoint,
25724
25792
  queryHeaders,
25725
25793
  withCredentials: !!withCredentials
@@ -25939,7 +26007,7 @@ var ContextProvider = ({
25939
26007
  });
25940
26008
  return curDashboardConfig;
25941
26009
  }
25942
- if (!populatedClient || !populatedClient.publicKey) {
26010
+ if (!populatedClient || !populatedClient.id) {
25943
26011
  return curDashboardConfig;
25944
26012
  }
25945
26013
  if (dashboardName === null || dashboardName === void 0)
@@ -26093,7 +26161,7 @@ var ContextProvider = ({
26093
26161
  try {
26094
26162
  const result = await quillFetch({
26095
26163
  client: {
26096
- clientId: publicKey2,
26164
+ id: publicKey2,
26097
26165
  queryEndpoint,
26098
26166
  queryHeaders,
26099
26167
  withCredentials: !!withCredentials
@@ -26636,8 +26704,7 @@ var ContextProvider = ({
26636
26704
  withCredentials: withCredentials ?? false,
26637
26705
  databaseType: envClient.databaseType,
26638
26706
  name: envClient.name,
26639
- clientId: publicKey2,
26640
- publicKey: publicKey2,
26707
+ id: publicKey2,
26641
26708
  featureFlags: envClient.featureFlags,
26642
26709
  clerkOrgId: envClient.clerkOrgId,
26643
26710
  allTenantTypes: hydratedTenantTypes
@@ -26709,16 +26776,16 @@ var ContextProvider = ({
26709
26776
  }, [publicKey]);
26710
26777
  (0, import_react.useEffect)(() => {
26711
26778
  if (!hasHandledInitialPopulatedClient.current) {
26712
- if (!populatedClient?.publicKey && !populatedClient?.currentTenants) {
26779
+ if (!populatedClient?.id && !populatedClient?.currentTenants) {
26713
26780
  return;
26714
26781
  }
26715
26782
  hasHandledInitialPopulatedClient.current = true;
26716
- currentPublicKey.current = populatedClient?.publicKey ?? null;
26783
+ currentPublicKey.current = populatedClient?.id ?? null;
26717
26784
  currentTenant.current = populatedClient?.currentTenants ?? null;
26718
26785
  return;
26719
26786
  }
26720
26787
  let publicKeyChanged = false;
26721
- if (populatedClient?.publicKey && currentPublicKey.current !== populatedClient?.publicKey) {
26788
+ if (populatedClient?.id && currentPublicKey.current !== populatedClient?.id) {
26722
26789
  publicKeyChanged = true;
26723
26790
  dispatch({ type: "CLEAR_DASHBOARDS" });
26724
26791
  dashboardFiltersDispatch({ type: "CLEAR_DASHBOARD_FILTERS" });
@@ -26727,7 +26794,7 @@ var ContextProvider = ({
26727
26794
  backfilledDashboards.current.clear();
26728
26795
  if (isAdmin) {
26729
26796
  setIsDashboardsLoading(true);
26730
- fetchDashboards(populatedClient?.publicKey);
26797
+ fetchDashboards(populatedClient?.id);
26731
26798
  } else {
26732
26799
  setIsDashboardsLoading(false);
26733
26800
  }
@@ -26759,17 +26826,17 @@ var ContextProvider = ({
26759
26826
  })
26760
26827
  );
26761
26828
  }
26762
- if (populatedClient?.currentTenants && populatedClient?.publicKey) {
26829
+ if (populatedClient?.currentTenants && populatedClient?.id) {
26763
26830
  const tenant = typeof populatedClient?.currentTenants[0] === "object" ? populatedClient?.currentTenants[0]?.tenantField : void 0;
26764
26831
  const tenantIds = tenant && typeof populatedClient?.currentTenants[0] === "object" ? populatedClient?.currentTenants[0]?.tenantIds : populatedClient?.currentTenants;
26765
26832
  eventTracking?.setUser?.({
26766
- clientId: populatedClient.publicKey,
26833
+ clientId: populatedClient.id,
26767
26834
  clerkOrgId: populatedClient.clerkOrgId,
26768
26835
  tenant,
26769
26836
  tenantIds
26770
26837
  });
26771
26838
  }
26772
- }, [populatedClient?.currentTenants, populatedClient?.publicKey]);
26839
+ }, [populatedClient?.currentTenants, populatedClient?.id]);
26773
26840
  if (!theme) {
26774
26841
  return null;
26775
26842
  }
@@ -27078,7 +27145,7 @@ var useDashboardInternal = (dashboardName, customFilters) => {
27078
27145
  });
27079
27146
  const body = {
27080
27147
  task: "set-section-order",
27081
- clientId: client.clientId,
27148
+ clientId: client.id,
27082
27149
  dashboardName,
27083
27150
  sectionOrder
27084
27151
  };
@@ -27306,7 +27373,7 @@ var useDashboards = () => {
27306
27373
  dateFilter,
27307
27374
  name: name2.trim(),
27308
27375
  task: "edit-dashboard",
27309
- clientId: clientId ?? client.clientId,
27376
+ clientId: clientId ?? client.id,
27310
27377
  tenantKeys: dashboardOwners
27311
27378
  };
27312
27379
  try {
@@ -27381,7 +27448,7 @@ var useDashboards = () => {
27381
27448
  initialCacheDateRange,
27382
27449
  name: name2.trim(),
27383
27450
  task: "edit-dashboard",
27384
- clientId: clientId ?? client.clientId,
27451
+ clientId: clientId ?? client.id,
27385
27452
  tenantKeys
27386
27453
  };
27387
27454
  try {
@@ -27559,7 +27626,7 @@ var useDashboards = () => {
27559
27626
  client,
27560
27627
  task: "delete-dashboard",
27561
27628
  metadata: {
27562
- clientId: client.clientId,
27629
+ clientId: client.id,
27563
27630
  databaseType: client.databaseType,
27564
27631
  name: name2
27565
27632
  }
@@ -28404,7 +28471,7 @@ async function getExportData(client, dashboardFilters, reportId, getToken, event
28404
28471
  metadata: {
28405
28472
  reportId,
28406
28473
  dashboardItemId: reportId,
28407
- clientId: client.publicKey,
28474
+ clientId: client.id,
28408
28475
  databaseType: client?.databaseType,
28409
28476
  filters: minimalFilters,
28410
28477
  useNewNodeSql: true,
@@ -29177,6 +29244,69 @@ function linspace(start, end, num) {
29177
29244
  }
29178
29245
  return result;
29179
29246
  }
29247
+ function stableColorIndex(field) {
29248
+ let hash = 0;
29249
+ for (const character of field.replace("comparison_", "")) {
29250
+ hash = Math.imul(hash, 31) + character.charCodeAt(0) >>> 0;
29251
+ }
29252
+ return hash;
29253
+ }
29254
+ function assignStableSeriesColors(fields, colors, knownFields = fields) {
29255
+ const normalize2 = (values) => [
29256
+ ...new Set(
29257
+ values.filter((field) => typeof field === "string").map((field) => field.replace("comparison_", ""))
29258
+ )
29259
+ ];
29260
+ const uniqueFields = normalize2(fields);
29261
+ const universe = normalize2([...knownFields, ...fields]);
29262
+ const result = /* @__PURE__ */ new Map();
29263
+ if (universe.length === 0) {
29264
+ return result;
29265
+ }
29266
+ if (!colors.length) {
29267
+ for (const field of uniqueFields) {
29268
+ result.set(field, "gray");
29269
+ }
29270
+ return result;
29271
+ }
29272
+ const palette = colors.length >= universe.length ? colors : generateArrayFromColor(colors, universe.length);
29273
+ const ordered = [...universe].sort((a, b) => {
29274
+ const diff = stableColorIndex(a) - stableColorIndex(b);
29275
+ return diff !== 0 ? diff : a.localeCompare(b);
29276
+ });
29277
+ const usedIndices = /* @__PURE__ */ new Set();
29278
+ const deferred = [];
29279
+ const assigned = /* @__PURE__ */ new Map();
29280
+ for (const field of ordered) {
29281
+ const preferred = stableColorIndex(field) % palette.length;
29282
+ if (!usedIndices.has(preferred)) {
29283
+ usedIndices.add(preferred);
29284
+ assigned.set(field, palette[preferred]);
29285
+ } else {
29286
+ deferred.push(field);
29287
+ }
29288
+ }
29289
+ for (const field of deferred) {
29290
+ const preferred = stableColorIndex(field) % palette.length;
29291
+ let found = false;
29292
+ for (let offset = 1; offset < palette.length; offset++) {
29293
+ const idx = (preferred + offset) % palette.length;
29294
+ if (!usedIndices.has(idx)) {
29295
+ usedIndices.add(idx);
29296
+ assigned.set(field, palette[idx]);
29297
+ found = true;
29298
+ break;
29299
+ }
29300
+ }
29301
+ if (!found) {
29302
+ assigned.set(field, palette[preferred]);
29303
+ }
29304
+ }
29305
+ for (const field of uniqueFields) {
29306
+ result.set(field, assigned.get(field));
29307
+ }
29308
+ return result;
29309
+ }
29180
29310
  function selectColor(element, colors, index) {
29181
29311
  if (!element?.field) return "gray";
29182
29312
  const isComparison = element.field.includes("comparison_");
@@ -31461,15 +31591,19 @@ var QuillPortal = ({
31461
31591
  };
31462
31592
 
31463
31593
  // src/components/Chart/CustomLegend.tsx
31594
+ init_textProcessing();
31464
31595
  var import_jsx_runtime27 = require("react/jsx-runtime");
31465
31596
  var getLegendLabel = (entry) => {
31466
31597
  const label = entry?.payload?.name ?? entry?.value ?? entry?.dataKey ?? "";
31467
- return typeof label === "string" ? label : String(label ?? "");
31598
+ return snakeAndCamelCaseToTitleCase(
31599
+ typeof label === "string" ? label : String(label ?? "")
31600
+ );
31468
31601
  };
31469
31602
  var LegendItem = ({
31470
31603
  entry,
31471
31604
  index,
31472
- theme
31605
+ theme,
31606
+ onClick
31473
31607
  }) => /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31474
31608
  "div",
31475
31609
  {
@@ -31478,30 +31612,37 @@ var LegendItem = ({
31478
31612
  alignItems: "baseline",
31479
31613
  marginRight: "1rem"
31480
31614
  },
31481
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { style: { display: "flex", flexDirection: "row", alignItems: "center" }, children: [
31482
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31483
- "svg",
31484
- {
31485
- style: { marginRight: "0.5rem" },
31486
- width: "16",
31487
- height: "16",
31488
- viewBox: "0 0 16 16",
31489
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { width: "16", height: "16", rx: "3", fill: entry?.color })
31490
- }
31491
- ),
31492
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31493
- "span",
31494
- {
31495
- style: {
31496
- color: theme?.secondaryTextColor,
31497
- fontFamily: theme?.fontFamily,
31498
- fontSize: theme?.fontSizeMedium || "14px",
31499
- whiteSpace: "nowrap"
31500
- },
31501
- children: getLegendLabel(entry)
31502
- }
31503
- )
31504
- ] })
31615
+ onClick: () => onClick ? onClick(entry) : void 0,
31616
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
31617
+ "div",
31618
+ {
31619
+ style: { display: "flex", flexDirection: "row", alignItems: "center" },
31620
+ children: [
31621
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31622
+ "svg",
31623
+ {
31624
+ style: { marginRight: "0.5rem" },
31625
+ width: "16",
31626
+ height: "16",
31627
+ viewBox: "0 0 16 16",
31628
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("rect", { width: "16", height: "16", rx: "3", fill: entry?.color })
31629
+ }
31630
+ ),
31631
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31632
+ "span",
31633
+ {
31634
+ style: {
31635
+ color: theme?.secondaryTextColor,
31636
+ fontFamily: theme?.fontFamily,
31637
+ fontSize: theme?.fontSizeMedium || "14px",
31638
+ whiteSpace: "nowrap"
31639
+ },
31640
+ children: getLegendLabel(entry)
31641
+ }
31642
+ )
31643
+ ]
31644
+ }
31645
+ )
31505
31646
  },
31506
31647
  `legend-${index}`
31507
31648
  );
@@ -31515,7 +31656,8 @@ var getOuterWidth = (element) => {
31515
31656
  };
31516
31657
  var RenderLegend = ({
31517
31658
  payload,
31518
- limit
31659
+ limit,
31660
+ onClickLegendElement
31519
31661
  }) => {
31520
31662
  const [theme] = (0, import_react12.useContext)(ThemeContext);
31521
31663
  const [isOpen, setIsOpen] = (0, import_react12.useState)(false);
@@ -31528,7 +31670,10 @@ var RenderLegend = ({
31528
31670
  const safePayload = payload ?? [];
31529
31671
  const maxItems = limit ?? safePayload.length;
31530
31672
  const measuredLimit = visibleCount ?? maxItems;
31531
- const visiblePayload = safePayload.slice(0, Math.min(maxItems, measuredLimit));
31673
+ const visiblePayload = safePayload.slice(
31674
+ 0,
31675
+ Math.min(maxItems, measuredLimit)
31676
+ );
31532
31677
  const handleOpen = () => setIsOpen(true);
31533
31678
  const handleClose = () => setIsOpen(false);
31534
31679
  (0, import_react12.useLayoutEffect)(() => {
@@ -31589,7 +31734,6 @@ var RenderLegend = ({
31589
31734
  visibility: "hidden",
31590
31735
  height: 0,
31591
31736
  overflow: "hidden",
31592
- pointerEvents: "none",
31593
31737
  display: "flex",
31594
31738
  alignItems: "center",
31595
31739
  flexWrap: "nowrap",
@@ -31613,7 +31757,15 @@ var RenderLegend = ({
31613
31757
  ref: (element) => {
31614
31758
  itemRefs.current[index] = element;
31615
31759
  },
31616
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(LegendItem, { entry, index, theme })
31760
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
31761
+ LegendItem,
31762
+ {
31763
+ entry,
31764
+ index,
31765
+ theme,
31766
+ onClick: onClickLegendElement
31767
+ }
31768
+ )
31617
31769
  },
31618
31770
  `legend-measure-${index}`
31619
31771
  ))
@@ -31654,7 +31806,8 @@ var RenderLegend = ({
31654
31806
  {
31655
31807
  entry,
31656
31808
  index,
31657
- theme
31809
+ theme,
31810
+ onClick: onClickLegendElement
31658
31811
  },
31659
31812
  `legend-${index}`
31660
31813
  ))
@@ -31701,7 +31854,8 @@ var RenderLegend = ({
31701
31854
  {
31702
31855
  entry,
31703
31856
  index,
31704
- theme
31857
+ theme,
31858
+ onClick: onClickLegendElement
31705
31859
  },
31706
31860
  `legend-popover-${index}`
31707
31861
  ))
@@ -31973,6 +32127,7 @@ var PieChartWrapper = import_react13.default.forwardRef(
31973
32127
  containerStyle,
31974
32128
  theme,
31975
32129
  onClickChartElement,
32130
+ onClickLegendElement,
31976
32131
  yAxisFields,
31977
32132
  showLegend = false,
31978
32133
  ...other
@@ -32069,7 +32224,13 @@ var PieChartWrapper = import_react13.default.forwardRef(
32069
32224
  paddingBottom: 20,
32070
32225
  fontFamily: theme?.fontFamily
32071
32226
  },
32072
- content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(RenderLegend, { limit: 5 })
32227
+ content: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
32228
+ RenderLegend,
32229
+ {
32230
+ limit: 5,
32231
+ onClickLegendElement
32232
+ }
32233
+ )
32073
32234
  }
32074
32235
  ),
32075
32236
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
@@ -32704,6 +32865,7 @@ init_valueFormatter();
32704
32865
  // src/utils/axisFormatter.ts
32705
32866
  var import_date_fns11 = require("date-fns");
32706
32867
  var import_date_fns_tz4 = require("date-fns-tz");
32868
+ init_textProcessing();
32707
32869
  var axisFormatter = ({ value, field, fields }) => {
32708
32870
  if (field === void 0 || field === null) return "";
32709
32871
  if (value === void 0 || value === null) return "";
@@ -32753,7 +32915,7 @@ var formatString2 = (value) => {
32753
32915
  if (typeof value === "object") {
32754
32916
  return JSON.stringify(value);
32755
32917
  }
32756
- return value.toString();
32918
+ return formatIdentifierLabel(value.toString());
32757
32919
  };
32758
32920
  var formatterDecimal2 = new Intl.NumberFormat("en-US", {
32759
32921
  style: "decimal",
@@ -32960,6 +33122,7 @@ function ChartTooltipRow2({
32960
33122
  }
32961
33123
 
32962
33124
  // src/components/Chart/ChartTooltipGroup.tsx
33125
+ init_textProcessing();
32963
33126
  var import_jsx_runtime32 = require("react/jsx-runtime");
32964
33127
  function ChartTooltipGroup({
32965
33128
  name: name2,
@@ -32994,7 +33157,7 @@ function ChartTooltipGroup({
32994
33157
  paddingBottom: 2,
32995
33158
  textTransform: "capitalize"
32996
33159
  },
32997
- children: name2.replaceAll("_", " ").toLowerCase()
33160
+ children: formatIdentifierLabel(name2)
32998
33161
  }
32999
33162
  ),
33000
33163
  items.map(({ color, value, name: name3 }, idx) => /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
@@ -33015,6 +33178,7 @@ function ChartTooltipGroup({
33015
33178
 
33016
33179
  // src/components/Chart/ChartTooltip.tsx
33017
33180
  init_dates();
33181
+ init_textProcessing();
33018
33182
  var import_jsx_runtime33 = require("react/jsx-runtime");
33019
33183
  var ChartTooltipPrimary = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(ChartTooltipFrame2, { theme: props.theme, children: [
33020
33184
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
@@ -33049,7 +33213,7 @@ var ChartTooltipPrimary = (props) => /* @__PURE__ */ (0, import_jsx_runtime33.js
33049
33213
  paddingTop: 2,
33050
33214
  paddingBottom: 2
33051
33215
  },
33052
- children: !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : props.label
33216
+ children: !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : formatIdentifierLabel(props.label)
33053
33217
  }
33054
33218
  )
33055
33219
  }
@@ -33132,7 +33296,7 @@ function reformatComparisonPayload(props, primaryLabel, comparisonLabel) {
33132
33296
  return columnsByKey;
33133
33297
  }
33134
33298
  function getTooltipLabel(props, altTooltipLabel, isDateXAxis) {
33135
- return props.payload.length <= 2 && altTooltipLabel && isDateXAxis ? !isNaN(new Date(altTooltipLabel)) && props.dateFormatter ? props.dateFormatter(altTooltipLabel) : !isNaN(new Date(altTooltipLabel)) ? (0, import_date_fns12.format)(new Date(altTooltipLabel), "MMM yyyy") : altTooltipLabel : !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : props.label;
33299
+ return props.payload.length <= 2 && altTooltipLabel && isDateXAxis ? !isNaN(new Date(altTooltipLabel)) && props.dateFormatter ? props.dateFormatter(altTooltipLabel) : !isNaN(new Date(altTooltipLabel)) ? (0, import_date_fns12.format)(new Date(altTooltipLabel), "MMM yyyy") : formatIdentifierLabel(altTooltipLabel) : !isNaN(new Date(props.label)) && props.dateFormatter ? props.dateFormatter(props.label) : !isNaN(new Date(props.label)) ? (0, import_date_fns12.format)(new Date(props.label), "MMM yyyy") : formatIdentifierLabel(props.label);
33136
33300
  }
33137
33301
  function ChartTooltipComparison(props) {
33138
33302
  const isDateXAxis = isDateFormat2(props.xAxisFormat);
@@ -33388,6 +33552,7 @@ function CustomReferenceLine({
33388
33552
 
33389
33553
  // src/components/Chart/LineChart.tsx
33390
33554
  init_columnProcessing();
33555
+ init_textProcessing();
33391
33556
  var import_jsx_runtime35 = require("react/jsx-runtime");
33392
33557
  function createLineForEmptyChart(yAxisFields, dateFilter, xAxisField, xAxisFormat) {
33393
33558
  let lineChartData = [];
@@ -33424,6 +33589,8 @@ function LineChart({
33424
33589
  cartesianGridLineColor,
33425
33590
  onClickChartElement = () => {
33426
33591
  },
33592
+ onClickLegendElement = () => {
33593
+ },
33427
33594
  dateFilter,
33428
33595
  referenceLines,
33429
33596
  showLegend = false
@@ -33520,7 +33687,7 @@ function LineChart({
33520
33687
  paddingBottom: 20,
33521
33688
  fontFamily: theme?.fontFamily
33522
33689
  },
33523
- content: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(RenderLegend, {})
33690
+ content: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(RenderLegend, { onClickLegendElement })
33524
33691
  }
33525
33692
  ),
33526
33693
  /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
@@ -33608,7 +33775,9 @@ function LineChart({
33608
33775
  color: p.color || "black",
33609
33776
  chartType: "line",
33610
33777
  dataKey: p.dataKey?.toLocaleString() || "",
33611
- name: name2 || p.name?.toString() || "",
33778
+ name: snakeAndCamelCaseToTitleCase(
33779
+ name2 || p.name?.toString() || ""
33780
+ ),
33612
33781
  payload: p.payload || {},
33613
33782
  type: p.type || "none",
33614
33783
  unit: "string",
@@ -33701,6 +33870,7 @@ function LineChart({
33701
33870
  import_recharts2.Area,
33702
33871
  {
33703
33872
  type: "linear",
33873
+ name: elem.label || elem.field,
33704
33874
  dataKey: elem.field,
33705
33875
  stroke: getCustomColor(index, elem.field) ?? selectColor(elem, colors, index - numComparisons),
33706
33876
  fill: `url(#${uniqueId})`,
@@ -33723,6 +33893,7 @@ function LineChart({
33723
33893
  var import_recharts3 = require("recharts");
33724
33894
  var import_react16 = require("react");
33725
33895
  init_valueFormatter();
33896
+ init_textProcessing();
33726
33897
  var import_jsx_runtime36 = require("react/jsx-runtime");
33727
33898
  function RadarChart({
33728
33899
  colors,
@@ -33738,6 +33909,8 @@ function RadarChart({
33738
33909
  isAnimationActive = true,
33739
33910
  onClickChartElement = () => {
33740
33911
  },
33912
+ onClickLegendElement = () => {
33913
+ },
33741
33914
  dateFilter,
33742
33915
  showLegend = false
33743
33916
  }) {
@@ -33831,7 +34004,7 @@ function RadarChart({
33831
34004
  paddingBottom: 20,
33832
34005
  fontFamily: theme?.fontFamily
33833
34006
  },
33834
- content: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(RenderLegend, {})
34007
+ content: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(RenderLegend, { onClickLegendElement })
33835
34008
  }
33836
34009
  ),
33837
34010
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
@@ -33866,7 +34039,9 @@ function RadarChart({
33866
34039
  color: p.color || "black",
33867
34040
  chartType: "radar",
33868
34041
  dataKey: p.dataKey?.toLocaleString() || "",
33869
- name: name2 || p.name?.toString() || "",
34042
+ name: snakeAndCamelCaseToTitleCase(
34043
+ name2 || p.name?.toString() || ""
34044
+ ),
33870
34045
  payload: p.payload || {},
33871
34046
  type: p.type || "none",
33872
34047
  unit: "string",
@@ -33973,6 +34148,10 @@ var CustomBar = (0, import_react17.memo)((props) => {
33973
34148
  width: rawWidth,
33974
34149
  height: rawHeight,
33975
34150
  fill,
34151
+ fillOpacity,
34152
+ stroke,
34153
+ strokeWidth,
34154
+ style,
33976
34155
  yAxisFields = [],
33977
34156
  dataKey,
33978
34157
  payload = {},
@@ -34030,7 +34209,17 @@ var CustomBar = (0, import_react17.memo)((props) => {
34030
34209
  rawY,
34031
34210
  radius
34032
34211
  ]);
34033
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("path", { d: path, fill });
34212
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
34213
+ "path",
34214
+ {
34215
+ d: path,
34216
+ fill,
34217
+ fillOpacity,
34218
+ stroke,
34219
+ strokeWidth,
34220
+ style
34221
+ }
34222
+ );
34034
34223
  });
34035
34224
  CustomBar.displayName = "CustomBar";
34036
34225
  var CustomBar_default = CustomBar;
@@ -34038,10 +34227,25 @@ var CustomBar_default = CustomBar;
34038
34227
  // src/components/Chart/BarChart.tsx
34039
34228
  var import_react18 = require("react");
34040
34229
  init_columnProcessing();
34230
+ init_textProcessing();
34041
34231
  var import_jsx_runtime38 = require("react/jsx-runtime");
34042
34232
  var CATEGORY_AXIS_WIDTH = 120;
34043
34233
  var VALUE_AXIS_WIDTH = 44;
34044
34234
  var STACKED_DOMAIN_HEADROOM = 1.05;
34235
+ function rowValueFromPivotRow(row, xAxisField, fallbackLabel) {
34236
+ const rawDate = row?.__quillRawDate;
34237
+ if (rawDate != null && rawDate !== "") {
34238
+ return String(rawDate);
34239
+ }
34240
+ const category = row?.[xAxisField];
34241
+ if (category != null && category !== "") {
34242
+ return String(category);
34243
+ }
34244
+ if (fallbackLabel != null && fallbackLabel !== "") {
34245
+ return String(fallbackLabel);
34246
+ }
34247
+ return null;
34248
+ }
34045
34249
  function getStackedDomain(data, fields, comparison) {
34046
34250
  const fieldsArray = fields.filter((field) => comparison || !field.field.startsWith("comparison_")).map((field) => field.field);
34047
34251
  if (fieldsArray.length === 0 || data.length === 0) {
@@ -34063,14 +34267,16 @@ function getStackedDomain(data, fields, comparison) {
34063
34267
  }
34064
34268
  return [0, maxStack * STACKED_DOMAIN_HEADROOM];
34065
34269
  }
34066
- var createCustomBar = (yAxisFields, theme, layout) => {
34270
+ var createCustomBar = (yAxisFields, theme, layout, active = false) => {
34067
34271
  return (props) => /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34068
34272
  CustomBar_default,
34069
34273
  {
34070
34274
  ...props,
34071
34275
  yAxisFields,
34072
34276
  theme,
34073
- layout
34277
+ layout,
34278
+ stroke: active ? theme?.primaryTextColor ?? "#111827" : props.stroke,
34279
+ strokeWidth: active ? 1.5 : props.strokeWidth
34074
34280
  }
34075
34281
  );
34076
34282
  };
@@ -34091,6 +34297,7 @@ function BarChart({
34091
34297
  hideYAxis = false,
34092
34298
  hideCartesianGrid = false,
34093
34299
  onClickChartElement,
34300
+ onClickLegendElement,
34094
34301
  dateFilter,
34095
34302
  referenceLines,
34096
34303
  showLegend = false,
@@ -34120,6 +34327,21 @@ function BarChart({
34120
34327
  () => stackedMode ? getStackedDomain(data, yAxisFields, comparison) : getDomain(data, yAxisFields, referenceLines),
34121
34328
  [stackedMode, data, yAxisFields, referenceLines, comparison]
34122
34329
  );
34330
+ const knownSeriesFieldsRef = (0, import_react18.useRef)([]);
34331
+ const knownColorsKeyRef = (0, import_react18.useRef)("");
34332
+ const seriesColorByField = (0, import_react18.useMemo)(() => {
34333
+ const visibleFields = yAxisFields.filter((field) => comparison || !field.field.startsWith("comparison_")).map((field) => field.field);
34334
+ const colorsKey = colors.join("\0");
34335
+ if (knownColorsKeyRef.current !== colorsKey) {
34336
+ knownSeriesFieldsRef.current = [];
34337
+ knownColorsKeyRef.current = colorsKey;
34338
+ }
34339
+ const knownFields = [
34340
+ .../* @__PURE__ */ new Set([...knownSeriesFieldsRef.current, ...visibleFields])
34341
+ ];
34342
+ knownSeriesFieldsRef.current = knownFields;
34343
+ return assignStableSeriesColors(visibleFields, colors, knownFields);
34344
+ }, [yAxisFields, colors, comparison]);
34123
34345
  const allowDecimals = (0, import_react18.useMemo)(
34124
34346
  () => getAllowDecimals(data, yAxisFields, referenceLines),
34125
34347
  [data, yAxisFields, referenceLines]
@@ -34143,6 +34365,16 @@ function BarChart({
34143
34365
  return void 0;
34144
34366
  return createCustomBar(sortYAxisFields([...yAxisFields]), theme, layout);
34145
34367
  }, [isStacked, yAxisFields, theme, layout]);
34368
+ const customActiveBarShape = (0, import_react18.useMemo)(() => {
34369
+ if (!theme?.barChartCornerRadius && !theme?.barChartCornerRadiusRatio)
34370
+ return void 0;
34371
+ return createCustomBar(
34372
+ sortYAxisFields([...yAxisFields]),
34373
+ theme,
34374
+ layout,
34375
+ true
34376
+ );
34377
+ }, [isStacked, yAxisFields, theme, layout]);
34146
34378
  if (!data || data.length === 0) {
34147
34379
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34148
34380
  "div",
@@ -34184,9 +34416,28 @@ function BarChart({
34184
34416
  {
34185
34417
  data: data ?? [],
34186
34418
  layout,
34187
- onClick: (event) => onClickChartElement ? onClickChartElement(
34188
- event?.activePayload ? event.activePayload[0].payload : void 0
34189
- ) : void 0,
34419
+ onClick: (event) => {
34420
+ if (!onClickChartElement || event?.activeLabel === void 0 || event?.activeTooltipIndex === void 0) {
34421
+ return;
34422
+ }
34423
+ const index = Number(event.activeTooltipIndex);
34424
+ const row = event.activePayload?.[0]?.payload ?? data[index] ?? {};
34425
+ onClickChartElement({
34426
+ ...row,
34427
+ interactionType: "bucket",
34428
+ activeLabel: event.activeLabel,
34429
+ rowValue: rowValueFromPivotRow(row, xAxisField, event.activeLabel),
34430
+ columnValue: void 0,
34431
+ activeDataKey: void 0,
34432
+ activeValue: void 0,
34433
+ activePayload: event.activePayload ?? [],
34434
+ category: event.activeLabel,
34435
+ series: void 0,
34436
+ value: void 0,
34437
+ row,
34438
+ index
34439
+ });
34440
+ },
34190
34441
  children: [
34191
34442
  !hideCartesianGrid && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34192
34443
  import_recharts4.CartesianGrid,
@@ -34206,7 +34457,7 @@ function BarChart({
34206
34457
  wrapperStyle: {
34207
34458
  paddingBottom: 20
34208
34459
  },
34209
- content: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(RenderLegend, {})
34460
+ content: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(RenderLegend, { onClickLegendElement })
34210
34461
  }
34211
34462
  ),
34212
34463
  isHorizontalBars ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
@@ -34285,11 +34536,13 @@ function BarChart({
34285
34536
  {
34286
34537
  wrapperStyle: { outline: "none", zIndex: 2 },
34287
34538
  isAnimationActive: false,
34288
- cursor: { fill: "#d1d5db", opacity: "0.15" },
34539
+ cursor: false,
34540
+ shared: false,
34289
34541
  content: ({ active, payload, label }) => {
34290
34542
  if (!payload || payload.length === 0) {
34291
34543
  return null;
34292
34544
  }
34545
+ const activeLabel = label ?? payload[0]?.payload?.[xAxisField] ?? "";
34293
34546
  const payloadItems = payload.map((p) => {
34294
34547
  const rawName = yAxisFields?.find(
34295
34548
  (f) => f.field === p.name?.toString()
@@ -34300,7 +34553,9 @@ function BarChart({
34300
34553
  color: p.color || "black",
34301
34554
  chartType: "line",
34302
34555
  dataKey: p.dataKey?.toLocaleString() || "",
34303
- name: name2 || p.name?.toString() || "",
34556
+ name: snakeAndCamelCaseToTitleCase(
34557
+ name2 || p.name?.toString() || ""
34558
+ ),
34304
34559
  payload: p.payload || {},
34305
34560
  type: p.type || "none",
34306
34561
  unit: "string",
@@ -34313,7 +34568,7 @@ function BarChart({
34313
34568
  theme,
34314
34569
  active,
34315
34570
  payload: payloadItems,
34316
- label,
34571
+ label: `${activeLabel}`,
34317
34572
  dateFormatter: (value) => valueFormatter({
34318
34573
  value,
34319
34574
  field: xAxisField,
@@ -34345,21 +34600,55 @@ function BarChart({
34345
34600
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
34346
34601
  import_recharts4.Bar,
34347
34602
  {
34603
+ name: elem.label || elem.field,
34348
34604
  dataKey: elem.field,
34349
34605
  stackId: stackedMode ? "same_id" : isStacked ? elem.field.replace("comparison_", "") : void 0,
34350
34606
  type: "linear",
34351
34607
  fill: getCustomColor(elem.field) ?? selectColor(
34352
34608
  elem,
34353
- colors.length >= yAxisFields.length / (comparison ? 2 : 1) ? colors : generateArrayFromColor(
34354
- colors.slice(0, 2),
34355
- yAxisFields.length
34356
- ),
34357
- yAxisFields.findIndex(
34358
- (field) => field.field === elem.field?.replace("comparison_", "")
34359
- )
34609
+ [
34610
+ seriesColorByField.get(
34611
+ elem.field.replace("comparison_", "")
34612
+ ) ?? colors[0] ?? "gray"
34613
+ ],
34614
+ 0
34360
34615
  ),
34361
34616
  isAnimationActive,
34362
- shape: customBarShape
34617
+ shape: customBarShape,
34618
+ activeBar: customActiveBarShape ?? {
34619
+ fillOpacity: 1,
34620
+ stroke: theme?.primaryTextColor ?? "#111827",
34621
+ strokeWidth: 1.5
34622
+ },
34623
+ style: {
34624
+ cursor: onClickChartElement ? "pointer" : void 0
34625
+ },
34626
+ onClick: (bar, index, event) => {
34627
+ event?.stopPropagation();
34628
+ const payload = bar.payload ?? data[index] ?? {};
34629
+ onClickChartElement?.({
34630
+ ...payload,
34631
+ interactionType: "bar",
34632
+ activeLabel: payload[xAxisField],
34633
+ rowValue: rowValueFromPivotRow(payload, xAxisField),
34634
+ columnValue: elem.field,
34635
+ activeDataKey: elem.field,
34636
+ activeValue: payload[elem.field] ?? bar.value,
34637
+ activePayload: [
34638
+ {
34639
+ dataKey: elem.field,
34640
+ name: elem.label || elem.field,
34641
+ payload,
34642
+ value: payload[elem.field] ?? bar.value
34643
+ }
34644
+ ],
34645
+ category: payload[xAxisField],
34646
+ series: elem.field,
34647
+ value: payload[elem.field] ?? bar.value,
34648
+ row: payload,
34649
+ index
34650
+ });
34651
+ }
34363
34652
  },
34364
34653
  elem.field
34365
34654
  );
@@ -39917,6 +40206,7 @@ var ChartDisplay = ({
39917
40206
  onPageChange,
39918
40207
  onSortChange,
39919
40208
  onClickChartElement,
40209
+ onClickLegendElement,
39920
40210
  overrideTheme,
39921
40211
  referenceLines,
39922
40212
  showLegend,
@@ -40001,6 +40291,7 @@ var ChartDisplay = ({
40001
40291
  theme: overrideTheme ?? theme,
40002
40292
  colorMap,
40003
40293
  onClickChartElement,
40294
+ onClickLegendElement,
40004
40295
  yAxisFields: config?.yAxisFields,
40005
40296
  showLegend: resolvedShowLegend
40006
40297
  }
@@ -40077,6 +40368,7 @@ var ChartDisplay = ({
40077
40368
  hideCartesianGrid,
40078
40369
  colorMap,
40079
40370
  onClickChartElement,
40371
+ onClickLegendElement,
40080
40372
  dateFilter: !hideDateRangeFilter ? dateFilter : void 0,
40081
40373
  referenceLines,
40082
40374
  showLegend: resolvedShowLegend
@@ -40104,6 +40396,7 @@ var ChartDisplay = ({
40104
40396
  hideCartesianGrid,
40105
40397
  colorMap,
40106
40398
  onClickChartElement,
40399
+ onClickLegendElement,
40107
40400
  dateFilter: !hideDateRangeFilter ? dateFilter : void 0,
40108
40401
  referenceLines,
40109
40402
  showLegend: resolvedShowLegend,
@@ -40260,6 +40553,7 @@ var ChartDisplay = ({
40260
40553
  className,
40261
40554
  isAnimationActive,
40262
40555
  onClickChartElement,
40556
+ onClickLegendElement,
40263
40557
  dateFilter: !hideDateRangeFilter ? dateFilter : void 0,
40264
40558
  showLegend: resolvedShowLegend
40265
40559
  }
@@ -40290,6 +40584,7 @@ var ChartDisplay = ({
40290
40584
  comparisonLineStyle: comparisonLineStyle ?? "solid",
40291
40585
  cartesianGridLineColor,
40292
40586
  onClickChartElement,
40587
+ onClickLegendElement,
40293
40588
  dateFilter: !hideDateRangeFilter ? dateFilter : void 0,
40294
40589
  referenceLines,
40295
40590
  showLegend: resolvedShowLegend
@@ -42348,7 +42643,7 @@ function DashboardLegacy({
42348
42643
  const [filterValues, setFilterValues] = (0, import_react40.useState)({});
42349
42644
  const prevNameRef = (0, import_react40.useRef)(name2);
42350
42645
  const prevFlagsRef = (0, import_react40.useRef)(flags);
42351
- const prevClientRef = (0, import_react40.useRef)(client?.publicKey ?? "");
42646
+ const prevClientRef = (0, import_react40.useRef)(client?.id ?? "");
42352
42647
  const addFilterPopoverButtonRef = (0, import_react40.useRef)(null);
42353
42648
  const viewFiltersPopoverButtonRef = (0, import_react40.useRef)(null);
42354
42649
  const previousFilters = (0, import_react40.useRef)(filters);
@@ -42404,15 +42699,15 @@ function DashboardLegacy({
42404
42699
  });
42405
42700
  }, [flags]);
42406
42701
  (0, import_react40.useEffect)(() => {
42407
- if (prevClientRef.current === client?.publicKey) {
42702
+ if (prevClientRef.current === client?.id) {
42408
42703
  return;
42409
42704
  }
42410
- const isInitialKeySet = !prevClientRef.current && client?.publicKey;
42705
+ const isInitialKeySet = !prevClientRef.current && client?.id;
42411
42706
  if (isInitialKeySet && Object.values(data?.sections ?? {}).flat().length) {
42412
- prevClientRef.current = client?.publicKey ?? "";
42707
+ prevClientRef.current = client?.id ?? "";
42413
42708
  return;
42414
42709
  }
42415
- prevClientRef.current = client?.publicKey ?? "";
42710
+ prevClientRef.current = client?.id ?? "";
42416
42711
  if (isClientLoading) {
42417
42712
  return;
42418
42713
  }
@@ -42424,7 +42719,7 @@ function DashboardLegacy({
42424
42719
  prevFlagsRef.current = flags;
42425
42720
  isInitialLoadOfDashboardRef.current = false;
42426
42721
  });
42427
- }, [client?.publicKey]);
42722
+ }, [client?.id]);
42428
42723
  (0, import_react40.useEffect)(() => {
42429
42724
  setFilterValues(
42430
42725
  Object.values(populatedDashboardFilters ?? {}).reduce((acc, f) => {
@@ -43407,6 +43702,7 @@ function StaticChart(props) {
43407
43702
  const {
43408
43703
  reportId,
43409
43704
  onClickChartElement,
43705
+ onClickLegendElement,
43410
43706
  containerStyle,
43411
43707
  showLegend,
43412
43708
  className
@@ -43459,6 +43755,7 @@ function StaticChart(props) {
43459
43755
  reportId,
43460
43756
  config,
43461
43757
  onClickChartElement,
43758
+ onClickLegendElement,
43462
43759
  loading,
43463
43760
  className,
43464
43761
  containerStyle: safeContainerStyle,
@@ -48501,7 +48798,7 @@ function ChartBuilder({
48501
48798
  task: "dashboard",
48502
48799
  metadata: {
48503
48800
  name: dashboardName,
48504
- clientId: client.clientId,
48801
+ clientId: client.id,
48505
48802
  databaseType: client.databaseType,
48506
48803
  useNewNodeSql: true,
48507
48804
  tenants
@@ -48561,11 +48858,11 @@ function ChartBuilder({
48561
48858
  const getReferencedTables = async (client2, dbTables, sqlQuery, reportBuilderState2, skipStar) => {
48562
48859
  const metadata = reportBuilderState2 ? {
48563
48860
  reportBuilderState: reportBuilderState2,
48564
- clientId: client2.clientId,
48861
+ clientId: client2.id,
48565
48862
  useNewNodeSql: true
48566
48863
  } : {
48567
48864
  query: sqlQuery,
48568
- clientId: client2.clientId,
48865
+ clientId: client2.id,
48569
48866
  useNewNodeSql: true
48570
48867
  };
48571
48868
  try {
@@ -48791,7 +49088,7 @@ function ChartBuilder({
48791
49088
  client,
48792
49089
  task: "dashnames",
48793
49090
  metadata: {
48794
- clientId: client.clientId
49091
+ clientId: client.id
48795
49092
  }
48796
49093
  });
48797
49094
  dashNames = resp.dashboardNames;
@@ -52336,7 +52633,7 @@ function SQLEditor({
52336
52633
  setColumns([]);
52337
52634
  setDisplayTable(false);
52338
52635
  }
52339
- }, [client?.publicKey]);
52636
+ }, [client?.id]);
52340
52637
  (0, import_react51.useEffect)(() => {
52341
52638
  if (isChartBuilderOpen === false) {
52342
52639
  onCloseChartBuilder && onCloseChartBuilder();
@@ -52595,7 +52892,7 @@ function SQLEditor({
52595
52892
  task: "astify",
52596
52893
  metadata: {
52597
52894
  query: sqlQuery,
52598
- clientId: client2.clientId,
52895
+ clientId: client2.id,
52599
52896
  useNewNodeSql: true
52600
52897
  }
52601
52898
  });
@@ -52788,7 +53085,7 @@ function SQLEditor({
52788
53085
  query: query || "",
52789
53086
  schema: filteredSchema,
52790
53087
  databaseType: client?.databaseType ?? "postgresql",
52791
- clientName: client?.publicKey || "",
53088
+ clientName: client?.id || "",
52792
53089
  setQuery,
52793
53090
  handleRunQuery: () => {
52794
53091
  handleRunQuery(currentProcessing, true);
@@ -54942,7 +55239,7 @@ var useReportBuilderInternal = ({
54942
55239
  !client.featureFlags?.["recommendedPivotsDisabled"]
54943
55240
  );
54944
55241
  }
54945
- if (!initialTableName && !reportId && client.publicKey) {
55242
+ if (!initialTableName && !reportId && client.id) {
54946
55243
  clearAllState();
54947
55244
  }
54948
55245
  }, [client]);
@@ -58457,6 +58754,7 @@ init_valueFormatter();
58457
58754
  // src/utils/queryBuilderFilters.ts
58458
58755
  init_Filter();
58459
58756
  init_reportBuilder();
58757
+ init_dates();
58460
58758
  var buildOperatorOption = (value, label, arity) => ({
58461
58759
  name: value,
58462
58760
  value,
@@ -58625,6 +58923,26 @@ var DATE_UNIT_BY_KEY = {
58625
58923
  day: TimeUnit.Day,
58626
58924
  hour: TimeUnit.Hour
58627
58925
  };
58926
+ var DATE_BUCKETS = /* @__PURE__ */ new Set(["day", "week", "month", "year"]);
58927
+ var parseInBucketValue = (value) => {
58928
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
58929
+ throw new Error(
58930
+ 'inBucket value must be `{ start: string, bucket: "day"|"week"|"month"|"year" }`'
58931
+ );
58932
+ }
58933
+ const record = value;
58934
+ const start = String(record.start ?? "").trim();
58935
+ const bucket = String(record.bucket ?? "").trim().toLowerCase();
58936
+ if (!start) {
58937
+ throw new Error("inBucket value.start is required");
58938
+ }
58939
+ if (!DATE_BUCKETS.has(bucket)) {
58940
+ throw new Error(
58941
+ `inBucket value.bucket must be day|week|month|year (got "${String(record.bucket)}")`
58942
+ );
58943
+ }
58944
+ return { start, bucket };
58945
+ };
58628
58946
  var EMPTY_QUERY_GROUP = {
58629
58947
  combinator: "and",
58630
58948
  rules: []
@@ -58844,6 +59162,17 @@ var internalFilterToRule = (filter) => {
58844
59162
  }
58845
59163
  case "date-custom-filter" /* DateCustomFilter */: {
58846
59164
  const customDate = filter.value;
59165
+ const dateCustom = filter;
59166
+ if (dateCustom.fromInBucket && dateCustom.dateBucket) {
59167
+ return {
59168
+ field,
59169
+ operator: "inBucket",
59170
+ value: {
59171
+ start: customDate.startDate,
59172
+ bucket: dateCustom.dateBucket
59173
+ }
59174
+ };
59175
+ }
58847
59176
  return {
58848
59177
  field,
58849
59178
  operator: "between",
@@ -59028,6 +59357,24 @@ var queryRuleToInternalFilter = (rule, fieldConfigByName) => {
59028
59357
  }
59029
59358
  };
59030
59359
  }
59360
+ if (compactOperatorKey === "inbucket") {
59361
+ const { start, bucket } = parseInBucketValue(rule.value);
59362
+ const range = getExclusiveDateBucketRange(start, bucket);
59363
+ const endInclusive = new Date(Date.parse(range.endExclusive) - 1).toISOString();
59364
+ return {
59365
+ filterType: "date-custom-filter" /* DateCustomFilter */,
59366
+ fieldType: FieldType.Date,
59367
+ operator: DateOperator.Custom,
59368
+ field,
59369
+ table,
59370
+ value: {
59371
+ startDate: range.start,
59372
+ endDate: endInclusive
59373
+ },
59374
+ dateBucket: bucket,
59375
+ fromInBucket: true
59376
+ };
59377
+ }
59031
59378
  const dateComparisonOperator = QUERY_TO_DATE_COMPARISON_OPERATOR[compactOperatorKey] ?? QUERY_TO_DATE_COMPARISON_OPERATOR[operatorKey];
59032
59379
  if (!dateComparisonOperator) {
59033
59380
  throw new Error(`Unsupported date operator "${String(rule.operator)}"`);
@@ -59214,6 +59561,31 @@ var filterStackToQueryBuilderFilters = (filterStack, fieldConfigByName, qualifyA
59214
59561
  ) : base;
59215
59562
  return qualified;
59216
59563
  };
59564
+ var queryBuilderFiltersForEditor = (group) => {
59565
+ const mapEntry = (entry) => {
59566
+ if (isCombinator(entry)) return entry;
59567
+ if (isRuleGroup(entry)) {
59568
+ return queryBuilderFiltersForEditor(entry);
59569
+ }
59570
+ if (!isRule(entry)) return entry;
59571
+ const operator = String(entry.operator ?? "").trim().toLowerCase().replace(/[_\s]+/g, "");
59572
+ if (operator !== "inbucket") return entry;
59573
+ const { start, bucket } = parseInBucketValue(entry.value);
59574
+ const range = getExclusiveDateBucketRange(start, bucket);
59575
+ const endInclusive = new Date(
59576
+ Date.parse(range.endExclusive) - 1
59577
+ ).toISOString();
59578
+ return {
59579
+ ...entry,
59580
+ operator: "between",
59581
+ value: [range.start, endInclusive]
59582
+ };
59583
+ };
59584
+ return {
59585
+ combinator: normalizeCombinator(group.combinator, "and"),
59586
+ rules: (group.rules ?? []).map(mapEntry)
59587
+ };
59588
+ };
59217
59589
  var queryBuilderFiltersToFilterStack = (query, fieldConfigByName) => {
59218
59590
  if (!isRuleGroup(query)) {
59219
59591
  throw new Error("Query must be a rule group");
@@ -59732,6 +60104,7 @@ var AXIS_FORMAT_OPTIONS = [
59732
60104
  var USEFORM_FILTERS_DEBUG_FLAG = "__QUILL_DEBUG_USEFORM_FILTERS__";
59733
60105
  var USEFORM_REFRESH_DEBUG_FLAG = "__QUILL_DEBUG_USEFORM_REFRESH__";
59734
60106
  var USEFORM_PIVOT_SHAPE_DEBUG_FLAG = "__QUILL_DEBUG_USEFORM_PIVOT_SHAPE__";
60107
+ var USEFORM_TASK_DEBUG_FLAG = "__QUILL_DEBUG_USEFORM_TASKS__";
59735
60108
  var isUseFormFiltersDebugEnabled = () => {
59736
60109
  const globalValue = typeof globalThis !== "undefined" ? globalThis?.[USEFORM_FILTERS_DEBUG_FLAG] : void 0;
59737
60110
  if (globalValue === true) {
@@ -59758,6 +60131,23 @@ var isUseFormRefreshDebugEnabled = () => {
59758
60131
  }
59759
60132
  return false;
59760
60133
  };
60134
+ var isUseFormTaskDebugEnabled = () => {
60135
+ const globalValue = typeof globalThis !== "undefined" ? globalThis?.[USEFORM_TASK_DEBUG_FLAG] : void 0;
60136
+ if (globalValue === true) {
60137
+ return true;
60138
+ }
60139
+ if (typeof process !== "undefined" && typeof process.env !== "undefined") {
60140
+ const envValue = String(
60141
+ process?.env?.QUILL_DEBUG_USEFORM_TASKS ?? ""
60142
+ ).trim().toLowerCase();
60143
+ return envValue === "1" || envValue === "true";
60144
+ }
60145
+ return false;
60146
+ };
60147
+ var logUseFormTaskDebug = (label, payload) => {
60148
+ if (!isUseFormTaskDebugEnabled()) return;
60149
+ console.log(`[useReport][task] ${label}`, payload);
60150
+ };
59761
60151
  var isUseFormPivotShapeDebugEnabled = () => {
59762
60152
  const globalValue = typeof globalThis !== "undefined" ? globalThis?.[USEFORM_PIVOT_SHAPE_DEBUG_FLAG] : void 0;
59763
60153
  if (globalValue === true) {
@@ -60242,6 +60632,8 @@ function normalizePivotForRefreshComparison(pivot) {
60242
60632
  const {
60243
60633
  rowFieldTable: _pivotRowTable,
60244
60634
  columnFieldTable: _pivotColumnTable,
60635
+ rowFilter: _rowFilter,
60636
+ columnFilter: _columnFilter,
60245
60637
  aggregations,
60246
60638
  ...pivotRest
60247
60639
  } = record;
@@ -61851,16 +62243,6 @@ function mergeDisplayAndSourceForTableFormats(args) {
61851
62243
  });
61852
62244
  return { columns, formatByColumnOptionId };
61853
62245
  }
61854
- var USE_FORM_AXIS_SERIES_COLORS = [
61855
- "#6366f1",
61856
- "#f59e0b",
61857
- "#10b981",
61858
- "#ef4444",
61859
- "#8b5cf6",
61860
- "#06b6d4",
61861
- "#f97316",
61862
- "#84cc16"
61863
- ];
61864
62246
  function axisFormatToSelectLabel(format9) {
61865
62247
  const raw = String(format9 ?? "").trim();
61866
62248
  const exact = AXIS_FORMAT_OPTIONS.find((option) => option.value === raw);
@@ -62340,6 +62722,9 @@ async function loadViaInMemoryEngines({
62340
62722
  pivot,
62341
62723
  reportBuilderState,
62342
62724
  allowReportTaskBootstrap = false,
62725
+ debugSource,
62726
+ debugRunId,
62727
+ debugLoadRequestId,
62343
62728
  draftSessionId
62344
62729
  }) {
62345
62730
  const requestedTask = allowReportTaskBootstrap ? "report" : "item";
@@ -62349,6 +62734,17 @@ async function loadViaInMemoryEngines({
62349
62734
  rowsPerRequest: DEFAULT_USE_REPORT_ROWS_PER_REQUEST
62350
62735
  }
62351
62736
  } : {};
62737
+ logUseFormTaskDebug("dispatch fetchReport", {
62738
+ reportId,
62739
+ task: requestedTask,
62740
+ source: debugSource ?? "unknown",
62741
+ runId: debugRunId ?? null,
62742
+ loadRequestId: debugLoadRequestId ?? null,
62743
+ allowReportTaskBootstrap,
62744
+ filterCount: internalFilters.length,
62745
+ hasPivot: Boolean(pivot),
62746
+ hasReportBuilderState: Boolean(reportBuilderState)
62747
+ });
62352
62748
  const { report, error } = await fetchReport({
62353
62749
  reportId,
62354
62750
  client,
@@ -62428,6 +62824,9 @@ async function loadViaPivotTemplate({
62428
62824
  reportBuilderState,
62429
62825
  baseReport,
62430
62826
  schema,
62827
+ debugSource,
62828
+ debugRunId,
62829
+ debugLoadRequestId,
62431
62830
  draftSessionId
62432
62831
  }) {
62433
62832
  const pivotForTemplate = enrichPivotRowFieldTypeForTemplate(
@@ -62435,6 +62834,16 @@ async function loadViaPivotTemplate({
62435
62834
  schema,
62436
62835
  baseReport
62437
62836
  );
62837
+ logUseFormTaskDebug("dispatch fetchReport", {
62838
+ reportId,
62839
+ task: "pivot-template",
62840
+ source: debugSource ?? "unknown",
62841
+ runId: debugRunId ?? null,
62842
+ loadRequestId: debugLoadRequestId ?? null,
62843
+ filterCount: internalFilters.length,
62844
+ hasPivot: Boolean(pivotForTemplate),
62845
+ hasReportBuilderState: Boolean(reportBuilderState)
62846
+ });
62438
62847
  const { report, error } = await fetchPivotTemplateReportForUseForm({
62439
62848
  reportId,
62440
62849
  client,
@@ -62662,8 +63071,19 @@ async function loadPivotTemplateInParallelWithReportTask({
62662
63071
  customFields,
62663
63072
  dashboardName,
62664
63073
  pivotRefreshOnly = false,
63074
+ debugSource,
63075
+ debugRunId,
63076
+ debugLoadRequestId,
62665
63077
  draftSessionId
62666
63078
  }) {
63079
+ logUseFormTaskDebug("parallel loader route", {
63080
+ reportId,
63081
+ source: debugSource ?? "unknown",
63082
+ runId: debugRunId ?? null,
63083
+ loadRequestId: debugLoadRequestId ?? null,
63084
+ pivotRefreshOnly,
63085
+ tasks: pivotRefreshOnly ? ["pivot-template"] : ["report", "pivot-template", "report-builder-state"]
63086
+ });
62667
63087
  if (pivotRefreshOnly) {
62668
63088
  const pivotOnlyResult = await loadViaPivotTemplate({
62669
63089
  reportId,
@@ -62676,6 +63096,9 @@ async function loadPivotTemplateInParallelWithReportTask({
62676
63096
  reportBuilderState,
62677
63097
  baseReport,
62678
63098
  schema,
63099
+ debugSource,
63100
+ debugRunId,
63101
+ debugLoadRequestId,
62679
63102
  draftSessionId
62680
63103
  });
62681
63104
  return pivotOnlyResult;
@@ -62691,6 +63114,9 @@ async function loadPivotTemplateInParallelWithReportTask({
62691
63114
  pivot,
62692
63115
  reportBuilderState,
62693
63116
  allowReportTaskBootstrap: true,
63117
+ debugSource,
63118
+ debugRunId,
63119
+ debugLoadRequestId,
62694
63120
  draftSessionId
62695
63121
  }),
62696
63122
  loadViaPivotTemplate({
@@ -62704,6 +63130,9 @@ async function loadPivotTemplateInParallelWithReportTask({
62704
63130
  reportBuilderState,
62705
63131
  baseReport,
62706
63132
  schema,
63133
+ debugSource,
63134
+ debugRunId,
63135
+ debugLoadRequestId,
62707
63136
  draftSessionId
62708
63137
  }),
62709
63138
  fetchReportBuilderStateByReportId({
@@ -62886,6 +63315,9 @@ async function loadReportForUseForm({
62886
63315
  customFields,
62887
63316
  dashboardName,
62888
63317
  useInMemoryEngines,
63318
+ debugSource,
63319
+ debugRunId,
63320
+ debugLoadRequestId,
62889
63321
  draftSessionId
62890
63322
  }) {
62891
63323
  const effectivePivot = pivot ?? initialReportBuilderState?.pivot ?? void 0;
@@ -62894,6 +63326,18 @@ async function loadReportForUseForm({
62894
63326
  ...initialReportBuilderState,
62895
63327
  pivot: effectivePivot ?? initialReportBuilderState.pivot ?? null
62896
63328
  } : void 0;
63329
+ logUseFormTaskDebug("resolve loader route", {
63330
+ reportId,
63331
+ source: debugSource ?? "unknown",
63332
+ runId: debugRunId ?? null,
63333
+ loadRequestId: debugLoadRequestId ?? null,
63334
+ hasPivot,
63335
+ hasReportBuilderState: Boolean(reportBuilderStateForLoad),
63336
+ allowReportTaskBootstrap,
63337
+ includeReportBuilderStateInPivotTask,
63338
+ filterCount: internalFilters.length,
63339
+ useInMemoryEngines
63340
+ });
62897
63341
  if (hasPivot) {
62898
63342
  const pivotResult = await loadPivotTemplateInParallelWithReportTask({
62899
63343
  reportId,
@@ -62909,6 +63353,9 @@ async function loadReportForUseForm({
62909
63353
  customFields,
62910
63354
  dashboardName,
62911
63355
  pivotRefreshOnly: includeReportBuilderStateInPivotTask,
63356
+ debugSource,
63357
+ debugRunId,
63358
+ debugLoadRequestId,
62912
63359
  draftSessionId
62913
63360
  });
62914
63361
  const pivotRows = pivotResult.report?.pivotRows;
@@ -62957,6 +63404,9 @@ async function loadReportForUseForm({
62957
63404
  schema,
62958
63405
  customFields,
62959
63406
  dashboardName,
63407
+ debugSource,
63408
+ debugRunId,
63409
+ debugLoadRequestId,
62960
63410
  draftSessionId
62961
63411
  });
62962
63412
  const normalizedBootstrapResult = bootstrapResult.report?.pivot == null ? stripPivotFromResult(bootstrapResult) : bootstrapResult;
@@ -62964,6 +63414,15 @@ async function loadReportForUseForm({
62964
63414
  }
62965
63415
  const shouldUseReportTaskForReload = internalFilters.length > 0;
62966
63416
  const resolvedTask = shouldUseReportTaskForReload ? "report" : "item";
63417
+ logUseFormTaskDebug("non-bootstrap task route", {
63418
+ reportId,
63419
+ task: resolvedTask,
63420
+ source: debugSource ?? "unknown",
63421
+ runId: debugRunId ?? null,
63422
+ loadRequestId: debugLoadRequestId ?? null,
63423
+ reason: shouldUseReportTaskForReload ? "live internal filters are present" : "no live internal filters are present",
63424
+ filterCount: internalFilters.length
63425
+ });
62967
63426
  return loadViaInMemoryEngines({
62968
63427
  reportId,
62969
63428
  client,
@@ -62972,6 +63431,9 @@ async function loadReportForUseForm({
62972
63431
  tenants,
62973
63432
  flags,
62974
63433
  allowReportTaskBootstrap: shouldUseReportTaskForReload,
63434
+ debugSource,
63435
+ debugRunId,
63436
+ debugLoadRequestId,
62975
63437
  draftSessionId
62976
63438
  });
62977
63439
  }
@@ -62990,12 +63452,18 @@ async function loadReportForUseForm({
62990
63452
  function generateDraftSessionId() {
62991
63453
  return typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `draft-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
62992
63454
  }
63455
+ var nextUseReportDebugRunId = 0;
62993
63456
  function useReport(reportIdArg, options = {}) {
62994
63457
  const propReportId = String(reportIdArg ?? "").trim();
62995
63458
  const [createdReportId, setCreatedReportId] = (0, import_react61.useState)(null);
62996
63459
  const effectiveReportId = propReportId || createdReportId || "";
62997
63460
  const { eventTracking } = (0, import_react61.useContext)(EventTrackingContext);
62998
63461
  const [draftSessionId, setDraftSessionId] = (0, import_react61.useState)(generateDraftSessionId);
63462
+ const [taskDebugRunId] = (0, import_react61.useState)(() => {
63463
+ nextUseReportDebugRunId += 1;
63464
+ return nextUseReportDebugRunId;
63465
+ });
63466
+ const taskDebugLoadRequestIdRef = (0, import_react61.useRef)(0);
62999
63467
  const useInMemoryEngines = options.useInMemoryEngines ?? false;
63000
63468
  const restrictFieldOptionsToSelectedDatasources = options.restrictFieldOptionsToSelectedDatasources ?? true;
63001
63469
  const reportOverride = options.reportOverride ?? null;
@@ -64298,6 +64766,8 @@ function useReport(reportIdArg, options = {}) {
64298
64766
  clientHash
64299
64767
  }),
64300
64768
  queryFn: createUseFormQueryFn(async () => {
64769
+ taskDebugLoadRequestIdRef.current += 1;
64770
+ const debugLoadRequestId = taskDebugLoadRequestIdRef.current;
64301
64771
  const allowReportTaskBootstrap = !initialReportBuilderState && bootstrapReportTaskUsedForReportIdRef.current !== effectiveReportId;
64302
64772
  const loadTargetId = String(effectiveReportId ?? "").trim();
64303
64773
  const sourceReportIdentity = String(
@@ -64321,6 +64791,9 @@ function useReport(reportIdArg, options = {}) {
64321
64791
  customFields: customFieldsRef.current,
64322
64792
  dashboardName: resolvedSourceDashboardName,
64323
64793
  useInMemoryEngines,
64794
+ debugSource: "initial-load",
64795
+ debugRunId: taskDebugRunId,
64796
+ debugLoadRequestId,
64324
64797
  draftSessionId: draftSessionId || void 0
64325
64798
  });
64326
64799
  return loadResult;
@@ -65628,6 +66101,7 @@ function useReport(reportIdArg, options = {}) {
65628
66101
  ...sourceReport,
65629
66102
  reportBuilderState: effectiveReportBuilderState
65630
66103
  };
66104
+ taskDebugLoadRequestIdRef.current += 1;
65631
66105
  const pivotRefreshResult = await loadReportForUseForm({
65632
66106
  reportId: effectiveReportId,
65633
66107
  initialReportBuilderState: effectiveReportBuilderState,
@@ -65643,6 +66117,9 @@ function useReport(reportIdArg, options = {}) {
65643
66117
  customFields: schemaData.customFields,
65644
66118
  dashboardName: resolvedSourceDashboardName,
65645
66119
  useInMemoryEngines,
66120
+ debugSource: "pivot-refresh",
66121
+ debugRunId: taskDebugRunId,
66122
+ debugLoadRequestId: taskDebugLoadRequestIdRef.current,
65646
66123
  draftSessionId: draftSessionId || void 0
65647
66124
  });
65648
66125
  return pivotRefreshResult;
@@ -65787,6 +66264,9 @@ function useReport(reportIdArg, options = {}) {
65787
66264
  return {
65788
66265
  ...previousReport,
65789
66266
  ...report,
66267
+ xAxisFormat: previousReport.xAxisFormat,
66268
+ columns: previousReport.columns,
66269
+ yAxisFields: previousReport.yAxisFields,
65790
66270
  pivot: previousReport.pivot,
65791
66271
  pivotRows: previousReport.pivotRows,
65792
66272
  pivotColumns: previousReport.pivotColumns,
@@ -65923,8 +66403,8 @@ function useReport(reportIdArg, options = {}) {
65923
66403
  for (const column of chartAxesBaseChart.columns ?? []) {
65924
66404
  registerOption(column.field, column.label, column.format);
65925
66405
  }
65926
- for (const yAxis of chartAxesBaseChart.yAxisFields ?? []) {
65927
- registerOption(yAxis.field, yAxis.label, yAxis.format);
66406
+ for (const yAxis2 of chartAxesBaseChart.yAxisFields ?? []) {
66407
+ registerOption(yAxis2.field, yAxis2.label, yAxis2.format);
65928
66408
  }
65929
66409
  if (chartAxesBaseChart.pivot?.columnField) {
65930
66410
  for (const aggregationAxis of buildPivotAggregationAxisFields(
@@ -66147,48 +66627,35 @@ function useReport(reportIdArg, options = {}) {
66147
66627
  }),
66148
66628
  [baseChart?.showLegend, chartVisibilityOverrides]
66149
66629
  );
66150
- const axisConfig = (0, import_react61.useMemo)(() => {
66630
+ const xAxis = (0, import_react61.useMemo)(() => {
66151
66631
  const pivotBucketXAxis = isPivotTableDateBucketRowAxis(
66152
66632
  chartAxesBaseChart,
66153
66633
  resolvedXAxisField
66154
66634
  );
66155
66635
  const xFormatLabel = pivotBucketXAxis && String(resolvedXAxisFormat ?? "").trim() === "string" ? "date" : axisFormatToSelectLabel(resolvedXAxisFormat);
66156
66636
  return {
66157
- xAxis: {
66158
- field: resolvedXAxisField,
66159
- label: resolvedXAxisLabel,
66160
- format: xFormatLabel,
66161
- show: true,
66162
- rotation: 0,
66163
- fontSize: 12
66164
- },
66165
- yAxis: {
66166
- fields: resolvedYAxisFields.map((yAxisField, index) => ({
66167
- field: yAxisField.field,
66168
- label: String(yAxisField.label ?? "").trim(),
66169
- format: axisFormatToSelectLabel(
66170
- toAxisFormat(yAxisField.format, "string")
66171
- ),
66172
- color: USE_FORM_AXIS_SERIES_COLORS[index % USE_FORM_AXIS_SERIES_COLORS.length]
66173
- })),
66174
- label: "",
66175
- show: true,
66176
- min: "",
66177
- max: "",
66178
- fontSize: 12
66179
- },
66180
- legend: {
66181
- show: chartVisibility.showLegend
66182
- }
66637
+ field: resolvedXAxisField,
66638
+ label: resolvedXAxisLabel,
66639
+ format: xFormatLabel
66183
66640
  };
66184
66641
  }, [
66185
66642
  chartAxesBaseChart,
66186
66643
  resolvedXAxisLabel,
66187
66644
  resolvedXAxisField,
66188
- resolvedXAxisFormat,
66189
- resolvedYAxisFields,
66190
- chartVisibility.showLegend
66645
+ resolvedXAxisFormat
66191
66646
  ]);
66647
+ const yAxis = (0, import_react61.useMemo)(
66648
+ () => ({
66649
+ fields: resolvedYAxisFields.map((yAxisField) => ({
66650
+ field: yAxisField.field,
66651
+ label: String(yAxisField.label ?? "").trim(),
66652
+ format: axisFormatToSelectLabel(
66653
+ toAxisFormat(yAxisField.format, "string")
66654
+ )
66655
+ }))
66656
+ }),
66657
+ [resolvedYAxisFields]
66658
+ );
66192
66659
  const resolvedYAxisFieldsForDisplay = (0, import_react61.useMemo)(() => {
66193
66660
  if (!baseChart) return resolvedYAxisFields;
66194
66661
  return mapResolvedPivotYAxisFieldsForDisplay({
@@ -66245,6 +66712,124 @@ function useReport(reportIdArg, options = {}) {
66245
66712
  resolvedXAxisLabel,
66246
66713
  resolvedYAxisFieldsForDisplay
66247
66714
  ]);
66715
+ const filterOptions = (0, import_react61.useMemo)(() => {
66716
+ const out = [];
66717
+ for (const [field, values] of filterValueOptionsByFieldName) {
66718
+ out.push({
66719
+ field,
66720
+ fieldType: "string",
66721
+ operator: "in",
66722
+ options: values.map(({ label, value }) => ({ label, value }))
66723
+ });
66724
+ }
66725
+ const pivot = chart?.pivot;
66726
+ const rowField = String(pivot?.rowField ?? "").trim();
66727
+ if (rowField && isDateType(String(pivot?.rowFieldType ?? ""))) {
66728
+ const field = pivot?.rowFieldTable ? `${pivot.rowFieldTable}.${rowField}` : rowField;
66729
+ const bucket = dateBucket || pivot?.dateBucket || "month";
66730
+ const byRaw = /* @__PURE__ */ new Map();
66731
+ for (const row of chart?.rows ?? []) {
66732
+ const record = row;
66733
+ const raw = record.__quillRawDate;
66734
+ if (raw == null || raw === "") continue;
66735
+ const key = String(raw);
66736
+ if (!byRaw.has(key)) {
66737
+ byRaw.set(key, String(record[rowField] ?? key));
66738
+ }
66739
+ }
66740
+ out.push({
66741
+ field,
66742
+ fieldType: "date",
66743
+ operator: "inBucket",
66744
+ dateBucket: bucket,
66745
+ options: [...byRaw.keys()].sort().map((value) => ({
66746
+ value,
66747
+ label: byRaw.get(value) ?? value
66748
+ }))
66749
+ });
66750
+ }
66751
+ return out;
66752
+ }, [
66753
+ chart?.pivot,
66754
+ chart?.rows,
66755
+ dateBucket,
66756
+ filterValueOptionsByFieldName
66757
+ ]);
66758
+ const chartForUi = (0, import_react61.useMemo)(() => {
66759
+ if (!chart?.pivot) return chart;
66760
+ const pivot = chart.pivot;
66761
+ const qualify = (field, table2) => table2 ? `${table2}.${field}` : field;
66762
+ const labelFor = (field) => chart.columns?.find((column) => column.field === field)?.label ?? field.split(".").pop().replace(/[_-]+/g, " ").replace(/\b\w/g, (char) => char.toUpperCase());
66763
+ const matchField = (entryField, field, table2) => {
66764
+ const qualified = qualify(field, table2);
66765
+ return entryField === qualified || entryField === field || entryField.endsWith(`.${field}`);
66766
+ };
66767
+ const selectedValue = (field, operator, options2) => {
66768
+ const rule = filtersForQueryBuilder.rules.find(
66769
+ (entry) => typeof entry === "object" && entry !== null && "field" in entry && entry.field === field && entry.operator === operator
66770
+ );
66771
+ if (!rule) return null;
66772
+ const raw = operator === "inBucket" ? rule.value?.start : Array.isArray(rule.value) ? rule.value[0] : void 0;
66773
+ if (raw == null) return null;
66774
+ const value = String(raw);
66775
+ return options2.some((option) => option.value === value) ? value : null;
66776
+ };
66777
+ let rowFilter = null;
66778
+ const rowField = String(pivot.rowField ?? "").trim();
66779
+ if (rowField) {
66780
+ if (isDateType(String(pivot.rowFieldType ?? ""))) {
66781
+ const entry = filterOptions.find(
66782
+ (option) => option.operator === "inBucket" && matchField(option.field, rowField, pivot.rowFieldTable)
66783
+ );
66784
+ if (entry) {
66785
+ const field = qualify(rowField, pivot.rowFieldTable);
66786
+ rowFilter = {
66787
+ ...entry,
66788
+ field,
66789
+ label: labelFor(rowField),
66790
+ value: selectedValue(field, entry.operator, entry.options)
66791
+ };
66792
+ }
66793
+ } else {
66794
+ const entry = filterOptions.find(
66795
+ (option) => option.operator === "in" && matchField(option.field, rowField, pivot.rowFieldTable)
66796
+ );
66797
+ if (entry) {
66798
+ const field = qualify(rowField, pivot.rowFieldTable);
66799
+ rowFilter = {
66800
+ ...entry,
66801
+ field,
66802
+ label: labelFor(rowField),
66803
+ value: selectedValue(field, entry.operator, entry.options)
66804
+ };
66805
+ }
66806
+ }
66807
+ }
66808
+ let columnFilter = null;
66809
+ const columnField = String(pivot.columnField ?? "").trim();
66810
+ if (columnField) {
66811
+ const entry = filterOptions.find(
66812
+ (option) => option.operator === "in" && matchField(option.field, columnField, pivot.columnFieldTable)
66813
+ );
66814
+ if (entry) {
66815
+ const field = qualify(columnField, pivot.columnFieldTable);
66816
+ columnFilter = {
66817
+ ...entry,
66818
+ field,
66819
+ label: labelFor(columnField),
66820
+ value: selectedValue(field, entry.operator, entry.options)
66821
+ };
66822
+ }
66823
+ }
66824
+ return {
66825
+ ...chart,
66826
+ pivot: {
66827
+ ...pivot,
66828
+ rowFilter,
66829
+ columnFilter
66830
+ }
66831
+ };
66832
+ }, [chart, filterOptions, filtersForQueryBuilder]);
66248
66833
  const isPivotTableChart = String(chartType ?? "").toLowerCase() === "table" && Boolean(
66249
66834
  chart && chart.pivot && Array.isArray(chart.columns) && chart.columns.length > 0
66250
66835
  );
@@ -66575,14 +67160,6 @@ function useReport(reportIdArg, options = {}) {
66575
67160
  schemaColumnOptions,
66576
67161
  table.columns
66577
67162
  ]);
66578
- const availableFields = (0, import_react61.useMemo)(
66579
- () => tableColumnPickerPoolOptions.map((option) => ({
66580
- id: option.value,
66581
- label: option.label,
66582
- type: option.type
66583
- })),
66584
- [tableColumnPickerPoolOptions]
66585
- );
66586
67163
  const axisSelectFormatLabels = (0, import_react61.useMemo)(
66587
67164
  () => AXIS_FORMAT_OPTIONS.map((option) => option.label),
66588
67165
  []
@@ -67028,8 +67605,12 @@ function useReport(reportIdArg, options = {}) {
67028
67605
  showLegend: Boolean(effectiveNextState.showLegend)
67029
67606
  }));
67030
67607
  }
67031
- if (effectiveNextState.chartAxes !== void 0) {
67032
- const cx = effectiveNextState.chartAxes;
67608
+ if (effectiveNextState.xAxis !== void 0 || effectiveNextState.yAxis !== void 0 || effectiveNextState.chartAxes !== void 0) {
67609
+ const cx = {
67610
+ ...effectiveNextState.chartAxes,
67611
+ ...effectiveNextState.xAxis !== void 0 ? { xAxis: effectiveNextState.xAxis } : {},
67612
+ ...effectiveNextState.yAxis !== void 0 ? { yAxis: effectiveNextState.yAxis } : {}
67613
+ };
67033
67614
  setChartAxisEdits((previousEdits) => {
67034
67615
  const nextEdits = { ...previousEdits };
67035
67616
  if (cx.xAxis) {
@@ -67549,8 +68130,9 @@ function useReport(reportIdArg, options = {}) {
67549
68130
  }
67550
68131
  };
67551
68132
  const setFilters = (nextFilters) => {
68133
+ const resolved = typeof nextFilters === "function" ? nextFilters(filtersForQueryBuilder) : nextFilters;
67552
68134
  const preparedForStack = prepareQueryBuilderFiltersForSet(
67553
- nextFilters,
68135
+ resolved,
67554
68136
  queryFilters
67555
68137
  );
67556
68138
  const nextFiltersNormalizedForConfig = normalizeQueryBuilderFiltersForConfig(preparedForStack);
@@ -67591,17 +68173,16 @@ function useReport(reportIdArg, options = {}) {
67591
68173
  });
67592
68174
  }
67593
68175
  } catch (error) {
67594
- if (isUseFormFiltersDebugEnabled()) {
67595
- console.error("[useForm-debug] setFilters swallowed error", {
67596
- error: error instanceof Error ? error.message : String(error),
67597
- requestedRules: (nextFilters?.rules ?? []).map((rule) => ({
67598
- table: rule?.table,
67599
- field: rule?.field,
67600
- operator: rule?.operator
67601
- })),
67602
- fieldConfigKeys: Object.keys(queryBuilderFieldConfigByName ?? {})
67603
- });
67604
- }
68176
+ console.error("[useForm] setFilters swallowed error", {
68177
+ error: error instanceof Error ? error.message : String(error),
68178
+ requestedRules: (resolved?.rules ?? []).map((rule) => ({
68179
+ table: rule?.table,
68180
+ field: rule?.field,
68181
+ operator: rule?.operator,
68182
+ value: rule?.value
68183
+ })),
68184
+ fieldConfigKeys: Object.keys(queryBuilderFieldConfigByName ?? {})
68185
+ });
67605
68186
  }
67606
68187
  };
67607
68188
  const saveChanges = (0, import_react61.useCallback)(async () => {
@@ -67663,7 +68244,7 @@ function useReport(reportIdArg, options = {}) {
67663
68244
  ]);
67664
68245
  return {
67665
68246
  /* ── Chart & table (exceptions: not value/options pairs) ── */
67666
- chart,
68247
+ chart: chartForUi,
67667
68248
  chartLoading,
67668
68249
  table,
67669
68250
  tableLoading,
@@ -67701,9 +68282,9 @@ function useReport(reportIdArg, options = {}) {
67701
68282
  columnActions,
67702
68283
  /** Schema columns for current datasources — pool for the table column picker. */
67703
68284
  columnOptions: tableColumnPickerPoolOptions,
67704
- xAxis: chartAxes.xAxis,
68285
+ xAxis,
67705
68286
  xAxisOptions: normalizedChartXAxisOptions,
67706
- yAxis: chartAxes.yAxis,
68287
+ yAxis,
67707
68288
  yAxisOptions: normalizedChartYAxisOptions,
67708
68289
  /** Same strings as `axisSelectFormatLabels` (X/Y share chart format presets). */
67709
68290
  xAxisFormatOptions: xAxisFormatOptionLabels,
@@ -67711,8 +68292,6 @@ function useReport(reportIdArg, options = {}) {
67711
68292
  /** Table column format dropdown labels (same set as chart axis formats). */
67712
68293
  tableFormatOptions: axisSelectFormatLabels,
67713
68294
  showLegend: chartVisibility.showLegend,
67714
- axisConfig,
67715
- availableFields,
67716
68295
  axisSelectFormatLabels,
67717
68296
  /** @deprecated Prefer top-level `xAxis`, `yAxis`, and `showLegend`. */
67718
68297
  chartAxes,
@@ -67725,6 +68304,12 @@ function useReport(reportIdArg, options = {}) {
67725
68304
  hasTableDrivenColumnOrder,
67726
68305
  filters: filtersForQueryBuilder,
67727
68306
  filterQueryBuilderProps,
68307
+ /**
68308
+ * Filter value pick lists for custom UIs (string unique values + pivot date
68309
+ * buckets). Same string data as `filterQueryBuilderProps.getValues`; not
68310
+ * wired into react-querybuilder unless you use it yourself.
68311
+ */
68312
+ filterOptions,
67728
68313
  /** True while `report-builder-unique-values` runs for filter value options (not chart/table load). */
67729
68314
  filterUniqueValuesLoading,
67730
68315
  limit,
@@ -68105,11 +68690,11 @@ function Chat({
68105
68690
  setIsLoading(false);
68106
68691
  };
68107
68692
  const submitDefaultMessage = async (nextMessages, abortController) => {
68108
- const clientId = client.clientId ?? client.publicKey;
68693
+ const clientId = client.id;
68109
68694
  let responseBuffer = "";
68110
68695
  for await (const chunk of quillStream({
68111
68696
  client: {
68112
- clientId,
68697
+ id: clientId,
68113
68698
  queryEndpoint: client.queryEndpoint,
68114
68699
  streamEndpoint: client.streamEndpoint,
68115
68700
  queryHeaders: client.queryHeaders,
@@ -68193,12 +68778,12 @@ function Chat({
68193
68778
  }
68194
68779
  };
68195
68780
  const submitAgentMessage = async (nextMessages, abortController) => {
68196
- const clientId = client.clientId ?? client.publicKey;
68781
+ const clientId = client.id;
68197
68782
  let updatedMessages = [...nextMessages];
68198
68783
  for await (const event of quillAgentStream({
68199
68784
  endpoint: `${agentEndpoint}/agent/chat`,
68200
68785
  messages: updatedMessages,
68201
- sourceClientId: clientId,
68786
+ sourceClientId: clientId ?? "<unknown>",
68202
68787
  getToken,
68203
68788
  abortSignal: abortController.signal
68204
68789
  })) {
@@ -68266,7 +68851,7 @@ function Chat({
68266
68851
  setIsLoading(true);
68267
68852
  const abortController = new AbortController();
68268
68853
  abortControllerRef.current = abortController;
68269
- const clientId = client.clientId ?? client.publicKey;
68854
+ const clientId = client.id;
68270
68855
  if (!clientId) {
68271
68856
  setInputError("No client selected.");
68272
68857
  setIsLoading(false);
@@ -68563,7 +69148,9 @@ var committedFiltersSignature = (committed) => {
68563
69148
  };
68564
69149
  function useReportFilterDraft(args) {
68565
69150
  const { reportId, committedFilters, queryBuilderProps, setFilters } = args;
68566
- const committed = isQueryBuilderDisplayGroup(committedFilters) ? committedFilters : EMPTY_COMMITTED_FILTERS;
69151
+ const committed = queryBuilderFiltersForEditor(
69152
+ isQueryBuilderDisplayGroup(committedFilters) ? committedFilters : EMPTY_COMMITTED_FILTERS
69153
+ );
68567
69154
  const committedRef = (0, import_react64.useRef)(committed);
68568
69155
  committedRef.current = committed;
68569
69156
  const setFiltersRef = (0, import_react64.useRef)(setFilters);
@@ -68618,6 +69205,12 @@ function useReportFilterDraft(args) {
68618
69205
  setHasUnappliedFilterChanges(false);
68619
69206
  setResetEpoch((epoch) => epoch + 1);
68620
69207
  }, []);
69208
+ const getDefaultField = (0, import_react64.useCallback)((fields) => {
69209
+ const stringField = fields.find(
69210
+ (field) => field.quillFieldType === "string" && String(field.name ?? "").trim()
69211
+ );
69212
+ return stringField?.name ?? fields[0]?.name ?? "";
69213
+ }, []);
68621
69214
  const getDefaultValue = (0, import_react64.useCallback)(
68622
69215
  (rule) => defaultFilterRuleValueForOperator(rule?.operator),
68623
69216
  []
@@ -68628,9 +69221,12 @@ function useReportFilterDraft(args) {
68628
69221
  fields: effectiveFields,
68629
69222
  // Uncontrolled: react-querybuilder owns the draft; only read at mount,
68630
69223
  // while state keeps the next mount hydrated from the latest edits.
68631
- defaultQuery: draftQuery,
69224
+ // Empty draft: omit defaultQuery so addRuleToNewGroups seeds a root rule
69225
+ // (RQB ignores auto-add when defaultQuery.rules is []).
69226
+ ...draftQuery.rules.length > 0 ? { defaultQuery: draftQuery } : {},
68632
69227
  onQueryChange: handleQueryChange,
68633
69228
  addRuleToNewGroups: true,
69229
+ getDefaultField,
68634
69230
  getDefaultValue
68635
69231
  }),
68636
69232
  // eslint-disable-next-line react-hooks/exhaustive-deps -- filterDraftKey covers draftRef resets
@@ -68639,6 +69235,7 @@ function useReportFilterDraft(args) {
68639
69235
  effectiveFields,
68640
69236
  draftQuery,
68641
69237
  handleQueryChange,
69238
+ getDefaultField,
68642
69239
  getDefaultValue,
68643
69240
  filterDraftKey
68644
69241
  ]
@@ -69522,7 +70119,7 @@ var useVirtualTables = () => {
69522
70119
  };
69523
70120
  };
69524
70121
  const handleRefreshSome = async (client, tables) => {
69525
- if (!client.clientId) return schemaData;
70122
+ if (!client.id) return schemaData;
69526
70123
  setLoadingTables({
69527
70124
  ...loadingTables,
69528
70125
  ...tables.reduce((acc, table) => {
@@ -69540,7 +70137,7 @@ var useVirtualTables = () => {
69540
70137
  name: table.name,
69541
70138
  customFieldInfo: table.customFieldInfo,
69542
70139
  id: table._id,
69543
- clientId: client.clientId,
70140
+ clientId: client.id,
69544
70141
  runQueryConfig: { getColumns: true },
69545
70142
  databaseType: client.databaseType,
69546
70143
  useNewNodeSql: true
@@ -69688,11 +70285,12 @@ var useChangelogRefresh = () => {
69688
70285
  reportsDispatch({ type: "DELETE_REPORT", id: reportId });
69689
70286
  dashboardDispatch({ type: "REMOVE_DASHBOARD_ITEM", id: reportId });
69690
70287
  }
69691
- const finalDashboardSet = reloadAllDashboards ? new Set(
69692
- Object.keys(dashboardConfig).filter(
70288
+ const finalDashboardSet = reloadAllDashboards ? /* @__PURE__ */ new Set([
70289
+ ...Object.keys(dashboardConfig).filter(
69693
70290
  (d) => !dashboardsToRemove.has(d)
69694
- )
69695
- ) : dashboardsToReload;
70291
+ ),
70292
+ ...dashboardsToReload
70293
+ ]) : dashboardsToReload;
69696
70294
  const tasks = [];
69697
70295
  const schemaIdsToReload = schemaIds.filter(
69698
70296
  (id) => !schemaIdsToRemove.has(id)
@@ -69808,6 +70406,7 @@ init_constants();
69808
70406
  isQueryBuilderDisplayRule,
69809
70407
  normalizeRelativeDateRules,
69810
70408
  prepareQueryBuilderFiltersForSet,
70409
+ queryBuilderFiltersForEditor,
69811
70410
  quillFetch,
69812
70411
  stripQueryBuilderTransientFields,
69813
70412
  tableColumnFormatFromUiSelection,