@vuu-ui/vuu-table-extras 0.13.30 → 0.13.32
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/cjs/datasource-stats/DatasourceStats.css.js +1 -1
- package/cjs/datasource-stats/DatasourceStats.js +67 -53
- package/cjs/datasource-stats/DatasourceStats.js.map +1 -1
- package/cjs/datasource-stats/useDatasourceStats.js +64 -0
- package/cjs/datasource-stats/useDatasourceStats.js.map +1 -0
- package/esm/datasource-stats/DatasourceStats.css.js +1 -1
- package/esm/datasource-stats/DatasourceStats.js +67 -53
- package/esm/datasource-stats/DatasourceStats.js.map +1 -1
- package/esm/datasource-stats/useDatasourceStats.js +62 -0
- package/esm/datasource-stats/useDatasourceStats.js.map +1 -0
- package/package.json +11 -11
- package/types/datasource-stats/DatasourceStats.d.ts +20 -6
- package/types/datasource-stats/useDatasourceStats.d.ts +14 -0
- package/types/index.d.ts +1 -1
- package/types/datasource-stats/index.d.ts +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dataSourceStats = ".vuuDatasourceStats {\n display:
|
|
3
|
+
var dataSourceStats = ".vuuDatasourceStats {\n align-items: center;\n display: grid;\n font-size: var(--vuuDatasourceStats-fontSize, 10px);\n gap: var(--vuuDatasourceStats-gap, var(--salt-spacing-100));\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n height: var(--vuuDatasourceStats-height, 100%);\n padding: 0 var(--salt-spacing-200);\n\n .vuuDatasourceStats-statsPanel {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-100);\n width: fit-content;\n }\n\n .vuuDatasourceStats-rowStats {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-freezeStatus {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-selectionStats {\n justify-self: center;\n grid-area: panel-center;\n }\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n\n.vuuDatasourceStats-value {\n color: var(--salt-content-primary-foreground);\n}\n.vuuDatasourceStats-actions {\n margin: 0 var(--salt-spacing-200);\n}\n\n}\n\n";
|
|
4
4
|
|
|
5
5
|
module.exports = dataSourceStats;
|
|
6
6
|
//# sourceMappingURL=DatasourceStats.css.js.map
|
|
@@ -4,23 +4,27 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var cx = require('clsx');
|
|
5
5
|
var styles = require('@salt-ds/styles');
|
|
6
6
|
var window = require('@salt-ds/window');
|
|
7
|
-
var react = require('react');
|
|
8
7
|
var DatasourceStats = require('./DatasourceStats.css.js');
|
|
9
|
-
var
|
|
8
|
+
var useDatasourceStats = require('./useDatasourceStats.js');
|
|
10
9
|
|
|
11
10
|
const classBase = "vuuDatasourceStats";
|
|
12
11
|
const numberFormatter = new Intl.NumberFormat();
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return timeFormatter(new Date(ts));
|
|
12
|
+
const getLabel = (label, count = 1) => {
|
|
13
|
+
if (count === 1) {
|
|
14
|
+
return typeof label === "string" ? label : label.singlular;
|
|
17
15
|
} else {
|
|
18
|
-
return
|
|
16
|
+
return typeof label === "string" ? `${label}s` : label.plural;
|
|
19
17
|
}
|
|
20
18
|
};
|
|
21
19
|
const DataSourceStats = ({
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
children,
|
|
21
|
+
className,
|
|
22
|
+
dataSource,
|
|
23
|
+
itemLabel = "row",
|
|
24
|
+
showFreezeStatus = true,
|
|
25
|
+
showRowStats = true,
|
|
26
|
+
showSelectionStats = true,
|
|
27
|
+
...htmlAttributes
|
|
24
28
|
}) => {
|
|
25
29
|
const targetWindow = window.useWindow();
|
|
26
30
|
styles.useComponentCssInjection({
|
|
@@ -28,54 +32,64 @@ const DataSourceStats = ({
|
|
|
28
32
|
css: DatasourceStats,
|
|
29
33
|
window: targetWindow
|
|
30
34
|
});
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(isFrozen, freezeTimestamp) => {
|
|
38
|
-
console.log(`DatasourceStats isFrozen ${isFrozen}`);
|
|
39
|
-
if (isFrozen) {
|
|
40
|
-
setFreezeTime(formatTime(freezeTimestamp));
|
|
41
|
-
} else {
|
|
42
|
-
setFreezeTime(void 0);
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
[]
|
|
46
|
-
);
|
|
47
|
-
react.useEffect(() => {
|
|
48
|
-
setSize(dataSource.size);
|
|
49
|
-
dataSource.on("resize", setSize);
|
|
50
|
-
dataSource.on("range", setRange);
|
|
51
|
-
dataSource.on("freeze", handleFreeze);
|
|
52
|
-
return () => {
|
|
53
|
-
dataSource.removeListener("resize", setSize);
|
|
54
|
-
dataSource.removeListener("range", setRange);
|
|
55
|
-
};
|
|
56
|
-
}, [dataSource, handleFreeze]);
|
|
57
|
-
const className = cx(classBase, classNameProp);
|
|
35
|
+
const { freezeTime, range, selectedCount, size } = useDatasourceStats.useDatasourceStats({
|
|
36
|
+
dataSource,
|
|
37
|
+
showFreezeStatus,
|
|
38
|
+
showRowStats,
|
|
39
|
+
showSelectionStats
|
|
40
|
+
});
|
|
58
41
|
const from = numberFormatter.format(range.firstRowInViewport);
|
|
59
|
-
const to = numberFormatter.format(range.lastRowInViewport);
|
|
42
|
+
const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));
|
|
60
43
|
const value = numberFormatter.format(size);
|
|
44
|
+
const showSelection = showSelectionStats && selectedCount > 0;
|
|
61
45
|
if (size === 0) {
|
|
62
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
|
|
46
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ...htmlAttributes, className: cx(classBase, className), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
|
|
63
47
|
} else {
|
|
64
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
48
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
49
|
+
"div",
|
|
50
|
+
{
|
|
51
|
+
...htmlAttributes,
|
|
52
|
+
className: cx(classBase, className, {
|
|
53
|
+
[`${classBase}-withSelection`]: showSelection
|
|
54
|
+
}),
|
|
55
|
+
children: [
|
|
56
|
+
showRowStats ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `${classBase}-statsPanel ${classBase}-rowStats`, children: [
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "Row count" }),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${classBase}-range`, children: [
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: from }),
|
|
60
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "-" }),
|
|
61
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: to })
|
|
62
|
+
] }),
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-label`, children: "of" }),
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: value })
|
|
65
|
+
] }) : null,
|
|
66
|
+
showFreezeStatus && freezeTime !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: `${classBase}-statsPanel ${classBase}-freezeStatus`, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
67
|
+
"span",
|
|
68
|
+
{
|
|
69
|
+
className: `${classBase}-label`,
|
|
70
|
+
children: `(frozen at ${freezeTime})`
|
|
71
|
+
}
|
|
72
|
+
) }) : null,
|
|
73
|
+
showSelection ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
className: `${classBase}-statsPanel ${classBase}-selectionStats`,
|
|
77
|
+
children: [
|
|
78
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-value`, children: selectedCount }),
|
|
79
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
80
|
+
"span",
|
|
81
|
+
{
|
|
82
|
+
className: `${classBase}-label`,
|
|
83
|
+
children: `selected ${getLabel(itemLabel, selectedCount)}`
|
|
84
|
+
}
|
|
85
|
+
),
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `${classBase}-actions`, children })
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
) : null
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
);
|
|
79
93
|
}
|
|
80
94
|
};
|
|
81
95
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, ReactNode } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport {\n DatasourceStatsHookProps,\n useDatasourceStats,\n} from \"./useDatasourceStats\";\n\nexport type ItemLabel =\n | string\n | {\n singlular: string;\n plural: string;\n };\n\nexport interface DataSourceStatsProps\n extends DatasourceStatsHookProps,\n Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * children will be displayed when selection present. Intended\n * use case is display of action button(s) that will operate on\n * selected rows.\n */\n children?: ReactNode;\n /**\n * Label will be used in display of selected row count, e.g\n * '6 trades selected', where 'trade' is the itemLabel, will\n * default to 'row'\n */\n itemLabel?: ItemLabel;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nconst getLabel = (label: ItemLabel, count = 1) => {\n if (count === 1) {\n return typeof label === \"string\" ? label : label.singlular;\n } else {\n return typeof label === \"string\" ? `${label}s` : label.plural;\n }\n};\n\nexport const DataSourceStats = ({\n children,\n className,\n dataSource,\n itemLabel = \"row\",\n showFreezeStatus = true,\n showRowStats = true,\n showSelectionStats = true,\n ...htmlAttributes\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const { freezeTime, range, selectedCount, size } = useDatasourceStats({\n dataSource,\n showFreezeStatus,\n showRowStats,\n showSelectionStats,\n });\n\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));\n const value = numberFormatter.format(size);\n const showSelection = showSelectionStats && selectedCount > 0;\n\n if (size === 0) {\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className, {\n [`${classBase}-withSelection`]: showSelection,\n })}\n >\n {showRowStats ? (\n <div className={`${classBase}-statsPanel ${classBase}-rowStats`}>\n <span className={`${classBase}-label`}>Row count</span>\n <span className={`${classBase}-range`}>\n <span className={`${classBase}-value`}>{from}</span>\n <span className={`${classBase}-label`}>-</span>\n <span className={`${classBase}-value`}>{to}</span>\n </span>\n <span className={`${classBase}-label`}>of</span>\n <span className={`${classBase}-value`}>{value}</span>\n </div>\n ) : null}\n {showFreezeStatus && freezeTime !== undefined ? (\n <div className={`${classBase}-statsPanel ${classBase}-freezeStatus`}>\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n </div>\n ) : null}\n {showSelection ? (\n <div\n className={`${classBase}-statsPanel ${classBase}-selectionStats`}\n >\n <span className={`${classBase}-value`}>{selectedCount}</span>\n <span\n className={`${classBase}-label`}\n >{`selected ${getLabel(itemLabel, selectedCount)}`}</span>\n <span className={`${classBase}-actions`}>{children}</span>\n </div>\n ) : null}\n </div>\n );\n }\n};\n"],"names":["useWindow","useComponentCssInjection","dataSourceStats","useDatasourceStats","jsx","jsxs"],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
|
|
6
|
+
const timeFormatter = vuuUtils.formatDate({ time: "hh:mm:ss" });
|
|
7
|
+
const formatTime = (ts) => {
|
|
8
|
+
if (typeof ts === "number") {
|
|
9
|
+
return timeFormatter(new Date(ts));
|
|
10
|
+
} else {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const useDatasourceStats = ({
|
|
15
|
+
dataSource
|
|
16
|
+
}) => {
|
|
17
|
+
const [selectedCount, setSelectedCount] = react.useState(0);
|
|
18
|
+
const [range, setRange] = react.useState(dataSource.range);
|
|
19
|
+
const [size, setSize] = react.useState(dataSource.size);
|
|
20
|
+
const [freezeTime, setFreezeTime] = react.useState(
|
|
21
|
+
formatTime(dataSource.freezeTimestamp)
|
|
22
|
+
);
|
|
23
|
+
const handleFreeze = react.useCallback(
|
|
24
|
+
(isFrozen, freezeTimestamp) => {
|
|
25
|
+
if (isFrozen) {
|
|
26
|
+
setFreezeTime(formatTime(freezeTimestamp));
|
|
27
|
+
} else {
|
|
28
|
+
setFreezeTime(void 0);
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
[]
|
|
32
|
+
);
|
|
33
|
+
const handleRowSelection = react.useCallback(
|
|
34
|
+
(_, count) => {
|
|
35
|
+
setSelectedCount(count);
|
|
36
|
+
},
|
|
37
|
+
[]
|
|
38
|
+
);
|
|
39
|
+
const handleSize = react.useCallback((size2) => {
|
|
40
|
+
setSize(size2);
|
|
41
|
+
}, []);
|
|
42
|
+
react.useMemo(() => {
|
|
43
|
+
setSize(dataSource.size);
|
|
44
|
+
dataSource.on("resize", handleSize);
|
|
45
|
+
dataSource.on("range", setRange);
|
|
46
|
+
dataSource.on("freeze", handleFreeze);
|
|
47
|
+
dataSource.on("row-selection", handleRowSelection);
|
|
48
|
+
return () => {
|
|
49
|
+
dataSource.removeListener("resize", handleSize);
|
|
50
|
+
dataSource.removeListener("range", setRange);
|
|
51
|
+
dataSource.removeListener("freeze", handleFreeze);
|
|
52
|
+
dataSource.removeListener("row-selection", handleRowSelection);
|
|
53
|
+
};
|
|
54
|
+
}, [dataSource, handleFreeze, handleRowSelection, handleSize]);
|
|
55
|
+
return {
|
|
56
|
+
range,
|
|
57
|
+
selectedCount,
|
|
58
|
+
size,
|
|
59
|
+
freezeTime
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.useDatasourceStats = useDatasourceStats;
|
|
64
|
+
//# sourceMappingURL=useDatasourceStats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/useDatasourceStats.ts"],"sourcesContent":["import { DataSource, RowSelectionEventHandler } from \"@vuu-ui/vuu-data-types\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface DatasourceStatsHookProps {\n dataSource: DataSource;\n showFreezeStatus?: boolean;\n showRowStats?: boolean;\n showSelectionStats?: boolean;\n}\n\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const useDatasourceStats = ({\n dataSource,\n}: DatasourceStatsHookProps) => {\n const [selectedCount, setSelectedCount] = useState(0);\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n const handleRowSelection = useCallback<RowSelectionEventHandler>(\n (_, count) => {\n setSelectedCount(count);\n },\n [],\n );\n\n const handleSize = useCallback((size: number) => {\n setSize(size);\n }, []);\n\n useMemo(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", handleSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n dataSource.on(\"row-selection\", handleRowSelection);\n return () => {\n dataSource.removeListener(\"resize\", handleSize);\n dataSource.removeListener(\"range\", setRange);\n dataSource.removeListener(\"freeze\", handleFreeze);\n dataSource.removeListener(\"row-selection\", handleRowSelection);\n };\n }, [dataSource, handleFreeze, handleRowSelection, handleSize]);\n\n return {\n range,\n selectedCount,\n size,\n freezeTime,\n };\n};\n"],"names":["formatDate","useState","useCallback","size","useMemo"],"mappings":";;;;;AAWA,MAAM,aAAgB,GAAAA,mBAAA,CAAW,EAAE,IAAA,EAAM,YAAY,CAAA;AAErD,MAAM,UAAA,GAAa,CAAC,EAA2B,KAAA;AAC7C,EAAI,IAAA,OAAO,OAAO,QAAU,EAAA;AAC1B,IAAA,OAAO,aAAc,CAAA,IAAI,IAAK,CAAA,EAAE,CAAC,CAAA;AAAA,GAC5B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAEO,MAAM,qBAAqB,CAAC;AAAA,EACjC;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAIC,eAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAAA,cAAA,CAAgB,WAAW,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAAA,cAAA,CAAS,WAAW,IAAI,CAAA;AAChD,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAAA,cAAA;AAAA,IAClC,UAAA,CAAW,WAAW,eAAe;AAAA,GACvC;AAEA,EAAA,MAAM,YAAe,GAAAC,iBAAA;AAAA,IACnB,CAAC,UAAmB,eAA4B,KAAA;AAC9C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,aAAA,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA;AAAA,OACpC,MAAA;AACL,QAAA,aAAA,CAAc,KAAS,CAAA,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,kBAAqB,GAAAA,iBAAA;AAAA,IACzB,CAAC,GAAG,KAAU,KAAA;AACZ,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,KACxB;AAAA,IACA;AAAC,GACH;AAEA,EAAM,MAAA,UAAA,GAAaA,iBAAY,CAAA,CAACC,KAAiB,KAAA;AAC/C,IAAA,OAAA,CAAQA,KAAI,CAAA;AAAA,GACd,EAAG,EAAE,CAAA;AAEL,EAAAC,aAAA,CAAQ,MAAM;AACZ,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,UAAU,CAAA;AAClC,IAAW,UAAA,CAAA,EAAA,CAAG,SAAS,QAAQ,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AACpC,IAAW,UAAA,CAAA,EAAA,CAAG,iBAAiB,kBAAkB,CAAA;AACjD,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,UAAU,CAAA;AAC9C,MAAW,UAAA,CAAA,cAAA,CAAe,SAAS,QAAQ,CAAA;AAC3C,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,YAAY,CAAA;AAChD,MAAW,UAAA,CAAA,cAAA,CAAe,iBAAiB,kBAAkB,CAAA;AAAA,KAC/D;AAAA,KACC,CAAC,UAAA,EAAY,YAAc,EAAA,kBAAA,EAAoB,UAAU,CAAC,CAAA;AAE7D,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,aAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var dataSourceStats = ".vuuDatasourceStats {\n display:
|
|
1
|
+
var dataSourceStats = ".vuuDatasourceStats {\n align-items: center;\n display: grid;\n font-size: var(--vuuDatasourceStats-fontSize, 10px);\n gap: var(--vuuDatasourceStats-gap, var(--salt-spacing-100));\n grid-template-areas: \"panel-start panel-center panel-end\";\n grid-template-columns: 1fr 1fr 1fr;\n grid-template-rows: auto;\n height: var(--vuuDatasourceStats-height, 100%);\n padding: 0 var(--salt-spacing-200);\n\n .vuuDatasourceStats-statsPanel {\n align-items: center;\n display: flex;\n gap: var(--salt-spacing-100);\n width: fit-content;\n }\n\n .vuuDatasourceStats-rowStats {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-freezeStatus {\n justify-self: flex-start;\n grid-area: panel-start;\n }\n .vuuDatasourceStats-selectionStats {\n justify-self: center;\n grid-area: panel-center;\n }\n\n.vuuDatasourceStats-label {\n color: var(--salt-content-secondary-foreground);\n}\n\n.vuuDatasourceStats-value {\n color: var(--salt-content-primary-foreground);\n}\n.vuuDatasourceStats-actions {\n margin: 0 var(--salt-spacing-200);\n}\n\n}\n\n";
|
|
2
2
|
|
|
3
3
|
export { dataSourceStats as default };
|
|
4
4
|
//# sourceMappingURL=DatasourceStats.css.js.map
|
|
@@ -2,23 +2,27 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import cx from 'clsx';
|
|
3
3
|
import { useComponentCssInjection } from '@salt-ds/styles';
|
|
4
4
|
import { useWindow } from '@salt-ds/window';
|
|
5
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
6
5
|
import dataSourceStats from './DatasourceStats.css.js';
|
|
7
|
-
import {
|
|
6
|
+
import { useDatasourceStats } from './useDatasourceStats.js';
|
|
8
7
|
|
|
9
8
|
const classBase = "vuuDatasourceStats";
|
|
10
9
|
const numberFormatter = new Intl.NumberFormat();
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return timeFormatter(new Date(ts));
|
|
10
|
+
const getLabel = (label, count = 1) => {
|
|
11
|
+
if (count === 1) {
|
|
12
|
+
return typeof label === "string" ? label : label.singlular;
|
|
15
13
|
} else {
|
|
16
|
-
return
|
|
14
|
+
return typeof label === "string" ? `${label}s` : label.plural;
|
|
17
15
|
}
|
|
18
16
|
};
|
|
19
17
|
const DataSourceStats = ({
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
children,
|
|
19
|
+
className,
|
|
20
|
+
dataSource,
|
|
21
|
+
itemLabel = "row",
|
|
22
|
+
showFreezeStatus = true,
|
|
23
|
+
showRowStats = true,
|
|
24
|
+
showSelectionStats = true,
|
|
25
|
+
...htmlAttributes
|
|
22
26
|
}) => {
|
|
23
27
|
const targetWindow = useWindow();
|
|
24
28
|
useComponentCssInjection({
|
|
@@ -26,54 +30,64 @@ const DataSourceStats = ({
|
|
|
26
30
|
css: dataSourceStats,
|
|
27
31
|
window: targetWindow
|
|
28
32
|
});
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
(isFrozen, freezeTimestamp) => {
|
|
36
|
-
console.log(`DatasourceStats isFrozen ${isFrozen}`);
|
|
37
|
-
if (isFrozen) {
|
|
38
|
-
setFreezeTime(formatTime(freezeTimestamp));
|
|
39
|
-
} else {
|
|
40
|
-
setFreezeTime(void 0);
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
[]
|
|
44
|
-
);
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
setSize(dataSource.size);
|
|
47
|
-
dataSource.on("resize", setSize);
|
|
48
|
-
dataSource.on("range", setRange);
|
|
49
|
-
dataSource.on("freeze", handleFreeze);
|
|
50
|
-
return () => {
|
|
51
|
-
dataSource.removeListener("resize", setSize);
|
|
52
|
-
dataSource.removeListener("range", setRange);
|
|
53
|
-
};
|
|
54
|
-
}, [dataSource, handleFreeze]);
|
|
55
|
-
const className = cx(classBase, classNameProp);
|
|
33
|
+
const { freezeTime, range, selectedCount, size } = useDatasourceStats({
|
|
34
|
+
dataSource,
|
|
35
|
+
showFreezeStatus,
|
|
36
|
+
showRowStats,
|
|
37
|
+
showSelectionStats
|
|
38
|
+
});
|
|
56
39
|
const from = numberFormatter.format(range.firstRowInViewport);
|
|
57
|
-
const to = numberFormatter.format(range.lastRowInViewport);
|
|
40
|
+
const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));
|
|
58
41
|
const value = numberFormatter.format(size);
|
|
42
|
+
const showSelection = showSelectionStats && selectedCount > 0;
|
|
59
43
|
if (size === 0) {
|
|
60
|
-
return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
|
|
44
|
+
return /* @__PURE__ */ jsx("div", { ...htmlAttributes, className: cx(classBase, className), children: /* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "No Rows to display" }) });
|
|
61
45
|
} else {
|
|
62
|
-
return /* @__PURE__ */ jsxs(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
46
|
+
return /* @__PURE__ */ jsxs(
|
|
47
|
+
"div",
|
|
48
|
+
{
|
|
49
|
+
...htmlAttributes,
|
|
50
|
+
className: cx(classBase, className, {
|
|
51
|
+
[`${classBase}-withSelection`]: showSelection
|
|
52
|
+
}),
|
|
53
|
+
children: [
|
|
54
|
+
showRowStats ? /* @__PURE__ */ jsxs("div", { className: `${classBase}-statsPanel ${classBase}-rowStats`, children: [
|
|
55
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "Row count" }),
|
|
56
|
+
/* @__PURE__ */ jsxs("span", { className: `${classBase}-range`, children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: from }),
|
|
58
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "-" }),
|
|
59
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: to })
|
|
60
|
+
] }),
|
|
61
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-label`, children: "of" }),
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: value })
|
|
63
|
+
] }) : null,
|
|
64
|
+
showFreezeStatus && freezeTime !== void 0 ? /* @__PURE__ */ jsx("div", { className: `${classBase}-statsPanel ${classBase}-freezeStatus`, children: /* @__PURE__ */ jsx(
|
|
65
|
+
"span",
|
|
66
|
+
{
|
|
67
|
+
className: `${classBase}-label`,
|
|
68
|
+
children: `(frozen at ${freezeTime})`
|
|
69
|
+
}
|
|
70
|
+
) }) : null,
|
|
71
|
+
showSelection ? /* @__PURE__ */ jsxs(
|
|
72
|
+
"div",
|
|
73
|
+
{
|
|
74
|
+
className: `${classBase}-statsPanel ${classBase}-selectionStats`,
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-value`, children: selectedCount }),
|
|
77
|
+
/* @__PURE__ */ jsx(
|
|
78
|
+
"span",
|
|
79
|
+
{
|
|
80
|
+
className: `${classBase}-label`,
|
|
81
|
+
children: `selected ${getLabel(itemLabel, selectedCount)}`
|
|
82
|
+
}
|
|
83
|
+
),
|
|
84
|
+
/* @__PURE__ */ jsx("span", { className: `${classBase}-actions`, children })
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
) : null
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
);
|
|
77
91
|
}
|
|
78
92
|
};
|
|
79
93
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"DatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/DatasourceStats.tsx"],"sourcesContent":["import cx from \"clsx\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { HTMLAttributes, ReactNode } from \"react\";\n\nimport dataSourceStats from \"./DatasourceStats.css\";\nimport {\n DatasourceStatsHookProps,\n useDatasourceStats,\n} from \"./useDatasourceStats\";\n\nexport type ItemLabel =\n | string\n | {\n singlular: string;\n plural: string;\n };\n\nexport interface DataSourceStatsProps\n extends DatasourceStatsHookProps,\n Omit<HTMLAttributes<HTMLDivElement>, \"children\"> {\n /**\n * children will be displayed when selection present. Intended\n * use case is display of action button(s) that will operate on\n * selected rows.\n */\n children?: ReactNode;\n /**\n * Label will be used in display of selected row count, e.g\n * '6 trades selected', where 'trade' is the itemLabel, will\n * default to 'row'\n */\n itemLabel?: ItemLabel;\n}\n\nconst classBase = \"vuuDatasourceStats\";\n\nconst numberFormatter = new Intl.NumberFormat();\n\nconst getLabel = (label: ItemLabel, count = 1) => {\n if (count === 1) {\n return typeof label === \"string\" ? label : label.singlular;\n } else {\n return typeof label === \"string\" ? `${label}s` : label.plural;\n }\n};\n\nexport const DataSourceStats = ({\n children,\n className,\n dataSource,\n itemLabel = \"row\",\n showFreezeStatus = true,\n showRowStats = true,\n showSelectionStats = true,\n ...htmlAttributes\n}: DataSourceStatsProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-datasource-stats\",\n css: dataSourceStats,\n window: targetWindow,\n });\n\n const { freezeTime, range, selectedCount, size } = useDatasourceStats({\n dataSource,\n showFreezeStatus,\n showRowStats,\n showSelectionStats,\n });\n\n const from = numberFormatter.format(range.firstRowInViewport);\n const to = numberFormatter.format(Math.min(range.lastRowInViewport, size));\n const value = numberFormatter.format(size);\n const showSelection = showSelectionStats && selectedCount > 0;\n\n if (size === 0) {\n return (\n <div {...htmlAttributes} className={cx(classBase, className)}>\n <span className={`${classBase}-label`}>No Rows to display</span>\n </div>\n );\n } else {\n return (\n <div\n {...htmlAttributes}\n className={cx(classBase, className, {\n [`${classBase}-withSelection`]: showSelection,\n })}\n >\n {showRowStats ? (\n <div className={`${classBase}-statsPanel ${classBase}-rowStats`}>\n <span className={`${classBase}-label`}>Row count</span>\n <span className={`${classBase}-range`}>\n <span className={`${classBase}-value`}>{from}</span>\n <span className={`${classBase}-label`}>-</span>\n <span className={`${classBase}-value`}>{to}</span>\n </span>\n <span className={`${classBase}-label`}>of</span>\n <span className={`${classBase}-value`}>{value}</span>\n </div>\n ) : null}\n {showFreezeStatus && freezeTime !== undefined ? (\n <div className={`${classBase}-statsPanel ${classBase}-freezeStatus`}>\n <span\n className={`${classBase}-label`}\n >{`(frozen at ${freezeTime})`}</span>\n </div>\n ) : null}\n {showSelection ? (\n <div\n className={`${classBase}-statsPanel ${classBase}-selectionStats`}\n >\n <span className={`${classBase}-value`}>{selectedCount}</span>\n <span\n className={`${classBase}-label`}\n >{`selected ${getLabel(itemLabel, selectedCount)}`}</span>\n <span className={`${classBase}-actions`}>{children}</span>\n </div>\n ) : null}\n </div>\n );\n }\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { formatDate } from '@vuu-ui/vuu-utils';
|
|
2
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
const timeFormatter = formatDate({ time: "hh:mm:ss" });
|
|
5
|
+
const formatTime = (ts) => {
|
|
6
|
+
if (typeof ts === "number") {
|
|
7
|
+
return timeFormatter(new Date(ts));
|
|
8
|
+
} else {
|
|
9
|
+
return void 0;
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const useDatasourceStats = ({
|
|
13
|
+
dataSource
|
|
14
|
+
}) => {
|
|
15
|
+
const [selectedCount, setSelectedCount] = useState(0);
|
|
16
|
+
const [range, setRange] = useState(dataSource.range);
|
|
17
|
+
const [size, setSize] = useState(dataSource.size);
|
|
18
|
+
const [freezeTime, setFreezeTime] = useState(
|
|
19
|
+
formatTime(dataSource.freezeTimestamp)
|
|
20
|
+
);
|
|
21
|
+
const handleFreeze = useCallback(
|
|
22
|
+
(isFrozen, freezeTimestamp) => {
|
|
23
|
+
if (isFrozen) {
|
|
24
|
+
setFreezeTime(formatTime(freezeTimestamp));
|
|
25
|
+
} else {
|
|
26
|
+
setFreezeTime(void 0);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
[]
|
|
30
|
+
);
|
|
31
|
+
const handleRowSelection = useCallback(
|
|
32
|
+
(_, count) => {
|
|
33
|
+
setSelectedCount(count);
|
|
34
|
+
},
|
|
35
|
+
[]
|
|
36
|
+
);
|
|
37
|
+
const handleSize = useCallback((size2) => {
|
|
38
|
+
setSize(size2);
|
|
39
|
+
}, []);
|
|
40
|
+
useMemo(() => {
|
|
41
|
+
setSize(dataSource.size);
|
|
42
|
+
dataSource.on("resize", handleSize);
|
|
43
|
+
dataSource.on("range", setRange);
|
|
44
|
+
dataSource.on("freeze", handleFreeze);
|
|
45
|
+
dataSource.on("row-selection", handleRowSelection);
|
|
46
|
+
return () => {
|
|
47
|
+
dataSource.removeListener("resize", handleSize);
|
|
48
|
+
dataSource.removeListener("range", setRange);
|
|
49
|
+
dataSource.removeListener("freeze", handleFreeze);
|
|
50
|
+
dataSource.removeListener("row-selection", handleRowSelection);
|
|
51
|
+
};
|
|
52
|
+
}, [dataSource, handleFreeze, handleRowSelection, handleSize]);
|
|
53
|
+
return {
|
|
54
|
+
range,
|
|
55
|
+
selectedCount,
|
|
56
|
+
size,
|
|
57
|
+
freezeTime
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export { useDatasourceStats };
|
|
62
|
+
//# sourceMappingURL=useDatasourceStats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDatasourceStats.js","sources":["../../../../packages/vuu-table-extras/src/datasource-stats/useDatasourceStats.ts"],"sourcesContent":["import { DataSource, RowSelectionEventHandler } from \"@vuu-ui/vuu-data-types\";\nimport { formatDate, Range } from \"@vuu-ui/vuu-utils\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nexport interface DatasourceStatsHookProps {\n dataSource: DataSource;\n showFreezeStatus?: boolean;\n showRowStats?: boolean;\n showSelectionStats?: boolean;\n}\n\nconst timeFormatter = formatDate({ time: \"hh:mm:ss\" });\n\nconst formatTime = (ts: number | undefined) => {\n if (typeof ts === \"number\") {\n return timeFormatter(new Date(ts));\n } else {\n return undefined;\n }\n};\n\nexport const useDatasourceStats = ({\n dataSource,\n}: DatasourceStatsHookProps) => {\n const [selectedCount, setSelectedCount] = useState(0);\n const [range, setRange] = useState<Range>(dataSource.range);\n const [size, setSize] = useState(dataSource.size);\n const [freezeTime, setFreezeTime] = useState(\n formatTime(dataSource.freezeTimestamp),\n );\n\n const handleFreeze = useCallback(\n (isFrozen: boolean, freezeTimestamp: number) => {\n if (isFrozen) {\n setFreezeTime(formatTime(freezeTimestamp));\n } else {\n setFreezeTime(undefined);\n }\n },\n [],\n );\n\n const handleRowSelection = useCallback<RowSelectionEventHandler>(\n (_, count) => {\n setSelectedCount(count);\n },\n [],\n );\n\n const handleSize = useCallback((size: number) => {\n setSize(size);\n }, []);\n\n useMemo(() => {\n setSize(dataSource.size);\n dataSource.on(\"resize\", handleSize);\n dataSource.on(\"range\", setRange);\n dataSource.on(\"freeze\", handleFreeze);\n dataSource.on(\"row-selection\", handleRowSelection);\n return () => {\n dataSource.removeListener(\"resize\", handleSize);\n dataSource.removeListener(\"range\", setRange);\n dataSource.removeListener(\"freeze\", handleFreeze);\n dataSource.removeListener(\"row-selection\", handleRowSelection);\n };\n }, [dataSource, handleFreeze, handleRowSelection, handleSize]);\n\n return {\n range,\n selectedCount,\n size,\n freezeTime,\n };\n};\n"],"names":["size"],"mappings":";;;AAWA,MAAM,aAAgB,GAAA,UAAA,CAAW,EAAE,IAAA,EAAM,YAAY,CAAA;AAErD,MAAM,UAAA,GAAa,CAAC,EAA2B,KAAA;AAC7C,EAAI,IAAA,OAAO,OAAO,QAAU,EAAA;AAC1B,IAAA,OAAO,aAAc,CAAA,IAAI,IAAK,CAAA,EAAE,CAAC,CAAA;AAAA,GAC5B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA;AAEX,CAAA;AAEO,MAAM,qBAAqB,CAAC;AAAA,EACjC;AACF,CAAgC,KAAA;AAC9B,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,KAAO,EAAA,QAAQ,CAAI,GAAA,QAAA,CAAgB,WAAW,KAAK,CAAA;AAC1D,EAAA,MAAM,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,QAAA,CAAS,WAAW,IAAI,CAAA;AAChD,EAAM,MAAA,CAAC,UAAY,EAAA,aAAa,CAAI,GAAA,QAAA;AAAA,IAClC,UAAA,CAAW,WAAW,eAAe;AAAA,GACvC;AAEA,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,UAAmB,eAA4B,KAAA;AAC9C,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,aAAA,CAAA,UAAA,CAAW,eAAe,CAAC,CAAA;AAAA,OACpC,MAAA;AACL,QAAA,aAAA,CAAc,KAAS,CAAA,CAAA;AAAA;AACzB,KACF;AAAA,IACA;AAAC,GACH;AAEA,EAAA,MAAM,kBAAqB,GAAA,WAAA;AAAA,IACzB,CAAC,GAAG,KAAU,KAAA;AACZ,MAAA,gBAAA,CAAiB,KAAK,CAAA;AAAA,KACxB;AAAA,IACA;AAAC,GACH;AAEA,EAAM,MAAA,UAAA,GAAa,WAAY,CAAA,CAACA,KAAiB,KAAA;AAC/C,IAAA,OAAA,CAAQA,KAAI,CAAA;AAAA,GACd,EAAG,EAAE,CAAA;AAEL,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAA,OAAA,CAAQ,WAAW,IAAI,CAAA;AACvB,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,UAAU,CAAA;AAClC,IAAW,UAAA,CAAA,EAAA,CAAG,SAAS,QAAQ,CAAA;AAC/B,IAAW,UAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AACpC,IAAW,UAAA,CAAA,EAAA,CAAG,iBAAiB,kBAAkB,CAAA;AACjD,IAAA,OAAO,MAAM;AACX,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,UAAU,CAAA;AAC9C,MAAW,UAAA,CAAA,cAAA,CAAe,SAAS,QAAQ,CAAA;AAC3C,MAAW,UAAA,CAAA,cAAA,CAAe,UAAU,YAAY,CAAA;AAChD,MAAW,UAAA,CAAA,cAAA,CAAe,iBAAiB,kBAAkB,CAAA;AAAA,KAC/D;AAAA,KACC,CAAC,UAAA,EAAY,YAAc,EAAA,kBAAA,EAAoB,UAAU,CAAC,CAAA;AAE7D,EAAO,OAAA;AAAA,IACL,KAAA;AAAA,IACA,aAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.13.
|
|
2
|
+
"version": "0.13.32",
|
|
3
3
|
"author": "heswell",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"devDependencies": {
|
|
6
|
-
"@vuu-ui/vuu-filter-types": "0.13.
|
|
7
|
-
"@vuu-ui/vuu-protocol-types": "0.13.
|
|
6
|
+
"@vuu-ui/vuu-filter-types": "0.13.32",
|
|
7
|
+
"@vuu-ui/vuu-protocol-types": "0.13.32"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@vuu-ui/vuu-codemirror": "0.13.
|
|
11
|
-
"@vuu-ui/vuu-data-react": "0.13.
|
|
12
|
-
"@vuu-ui/vuu-data-types": "0.13.
|
|
13
|
-
"@vuu-ui/vuu-table-types": "0.13.
|
|
14
|
-
"@vuu-ui/vuu-popups": "0.13.
|
|
15
|
-
"@vuu-ui/vuu-table": "0.13.
|
|
16
|
-
"@vuu-ui/vuu-utils": "0.13.
|
|
17
|
-
"@vuu-ui/vuu-ui-controls": "0.13.
|
|
10
|
+
"@vuu-ui/vuu-codemirror": "0.13.32",
|
|
11
|
+
"@vuu-ui/vuu-data-react": "0.13.32",
|
|
12
|
+
"@vuu-ui/vuu-data-types": "0.13.32",
|
|
13
|
+
"@vuu-ui/vuu-table-types": "0.13.32",
|
|
14
|
+
"@vuu-ui/vuu-popups": "0.13.32",
|
|
15
|
+
"@vuu-ui/vuu-table": "0.13.32",
|
|
16
|
+
"@vuu-ui/vuu-utils": "0.13.32",
|
|
17
|
+
"@vuu-ui/vuu-ui-controls": "0.13.32",
|
|
18
18
|
"@lezer/lr": "1.4.2",
|
|
19
19
|
"@salt-ds/core": "1.43.0",
|
|
20
20
|
"@salt-ds/styles": "0.2.1",
|
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import { DatasourceStatsHookProps } from "./useDatasourceStats";
|
|
3
|
+
export type ItemLabel = string | {
|
|
4
|
+
singlular: string;
|
|
5
|
+
plural: string;
|
|
6
|
+
};
|
|
7
|
+
export interface DataSourceStatsProps extends DatasourceStatsHookProps, Omit<HTMLAttributes<HTMLDivElement>, "children"> {
|
|
8
|
+
/**
|
|
9
|
+
* children will be displayed when selection present. Intended
|
|
10
|
+
* use case is display of action button(s) that will operate on
|
|
11
|
+
* selected rows.
|
|
12
|
+
*/
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Label will be used in display of selected row count, e.g
|
|
16
|
+
* '6 trades selected', where 'trade' is the itemLabel, will
|
|
17
|
+
* default to 'row'
|
|
18
|
+
*/
|
|
19
|
+
itemLabel?: ItemLabel;
|
|
5
20
|
}
|
|
6
|
-
export declare const DataSourceStats: ({ className
|
|
7
|
-
export {};
|
|
21
|
+
export declare const DataSourceStats: ({ children, className, dataSource, itemLabel, showFreezeStatus, showRowStats, showSelectionStats, ...htmlAttributes }: DataSourceStatsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DataSource } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import { Range } from "@vuu-ui/vuu-utils";
|
|
3
|
+
export interface DatasourceStatsHookProps {
|
|
4
|
+
dataSource: DataSource;
|
|
5
|
+
showFreezeStatus?: boolean;
|
|
6
|
+
showRowStats?: boolean;
|
|
7
|
+
showSelectionStats?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const useDatasourceStats: ({ dataSource, }: DatasourceStatsHookProps) => {
|
|
10
|
+
range: Range;
|
|
11
|
+
selectedCount: number;
|
|
12
|
+
size: number;
|
|
13
|
+
freezeTime: string | undefined;
|
|
14
|
+
};
|
package/types/index.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export { columnSettingsFromColumnMenuPermissions, tableSettingsFromColumnMenuPer
|
|
|
12
12
|
export * from "./column-expression-input";
|
|
13
13
|
export * from "./column-expression-panel";
|
|
14
14
|
export * from "./column-formatting-settings";
|
|
15
|
-
export
|
|
15
|
+
export { DataSourceStats, type DataSourceStatsProps, } from "./datasource-stats/DatasourceStats";
|
|
16
16
|
export { TableProvider, useTableContext } from "./table-provider/TableProvider";
|
|
17
17
|
export { FreezeControl } from "./freeze-control/FreezeControl";
|
|
18
18
|
export { type ColumnChangeHandler, type ColumnItem, ColumnList, } from "./column-list";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./DatasourceStats";
|