@bluemarble/bi 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DashboardDevtools-6v5HDe-A.js → DashboardDevtools-SCewfQGR.js} +508 -28
- package/dist/DashboardDevtools-SCewfQGR.js.map +1 -0
- package/dist/{ModelDictionary-D3JzCd6x.js → ModelDictionary-C2tzlOY8.js} +4 -3
- package/dist/{ModelDictionary-D3JzCd6x.js.map → ModelDictionary-C2tzlOY8.js.map} +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +164 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/index.d.ts +26 -5
- package/dist/client/index.js +72 -26
- package/dist/client/index.js.map +1 -1
- package/dist/codegen-DBe4-XW_.js +354 -0
- package/dist/codegen-DBe4-XW_.js.map +1 -0
- package/dist/{types-FdrY0FOZ.d.ts → layout-B7eYgNyR.d.ts} +226 -152
- package/dist/{layout-QuOYFmp1.js → layout-BS51SQcJ.js} +219 -346
- package/dist/layout-BS51SQcJ.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +2 -1
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +4 -1
- package/dist/DashboardDevtools-6v5HDe-A.js.map +0 -1
- package/dist/layout-QuOYFmp1.js.map +0 -1
package/dist/client/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as isBuiltinChart, h as
|
|
2
|
-
import { a as formatCurrency, c as measureFormat, d as useDashboard, i as fieldLabel, l as measureFormatter, m as layoutItemKey, n as INSPECT_ATTRIBUTE, o as formatMeasure, p as LAYOUT_ITEM_ATTRIBUTE, r as useModelQuery, s as formatNumber, t as ModelDictionary, u as DashboardProvider } from "../ModelDictionary-
|
|
1
|
+
import { T as rowRuleStyles, _ as tableColumns, f as isBuiltinChart, h as percentColumn, o as chartCardStyle, u as customChartProps } from "../layout-BS51SQcJ.js";
|
|
2
|
+
import { a as formatCurrency, c as measureFormat, d as useDashboard, i as fieldLabel, l as measureFormatter, m as layoutItemKey, n as INSPECT_ATTRIBUTE, o as formatMeasure, p as LAYOUT_ITEM_ATTRIBUTE, r as useModelQuery, s as formatNumber, t as ModelDictionary, u as DashboardProvider } from "../ModelDictionary-C2tzlOY8.js";
|
|
3
3
|
import { Box, Checkbox, CircularProgress, FormControl, InputLabel, ListItemText, MenuItem, OutlinedInput, Paper, Select, Table, TableBody, TableCell, TableHead, TableRow, TableSortLabel, Typography } from "@mui/material";
|
|
4
4
|
import { Bar, BarChart as BarChart$1, CartesianGrid, Cell, ComposedChart, LabelList, Line, Pie, PieChart, ResponsiveContainer, Tooltip as Tooltip$1, XAxis, YAxis } from "recharts";
|
|
5
5
|
import { createContext, useContext, useEffect, useLayoutEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -705,8 +705,7 @@ function DashboardCanvas({ layout, children }) {
|
|
|
705
705
|
//#endregion
|
|
706
706
|
//#region src/client/DataTable.tsx
|
|
707
707
|
const EMPTY = [];
|
|
708
|
-
|
|
709
|
-
const PERCENT = "%:";
|
|
708
|
+
const NO_RULES = [];
|
|
710
709
|
function compare(a, b) {
|
|
711
710
|
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
712
711
|
return String(a).localeCompare(String(b), "pt-BR", { numeric: true });
|
|
@@ -715,17 +714,25 @@ function compare(a, b) {
|
|
|
715
714
|
* Tabela de medidas por dimensões, com total e ordenação pelo cabeçalho. Ex.:
|
|
716
715
|
* `<DataTable dimensions={['navio']} measures={['volTotal', 'custoTotal', 'custoTon']} />`.
|
|
717
716
|
*/
|
|
718
|
-
function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDimensions = {}, showTotal = true, sortBy, sortDirection = "desc", clickToFilter = false, height = 400, labels, formats: formatsByMeasure, percentDecimals = 1, columnOrder, queryLabel }) {
|
|
717
|
+
function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDimensions = {}, showTotal = true, sortBy, sortDirection = "desc", clickToFilter = false, height = 400, labels, formats: formatsByMeasure, percentDecimals = 1, columnOrder, formatRules = NO_RULES, cellBorders = false, borderColor = "#e0e0e0", align, verticalAlign, queryLabel }) {
|
|
719
718
|
const { meta } = useDashboard();
|
|
720
719
|
const name = queryLabel ?? `DataTable · ${dimensions.join(", ") || "total"}`;
|
|
721
720
|
const firstDimension = dimensions[0];
|
|
722
721
|
const ignoreFilters = clickToFilter && firstDimension ? [firstDimension] : void 0;
|
|
723
722
|
const extraMeasures = percentOf.filter((measure) => !measures.includes(measure));
|
|
723
|
+
const outside = [...new Set([sortBy, ...formatRules.map((rule) => rule.field)].filter(Boolean))].filter((field) => !field.startsWith("%:") && !dimensions.includes(field) && !measures.includes(field) && !extraMeasures.includes(field));
|
|
724
|
+
const waitingMeta = outside.length > 0 && !meta;
|
|
725
|
+
const queryDimensions = [...dimensions, ...outside.filter((field) => meta?.dimensions[field])];
|
|
724
726
|
const { rows, isLoading, error, inspectProps } = useModelQuery({
|
|
725
|
-
dimensions,
|
|
726
|
-
measures: [
|
|
727
|
+
dimensions: queryDimensions,
|
|
728
|
+
measures: [
|
|
729
|
+
...measures,
|
|
730
|
+
...extraMeasures,
|
|
731
|
+
...outside.filter((field) => meta?.measures[field] && !meta.dimensions[field])
|
|
732
|
+
],
|
|
727
733
|
ignoreFilters,
|
|
728
|
-
label: name
|
|
734
|
+
label: name,
|
|
735
|
+
skip: waitingMeta
|
|
729
736
|
});
|
|
730
737
|
const totals = useModelQuery({
|
|
731
738
|
measures,
|
|
@@ -746,7 +753,7 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
746
753
|
direction: sortDirection
|
|
747
754
|
});
|
|
748
755
|
}
|
|
749
|
-
const sortKey = sort.by?.startsWith(
|
|
756
|
+
const sortKey = sort.by?.startsWith("%:") ? sort.by.slice(2) : sort.by;
|
|
750
757
|
const sorted = sortKey ? [...rows].sort((a, b) => {
|
|
751
758
|
const [x, y] = [a[sortKey], b[sortKey]];
|
|
752
759
|
if (x === null || x === void 0) return 1;
|
|
@@ -758,7 +765,7 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
758
765
|
const dimensionText = (dimension, value) => value === null || value === void 0 ? "(vazio)" : (formatDimensions[dimension] ?? String)(value);
|
|
759
766
|
const labelOf = (column) => fieldLabel(meta, column, labels);
|
|
760
767
|
const headerOf = (column) => {
|
|
761
|
-
if (!column.startsWith(
|
|
768
|
+
if (!column.startsWith("%:")) return labelOf(column);
|
|
762
769
|
const measure = column.slice(2);
|
|
763
770
|
return measures.includes(measure) ? "%" : `% ${labelOf(measure)}`;
|
|
764
771
|
};
|
|
@@ -768,10 +775,25 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
768
775
|
const total = sums[measure];
|
|
769
776
|
return value === null || value === void 0 || !total ? null : Number(value) / total;
|
|
770
777
|
};
|
|
771
|
-
const columns =
|
|
778
|
+
const columns = tableColumns([...dimensions, ...measures], percentOf.filter((measure) => !dimensions.includes(measure)), columnOrder);
|
|
779
|
+
const ruleStyles = (row) => {
|
|
780
|
+
if (!formatRules.length) return void 0;
|
|
781
|
+
const evaluated = { ...row };
|
|
782
|
+
for (const measure of percentOf) evaluated[percentColumn(measure)] = percentOfRow(row, measure);
|
|
783
|
+
return rowRuleStyles(formatRules, evaluated, columns);
|
|
784
|
+
};
|
|
785
|
+
const ruleSx = (style) => style && {
|
|
786
|
+
...style.color && { color: style.color },
|
|
787
|
+
...style.background && { bgcolor: style.background },
|
|
788
|
+
...style.bold && { fontWeight: 700 },
|
|
789
|
+
...style.align && { textAlign: style.align },
|
|
790
|
+
...style.verticalAlign && { verticalAlign: style.verticalAlign }
|
|
791
|
+
};
|
|
772
792
|
const isDimension = (column) => dimensions.includes(column);
|
|
793
|
+
const alignOf = (column) => align?.[column] ?? (isDimension(column) ? "left" : "right");
|
|
794
|
+
const verticalOf = (column) => verticalAlign?.[column] ?? "middle";
|
|
773
795
|
const totalLabelColumn = columns.find(isDimension);
|
|
774
|
-
const cellText = (row, column) => column.startsWith(
|
|
796
|
+
const cellText = (row, column) => column.startsWith("%:") ? formatPercent(percentOfRow(row, column.slice(2))) : formats[column]?.(row[column]);
|
|
775
797
|
const toggleSort = (column) => setSort((current) => current.by === column ? {
|
|
776
798
|
by: column,
|
|
777
799
|
direction: current.direction === "asc" ? "desc" : "asc"
|
|
@@ -780,19 +802,21 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
780
802
|
direction: dimensions.includes(column) ? "asc" : "desc"
|
|
781
803
|
});
|
|
782
804
|
const totalRow = dimensions.length ? totals.rows[0] : void 0;
|
|
805
|
+
const loading = isLoading || waitingMeta;
|
|
783
806
|
const placeholder = chartPlaceholder({
|
|
784
807
|
height: 160,
|
|
785
808
|
error,
|
|
786
|
-
isLoading,
|
|
809
|
+
isLoading: loading,
|
|
787
810
|
empty: !rows.length
|
|
788
811
|
});
|
|
789
812
|
const header = (column, numeric) => /* @__PURE__ */ jsx(TableCell, {
|
|
790
|
-
align:
|
|
813
|
+
align: alignOf(column),
|
|
791
814
|
sortDirection: sort.by === column ? sort.direction : false,
|
|
792
815
|
sx: {
|
|
793
816
|
fontWeight: 700,
|
|
794
817
|
bgcolor: "#f3f3f3",
|
|
795
|
-
whiteSpace: "nowrap"
|
|
818
|
+
whiteSpace: "nowrap",
|
|
819
|
+
verticalAlign: verticalOf(column)
|
|
796
820
|
},
|
|
797
821
|
children: /* @__PURE__ */ jsx(TableSortLabel, {
|
|
798
822
|
active: sort.by === column,
|
|
@@ -807,7 +831,7 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
807
831
|
minWidth: 0,
|
|
808
832
|
position: "relative"
|
|
809
833
|
},
|
|
810
|
-
children: [
|
|
834
|
+
children: [loading && /* @__PURE__ */ jsx(CircularProgress, {
|
|
811
835
|
size: 14,
|
|
812
836
|
sx: {
|
|
813
837
|
position: "absolute",
|
|
@@ -818,16 +842,20 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
818
842
|
sx: {
|
|
819
843
|
maxHeight: height,
|
|
820
844
|
overflow: "auto",
|
|
821
|
-
opacity:
|
|
845
|
+
opacity: loading ? .5 : 1,
|
|
822
846
|
transition: "opacity .2s"
|
|
823
847
|
},
|
|
824
848
|
children: /* @__PURE__ */ jsxs(Table, {
|
|
825
849
|
size: "small",
|
|
826
850
|
stickyHeader: true,
|
|
827
|
-
sx: { "& td, & th": {
|
|
851
|
+
sx: { "& td, & th": {
|
|
852
|
+
fontSize: 13,
|
|
853
|
+
...cellBorders && { border: `1px solid ${borderColor}` }
|
|
854
|
+
} },
|
|
828
855
|
children: [/* @__PURE__ */ jsx(TableHead, { children: /* @__PURE__ */ jsx(TableRow, { children: columns.map((column) => header(column, !isDimension(column))) }) }), /* @__PURE__ */ jsxs(TableBody, { children: [sorted.map((row) => {
|
|
829
856
|
const value = firstDimension ? row[firstDimension] : null;
|
|
830
857
|
const clickable = clickToFilter && value !== null && value !== void 0;
|
|
858
|
+
const styles = ruleStyles(row);
|
|
831
859
|
return /* @__PURE__ */ jsx(TableRow, {
|
|
832
860
|
hover: true,
|
|
833
861
|
onClick: clickable ? (event) => filter.toggle(value, event) : void 0,
|
|
@@ -836,12 +864,23 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
836
864
|
cursor: clickable ? "pointer" : void 0,
|
|
837
865
|
opacity: clickable && filter.isDimmed(value) ? .5 : 1
|
|
838
866
|
},
|
|
839
|
-
children: columns.map((column) => isDimension(column) ? /* @__PURE__ */ jsx(TableCell, {
|
|
840
|
-
align:
|
|
841
|
-
sx: {
|
|
867
|
+
children: columns.map((column) => isDimension(column) ? /* @__PURE__ */ jsx(TableCell, {
|
|
868
|
+
align: alignOf(column),
|
|
869
|
+
sx: {
|
|
870
|
+
verticalAlign: verticalOf(column),
|
|
871
|
+
...ruleSx(styles?.[column])
|
|
872
|
+
},
|
|
873
|
+
children: dimensionText(column, row[column])
|
|
874
|
+
}, column) : /* @__PURE__ */ jsx(TableCell, {
|
|
875
|
+
align: alignOf(column),
|
|
876
|
+
sx: {
|
|
877
|
+
whiteSpace: "nowrap",
|
|
878
|
+
verticalAlign: verticalOf(column),
|
|
879
|
+
...ruleSx(styles?.[column])
|
|
880
|
+
},
|
|
842
881
|
children: cellText(row, column)
|
|
843
882
|
}, column))
|
|
844
|
-
},
|
|
883
|
+
}, queryDimensions.map((dimension) => String(row[dimension])).join("\0"));
|
|
845
884
|
}), totalRow && /* @__PURE__ */ jsx(TableRow, {
|
|
846
885
|
sx: { "& td": {
|
|
847
886
|
fontWeight: 700,
|
|
@@ -850,10 +889,17 @@ function DataTable({ dimensions = EMPTY, measures, percentOf = EMPTY, formatDime
|
|
|
850
889
|
bgcolor: "#f3f3f3",
|
|
851
890
|
borderTop: "2px solid #ddd"
|
|
852
891
|
} },
|
|
853
|
-
children: columns.map((column) => isDimension(column) ? /* @__PURE__ */ jsx(TableCell, {
|
|
854
|
-
align:
|
|
855
|
-
sx: {
|
|
856
|
-
children: column
|
|
892
|
+
children: columns.map((column) => isDimension(column) ? /* @__PURE__ */ jsx(TableCell, {
|
|
893
|
+
align: alignOf(column),
|
|
894
|
+
sx: { verticalAlign: verticalOf(column) },
|
|
895
|
+
children: column === totalLabelColumn ? "Total" : ""
|
|
896
|
+
}, column) : /* @__PURE__ */ jsx(TableCell, {
|
|
897
|
+
align: alignOf(column),
|
|
898
|
+
sx: {
|
|
899
|
+
whiteSpace: "nowrap",
|
|
900
|
+
verticalAlign: verticalOf(column)
|
|
901
|
+
},
|
|
902
|
+
children: column.startsWith("%:") ? formatPercent(sums[column.slice(2)] ? 1 : null) : formats[column]?.(totalRow[column])
|
|
857
903
|
}, column))
|
|
858
904
|
})] })]
|
|
859
905
|
})
|