@quillsql/react 2.16.36 → 2.16.38

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.js CHANGED
@@ -18858,6 +18858,21 @@ var init_tableProcessing = __esm({
18858
18858
  }
18859
18859
  });
18860
18860
 
18861
+ // src/utils/changelogNotify.ts
18862
+ function setChangelogHandler(handler) {
18863
+ changelogHandler = handler;
18864
+ }
18865
+ function notifyChangelogs(entries) {
18866
+ changelogHandler?.(entries);
18867
+ }
18868
+ var changelogHandler;
18869
+ var init_changelogNotify = __esm({
18870
+ "src/utils/changelogNotify.ts"() {
18871
+ "use strict";
18872
+ changelogHandler = null;
18873
+ }
18874
+ });
18875
+
18861
18876
  // src/utils/dataFetcher.tsx
18862
18877
  var dataFetcher_exports = {};
18863
18878
  __export(dataFetcher_exports, {
@@ -18871,6 +18886,15 @@ __export(dataFetcher_exports, {
18871
18886
  quillFetch: () => quillFetch,
18872
18887
  quillStream: () => quillStream
18873
18888
  });
18889
+ function normalizeChangelogData(data) {
18890
+ if (!data) return data;
18891
+ if (Array.isArray(data.changelogs)) return data;
18892
+ if (!Array.isArray(data.changeLogs)) return data;
18893
+ return {
18894
+ ...data,
18895
+ changelogs: data.changeLogs
18896
+ };
18897
+ }
18874
18898
  function fetchQuillData(responseData) {
18875
18899
  if (!responseData) {
18876
18900
  return null;
@@ -19391,6 +19415,7 @@ var init_dataFetcher = __esm({
19391
19415
  init_reportBuilder();
19392
19416
  init_tableProcessing();
19393
19417
  init_dates();
19418
+ init_changelogNotify();
19394
19419
  quillFetch = async ({
19395
19420
  client,
19396
19421
  task,
@@ -19429,8 +19454,12 @@ var init_dataFetcher = __esm({
19429
19454
  if (result.data?.data && (result.data.queries || result.data.status || result.data.error)) {
19430
19455
  result = result.data;
19431
19456
  }
19457
+ const normalizedData = normalizeChangelogData(result.data);
19458
+ if (task !== "fetch-changelog-list" && Array.isArray(normalizedData?.changelogs)) {
19459
+ notifyChangelogs(normalizedData.changelogs);
19460
+ }
19432
19461
  return {
19433
- data: result.data,
19462
+ data: normalizedData,
19434
19463
  queries: result.queries,
19435
19464
  status: result.status,
19436
19465
  error: result.error
@@ -21674,6 +21703,7 @@ function convertSchemaInfoToTable(schemaData) {
21674
21703
  _id: table._id,
21675
21704
  customFieldInfo: table.customFieldInfo,
21676
21705
  displayName: table.displayName,
21706
+ description: table.description,
21677
21707
  broken: table.broken,
21678
21708
  error: table.error,
21679
21709
  ownerTenantFields: table.ownerTenantFields
@@ -23803,6 +23833,7 @@ function normalizePSTRanges(start, end) {
23803
23833
  }
23804
23834
 
23805
23835
  // src/Context.tsx
23836
+ init_changelogNotify();
23806
23837
  import { jsx } from "react/jsx-runtime";
23807
23838
  var dummySetter = () => {
23808
23839
  };
@@ -24241,7 +24272,8 @@ var ContextProvider = ({
24241
24272
  flags,
24242
24273
  isAdmin,
24243
24274
  getAuthorizationToken = async () => "",
24244
- eventTracking = null
24275
+ eventTracking = null,
24276
+ onChangelogs
24245
24277
  }) => {
24246
24278
  const cacheCabByTypeRef = useRef({});
24247
24279
  const getCacheCab = useCallback((storageType) => {
@@ -24251,6 +24283,10 @@ var ContextProvider = ({
24251
24283
  }
24252
24284
  return cacheCabByTypeRef.current[key];
24253
24285
  }, []);
24286
+ useEffect(() => {
24287
+ setChangelogHandler(onChangelogs ?? null);
24288
+ return () => setChangelogHandler(null);
24289
+ }, [onChangelogs]);
24254
24290
  const [client, setClient] = useState(
24255
24291
  typeof window !== "undefined" && sessionStorage ? JSON.parse(sessionStorage.getItem("quill-client") ?? "null") : null
24256
24292
  );
@@ -24308,8 +24344,7 @@ var ContextProvider = ({
24308
24344
  customReportFiltersReducer,
24309
24345
  {}
24310
24346
  );
24311
- const filterOptionsAbortControllers = useRef(/* @__PURE__ */ new Set());
24312
- const loadingFiltersForDashboard = useRef(/* @__PURE__ */ new Set());
24347
+ const dashboardFilterLoadState = useRef({});
24313
24348
  const backfilledDashboards = useRef(/* @__PURE__ */ new Set());
24314
24349
  const [reportFilters, reportFiltersDispatch] = useReducer(
24315
24350
  reportFiltersReducer,
@@ -24675,14 +24710,15 @@ var ContextProvider = ({
24675
24710
  }
24676
24711
  }
24677
24712
  async function loadFiltersForDashboard(dashboardName, filters, updatedFilterLabel, customFilters) {
24678
- if (loadingFiltersForDashboard.current.has(dashboardName)) {
24679
- return;
24680
- }
24681
- loadingFiltersForDashboard.current.add(dashboardName);
24713
+ const previousLoad = dashboardFilterLoadState.current[dashboardName];
24714
+ previousLoad?.controllers.forEach((controller) => controller.abort());
24715
+ const nextRequestId = (previousLoad?.requestId ?? 0) + 1;
24716
+ dashboardFilterLoadState.current[dashboardName] = {
24717
+ requestId: nextRequestId,
24718
+ controllers: /* @__PURE__ */ new Set()
24719
+ };
24720
+ const shouldApply = () => dashboardFilterLoadState.current[dashboardName]?.requestId === nextRequestId;
24682
24721
  try {
24683
- filterOptionsAbortControllers.current.forEach(
24684
- (controller) => controller.abort()
24685
- );
24686
24722
  dashboardFiltersDispatch({
24687
24723
  type: "ADD_DASHBOARD_FILTERS",
24688
24724
  dashboardName,
@@ -24696,6 +24732,9 @@ var ContextProvider = ({
24696
24732
  });
24697
24733
  await Promise.allSettled(
24698
24734
  filters.map(async (filter) => {
24735
+ if (!shouldApply()) {
24736
+ return null;
24737
+ }
24699
24738
  if (filter.filterType === "date_range") {
24700
24739
  dashboardFiltersDispatch({
24701
24740
  type: "UPDATE_DASHBOARD_FILTER",
@@ -24721,11 +24760,11 @@ var ContextProvider = ({
24721
24760
  return null;
24722
24761
  }
24723
24762
  if (filter.filterType === "tenant") {
24724
- await fetchTenantFilterOptions(dashboardName, filter);
24763
+ await fetchTenantFilterOptions(dashboardName, filter, shouldApply);
24725
24764
  return null;
24726
24765
  }
24727
24766
  const filterOptionsAbortController = new AbortController();
24728
- filterOptionsAbortControllers.current.add(
24767
+ dashboardFilterLoadState.current[dashboardName]?.controllers.add(
24729
24768
  filterOptionsAbortController
24730
24769
  );
24731
24770
  try {
@@ -24759,33 +24798,36 @@ var ContextProvider = ({
24759
24798
  getToken: getAuthorizationToken
24760
24799
  });
24761
24800
  const filterOptions = result.data?.filters[0]?.options ?? [];
24762
- dashboardFiltersDispatch({
24763
- type: "UPDATE_DASHBOARD_FILTER",
24764
- dashboardName,
24765
- filterName: filter.label,
24766
- data: {
24767
- filter: {
24768
- ...filter,
24769
- options: filterOptions
24770
- },
24771
- loading: false
24772
- }
24773
- });
24774
- return null;
24775
- } catch (error) {
24776
- if (error instanceof Error && error.name === "AbortError") {
24801
+ if (shouldApply() && !filterOptionsAbortController.signal.aborted) {
24777
24802
  dashboardFiltersDispatch({
24778
24803
  type: "UPDATE_DASHBOARD_FILTER",
24779
24804
  dashboardName,
24780
24805
  filterName: filter.label,
24781
24806
  data: {
24782
- filter,
24807
+ filter: {
24808
+ ...filter,
24809
+ options: filterOptions
24810
+ },
24783
24811
  loading: false
24784
24812
  }
24785
24813
  });
24814
+ }
24815
+ return null;
24816
+ } catch (error) {
24817
+ if (error instanceof Error && error.name === "AbortError") {
24818
+ if (shouldApply()) {
24819
+ dashboardFiltersDispatch({
24820
+ type: "UPDATE_DASHBOARD_FILTER",
24821
+ dashboardName,
24822
+ filterName: filter.label,
24823
+ data: {
24824
+ filter,
24825
+ loading: false
24826
+ }
24827
+ });
24828
+ }
24786
24829
  return;
24787
24830
  }
24788
- console.error("ERROR:", error);
24789
24831
  eventTracking?.logError?.({
24790
24832
  type: "bug",
24791
24833
  // TODO: determine type
@@ -24799,14 +24841,13 @@ var ContextProvider = ({
24799
24841
  }
24800
24842
  });
24801
24843
  } finally {
24802
- filterOptionsAbortControllers.current.delete(
24844
+ dashboardFilterLoadState.current[dashboardName]?.controllers.delete(
24803
24845
  filterOptionsAbortController
24804
24846
  );
24805
24847
  }
24806
24848
  })
24807
24849
  );
24808
24850
  } finally {
24809
- loadingFiltersForDashboard.current.delete(dashboardName);
24810
24851
  }
24811
24852
  }
24812
24853
  async function loadDashboard(dashboardName, fetchFromServer = false, reportAction) {
@@ -25434,8 +25475,11 @@ var ContextProvider = ({
25434
25475
  },
25435
25476
  [populatedClient, viewerTenantsByOwner]
25436
25477
  );
25437
- const fetchTenantFilterOptions = async (dashboardName, filter) => {
25478
+ const fetchTenantFilterOptions = async (dashboardName, filter, shouldApply) => {
25438
25479
  const mappings = await getMappedTenantsForDashboard(dashboardName);
25480
+ if (!shouldApply()) {
25481
+ return;
25482
+ }
25439
25483
  const options = mappings?.[filter.field] ?? [];
25440
25484
  dashboardFiltersDispatch({
25441
25485
  type: "UPDATE_DASHBOARD_FILTER",
@@ -26205,6 +26249,40 @@ var useAllReports = () => {
26205
26249
  allReportsById
26206
26250
  };
26207
26251
  };
26252
+ function hydrateDateFilter(raw) {
26253
+ if (!raw) return void 0;
26254
+ return {
26255
+ ...raw,
26256
+ presetOptions: raw.presetOptions?.map(
26257
+ (p) => ({
26258
+ ...p,
26259
+ loopStart: p.loopStart ? new Date(p.loopStart) : void 0,
26260
+ loopEnd: p.loopEnd ? new Date(p.loopEnd) : void 0
26261
+ })
26262
+ ),
26263
+ defaultPresetRanges: raw.defaultPresetRanges?.map(
26264
+ (p) => ({
26265
+ ...p,
26266
+ loopStart: p.loopStart ? new Date(p.loopStart) : void 0,
26267
+ loopEnd: p.loopEnd ? new Date(p.loopEnd) : void 0,
26268
+ customLabel: p.customLabel
26269
+ })
26270
+ )
26271
+ };
26272
+ }
26273
+ function getTaskResponseError(result) {
26274
+ const status = result.status ?? result.data?.status;
26275
+ const message = result.error ?? result.data?.error;
26276
+ if (status === "error") {
26277
+ return message ?? "Request failed";
26278
+ }
26279
+ if (message) {
26280
+ if (!result.data?.dashboard) {
26281
+ return message;
26282
+ }
26283
+ }
26284
+ return void 0;
26285
+ }
26208
26286
  var useDashboards = () => {
26209
26287
  const [dashboardReports, dashboardDispatch] = useContext(DashboardContext);
26210
26288
  const {
@@ -26215,7 +26293,8 @@ var useDashboards = () => {
26215
26293
  const {
26216
26294
  dashboardFilters,
26217
26295
  loadFiltersForDashboard,
26218
- dispatch: dashboardFiltersDispatch
26296
+ dispatch: dashboardFiltersDispatch,
26297
+ customFilterDispatch
26219
26298
  } = useContext(DashboardFiltersContext);
26220
26299
  const { reportsDispatch } = useContext(ReportsContext);
26221
26300
  const { reportFiltersDispatch } = useContext(ReportFiltersContext);
@@ -26242,7 +26321,8 @@ var useDashboards = () => {
26242
26321
  tenantFilters,
26243
26322
  filters,
26244
26323
  dateFilter,
26245
- dashboardOwners
26324
+ dashboardOwners,
26325
+ clientId
26246
26326
  }) => {
26247
26327
  if (!client) return;
26248
26328
  if (dashboardOwners?.some((key) => !key)) {
@@ -26270,7 +26350,7 @@ var useDashboards = () => {
26270
26350
  dateFilter,
26271
26351
  name: name2.trim(),
26272
26352
  task: "edit-dashboard",
26273
- clientId: client.clientId,
26353
+ clientId: clientId ?? client.clientId,
26274
26354
  tenantKeys: dashboardOwners
26275
26355
  };
26276
26356
  try {
@@ -26279,6 +26359,10 @@ var useDashboards = () => {
26279
26359
  task: "edit-dashboard",
26280
26360
  metadata: body
26281
26361
  });
26362
+ const updatedDashboard = updated.data.dashboard;
26363
+ if (!updatedDashboard) {
26364
+ throw new Error("Missing dashboard in edit-dashboard response");
26365
+ }
26282
26366
  eventTracking?.logEvent?.("create-dashboard", {
26283
26367
  dashboardName: name2
26284
26368
  });
@@ -26293,8 +26377,8 @@ var useDashboards = () => {
26293
26377
  id: name2,
26294
26378
  data: {
26295
26379
  config: {
26296
- ...updated.data.dashboard,
26297
- createdAt: new Date(updated.data.dashboard.createdAt)
26380
+ ...updatedDashboard,
26381
+ createdAt: new Date(updatedDashboard.createdAt)
26298
26382
  },
26299
26383
  loading: false
26300
26384
  }
@@ -26322,22 +26406,17 @@ var useDashboards = () => {
26322
26406
  dateFilter,
26323
26407
  customFilters,
26324
26408
  tenantKeys,
26325
- initialCacheDateRange
26409
+ initialCacheDateRange,
26410
+ clientId
26326
26411
  }) => {
26327
- if (!client) return;
26412
+ if (!client) {
26413
+ throw new Error("Client not loaded");
26414
+ }
26328
26415
  if (tenantKeys?.some((key) => !key)) {
26329
26416
  throw new Error("Tenant keys cannot be empty or undefined");
26330
26417
  }
26331
26418
  const dashboard = dashboardConfig[name2]?.config;
26332
- dashboardConfigDispatch({
26333
- type: "DELETE_DASHBOARD",
26334
- id: name2
26335
- });
26336
26419
  const oldFilters = dashboardFilters[name2];
26337
- dashboardFiltersDispatch({
26338
- type: "DELETE_DASHBOARD_FILTERS",
26339
- dashboardName: name2
26340
- });
26341
26420
  const body = {
26342
26421
  newDashboardName: newName.trim(),
26343
26422
  filters,
@@ -26346,7 +26425,7 @@ var useDashboards = () => {
26346
26425
  initialCacheDateRange,
26347
26426
  name: name2.trim(),
26348
26427
  task: "edit-dashboard",
26349
- clientId: client.clientId,
26428
+ clientId: clientId ?? client.clientId,
26350
26429
  tenantKeys
26351
26430
  };
26352
26431
  try {
@@ -26355,9 +26434,23 @@ var useDashboards = () => {
26355
26434
  task: "edit-dashboard",
26356
26435
  metadata: body
26357
26436
  });
26437
+ const taskError = getTaskResponseError(updated);
26438
+ if (taskError) {
26439
+ throw new Error(taskError);
26440
+ }
26441
+ const updatedDashboard = updated?.data?.dashboard ?? updated?.metadata?.dashboard ?? updated?.data?.metadata?.dashboard;
26442
+ if (!updatedDashboard) {
26443
+ throw new Error("Missing dashboard in edit-dashboard response");
26444
+ }
26445
+ if (name2 !== updatedDashboard.name) {
26446
+ dashboardConfigDispatch({
26447
+ type: "DELETE_DASHBOARD",
26448
+ id: name2
26449
+ });
26450
+ }
26358
26451
  eventTracking?.logEvent?.("update-dashboard", {
26359
- dashboardName: updated.data.dashboard.name,
26360
- dashboardId: updated.data.dashboard.dashboardId
26452
+ dashboardName: updatedDashboard.name,
26453
+ dashboardId: updatedDashboard.dashboardId
26361
26454
  });
26362
26455
  if (filters.length > 0 || dateFilter) {
26363
26456
  eventTracking?.logEvent?.("update-dashboard-filters", {
@@ -26367,36 +26460,19 @@ var useDashboards = () => {
26367
26460
  }
26368
26461
  dashboardConfigDispatch({
26369
26462
  type: "UPDATE_DASHBOARD",
26370
- id: updated.data.dashboard.name,
26463
+ id: updatedDashboard.name,
26371
26464
  data: {
26372
26465
  config: {
26373
26466
  ...dashboard,
26374
- ...updated.data.dashboard,
26467
+ ...updatedDashboard,
26375
26468
  allTenantFilters: tenantFilters ?? [],
26376
- dateFilter: updated.data.dashboard.dateFilter ? {
26377
- ...updated.data.dashboard.dateFilter,
26378
- presetOptions: updated.data.dashboard.dateFilter.presetOptions?.map(
26379
- (preset) => ({
26380
- ...preset,
26381
- loopStart: preset.loopStart ? new Date(preset.loopStart) : void 0,
26382
- loopEnd: preset.loopEnd ? new Date(preset.loopEnd) : void 0
26383
- })
26384
- ),
26385
- defaultPresetRanges: updated.data.dashboard.dateFilter.defaultPresetRanges?.map(
26386
- (preset) => ({
26387
- ...preset,
26388
- loopStart: preset.loopStart ? new Date(preset.loopStart) : void 0,
26389
- loopEnd: preset.loopEnd ? new Date(preset.loopEnd) : void 0,
26390
- customLabel: preset.customLabel
26391
- })
26392
- )
26393
- } : void 0,
26394
- createdAt: new Date(updated.data.dashboard.createdAt)
26469
+ dateFilter: hydrateDateFilter(updatedDashboard.dateFilter),
26470
+ createdAt: new Date(updatedDashboard.createdAt)
26395
26471
  },
26396
26472
  loading: false
26397
26473
  }
26398
26474
  });
26399
- Object.values(updated.data.dashboard.sections ?? {}).flat().forEach((report) => {
26475
+ Object.values(updatedDashboard.sections ?? {}).flat().forEach((report) => {
26400
26476
  dashboardDispatch({
26401
26477
  type: "ADD_DASHBOARD_ITEM",
26402
26478
  id: report._id,
@@ -26422,42 +26498,28 @@ var useDashboards = () => {
26422
26498
  id: report._id
26423
26499
  });
26424
26500
  });
26425
- if (dashboardFilters[name2])
26501
+ if (dashboardFilters[name2] && name2 !== newName)
26426
26502
  dashboardFiltersDispatch({
26427
26503
  type: "ADD_DASHBOARD_FILTERS",
26428
26504
  dashboardName: newName,
26429
26505
  data: dashboardFilters[name2]
26430
26506
  });
26507
+ const dateFilterSource = updatedDashboard.dateFilter ?? dateFilter;
26431
26508
  const range = convertPresetOptionsToSelectableList(
26432
- updated.data.dashboard.dateFilter?.presetOptions ?? [],
26433
- updated.data.dashboard.dateFilter?.defaultPresetRanges ?? []
26509
+ dateFilterSource?.presetOptions ?? [],
26510
+ dateFilterSource?.defaultPresetRanges ?? []
26434
26511
  ).find(
26435
- (option) => option.value === updated.data.dashboard.dateFilter?.primaryRange?.value
26436
- ) ?? PRIMARY_RANGE[updated.data.dashboard.dateFilter?.primaryRange?.value ?? "LAST_30_DAYS"] ?? PRIMARY_RANGE["LAST_30_DAYS"];
26437
- const updatedDateFilter = updated.data.dashboard.dateFilter ? {
26438
- ...updated.data.dashboard.dateFilter,
26439
- presetOptions: updated.data.dashboard.dateFilter.presetOptions?.map(
26440
- (preset) => ({
26441
- ...preset,
26442
- loopStart: preset.loopStart ? new Date(preset.loopStart) : void 0,
26443
- loopEnd: preset.loopEnd ? new Date(preset.loopEnd) : void 0
26444
- })
26445
- ),
26446
- defaultPresetRanges: updated.data.dashboard.dateFilter.defaultPresetRanges?.map(
26447
- (preset) => ({
26448
- ...preset,
26449
- loopStart: preset.loopStart ? new Date(preset.loopStart) : void 0,
26450
- loopEnd: preset.loopEnd ? new Date(preset.loopEnd) : void 0,
26451
- customLabel: preset.customLabel
26452
- })
26453
- ),
26454
- dashboardName: updated.data.dashboard.name,
26455
- preset: updated.data.dashboard.dateFilter.primaryRange,
26512
+ (option) => option.value === dateFilterSource?.primaryRange?.value
26513
+ ) ?? PRIMARY_RANGE[dateFilterSource?.primaryRange?.value ?? "LAST_30_DAYS"] ?? PRIMARY_RANGE["LAST_30_DAYS"];
26514
+ const updatedDateFilter = dateFilterSource ? {
26515
+ ...hydrateDateFilter(dateFilterSource),
26516
+ dashboardName: updatedDashboard.name,
26517
+ preset: dateFilterSource.primaryRange,
26456
26518
  filterType: "date_range" /* Date */,
26457
26519
  dateField: [
26458
26520
  ...new Map(
26459
26521
  Object.values(
26460
- dashboardConfig[updated.data.dashboard.name]?.config.sections ?? {}
26522
+ dashboardConfig[updatedDashboard.name]?.config.sections ?? {}
26461
26523
  ).flat().map((report) => {
26462
26524
  const key = JSON.stringify(report.dateField);
26463
26525
  return [key, report.dateField];
@@ -26469,11 +26531,13 @@ var useDashboards = () => {
26469
26531
  endDate: !range.endDate || range.endDate instanceof Date ? range.endDate : new Date(range.endDate)
26470
26532
  // when range.endDate is a string
26471
26533
  } : void 0;
26472
- const mappedTenants = await getMappedTenantsForDashboard(newName);
26534
+ const mappedTenants = await getMappedTenantsForDashboard(newName).catch(
26535
+ () => void 0
26536
+ );
26473
26537
  const mappedTenantKeys = Object.keys(mappedTenants ?? {});
26474
26538
  const newFilters = [
26475
26539
  ...updatedDateFilter ? [updatedDateFilter] : [],
26476
- ...updated.data.dashboard.filters.map(
26540
+ ...(updatedDashboard.filters ?? []).map(
26477
26541
  (f) => ({
26478
26542
  ...f,
26479
26543
  selectedValue: oldFilters?.[f.label]?.filter?.selectedValue,
@@ -26481,7 +26545,7 @@ var useDashboards = () => {
26481
26545
  operator: oldFilters?.[f.label]?.filter?.operator
26482
26546
  })
26483
26547
  ) ?? [],
26484
- ...(updated.data.dashboard.tenantFilters?.map(
26548
+ ...(updatedDashboard.tenantFilters?.map(
26485
26549
  (f) => ({
26486
26550
  ...f,
26487
26551
  values: oldFilters?.[f.label]?.filter?.values
@@ -26504,16 +26568,18 @@ var useDashboards = () => {
26504
26568
  };
26505
26569
  }
26506
26570
  });
26507
- dashboardFiltersDispatch({
26508
- type: "DELETE_DASHBOARD_FILTERS",
26509
- dashboardName: name2
26510
- });
26511
- loadFiltersForDashboard(
26512
- updated.data.dashboard.name,
26571
+ await loadFiltersForDashboard(
26572
+ updatedDashboard.name,
26513
26573
  newFilters,
26514
26574
  void 0,
26515
26575
  customFilters
26516
26576
  );
26577
+ if (name2 !== updatedDashboard.name) {
26578
+ dashboardFiltersDispatch({
26579
+ type: "DELETE_DASHBOARD_FILTERS",
26580
+ dashboardName: name2
26581
+ });
26582
+ }
26517
26583
  } catch (e) {
26518
26584
  console.error(e);
26519
26585
  eventTracking?.logError?.({
@@ -26528,6 +26594,7 @@ var useDashboards = () => {
26528
26594
  function: "updateDashboard"
26529
26595
  }
26530
26596
  });
26597
+ throw e;
26531
26598
  }
26532
26599
  };
26533
26600
  const deleteDashboard = async (name2) => {
@@ -26545,6 +26612,14 @@ var useDashboards = () => {
26545
26612
  type: "DELETE_DASHBOARD",
26546
26613
  id: name2
26547
26614
  });
26615
+ dashboardFiltersDispatch({
26616
+ type: "DELETE_DASHBOARD_FILTERS",
26617
+ dashboardName: name2
26618
+ });
26619
+ customFilterDispatch({
26620
+ type: "DELETE_CUSTOM_DASHBOARD_FILTERS",
26621
+ dashboardName: name2
26622
+ });
26548
26623
  };
26549
26624
  return {
26550
26625
  dashboards: isLoading || isDashboardsLoading ? null : dashboards,
@@ -26772,7 +26847,7 @@ var useDashboard = (dashboardName, config) => {
26772
26847
  const fetchStartTime = Date.now();
26773
26848
  let totalCached = 0;
26774
26849
  await Promise.all(
26775
- allReports.map(async (reportInfo, idx) => {
26850
+ allReports.map(async (reportInfo) => {
26776
26851
  const reportId = reportInfo.id;
26777
26852
  const requestId = (reportRequestIds.current[reportId] ?? 0) + 1;
26778
26853
  reportRequestIds.current[reportId] = requestId;
@@ -26819,7 +26894,19 @@ var useDashboard = (dashboardName, config) => {
26819
26894
  };
26820
26895
  };
26821
26896
  if (cacheEnabled && cacheCab.isCacheable(reportId)) {
26822
- const report2 = await cacheCab.get(reportId, dashboardFilters2, customFilters.concat(customReportFiltersArray), reportInfo.pivot, client, tenants, flags, pageSize, getToken, eventTracking, forceCacheToRefresh);
26897
+ const report2 = await cacheCab.get(
26898
+ reportId,
26899
+ dashboardFilters2,
26900
+ customFilters.concat(customReportFiltersArray),
26901
+ reportInfo.pivot,
26902
+ client,
26903
+ tenants,
26904
+ flags,
26905
+ pageSize,
26906
+ getToken,
26907
+ eventTracking,
26908
+ forceCacheToRefresh
26909
+ );
26823
26910
  if (reportRequestIds.current[reportId] !== requestId) {
26824
26911
  return null;
26825
26912
  }
@@ -27032,11 +27119,15 @@ var useDashboard = (dashboardName, config) => {
27032
27119
  })
27033
27120
  );
27034
27121
  if (!loadedDashes.includes(dashboardName) || !cacheEnabled || forceCacheToRefresh) {
27035
- setLoadedDashes((prev) => prev.includes(dashboardName) ? prev : [...prev, dashboardName]);
27122
+ setLoadedDashes(
27123
+ (prev) => prev.includes(dashboardName) ? prev : [...prev, dashboardName]
27124
+ );
27036
27125
  setLastUpdatedDict((prev) => ({ ...prev, [dashboardName]: Date.now() }));
27037
27126
  }
27038
27127
  if (logCacheStatistics) {
27039
- console.log(`Dashboard "${dashboardName}": Cache Rate: ${(100 * totalCached / allReports.length).toFixed(1)}%, load time: ${((Date.now() - fetchStartTime) / 1e3).toFixed(2)} secs`);
27128
+ console.log(
27129
+ `Dashboard "${dashboardName}": Cache Rate: ${(100 * totalCached / allReports.length).toFixed(1)}%, load time: ${((Date.now() - fetchStartTime) / 1e3).toFixed(2)} secs`
27130
+ );
27040
27131
  }
27041
27132
  };
27042
27133
  return {
@@ -42351,7 +42442,8 @@ var getThemedStyles = (theme) => ({
42351
42442
  function Dashboard({
42352
42443
  name: name2,
42353
42444
  onClickReport,
42354
- containerStyle
42445
+ containerStyle,
42446
+ EmptyDashboardComponent
42355
42447
  }) {
42356
42448
  const [themeFromContext] = useContext22(ThemeContext);
42357
42449
  const theme = useMemo19(
@@ -42534,7 +42626,8 @@ function Dashboard({
42534
42626
  sections,
42535
42627
  sectionOrder,
42536
42628
  onClickReport,
42537
- styles: themedStyles
42629
+ styles: themedStyles,
42630
+ EmptyDashboardComponent
42538
42631
  }
42539
42632
  )
42540
42633
  ] });
@@ -42542,7 +42635,8 @@ function Dashboard({
42542
42635
  function DashboardContent({
42543
42636
  sections,
42544
42637
  sectionOrder,
42545
- onClickReport
42638
+ onClickReport,
42639
+ EmptyDashboardComponent
42546
42640
  }) {
42547
42641
  const getSection = (name2) => {
42548
42642
  if (!sections) {
@@ -42603,6 +42697,11 @@ function DashboardContent({
42603
42697
  return aIndex - bIndex;
42604
42698
  });
42605
42699
  }, [sections, sectionOrder]);
42700
+ if (sections && (Object.keys(sections).length === 0 || Object.values(sections).flat().length === 0)) {
42701
+ if (EmptyDashboardComponent) {
42702
+ return /* @__PURE__ */ jsx60(EmptyDashboardComponent, {});
42703
+ }
42704
+ }
42606
42705
  return /* @__PURE__ */ jsxs43("div", { style: styles.contentWrap, children: [
42607
42706
  metricReports.length === 0 ? null : /* @__PURE__ */ jsx60("div", { style: styles.splitGrid, children: /* @__PURE__ */ jsx60("section", { children: metricReports.map((report) => /* @__PURE__ */ jsxs43(
42608
42707
  "div",
@@ -42721,7 +42820,8 @@ var QuillProvider = ({
42721
42820
  withCredentials,
42722
42821
  isAdmin,
42723
42822
  getAuthorizationToken,
42724
- eventTracking
42823
+ eventTracking,
42824
+ onChangelogs
42725
42825
  }) => {
42726
42826
  if (queryEndpoint === QUILL_SERVER + QUILL_QUERY_ENDPOINT && !tenants) {
42727
42827
  throw new Error("Tenants are required when using the quill cloud endpoint");
@@ -42740,6 +42840,7 @@ var QuillProvider = ({
42740
42840
  isAdmin,
42741
42841
  getAuthorizationToken,
42742
42842
  eventTracking,
42843
+ onChangelogs,
42743
42844
  children
42744
42845
  }
42745
42846
  );
@@ -42922,7 +43023,7 @@ import {
42922
43023
  useEffect as useEffect25,
42923
43024
  useRef as useRef20,
42924
43025
  useMemo as useMemo25,
42925
- useCallback as useCallback5
43026
+ useCallback as useCallback4
42926
43027
  } from "react";
42927
43028
  import MonacoEditor from "@monaco-editor/react";
42928
43029
 
@@ -42933,7 +43034,7 @@ import {
42933
43034
  useState as useState31,
42934
43035
  useContext as useContext28,
42935
43036
  useMemo as useMemo24,
42936
- useCallback as useCallback4
43037
+ useCallback as useCallback3
42937
43038
  } from "react";
42938
43039
  import {
42939
43040
  closestCenter,
@@ -42954,7 +43055,7 @@ import { CSS as DND_CSS } from "@dnd-kit/utilities";
42954
43055
 
42955
43056
  // src/internals/ReportBuilder/PivotModal.tsx
42956
43057
  import {
42957
- useCallback as useCallback3,
43058
+ useCallback as useCallback2,
42958
43059
  useContext as useContext25,
42959
43060
  useMemo as useMemo21,
42960
43061
  useState as useState28,
@@ -43837,7 +43938,7 @@ var PivotModal = ({
43837
43938
  setIsOpen(false);
43838
43939
  setPopUpTitle("Add pivot");
43839
43940
  };
43840
- const onCommitPivot = useCallback3(() => {
43941
+ const onCommitPivot = useCallback2(() => {
43841
43942
  const errors2 = [];
43842
43943
  if ((pivotAggregations?.length ?? 0) === 0) {
43843
43944
  errors2.push("You must have at least one aggregation");
@@ -43979,7 +44080,7 @@ var PivotModal = ({
43979
44080
  const onEditRecommendedPivot = (pivot) => {
43980
44081
  onEditPivot(pivot, null);
43981
44082
  };
43982
- const refreshPivots = useCallback3(async () => {
44083
+ const refreshPivots = useCallback2(async () => {
43983
44084
  if (!client) {
43984
44085
  return;
43985
44086
  }
@@ -47496,7 +47597,7 @@ function ChartBuilder({
47496
47597
  ) ?? {};
47497
47598
  }, [client?.allTenantTypes]);
47498
47599
  const [selectedPivotTable, setSelectedPivotTable] = useState31(pivotData);
47499
- const getDefaultXAxisFormat = useCallback4(
47600
+ const getDefaultXAxisFormat = useCallback3(
47500
47601
  (form) => {
47501
47602
  if (form.pivot?.rowField) {
47502
47603
  if (isDateField(form.pivot.rowFieldType ?? "")) {
@@ -49734,7 +49835,8 @@ function ChartBuilder({
49734
49835
  SecondaryButtonComponent,
49735
49836
  {
49736
49837
  onClick: deleteChart,
49737
- label: "Delete"
49838
+ label: "Delete",
49839
+ disabled: isSubmitting
49738
49840
  }
49739
49841
  ),
49740
49842
  !hideSubmitButton && /* @__PURE__ */ jsxs49(Fragment12, { children: [
@@ -49745,7 +49847,8 @@ function ChartBuilder({
49745
49847
  setIsOpen(false);
49746
49848
  onDiscardChanges && onDiscardChanges();
49747
49849
  },
49748
- label: "Discard changes"
49850
+ label: "Discard changes",
49851
+ disabled: isSubmitting
49749
49852
  }
49750
49853
  ),
49751
49854
  /* @__PURE__ */ jsx68(
@@ -49758,10 +49861,11 @@ function ChartBuilder({
49758
49861
  editChart();
49759
49862
  }
49760
49863
  },
49761
- disabled: formData.name === "" || formData.dashboardName === "" || formData.chartType === "" || filterIssues.length !== 0 || Object.values(validFilter).includes(false) || currentDashboard?.tenantKeys && customTenantAccess && Object.values(formFlags ?? {}).every(
49864
+ disabled: isSubmitting || formData.name === "" || formData.dashboardName === "" || formData.chartType === "" || filterIssues.length !== 0 || Object.values(validFilter).includes(false) || currentDashboard?.tenantKeys && customTenantAccess && Object.values(formFlags ?? {}).every(
49762
49865
  (value) => !value.length
49763
49866
  ),
49764
49867
  tooltipText: memoizedTooltipText,
49868
+ isLoading: isSubmitting,
49765
49869
  label: buttonLabel ? buttonLabel : report ? "Save changes" : "Add to dashboard"
49766
49870
  }
49767
49871
  )
@@ -50874,7 +50978,7 @@ function SQLEditor({
50874
50978
  onCloseChartBuilder && onCloseChartBuilder();
50875
50979
  }
50876
50980
  }, [isChartBuilderOpen]);
50877
- const handleRunSqlPrompt = useCallback5(async () => {
50981
+ const handleRunSqlPrompt = useCallback4(async () => {
50878
50982
  if (!client || sqlResponseLoading) {
50879
50983
  return;
50880
50984
  }
@@ -50893,7 +50997,7 @@ function SQLEditor({
50893
50997
  setQuery(resp.message);
50894
50998
  setSqlResponseLoading(false);
50895
50999
  }, [sqlPrompt, sqlResponseLoading]);
50896
- const debounceRunSqlPrompt = useCallback5(
51000
+ const debounceRunSqlPrompt = useCallback4(
50897
51001
  createDebounce(handleRunSqlPrompt, 500),
50898
51002
  [handleRunSqlPrompt]
50899
51003
  );
@@ -59489,16 +59593,24 @@ var useVirtualTables = () => {
59489
59593
  getToken,
59490
59594
  eventTracking
59491
59595
  });
59492
- setSchemaData({
59493
- schema: schemaData.schema.map((table) => {
59596
+ setSchemaData((prev) => {
59597
+ const existingIds = new Set(prev.schema.map((table) => table._id));
59598
+ const updatedSchema = prev.schema.map((table) => {
59494
59599
  if (tableIds.includes(table._id)) {
59495
59600
  return schema.find((newTable) => newTable._id === table._id) || table;
59496
59601
  }
59497
59602
  return table;
59498
- }, {}),
59499
- customFields: customFieldsByTable,
59500
- isSchemaLoading: false,
59501
- schemaWithCustomFields
59603
+ });
59604
+ const addedSchema = schema.filter(
59605
+ (table) => tableIds.includes(table._id) && !existingIds.has(table._id)
59606
+ );
59607
+ return {
59608
+ ...prev,
59609
+ schema: [...updatedSchema, ...addedSchema],
59610
+ customFields: customFieldsByTable,
59611
+ isSchemaLoading: false,
59612
+ schemaWithCustomFields
59613
+ };
59502
59614
  });
59503
59615
  return {
59504
59616
  schema,
@@ -59574,27 +59686,67 @@ var useVirtualTables = () => {
59574
59686
 
59575
59687
  // src/hooks/useChangelogRefresh.ts
59576
59688
  import { useContext as useContext43 } from "react";
59689
+ init_filterProcessing();
59577
59690
  var CALLER = "agent-changelog";
59691
+ var getChangeType = (entry) => {
59692
+ let parsed;
59693
+ if (typeof entry.changeObject === "string") {
59694
+ try {
59695
+ parsed = JSON.parse(entry.changeObject);
59696
+ } catch {
59697
+ return "UNKNOWN";
59698
+ }
59699
+ } else if (entry.changeObject && typeof entry.changeObject === "object") {
59700
+ parsed = entry.changeObject;
59701
+ } else {
59702
+ console.error(`Unknown changelog entry ${entry._id}`);
59703
+ return "UNKNOWN";
59704
+ }
59705
+ const changeType = parsed?.changeType;
59706
+ return typeof changeType === "string" ? changeType.toUpperCase() : "UNKNOWN";
59707
+ };
59578
59708
  var useChangelogRefresh = () => {
59579
- const { loadDashboard, dashboardConfig } = useContext43(DashboardConfigContext);
59709
+ const { loadDashboard, dashboardConfig, dashboardConfigDispatch } = useContext43(DashboardConfigContext);
59710
+ const {
59711
+ loadFiltersForDashboard,
59712
+ dispatch: dashboardFiltersDispatch,
59713
+ customFilterDispatch
59714
+ } = useContext43(DashboardFiltersContext);
59715
+ const [, dashboardDispatch] = useContext43(DashboardContext);
59716
+ const { reportsDispatch } = useContext43(ReportsContext);
59717
+ const [, setSchemaData] = useContext43(SchemaDataContext);
59580
59718
  const { allReportsById } = useAllReports();
59581
59719
  const { reloadSome } = useVirtualTables();
59582
59720
  const refreshChangelogEntries = async (entries, client) => {
59583
59721
  const dashboardsToReload = /* @__PURE__ */ new Set();
59584
59722
  let reloadAllDashboards = false;
59585
59723
  const schemaIds = [];
59724
+ const schemaIdsToRemove = /* @__PURE__ */ new Set();
59725
+ const dashboardsToRemove = /* @__PURE__ */ new Set();
59726
+ const reportsToRemove = /* @__PURE__ */ new Map();
59586
59727
  for (const entry of entries) {
59587
59728
  if (!entry.entityId || !entry.entityType) continue;
59729
+ const changeType = getChangeType(entry);
59588
59730
  switch (entry.entityType) {
59589
59731
  case "schema":
59590
- schemaIds.push(entry.entityId);
59732
+ if (changeType === "DELETE") {
59733
+ schemaIdsToRemove.add(entry.entityId);
59734
+ } else {
59735
+ schemaIds.push(entry.entityId);
59736
+ }
59591
59737
  break;
59592
59738
  case "dashboard":
59593
- dashboardsToReload.add(entry.entityId);
59739
+ if (changeType === "DELETE") {
59740
+ dashboardsToRemove.add(entry.entityId);
59741
+ } else {
59742
+ dashboardsToReload.add(entry.entityId);
59743
+ }
59594
59744
  break;
59595
59745
  case "report": {
59596
59746
  const owningDashboard = allReportsById[entry.entityId]?.dashboardName;
59597
- if (owningDashboard) {
59747
+ if (changeType === "DELETE") {
59748
+ reportsToRemove.set(entry.entityId, owningDashboard);
59749
+ } else if (owningDashboard) {
59598
59750
  dashboardsToReload.add(owningDashboard);
59599
59751
  } else {
59600
59752
  reloadAllDashboards = true;
@@ -59605,25 +59757,97 @@ var useChangelogRefresh = () => {
59605
59757
  break;
59606
59758
  }
59607
59759
  }
59608
- const finalDashboardSet = reloadAllDashboards ? new Set(Object.keys(dashboardConfig)) : dashboardsToReload;
59760
+ if (schemaIdsToRemove.size) {
59761
+ setSchemaData((prev) => ({
59762
+ ...prev,
59763
+ schema: prev.schema.filter(
59764
+ (table) => !schemaIdsToRemove.has(table._id)
59765
+ ),
59766
+ schemaWithCustomFields: (prev.schemaWithCustomFields ?? []).filter(
59767
+ (table) => !schemaIdsToRemove.has(table?._id)
59768
+ )
59769
+ }));
59770
+ }
59771
+ for (const dashboardName of dashboardsToRemove) {
59772
+ dashboardConfigDispatch({ type: "DELETE_DASHBOARD", id: dashboardName });
59773
+ dashboardFiltersDispatch({
59774
+ type: "DELETE_DASHBOARD_FILTERS",
59775
+ dashboardName
59776
+ });
59777
+ customFilterDispatch({
59778
+ type: "DELETE_CUSTOM_DASHBOARD_FILTERS",
59779
+ dashboardName
59780
+ });
59781
+ dashboardDispatch({ type: "CLEAR_DASHBOARD", dashboard: dashboardName });
59782
+ dashboardsToReload.delete(dashboardName);
59783
+ }
59784
+ for (const [reportId] of reportsToRemove) {
59785
+ reportsDispatch({ type: "DELETE_REPORT", id: reportId });
59786
+ dashboardDispatch({ type: "REMOVE_DASHBOARD_ITEM", id: reportId });
59787
+ }
59788
+ const finalDashboardSet = reloadAllDashboards ? new Set(
59789
+ Object.keys(dashboardConfig).filter(
59790
+ (d) => !dashboardsToRemove.has(d)
59791
+ )
59792
+ ) : dashboardsToReload;
59609
59793
  const tasks = [];
59610
- if (schemaIds.length) {
59794
+ const schemaIdsToReload = schemaIds.filter(
59795
+ (id) => !schemaIdsToRemove.has(id)
59796
+ );
59797
+ if (schemaIdsToReload.length) {
59611
59798
  tasks.push(
59612
- reloadSome(client, schemaIds, CALLER).catch((err) => {
59799
+ reloadSome(client, schemaIdsToReload, CALLER).catch((err) => {
59613
59800
  console.warn("[changelog-refresh] reloadSome failed:", err);
59614
59801
  })
59615
59802
  );
59616
59803
  }
59804
+ for (const [reportId, owningDashboard] of reportsToRemove) {
59805
+ if (!owningDashboard) continue;
59806
+ finalDashboardSet.delete(owningDashboard);
59807
+ tasks.push(
59808
+ Promise.resolve(
59809
+ loadDashboard(owningDashboard, true, {
59810
+ report: { id: reportId },
59811
+ action: "delete"
59812
+ })
59813
+ ).catch((err) => {
59814
+ console.warn(
59815
+ `[changelog-refresh] loadDashboard "${owningDashboard}" (report delete) failed:`,
59816
+ err
59817
+ );
59818
+ })
59819
+ );
59820
+ }
59617
59821
  for (const dashboardName of finalDashboardSet) {
59618
59822
  tasks.push(
59619
- Promise.resolve(loadDashboard(dashboardName, true)).catch(
59620
- (err) => {
59621
- console.warn(
59622
- `[changelog-refresh] loadDashboard "${dashboardName}" failed:`,
59623
- err
59624
- );
59625
- }
59626
- )
59823
+ Promise.resolve(loadDashboard(dashboardName, true)).then((updatedDashboard) => {
59824
+ if (!updatedDashboard) return;
59825
+ const dateFilter = updatedDashboard.dateFilter ? createDefaultDateFilter(
59826
+ updatedDashboard.dateFilter,
59827
+ Object.values(updatedDashboard.sections ?? {}).flat(),
59828
+ dashboardName
59829
+ ) : void 0;
59830
+ return loadFiltersForDashboard(
59831
+ dashboardName,
59832
+ [
59833
+ ...dateFilter ? [dateFilter] : [],
59834
+ ...updatedDashboard.filters?.map((filter) => ({
59835
+ ...filter,
59836
+ query: void 0
59837
+ })) ?? [],
59838
+ ...updatedDashboard.tenantFilters?.map((filter) => ({
59839
+ ...filter
59840
+ })) ?? []
59841
+ ],
59842
+ void 0,
59843
+ void 0
59844
+ );
59845
+ }).catch((err) => {
59846
+ console.warn(
59847
+ `[changelog-refresh] loadDashboard "${dashboardName}" failed:`,
59848
+ err
59849
+ );
59850
+ })
59627
59851
  );
59628
59852
  }
59629
59853
  await Promise.all(tasks);
@@ -59634,6 +59858,7 @@ var useChangelogRefresh = () => {
59634
59858
  };
59635
59859
 
59636
59860
  // src/index.ts
59861
+ init_dataFetcher();
59637
59862
  init_dataProcessing();
59638
59863
  init_Filter();
59639
59864
  init_constants();
@@ -59669,6 +59894,7 @@ export {
59669
59894
  ThemeContext,
59670
59895
  downloadCSV,
59671
59896
  quillFormat as format,
59897
+ quillFetch,
59672
59898
  useAllReports,
59673
59899
  useAskQuill,
59674
59900
  useChangelogRefresh,