@quillsql/react 2.12.53 → 2.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/dist/cjs/Chart.d.ts.map +1 -1
  2. package/dist/cjs/Chart.js +4 -2
  3. package/dist/cjs/ChartBuilder.d.ts +4 -1
  4. package/dist/cjs/ChartBuilder.d.ts.map +1 -1
  5. package/dist/cjs/ChartBuilder.js +9 -9
  6. package/dist/cjs/ChartEditor.d.ts.map +1 -1
  7. package/dist/cjs/ChartEditor.js +47 -24
  8. package/dist/cjs/Context.d.ts +14 -2
  9. package/dist/cjs/Context.d.ts.map +1 -1
  10. package/dist/cjs/Context.js +118 -41
  11. package/dist/cjs/Dashboard.d.ts +4 -1
  12. package/dist/cjs/Dashboard.d.ts.map +1 -1
  13. package/dist/cjs/Dashboard.js +138 -354
  14. package/dist/cjs/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  15. package/dist/cjs/DateRangePicker/QuillDateRangePicker.js +14 -6
  16. package/dist/cjs/ReportBuilder.d.ts.map +1 -1
  17. package/dist/cjs/ReportBuilder.js +13 -7
  18. package/dist/cjs/SQLEditor.d.ts.map +1 -1
  19. package/dist/cjs/SQLEditor.js +6 -5
  20. package/dist/cjs/Table.d.ts.map +1 -1
  21. package/dist/cjs/Table.js +5 -2
  22. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts +2 -1
  23. package/dist/cjs/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  24. package/dist/cjs/components/Dashboard/DashboardFilter.js +7 -7
  25. package/dist/cjs/components/Dashboard/DataLoader.d.ts +6 -4
  26. package/dist/cjs/components/Dashboard/DataLoader.d.ts.map +1 -1
  27. package/dist/cjs/components/Dashboard/DataLoader.js +81 -41
  28. package/dist/cjs/components/Dashboard/TableComponent.d.ts.map +1 -1
  29. package/dist/cjs/components/Dashboard/TableComponent.js +8 -1
  30. package/dist/cjs/components/QuillMultiSelect.js +1 -1
  31. package/dist/cjs/components/QuillMultiSelectWithCombo.js +1 -1
  32. package/dist/cjs/components/QuillSelect.d.ts +1 -1
  33. package/dist/cjs/components/QuillSelect.d.ts.map +1 -1
  34. package/dist/cjs/components/QuillSelect.js +3 -3
  35. package/dist/cjs/components/QuillSelectWithCombo.d.ts +1 -1
  36. package/dist/cjs/components/QuillSelectWithCombo.d.ts.map +1 -1
  37. package/dist/cjs/components/QuillSelectWithCombo.js +3 -3
  38. package/dist/cjs/components/QuillTable.d.ts +1 -1
  39. package/dist/cjs/components/QuillTable.d.ts.map +1 -1
  40. package/dist/cjs/components/QuillTable.js +26 -16
  41. package/dist/cjs/components/ReportBuilder/ui.d.ts +0 -1
  42. package/dist/cjs/components/ReportBuilder/ui.d.ts.map +1 -1
  43. package/dist/cjs/components/ReportBuilder/ui.js +1 -13
  44. package/dist/cjs/components/UiComponents.d.ts +2 -1
  45. package/dist/cjs/components/UiComponents.d.ts.map +1 -1
  46. package/dist/cjs/components/UiComponents.js +3 -3
  47. package/dist/cjs/hooks/useDashboard.d.ts +4 -1
  48. package/dist/cjs/hooks/useDashboard.d.ts.map +1 -1
  49. package/dist/cjs/hooks/useDashboard.js +129 -64
  50. package/dist/cjs/hooks/useExport.d.ts.map +1 -1
  51. package/dist/cjs/hooks/useExport.js +8 -2
  52. package/dist/cjs/hooks/useQuill.d.ts.map +1 -1
  53. package/dist/cjs/hooks/useQuill.js +14 -14
  54. package/dist/cjs/models/Client.d.ts +6 -0
  55. package/dist/cjs/models/Client.d.ts.map +1 -1
  56. package/dist/cjs/models/Dashboard.d.ts +1 -1
  57. package/dist/cjs/models/Dashboard.d.ts.map +1 -1
  58. package/dist/cjs/models/Filter.d.ts +4 -3
  59. package/dist/cjs/models/Filter.d.ts.map +1 -1
  60. package/dist/cjs/models/Filter.js +38 -1
  61. package/dist/cjs/utils/dashboard.d.ts.map +1 -1
  62. package/dist/cjs/utils/dashboard.js +3 -2
  63. package/dist/cjs/utils/paginationProcessing.js +1 -1
  64. package/dist/cjs/utils/report.d.ts +2 -2
  65. package/dist/cjs/utils/report.d.ts.map +1 -1
  66. package/dist/cjs/utils/report.js +6 -5
  67. package/dist/cjs/utils/tableProcessing.d.ts +4 -4
  68. package/dist/cjs/utils/tableProcessing.d.ts.map +1 -1
  69. package/dist/cjs/utils/tableProcessing.js +3 -1
  70. package/dist/esm/Chart.d.ts.map +1 -1
  71. package/dist/esm/Chart.js +4 -2
  72. package/dist/esm/ChartBuilder.d.ts +4 -1
  73. package/dist/esm/ChartBuilder.d.ts.map +1 -1
  74. package/dist/esm/ChartBuilder.js +9 -9
  75. package/dist/esm/ChartEditor.d.ts.map +1 -1
  76. package/dist/esm/ChartEditor.js +48 -25
  77. package/dist/esm/Context.d.ts +14 -2
  78. package/dist/esm/Context.d.ts.map +1 -1
  79. package/dist/esm/Context.js +118 -41
  80. package/dist/esm/Dashboard.d.ts +4 -1
  81. package/dist/esm/Dashboard.d.ts.map +1 -1
  82. package/dist/esm/Dashboard.js +138 -354
  83. package/dist/esm/DateRangePicker/QuillDateRangePicker.d.ts.map +1 -1
  84. package/dist/esm/DateRangePicker/QuillDateRangePicker.js +15 -7
  85. package/dist/esm/ReportBuilder.d.ts.map +1 -1
  86. package/dist/esm/ReportBuilder.js +14 -8
  87. package/dist/esm/SQLEditor.d.ts.map +1 -1
  88. package/dist/esm/SQLEditor.js +6 -5
  89. package/dist/esm/Table.d.ts.map +1 -1
  90. package/dist/esm/Table.js +5 -2
  91. package/dist/esm/components/Dashboard/DashboardFilter.d.ts +2 -1
  92. package/dist/esm/components/Dashboard/DashboardFilter.d.ts.map +1 -1
  93. package/dist/esm/components/Dashboard/DashboardFilter.js +7 -7
  94. package/dist/esm/components/Dashboard/DataLoader.d.ts +6 -4
  95. package/dist/esm/components/Dashboard/DataLoader.d.ts.map +1 -1
  96. package/dist/esm/components/Dashboard/DataLoader.js +83 -43
  97. package/dist/esm/components/Dashboard/TableComponent.d.ts.map +1 -1
  98. package/dist/esm/components/Dashboard/TableComponent.js +8 -1
  99. package/dist/esm/components/QuillMultiSelect.js +1 -1
  100. package/dist/esm/components/QuillMultiSelectWithCombo.js +1 -1
  101. package/dist/esm/components/QuillSelect.d.ts +1 -1
  102. package/dist/esm/components/QuillSelect.d.ts.map +1 -1
  103. package/dist/esm/components/QuillSelect.js +3 -3
  104. package/dist/esm/components/QuillSelectWithCombo.d.ts +1 -1
  105. package/dist/esm/components/QuillSelectWithCombo.d.ts.map +1 -1
  106. package/dist/esm/components/QuillSelectWithCombo.js +3 -3
  107. package/dist/esm/components/QuillTable.d.ts +1 -1
  108. package/dist/esm/components/QuillTable.d.ts.map +1 -1
  109. package/dist/esm/components/QuillTable.js +26 -16
  110. package/dist/esm/components/ReportBuilder/ui.d.ts +0 -1
  111. package/dist/esm/components/ReportBuilder/ui.d.ts.map +1 -1
  112. package/dist/esm/components/ReportBuilder/ui.js +0 -8
  113. package/dist/esm/components/UiComponents.d.ts +2 -1
  114. package/dist/esm/components/UiComponents.d.ts.map +1 -1
  115. package/dist/esm/components/UiComponents.js +3 -3
  116. package/dist/esm/hooks/useDashboard.d.ts +4 -1
  117. package/dist/esm/hooks/useDashboard.d.ts.map +1 -1
  118. package/dist/esm/hooks/useDashboard.js +128 -66
  119. package/dist/esm/hooks/useExport.d.ts.map +1 -1
  120. package/dist/esm/hooks/useExport.js +9 -3
  121. package/dist/esm/hooks/useQuill.d.ts.map +1 -1
  122. package/dist/esm/hooks/useQuill.js +15 -15
  123. package/dist/esm/models/Client.d.ts +6 -0
  124. package/dist/esm/models/Client.d.ts.map +1 -1
  125. package/dist/esm/models/Dashboard.d.ts +1 -1
  126. package/dist/esm/models/Dashboard.d.ts.map +1 -1
  127. package/dist/esm/models/Filter.d.ts +4 -3
  128. package/dist/esm/models/Filter.d.ts.map +1 -1
  129. package/dist/esm/models/Filter.js +36 -0
  130. package/dist/esm/utils/dashboard.d.ts.map +1 -1
  131. package/dist/esm/utils/dashboard.js +3 -2
  132. package/dist/esm/utils/paginationProcessing.js +1 -1
  133. package/dist/esm/utils/report.d.ts +2 -2
  134. package/dist/esm/utils/report.d.ts.map +1 -1
  135. package/dist/esm/utils/report.js +6 -5
  136. package/dist/esm/utils/tableProcessing.d.ts +4 -4
  137. package/dist/esm/utils/tableProcessing.d.ts.map +1 -1
  138. package/dist/esm/utils/tableProcessing.js +3 -1
  139. package/package.json +1 -1
