@vizzly/dashboard 0.15.0-dev-22a3a4d82d007a71e3d303cc3550ce20bed7a1e9 → 0.15.0-dev-f6507ed8045dad10d9fb36c61aa24ece44161d7f

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.
@@ -5261,6 +5261,16 @@ var CONSTANTS$4 = {
5261
5261
  type: 'conditionalFormatting',
5262
5262
  title: 'Conditional Formatting',
5263
5263
  description: ''
5264
+ },
5265
+ visual_format: {
5266
+ type: 'visualFormat',
5267
+ title: 'Visual Format',
5268
+ description: 'Configure how group columns are visually represented'
5269
+ },
5270
+ kpi_summarisation: {
5271
+ type: 'kpiSummarisation',
5272
+ title: '',
5273
+ description: 'Show aggregate statistics above column headers'
5264
5274
  }
5265
5275
  }
5266
5276
  };
@@ -5370,7 +5380,7 @@ var BasicTable = function BasicTable(config) {
5370
5380
  subSection: [(_CONSTANTS$format_pan = CONSTANTS$4.format_panel.format) == null ? void 0 : _CONSTANTS$format_pan.subSectionDefinition.time]
5371
5381
  }), namespace(CONSTANTS$4, 'prefixes'), _extends({}, namespace(CONSTANTS$4, 'conditional_formatting'), {
5372
5382
  ruleType: 'backgroundColor'
5373
- })];
5383
+ }), namespace(CONSTANTS$4, 'visual_format'), namespace(CONSTANTS$4, 'kpi_summarisation')];
5374
5384
  },
5375
5385
  supportedCustomFields: {
5376
5386
  percentages: false,
@@ -7098,13 +7108,38 @@ var attributesSchema$a = function attributesSchema(config) {
7098
7108
  hiddenFields: Joi.array().items(Joi.string()),
7099
7109
  tableDrilldown: Joi.array().items(Joi.object({
7100
7110
  subsetDimension: Joi.string().required().description('The ID of the field in the data set to drill down by.')
7101
- })).description('Drilldown configuration for a pivot table.')
7111
+ })).description('Drilldown configuration for a pivot table.'),
7112
+ summarizeKPIs: Joi["boolean"]()["default"](false).description('Enable/disable KPI summarisation above column headers.'),
7113
+ visualFormatColumns: Joi.array().items(Joi.string().min(1))["default"]([]).sparse(false).description('Array of column names to display as horizontal bars.'),
7114
+ results: Joi.array().items(Joi.object({
7115
+ content: Joi.array().required(),
7116
+ fields: Joi.array().items(Joi.object({
7117
+ id: Joi.string().required(),
7118
+ publicName: Joi.string().required(),
7119
+ dataType: Joi.string().required(),
7120
+ hidden: Joi["boolean"](),
7121
+ fieldId: Joi.string().required(),
7122
+ "function": Joi.string().required(),
7123
+ outputDataType: Joi.string().required()
7124
+ }).unknown(true)).required(),
7125
+ hasMoreResults: Joi.alternatives([Joi["boolean"](), Joi.valid(null)])
7126
+ }).unknown(true)).description('Query results data structure containing fields and content.')
7102
7127
  }));
7103
7128
  };
7104
7129
 
7105
7130
  var setAttributes$a = (function (config) {
7106
7131
  return function (dataTable, partial) {
7132
+ var _partial$dimension;
7107
7133
  var newAttributes = setAttributes(dataTable, partial, attributesSchema$a(config));
7134
+ var numOfColumnsInDataTable = dataTable.dimension.filter(function (d) {
7135
+ return d.pivot === 'y';
7136
+ }).length;
7137
+ var numOfColumnsInPartial = (_partial$dimension = partial.dimension) == null ? void 0 : _partial$dimension.filter(function (d) {
7138
+ return d.pivot === 'y';
7139
+ }).length;
7140
+ var dimensionColumnsHasChanged = numOfColumnsInPartial === undefined ? false : numOfColumnsInDataTable !== numOfColumnsInPartial;
7141
+ var shouldRemoveVisualFormatColumns = dimensionColumnsHasChanged && !partial.visualFormatColumns;
7142
+ if (shouldRemoveVisualFormatColumns) newAttributes.visualFormatColumns = [];
7108
7143
  newAttributes = removeUnusedOrderFieldsFromTimeSeriesComponent(newAttributes);
7109
7144
  return newAttributes;
7110
7145
  };
@@ -7189,6 +7224,16 @@ var CONSTANTS$a = {
7189
7224
  }
7190
7225
  }
7191
7226
  },
7227
+ kpi_summarisation: {
7228
+ type: 'kpiSummarisation',
7229
+ title: '',
7230
+ description: 'Show aggregate statistics above each column.'
7231
+ },
7232
+ visual_format: {
7233
+ type: 'visualFormat',
7234
+ title: 'Visual Format',
7235
+ description: 'Configure how the group column is displayed visually.'
7236
+ },
7192
7237
  format: {
7193
7238
  type: 'format',
7194
7239
  title: 'Format',
@@ -7240,7 +7285,7 @@ var DataTable = function DataTable(config) {
7240
7285
  return hydrated;
7241
7286
  },
7242
7287
  load: function load(dumped) {
7243
- var _dumped$tags, _dumped$hiddenFields;
7288
+ var _dumped$tags, _dumped$hiddenFields, _dumped$summarizeKPIs, _dumped$visualFormatC;
7244
7289
  return {
7245
7290
  type: dumped.type,
7246
7291
  measure: upcastMeasure(dumped.measure),
@@ -7266,7 +7311,9 @@ var DataTable = function DataTable(config) {
7266
7311
  sizing: dumped.sizing,
7267
7312
  tableDrilldown: upcastTableDrilldown(dumped.tableDrilldown),
7268
7313
  tags: (_dumped$tags = dumped.tags) != null ? _dumped$tags : [],
7269
- hiddenFields: (_dumped$hiddenFields = dumped.hiddenFields) != null ? _dumped$hiddenFields : []
7314
+ hiddenFields: (_dumped$hiddenFields = dumped.hiddenFields) != null ? _dumped$hiddenFields : [],
7315
+ summarizeKPIs: (_dumped$summarizeKPIs = dumped.summarizeKPIs) != null ? _dumped$summarizeKPIs : false,
7316
+ visualFormatColumns: (_dumped$visualFormatC = dumped.visualFormatColumns) != null ? _dumped$visualFormatC : []
7270
7317
  };
7271
7318
  },
7272
7319
  setAttributes: setAttributes$a(config),
@@ -7296,7 +7343,9 @@ var DataTable = function DataTable(config) {
7296
7343
  sizing: {},
7297
7344
  tableDrilldown: [],
7298
7345
  tags: [],
7299
- hiddenFields: []
7346
+ hiddenFields: [],
7347
+ summarizeKPIs: false,
7348
+ visualFormatColumns: []
7300
7349
  }, overrides);
7301
7350
  },
7302
7351
  schema: attributesSchema$a(config),
@@ -7360,12 +7409,8 @@ var DataTable = function DataTable(config) {
7360
7409
  return dimensionsForPivot(attrs.dimension, 'x');
7361
7410
  },
7362
7411
  testId: 'add-dimension'
