@bygd/nc-report-ui 0.1.34 → 0.1.36

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.
@@ -1,27 +1,37 @@
1
1
  import * as React from 'react';
2
2
  import React__default, { useEffect, useMemo, useState, useRef, useContext, createContext } from 'react';
3
- import Paper from '@material-ui/core/Paper';
4
- import { makeStyles } from '@material-ui/core/styles';
5
- import { CircularProgress } from '@material-ui/core';
3
+ import Paper from '@mui/material/Paper';
4
+ import Box from '@mui/material/Box';
5
+ import CircularProgress from '@mui/material/CircularProgress';
6
6
  import { Chart as Chart$1 } from 'react-google-charts';
7
7
  import numeral from 'numeral';
8
8
  import axios from 'axios';
9
- import Typography from '@material-ui/core/Typography';
9
+ import Typography from '@mui/material/Typography';
10
+ import Link from '@mui/material/Link';
10
11
  import nunjucks from 'nunjucks';
11
- import FormControl$2 from '@material-ui/core/FormControl';
12
- import Select$1 from '@material-ui/core/Select';
13
- import MenuItem$1 from '@material-ui/core/MenuItem';
12
+ import FormControl$1 from '@mui/material/FormControl';
13
+ import Select from '@mui/material/Select';
14
+ import MenuItem from '@mui/material/MenuItem';
14
15
  import { useInView } from 'react-intersection-observer';
15
- import { FormControl, Autocomplete, TextField, CircularProgress as CircularProgress$1, Chip, Checkbox, FormHelperText, Snackbar, Alert, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, Box as Box$1, Typography as Typography$1, Tooltip, IconButton, Paper as Paper$1, Tabs, Tab, Badge } from '@mui/material';
16
+ import { FormControl, Autocomplete, TextField, CircularProgress as CircularProgress$1, Chip, Checkbox, FormHelperText, Snackbar, Alert, Dialog, DialogTitle, DialogContent, DialogContentText, DialogActions, Button, Box as Box$1, Typography as Typography$1, Tooltip as Tooltip$1, IconButton as IconButton$1, Paper as Paper$1, Tabs, Tab, Badge } from '@mui/material';
16
17
  import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
17
18
  import CheckBoxIcon from '@mui/icons-material/CheckBox';
18
- import Box from '@mui/material/Box';
19
- import MenuItem from '@mui/material/MenuItem';
20
- import FormControl$1 from '@mui/material/FormControl';
21
- import Select from '@mui/material/Select';
22
19
  import EventEmitter from 'eventemitter3';
23
- import Grid from '@material-ui/core/Grid';
24
- import Container from '@material-ui/core/Container';
20
+ import Grid from '@mui/material/Grid';
21
+ import IconButton from '@mui/material/IconButton';
22
+ import Tooltip from '@mui/material/Tooltip';
23
+ import Container from '@mui/material/Container';
24
+ import InsertChartOutlinedIcon from '@mui/icons-material/InsertChartOutlined';
25
+ import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
26
+ import TableChartOutlinedIcon from '@mui/icons-material/TableChartOutlined';
27
+ import BarChartIcon from '@mui/icons-material/BarChart';
28
+ import PieChartOutlineIcon from '@mui/icons-material/PieChartOutline';
29
+ import DonutLargeIcon from '@mui/icons-material/DonutLarge';
30
+ import ShowChartIcon from '@mui/icons-material/ShowChart';
31
+ import StackedLineChartIcon from '@mui/icons-material/StackedLineChart';
32
+ import MapOutlinedIcon from '@mui/icons-material/MapOutlined';
33
+ import PinOutlinedIcon from '@mui/icons-material/PinOutlined';
34
+ import QueryStatsIcon from '@mui/icons-material/QueryStats';
25
35
  import { DataGrid, GridAddIcon, GridDeleteIcon } from '@mui/x-data-grid';
26
36
  import AddIcon from '@mui/icons-material/Add';
27
37
  import EditIcon from '@mui/icons-material/Edit';
@@ -64,19 +74,16 @@ function _extends() {
64
74
  }, _extends.apply(null, arguments);
65
75
  }
66
76
 