@@ -27,7 +27,7 @@ import QuillTemplateMetricComponent from './components/Dashboard/TemplateMetricC
27
27
  import QuillTemplateTableComponent from './components/Dashboard/TemplateTableComponent';
28
28
  import QuillDashboardTemplate from './components/Dashboard/DashboardTemplate';
29
29
  import { DashboardFilterType, } from './models/Filter';
30
- import equal from 'fast-deep-equal';
30
+ import { DEFAULT_PAGINATION } from './utils/paginationProcessing';
31
31
  const defaultChartContainerStyles = {
32
32
  display: 'flex',
33
33
  width: '100%',
@@ -43,6 +43,15 @@ const charts = (sections, section, sortByOrdering) => sections[section]
43
43
  const tables = (sections, section, sortByOrdering) => sections[section]
44
44
  .filter(({ chartType }) => chartType === 'table')
45
45
  .sort(sortByOrdering);
46
+ const sortByOrdering = (a, b) => {
47
+ if (a.order === undefined && b.order === undefined)
48
+ return 0;
49
+ if (a.order === undefined)
50
+ return 1;
51
+ if (b.order === undefined)
52
+ return -1;
53
+ return a.order - b.order;
54
+ };
46
55
  /**
47
56
  * ### Quill Dashboard
48
57
  *
@@ -74,37 +83,52 @@ const tables = (sections, section, sortByOrdering) => sections[section]
74
83
  * ### API Reference
75
84
  * @see https://docs.quillsql.com/components/dashboard
76
85
  */
77
- export default function Dashboard({ name, hidden = false, SelectComponent = QuillSelectComponentWithCombo, MultiSelectComponent = QuillMultiSelectComponentWithCombo, ModalComponent = QuillModalComponent, ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, FilterTagComponent = QuillFilterPopover, PopoverComponent = MemoizedPopover, TextInputComponent = QuillTextInput, EmptyDashboardComponent = QuillEmptyDashboardComponent, DateRangePickerComponent = QuillDateRangePicker, MetricComponent = QuillMetricComponent, ChartComponent = QuillChartComponent, TableComponent = QuillTableComponent, TemplateMetricComponent = QuillTemplateMetricComponent, TemplateChartComponent = QuillTemplateChartComponent, TemplateTableComponent = QuillTemplateTableComponent, DashboardSectionComponent = DashboardSection, DashboardSectionContainerComponent = DashboardSectionContainer, FilterContainerComponent = QuillFilterContainerComponent, DashboardLoadingComponent = QuillLoadingDashboardComponent, ErrorComponent = QuillChartErrorWithAction, onClickReport, hoverActions, onChangeLoading, hideFilters, hideXAxis = false, hideYAxis = false, hideCartesianGrid = false, comparisonLineStyle = 'solid', containerStyle, className, chartContainerStyle = defaultChartContainerStyles, filters, onClickChartElement, dateBucket, additionalProcessing, hideAdminErrors = true, templateDashboardName, }) {
78
- const { isLoading, data, isDashboardFiltersLoading, dashboardFilters: populatedDashboardFilters, reload, } = useDashboard(name);
79
- const [presetFilters, setPresetFilters] = useState(null);
86
+ export default function Dashboard({ name, hidden = false, SelectComponent = QuillSelectComponentWithCombo, MultiSelectComponent = QuillMultiSelectComponentWithCombo, ModalComponent = QuillModalComponent, ButtonComponent = MemoizedButton, SecondaryButtonComponent = MemoizedSecondaryButton, FilterTagComponent = QuillFilterPopover, PopoverComponent = MemoizedPopover, TextInputComponent = QuillTextInput, EmptyDashboardComponent = QuillEmptyDashboardComponent, DateRangePickerComponent = QuillDateRangePicker, MetricComponent = QuillMetricComponent, ChartComponent = QuillChartComponent, TableComponent = QuillTableComponent, TemplateMetricComponent = QuillTemplateMetricComponent, TemplateChartComponent = QuillTemplateChartComponent, TemplateTableComponent = QuillTemplateTableComponent, DashboardSectionComponent = DashboardSection, DashboardSectionContainerComponent = DashboardSectionContainer, FilterContainerComponent = QuillFilterContainerComponent, DashboardLoadingComponent = QuillLoadingDashboardComponent, ErrorComponent = QuillChartErrorWithAction, onClickReport, hoverActions, onChangeLoading, hideFilters, hideXAxis = false, hideYAxis = false, hideCartesianGrid = false, comparisonLineStyle = 'solid', containerStyle, className, chartContainerStyle = defaultChartContainerStyles,
87
+ // TODO: do something with these custom filters
88
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
89
+ filters, onClickChartElement, dateBucket, additionalProcessing, hideAdminErrors = true, templateDashboardName, pagination = { rowsPerPage: 10, rowsPerRequest: 50 }, }) {
90
+ const { isLoading, data, isDashboardFilterLoading, dashboardFilters: populatedDashboardFilters, reload, } = useDashboard(name);
80
91
  const [client, isClientLoading] = useContext(ClientContext);
81
92
  const [theme] = useContext(ThemeContext);
82
- const [initialLoad, setInitialLoad] = useState(true);
83
- const [appliedFilters, setAppliedFilters] = useState(null);
84
- const { dashboardFilters, dashboardFiltersDispatch } = useContext(DashboardFiltersContext);
93
+ const { dispatch: dashboardFiltersDispatch } = useContext(DashboardFiltersContext);
85
94
  const [schemaData] = useContext(SchemaDataContext);
86
- const [filterSchemaIsLoaded, setFilterSchemaIsLoaded] = useState(false);
87
- const [filterSchema, setFilterSchema] = useState({ columns: [] }); // Schema to be passed into FilterModal
88
95
  const [fieldValuesMap, setFieldValuesMap] = useState({}); // Mapping of unique values per field, used in string filter 'in' and 'not in'
89
96
  const [referencedTables, setReferencedTables] = useState([]); // Intersection of tables referenced in the dashboard
90
97
  const [fieldValuesIsLoaded, setFieldValuesIsLoaded] = useState(false);
91
98
  const [addFilterPopoverIsOpen, setAddFilterPopoverIsOpen] = useState(false);
92
99
  const [filterListIsOpen, setFilterListIsOpen] = useState(false);
93
100
  const [filterListAddFilterPopoverIsOpen, setFilterListAddFilterPopoverIsOpen,] = useState(false);
94
- const [uniqueCounter, setUniqueCounter] = useState(0);
95
- const userFilters = useMemo(() => {
96
- return (appliedFilters
97
- ?.map((filter, index) => {
98
- return { filter, index };
99
- })
100
- .filter((filter) => filter.filter.isUserFilter) ?? []);
101
- }, [appliedFilters]);
102
- const adminFilters = useMemo(() => {
103
- return appliedFilters?.filter((filter) => !filter.isUserFilter) ?? [];
104
- }, [appliedFilters]);
101
+ const presetOptions = useMemo(() => {
102
+ return populatedDashboardFilters?.[0]?.filterType === 'date_range'
103
+ ? populatedDashboardFilters[0].presetRanges?.map((elem) => {
104
+ if (!elem.isStatic) {
105
+ return {
106
+ label: elem.label,
107
+ value: elem.value,
108
+ startDate: PRIMARY_RANGE[elem.value].start,
109
+ endDate: PRIMARY_RANGE[elem.value].end,
110
+ };
111
+ }
112
+ return {
113
+ label: elem.label,
114
+ value: elem.value,
115
+ startDate: new Date(elem.startDate),
116
+ endDate: new Date(elem.endDate),
117
+ };
118
+ }) ?? defaultOptionsV2
119
+ : defaultOptionsV2;
120
+ }, [populatedDashboardFilters]);
121
+ const [userFilters, setUserFilters] = useState({});
122
+ // A filter value can either be a string, an array of strings for a multiselect, or a date range (that could have a comparison range)
123
+ const [filterValues, setFilterValues] = useState({});
105
124
  useEffect(() => {
125
+ setFilterValues({});
106
126
  reload(name, true);
107
- }, [name, client?.organizationId]);
127
+ }, [client?.organizationId]);
128
+ useEffect(() => {
129
+ setFilterValues({});
130
+ reload(name, false);
131
+ }, [name]);
108
132
  const customOperatorOptions = {
109
133
  [FieldTypes.Number]: [
110
134
  NumberOperator.EqualTo,
@@ -132,28 +156,6 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
132
156
  NullOperator.IsNull,
133
157
  ],
134
158
  };
135
- useEffect(() => {
136
- if (!data)
137
- return;
138
- onDashboardDataChange(data, schemaData.schema);
139
- }, [data, filters, schemaData.schema]);
140
- useEffect(() => {
141
- if (isDashboardFiltersLoading)
142
- return;
143
- if (populatedDashboardFilters) {
144
- const newApplied = appliedFilters?.map((filter) => {
145
- if ((filter.options && filter.options.length) ||
146
- filter.isUserFilter) {
147
- return filter;
148
- }
149
- const equivalent = populatedDashboardFilters.find((populatedFilter) => populatedFilter._id === filter._id);
150
- return { ...filter, options: equivalent?.options ?? filter.options };
151
- }) ?? populatedDashboardFilters;
152
- if (!equal(appliedFilters, newApplied)) {
153
- setAppliedFilters(newApplied);
154
- }
155
- }
156
- }, [isDashboardFiltersLoading, populatedDashboardFilters]);
157
159
  // Go through all columns in the referenced tables and get the unique values to use in fieldValuesMap
158
160
  useEffect(() => {
159
161
  const fetchData = async () => {
@@ -174,24 +176,22 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
174
176
  setFieldValuesMap(newFieldValues);
175
177
  setFieldValuesIsLoaded(true);
176
178
  };
177
- fetchData();
179
+ if (data?.customFiltersEnabled) {
180
+ fetchData();
181
+ }
178
182
  }, [referencedTables]);
179
- // Get the relevant information from the dashboard and schema to pass to FilterModal
180
- const updateFilterSchema = (sections, schema) => {
181
- if (!sections || !schema || schema.length === 0) {
182
- return;
183
+ const filterSchema = useMemo(() => {
184
+ if (!data?.sections ||
185
+ !schemaData.schema ||
186
+ schemaData.schema.length === 0) {
187
+ return { columns: [] };
183
188
  }
184
- setFilterSchemaIsLoaded(false);
189
+ const sections = data?.sections;
190
+ const schema = schemaData.schema;
185
191
  // find intersection of all referenced tables
186
- const tables = Object.keys(sections)
187
- .map((section) => {
188
- return sections[section].map((chart) => {
189
- return chart.referencedTables;
190
- });
191
- })
192
- .reduce((accumulator, currentArray) => {
193
- return accumulator.concat(currentArray);
194
- }, []);
192
+ const tables = Object.values(sections)
193
+ .flatMap((section) => section.map((chart) => chart.referencedTables))
194
+ .flat();
195
195
  if (tables && tables.length > 0) {
196
196
  let intersection = new Set(tables[0]);
197
197
  for (let i = 1; i < tables.length; ++i) {
@@ -215,292 +215,94 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
215
215
  .reduce((accumulator, currentArray) => {
216
216
  return accumulator.concat(currentArray);
217
217
  }, []);
218
- setFilterSchema({ columns });
219
- }
220
- else {
221
- setFilterSchema({ columns: [] });
222
- }
223
- setFilterSchemaIsLoaded(true);
224
- };
225
- const onDashboardDataChange = (resp, schema) => {
226
- // setDashboardSections(resp.sections ?? {});
227
- updateFilterSchema(resp.sections, schema);
228
- const filterArray = [];
229
- if (resp.dateFilter && Object.keys(resp.dateFilter).length) {
230
- let presetsOptions = defaultOptionsV2;
231
- if (resp.dateFilter.presetRanges) {
232
- presetsOptions = resp.dateFilter.presetRanges.map((elem) => {
233
- if (!elem.isStatic) {
234
- return {
235
- label: elem.label,
236
- value: elem.value,
237
- startDate: PRIMARY_RANGE[elem.value].start,
238
- endDate: PRIMARY_RANGE[elem.value].end,
239
- };
240
- }
241
- return {
242
- label: elem.label,
243
- value: elem.value,
244
- startDate: new Date(elem.startDate),
245
- endDate: new Date(elem.endDate),
246
- };
247
- });
248
- }
249
- setPresetFilters(presetsOptions);
250
- // Attempt to find a date filter in the current applied filters
251
- const currentDateFilter = appliedFilters?.find((filter) => filter.filterType === 'date_range');
252
- const key = currentDateFilter?.preset?.value ||
253
- resp.dateFilter?.primaryRange?.value ||
254
- 'LAST_6_MONTHS';
255
- const primaryPreset = presetsOptions.find((option) => {
256
- return option.value === key;
257
- });
258
- const filter = {
259
- startDate: primaryPreset.startDate,
260
- endDate: primaryPreset.endDate,
261
- filterType: 'date_range',
262
- options: presetsOptions.map((elem) => {
263
- return {
264
- label: elem.label,
265
- value: elem.value,
266
- };
267
- }),
268
- field: 'date_range',
269
- label: resp.dateFilter.label,
270
- preset: {
271
- label: primaryPreset.label,
272
- value: primaryPreset.value,
273
- },
274
- dashboardName: name,
275
- };
276
- if (resp.dateFilter.comparison) {
277
- filter.comparison = true;
278
- const compKey = resp.dateFilter.defaultComparisonRange ?? 'PREV_PERIOD';
279
- const range = { start: filter.startDate, end: filter.endDate };
280
- filter.comparisonRange = {
281
- startDate: COMPARISON_RANGE[compKey](range)?.start,
282
- endDate: COMPARISON_RANGE[compKey](range)?.end,
283
- value: compKey,
284
- };
285
- }
286
- else {
287
- filter.comparison = false;
288
- }
289
- filterArray.push(filter);
290
- }
291
- // Add string filters to filterArray
292
- if (resp.filters && resp.filters.length) {
293
- Object.values(resp.filters)
294
- .filter((filter) => filter.filterType !== 'date_range')
295
- .forEach((filter) => {
296
- let processedFilter = processFilter(filter);
297
- if (populatedDashboardFilters) {
298
- const equivalent = populatedDashboardFilters.find((populatedFilter) => populatedFilter._id === filter._id);
299
- processedFilter = {
300
- ...processedFilter,
301
- options: equivalent?.options ?? filter.options,
302
- };
303
- }
304
- filterArray.push(processedFilter);
305
- });
306
- }
307
- // Add custom filter to filterArray
308
- if (filters) {
309
- filters.forEach((filter) => {
310
- filterArray.push({
311
- ...filter,
312
- dashboardName: name,
313
- isUserFilter: true,
314
- });
315
- });
316
- }
317
- // remove all that are already present in dashboardSpecificFilters
318
- const dashboardSpecificFilters = dashboardFilters.filter((f) => f.dashboardName === name);
319
- if (!equal(dashboardSpecificFilters, filterArray)) {
320
- dashboardFiltersDispatch({
321
- type: 'CLEAR_AND_ADD_DASHBOARD_FILTERS',
322
- data: filterArray,
323
- dashboardName: name,
324
- });
325
- }
326
- if (!equal(appliedFilters, filterArray)) {
327
- setAppliedFilters(filterArray);
328
- }
329
- setInitialLoad(false);
330
- };
331
- const handleOnClickDashboardItem = (elem) => {
332
- if (onClickReport) {
333
- onClickReport({ ...elem, _id: elem.id });
334
- }
335
- };
336
- function removeQuotes(str) {
337
- if (str.startsWith('"') && str.endsWith('"')) {
338
- return str.slice(1, -1);
218
+ return { columns };
339
219
  }
340
220
  else {
341
- return str;
342
- }
343
- }
344
- const processFilter = (filter, value = null) => {
345
- //for dateObjects only, since values are arrays for dateObjects
346
- const { ...filterWithoutSelectedValue } = filter; // _ is a throwaway variable
347
- let selectedValue;
348
- let selectedElem;
349
- if (filter.filterType === 'string') {
350
- if (filter.options) {
351
- selectedElem = filter.options.find((elem) => elem[removeQuotes(filter.field)] === value);
352
- }
353
- if (selectedElem) {
354
- selectedValue = selectedElem[removeQuotes(filter.field)];
355
- }
356
- return {
357
- ...filterWithoutSelectedValue,
358
- ...(selectedValue ? { selectedValue } : {}),
359
- dashboardName: name,
360
- };
361
- }
362
- if (filter.filterType === 'date' || filter.filterType === 'date_range') {
363
- return {
364
- startDate: value ? value[0] : filter.startDate,
365
- endDate: value ? value[1] : filter.endDate,
366
- filterType: 'date_range',
367
- label: 'Date',
368
- field: 'date_range',
369
- options: filter.options,
370
- dashboardName: name,
371
- };
221
+ return { columns: [] };
372
222
  }
373
- };
223
+ }, [data?.sections, schemaData.schema]);
224
+ const handleOnClickDashboardItem = (elem) => onClickReport && onClickReport({ ...elem, _id: elem.id });
374
225
  const updateFilter = (filter, value = null, comparison = null) => {
375
- if (!appliedFilters) {
226
+ if (!populatedDashboardFilters)
376
227
  return;
377
- }
378
- //for dateObjects only, since values are arrays for dateObjects
379
- const { ...filterWithoutSelectedValue } = filter; // _ is a throwaway variable
228
+ let filterValue = {};
380
229
  if (filter.filterType === 'string') {
381
- let selectedValue = {};
382
230
  if (filter.stringFilterType === 'multiselect') {
383
231
  if ((value?.length ?? 0) === 0) {
384
- selectedValue = { values: [] };
232
+ filterValue = { values: undefined, operator: undefined };
385
233
  }
386
234
  else {
387
- selectedValue = { values: value, operator: 'IN' };
235
+ filterValue = { values: value, operator: 'IN' };
388
236
  }
389
237
  }
390
238
  else {
391
- selectedValue = { selectedValue: value };
392
- }
393
- const newFilter = {
394
- ...filterWithoutSelectedValue,
395
- ...selectedValue,
396
- dashboardName: name,
397
- stringFilterType: filter.stringFilterType,
398
- table: filter.table,
399
- labelField: filter.labelField,
400
- label: filter.label,
401
- field: filter.field,
402
- filterType: DashboardFilterType.String,
403
- };
404
- dashboardFiltersDispatch({
405
- type: 'UPDATE_DASHBOARD_FILTER',
406
- id: filter.field,
407
- data: newFilter,
408
- });
409
- const index = appliedFilters.findIndex((filter) => filter.field === newFilter.field &&
410
- filter.dashboardName === newFilter.dashboardName);
411
- if (index !== -1) {
412
- setAppliedFilters([
413
- ...appliedFilters.slice(0, index),
414
- newFilter,
415
- ...appliedFilters.slice(index + 1),
416
- ]);
239
+ filterValue = { selectedValue: value };
417
240
  }
418
- return;
241
+ setFilterValues((filterValues) => ({
242
+ ...filterValues,
243
+ [filter.label]: filterValue,
244
+ }));
419
245
  }
420
- if (filter.filterType === DashboardFilterType.Date) {
246
+ else if (filter.filterType === DashboardFilterType.Date) {
421
247
  if (comparison ||
422
- (filter.comparison && filter.comparisonRange.value !== 'NO_COMPARISON')) {
248
+ (filter.comparison &&
249
+ (filter.comparisonRange?.value ?? 'NO_COMPARISON') !==
250
+ 'NO_COMPARISON')) {
423
251
  let preset = '';
424
252
  if (comparison) {
425
- preset = filter.preset.label;
253
+ preset = filter.preset.value;
426
254
  }
427
- const key = comparison?.value || filter.comparisonRange.value;
255
+ const key = comparison?.value ||
256
+ (filter.comparisonRange?.value ?? 'NO_COMPARISON');
428
257
  let primaryRange = {
429
258
  start: value ? value.startDate : filter.startDate,
430
259
  end: value ? value.endDate : filter.endDate,
431
260
  };
432
261
  if (value && value.preset) {
433
262
  preset = value.preset;
434
- primaryRange = getRangeFromPresetOptions(value.preset, presetFilters);
263
+ primaryRange = getRangeFromPresetOptions(value.preset, presetOptions);
435
264
  }
436
- const newFilter = {
265
+ filterValue = {
437
266
  startDate: primaryRange.start,
438
267
  endDate: primaryRange.end,
439
- filterType: DashboardFilterType.Date,
440
- label: filter.label,
441
- field: 'date_range',
442
- preset: { label: preset, value: preset },
443
- options: filter.options,
444
- comparison: true,
268
+ preset: {
269
+ label: presetOptions.find((o) => o.value === preset)?.label ?? preset,
270
+ value: preset,
271
+ },
445
272
  comparisonRange: {
446
273
  startDate: COMPARISON_RANGE[key](primaryRange)?.start,
447
274
  endDate: COMPARISON_RANGE[key](primaryRange)?.end,
448
275
  value: key,
449
276
  },
450
- defaultComparisonRange: filter.defaultComparisonRange,
451
- primaryRange: filter.primaryRange,
452
- dashboardName: name,
453
277
  };
454
- dashboardFiltersDispatch({
455
- type: 'UPDATE_DASHBOARD_FILTER',
456
- id: 'date_range',
457
- data: newFilter,
458
- });
459
- const index = appliedFilters.findIndex((filter) => filter.field === newFilter.field &&
460
- filter.dashboardName === newFilter.dashboardName);
461
- if (index !== -1) {
462
- setAppliedFilters([
463
- ...appliedFilters.slice(0, index),
464
- newFilter,
465
- ...appliedFilters.slice(index + 1),
466
- ]);
467
- }
278
+ setFilterValues((filterValues) => ({
279
+ ...filterValues,
280
+ [filter.label]: filterValue,
281
+ }));
468
282
  }
469
283
  else {
470
284
  const primaryRange = value && value.preset
471
- ? getRangeFromPresetOptions(value.preset, presetFilters)
285
+ ? getRangeFromPresetOptions(value.preset, presetOptions)
472
286
  : {
473
287
  start: value?.startDate || filter.startDate,
474
288
  end: value?.endDate || filter.endDate,
475
289
  };
476
290
  const preset = value?.preset ? value.preset : '';
477
- const newFilter = {
478
- ...filter,
479
- preset: { label: preset, value: preset },
291
+ filterValue = {
480
292
  startDate: primaryRange.start,
481
293
  endDate: primaryRange.end,
482
- filterType: DashboardFilterType.Date,
483
- field: 'date_range',
484
- options: filter.options,
485
- label: filter.label,
486
- dashboardName: name,
294
+ preset: { label: preset, value: preset },
487
295
  };
488
- dashboardFiltersDispatch({
489
- type: 'UPDATE_DASHBOARD_FILTER',
490
- id: 'date_range',
491
- data: newFilter,
492
- });
493
- const index = appliedFilters.findIndex((filter) => filter.field === newFilter.field &&
494
- filter.dashboardName === newFilter.dashboardName);
495
- if (index !== -1) {
496
- setAppliedFilters([
497
- ...appliedFilters.slice(0, index),
498
- newFilter,
499
- ...appliedFilters.slice(index + 1),
500
- ]);
501
- }
296
+ setFilterValues((filterValues) => ({
297
+ ...filterValues,
298
+ [filter.label]: filterValue,
299
+ }));
502
300
  }
503
301
  }
302
+ reload(name, false, undefined, {
303
+ filters: populatedDashboardFilters.map((f) => filter.label === f.label ? { ...f, ...filterValue } : f),
304
+ editedFilterLabel: filter.label,
305
+ });
504
306
  };
505
307
  // generate the correct filter structure
506
308
  const getUserFilter = (filter, id, existingFilter) => {
@@ -525,34 +327,20 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
525
327
  return userFilter;
526
328
  };
527
329
  // new update filter function for user added filters
528
- const updateUserFilter = (filter, id) => {
529
- if (!appliedFilters) {
530
- return;
531
- }
532
- const newFilter = getUserFilter(filter, id);
533
- dashboardFiltersDispatch({
534
- type: 'ADD_DASHBOARD_FILTER',
535
- data: newFilter,
536
- });
537
- setAppliedFilters([...appliedFilters, newFilter]);
330
+ const updateUserFilter = (filter) => {
331
+ setUserFilters((userFilters) => ({
332
+ ...userFilters,
333
+ [filter.field]: filter,
334
+ }));
538
335
  };
539
336
  useEffect(() => {
540
- if (onChangeLoading) {
541
- onChangeLoading(isLoading || initialLoad);
337
+ if (onChangeLoading && isLoading) {
338
+ onChangeLoading(isLoading);
542
339
  }
543
- }, [isLoading, initialLoad, onChangeLoading]);
544
- const sortByOrdering = (a, b) => {
545
- if (a.order === undefined && b.order === undefined)
546
- return 0;
547
- if (a.order === undefined)
548
- return 1;
549
- if (b.order === undefined)
550
- return -1;
551
- return a.order - b.order;
552
- };
340
+ }, [isLoading, onChangeLoading]);
553
341
  if (!isLoading &&
554
342
  (Object.keys(data?.sections ?? {}).length === 0 ||
555
- data?.sections?.['']?.length === 0)) {
343
+ Object.values(data?.sections ?? {})[0]?.length === 0)) {
556
344
  return _jsx(EmptyDashboardComponent, {});
557
345
  }
558
346
  if (hidden || isLoading || isClientLoading || !data?.sections) {
@@ -560,13 +348,18 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
560
348
  }
561
349
  return (_jsxs("div", { className: className, ...styleToProps(containerStyle), children: [data &&
562
350
  data.customFiltersEnabled &&
563
- filterSchemaIsLoaded &&
564
351
  !hideAdminErrors &&
565
352
  !hideFilters &&
566
353
  data &&
567
354
  data.customFiltersEnabled &&
568
355
  filterSchema &&
569
- filterSchema.columns.length === 0 && (_jsx("div", { style: { marginBottom: 10 }, children: _jsx(QuillErrorMessageComponent, { errorMessage: "Warning: No custom filter options because there are no common views among the charts in the dashboard" }) })), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, children: [!hideFilters && (_jsxs(FilterContainerComponent, { children: [adminFilters.map((filter, index) => (_jsx(DashboardFilter, { filter: filter, onChangeFilter: updateFilter, theme: theme, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, DateRangePickerComponent: DateRangePickerComponent, isLoading: isDashboardFiltersLoading }, filter._id ?? index))), _jsxs("div", { style: {
356
+ filterSchema.columns.length === 0 && (_jsx("div", { style: { marginBottom: 10 }, children: _jsx(QuillErrorMessageComponent, { errorMessage: "Warning: No custom filter options because there are no common views among the charts in the dashboard" }) })), _jsxs("div", { style: { display: 'flex', flexDirection: 'row', alignItems: 'center' }, children: [!hideFilters && (_jsxs(FilterContainerComponent, { children: [(populatedDashboardFilters ?? []).map((filter) => (_jsx(DashboardFilter, { filter: {
357
+ ...filter,
358
+ ...(filter.filterType === 'date_range' && {
359
+ options: presetOptions,
360
+ }),
361
+ ...filterValues[filter.label],
362
+ }, onChangeFilter: updateFilter, theme: theme, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, DateRangePickerComponent: DateRangePickerComponent, isLoading: isDashboardFilterLoading(filter.label) }, filter.label + name))), _jsxs("div", { style: {
570
363
  display: 'flex',
571
364
  flexDirection: 'column',
572
365
  }, children: [data && data.customFiltersEnabled && (_jsx(SecondaryButtonComponent, { onClick: () => {
@@ -576,14 +369,12 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
576
369
  }
577
370
  }, label: `Add Filter` })), _jsx(PopoverComponent, { isOpen: addFilterPopoverIsOpen, setIsOpen: setAddFilterPopoverIsOpen, popoverTitle: "Add Filter", popoverChildren: _jsx(FilterModal, { schema: filterSchema, fieldValuesMap: fieldValuesMap, onSubmitFilter: (filter) => {
578
371
  setAddFilterPopoverIsOpen(false);
579
- if (appliedFilters) {
580
- updateUserFilter(filter, appliedFilters.length);
581
- }
582
- }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, TextInputComponent: TextInputComponent }), containerStyle: { position: 'relative', top: 10 } })] }), userFilters.length > 0 && (_jsx(ModalComponent, { triggerLabel: `Filters${userFilters.length > 0 ? ` (${userFilters.length})` : ''}`, isOpen: filterListIsOpen, setIsOpen: setFilterListIsOpen, title: "Filters", children: _jsxs("div", { style: {
372
+ updateUserFilter(filter);
373
+ }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, TextInputComponent: TextInputComponent }), containerStyle: { position: 'relative', top: 10 } })] }), Object.values(userFilters).length > 0 && (_jsx(ModalComponent, { triggerLabel: `Filters${Object.values(userFilters).length > 0 ? ` (${Object.values(userFilters).length})` : ''}`, isOpen: filterListIsOpen, setIsOpen: setFilterListIsOpen, title: "Filters", children: _jsxs("div", { style: {
583
374
  display: 'flex',
584
375
  flexDirection: 'column',
585
376
  alignItems: 'start',
586
- }, children: [userFilters.map(({ filter, index }) => (_jsx(FilterPopoverWrapper, { schema: filterSchema, filter: {
377
+ }, children: [Object.values(userFilters).map((filter, index) => (_jsx(FilterPopoverWrapper, { schema: filterSchema, filter: {
587
378
  filterType: filter.filterType,
588
379
  fieldType: filter.fieldType,
589
380
  field: filter.field,
@@ -591,31 +382,17 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
591
382
  value: filter.value,
592
383
  }, filterLabel: filter ? filterSentence(filter) : '', index: index, fieldValuesMap: fieldValuesMap, customOperatorOptions: customOperatorOptions, FilterTagComponent: FilterTagComponent, FilterModal: FilterModal, ButtonComponent: ButtonComponent, SecondaryButtonComponent: SecondaryButtonComponent, SelectComponent: SelectComponent, TextInputComponent: TextInputComponent, MultiSelectComponent: MultiSelectComponent, handleFilterSave: (newFilter) => {
593
384
  const updatedFilter = getUserFilter(newFilter, filter._id, filter);
594
- if (!appliedFilters) {
595
- return;
596
- }
597
385
  dashboardFiltersDispatch({
598
386
  type: 'UPDATE_DASHBOARD_FILTER',
599
387
  id: updatedFilter._id,
600
388
  data: updateFilter,
601
389
  });
602
- setAppliedFilters([
603
- ...appliedFilters.slice(0, index),
604
- updatedFilter,
605
- ...appliedFilters.slice(index + 1),
606
- ]);
607
390
  }, handleFilterDelete: () => {
608
- if (!appliedFilters) {
609
- return;
610
- }
611
- dashboardFiltersDispatch({
612
- type: 'DELETE_DASHBOARD_FILTER',
613
- id: appliedFilters[index]._id,
391
+ setUserFilters((userFilters) => {
392
+ const updatedFilters = { ...userFilters };
393
+ delete updatedFilters[filter.field];
394
+ return updatedFilters;
614
395
  });
615
- setAppliedFilters([
616
- ...appliedFilters.slice(0, index),
617
- ...appliedFilters.slice(index + 1),
618
- ]);
619
396
  }, containerStyle: { width: 300, marginBottom: 10 } }, `userFilter_${index}_${filter ? filterSentence(filter) : ''}`))), _jsxs("div", { style: {
620
397
  display: 'flex',
621
398
  flexDirection: 'column',
@@ -626,10 +403,8 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
626
403
  }, label: `Add Filter` }), _jsx(PopoverComponent, { isOpen: filterListAddFilterPopoverIsOpen, setIsOpen: setFilterListAddFilterPopoverIsOpen, popoverTitle: "Add Filter", popoverChildren: _jsx(FilterModal, { schema: filterSchema, fieldValuesMap: fieldValuesMap, onSubmitFilter: (filter) => {
627
404
  setFilterListAddFilterPopoverIsOpen(false);
628
405
  setFilterListIsOpen(false);
629
- const id = uniqueCounter;
630
- setUniqueCounter(uniqueCounter + 1);
631
- updateUserFilter(filter, id);
632
- }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, TextInputComponent: TextInputComponent }), containerStyle: { position: 'relative', top: 10 } })] })] }) }))] })), templateDashboardName && (_jsx(QuillDashboardTemplate, { name: templateDashboardName, originDashboard: name, client: client, appliedFilters: appliedFilters, ModalComponent: ModalComponent, TemplateChartComponent: TemplateChartComponent, TemplateMetricComponent: TemplateMetricComponent, TemplateTableComponent: TemplateTableComponent, ButtonComponent: SecondaryButtonComponent }))] }), Object.keys(data.sections)
406
+ updateUserFilter(filter);
407
+ }, onDeleteFilter: () => { }, ButtonComponent: ButtonComponent, SelectComponent: SelectComponent, MultiSelectComponent: MultiSelectComponent, TextInputComponent: TextInputComponent }), containerStyle: { position: 'relative', top: 10 } })] })] }) }))] })), templateDashboardName && (_jsx(QuillDashboardTemplate, { name: templateDashboardName, originDashboard: name, client: client, appliedFilters: populatedDashboardFilters, ModalComponent: ModalComponent, TemplateChartComponent: TemplateChartComponent, TemplateMetricComponent: TemplateMetricComponent, TemplateTableComponent: TemplateTableComponent, ButtonComponent: SecondaryButtonComponent }))] }), Object.keys(data.sections)
633
408
  .sort(function (a, b) {
634
409
  return a.length - b.length;
635
410
  })