7363
- }), _extends({}, namespace(CONSTANTS$a, 'drilldown'), {
7364
- options: {
7365
- maxOptions: 1,
7366
- property: 'tableDrilldown'
7367
- }
7368
- }), _extends({}, namespace(CONSTANTS$a, 'field_metrics'), {
7412
+ }), // { ...namespace<'drilldown'>(CONSTANTS, 'drilldown'), options: { maxOptions: 1, property: 'tableDrilldown' } },
7413
+ _extends({}, namespace(CONSTANTS$a, 'field_metrics'), {
7369
7414
  fieldFilterOptions: {
7370
7415
  forComponent: 'dataTable'
7371
7416
  },
@@ -7384,7 +7429,7 @@ var DataTable = function DataTable(config) {
7384
7429
  },
7385
7430
  formatPanelConfig: function formatPanelConfig() {
7386
7431
  var _CONSTANTS$format_pan;
7387
- return [headingConstant(CONSTANTS$a), _extends({}, namespace(CONSTANTS$a, 'format'), {
7432
+ return [headingConstant(CONSTANTS$a), namespace(CONSTANTS$a, 'kpi_summarisation'), namespace(CONSTANTS$a, 'visual_format'), _extends({}, namespace(CONSTANTS$a, 'format'), {
7388
7433
  subSection: [(_CONSTANTS$format_pan = CONSTANTS$a.format_panel.format) == null ? void 0 : _CONSTANTS$format_pan.subSectionDefinition.time]
7389
7434
  }), namespace(CONSTANTS$a, 'prefixes'), _extends({}, namespace(CONSTANTS$a, 'conditional_formatting'), {
7390
7435
  ruleType: 'backgroundColor'
@@ -52166,7 +52211,9 @@ var defaultProps$7 = {
52166
52211
  numberFormat: {},
52167
52212
  sizing: {},
52168
52213
  tableDrilldown: [],
52169
- tags: []
52214
+ tags: [],
52215
+ summarizeKPIs: false,
52216
+ visualFormatColumns: []
52170
52217
  };
52171
52218
 
52172
52219
  function hasPrevious(offset) {
@@ -52290,6 +52337,11 @@ var thGroupRow = function thGroupRow(themedStyles) {
52290
52337
  2: {
52291
52338
  background: themedStyles == null || (_themedStyles$th11 = themedStyles.th) == null || (_themedStyles$th11 = _themedStyles$th11.level) == null ? void 0 : _themedStyles$th11[2].background
52292
52339
  }
52340
+ },
52341
+ alignTop: {
52342
+ "true": {
52343
+ verticalAlign: 'top'
52344
+ }
52293
52345
  }
52294
52346
  }
52295
52347
  }));
@@ -52690,7 +52742,8 @@ var TH = /*#__PURE__*/forwardRef(function (props, ref) {
52690
52742
  }));
52691
52743
  } else if (props.scope === 'row') {
52692
52744
  return tableStyles.thGroupRow(theme == null ? void 0 : theme.tables)(_extends({}, styleOptions, {
52693
- deadSpace: props != null && props.deadSpace ? 'true' : undefined
52745
+ deadSpace: props != null && props.deadSpace ? 'true' : undefined,
52746
+ alignTop: true
52694
52747
  }));
52695
52748
  } else {
52696
52749
  var _theme$tables2;
@@ -52716,6 +52769,7 @@ var TH = /*#__PURE__*/forwardRef(function (props, ref) {
52716
52769
  "data-clickenabled": clickEnabled ? 'true' : 'false',
52717
52770
  onClick: props == null ? void 0 : props.onClick,
52718
52771
  onKeyDown: handleRowClick,
52772
+ rowSpan: props.rowSpan,
52719
52773
  children: [(props == null ? void 0 : props.dragSettings) && jsx(TableColumnResizer, _extends({}, props == null ? void 0 : props.dragSettings)), jsx("div", {
52720
52774
  style: props.columnStyles,
52721
52775
  className: styles({
@@ -52866,8 +52920,8 @@ var TR = function TR(props) {
52866
52920
  return jsx("tr", {
52867
52921
  "data-themeapi": props.odd ? 'tables.body.odd' : 'tables.body.even',
52868
52922
  className: "" + tableStyles.tr(theme == null ? void 0 : theme.tables)({
52869
- odd: props.odd && 'true',
52870
- even: props.even && 'true'
52923
+ odd: props.odd && props.hover,
52924
+ even: props.even && props.hover
52871
52925
  }),
52872
52926
  "data-chipposition": "top.left",
52873
52927
  "aria-expanded": props.expanded === true ? 'true' : (props == null ? void 0 : props.expanded) === false ? 'false' : undefined,
@@ -53281,7 +53335,8 @@ var button$4 = /*#__PURE__*/buildStyleOverrides({
53281
53335
  height: '1.25rem',
53282
53336
  width: '1.25rem',
53283
53337
  '&:disabled': {
53284
- opacity: 0.4
53338
+ opacity: 0.4,
53339
+ cursor: 'default'
53285
53340
  }
53286
53341
  });
53287
53342
  var text$2 = /*#__PURE__*/buildStyleOverrides({
@@ -53317,8 +53372,8 @@ var Pagination = function Pagination(props) {
53317
53372
 
53318
53373
  var getNumberFormat = function getNumberFormat(id, exportNames) {
53319
53374
  if (exportNames[id]) return exportNames[id];
53320
- if (isDatumKey(id)) return exportNames[toFieldId(id)];
53321
- return undefined;
53375
+ if (isDatumKey(id) && exportNames[toFieldId(id)]) return exportNames[toFieldId(id)];
53376
+ return '_vizzly_compact';
53322
53377
  };
53323
53378
 
53324
53379
  /**
@@ -53431,34 +53486,6 @@ var findPrefix = function findPrefix(prefixes, resultField) {
53431
53486
  })) == null ? void 0 : _prefixes$find.prefix;
53432
53487
  };
53433
53488
 
53434
- var consolidateTableHeadings = function consolidateTableHeadings(titles) {
53435
- var result = [];
53436
- var _loop = function _loop() {
53437
- var content = _step.value;
53438
- var existingCell = result.find(function (c) {
53439
- return c.content === content.formatted;
53440
- });
53441
- if (existingCell) {
53442
- existingCell.colSpan += 1;
53443
- } else {
53444
- result.push({
53445
- content: content.formatted,
53446
- colSpan: 1,
53447
- unformatted: content.unformatted
53448
- });
53449
- }
53450
- };
53451
- for (var _iterator = _createForOfIteratorHelperLoose(titles), _step; !(_step = _iterator()).done;) {
53452
- _loop();
53453
- }
53454
- return result;
53455
- };
53456
- function processValues(parsedDatumKey, formatter) {
53457
- return parsedDatumKey.dimensionValues.map(function (value, valueIndex) {
53458
- var fieldId = parsedDatumKey.dimensionKeys[valueIndex];
53459
- return formatter(value, fieldId);
53460
- }).join(', ');
53461
- }
53462
53489
  var getPivotTableGroupTitles = function getPivotTableGroupTitles(result, dimension, tableRepresentationFields, dateTimeFormatOptions, supportedTimeTruncFunctions) {
53463
53490
  var show = some(dimension, function (d) {
53464
53491
  return d.pivot == 'y';
@@ -53509,6 +53536,34 @@ var formatYAxisGroupValue = function formatYAxisGroupValue(result, resultFieldId
53509
53536
  return "" + value;
53510
53537
  }
53511
53538
  };
53539
+ var consolidateTableHeadings = function consolidateTableHeadings(titles) {
53540
+ var result = [];
53541
+ var _loop = function _loop() {
53542
+ var content = _step.value;
53543
+ var existingCell = result.find(function (c) {
53544
+ return c.content === content.formatted;
53545
+ });
53546
+ if (existingCell) {
53547
+ existingCell.colSpan += 1;
53548
+ } else {
53549
+ result.push({
53550
+ content: content.formatted,
53551
+ colSpan: 1,
53552
+ unformatted: content.unformatted
53553
+ });
53554
+ }
53555
+ };
53556
+ for (var _iterator = _createForOfIteratorHelperLoose(titles), _step; !(_step = _iterator()).done;) {
53557
+ _loop();
53558
+ }
53559
+ return result;
53560
+ };
53561
+ function processValues(parsedDatumKey, formatter) {
53562
+ return parsedDatumKey.dimensionValues.map(function (value, valueIndex) {
53563
+ var fieldId = parsedDatumKey.dimensionKeys[valueIndex];
53564
+ return formatter(value, fieldId);
53565
+ }).join(', ');
53566
+ }
53512
53567
 
53513
53568
  var getExportName = function getExportName(id, exportNames) {
53514
53569
  if (exportNames[id]) return exportNames[id];
@@ -53745,6 +53800,86 @@ function getFormattedByRule(_ref) {
53745
53800
  return {};
53746
53801
  }
53747
53802
 
53803
+ function _EMOTION_STRINGIFIED_CSS_ERROR__$b() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; }
53804
+ var calculatePercentage = function calculatePercentage(value, max) {
53805
+ if (max === 0) return 0;
53806
+ if (value < 0) return 0;
53807
+ return value / max * 100;
53808
+ };
53809
+ var VisualFormatCell = function VisualFormatCell(_ref) {
53810
+ var value = _ref.value,
53811
+ displayValue = _ref.displayValue,
53812
+ columnName = _ref.columnName,
53813
+ visualFormatColumns = _ref.visualFormatColumns,
53814
+ columnValues = _ref.columnValues,
53815
+ conditionalFormattingColor = _ref.conditionalFormattingColor;
53816
+ var shouldShowHorizontalBar = visualFormatColumns.includes(columnName);
53817
+ var numericValue = Number(value);
53818
+ var isNumeric = !isNaN(numericValue);
53819
+ if (!shouldShowHorizontalBar && !isNumeric) {
53820
+ return jsx("span", {
53821
+ children: displayValue || value
53822
+ });
53823
+ }
53824
+ if (isNumeric) {
53825
+ var actualMax = Math.max.apply(Math, columnValues);
53826
+ var percentage = calculatePercentage(numericValue, actualMax);
53827
+ var barColor = conditionalFormattingColor || (shouldShowHorizontalBar ? '#2196f3' : '#4caf50');
53828
+ return jsxs("div", {
53829
+ style: {
53830
+ display: 'flex',
53831
+ alignItems: 'center',
53832
+ gap: '0.5rem',
53833
+ padding: '2px'
53834
+ },
53835
+ children: [!!value && jsxs("svg", {
53836
+ width: "70%",
53837
+ height: "20",
53838
+ style: {
53839
+ flexShrink: 0
53840
+ },
53841
+ children: [jsx("rect", {
53842
+ x: 0,
53843
+ y: 2,
53844
+ width: "100%",
53845
+ height: "16",
53846
+ fill: "#e0e0e0",
53847
+ rx: 2
53848
+ }), jsx("rect", {
53849
+ x: 0,
53850
+ y: 2,
53851
+ width: Math.max(4, percentage / 100 * 100) + "%",
53852
+ height: "16",
53853
+ fill: barColor,
53854
+ rx: 2,
53855
+ className: /*#__PURE__*/css$1(process.env.NODE_ENV === "production" ? {
53856
+ name: "1sb6tbp",
53857
+ styles: "cursor:pointer;transition:width 0.3s ease"
53858
+ } : {
53859
+ name: "1qyjf6m-VisualFormatCell",
53860
+ styles: "cursor:pointer;transition:width 0.3s ease;label:VisualFormatCell;",
53861
+ map: "/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIlZpc3VhbEZvcm1hdENlbGwudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTZEeUIiLCJmaWxlIjoiVmlzdWFsRm9ybWF0Q2VsbC50c3giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgVGFibGVDb250ZW50IH0gZnJvbSAnc2hhcmVkLWxvZ2ljL3NyYy9EYXRhVGFibGUvdHlwZXMnO1xuaW1wb3J0IHsgY3NzIH0gZnJvbSAnQGVtb3Rpb24vY3NzJztcblxuaW50ZXJmYWNlIFZpc3VhbEZvcm1hdENlbGxQcm9wcyB7XG4gIHZhbHVlOiBUYWJsZUNvbnRlbnRbJ3ZhbHVlJ107XG4gIGRpc3BsYXlWYWx1ZTogVGFibGVDb250ZW50WydkaXNwbGF5VmFsdWUnXTtcbiAgY29sdW1uTmFtZTogc3RyaW5nO1xuICB2aXN1YWxGb3JtYXRDb2x1bW5zOiBzdHJpbmdbXTtcbiAgY29sdW1uVmFsdWVzOiBudW1iZXJbXTtcbiAgY29uZGl0aW9uYWxGb3JtYXR0aW5nQ29sb3I/OiBzdHJpbmc7XG59XG5cbmNvbnN0IGNhbGN1bGF0ZVBlcmNlbnRhZ2UgPSAodmFsdWU6IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIgPT4ge1xuICBpZiAobWF4ID09PSAwKSByZXR1cm4gMDtcbiAgaWYgKHZhbHVlIDwgMCkgcmV0dXJuIDA7XG4gIHJldHVybiAodmFsdWUgLyBtYXgpICogMTAwO1xufTtcblxuZXhwb3J0IGNvbnN0IFZpc3VhbEZvcm1hdENlbGw6IFJlYWN0LkZDPFZpc3VhbEZvcm1hdENlbGxQcm9wcz4gPSAoe1xuICB2YWx1ZSxcbiAgZGlzcGxheVZhbHVlLFxuICBjb2x1bW5OYW1lLFxuICB2aXN1YWxGb3JtYXRDb2x1bW5zLFxuICBjb2x1bW5WYWx1ZXMsXG4gIGNvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbG9yLFxufSkgPT4ge1xuICBjb25zdCBzaG91bGRTaG93SG9yaXpvbnRhbEJhciA9IHZpc3VhbEZvcm1hdENvbHVtbnMuaW5jbHVkZXMoY29sdW1uTmFtZSk7XG5cbiAgY29uc3QgbnVtZXJpY1ZhbHVlID0gTnVtYmVyKHZhbHVlKTtcbiAgY29uc3QgaXNOdW1lcmljID0gIWlzTmFOKG51bWVyaWNWYWx1ZSk7XG5cbiAgaWYgKCFzaG91bGRTaG93SG9yaXpvbnRhbEJhciAmJiAhaXNOdW1lcmljKSB7XG4gICAgcmV0dXJuIDxzcGFuPntkaXNwbGF5VmFsdWUgfHwgdmFsdWV9PC9zcGFuPjtcbiAgfVxuXG4gIGlmIChpc051bWVyaWMpIHtcbiAgICBjb25zdCBhY3R1YWxNYXggPSBNYXRoLm1heCguLi5jb2x1bW5WYWx1ZXMpO1xuICAgIGNvbnN0IHBlcmNlbnRhZ2UgPSBjYWxjdWxhdGVQZXJjZW50YWdlKG51bWVyaWNWYWx1ZSwgYWN0dWFsTWF4KTtcbiAgICBjb25zdCBiYXJDb2xvciA9IGNvbmRpdGlvbmFsRm9ybWF0dGluZ0NvbG9yIHx8IChzaG91bGRTaG93SG9yaXpvbnRhbEJhciA/ICcjMjE5NmYzJyA6ICcjNGNhZjUwJyk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdlxuICAgICAgICBzdHlsZT17e1xuICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICBhbGlnbkl0ZW1zOiAnY2VudGVyJyxcbiAgICAgICAgICBnYXA6ICcwLjVyZW0nLFxuICAgICAgICAgIHBhZGRpbmc6ICcycHgnLFxuICAgICAgICB9fVxuICAgICAgPlxuICAgICAgICB7ISF2YWx1ZSAmJiAoXG4gICAgICAgICAgPHN2ZyB3aWR0aD1cIjcwJVwiIGhlaWdodD1cIjIwXCIgc3R5bGU9e3sgZmxleFNocmluazogMCB9fT5cbiAgICAgICAgICAgIDxyZWN0IHg9ezB9IHk9ezJ9IHdpZHRoPVwiMTAwJVwiIGhlaWdodD1cIjE2XCIgZmlsbD1cIiNlMGUwZTBcIiByeD17Mn0gLz5cbiAgICAgICAgICAgIDxyZWN0XG4gICAgICAgICAgICAgIGtleT17J2JhclJlY3RLZXknfVxuICAgICAgICAgICAgICB4PXswfVxuICAgICAgICAgICAgICB5PXsyfVxuICAgICAgICAgICAgICB3aWR0aD17YCR7TWF0aC5tYXgoNCwgKHBlcmNlbnRhZ2UgLyAxMDApICogMTAwKX0lYH1cbiAgICAgICAgICAgICAgaGVpZ2h0PVwiMTZcIlxuICAgICAgICAgICAgICBmaWxsPXtiYXJDb2xvcn1cbiAgICAgICAgICAgICAgcng9ezJ9XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT17Y3NzKHtcbiAgICAgICAgICAgICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgICAgICAgICAgICB0cmFuc2l0aW9uOiAnd2lkdGggMC4zcyBlYXNlJyxcbiAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICApfVxuICAgICAgICA8c3BhblxuICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICBmb250U2l6ZTogJzAuODEyNXJlbScsXG4gICAgICAgICAgICBtaW5XaWR0aDogJ2ZpdC1jb250ZW50JyxcbiAgICAgICAgICAgIHdoaXRlU3BhY2U6ICdub3dyYXAnLFxuICAgICAgICAgICAgZm9udFdlaWdodDogc2hvdWxkU2hvd0hvcml6b250YWxCYXIgPyAnYm9sZCcgOiAnbm9ybWFsJyxcbiAgICAgICAgICAgIG1hcmdpbkxlZnQ6ICdhdXRvJyxcbiAgICAgICAgICAgIGZsZXhTaHJpbms6IDAsXG4gICAgICAgICAgfX1cbiAgICAgICAgPlxuICAgICAgICAgIHtkaXNwbGF5VmFsdWUgfHwgdmFsdWV9IHtzaG91bGRTaG93SG9yaXpvbnRhbEJhciA/ICfimIUnIDogJyd9XG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cblxuICByZXR1cm4gPHNwYW4+e2Rpc3BsYXlWYWx1ZSB8fCB2YWx1ZX08L3NwYW4+O1xufTtcbiJdfQ== */",
53862
+ toString: _EMOTION_STRINGIFIED_CSS_ERROR__$b
53863
+ })
53864
+ }, 'barRectKey')]
53865
+ }), jsxs("span", {
53866
+ style: {
53867
+ fontSize: '0.8125rem',
53868
+ minWidth: 'fit-content',
53869
+ whiteSpace: 'nowrap',
53870
+ fontWeight: shouldShowHorizontalBar ? 'bold' : 'normal',
53871
+ marginLeft: 'auto',
53872
+ flexShrink: 0
53873
+ },
53874
+ children: [displayValue || value, " ", shouldShowHorizontalBar ? '★' : '']
53875
+ })]
53876
+ });
53877
+ }
53878
+ return jsx("span", {
53879
+ children: displayValue || value
53880
+ });
53881
+ };
53882
+
53748
53883
  var DataTableTR = function DataTableTR(props) {
53749
53884
  var row = props.row,
53750
53885
  rowIndex = props.rowIndex,
@@ -53753,7 +53888,8 @@ var DataTableTR = function DataTableTR(props) {
53753
53888
  conditionalFormattingRules = props.conditionalFormattingRules,
53754
53889
  dataSet = props.dataSet,
53755
53890
  protectedFields = props.protectedFields,
53756
- drilldownAction = props.drilldownAction;
53891
+ drilldownAction = props.drilldownAction,
53892
+ rowSpan = props.rowSpan;
53757
53893
  var _useDashboardBehaviou = useDashboardBehaviourContext(),
53758
53894
  queryEngineConfig = _useDashboardBehaviou.queryEngineConfig,
53759
53895
  textOverride = _useDashboardBehaviou.textOverride;
@@ -53765,8 +53901,8 @@ var DataTableTR = function DataTableTR(props) {
53765
53901
  if (tableRepresentation == null) return null;
53766
53902
  var field = tableRepresentation.fields[cellIndex];
53767
53903
  var canShowArrow = props.drilldown.length > 0 && cellIndex === 0;
53768
- var width = buildColumnWidth(field.datumKey, props == null ? void 0 : props.sizing, props == null ? void 0 : props.defaultColumnWidth, props == null ? void 0 : props.alternativeColumnSizing);
53769
53904
  var conditionalStyled;
53905
+ var conditionalFormattingToApply;
53770
53906
  if (isDatumKey(field.datumKey)) {
53771
53907
  var datum = parse(field.datumKey);
53772
53908
  var dataPoint = {};
@@ -53778,18 +53914,61 @@ var DataTableTR = function DataTableTR(props) {
53778
53914
  datum.dimensionKeys.forEach(function (key, i) {
53779
53915
  dataPoint[key] = datum.dimensionValues[i];
53780
53916
  });
53781
- var conditionalFormattingToApply = applyConditionFormattingRules(dimension, conditionalFormattingRules, dataPoint, field.datumKey, dataSet);
53917
+ conditionalFormattingToApply = applyConditionFormattingRules(dimension, conditionalFormattingRules, dataPoint, field.datumKey, dataSet);
53782
53918
  if (conditionalFormattingToApply) {
53783
53919
  conditionalStyled = getFormattedByRule(conditionalFormattingToApply);
53784
53920
  }
53785
53921
  }
53786
53922
  var component = props.renderTableCell(rowIndex, cellIndex, cell.value, field.datumKey);
53787
- if (findDimension(dimension, field.id, {
53923
+ var shouldApplyVisualFormat = false;
53924
+ if (props.visualFormatColumns && field.dataType === 'number') {
53925
+ var groupedValues = props.visualFormatColumns.map(function (column) {
53926
+ return {
53927
+ originalValue: column,
53928
+ splitValues: column.split(',').map(function (val) {
53929
+ return val.trim();
53930
+ })
53931
+ };
53932
+ });
53933
+ shouldApplyVisualFormat = groupedValues.some(function (group) {
53934
+ return group.splitValues.every(function (value) {
53935
+ return field.datumKey && field.datumKey.includes(value) || field.id && field.id.includes(value);
53936
+ });
53937
+ });
53938
+ }
53939
+ var columnWidth = buildColumnWidth(field.datumKey, props == null ? void 0 : props.sizing, props == null ? void 0 : props.defaultColumnWidth, props == null ? void 0 : props.alternativeColumnSizing);
53940
+ var width = shouldApplyVisualFormat ? columnWidth * 1.5 : columnWidth;
53941
+ var columnValues = shouldApplyVisualFormat ? tableRepresentation.content.map(function (row) {
53942
+ var _row$cellIndex;
53943
+ return Number((_row$cellIndex = row[cellIndex]) == null ? void 0 : _row$cellIndex.value);
53944
+ }).filter(function (val) {
53945
+ return !isNaN(val);
53946
+ }) : [];
53947
+ var cellContent = component ? jsx(CustomCell, {
53948
+ component: component
53949
+ }) : cell.displayValue !== 'undefined' ? cell.displayValue : '';
53950
+ if (shouldApplyVisualFormat) {
53951
+ var conditionalFormattingColor;
53952
+ if (conditionalFormattingToApply && conditionalFormattingToApply.type === 'backgroundColor') {
53953
+ conditionalFormattingColor = conditionalFormattingToApply.value;
53954
+ }
53955
+ cellContent = jsx(VisualFormatCell, {
53956
+ value: cell.value,
53957
+ displayValue: cell.displayValue,
53958
+ columnName: field.datumKey || field.id,
53959
+ visualFormatColumns: props.visualFormatColumns || [],
53960
+ columnValues: columnValues,
53961
+ conditionalFormattingColor: conditionalFormattingColor
53962
+ });
53963
+ }
53964
+ var isDimensionColumn = findDimension(dimension, field.id, {
53788
53965
  supportedAggregates: queryEngineConfig.supportedAggregates,
53789
53966
  supportedTimeTruncFunctions: queryEngineConfig.supportedTimeTruncFunctions,
53790
53967
  supportedTransformationFunctions: undefined
53791
- })) {
53968
+ });
53969
+ if (isDimensionColumn) {
53792
53970
  var _props$level;
53971
+ if (rowSpan[cellIndex] === undefined) return null;
53793
53972
  return jsx(Table.TH, {
53794
53973
  first: cellIndex === 0,
53795
53974
  last: cellIndex + 1 === row.length,
@@ -53807,9 +53986,11 @@ var DataTableTR = function DataTableTR(props) {
53807
53986
  label: "" + cell.displayValue
53808
53987
  } : undefined,
53809
53988
  level: (_props$level = props == null ? void 0 : props.level) != null ? _props$level : undefined,
53810
- children: component ? jsx(CustomCell, {
53811
- component: component
53812
- }) : cell.displayValue !== 'undefined' ? cell.displayValue : ''
53989
+ rowSpan: rowSpan[cellIndex],
53990
+ cellStyles: {
53991
+ borderBottom: '1px solid #c3c6ca'
53992
+ },
53993
+ children: cellContent
53813
53994
  }, "table_row_" + rowIndex + "_cell_" + cellIndex);
53814
53995
  }
53815
53996
  return jsx(Table.TD, {
@@ -53821,7 +54002,7 @@ var DataTableTR = function DataTableTR(props) {
53821
54002
  align: field.dataType == 'number' ? 'alignRight' : 'alignLeft',
53822
54003
  clickEnabled: hasProtectedFields(protectedFields),
53823
54004
  simple: generatingPDF,
53824
- style: _extends({}, props == null ? void 0 : props.cellStyles, conditionalStyled ? conditionalStyled : {}, {
54005
+ style: _extends({}, props == null ? void 0 : props.cellStyles, conditionalStyled && !shouldApplyVisualFormat ? conditionalStyled : {}, {
53825
54006
  width: width,
53826
54007
  maxWidth: width,
53827
54008
  minWidth: width
@@ -53830,10 +54011,8 @@ var DataTableTR = function DataTableTR(props) {
53830
54011
  return props == null ? void 0 : props.setShowMore(cell.displayValue);
53831
54012
  },
53832
54013
  showMoreLabel: textOverride('table_settings.show_more', 'Show more'),
53833
- customRender: !!component,
53834
- children: component ? jsx(CustomCell, {
53835
- component: component
53836
- }) : cell.displayValue !== undefined ? cell.displayValue : ''
54014
+ customRender: !!component || shouldApplyVisualFormat,
54015
+ children: cellContent
53837
54016
  }, "table_row_" + rowIndex + "_cell_" + cellIndex + "_" + JSON.stringify(cell.displayValue) + "}");
53838
54017
  })
53839
54018
  });
@@ -53907,6 +54086,7 @@ var DataTableRow = function DataTableRow(props) {
53907
54086
  even: rowIndex % 2 === 0,
53908
54087
  level: drilldown ? 1 : undefined,
53909
54088
  expanded: drilldown ? expanded : undefined,
54089
+ hover: false,
53910
54090
  children: jsx(DataTableTR, _extends({}, props, {
53911
54091
  drilldownAction: hasDrilldown ? {
53912
54092
  onExpanded: handleOnExpand,
@@ -54241,6 +54421,115 @@ var buildConditionalFormattingBoundaries = function buildConditionalFormattingBo
54241
54421
  return conditionalFormattingBoundaries;
54242
54422
  };
54243
54423
 
54424
+ var KPISummaryHeader = function KPISummaryHeader(_ref) {
54425
+ var tableRepresentation = _ref.tableRepresentation,
54426
+ KPIResults = _ref.KPIResults,
54427
+ dimensionXFields = _ref.dimensionXFields;
54428
+ var _useDashboardBehaviou = useDashboardBehaviourContext(),
54429
+ textOverride = _useDashboardBehaviou.textOverride;
54430
+ var _useDashboardContext = useDashboardContext(),
54431
+ generatingPDF = _useDashboardContext.generatingPDF;
54432
+ var cellStyles = {
54433
+ backgroundColor: '#f8f9fa',
54434
+ fontWeight: 'bold',
54435
+ padding: '8px',
54436
+ fontSize: '0.8125rem',
54437
+ borderBottom: '1px solid #c3c6ca',
54438
+ borderRight: '1px solid #c3c6ca'
54439
+ };
54440
+ var summaryDataFields = tableRepresentation.fields.slice(dimensionXFields.length);
54441
+ var occurrencesMap = new Map();
54442
+ var KPISummaryValues = summaryDataFields.map(function (field) {
54443
+ var datumKey = parse(field.datumKey);
54444
+ var value = KPIResults == null ? void 0 : KPIResults.content.find(function (result) {
54445
+ return areAllStringsInArray(result.filter(function (item) {
54446
+ return typeof item !== 'number';
54447
+ }), datumKey.dimensionValues);
54448
+ });
54449
+ if (!value) return undefined;
54450
+ var occurrenceKey = value.filter(function (item) {
54451
+ return typeof item !== 'number';
54452
+ }).join('|');
54453
+ var offSet = (value.filter(function (item) {
54454
+ return typeof item !== 'number';
54455
+ }).length || 1) - 1;
54456
+ if (occurrencesMap.has(occurrenceKey)) {
54457
+ var occurrences = occurrencesMap.get(occurrenceKey) || 0;
54458
+ occurrencesMap.set(occurrenceKey, occurrences + 1);
54459
+ return value[offSet + occurrences + 1];
54460
+ }
54461
+ occurrencesMap.set(occurrenceKey, 1);
54462
+ return value[offSet + 1];
54463
+ });
54464
+ return jsxs(Table.HeadTR, {
54465
+ children: [jsx(Table.TH, {
54466
+ cellStyles: cellStyles,
54467
+ simple: generatingPDF,
54468
+ colSpan: dimensionXFields.length,
54469
+ children: textOverride('data_table.kpi_summary', 'KPI Summary')
54470
+ }, "kpi-label"), summaryDataFields.map(function (field, fieldIndex) {
54471
+ if (field.hidden) return null;
54472
+ var KPIValue = KPISummaryValues ? KPISummaryValues[fieldIndex] : 0;
54473
+ var isCustomMetric = field["function"] === 'none';
54474
+ return jsx(Table.TH, {
54475
+ cellStyles: cellStyles,
54476
+ simple: generatingPDF,
54477
+ children: jsxs("div", {
54478
+ style: {
54479
+ display: 'flex',
54480
+ alignItems: 'center',
54481
+ fontSize: '0.8125rem',
54482
+ gap: '3px'
54483
+ },
54484
+ children: [!isCustomMetric && jsxs(Fragment$1, {
54485
+ children: [jsx("div", {
54486
+ style: {
54487
+ fontWeight: 'bold'
54488
+ },
54489
+ children: textOverride("aggregate." + field["function"], field["function"])
54490
+ }), jsx("span", {
54491
+ children: "\u2022"
54492
+ })]
54493
+ }), jsx("div", {
54494
+ style: {
54495
+ textTransform: 'uppercase'
54496
+ },
54497
+ children: formatKPIValue(KPIValue, field.dataType)
54498
+ })]
54499
+ })
54500
+ }, "kpi-" + fieldIndex);
54501
+ })]
54502
+ });
54503
+ };
54504
+ var formatKPIValue = function formatKPIValue(value, dataType) {
54505
+ if (value === undefined || isNaN(value)) {
54506
+ return '-';
54507
+ }
54508
+ var Billion = 1000000000;
54509
+ var Million = 1000000;
54510
+ var Thousand = 1000;
54511
+ if (dataType === 'number') {
54512
+ if (Math.abs(value) >= Billion) {
54513
+ return (value / Billion).toFixed(2) + 'B';
54514
+ } else if (Math.abs(value) >= Million) {
54515
+ return (value / Million).toFixed(2) + 'M';
54516
+ } else if (Math.abs(value) >= 1000) {
54517
+ return (value / Thousand).toFixed(2) + 'K';
54518
+ } else {
54519
+ return value.toLocaleString(undefined, {
54520
+ minimumFractionDigits: 0,
54521
+ maximumFractionDigits: 2
54522
+ });
54523
+ }
54524
+ }
54525
+ return value.toString();
54526
+ };
54527
+ function areAllStringsInArray(stringsToCheck, targetArray) {
54528
+ return stringsToCheck.every(function (str) {
54529
+ return targetArray.includes(str);
54530
+ });
54531
+ }
54532
+
54244
54533
  var DataTableView = function DataTableView(props) {
54245
54534
  var _props$library, _props$viewId, _props$result, _props$result2, _props$result3, _props$result4, _props$library2;
54246
54535
  var headerProps = {
@@ -54257,6 +54546,11 @@ var DataTableView = function DataTableView(props) {
54257
54546
  setPartialAttributes: props.setPartialAttributes
54258
54547
  };
54259
54548
  var sizing = props.sizing;
54549
+ var _ref = props.pivotTablePagination || {},
54550
+ _ref$paginationStartI = _ref.paginationStartIndex,
54551
+ paginationStartIndex = _ref$paginationStartI === void 0 ? 0 : _ref$paginationStartI,
54552
+ _ref$paginationEndInd = _ref.paginationEndIndex,
54553
+ paginationEndIndex = _ref$paginationEndInd === void 0 ? 0 : _ref$paginationEndInd;
54260
54554
  var _useDashboardBehaviou = useDashboardBehaviourContext(),
54261
54555
  labelFormat = _useDashboardBehaviou.labelFormat,
54262
54556
  textOverride = _useDashboardBehaviou.textOverride,
@@ -54267,8 +54561,6 @@ var DataTableView = function DataTableView(props) {
54267
54561
  tableRef = _useWidth[0],
54268
54562
  tableWidth = _useWidth[1];
54269
54563
  var defaultColumnWidth = buildDefaultColumnWidth(tableWidth, (((_props$result = props.result) == null ? void 0 : _props$result.fields) || []).length);
54270
-
54271
- // const alternativeColumnSizing = useResizingColumn();
54272
54564
  var alternativeColumnSizing = {};
54273
54565
  var handleResizedColumn = function handleResizedColumn(options) {
54274
54566
  var _extends2;
@@ -54309,25 +54601,26 @@ var DataTableView = function DataTableView(props) {
54309
54601
  valueAlias: valueAlias
54310
54602
  });
54311
54603
  }, [props.measure, props.xMeasure, props.yMeasure, props.result, props.dateTimeFormat, props.numberFormat, props.prefixes, props.dateTimeFormatOptions, props.numberFormatOptions, props.supportedAggregates, props.supportedTimeTruncFunctions, props == null ? void 0 : props.dimension]);
54312
- var hidePaginations = ((_props$result2 = props.result) != null && _props$result2.content ? (_props$result3 = props.result) == null ? void 0 : _props$result3.content.length : 0) > (tableRepresentation ? tableRepresentation.content.length : 0);
54604
+ var hidePaginations = props.pivotTablePagination ? props.pivotTablePagination.totalRows <= props.pivotTablePagination.pageSize : ((_props$result2 = props.result) != null && _props$result2.content ? (_props$result3 = props.result) == null ? void 0 : _props$result3.content.length : 0) > (tableRepresentation ? tableRepresentation.content.length : 0);
54605
+ var isPivotTable = props.pivotTablePagination !== undefined;
54313
54606
  var TableFooter = useMemo(function () {
54314
- var _props$offset, _props$offset2, _props$limit;
54315
- return jsx(Fragment$1, {
54316
- children: props.result && !hidePaginations && jsx(Pagination, {
54317
- offset: props == null ? void 0 : props.offset,
54318
- limit: props == null ? void 0 : props.limit,
54319
- onNext: props == null ? void 0 : props.onNext,
54320
- onPrevious: props == null ? void 0 : props.onPrevious,
54321
- previousDisabled: !hasPrevious((_props$offset = props.offset) != null ? _props$offset : 0),
54322
- nextDisabled: !hasNext({
54323
- offset: (_props$offset2 = props.offset) != null ? _props$offset2 : 0,
54324
- limit: (_props$limit = props.limit) != null ? _props$limit : 0,
54325
- total: tableRepresentation ? tableRepresentation.content.length : 0
54326
- }),
54327
- textOverride: textOverride
54328
- })
54607
+ var _props$offset, _props$limit, _props$offset2;
54608
+ if (!props.result || hidePaginations || tableRepresentation === null) return null;
54609
+ var isNextDisabled = isPivotTable ? paginationEndIndex >= tableRepresentation.content.length : !hasNext({
54610
+ offset: (_props$offset = props.offset) != null ? _props$offset : 0,
54611
+ limit: (_props$limit = props.limit) != null ? _props$limit : 0,
54612
+ total: tableRepresentation ? tableRepresentation.content.length : 0
54613
+ });
54614
+ return jsx(Pagination, {
54615
+ offset: props == null ? void 0 : props.offset,
54616
+ limit: props == null ? void 0 : props.limit,
54617
+ onNext: props == null ? void 0 : props.onNext,
54618
+ onPrevious: props == null ? void 0 : props.onPrevious,
54619
+ previousDisabled: !hasPrevious((_props$offset2 = props.offset) != null ? _props$offset2 : 0),
54620
+ nextDisabled: isNextDisabled,
54621
+ textOverride: textOverride
54329
54622
  });
54330
- }, [props.offset, props.limit, props.onPrevious, props.onNext, (_props$result4 = props.result) == null ? void 0 : _props$result4.content.length, hidePaginations]);
54623
+ }, [props.offset, props.limit, props.onPrevious, props.onNext, (_props$result4 = props.result) == null ? void 0 : _props$result4.content.length, hidePaginations, tableRepresentation, isPivotTable, paginationEndIndex, textOverride]);
54331
54624
  var lastPivotColumnId = useMemo(function () {
54332
54625
  if (!tableRepresentation) return null;
54333
54626
  return getLastPivotColumn(tableRepresentation, props.dimension, props.supportedAggregates, props.supportedTimeTruncFunctions);
@@ -54361,6 +54654,13 @@ var DataTableView = function DataTableView(props) {
54361
54654
  var handleTableRender = function handleTableRender(rowIndex, cellIndex, value, fieldV2, additionalAttributes) {
54362
54655
  return buildTableCell(props, cellIndex, rowIndex, value, fieldV2, additionalAttributes);
54363
54656
  };
54657
+ var dimensionXFields = props.dimension.filter(function (dim) {
54658
+ return dim.pivot === 'x';
54659
+ }).map(function (dim) {
54660
+ return dim.field;
54661
+ }) || [];
54662
+ var tableBodyData = isPivotTable ? tableRepresentation.content.slice(paginationStartIndex, paginationEndIndex) : tableRepresentation.content;
54663
+ var spanRowMatrix = createSpanRowMatrix(tableBodyData);
54364
54664
  return jsxs(ViewWrapper, {
54365
54665
  queriesAreChanging: props.queriesAreChanging,
54366
54666
  id: props.id,
@@ -54387,6 +54687,14 @@ var DataTableView = function DataTableView(props) {
54387
54687
  children: groupingHeading.content
54388
54688
  }, groupingHeading + "_" + headerIndex);
54389
54689
  })
54690
+ }), props.summarizeKPIs && jsx(KPISummaryHeader, {
54691
+ tableRepresentation: tableRepresentation,
54692
+ numberFormat: props.numberFormat,
54693
+ numberFormatOptions: props.numberFormatOptions,
54694
+ supportedAggregates: props.supportedAggregates,
54695
+ supportedTimeTruncFunctions: props.supportedTimeTruncFunctions,
54696
+ KPIResults: props.KPIResults,
54697
+ dimensionXFields: dimensionXFields
54390
54698
  }), jsx(Table.HeadTR, {
54391
54699
  children: tableRepresentation.fields.map(function (field, headerIndex) {
54392
54700
  if (field.hidden) return null;
@@ -54433,7 +54741,7 @@ var DataTableView = function DataTableView(props) {
54433
54741
  })
54434
54742
  })]
54435
54743
  }), jsx(Table.Body, {
54436
- children: tableRepresentation.content.map(function (row, rowIndex) {
54744
+ children: tableBodyData.map(function (row, rowIndex) {
54437
54745
  return jsx(DataTableRow, {
54438
54746
  protectedFields: props == null ? void 0 : props.protectedFields,
54439
54747
  dataSet: props == null ? void 0 : props.dataSet,
@@ -54448,10 +54756,12 @@ var DataTableView = function DataTableView(props) {
54448
54756
  handleOnChange: handleOnChange,
54449
54757
  handleTableCellRender: handleTableRender,
54450
54758
  cellStyles: cellStyles,
54759
+ rowSpan: spanRowMatrix[rowIndex],
54451
54760
  setShowMore: setShowMore,
54452
54761
  drilldown: props.tableDrilldown,
54453
54762
  drilldownInputProps: props == null ? void 0 : props.drilldownInputProps,
54454
- queriesAreChanging: props.queriesAreChanging
54763
+ queriesAreChanging: props.queriesAreChanging,
54764
+ visualFormatColumns: props.visualFormatColumns
54455
54765
  }, rowIndex);
54456
54766
  })
54457
54767
  })]
@@ -54470,33 +54780,148 @@ var DataTableView$1 = (function (props) {
54470
54780
  return jsx(DataTableView, _extends({}, props));
54471
54781
  });
54472
54782
 
54783
+ /**
54784
+ * Creates a matrix that tracks row span counts for each row in a table representation.
54785
+ * Groups consecutive rows with identical pivot groups and calculates how many rows each group spans.
54786
+ *
54787
+ * @param tableRepresentationContent - The 2D array representing table content
54788
+ * @returns A matrix where each cell contains the row span count for that position, or undefined if not a span start
54789
+ */
54790
+ function createSpanRowMatrix(tableRepresentationContent) {
54791
+ var spanRowMatrix = [];
54792
+ var numRows = tableRepresentationContent.length;
54793
+ if (numRows === 0) return spanRowMatrix;
54794
+ var numCols = tableRepresentationContent[0].length;
54795
+ for (var i = 0; i < numRows; i++) {
54796
+ spanRowMatrix[i] = new Array(numCols).fill(undefined);
54797
+ }
54798
+ for (var col = 0; col < numCols; col++) {
54799
+ var pivotRow = 0;
54800
+ var spanCount = 0;
54801
+ var pivotGroup = createPivotGroup(tableRepresentationContent[pivotRow], col);
54802
+ for (var row = 0; row < numRows; row++) {
54803
+ if (createPivotGroup(tableRepresentationContent[row], col) === pivotGroup) {
54804
+ spanCount++;
54805
+ } else {
54806
+ spanRowMatrix[pivotRow][col] = spanCount;
54807
+ spanCount = 1;
54808
+ pivotRow = row;
54809
+ pivotGroup = createPivotGroup(tableRepresentationContent[pivotRow], col);
54810
+ }
54811
+ }
54812
+ spanRowMatrix[pivotRow][col] = spanCount;
54813
+ }
54814
+ return spanRowMatrix;
54815
+ }
54816
+ function createPivotGroup(row, col) {
54817
+ var result = '';
54818
+ for (var colIndex = 0; colIndex <= col; colIndex++) {
54819
+ var _row$colIndex;
54820
+ result += ((_row$colIndex = row[colIndex]) == null ? void 0 : _row$colIndex.displayValue) + ',';
54821
+ }
54822
+ return result;
54823
+ }
54824
+
54473
54825
  var DataTable$2 = function DataTable(props) {
54826
+ var _attributes$timeDimen, _attributes$timeDimen2;
54474
54827
  var _props$component = props.component,
54475
54828
  attributes = _props$component.attributes,
54476
54829
  localFilters = _props$component.localFilters;
54477
- var _useQueryEffect = useQueryEffect(attributes, props.runQueriesCallback, {
54830
+ var isPivotTable = attributes.dimension.some(function (dim) {
54831
+ return dim.pivot === 'y';
54832
+ });
54833
+ var attributesWithSortedDimension = _extends({}, attributes, {
54834
+ dimension: [].concat(attributes.dimension.filter(function (dim) {
54835
+ return dim.pivot !== 'y';
54836
+ }), attributes.dimension.filter(function (dim) {
54837
+ return dim.pivot === 'y';
54838
+ }))
54839
+ });
54840
+ var queryAttributes = isPivotTable ? _extends({}, attributesWithSortedDimension, {
54841
+ limit: 30000,
54842
+ offset: undefined
54843
+ }) : attributes;
54844
+ var kpiSummaryQuery = _extends({}, attributes, {
54845
+ limit: undefined,
54846
+ offset: undefined,
54847
+ dimension: attributes.dimension.filter(function (dim) {
54848
+ return dim.pivot === 'y';
54849
+ })
54850
+ });
54851
+ var queries = [_extends({}, queryAttributes, {
54852
+ timeDimension: (_attributes$timeDimen = attributes.timeDimension) != null ? _attributes$timeDimen : null
54853
+ }), _extends({}, kpiSummaryQuery, {
54854
+ timeDimension: (_attributes$timeDimen2 = attributes.timeDimension) != null ? _attributes$timeDimen2 : null
54855
+ })];
54856
+ var _useQueryEffect = useQueryEffect(queries, props.runQueriesCallback, {
54478
54857
  localFilters: localFilters,
54479
54858
  globalFilters: props.globalFilters
54480
54859
  }, props.dataSet, undefined, props.dashboardBehaviour.variables),
54481
- queriesAreChanging = _useQueryEffect.queriesAreChanging,
54482
- results = _useQueryEffect.results;
54860
+ results = _useQueryEffect.results,
54861
+ queriesAreChanging = _useQueryEffect.queriesAreChanging;
54862
+ var KPIResults = results[1];
54863
+ var _useState = useState(0),
54864
+ page = _useState[0],
54865
+ setPage = _useState[1];
54866
+ useEffect(function () {
54867
+ setPage(0);
54868
+ }, [attributes.dimension, attributes.measure, localFilters, props.globalFilters]);
54869
+ var pageSize = attributes.limit || 10;
54870
+ var _useMemo = useMemo(function () {
54871
+ if (!isPivotTable || !results[0]) {
54872
+ return {
54873
+ paginatedResult: results[0],
54874
+ totalPivotRows: 0,
54875
+ paginationStartIndex: 0,
54876
+ paginationEndIndex: 0
54877
+ };
54878
+ }
54879
+ var fullResult = results[0];
54880
+ var totalRows = fullResult.content.length;
54881
+ var startGroupIndex = page * pageSize;
54882
+ var endGroupIndex = Math.min(startGroupIndex + pageSize, totalRows);
54883
+ return {
54884
+ paginatedResult: _extends({}, fullResult, {
54885
+ content: fullResult.content.slice(startGroupIndex, endGroupIndex)
54886
+ }),
54887
+ totalPivotRows: totalRows,
54888
+ paginationStartIndex: startGroupIndex,
54889
+ paginationEndIndex: endGroupIndex
54890
+ };
54891
+ }, [isPivotTable, results, page, pageSize]),
54892
+ paginationStartIndex = _useMemo.paginationStartIndex,
54893
+ paginationEndIndex = _useMemo.paginationEndIndex,
54894
+ totalPivotRows = _useMemo.totalPivotRows;
54895
+ var totalPages = isPivotTable ? Math.ceil(totalPivotRows / pageSize) : 1;
54483
54896
  var onNext = function onNext() {
54484
- var _attributes$limit, _attributes$offset, _results$0$content$le, _results$;
54485
- if (!hasNext({
54486
- limit: (_attributes$limit = attributes.limit) != null ? _attributes$limit : 0,
54487
- offset: (_attributes$offset = attributes.offset) != null ? _attributes$offset : 0,
54488
- total: (_results$0$content$le = (_results$ = results[0]) == null ? void 0 : _results$.content.length) != null ? _results$0$content$le : 0
54489
- })) return;
54490
- props.updateComponentAttributes(_extends({}, attributes, {
54491
- offset: nextOffset(attributes.offset, attributes.limit)
54492
- }));
54897
+ if (isPivotTable) {
54898
+ if (page < totalPages - 1) {
54899
+ setPage(page + 1);
54900
+ }
54901
+ } else {
54902
+ var _attributes$limit, _attributes$offset, _results$0$content$le, _results$;
54903
+ if (!hasNext({
54904
+ limit: (_attributes$limit = attributes.limit) != null ? _attributes$limit : 0,
54905
+ offset: (_attributes$offset = attributes.offset) != null ? _attributes$offset : 0,
54906
+ total: (_results$0$content$le = (_results$ = results[0]) == null ? void 0 : _results$.content.length) != null ? _results$0$content$le : 0
54907
+ })) return;
54908
+ props.updateComponentAttributes(_extends({}, attributes, {
54909
+ offset: nextOffset(attributes.offset, attributes.limit)
54910
+ }));
54911
+ }
54493
54912
  };
54494
54913
  var onPrevious = function onPrevious() {
54495
- var _attributes$offset2;
54496
- if (!hasPrevious((_attributes$offset2 = attributes.offset) != null ? _attributes$offset2 : 0)) return;
54497
- props.updateComponentAttributes(_extends({}, attributes, {
54498
- offset: previousOffset(attributes.offset, attributes.limit)
54499
- }));
54914
+ if (isPivotTable) {
54915
+ if (page > 0) {
54916
+ setPage(page - 1);
54917
+ }
54918
+ } else {
54919
+ var _attributes$offset2;
54920
+ if (!hasPrevious((_attributes$offset2 = attributes.offset) != null ? _attributes$offset2 : 0)) return;
54921
+ props.updateComponentAttributes(_extends({}, attributes, {
54922
+ offset: previousOffset(attributes.offset, attributes.limit)
54923
+ }));
54924
+ }
54500
54925
  };
54501
54926
  var onOrder = function onOrder(_ref) {
54502
54927
  var fieldId = _ref.fieldId,
@@ -54506,15 +54931,11 @@ var DataTable$2 = function DataTable(props) {
54506
54931
  var currentFieldIndex = currentOrder.findIndex(function (o) {
54507
54932
  return o.field === fieldId && o["function"] == func;
54508
54933
  });
54509
-
54510
- // Unset the direction -> remove it from the order
54511
54934
  if (direction === null) {
54512
54935
  currentOrder.splice(currentFieldIndex, 1);
54513
54936
  } else if (currentFieldIndex > -1) {
54514
- // if the current field already has an ordering rule -> update the direction
54515
54937
  currentOrder[currentFieldIndex].direction = direction;
54516
54938
  } else {
54517
- // add a new order
54518
54939
  currentOrder.push({
54519
54940
  field: fieldId,
54520
54941
  direction: direction,
@@ -54534,7 +54955,7 @@ var DataTable$2 = function DataTable(props) {
54534
54955
  var onSetNumberFormat = function onSetNumberFormat(fieldId, numberFormatId) {
54535
54956
  var newNumberformats = _extends({}, attributes.numberFormat);
54536
54957
  if (!numberFormatId) {
54537
- delete newNumberformats[fieldId];
54958
+ newNumberformats[fieldId] = 'none';
54538
54959
  } else {
54539
54960
  newNumberformats[fieldId] = numberFormatId;
54540
54961
  }
@@ -54548,13 +54969,9 @@ var DataTable$2 = function DataTable(props) {
54548
54969
  }));
54549
54970
  };
54550
54971
  var result = results[0];
54551
-
54552
- // If the result doesn't match the query, then wait by returning null
54553
54972
  if (result && result.fields.length != attributes.dimension.length + attributes.measure.length) {
54554
54973
  return null;
54555
54974
  }
54556
-
54557
- // Only show the table when the right result fields have been returned...
54558
54975
  var requiredMeasureIds = attributes.measure.map(function (m) {
54559
54976
  return id$2(m);
54560
54977
  });
@@ -54568,7 +54985,11 @@ var DataTable$2 = function DataTable(props) {
54568
54985
  return requiredDimensions.includes(field.id) || requiredMeasureIds.includes(field.id);
54569
54986
  });
54570
54987
  if (!show) return null;
54571
- return jsx(DataTableView$1, _extends({}, attributes, {
54988
+ var effectiveAttributes = isPivotTable ? _extends({}, attributes, {
54989
+ offset: page * pageSize,
54990
+ limit: pageSize
54991
+ }) : attributes;
54992
+ return jsx(DataTableView$1, _extends({}, effectiveAttributes, {
54572
54993
  dataSet: props.dataSet,
54573
54994
  onSetExportName: onSetExportName,
54574
54995
  id: props.id,
@@ -54596,7 +55017,14 @@ var DataTable$2 = function DataTable(props) {
54596
55017
  runQueriesCallback: props.runQueriesCallback,
54597
55018
  globalFilters: props.globalFilters
54598
55019
  },
54599
- defaultFormats: props.dashboardBehaviour.defaultFormats
55020
+ defaultFormats: props.dashboardBehaviour.defaultFormats,
55021
+ KPIResults: KPIResults,
55022
+ pivotTablePagination: isPivotTable ? {
55023
+ totalRows: totalPivotRows,
55024
+ pageSize: pageSize,
55025
+ paginationStartIndex: paginationStartIndex,
55026
+ paginationEndIndex: paginationEndIndex
55027
+ } : undefined
54600
55028
  }));
54601
55029
  };
54602
55030
 
@@ -66567,6 +66995,137 @@ var WaterfallColorsSection = function WaterfallColorsSection(props) {
66567
66995
  });
66568
66996
  };
66569
66997
 
66998
+ var VisualFormatSection = function VisualFormatSection(props) {
66999
+ var _props$attributes$dim;
67000
+ var _useDashboardBehaviou = useDashboardBehaviourContext(),
67001
+ textOverride = _useDashboardBehaviou.textOverride,
67002
+ mode = _useDashboardBehaviou.mode;
67003
+ var previousYDimensionsRef = useRef([]);
67004
+ var editor = useEditor();
67005
+ var dashboardBehaviour = useDashboardBehaviourContext();
67006
+ var kpiSummaryQuery = _extends({}, props.attributes, {
67007
+ dimension: ((_props$attributes$dim = props.attributes.dimension) == null ? void 0 : _props$attributes$dim.filter(function (dim) {
67008
+ return dim.pivot === 'y';
67009
+ })) || [],
67010
+ measure: [],
67011
+ limit: undefined,
67012
+ offset: undefined
67013
+ });
67014
+ var _useQueryEffect = useQueryEffect(kpiSummaryQuery, (editor == null ? void 0 : editor.runQueriesCallback) || function () {
67015
+ return Promise.resolve([]);
67016
+ }, {
67017
+ localFilters: (editor == null ? void 0 : editor.component.localFilters) || [],
67018
+ globalFilters: []
67019
+ }, props.dataSet, undefined, dashboardBehaviour.variables),
67020
+ results = _useQueryEffect.results;
67021
+ var yDimensionsChanged = function yDimensionsChanged() {
67022
+ var _props$attributes$dim2;
67023
+ var currentYDimensions = ((_props$attributes$dim2 = props.attributes.dimension) == null ? void 0 : _props$attributes$dim2.filter(function (dim) {
67024
+ return dim.pivot === 'y';
67025
+ })) || [];
67026
+ var deepEqual = function deepEqual(a, b) {
67027
+ if (a.length !== b.length) return false;
67028
+ return a.every(function (item, index) {
67029
+ var _b$index, _b$index2, _b$index3;
67030
+ return item.field === ((_b$index = b[index]) == null ? void 0 : _b$index.field) && item["function"] === ((_b$index2 = b[index]) == null ? void 0 : _b$index2["function"]) && item.pivot === ((_b$index3 = b[index]) == null ? void 0 : _b$index3.pivot);
67031
+ });
67032
+ };
67033
+ var hasChanged = deepEqual(currentYDimensions, previousYDimensionsRef.current);
67034
+ if (hasChanged) previousYDimensionsRef.current = currentYDimensions;
67035
+ return hasChanged;
67036
+ };
67037
+ useEffect(function () {
67038
+ var _props$attributes$vis;
67039
+ if (yDimensionsChanged() && (((_props$attributes$vis = props.attributes.visualFormatColumns) == null ? void 0 : _props$attributes$vis.length) || 0) > 0) {
67040
+ props.setAttributes({
67041
+ visualFormatColumns: []
67042
+ });
67043
+ }
67044
+ }, [props.attributes.dimension]);
67045
+ var handleColumnAdd = function handleColumnAdd(field) {
67046
+ var currentColumns = props.attributes.visualFormatColumns || [];
67047
+ if (field && !currentColumns.includes(field)) {
67048
+ var newColumns = [].concat(currentColumns, [field]);
67049
+ props.setAttributes({
67050
+ visualFormatColumns: newColumns
67051
+ });
67052
+ } else {
67053
+ console.warn('Field is invalid or already exists:', field);
67054
+ }
67055
+ };
67056
+ var handleColumnRemove = function handleColumnRemove(itemIndex) {
67057
+ var currentColumns = props.attributes.visualFormatColumns || [];
67058
+ var newColumns = currentColumns.filter(function (_, index) {
67059
+ return index !== itemIndex;
67060
+ }).filter(function (item) {
67061
+ return item !== undefined && item !== null;
67062
+ });
67063
+ props.setAttributes({
67064
+ visualFormatColumns: newColumns
67065
+ });
67066
+ };
67067
+ var firstResult = results == null ? void 0 : results[0];
67068
+ var uniqueFirstValues = (firstResult == null ? void 0 : firstResult.content) || [];
67069
+ var availableFields = uniqueFirstValues.map(function (value) {
67070
+ return {
67071
+ title: value.join(', '),
67072
+ icon: 'string',
67073
+ value: value.join(', ')
67074
+ };
67075
+ });
67076
+ var selectedItems = (props.attributes.visualFormatColumns || []).map(function (columnId) {
67077
+ var field = availableFields.find(function (f) {
67078
+ return f.title === columnId;
67079
+ });
67080
+ return field || null;
67081
+ }).filter(function (item) {
67082
+ return item !== null;
67083
+ });
67084
+ return jsxs(Section, {
67085
+ title: props.section.title,
67086
+ children: [jsx(ListView, {
67087
+ mode: mode,
67088
+ onDeleteItem: handleColumnRemove,
67089
+ items: selectedItems,
67090
+ newItem: {
67091
+ callToAction: textOverride('visual_format.add_column', 'Add column'),
67092
+ onNew: handleColumnAdd,
67093
+ initValues: availableFields,
67094
+ hide: availableFields.length === 0
67095
+ },
67096
+ purpose: "visualFormat",
67097
+ testId: "visual-format-columns"
67098
+ }), availableFields.length === 0 && jsx("p", {
67099
+ style: {
67100
+ color: '#9ca3af',
67101
+ fontSize: '0.875rem',
67102
+ fontStyle: 'italic',
67103
+ margin: '1rem 0'
67104
+ },
67105
+ children: textOverride('visual_format.no_columns', 'No numeric columns available')
67106
+ })]
67107
+ });
67108
+ };
67109
+
67110
+ var KPISummarisationSection = function KPISummarisationSection(props) {
67111
+ var _useDashboardBehaviou = useDashboardBehaviourContext(),
67112
+ textOverride = _useDashboardBehaviou.textOverride;
67113
+ return jsx(Section, {
67114
+ title: props.section.title,
67115
+ children: jsx(Section.Grid, {
67116
+ children: jsx(Checkbox, {
67117
+ label: textOverride('kpi_summarisation.enable', 'Summarize KPIs'),
67118
+ currentValue: props.attributes.summarizeKPIs || false,
67119
+ onChange: function onChange(checked) {
67120
+ props.setAttributes({
67121
+ summarizeKPIs: checked
67122
+ });
67123
+ }
67124
+ })
67125
+ })
67126
+ });
67127
+ };
67128
+
66570
67129
  var QuadrantSection = function QuadrantSection(props) {
66571
67130
  var _props$attributes$qua, _props$attributes$qua2, _props$section;
66572
67131
  var _useDashboardBehaviou = useDashboardBehaviourContext(),
@@ -66704,6 +67263,10 @@ var FormatPanelFromConfig = function FormatPanelFromConfig(props) {
66704
67263
  section: section
66705
67264
  })), section.type === 'richText' && jsx(RichTextFormatSection, _extends({}, props, {
66706
67265
  section: section
67266
+ })), section.type === 'visualFormat' && jsx(VisualFormatSection, _extends({}, props, {
67267
+ section: section
67268
+ })), section.type === 'kpiSummarisation' && jsx(KPISummarisationSection, _extends({}, props, {
67269
+ section: section
66707
67270
  })), section.type == 'trends' && jsx(TrendsSection, _extends({}, props, {
66708
67271
  section: section
66709
67272
  }))]