67
- const useStyles$1 = makeStyles(theme => ({
68
- root: {
69
- width: "100%",
70
- "& > * + *": {
71
- marginTop: theme.spacing(2)
72
- }
73
- }
74
- }));
75
77
  function LinearIndeterminate(props) {
76
- const classes = useStyles$1();
77
- return /*#__PURE__*/React__default.createElement("div", _extends({
78
- className: classes.root
79
- }, props), /*#__PURE__*/React__default.createElement(CircularProgress, {
78
+ return /*#__PURE__*/React__default.createElement(Box, _extends({}, props, {
79
+ sx: {
80
+ width: "100%",
81
+ "& > * + *": {
82
+ mt: 2
83
+ },
84
+ ...(props?.sx || {})
85
+ }
86
+ }), /*#__PURE__*/React__default.createElement(CircularProgress, {
80
87
  style: {
81
88
  color: "rgb(70, 134, 128)"
82
89
  } // custom color
@@ -100,7 +107,7 @@ function ValuePicker(view, schema, outputFormat = 'array') {
100
107
  const value = row[item.name];
101
108
  const ref = mapped[item.name];
102
109
  let formatted = value;
103
- if (ref.type === 'timestamp') formatted = new Date(value);else if (!ref.format) formatted = value;else if (ref.format && ref.prefix) formatted = {
110
+ if (!ref) formatted = value;else if (ref.type === 'timestamp') formatted = new Date(value);else if (!ref.format) formatted = value;else if (ref.format && ref.prefix) formatted = {
104
111
  v: +value,
105
112
  f: ref.prefix + " " + numeral(value).format(ref.format)
106
113
  };else if (ref.format) formatted = {
@@ -454,27 +461,44 @@ const Api = {
454
461
  }
455
462
  };
456
463
 
457
- const useStyles = makeStyles(theme => ({
458
- headerRow: {
459
- fontFamily: theme.typography.fontFamily,
460
- fontSize: theme.typography.fontSize
461
- },
462
- tableRow: {
463
- fontFamily: theme.typography.fontFamily,
464
- fontSize: theme.typography.fontSize
465
- },
466
- oddTableRow: {
467
- fontFamily: theme.typography.fontFamily,
468
- fontSize: theme.typography.fontSize
469
- },
470
- headerCell: {
471
- backgroundColor: "white",
472
- padding: "4px !important"
464
+ function styleInject(css, ref) {
465
+ if ( ref === void 0 ) ref = {};
466
+ var insertAt = ref.insertAt;
467
+
468
+ if (typeof document === 'undefined') { return; }
469
+
470
+ var head = document.head || document.getElementsByTagName('head')[0];
471
+ var style = document.createElement('style');
472
+ style.type = 'text/css';
473
+
474
+ if (insertAt === 'top') {
475
+ if (head.firstChild) {
476
+ head.insertBefore(style, head.firstChild);
477
+ } else {
478
+ head.appendChild(style);
479
+ }
480
+ } else {
481
+ head.appendChild(style);
473
482
  }
474
- // tableCell:{
475
- // // padding:"4px !important"
476
- // },
477
- }));
483
+
484
+ if (style.styleSheet) {
485
+ style.styleSheet.cssText = css;
486
+ } else {
487
+ style.appendChild(document.createTextNode(css));
488
+ }
489
+ }
490
+
491
+ var css_248z = "/* Google Charts Table styling — class names here are referenced from\n * GoogleChart.js via the `cssClassNames` option and must stay in sync. */\n\n.ncGcHeaderRow {\n font-size: 13px;\n}\n\n.ncGcHeaderCell {\n background-color: #ffffff !important;\n padding: 12px 16px !important;\n border-bottom: 1px solid #e5e7eb !important;\n border-right: none !important;\n font-weight: 600 !important;\n color: #6b7280 !important;\n text-align: left !important;\n white-space: nowrap;\n}\n\n.ncGcTableRow,\n.ncGcOddTableRow {\n font-size: 14px;\n background-color: #ffffff;\n}\n\n.ncGcTableRow a,\n.ncGcOddTableRow a {\n color: #468682;\n text-decoration: underline;\n}\n\n.ncGcTableRow a:hover,\n.ncGcOddTableRow a:hover {\n color: #305f5c;\n}\n\n.ncGcHoverTableRow {\n background-color: #f9fafb !important;\n}\n\n.ncGcTableCell {\n padding: 12px 16px !important;\n border-bottom: 1px solid #f1f2f4 !important;\n border-right: none !important;\n color: #1f2937;\n}\n";
492
+ styleInject(css_248z);
493
+
494
+ const tableClassNames = {
495
+ headerRow: "ncGcHeaderRow",
496
+ headerCell: "ncGcHeaderCell",
497
+ tableRow: "ncGcTableRow",
498
+ oddTableRow: "ncGcOddTableRow",
499
+ hoverTableRow: "ncGcHoverTableRow",
500
+ tableCell: "ncGcTableCell"
501
+ };
478
502
  const dateRangeFormats = {
479
503
  none: "YYYY-MM-dd",
480
504
  day: "MMM dd",
@@ -489,10 +513,10 @@ function GoogleChart({
489
513
  report,
490
514
  schema,
491
515
  dashboard,
492
- query
516
+ query,
517
+ params
493
518
  }) {
494
519
  const [data, setData] = React__default.useState([]);
495
- const classes = useStyles();
496
520
  const [dateRanges, setDateRanges] = React__default.useState([]);
497
521
  useEffect(() => {
498
522
  (async () => {
@@ -514,7 +538,8 @@ function GoogleChart({
514
538
  if (chart?.doc.chart?.type === "Table") {
515
539
  return {
516
540
  ...chart?.doc.chart?.options,
517
- cssClassNames: classes
541
+ cssClassNames: tableClassNames,
542
+ allowHtml: true
518
543
  };
519
544
  } else if (chart?.doc.chart?.type === "AreaChart") {
520
545
  const hAxisFromChart = chart?.doc.chart?.options?.hAxis || {};
@@ -550,16 +575,82 @@ function GoogleChart({
550
575
  });
551
576
  source?.length ? setData(result) : setData();
552
577
  }, [chart, source, view, report, schema]);
578
+ const hidden = (view?.columns || []).filter(c => c.hidden).map(c => c.name);
579
+ const visibleIndexes = (view?.columns || []).map((col, i) => hidden.includes(col.name) ? -1 : i).filter(i => i !== -1);
580
+ const getRaw = cell => cell && typeof cell === "object" && "v" in cell ? cell.v : cell;
581
+ const getDisplay = cell => cell && typeof cell === "object" && "f" in cell ? cell.f : cell;
582
+ const escapeHtml = s => String(s ?? "").replace(/[&<>"']/g, c => ({
583
+ "&": "&amp;",
584
+ "<": "&lt;",
585
+ ">": "&gt;",
586
+ '"': "&quot;",
587
+ "'": "&#39;"
588
+ })[c]);
589
+ const paramAliases = {
590
+ client_id: params?.client
591
+ };
592
+ const renderLink = (template, fullRow) => template.replace(/\{\{([\w.]+)\}\}/g, (_, key) => {
593
+ if (key.startsWith("params.")) {
594
+ const k = key.slice("params.".length);
595
+ return encodeURIComponent(params?.[k] ?? "");
596
+ }
597
+ const idx = (view?.columns || []).findIndex(c => c.name === key);
598
+ if (idx >= 0) return encodeURIComponent(getRaw(fullRow[idx]) ?? "");
599
+ if (key in paramAliases) return encodeURIComponent(paramAliases[key] ?? "");
600
+ if (params && key in params) return encodeURIComponent(params[key] ?? "");
601
+ return "";
602
+ });
603
+ const displayData = data?.length ? data.map((row, rowIdx) => {
604
+ if (rowIdx === 0) return visibleIndexes.map(i => row[i]);
605
+ return visibleIndexes.map(i => {
606
+ const col = view.columns[i];
607
+ const cell = row[i];
608
+ if (!col?.link) return cell;
609
+ const url = renderLink(col.link, row);
610
+ const display = escapeHtml(getDisplay(cell));
611
+ return {
612
+ v: getRaw(cell),
613
+ f: `<a href="${url}" target="blank">${display}</a>`
614
+ };
615
+ });
616
+ }) : data;
617
+ const maxHeight = chart?.doc?.chart?.options?.maxHeight;
618
+ const containerStyle = maxHeight ? {
619
+ maxHeight,
620
+ overflow: "auto"
621
+ } : {};
553
622
  return data ? /*#__PURE__*/React__default.createElement("div", {
554
- style: {}
623
+ style: containerStyle
555
624
  }, /*#__PURE__*/React__default.createElement(Chart$1, _extends({
556
625
  width: chart?.doc.size?.width || "100%"
557
626
  //height={dashboard ? (chart?.doc.size?.height || '300px') : '100%'}
558
627
  ,
559
628
  chartType: chart?.doc.chart?.type,
560
- data: data,
629
+ data: displayData,
561
630
  options: getOptions(data)
562
- }, chart?.doc.chart?.props))) : /*#__PURE__*/React__default.createElement("div", null);
631
+ }, chart?.doc.chart?.props, {
632
+ chartEvents: [{
633
+ eventName: "select",
634
+ callback: ({
635
+ chartWrapper
636
+ }) => {
637
+ const selection = chartWrapper.getChart().getSelection();
638
+ if (!selection.length) return;
639
+ const {
640
+ row
641
+ } = selection[0];
642
+ const values = data[row + 1];
643
+ const rowObject = (view?.columns || []).reduce((acc, col, i) => {
644
+ const v = values[i];
645
+ acc[col.name] = v && typeof v === "object" && "v" in v ? v.v : v;
646
+ return acc;
647
+ }, {});
648
+
649
+ //const url = https://dev.netcapital.pro/client/financing-order/applications/bdc1a65c-808a-425a-97d9-587b5f6bc003?clientId=7774bcad-05dc-48cf-a52b-9a8a56168818
650
+ console.log("clicked row:", row, rowObject);
651
+ }
652
+ }]
653
+ }))) : /*#__PURE__*/React__default.createElement("div", null);
563
654
  }
564
655
 
565
656
  function LabelChart({
@@ -567,7 +658,8 @@ function LabelChart({
567
658
  source,
568
659
  view,
569
660
  report,
570
- schema
661
+ schema,
662
+ onNavigate
571
663
  }) {
572
664
  const [data, setData] = React__default.useState([]);
573
665
  const [value, setValue] = React__default.useState();
@@ -592,18 +684,34 @@ function LabelChart({
592
684
  setSubText(subTextRendered);
593
685
  }
594
686
  }, [chart, source, view, report, schema]);
687
+ const nextView = chart?.doc?.chart?.options?.nextView;
688
+ const canNavigate = typeof nextView === "number" && typeof onNavigate === "function";
595
689
  return /*#__PURE__*/React__default.createElement("div", {
596
690
  style: {
597
691
  display: "flex",
598
692
  justifyContent: "center",
599
693
  alignContent: "center",
600
- //alignItems: "center",
694
+ //alignItems: "center",
601
695
  height: "100%",
602
696
  flexDirection: "column"
603
697
  }
698
+ }, /*#__PURE__*/React__default.createElement("div", {
699
+ style: {
700
+ display: "flex",
701
+ alignItems: "center",
702
+ gap: 8
703
+ }
604
704
  }, /*#__PURE__*/React__default.createElement(Typography, {
605
705
  variant: "h6"
606
- }, value?.f || value), /*#__PURE__*/React__default.createElement(Typography, {
706
+ }, value?.f || value), canNavigate && /*#__PURE__*/React__default.createElement(Link, {
707
+ component: "button",
708
+ variant: "h6",
709
+ onClick: () => onNavigate(nextView),
710
+ style: {
711
+ lineHeight: 1,
712
+ fontSize: "2rem"
713
+ }
714
+ }, "\xBB")), /*#__PURE__*/React__default.createElement(Typography, {
607
715
  variant: "caption"
608
716
  }, subText));
609
717
  }
@@ -1081,6 +1189,11 @@ var Chart = ({
1081
1189
  value: props?.filter
1082
1190
  });
1083
1191
  const [currentQuery, setCurrentQuery] = React__default.useState({});
1192
+ useEffect(() => {
1193
+ console.log('CHART', {
1194
+ id
1195
+ });
1196
+ }, [id]);
1084
1197
 
1085
1198
  // sample label
1086
1199
  // if(id!=='financing_applications') return null;
@@ -1160,7 +1273,9 @@ var Chart = ({
1160
1273
  report: report,
1161
1274
  schema: schema,
1162
1275
  dashboard: dashboard,
1163
- query: currentQuery
1276
+ query: currentQuery,
1277
+ params: props.params,
1278
+ onNavigate: props.onNavigate
1164
1279
  }));
1165
1280
  };
1166
1281
  const onViewChanged = React__default.useCallback(event => {
@@ -1288,19 +1403,24 @@ var Chart = ({
1288
1403
  gap: "12px",
1289
1404
  height: "100%"
1290
1405
  }
1291
- }, chart && /*#__PURE__*/React__default.createElement("div", {
1406
+ }, (chart || props?.headerActions) && /*#__PURE__*/React__default.createElement("div", {
1292
1407
  style: {
1293
1408
  display: "flex",
1294
1409
  alignItems: "center",
1295
1410
  lineHeight: 0
1296
1411
  }
1297
- }, /*#__PURE__*/React__default.createElement(Typography, {
1412
+ }, chart && /*#__PURE__*/React__default.createElement(Typography, {
1298
1413
  variant: "subtitle2",
1299
1414
  style: {
1300
1415
  fontWeight: 600,
1301
1416
  color: "#252525"
1302
1417
  }
1303
- }, props?.title || chart.doc.name, " ")), loading ? /*#__PURE__*/React__default.createElement(LinearIndeterminate, {
1418
+ }, props?.title || chart.doc.name, " "), props?.headerActions && /*#__PURE__*/React__default.createElement("div", {
1419
+ style: {
1420
+ marginLeft: "auto",
1421
+ lineHeight: "normal"
1422
+ }
1423
+ }, props.headerActions)), loading ? /*#__PURE__*/React__default.createElement(LinearIndeterminate, {
1304
1424
  style: {
1305
1425
  display: "flex",
1306
1426
  justifyContent: "center",
@@ -1316,7 +1436,10 @@ var Chart = ({
1316
1436
  style: {
1317
1437
  flexGrow: 1
1318
1438
  }
1319
- }), /*#__PURE__*/React__default.createElement("div", null, chart?.doc?.view?.length > 1 && /*#__PURE__*/React__default.createElement(FormControl$2, null, /*#__PURE__*/React__default.createElement(Select$1, {
1439
+ }), /*#__PURE__*/React__default.createElement("div", null, chart?.doc?.view?.length > 1 && /*#__PURE__*/React__default.createElement(FormControl$1, {
1440
+ variant: "standard"
1441
+ }, /*#__PURE__*/React__default.createElement(Select, {
1442
+ variant: "standard",
1320
1443
  labelId: "date-range-select-label",
1321
1444
  id: "date-range-select",
1322
1445
  value: activeViewIndex,
@@ -1325,7 +1448,7 @@ var Chart = ({
1325
1448
  fontSize: "12px"
1326
1449
  },
1327
1450
  disableUnderline: true
1328
- }, chart.doc.view.map((item, index) => /*#__PURE__*/React__default.createElement(MenuItem$1, {
1451
+ }, chart.doc.view.map((item, index) => /*#__PURE__*/React__default.createElement(MenuItem, {
1329
1452
  key: index,
1330
1453
  value: index
1331
1454
  }, item.title)))))), /*#__PURE__*/React__default.createElement("div", {
@@ -1428,6 +1551,89 @@ const useReportingContextOptional = () => {
1428
1551
  return useContext(ReportingContext);
1429
1552
  };
1430
1553
 
1554
+ const VIEW_ICONS = {
1555
+ count: PinOutlinedIcon,
1556
+ list: FormatListBulletedIcon,
1557
+ table: TableChartOutlinedIcon,
1558
+ bar: BarChartIcon,
1559
+ pie: PieChartOutlineIcon,
1560
+ donut: DonutLargeIcon,
1561
+ line: ShowChartIcon,
1562
+ area: StackedLineChartIcon,
1563
+ map: MapOutlinedIcon,
1564
+ stats: QueryStatsIcon
1565
+ };
1566
+ const resolveViewIcon = icon => VIEW_ICONS[icon] || InsertChartOutlinedIcon;
1567
+ function ColumnItem({
1568
+ column,
1569
+ md,
1570
+ api,
1571
+ cache,
1572
+ dashboard,
1573
+ schema,
1574
+ params
1575
+ }) {
1576
+ const views = Array.isArray(column.views) ? column.views : null;
1577
+ const [activeIndex, setActiveIndex] = React__default.useState(0);
1578
+ if (views && views.length > 0) {
1579
+ const safeIndex = Math.min(activeIndex, views.length - 1);
1580
+ const active = views[safeIndex];
1581
+ const toolbar = /*#__PURE__*/React__default.createElement(Box, {
1582
+ display: "flex"
1583
+ }, views.map((v, i) => {
1584
+ const Icon = resolveViewIcon(v.icon);
1585
+ const selected = i === safeIndex;
1586
+ return /*#__PURE__*/React__default.createElement(Tooltip, {
1587
+ key: v.id || i,
1588
+ title: v.name || v.id || ""
1589
+ }, /*#__PURE__*/React__default.createElement(IconButton, {
1590
+ size: "small",
1591
+ onClick: () => setActiveIndex(i),
1592
+ "aria-label": v.name || v.id,
1593
+ "aria-pressed": selected,
1594
+ style: {
1595
+ color: selected ? "#468682" : "#9ca3af"
1596
+ }
1597
+ }, /*#__PURE__*/React__default.createElement(Icon, {
1598
+ fontSize: "small"
1599
+ })));
1600
+ }));
1601
+ return /*#__PURE__*/React__default.createElement(Grid, {
1602
+ size: {
1603
+ xs: 12,
1604
+ md
1605
+ }
1606
+ }, /*#__PURE__*/React__default.createElement(Chart, {
1607
+ api: api,
1608
+ cache: cache,
1609
+ id: active.id,
1610
+ dashboard: dashboard,
1611
+ schema: schema,
1612
+ title: column.name || active.title,
1613
+ filter: active.filter,
1614
+ params: params,
1615
+ headerActions: toolbar,
1616
+ onNavigate: i => {
1617
+ if (typeof i === "number" && i >= 0 && i < views.length) setActiveIndex(i);
1618
+ }
1619
+ }));
1620
+ }
1621
+ return /*#__PURE__*/React__default.createElement(Grid, {
1622
+ size: {
1623
+ xs: 12,
1624
+ md
1625
+ }
1626
+ }, /*#__PURE__*/React__default.createElement(Chart, {
1627
+ api: api,
1628
+ cache: cache,
1629
+ id: column.id,
1630
+ dashboard: dashboard,
1631
+ schema: schema,
1632
+ title: column.title,
1633
+ filter: column.filter,
1634
+ params: params
1635
+ }));
1636
+ }
1431
1637
  function Dashboard({
1432
1638
  id,
1433
1639
  api,
@@ -1476,18 +1682,21 @@ function Dashboard({
1476
1682
  const create_rows_and_columns = async entity => {
1477
1683
  const srcRows = entity?.doc?.rows || [];
1478
1684
  const targetRows = [];
1685
+ const resolveFilter = entity => {
1686
+ if (entity?.override?.filter?.length) {
1687
+ const filter = {};
1688
+ entity.override.filter.forEach(item => {
1689
+ if (item.hasOwnProperty("value")) filter[item.field] = [item.value];
1690
+ // else filter[item.field] = [sourceDataRow[item.field]];
1691
+ });
1692
+ entity.filter = filter;
1693
+ }
1694
+ };
1479
1695
  for (let i = 0; i < srcRows.length; i++) {
1480
1696
  const row = srcRows[i];
1481
1697
  row.columns?.forEach(column => {
1482
- // filter
1483
- if (column.override?.filter?.length) {
1484
- const filter = {};
1485
- column.override.filter.forEach(item => {
1486
- if (item.hasOwnProperty("value")) filter[item.field] = [item.value];
1487
- // else filter[item.field] = [sourceDataRow[item.field]];
1488
- });
1489
- column.filter = filter;
1490
- }
1698
+ resolveFilter(column);
1699
+ column.views?.forEach(resolveFilter);
1491
1700
  });
1492
1701
  targetRows.push(row);
1493
1702
  }
@@ -1546,42 +1755,33 @@ function Dashboard({
1546
1755
  /*#__PURE__*/
1547
1756
  // Row 2 is special: nested grid inside a full-width container
1548
1757
  React__default.createElement(Grid, {
1549
- item: true,
1550
- xs: 12
1758
+ size: {
1759
+ xs: 12
1760
+ }
1551
1761
  }, /*#__PURE__*/React__default.createElement(Grid, {
1552
1762
  container: true,
1553
1763
  spacing: 3
1554
- }, row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(Grid, {
1764
+ }, row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(ColumnItem, {
1555
1765
  key: i,
1556
- item: true,
1557
- xs: 12,
1558
- md: md
1559
- }, /*#__PURE__*/React__default.createElement(Chart, {
1766
+ column: column,
1767
+ md: md,
1560
1768
  api: finalApi,
1561
1769
  cache: cache.current,
1562
- id: column.id,
1563
1770
  dashboard: dashboard,
1564
1771
  schema: schema,
1565
- title: column.title,
1566
- filter: column.filter,
1567
1772
  params: finalParams
1568
- }))))) :
1773
+ })))) :
1569
1774
  // All other rows behave normally
1570
- row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(Grid, {
1775
+ row.columns.map((column, i) => /*#__PURE__*/React__default.createElement(ColumnItem, {
1571
1776
  key: i,
1572
- item: true,
1573
- xs: 12,
1574
- md: md
1575
- }, /*#__PURE__*/React__default.createElement(Chart, {
1777
+ column: column,
1778
+ md: md,
1576
1779
  api: finalApi,
1577
1780
  cache: cache.current,
1578
- id: column.id,
1579
1781
  dashboard: dashboard,
1580
1782
  schema: schema,
1581
- title: column.title,
1582
- filter: column.filter,
1583
1783
  params: finalParams
1584
- }))));
1784
+ })));
1585
1785
  })))
1586
1786
  );
1587
1787
  }
@@ -1854,40 +2054,40 @@ const ReportDefinitionsList = ({
1854
2054
  display: "flex",
1855
2055
  gap: 1
1856
2056
  }
1857
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
2057
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
1858
2058
  title: "Run"
1859
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2059
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
1860
2060
  size: "small",
1861
2061
  color: "success",
1862
2062
  onClick: e => handleRun(params.row.id, e)
1863
2063
  }, /*#__PURE__*/React__default.createElement(PlayArrowIcon, {
1864
2064
  fontSize: "small"
1865
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
2065
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
1866
2066
  title: "Edit"
1867
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2067
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
1868
2068
  size: "small",
1869
2069
  color: "primary",
1870
2070
  onClick: e => handleEdit(params.row.id, e)
1871
2071
  }, /*#__PURE__*/React__default.createElement(EditIcon, {
1872
2072
  fontSize: "small"
1873
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
2073
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
1874
2074
  title: "Clone"
1875
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2075
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
1876
2076
  size: "small",
1877
2077
  onClick: e => handleClone(params.row.id, e)
1878
2078
  }, /*#__PURE__*/React__default.createElement(ContentCopyIcon, {
1879
2079
  fontSize: "small"
1880
- }))), isUserOverride ? /*#__PURE__*/React__default.createElement(Tooltip, {
2080
+ }))), isUserOverride ? /*#__PURE__*/React__default.createElement(Tooltip$1, {
1881
2081
  title: "Revert to the system report"
1882
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2082
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
1883
2083
  size: "small",
1884
2084
  color: "warning",
1885
2085
  onClick: e => handleDelete(params.row.id, e)
1886
2086
  }, /*#__PURE__*/React__default.createElement(RestoreIcon, {
1887
2087
  fontSize: "small"
1888
- }))) : /*#__PURE__*/React__default.createElement(Tooltip, {
2088
+ }))) : /*#__PURE__*/React__default.createElement(Tooltip$1, {
1889
2089
  title: "Delete"
1890
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2090
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
1891
2091
  size: "small",
1892
2092
  color: "error",
1893
2093
  onClick: e => handleDelete(params.row.id, e)
@@ -2420,7 +2620,7 @@ const SortableChip$1 = ({
2420
2620
  sx: {
2421
2621
  minWidth: 0
2422
2622
  }
2423
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
2623
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
2424
2624
  title: fullLabel || displayLabel,
2425
2625
  arrow: true,
2426
2626
  placement: "top"
@@ -2443,30 +2643,30 @@ const SortableChip$1 = ({
2443
2643
  opacity: 0,
2444
2644
  transition: "opacity 0.2s"
2445
2645
  }
2446
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
2646
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
2447
2647
  title: "Edit title",
2448
2648
  arrow: true,
2449
2649
  placement: "top"
2450
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2650
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2451
2651
  size: "small",
2452
2652
  onClick: handleEditClick,
2453
2653
  "aria-label": "edit title"
2454
2654
  }, /*#__PURE__*/React__default.createElement(EditIcon, {
2455
2655
  fontSize: "small"
2456
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
2656
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
2457
2657
  title: sortOrder === null ? "No sort" : sortOrder === "asc" ? "Ascending" : "Descending",
2458
2658
  arrow: true,
2459
2659
  placement: "top"
2460
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2660
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2461
2661
  size: "small",
2462
2662
  onClick: handleSortToggle,
2463
2663
  "aria-label": "toggle sort order",
2464
2664
  color: sortOrder ? "primary" : "default"
2465
- }, getSortIcon())), /*#__PURE__*/React__default.createElement(Tooltip, {
2665
+ }, getSortIcon())), /*#__PURE__*/React__default.createElement(Tooltip$1, {
2466
2666
  title: "Delete",
2467
2667
  arrow: true,
2468
2668
  placement: "top"
2469
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2669
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2470
2670
  size: "small",
2471
2671
  onClick: onDelete,
2472
2672
  "aria-label": "delete",
@@ -2487,14 +2687,14 @@ const SortableChip$1 = ({
2487
2687
  opacity: 0,
2488
2688
  transition: "opacity 0.2s"
2489
2689
  }
2490
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2690
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2491
2691
  size: "small",
2492
2692
  onClick: onMoveUp,
2493
2693
  disabled: isFirst,
2494
2694
  "aria-label": "move up"
2495
2695
  }, /*#__PURE__*/React__default.createElement(ArrowUpwardIcon, {
2496
2696
  fontSize: "small"
2497
- })), /*#__PURE__*/React__default.createElement(IconButton, {
2697
+ })), /*#__PURE__*/React__default.createElement(IconButton$1, {
2498
2698
  size: "small",
2499
2699
  onClick: onMoveDown,
2500
2700
  disabled: isLast,
@@ -2518,32 +2718,32 @@ const SortableChip$1 = ({
2518
2718
  gap: 0.5,
2519
2719
  opacity: 1
2520
2720
  }
2521
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
2721
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
2522
2722
  title: "Save",
2523
2723
  arrow: true,
2524
2724
  placement: "top"
2525
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2725
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2526
2726
  size: "small",
2527
2727
  onClick: handleSave,
2528
2728
  color: "primary",
2529
2729
  "aria-label": "save title"
2530
2730
  }, /*#__PURE__*/React__default.createElement(CheckIcon, {
2531
2731
  fontSize: "small"
2532
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
2732
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
2533
2733
  title: "Cancel",
2534
2734
  arrow: true,
2535
2735
  placement: "top"
2536
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2736
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2537
2737
  size: "small",
2538
2738
  onClick: handleCancel,
2539
2739
  "aria-label": "cancel edit"
2540
2740
  }, /*#__PURE__*/React__default.createElement(CloseIcon, {
2541
2741
  fontSize: "small"
2542
- }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip, {
2742
+ }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip$1, {
2543
2743
  title: "Reset to default",
2544
2744
  arrow: true,
2545
2745
  placement: "top"
2546
- }, /*#__PURE__*/React__default.createElement(IconButton, {
2746
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
2547
2747
  size: "small",
2548
2748
  onClick: handleReset,
2549
2749
  color: "warning",
@@ -2881,11 +3081,11 @@ const Dimensions = ({
2881
3081
  width: "400px",
2882
3082
  fontFamily: "system-ui"
2883
3083
  }
2884
- }), /*#__PURE__*/React__default.createElement(Tooltip, {
3084
+ }), /*#__PURE__*/React__default.createElement(Tooltip$1, {
2885
3085
  title: "Add all available dimensions",
2886
3086
  arrow: true,
2887
3087
  placement: "top"
2888
- }, /*#__PURE__*/React__default.createElement("span", null, /*#__PURE__*/React__default.createElement(IconButton, {
3088
+ }, /*#__PURE__*/React__default.createElement("span", null, /*#__PURE__*/React__default.createElement(IconButton$1, {
2889
3089
  onClick: handleAddAll,
2890
3090
  disabled: getDimensionItems().filter(item => !item.disabled).length === 0,
2891
3091
  "aria-label": "add all dimensions",
@@ -3002,7 +3202,7 @@ const MetricSourceIcon = ({
3002
3202
  fontSize: '15px'
3003
3203
  };
3004
3204
  if (source === 'kpi') {
3005
- return /*#__PURE__*/React__default.createElement(Tooltip, {
3205
+ return /*#__PURE__*/React__default.createElement(Tooltip$1, {
3006
3206
  title: "KPI Metric",
3007
3207
  arrow: true,
3008
3208
  placement: "top"
@@ -3014,7 +3214,7 @@ const MetricSourceIcon = ({
3014
3214
  }));
3015
3215
  }
3016
3216
  if (source === 'dynamic') {
3017
- return /*#__PURE__*/React__default.createElement(Tooltip, {
3217
+ return /*#__PURE__*/React__default.createElement(Tooltip$1, {
3018
3218
  title: "Dynamic Metric",
3019
3219
  arrow: true,
3020
3220
  placement: "top"
@@ -3026,7 +3226,7 @@ const MetricSourceIcon = ({
3026
3226
  }));
3027
3227
  }
3028
3228
  if (source === 'provider') {
3029
- return /*#__PURE__*/React__default.createElement(Tooltip, {
3229
+ return /*#__PURE__*/React__default.createElement(Tooltip$1, {
3030
3230
  title: "Provider Metric",
3031
3231
  arrow: true,
3032
3232
  placement: "top"
@@ -3180,7 +3380,7 @@ const SortableChip = ({
3180
3380
  sx: {
3181
3381
  minWidth: 0
3182
3382
  }
3183
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
3383
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
3184
3384
  title: fullLabel || displayLabel,
3185
3385
  arrow: true,
3186
3386
  placement: "top"
@@ -3203,21 +3403,21 @@ const SortableChip = ({
3203
3403
  opacity: 0,
3204
3404
  transition: "opacity 0.2s"
3205
3405
  }
3206
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
3406
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
3207
3407
  title: "Edit title",
3208
3408
  arrow: true,
3209
3409
  placement: "top"
3210
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3410
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3211
3411
  size: "small",
3212
3412
  onClick: handleEditClick,
3213
3413
  "aria-label": "edit title"
3214
3414
  }, /*#__PURE__*/React__default.createElement(EditIcon, {
3215
3415
  fontSize: "small"
3216
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
3416
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
3217
3417
  title: "Delete",
3218
3418
  arrow: true,
3219
3419
  placement: "top"
3220
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3420
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3221
3421
  size: "small",
3222
3422
  onClick: onDelete,
3223
3423
  "aria-label": "delete",
@@ -3238,14 +3438,14 @@ const SortableChip = ({
3238
3438
  opacity: 0,
3239
3439
  transition: "opacity 0.2s"
3240
3440
  }
3241
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3441
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3242
3442
  size: "small",
3243
3443
  onClick: onMoveUp,
3244
3444
  disabled: isFirst,
3245
3445
  "aria-label": "move up"
3246
3446
  }, /*#__PURE__*/React__default.createElement(ArrowUpwardIcon, {
3247
3447
  fontSize: "small"
3248
- })), /*#__PURE__*/React__default.createElement(IconButton, {
3448
+ })), /*#__PURE__*/React__default.createElement(IconButton$1, {
3249
3449
  size: "small",
3250
3450
  onClick: onMoveDown,
3251
3451
  disabled: isLast,
@@ -3269,32 +3469,32 @@ const SortableChip = ({
3269
3469
  gap: 0.5,
3270
3470
  opacity: 1
3271
3471
  }
3272
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
3472
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
3273
3473
  title: "Save",
3274
3474
  arrow: true,
3275
3475
  placement: "top"
3276
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3476
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3277
3477
  size: "small",
3278
3478
  onClick: handleSave,
3279
3479
  color: "primary",
3280
3480
  "aria-label": "save title"
3281
3481
  }, /*#__PURE__*/React__default.createElement(CheckIcon, {
3282
3482
  fontSize: "small"
3283
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
3483
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
3284
3484
  title: "Cancel",
3285
3485
  arrow: true,
3286
3486
  placement: "top"
3287
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3487
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3288
3488
  size: "small",
3289
3489
  onClick: handleCancel,
3290
3490
  "aria-label": "cancel edit"
3291
3491
  }, /*#__PURE__*/React__default.createElement(CloseIcon, {
3292
3492
  fontSize: "small"
3293
- }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip, {
3493
+ }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip$1, {
3294
3494
  title: "Reset to default",
3295
3495
  arrow: true,
3296
3496
  placement: "top"
3297
- }, /*#__PURE__*/React__default.createElement(IconButton, {
3497
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
3298
3498
  size: "small",
3299
3499
  onClick: handleReset,
3300
3500
  color: "warning",
@@ -3618,11 +3818,11 @@ const Metrics = ({
3618
3818
  width: '400px',
3619
3819
  fontFamily: "system-ui"
3620
3820
  }
3621
- }), /*#__PURE__*/React__default.createElement(Tooltip, {
3821
+ }), /*#__PURE__*/React__default.createElement(Tooltip$1, {
3622
3822
  title: "Add all available metrics",
3623
3823
  arrow: true,
3624
3824
  placement: "top"
3625
- }, /*#__PURE__*/React__default.createElement("span", null, /*#__PURE__*/React__default.createElement(IconButton, {
3825
+ }, /*#__PURE__*/React__default.createElement("span", null, /*#__PURE__*/React__default.createElement(IconButton$1, {
3626
3826
  onClick: handleAddAll,
3627
3827
  disabled: getMetricItems().filter(item => !item.disabled).length === 0,
3628
3828
  "aria-label": "add all metrics",
@@ -4760,28 +4960,28 @@ const Filters = ({
4760
4960
  opacity: 0,
4761
4961
  transition: "opacity 0.2s"
4762
4962
  }
4763
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
4963
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
4764
4964
  title: "Rename filter",
4765
4965
  arrow: true
4766
- }, /*#__PURE__*/React__default.createElement(IconButton, {
4966
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4767
4967
  size: "small",
4768
4968
  onClick: () => handleStartEditTitle(fullPath, dimensionTitleOverrides[fullPath] || filter.dimensionTitle),
4769
4969
  disabled: isEditing
4770
4970
  }, /*#__PURE__*/React__default.createElement(EditIcon, {
4771
4971
  fontSize: "small"
4772
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
4972
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
4773
4973
  title: "Edit filter values",
4774
4974
  arrow: true
4775
- }, /*#__PURE__*/React__default.createElement(IconButton, {
4975
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4776
4976
  size: "small",
4777
4977
  onClick: () => handleEditFilter(fullPath, filter),
4778
4978
  disabled: isEditing
4779
4979
  }, /*#__PURE__*/React__default.createElement(FilterAltIcon, {
4780
4980
  fontSize: "small"
4781
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
4981
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
4782
4982
  title: "Remove filter",
4783
4983
  arrow: true
4784
- }, /*#__PURE__*/React__default.createElement(IconButton, {
4984
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4785
4985
  size: "small",
4786
4986
  onClick: () => onRemoveFilter(fullPath),
4787
4987
  sx: {
@@ -4789,11 +4989,11 @@ const Filters = ({
4789
4989
  }
4790
4990
  }, /*#__PURE__*/React__default.createElement(GridDeleteIcon, {
4791
4991
  fontSize: "small"
4792
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
4992
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
4793
4993
  title: /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("strong", null, "Path:"), " ", formatProviderPath(filter), " \u2192 ", dimensionTitleOverrides[fullPath] || filter.dimensionTitle), /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("strong", null, "Full Path:"), " ", fullPath), /*#__PURE__*/React__default.createElement("div", null, /*#__PURE__*/React__default.createElement("strong", null, isDate ? 'Date Range' : `Values (${valueCount})`, ":"), " ", valuesList)),
4794
4994
  arrow: true,
4795
4995
  placement: "right"
4796
- }, /*#__PURE__*/React__default.createElement(IconButton, {
4996
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4797
4997
  size: "small",
4798
4998
  disabled: isEditing
4799
4999
  }, /*#__PURE__*/React__default.createElement(InfoOutlinedIcon, {
@@ -4816,27 +5016,27 @@ const Filters = ({
4816
5016
  display: "flex",
4817
5017
  gap: 0.5
4818
5018
  }
4819
- }, /*#__PURE__*/React__default.createElement(Tooltip, {
5019
+ }, /*#__PURE__*/React__default.createElement(Tooltip$1, {
4820
5020
  title: "Save",
4821
5021
  arrow: true
4822
- }, /*#__PURE__*/React__default.createElement(IconButton, {
5022
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4823
5023
  size: "small",
4824
5024
  onClick: () => handleSaveTitle(fullPath),
4825
5025
  color: "primary"
4826
5026
  }, /*#__PURE__*/React__default.createElement(CheckIcon, {
4827
5027
  fontSize: "small"
4828
- }))), /*#__PURE__*/React__default.createElement(Tooltip, {
5028
+ }))), /*#__PURE__*/React__default.createElement(Tooltip$1, {
4829
5029
  title: "Cancel",
4830
5030
  arrow: true
4831
- }, /*#__PURE__*/React__default.createElement(IconButton, {
5031
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4832
5032
  size: "small",
4833
5033
  onClick: handleCancelEditTitle
4834
5034
  }, /*#__PURE__*/React__default.createElement(CloseIcon, {
4835
5035
  fontSize: "small"
4836
- }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip, {
5036
+ }))), hasCustomTitle && /*#__PURE__*/React__default.createElement(Tooltip$1, {
4837
5037
  title: "Reset to default",
4838
5038
  arrow: true
4839
- }, /*#__PURE__*/React__default.createElement(IconButton, {
5039
+ }, /*#__PURE__*/React__default.createElement(IconButton$1, {
4840
5040
  size: "small",
4841
5041
  onClick: () => handleResetTitle(fullPath),
4842
5042
  color: "warning"