@@ -643,13 +418,19 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
643
418
  textAlign: 'left',
644
419
  marginTop: 12,
645
420
  }, children: section })] })), metrics(data.sections, section, sortByOrdering).length > 0 && (_jsx(DashboardSectionComponent, { section: "metrics", children: metrics(data.sections, section, sortByOrdering).map((item, index) => {
646
- return (_jsx(DataLoader, { item: item, filters: appliedFilters, children: ({ isLoading, error, data, }) => (_jsx(MetricComponent, { error: error, isLoading: isLoading, report: data, onClick: !isLoading && onClickReport
421
+ return (_jsx(DataLoader, { item: item, filters: populatedDashboardFilters, additionalProcessing: {
422
+ page: DEFAULT_PAGINATION,
423
+ last: additionalProcessing?.last,
424
+ }, children: ({ isLoading, error, data, }) => (_jsx(MetricComponent, { error: error, isLoading: isLoading, report: data, onClick: !isLoading && onClickReport
647
425
  ? () => handleOnClickDashboardItem({
648
426
  ...item,
649
427
  ...data,
650
428
  })
651
- : () => { }, hoverActions: hoverActions }, item.name + '' + index)) }, `${item._id}${index}`));
652
- }) })), charts(data.sections, section, sortByOrdering).length > 0 && (_jsx(DashboardSectionComponent, { section: "charts", children: charts(data.sections, section, sortByOrdering).map((item, index) => (_jsx(ChartDataLoader, { item: item, dateBucket: dateBucket, additionalProcessing: additionalProcessing, filters: appliedFilters, children: ({ isLoading, data, error, dateBucket, }) => (_jsx(ChartComponent, { report: data, error: error, onClick: () => {
429
+ : () => { }, hoverActions: hoverActions }, item.name + '' + index)) }, `metric${index}`));
430
+ }) })), charts(data.sections, section, sortByOrdering).length > 0 && (_jsx(DashboardSectionComponent, { section: "charts", children: charts(data.sections, section, sortByOrdering).map((item, index) => (_jsx(ChartDataLoader, { item: item, dateBucket: dateBucket, additionalProcessing: {
431
+ page: pagination,
432
+ last: additionalProcessing?.last,
433
+ }, filters: populatedDashboardFilters, children: ({ isLoading, data, error, dateBucket, }) => (_jsx(ChartComponent, { report: data, error: error, onClick: () => {
653
434
  if (!isLoading && onClickReport) {
654
435
  handleOnClickDashboardItem({
655
436
  ...item,
@@ -661,7 +442,10 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
661
442
  height: 300,
662
443
  } })) : (_jsx(ChartDisplay, { reportId: data.id, config: data, loading: isLoading, containerStyle: chartContainerStyle, colors: theme.chartColors?.length
663
444
  ? theme.chartColors
664
- : undefined, scrollable: false, hideXAxis: hideXAxis, hideYAxis: hideYAxis, hideCartesianGrid: hideCartesianGrid, comparisonLineStyle: comparisonLineStyle, onClickChartElement: onClickChartElement })) }, item.name + '' + index)) }, `${item._id}${index}`))) })), tables(data.sections, section, sortByOrdering).length > 0 && (_jsx(DashboardSectionComponent, { section: "tables", children: tables(data.sections, section, sortByOrdering).map((item, index) => (_jsx(DataLoader, { item: item, filters: appliedFilters, children: ({ isLoading, error, onPageChange, onSortChange, data, rowCount, rowCountIsLoading, }) => (_jsx(TableComponent, { report: data, isLoading: isLoading, error: error, onClick: !isLoading && onClickReport
445
+ : undefined, scrollable: false, hideXAxis: hideXAxis, hideYAxis: hideYAxis, hideCartesianGrid: hideCartesianGrid, comparisonLineStyle: comparisonLineStyle, onClickChartElement: onClickChartElement })) }, item.name + '' + index)) }, `chart${index}`))) })), tables(data.sections, section, sortByOrdering).length > 0 && (_jsx(DashboardSectionComponent, { section: "tables", children: tables(data.sections, section, sortByOrdering).map((item, index) => (_jsx(DataLoader, { item: item, filters: populatedDashboardFilters, additionalProcessing: {
446
+ page: pagination,
447
+ last: additionalProcessing?.last,
448
+ }, children: ({ isLoading, error, onPageChange, onSortChange, data, rowCount, rowCountIsLoading, }) => (_jsx(TableComponent, { report: data, isLoading: isLoading, error: error, onClick: !isLoading && onClickReport
665
449
  ? () => handleOnClickDashboardItem({
666
450
  ...item,
667
451
  ...data,
@@ -669,6 +453,6 @@ export default function Dashboard({ name, hidden = false, SelectComponent = Quil
669
453
  : undefined, hoverActions: hoverActions, rowCount: rowCount ??
670
454
  data?.rowCount ??
671
455
  data?.rows?.length ??
672
- 0, rowCountIsLoading: rowCountIsLoading, onPageChange: (page) => onPageChange(page), onSortChange: (sort) => onSortChange(sort) })) }, `${item._id}${index}`))) }))] }, section + '' + sectionIndex));
456
+ 0, rowCountIsLoading: rowCountIsLoading, onPageChange: (page) => onPageChange(page), onSortChange: (sort) => onSortChange(sort) })) }, `${name}${index}`))) }))] }, section + '' + sectionIndex));
673
457
  })] }));
674
458
  }