@datawheel/data-explorer 0.1.2 → 0.2.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/main.js +293 -239
- package/package.json +3 -1
package/dist/main.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { keyframes, createStyles, Select, rem, Flex, Title, Text, Group, Button, Box, Anchor, Input, Stack, SimpleGrid, Table, MultiSelect, Center, Alert, Loader, Modal, NumberInput, Menu, ActionIcon, useMantineTheme,
|
|
1
|
+
import { keyframes, createStyles, Select, rem, Flex, Title, Text, Group, Button, Box, Anchor, Input, Stack, SimpleGrid, ScrollArea, Table, MultiSelect, Center, Alert, Loader, Modal, NumberInput, Menu, ActionIcon, useMantineTheme, MantineProvider, Paper, useComponentDefaultProps, Switch, ThemeIcon, Tooltip, Tabs, CloseButton, Drawer, Checkbox, UnstyledButton, TextInput, Accordion, Popover, Divider } from '@mantine/core';
|
|
2
2
|
import { useClipboard, useClickOutside, useFullscreen, useMediaQuery, useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
|
3
3
|
import { Prism } from '@mantine/prism';
|
|
4
4
|
import { IconWorld, IconExternalLink, IconClipboard, IconAlertCircle, IconAlertTriangle, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconCopy, IconDownload, IconDotsVertical, IconArrowsMinimize, IconArrowsMaximize, IconInfoCircleFilled, IconTrash, IconSearch, IconPhotoDown, IconVectorTriangle, IconStack3, IconFilterOff, IconFilter, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconLanguage } from '@tabler/icons-react';
|
|
@@ -14,7 +14,7 @@ import formUrlEncode from 'form-urlencoded';
|
|
|
14
14
|
import formUrlDecode from 'form-urldecoded';
|
|
15
15
|
import { MRT_ProgressBar, flexRender, MRT_TableBodyCell, MRT_ToolbarAlertBanner, useMantineReactTable, MantineReactTable, MRT_TablePagination } from 'mantine-react-table';
|
|
16
16
|
import { formatAbbreviate, format } from 'd3plus-format';
|
|
17
|
-
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
|
|
17
|
+
import { QueryClient, QueryClientProvider, useQuery, useQueryClient } from '@tanstack/react-query';
|
|
18
18
|
import debounce from 'lodash.debounce';
|
|
19
19
|
import { matchSorter } from 'match-sorter';
|
|
20
20
|
import yn from 'yn';
|
|
@@ -203,6 +203,7 @@ var defaultTranslation = {
|
|
|
203
203
|
dataset: "Select Dataset"
|
|
204
204
|
},
|
|
205
205
|
comparison: {
|
|
206
|
+
BT: "Between",
|
|
206
207
|
EQ: "Equal to",
|
|
207
208
|
GT: "Greater than",
|
|
208
209
|
GTE: "Equal or greater than",
|
|
@@ -238,12 +239,15 @@ var defaultTranslation = {
|
|
|
238
239
|
action_clear: "Clear query",
|
|
239
240
|
action_clear_description: "Clear all parameters from your current query",
|
|
240
241
|
action_execute: "Execute query",
|
|
242
|
+
add_columns: "Add columns",
|
|
241
243
|
column_title: "Parameters",
|
|
242
244
|
current_endpoint: "Current endpoint: {{label}}",
|
|
243
245
|
dimmenu_abbrjoint: ": ",
|
|
244
246
|
dimmenu_dimension: "{{dimension}}",
|
|
245
247
|
dimmenu_hierarchy: "{{abbr}}",
|
|
246
248
|
dimmenu_level: "{{abbr}}",
|
|
249
|
+
filter_mode: "Filter Mode",
|
|
250
|
+
filter_by: "Filter by {{name}}",
|
|
247
251
|
error_no_cut_selected_detail: "You can add data filters based on selected drilldowns.",
|
|
248
252
|
error_no_cut_selected_title: "No cuts added",
|
|
249
253
|
error_no_dimension_selected_detail: "You must add at least one drilldown.",
|
|
@@ -1362,7 +1366,6 @@ function parseStateFromSearchParams(query) {
|
|
|
1362
1366
|
const comparison = cond[0];
|
|
1363
1367
|
const inputtedValue = cond[1];
|
|
1364
1368
|
const interpretedValue = Number.parseFloat(cond[1]);
|
|
1365
|
-
console.log("Entro parse", comparison, inputtedValue, interpretedValue);
|
|
1366
1369
|
return [comparison, inputtedValue, interpretedValue];
|
|
1367
1370
|
}
|
|
1368
1371
|
}
|
|
@@ -1560,24 +1563,7 @@ function calcMaxMemberCount(query, params, dispatch) {
|
|
|
1560
1563
|
});
|
|
1561
1564
|
const memberLengths = query.getParam("drilldowns").map(
|
|
1562
1565
|
(level) => Level.isLevel(level) ? drills[level.uniqueName] || ds.fetchMembers(level).then(async (members) => {
|
|
1563
|
-
const {
|
|
1564
|
-
({
|
|
1565
|
-
cube: cube.name,
|
|
1566
|
-
dimension: dimension.name,
|
|
1567
|
-
fullName,
|
|
1568
|
-
depth,
|
|
1569
|
-
_type: "level",
|
|
1570
|
-
name: name4,
|
|
1571
|
-
uri: level._source.uri,
|
|
1572
|
-
properties: properties.map((p) => ({
|
|
1573
|
-
name: p.name,
|
|
1574
|
-
annotations: p.annotations,
|
|
1575
|
-
uri: p._source.uri,
|
|
1576
|
-
_type: "property"
|
|
1577
|
-
})),
|
|
1578
|
-
hierarchy: hierarchy.name,
|
|
1579
|
-
annotations
|
|
1580
|
-
});
|
|
1566
|
+
const { dimension } = level;
|
|
1581
1567
|
const drilldown = Object.values(params.drilldowns).find(
|
|
1582
1568
|
(d) => d.uniqueName === level.uniqueName
|
|
1583
1569
|
);
|
|
@@ -1717,7 +1703,7 @@ function willDownloadQuery(format2) {
|
|
|
1717
1703
|
const dataURL = query.toString("logiclayer").replace(olapClient.datasource.serverUrl, "");
|
|
1718
1704
|
return Promise.all([
|
|
1719
1705
|
axios({ url: dataURL, responseType: "blob" }).then((response) => response.data),
|
|
1720
|
-
calcMaxMemberCount(query, params).then((maxRows) => {
|
|
1706
|
+
calcMaxMemberCount(query, params, dispatch).then((maxRows) => {
|
|
1721
1707
|
if (maxRows > 5e4) {
|
|
1722
1708
|
dispatch(loadingActions.setLoadingMessage({ type: "HEAVY_QUERY", rows: maxRows }));
|
|
1723
1709
|
}
|
|
@@ -1739,10 +1725,19 @@ function willExecuteQuery({ limit, offset } = {}) {
|
|
|
1739
1725
|
const allParams = isPrefetch ? { ...params, pagiLimit: limit, pagiOffset: offset } : params;
|
|
1740
1726
|
const { result: currentResult } = selectCurrentQueryItem(state);
|
|
1741
1727
|
if (!isValidQuery(params)) return Promise.resolve();
|
|
1742
|
-
return olapClient.getCube(params.cube).then((cube) => {
|
|
1728
|
+
return olapClient.getCube(params.cube).then(async (cube) => {
|
|
1743
1729
|
const query = applyQueryParams(cube.query, allParams, { previewLimit });
|
|
1730
|
+
const axios = olapClient.datasource.axiosInstance;
|
|
1731
|
+
const dataURL = query.toString("logiclayer").replace(olapClient.datasource.serverUrl, "");
|
|
1744
1732
|
return Promise.all([
|
|
1745
|
-
|
|
1733
|
+
axios({ url: dataURL }).then((response) => {
|
|
1734
|
+
return {
|
|
1735
|
+
data: response.data,
|
|
1736
|
+
headers: { ...response.headers },
|
|
1737
|
+
query,
|
|
1738
|
+
status: response.status
|
|
1739
|
+
};
|
|
1740
|
+
}),
|
|
1746
1741
|
calcMaxMemberCount(query, allParams, dispatch).then((maxRows) => {
|
|
1747
1742
|
if (maxRows > 5e4) {
|
|
1748
1743
|
dispatch(loadingActions.setLoadingMessage({ type: "HEAVY_QUERY", rows: maxRows }));
|
|
@@ -1751,19 +1746,20 @@ function willExecuteQuery({ limit, offset } = {}) {
|
|
|
1751
1746
|
]).then(
|
|
1752
1747
|
(result) => {
|
|
1753
1748
|
const [aggregation] = result;
|
|
1749
|
+
const { data, headers, status } = aggregation;
|
|
1754
1750
|
!isPrefetch && dispatch(
|
|
1755
1751
|
queriesActions.updateResult({
|
|
1756
|
-
data
|
|
1757
|
-
types:
|
|
1758
|
-
headers: { ...
|
|
1752
|
+
data,
|
|
1753
|
+
types: (data == null ? void 0 : data.data.length) ? describeData(cube.toJSON(), params, data == null ? void 0 : data.data) : currentResult.types,
|
|
1754
|
+
headers: { ...headers },
|
|
1759
1755
|
sourceCall: query.toSource(),
|
|
1760
|
-
status:
|
|
1756
|
+
status: status || 500,
|
|
1761
1757
|
url: query.toString(endpoint)
|
|
1762
1758
|
})
|
|
1763
1759
|
);
|
|
1764
1760
|
return {
|
|
1765
|
-
data
|
|
1766
|
-
types:
|
|
1761
|
+
data,
|
|
1762
|
+
types: (data == null ? void 0 : data.data.length) ? describeData(cube.toJSON(), params, data == null ? void 0 : data.data) : currentResult.types
|
|
1767
1763
|
};
|
|
1768
1764
|
},
|
|
1769
1765
|
(error) => {
|
|
@@ -2183,40 +2179,41 @@ function IconChevronRight() {
|
|
|
2183
2179
|
return /* @__PURE__ */ React10__default.createElement("svg", { width: "9", height: "13", viewBox: "0 0 7 11", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React10__default.createElement("path", { d: "M1 10L5.5 5.5L1 1", stroke: "black", strokeLinecap: "round" }));
|
|
2184
2180
|
}
|
|
2185
2181
|
function DataSetSVG() {
|
|
2186
|
-
return /* @__PURE__ */ React10__default.createElement(
|
|
2187
|
-
"
|
|
2188
|
-
{
|
|
2189
|
-
d: "M3.33325 5C3.33325 5.66304 4.03563 6.29893 5.28587 6.76777C6.53612 7.23661 8.23181 7.5 9.99992 7.5C11.768 7.5 13.4637 7.23661 14.714 6.76777C15.9642 6.29893 16.6666 5.66304 16.6666 5C16.6666 4.33696 15.9642 3.70107 14.714 3.23223C13.4637 2.76339 11.768 2.5 9.99992 2.5C8.23181 2.5 6.53612 2.76339 5.28587 3.23223C4.03563 3.70107 3.33325 4.33696 3.33325 5Z",
|
|
2190
|
-
stroke: "#212529",
|
|
2191
|
-
strokeLinecap: "round",
|
|
2192
|
-
strokeLinejoin: "round"
|
|
2193
|
-
}
|
|
2194
|
-
), /* @__PURE__ */ React10__default.createElement(
|
|
2195
|
-
"path",
|
|
2196
|
-
{
|
|
2197
|
-
d: "M3.33325 5V10C3.33325 10.663 4.03563 11.2989 5.28587 11.7678C6.53612 12.2366 8.23181 12.5 9.99992 12.5C11.768 12.5 13.4637 12.2366 14.714 11.7678C15.9642 11.2989 16.6666 10.663 16.6666 10V5",
|
|
2198
|
-
stroke: "#212529",
|
|
2199
|
-
strokeLinecap: "round",
|
|
2200
|
-
strokeLinejoin: "round"
|
|
2201
|
-
}
|
|
2202
|
-
), /* @__PURE__ */ React10__default.createElement(
|
|
2203
|
-
"path",
|
|
2204
|
-
{
|
|
2205
|
-
d: "M3.33325 10V15C3.33325 15.663 4.03563 16.2989 5.28587 16.7678C6.53612 17.2366 8.23181 17.5 9.99992 17.5C11.768 17.5 13.4637 17.2366 14.714 16.7678C15.9642 16.2989 16.6666 15.663 16.6666 15V10",
|
|
2206
|
-
stroke: "#212529",
|
|
2207
|
-
strokeLinecap: "round",
|
|
2208
|
-
strokeLinejoin: "round"
|
|
2209
|
-
}
|
|
2210
|
-
));
|
|
2211
|
-
}
|
|
2212
|
-
function HomeSVG() {
|
|
2213
|
-
return /* @__PURE__ */ React10__default.createElement("svg", { width: "22", height: "24", viewBox: "0 0 16 18", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React10__default.createElement(
|
|
2214
|
-
"path",
|
|
2182
|
+
return /* @__PURE__ */ React10__default.createElement(
|
|
2183
|
+
"svg",
|
|
2215
2184
|
{
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2185
|
+
width: "25",
|
|
2186
|
+
height: "25",
|
|
2187
|
+
viewBox: "0 0 20 20",
|
|
2188
|
+
fill: "none",
|
|
2189
|
+
stroke: "currentColor",
|
|
2190
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
2191
|
+
},
|
|
2192
|
+
/* @__PURE__ */ React10__default.createElement(
|
|
2193
|
+
"path",
|
|
2194
|
+
{
|
|
2195
|
+
d: "M3.33325 5C3.33325 5.66304 4.03563 6.29893 5.28587 6.76777C6.53612 7.23661 8.23181 7.5 9.99992 7.5C11.768 7.5 13.4637 7.23661 14.714 6.76777C15.9642 6.29893 16.6666 5.66304 16.6666 5C16.6666 4.33696 15.9642 3.70107 14.714 3.23223C13.4637 2.76339 11.768 2.5 9.99992 2.5C8.23181 2.5 6.53612 2.76339 5.28587 3.23223C4.03563 3.70107 3.33325 4.33696 3.33325 5Z",
|
|
2196
|
+
strokeLinecap: "round",
|
|
2197
|
+
strokeLinejoin: "round"
|
|
2198
|
+
}
|
|
2199
|
+
),
|
|
2200
|
+
/* @__PURE__ */ React10__default.createElement(
|
|
2201
|
+
"path",
|
|
2202
|
+
{
|
|
2203
|
+
d: "M3.33325 5V10C3.33325 10.663 4.03563 11.2989 5.28587 11.7678C6.53612 12.2366 8.23181 12.5 9.99992 12.5C11.768 12.5 13.4637 12.2366 14.714 11.7678C15.9642 11.2989 16.6666 10.663 16.6666 10V5",
|
|
2204
|
+
strokeLinecap: "round",
|
|
2205
|
+
strokeLinejoin: "round"
|
|
2206
|
+
}
|
|
2207
|
+
),
|
|
2208
|
+
/* @__PURE__ */ React10__default.createElement(
|
|
2209
|
+
"path",
|
|
2210
|
+
{
|
|
2211
|
+
d: "M3.33325 10V15C3.33325 15.663 4.03563 16.2989 5.28587 16.7678C6.53612 17.2366 8.23181 17.5 9.99992 17.5C11.768 17.5 13.4637 17.2366 14.714 16.7678C15.9642 16.2989 16.6666 15.663 16.6666 15V10",
|
|
2212
|
+
strokeLinecap: "round",
|
|
2213
|
+
strokeLinejoin: "round"
|
|
2214
|
+
}
|
|
2215
|
+
)
|
|
2216
|
+
);
|
|
2220
2217
|
}
|
|
2221
2218
|
function StackSVG() {
|
|
2222
2219
|
return /* @__PURE__ */ React10__default.createElement(
|
|
@@ -2455,6 +2452,11 @@ function TableFooter(props) {
|
|
|
2455
2452
|
const { url } = result;
|
|
2456
2453
|
const { copy, copied } = useClipboard({ timeout: 1e3 });
|
|
2457
2454
|
const copyHandler = useCallback(() => copy(url), [url]);
|
|
2455
|
+
const totalRowCount = table.options.rowCount;
|
|
2456
|
+
const {
|
|
2457
|
+
pagination: { pageSize }
|
|
2458
|
+
} = table.getState();
|
|
2459
|
+
const showPagination = totalRowCount && Boolean(totalRowCount > pageSize);
|
|
2458
2460
|
return /* @__PURE__ */ React10__default.createElement(Box, { w: "100%", sx: { flex: "0 0 70px" } }, /* @__PURE__ */ React10__default.createElement(
|
|
2459
2461
|
Flex,
|
|
2460
2462
|
{
|
|
@@ -2465,7 +2467,7 @@ function TableFooter(props) {
|
|
|
2465
2467
|
gap: "sm"
|
|
2466
2468
|
},
|
|
2467
2469
|
/* @__PURE__ */ React10__default.createElement(CubeSource, null),
|
|
2468
|
-
/* @__PURE__ */ React10__default.createElement(Group, { position: "right", spacing: "sm" }, /* @__PURE__ */ React10__default.createElement(Text, { c: "dimmed" }, t("results.count_rows", { n:
|
|
2470
|
+
/* @__PURE__ */ React10__default.createElement(Group, { position: "right", spacing: "sm" }, /* @__PURE__ */ React10__default.createElement(Text, { c: "dimmed" }, t("results.count_rows", { n: totalRowCount })), showPagination && /* @__PURE__ */ React10__default.createElement(MRT_TablePagination, { table }), /* @__PURE__ */ React10__default.createElement(ApiAndCsvButtons, { copied, copyHandler, url }))
|
|
2469
2471
|
));
|
|
2470
2472
|
}
|
|
2471
2473
|
var ApiAndCsvButtons = (props) => {
|
|
@@ -2672,6 +2674,7 @@ function abbreviateFullName(nameParts, joint = "/") {
|
|
|
2672
2674
|
}
|
|
2673
2675
|
function AddColumnsDrawer() {
|
|
2674
2676
|
const [opened, { open, close: close2 }] = useDisclosure(false);
|
|
2677
|
+
const { translate: t } = useTranslation();
|
|
2675
2678
|
const theme = useMantineTheme();
|
|
2676
2679
|
const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
|
|
2677
2680
|
return /* @__PURE__ */ React10__default.createElement(React10__default.Fragment, null, /* @__PURE__ */ React10__default.createElement(
|
|
@@ -2680,8 +2683,8 @@ function AddColumnsDrawer() {
|
|
|
2680
2683
|
opened,
|
|
2681
2684
|
position: "right",
|
|
2682
2685
|
onClose: close2,
|
|
2683
|
-
title: /* @__PURE__ */ React10__default.createElement(Group, null, /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "
|
|
2684
|
-
styles: (
|
|
2686
|
+
title: /* @__PURE__ */ React10__default.createElement(Group, null, /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "1rem" }), /* @__PURE__ */ React10__default.createElement(Text, { fw: 700 }, t("params.add_columns"))),
|
|
2687
|
+
styles: (t2) => ({
|
|
2685
2688
|
inner: {
|
|
2686
2689
|
position: "absolute",
|
|
2687
2690
|
inset: 0
|
|
@@ -2690,7 +2693,7 @@ function AddColumnsDrawer() {
|
|
|
2690
2693
|
background: "transparent"
|
|
2691
2694
|
},
|
|
2692
2695
|
content: {
|
|
2693
|
-
backgroundColor:
|
|
2696
|
+
backgroundColor: t2.colorScheme === "dark" ? t2.colors.dark[8] : t2.colors.gray[1]
|
|
2694
2697
|
}
|
|
2695
2698
|
}),
|
|
2696
2699
|
overlayProps: {
|
|
@@ -2700,7 +2703,7 @@ function AddColumnsDrawer() {
|
|
|
2700
2703
|
},
|
|
2701
2704
|
/* @__PURE__ */ React10__default.createElement(MeasuresOptions, null),
|
|
2702
2705
|
/* @__PURE__ */ React10__default.createElement(DrillDownOptions, null)
|
|
2703
|
-
), /* @__PURE__ */ React10__default.createElement(Group, { position: "center" }, smallerThanMd ? /* @__PURE__ */ React10__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React10__default.createElement(Button, { leftIcon: /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "
|
|
2706
|
+
), /* @__PURE__ */ React10__default.createElement(Group, { position: "center" }, smallerThanMd ? /* @__PURE__ */ React10__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React10__default.createElement(Button, { leftIcon: /* @__PURE__ */ React10__default.createElement(IconStack3, { size: "1rem" }), onClick: open, m: "md", size: "xs" }, t("params.add_columns"))));
|
|
2704
2707
|
}
|
|
2705
2708
|
function DrillDownOptions() {
|
|
2706
2709
|
const locale = useSelector$1(selectLocale);
|
|
@@ -2712,7 +2715,7 @@ function DrillDownOptions() {
|
|
|
2712
2715
|
cutItem.active = false;
|
|
2713
2716
|
actions2.updateCut(cutItem);
|
|
2714
2717
|
}, []);
|
|
2715
|
-
|
|
2718
|
+
useCallback(
|
|
2716
2719
|
(level) => {
|
|
2717
2720
|
var _a;
|
|
2718
2721
|
const drilldownItem = (_a = selectedDimensions.find((item) => item.uniqueName === level.uniqueName)) != null ? _a : buildDrilldown({ ...level });
|
|
@@ -2739,7 +2742,6 @@ function DrillDownOptions() {
|
|
|
2739
2742
|
dimension,
|
|
2740
2743
|
locale: locale.code,
|
|
2741
2744
|
key: dimension.uri,
|
|
2742
|
-
onItemSelect: createHandler,
|
|
2743
2745
|
activeItems
|
|
2744
2746
|
}
|
|
2745
2747
|
)),
|
|
@@ -2862,9 +2864,10 @@ function LevelItem({ dimension, hierarchy, isSubMenu, level, locale, activeItems
|
|
|
2862
2864
|
actions2.updateDrilldown({ ...currentDrilldown, active: !currentDrilldown.active });
|
|
2863
2865
|
},
|
|
2864
2866
|
checked,
|
|
2865
|
-
label
|
|
2867
|
+
label,
|
|
2868
|
+
size: "xs"
|
|
2866
2869
|
}
|
|
2867
|
-
), /* @__PURE__ */ React10__default.createElement(Group, null, /* @__PURE__ */ React10__default.createElement(ActionIcon, { size: "
|
|
2870
|
+
), /* @__PURE__ */ React10__default.createElement(Group, null, /* @__PURE__ */ React10__default.createElement(ActionIcon, { size: "sm", onClick: () => setActiveFilter((value) => !value) }, activeFilter ? /* @__PURE__ */ React10__default.createElement(IconFilterOff, null) : /* @__PURE__ */ React10__default.createElement(IconFilter, null)), /* @__PURE__ */ React10__default.createElement(ThemeIcon, { size: "xs", color: "gray", variant: "light", bg: "transparent" }, /* @__PURE__ */ React10__default.createElement(StackSVG, null)))), activeFilter && /* @__PURE__ */ React10__default.createElement(Box, { pt: "md" }, /* @__PURE__ */ React10__default.createElement(
|
|
2868
2871
|
MultiSelect,
|
|
2869
2872
|
{
|
|
2870
2873
|
sx: { flex: "1 1 100%" },
|
|
@@ -2889,14 +2892,14 @@ function LevelItem({ dimension, hierarchy, isSubMenu, level, locale, activeItems
|
|
|
2889
2892
|
}
|
|
2890
2893
|
)));
|
|
2891
2894
|
}
|
|
2892
|
-
function
|
|
2895
|
+
function getFilterfnKey(type) {
|
|
2893
2896
|
switch (type) {
|
|
2894
2897
|
case "greaterThan":
|
|
2895
|
-
return "
|
|
2898
|
+
return "GT";
|
|
2896
2899
|
case "lessThan":
|
|
2897
|
-
return "
|
|
2900
|
+
return "LT";
|
|
2898
2901
|
case "between":
|
|
2899
|
-
return "
|
|
2902
|
+
return "BT";
|
|
2900
2903
|
default:
|
|
2901
2904
|
return "Not Found";
|
|
2902
2905
|
}
|
|
@@ -2986,7 +2989,8 @@ function MinMax({ filter, ...rest }) {
|
|
|
2986
2989
|
}
|
|
2987
2990
|
function FilterFnsMenu({ filter }) {
|
|
2988
2991
|
const actions2 = useActions();
|
|
2989
|
-
|
|
2992
|
+
const { translate: t } = useTranslation();
|
|
2993
|
+
return /* @__PURE__ */ React10__default.createElement(React10__default.Fragment, null, /* @__PURE__ */ React10__default.createElement(Menu, { shadow: "md", width: 200 }, /* @__PURE__ */ React10__default.createElement(Menu.Target, null, /* @__PURE__ */ React10__default.createElement(ActionIcon, { size: "xs" }, /* @__PURE__ */ React10__default.createElement(IconSettings, null))), /* @__PURE__ */ React10__default.createElement(Menu.Dropdown, null, /* @__PURE__ */ React10__default.createElement(Menu.Label, null, t("params.filter_mode")), /* @__PURE__ */ React10__default.createElement(
|
|
2990
2994
|
Menu.Item,
|
|
2991
2995
|
{
|
|
2992
2996
|
icon: /* @__PURE__ */ React10__default.createElement(IconMathGreater, { size: 14 }),
|
|
@@ -2995,7 +2999,7 @@ function FilterFnsMenu({ filter }) {
|
|
|
2995
2999
|
actions2.updateFilter(buildFilter({ ...filter, ...conditions, active: false }));
|
|
2996
3000
|
}
|
|
2997
3001
|
},
|
|
2998
|
-
"
|
|
3002
|
+
t("comparison.GT")
|
|
2999
3003
|
), /* @__PURE__ */ React10__default.createElement(
|
|
3000
3004
|
Menu.Item,
|
|
3001
3005
|
{
|
|
@@ -3005,7 +3009,7 @@ function FilterFnsMenu({ filter }) {
|
|
|
3005
3009
|
actions2.updateFilter(buildFilter({ ...filter, ...conditions, active: false }));
|
|
3006
3010
|
}
|
|
3007
3011
|
},
|
|
3008
|
-
"
|
|
3012
|
+
t("comparison.LT")
|
|
3009
3013
|
), /* @__PURE__ */ React10__default.createElement(
|
|
3010
3014
|
Menu.Item,
|
|
3011
3015
|
{
|
|
@@ -3015,16 +3019,15 @@ function FilterFnsMenu({ filter }) {
|
|
|
3015
3019
|
actions2.updateFilter(buildFilter({ ...filter, ...conditions, active: false }));
|
|
3016
3020
|
}
|
|
3017
3021
|
},
|
|
3018
|
-
"
|
|
3022
|
+
t("comparison.BT")
|
|
3019
3023
|
))));
|
|
3020
3024
|
}
|
|
3021
3025
|
function MeasuresOptions() {
|
|
3022
|
-
|
|
3023
|
-
|
|
3026
|
+
useSelector$1(selectLocale);
|
|
3027
|
+
useTranslation();
|
|
3024
3028
|
const itemMap = useSelector$1(selectMeasureMap);
|
|
3025
3029
|
const filtersMap = useSelector$1(selectFilterMap);
|
|
3026
3030
|
const filtersItems = useSelector$1(selectFilterItems);
|
|
3027
|
-
useSelector$1(selectOlapMeasureMap);
|
|
3028
3031
|
const measures = useSelector$1(selectOlapMeasureItems);
|
|
3029
3032
|
const actions2 = useActions();
|
|
3030
3033
|
function handlerCreateMeasure(data) {
|
|
@@ -3048,40 +3051,49 @@ function MeasuresOptions() {
|
|
|
3048
3051
|
});
|
|
3049
3052
|
return { measure, filter };
|
|
3050
3053
|
});
|
|
3051
|
-
}, [itemMap, measures, filtersMap, filtersItems
|
|
3054
|
+
}, [itemMap, measures, filtersMap, filtersItems]);
|
|
3052
3055
|
const activeItems = filteredItems.filter((f) => isActiveItem(f.measure));
|
|
3053
3056
|
const options = filteredItems.map(({ measure, filter }) => {
|
|
3054
|
-
|
|
3055
|
-
const text = getFilterfnText(filterFn);
|
|
3056
|
-
const isBetween = filterFn === "between";
|
|
3057
|
-
const checked = activeItems.map((active) => active.measure.name).includes(measure.name);
|
|
3058
|
-
return /* @__PURE__ */ React10__default.createElement(Box, { key: measure.name }, /* @__PURE__ */ React10__default.createElement(Group, { mt: "sm", position: "apart" }, /* @__PURE__ */ React10__default.createElement(
|
|
3059
|
-
Checkbox,
|
|
3060
|
-
{
|
|
3061
|
-
onChange: () => {
|
|
3062
|
-
actions2.updateMeasure({ ...measure, active: !measure.active });
|
|
3063
|
-
actions2.updateFilter({ ...filter, active: checked ? false : true });
|
|
3064
|
-
},
|
|
3065
|
-
checked,
|
|
3066
|
-
label: measure.name
|
|
3067
|
-
}
|
|
3068
|
-
), /* @__PURE__ */ React10__default.createElement(Group, null, /* @__PURE__ */ React10__default.createElement(FilterFnsMenu, { filter }), /* @__PURE__ */ React10__default.createElement(ActionIcon, { size: "xs", onClick: () => setActiveFilter((value) => !value) }, activeFilter ? /* @__PURE__ */ React10__default.createElement(IconFilterOff, null) : /* @__PURE__ */ React10__default.createElement(IconFilter, null)), /* @__PURE__ */ React10__default.createElement(ThemeIcon, { size: "xs", color: "gray", variant: "light", bg: "transparent" }, /* @__PURE__ */ React10__default.createElement(BarsSVG, null)))), activeFilter && /* @__PURE__ */ React10__default.createElement(Box, { pt: "md" }, isBetween ? /* @__PURE__ */ React10__default.createElement(MinMax, { filter }) : /* @__PURE__ */ React10__default.createElement(NumberInputComponent, { text, filter })));
|
|
3057
|
+
return /* @__PURE__ */ React10__default.createElement(FilterItem4, { measure, filter, activeItems });
|
|
3069
3058
|
});
|
|
3070
3059
|
return options;
|
|
3071
3060
|
}
|
|
3061
|
+
function FilterItem4({
|
|
3062
|
+
measure,
|
|
3063
|
+
filter,
|
|
3064
|
+
activeItems
|
|
3065
|
+
}) {
|
|
3066
|
+
const [activeFilter, setActiveFilter] = useState(false);
|
|
3067
|
+
const { translate: t } = useTranslation();
|
|
3068
|
+
const filterFn = getFilterFn(filter);
|
|
3069
|
+
const text = t(`comparison.${getFilterfnKey(filterFn)}`);
|
|
3070
|
+
const isBetween = filterFn === "between";
|
|
3071
|
+
const checked = activeItems.map((active) => active.measure.name).includes(measure.name);
|
|
3072
|
+
const actions2 = useActions();
|
|
3073
|
+
return /* @__PURE__ */ React10__default.createElement(Box, { key: measure.name }, /* @__PURE__ */ React10__default.createElement(Group, { mt: "sm", position: "apart" }, /* @__PURE__ */ React10__default.createElement(
|
|
3074
|
+
Checkbox,
|
|
3075
|
+
{
|
|
3076
|
+
onChange: () => {
|
|
3077
|
+
actions2.updateMeasure({ ...measure, active: !measure.active });
|
|
3078
|
+
actions2.updateFilter({ ...filter, active: checked ? false : true });
|
|
3079
|
+
},
|
|
3080
|
+
checked,
|
|
3081
|
+
label: measure.name,
|
|
3082
|
+
size: "xs"
|
|
3083
|
+
}
|
|
3084
|
+
), /* @__PURE__ */ React10__default.createElement(Group, null, activeFilter && /* @__PURE__ */ React10__default.createElement(FilterFnsMenu, { filter }), /* @__PURE__ */ React10__default.createElement(ActionIcon, { size: "xs", onClick: () => setActiveFilter((value) => !value) }, activeFilter ? /* @__PURE__ */ React10__default.createElement(IconFilterOff, null) : /* @__PURE__ */ React10__default.createElement(IconFilter, null)), /* @__PURE__ */ React10__default.createElement(ThemeIcon, { size: "xs", color: "gray", variant: "light", bg: "transparent" }, /* @__PURE__ */ React10__default.createElement(BarsSVG, null)))), activeFilter && /* @__PURE__ */ React10__default.createElement(Box, { pt: "md" }, isBetween ? /* @__PURE__ */ React10__default.createElement(MinMax, { filter }) : /* @__PURE__ */ React10__default.createElement(NumberInputComponent, { text, filter })));
|
|
3085
|
+
}
|
|
3072
3086
|
var DrawerMenu_default = AddColumnsDrawer;
|
|
3073
3087
|
var removeColumn = (actions2, entity, measures, drilldowns) => {
|
|
3074
3088
|
if (entity._type === "measure") {
|
|
3075
3089
|
if (entity.name) {
|
|
3076
|
-
const measure =
|
|
3090
|
+
const measure = measures.find((d) => d.name === entity.name);
|
|
3077
3091
|
measure && actions2.updateMeasure({ ...measure, active: false });
|
|
3078
|
-
actions2.willRequestQuery();
|
|
3079
3092
|
}
|
|
3080
3093
|
}
|
|
3081
3094
|
if (entity._type === "level") {
|
|
3082
|
-
const drilldown =
|
|
3095
|
+
const drilldown = drilldowns.find((d) => d.uniqueName === (entity == null ? void 0 : entity.uniqueName));
|
|
3083
3096
|
drilldown && actions2.updateDrilldown({ ...drilldown, active: false });
|
|
3084
|
-
actions2.willRequestQuery();
|
|
3085
3097
|
}
|
|
3086
3098
|
};
|
|
3087
3099
|
function showTrashIcon(columns, type) {
|
|
@@ -3105,45 +3117,10 @@ var getEntityText = (entityType) => {
|
|
|
3105
3117
|
return "";
|
|
3106
3118
|
}
|
|
3107
3119
|
};
|
|
3108
|
-
|
|
3109
|
-
switch (entityType) {
|
|
3110
|
-
case "measure":
|
|
3111
|
-
return {
|
|
3112
|
-
columnFilterModeOptions: ["between", "greaterThan", "lessThan"]
|
|
3113
|
-
};
|
|
3114
|
-
case "level":
|
|
3115
|
-
return { columnFilterModeOptions: true };
|
|
3116
|
-
default:
|
|
3117
|
-
return { columnFilterModeOptions: true };
|
|
3118
|
-
}
|
|
3119
|
-
};
|
|
3120
|
-
function getMemberFilterFnTypes(member) {
|
|
3121
|
-
return {
|
|
3122
|
-
value: String(member.key),
|
|
3123
|
-
label: member.caption ? `${member.caption} ${member.key}` : member.name
|
|
3124
|
-
};
|
|
3125
|
-
}
|
|
3126
|
-
function getMantineFilterMultiSelectProps(isId, isNumeric2, range, entity, drilldowns, columnKey, types) {
|
|
3120
|
+
function getMantineFilterMultiSelectProps(isId, isNumeric, range) {
|
|
3127
3121
|
let result = {};
|
|
3128
|
-
const filterVariant = !isId && !
|
|
3122
|
+
const filterVariant = !isId && !isNumeric && (!range || range && range[1] - range[0] <= 100) ? "multi-select" : "text";
|
|
3129
3123
|
result = Object.assign({}, result, { filterVariant });
|
|
3130
|
-
if (result.filterVariant === "multi-select") {
|
|
3131
|
-
if (entity._type === "level") {
|
|
3132
|
-
const dd = Object.keys(drilldowns).reduce(
|
|
3133
|
-
(prev, key) => ({ ...prev, [drilldowns[key].uniqueName]: drilldowns[key] }),
|
|
3134
|
-
{}
|
|
3135
|
-
);
|
|
3136
|
-
const drilldwonData = dd[entity.uniqueName];
|
|
3137
|
-
if (drilldwonData && drilldwonData.members) {
|
|
3138
|
-
result = Object.assign({}, result, {
|
|
3139
|
-
mantineFilterMultiSelectProps: {
|
|
3140
|
-
data: drilldwonData.members.map(getMemberFilterFnTypes),
|
|
3141
|
-
placeholder: columnKey
|
|
3142
|
-
}
|
|
3143
|
-
});
|
|
3144
|
-
}
|
|
3145
|
-
}
|
|
3146
|
-
}
|
|
3147
3124
|
return result;
|
|
3148
3125
|
}
|
|
3149
3126
|
function getSortIcon(value, entityType) {
|
|
@@ -3187,41 +3164,87 @@ function getFiltersConditions(fn, value) {
|
|
|
3187
3164
|
]);
|
|
3188
3165
|
return (_a = comparisonMap.get(fn)) == null ? void 0 : _a(value);
|
|
3189
3166
|
}
|
|
3190
|
-
function useTableData({ offset, limit, columns, filters, cuts }) {
|
|
3167
|
+
function useTableData({ offset, limit, columns, filters, cuts, pagination }) {
|
|
3191
3168
|
const normalizedFilters = filters.map((filter) => ({
|
|
3192
3169
|
id: filter.measure,
|
|
3193
|
-
value: getFilterValue(filter)
|
|
3194
|
-
fn: getFilterFn(filter)
|
|
3170
|
+
value: getFilterValue(filter)
|
|
3171
|
+
// fn: getFilterFn(filter)
|
|
3195
3172
|
}));
|
|
3196
3173
|
const normalizedCuts = cuts.map((cut) => ({ id: cut.uniqueName, members: cut.members }));
|
|
3197
3174
|
const filterKey = JSON.stringify(normalizedFilters);
|
|
3198
3175
|
const cutKey = JSON.stringify(normalizedCuts);
|
|
3199
3176
|
const actions2 = useActions();
|
|
3200
|
-
const
|
|
3201
|
-
const page =
|
|
3177
|
+
const columnsStr = JSON.stringify(columns.sort());
|
|
3178
|
+
const page = pagination.pageIndex;
|
|
3179
|
+
const [filterKeydebouced, setDebouncedTerm] = useState([
|
|
3180
|
+
columnsStr,
|
|
3181
|
+
filterKey,
|
|
3182
|
+
cutKey,
|
|
3183
|
+
page
|
|
3184
|
+
]);
|
|
3202
3185
|
useEffect(() => {
|
|
3203
3186
|
const handler = debounce(() => {
|
|
3204
|
-
const term = [
|
|
3187
|
+
const term = [columnsStr, filterKey, cutKey, page];
|
|
3205
3188
|
setDebouncedTerm(term);
|
|
3206
3189
|
}, 700);
|
|
3207
3190
|
handler();
|
|
3208
|
-
return () =>
|
|
3209
|
-
|
|
3210
|
-
};
|
|
3211
|
-
}, [...columns, offset, filterKey, cutKey, page]);
|
|
3191
|
+
return () => handler.cancel();
|
|
3192
|
+
}, [columnsStr, offset, filterKey, cutKey, page]);
|
|
3212
3193
|
return useQuery({
|
|
3213
3194
|
queryKey: ["table", filterKeydebouced],
|
|
3214
3195
|
queryFn: () => {
|
|
3215
3196
|
return actions2.willExecuteQuery().then((res) => {
|
|
3216
3197
|
const { data, types } = res;
|
|
3217
|
-
|
|
3198
|
+
const { data: tableData, page: page2 } = data;
|
|
3199
|
+
return { data: tableData != null ? tableData : [], types, page: page2 };
|
|
3218
3200
|
});
|
|
3219
3201
|
},
|
|
3220
3202
|
staleTime: 3e5,
|
|
3221
3203
|
enabled: !!filterKeydebouced
|
|
3222
|
-
// placeholderData: keepPreviousData
|
|
3223
3204
|
});
|
|
3224
3205
|
}
|
|
3206
|
+
function usePrefetch({
|
|
3207
|
+
data,
|
|
3208
|
+
isPlaceholderData,
|
|
3209
|
+
limit,
|
|
3210
|
+
offset,
|
|
3211
|
+
totalRowCount,
|
|
3212
|
+
columns,
|
|
3213
|
+
cuts,
|
|
3214
|
+
filters,
|
|
3215
|
+
pagination
|
|
3216
|
+
}) {
|
|
3217
|
+
const queryClient2 = useQueryClient();
|
|
3218
|
+
const actions2 = useActions();
|
|
3219
|
+
const page = pagination.pageIndex + 1;
|
|
3220
|
+
const hasMore = page * pagination.pageSize <= totalRowCount;
|
|
3221
|
+
const off = page * pagination.pageSize;
|
|
3222
|
+
const normalizedFilters = filters.map((filter) => ({
|
|
3223
|
+
id: filter.measure,
|
|
3224
|
+
value: getFilterValue(filter)
|
|
3225
|
+
// fn: getFilterFn(filter)
|
|
3226
|
+
}));
|
|
3227
|
+
const normalizedCuts = cuts.map((cut) => ({ id: cut.uniqueName, members: cut.members }));
|
|
3228
|
+
const filterKey = JSON.stringify(normalizedFilters);
|
|
3229
|
+
const cutKey = JSON.stringify(normalizedCuts);
|
|
3230
|
+
const columnsStr = JSON.stringify(columns.sort());
|
|
3231
|
+
const key = [columnsStr, filterKey, cutKey, page];
|
|
3232
|
+
React10__default.useEffect(() => {
|
|
3233
|
+
if (!isPlaceholderData && hasMore) {
|
|
3234
|
+
queryClient2.prefetchQuery({
|
|
3235
|
+
queryKey: ["table", key],
|
|
3236
|
+
queryFn: () => {
|
|
3237
|
+
return actions2.willExecuteQuery({ offset: off, limit }).then((res) => {
|
|
3238
|
+
const { data: data2, types } = res;
|
|
3239
|
+
const { data: tableData, page: page2 } = data2;
|
|
3240
|
+
return { data: tableData != null ? tableData : [], types, page: page2 };
|
|
3241
|
+
});
|
|
3242
|
+
},
|
|
3243
|
+
staleTime: 3e5
|
|
3244
|
+
});
|
|
3245
|
+
}
|
|
3246
|
+
}, [data, limit, offset, page, isPlaceholderData, key, queryClient2, hasMore, off]);
|
|
3247
|
+
}
|
|
3225
3248
|
function useTable({
|
|
3226
3249
|
cube,
|
|
3227
3250
|
result,
|
|
@@ -3230,24 +3253,12 @@ function useTable({
|
|
|
3230
3253
|
...mantineTableProps
|
|
3231
3254
|
}) {
|
|
3232
3255
|
const { types } = result;
|
|
3233
|
-
const { measures, drilldowns } = useSelector$1(selectCurrentQueryParams);
|
|
3234
3256
|
const filterItems = useSelector$1(selectFilterItems);
|
|
3235
|
-
const
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
}
|
|
3241
|
-
return prev;
|
|
3242
|
-
}, []),
|
|
3243
|
-
...Object.keys(drilldowns).reduce((prev, curr) => {
|
|
3244
|
-
const dd = drilldowns[curr];
|
|
3245
|
-
if (dd.active) {
|
|
3246
|
-
return [...prev, curr];
|
|
3247
|
-
}
|
|
3248
|
-
return prev;
|
|
3249
|
-
}, [])
|
|
3250
|
-
];
|
|
3257
|
+
const filtersMap = useSelector$1(selectFilterMap);
|
|
3258
|
+
const measuresOlap = useSelector$1(selectOlapMeasureItems);
|
|
3259
|
+
const measuresMap = useSelector$1(selectMeasureMap);
|
|
3260
|
+
const drilldowns = useSelector$1(selectDrilldownItems);
|
|
3261
|
+
const measures = useSelector$1(selectMeasureItems);
|
|
3251
3262
|
const actions2 = useActions();
|
|
3252
3263
|
const itemsCuts = useSelector$1(selectCutItems);
|
|
3253
3264
|
const { limit, offset } = useSelector$1(selectPaginationParams);
|
|
@@ -3255,18 +3266,58 @@ function useTable({
|
|
|
3255
3266
|
pageIndex: offset,
|
|
3256
3267
|
pageSize: limit
|
|
3257
3268
|
});
|
|
3269
|
+
const finalUniqueKeys = useMemo(
|
|
3270
|
+
() => [
|
|
3271
|
+
...measures.map((m) => m.active ? m.name : null),
|
|
3272
|
+
...drilldowns.map((d) => d.active ? d.uniqueName : null)
|
|
3273
|
+
].filter((a) => a !== null),
|
|
3274
|
+
[measures, drilldowns]
|
|
3275
|
+
);
|
|
3276
|
+
function handlerCreateMeasure(data2) {
|
|
3277
|
+
const measure = buildMeasure(data2);
|
|
3278
|
+
actions2.updateMeasure(measure);
|
|
3279
|
+
return measure;
|
|
3280
|
+
}
|
|
3281
|
+
function handlerCreateFilter(data2) {
|
|
3282
|
+
const filter = buildFilter(data2);
|
|
3283
|
+
actions2.updateFilter(filter);
|
|
3284
|
+
return filter;
|
|
3285
|
+
}
|
|
3286
|
+
useMemo(() => {
|
|
3287
|
+
return filterMap(measuresOlap, (m) => {
|
|
3288
|
+
const measure = measuresMap[m.name] || handlerCreateMeasure({ ...m, active: false });
|
|
3289
|
+
const foundFilter = filtersMap[m.name] || filterItems.find((f) => f.measure === measure.name);
|
|
3290
|
+
const filter = foundFilter || handlerCreateFilter({
|
|
3291
|
+
measure: measure.name,
|
|
3292
|
+
active: false,
|
|
3293
|
+
key: measure.name
|
|
3294
|
+
});
|
|
3295
|
+
return { measure, filter };
|
|
3296
|
+
});
|
|
3297
|
+
}, [measuresMap, measuresOlap, filtersMap, filterItems]);
|
|
3258
3298
|
const { isLoading, isFetching, isError, data, isPlaceholderData } = useTableData({
|
|
3259
3299
|
offset,
|
|
3260
3300
|
limit,
|
|
3261
3301
|
columns: finalUniqueKeys,
|
|
3262
3302
|
filters: filterItems.filter(isActiveItem),
|
|
3263
|
-
cuts: itemsCuts.filter(isActiveCut)
|
|
3303
|
+
cuts: itemsCuts.filter(isActiveCut),
|
|
3304
|
+
pagination
|
|
3264
3305
|
});
|
|
3265
3306
|
const tableData = (data == null ? void 0 : data.data) || [];
|
|
3266
3307
|
const tableTypes = (data == null ? void 0 : data.types) || types;
|
|
3308
|
+
const totalRowCount = data == null ? void 0 : data.page.total;
|
|
3267
3309
|
const finalKeys = Object.values(tableTypes).filter((t2) => !t2.isId).filter(columnFilter).sort(columnSorting);
|
|
3268
|
-
|
|
3269
|
-
|
|
3310
|
+
usePrefetch({
|
|
3311
|
+
data: tableData,
|
|
3312
|
+
isPlaceholderData,
|
|
3313
|
+
offset,
|
|
3314
|
+
limit,
|
|
3315
|
+
totalRowCount,
|
|
3316
|
+
columns: finalUniqueKeys,
|
|
3317
|
+
filters: filterItems.filter(isActiveItem),
|
|
3318
|
+
cuts: itemsCuts.filter(isActiveCut),
|
|
3319
|
+
pagination
|
|
3320
|
+
});
|
|
3270
3321
|
useEffect(() => {
|
|
3271
3322
|
actions2.updatePagination({
|
|
3272
3323
|
limit: pagination.pageSize,
|
|
@@ -3299,19 +3350,11 @@ function useTable({
|
|
|
3299
3350
|
range,
|
|
3300
3351
|
isId
|
|
3301
3352
|
} = column;
|
|
3302
|
-
const
|
|
3303
|
-
const formatterKey = getFormatterKey(columnKey) || (
|
|
3353
|
+
const isNumeric = valueType === "number" && columnKey !== "Year";
|
|
3354
|
+
const formatterKey = getFormatterKey(columnKey) || (isNumeric ? "Decimal" : "identity");
|
|
3304
3355
|
const formatter = getFormatter(formatterKey);
|
|
3305
|
-
const
|
|
3306
|
-
const mantineFilterVariantObject = getMantineFilterMultiSelectProps(
|
|
3307
|
-
isId,
|
|
3308
|
-
isNumeric2,
|
|
3309
|
-
range,
|
|
3310
|
-
entity,
|
|
3311
|
-
drilldowns,
|
|
3312
|
-
columnKey);
|
|
3356
|
+
const mantineFilterVariantObject = getMantineFilterMultiSelectProps(isId, isNumeric, range);
|
|
3313
3357
|
return {
|
|
3314
|
-
...filterOption,
|
|
3315
3358
|
...mantineFilterVariantObject,
|
|
3316
3359
|
entityType,
|
|
3317
3360
|
header,
|
|
@@ -3335,7 +3378,7 @@ function useTable({
|
|
|
3335
3378
|
onClick: column2.getToggleSortingHandler()
|
|
3336
3379
|
},
|
|
3337
3380
|
getSortIcon(column2.getIsSorted(), entityType)
|
|
3338
|
-
))
|
|
3381
|
+
))), /* @__PURE__ */ React10__default.createElement(
|
|
3339
3382
|
CustomActionIcon_default,
|
|
3340
3383
|
{
|
|
3341
3384
|
label: `At least one ${getEntityText(entityType)} is required.`,
|
|
@@ -3351,10 +3394,10 @@ function useTable({
|
|
|
3351
3394
|
},
|
|
3352
3395
|
formatter,
|
|
3353
3396
|
formatterKey,
|
|
3354
|
-
id: (_a = entity.
|
|
3397
|
+
id: (_a = entity.uniqueName) != null ? _a : entity.name,
|
|
3355
3398
|
dataType: valueType,
|
|
3356
3399
|
accessorFn: (item) => item[columnKey],
|
|
3357
|
-
Cell:
|
|
3400
|
+
Cell: isNumeric ? ({ cell }) => formatter(cell.getValue()) : ({ cell, renderedCellValue, row }) => {
|
|
3358
3401
|
const cellId = row.original[`${cell.column.id} ID`];
|
|
3359
3402
|
return /* @__PURE__ */ React10__default.createElement(Flex, { justify: "space-between", sx: { width: "100%", maxWidth: 400 }, gap: "sm" }, /* @__PURE__ */ React10__default.createElement(
|
|
3360
3403
|
Text,
|
|
@@ -3450,7 +3493,7 @@ function useTable({
|
|
|
3450
3493
|
);
|
|
3451
3494
|
const table = useMantineReactTable({
|
|
3452
3495
|
columns,
|
|
3453
|
-
data:
|
|
3496
|
+
data: tableData,
|
|
3454
3497
|
onPaginationChange: setPagination,
|
|
3455
3498
|
enableHiding: false,
|
|
3456
3499
|
manualFiltering: true,
|
|
@@ -3466,16 +3509,16 @@ function useTable({
|
|
|
3466
3509
|
...constTableProps,
|
|
3467
3510
|
...mantineTableProps
|
|
3468
3511
|
});
|
|
3469
|
-
return { table, isError, isLoading };
|
|
3512
|
+
return { table, isError, isLoading, data: tableData };
|
|
3470
3513
|
}
|
|
3471
|
-
function TableView({ table, result, isError, isLoading }) {
|
|
3514
|
+
function TableView({ table, result, isError, isLoading, data }) {
|
|
3472
3515
|
const isData = Boolean(table.getRowModel().rows.length);
|
|
3473
3516
|
return /* @__PURE__ */ React10__default.createElement(Box, { sx: { height: "100%" } }, /* @__PURE__ */ React10__default.createElement(Flex, { direction: "column", justify: "space-between", sx: { height: "100%", flex: "1 1 auto" } }, /* @__PURE__ */ React10__default.createElement(MRT_ProgressBar, { isTopToolbar: false, table }), /* @__PURE__ */ React10__default.createElement(
|
|
3474
|
-
|
|
3517
|
+
ScrollArea,
|
|
3475
3518
|
{
|
|
3519
|
+
h: isData ? "100%" : "auto",
|
|
3476
3520
|
sx: {
|
|
3477
3521
|
flex: "1 1 auto",
|
|
3478
|
-
height: isData ? "100%" : "auto",
|
|
3479
3522
|
position: "relative",
|
|
3480
3523
|
overflow: "scroll"
|
|
3481
3524
|
}
|
|
@@ -3505,11 +3548,11 @@ function TableView({ table, result, isError, isLoading }) {
|
|
|
3505
3548
|
table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ React10__default.createElement(Box, { component: "tr", key: headerGroup.id, sx: { fontWeight: "normal" } }, headerGroup.headers.map((header) => {
|
|
3506
3549
|
var _a;
|
|
3507
3550
|
const column = table.getColumn(header.id);
|
|
3508
|
-
const
|
|
3551
|
+
const isNumeric = column.columnDef.dataType === "number";
|
|
3509
3552
|
const isRowIndex = column.id === "#";
|
|
3510
3553
|
const base = (theme) => ({
|
|
3511
3554
|
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[7] : theme.colors.gray[0],
|
|
3512
|
-
align:
|
|
3555
|
+
align: isNumeric ? "right" : "left",
|
|
3513
3556
|
height: 60,
|
|
3514
3557
|
paddingBottom: 10,
|
|
3515
3558
|
minWidth: 210,
|
|
@@ -3538,7 +3581,7 @@ function TableView({ table, result, isError, isLoading }) {
|
|
|
3538
3581
|
(_a = header.column.columnDef.Header) != null ? _a : header.column.columnDef.header,
|
|
3539
3582
|
header.getContext()
|
|
3540
3583
|
),
|
|
3541
|
-
!isRowIndex && /* @__PURE__ */ React10__default.createElement(ColumnFilterCell, { isNumeric
|
|
3584
|
+
!isRowIndex && /* @__PURE__ */ React10__default.createElement(ColumnFilterCell, { isNumeric, header, table })
|
|
3542
3585
|
);
|
|
3543
3586
|
})))
|
|
3544
3587
|
),
|
|
@@ -3553,33 +3596,34 @@ function TableView({ table, result, isError, isLoading }) {
|
|
|
3553
3596
|
)))))
|
|
3554
3597
|
),
|
|
3555
3598
|
!isData && !isError && !isLoading && /* @__PURE__ */ React10__default.createElement(NoRecords, null)
|
|
3556
|
-
), /* @__PURE__ */ React10__default.createElement(MRT_ToolbarAlertBanner, { stackAlertBanner: true, table }), /* @__PURE__ */ React10__default.createElement(TableFooter_default, { table, result })));
|
|
3599
|
+
), /* @__PURE__ */ React10__default.createElement(MRT_ToolbarAlertBanner, { stackAlertBanner: true, table }), /* @__PURE__ */ React10__default.createElement(TableFooter_default, { table, data, result })));
|
|
3557
3600
|
}
|
|
3558
3601
|
var ColumnFilterCell = ({
|
|
3559
3602
|
header,
|
|
3560
|
-
|
|
3561
|
-
isNumeric: isNumeric2
|
|
3603
|
+
isNumeric
|
|
3562
3604
|
}) => {
|
|
3563
3605
|
const filterVariant = header.column.columnDef.filterVariant;
|
|
3564
3606
|
const isMulti = filterVariant === "multi-select";
|
|
3565
3607
|
if (isMulti) {
|
|
3566
3608
|
return /* @__PURE__ */ React10__default.createElement(MultiFilter, { header });
|
|
3567
3609
|
}
|
|
3568
|
-
if (
|
|
3610
|
+
if (isNumeric) {
|
|
3569
3611
|
return /* @__PURE__ */ React10__default.createElement(NumericFilter, { header });
|
|
3570
3612
|
}
|
|
3571
3613
|
};
|
|
3572
3614
|
function NumericFilter({ header }) {
|
|
3573
3615
|
const filters = useSelector$1(selectFilterItems);
|
|
3616
|
+
const { translate: t } = useTranslation();
|
|
3574
3617
|
const filter = filters.find((f) => f.measure === header.column.id);
|
|
3575
3618
|
if (filter) {
|
|
3576
3619
|
const filterFn = getFilterFn(filter);
|
|
3577
|
-
const text =
|
|
3620
|
+
const text = t(`comparison.${getFilterfnKey(filterFn)}`);
|
|
3578
3621
|
const isBetween = filterFn === "between";
|
|
3579
3622
|
return /* @__PURE__ */ React10__default.createElement(Flex, { gap: "xs", style: { fontWeight: "normal" } }, /* @__PURE__ */ React10__default.createElement(Box, { sx: { flex: "1 1 auto" } }, isBetween ? /* @__PURE__ */ React10__default.createElement(MinMax, { filter, hideControls: true }) : /* @__PURE__ */ React10__default.createElement(NumberInputComponent, { text, filter })), /* @__PURE__ */ React10__default.createElement(Box, { sx: { alignSelf: "flex-end" } }, /* @__PURE__ */ React10__default.createElement(FilterFnsMenu, { filter })));
|
|
3580
3623
|
}
|
|
3581
3624
|
}
|
|
3582
3625
|
function MultiFilter({ header }) {
|
|
3626
|
+
const { translate: t } = useTranslation();
|
|
3583
3627
|
const cutItems = useSelector$1(selectCutItems);
|
|
3584
3628
|
const drilldownItems = useSelector$1(selectDrilldownItems);
|
|
3585
3629
|
const label = header.column.id;
|
|
@@ -3599,11 +3643,11 @@ function MultiFilter({ header }) {
|
|
|
3599
3643
|
onChange: (value) => {
|
|
3600
3644
|
updatecutHandler({ ...cut, active: true }, value);
|
|
3601
3645
|
},
|
|
3602
|
-
placeholder:
|
|
3646
|
+
placeholder: t("params.filter_by", { name: label }),
|
|
3603
3647
|
value: cut.members || [],
|
|
3604
3648
|
data: drilldown.members.map((m) => ({
|
|
3605
3649
|
value: String(m.key),
|
|
3606
|
-
label: m.caption ? `${m.caption} ${m.key}` : m.name
|
|
3650
|
+
label: m.caption ? `${m.caption} (${m.key})` : m.name
|
|
3607
3651
|
})),
|
|
3608
3652
|
clearButtonProps: { "aria-label": "Clear selection" },
|
|
3609
3653
|
clearable: true,
|
|
@@ -3841,7 +3885,7 @@ function SuccessResult(props) {
|
|
|
3841
3885
|
const { previewLimit, actions: actions2 } = useSettings();
|
|
3842
3886
|
const queryItem = useSelector$1(selectCurrentQueryItem);
|
|
3843
3887
|
const isPreviewMode = useSelector$1(selectIsPreviewMode);
|
|
3844
|
-
const { table, isError, isLoading } = useTable({ cube, result });
|
|
3888
|
+
const { table, isError, isLoading, data } = useTable({ cube, result });
|
|
3845
3889
|
const fullscreen = useFullscreen();
|
|
3846
3890
|
const [CurrentComponent, panelKey, panelMeta] = useMemo(() => {
|
|
3847
3891
|
const currentPanel = queryItem.panel || `${panels[0].key}-`;
|
|
@@ -3873,7 +3917,8 @@ function SuccessResult(props) {
|
|
|
3873
3917
|
result,
|
|
3874
3918
|
table,
|
|
3875
3919
|
isError,
|
|
3876
|
-
isLoading
|
|
3920
|
+
isLoading,
|
|
3921
|
+
data
|
|
3877
3922
|
}
|
|
3878
3923
|
)))))));
|
|
3879
3924
|
}
|
|
@@ -4177,12 +4222,13 @@ function SideBar(props) {
|
|
|
4177
4222
|
id: "dex-sidebar",
|
|
4178
4223
|
py: "md",
|
|
4179
4224
|
sx: (t2) => ({
|
|
4180
|
-
height: "calc(100vh -
|
|
4225
|
+
height: "calc(100vh - 50px)",
|
|
4181
4226
|
backgroundColor: t2.colorScheme === "dark" ? t2.colors.dark[8] : t2.colors.gray[1],
|
|
4182
4227
|
boxShadow: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)",
|
|
4183
4228
|
maxWidth: expanded ? 300 : 54,
|
|
4184
4229
|
padding: 0,
|
|
4185
4230
|
zIndex: 99,
|
|
4231
|
+
boxSizing: "border-box",
|
|
4186
4232
|
[t2.fn.smallerThan("md")]: {
|
|
4187
4233
|
position: "absolute",
|
|
4188
4234
|
width: expanded ? 300 : 54,
|
|
@@ -4333,10 +4379,49 @@ init_esm_shims();
|
|
|
4333
4379
|
|
|
4334
4380
|
// src/components/Results.tsx
|
|
4335
4381
|
init_esm_shims();
|
|
4382
|
+
|
|
4383
|
+
// src/hooks/useSelectCube.tsx
|
|
4384
|
+
init_esm_shims();
|
|
4385
|
+
function useSelectCube(onSelectCube) {
|
|
4386
|
+
const { updateMeasure, updateCut, updateDrilldown, willFetchMembers: willFetchMembers2 } = useActions();
|
|
4387
|
+
const createCutHandler2 = React10__default.useCallback((level) => {
|
|
4388
|
+
const cutItem = buildCut({ ...level });
|
|
4389
|
+
cutItem.active = false;
|
|
4390
|
+
updateCut(cutItem);
|
|
4391
|
+
}, []);
|
|
4392
|
+
const addDrilldown = useCallback((level, dimensions) => {
|
|
4393
|
+
const drilldownItem = buildDrilldown(level);
|
|
4394
|
+
createCutHandler2(level);
|
|
4395
|
+
updateDrilldown(drilldownItem);
|
|
4396
|
+
return willFetchMembers2({ ...level, level: level.name }).then((members) => {
|
|
4397
|
+
const dimension = dimensions.find((dim) => dim.name === level.dimension);
|
|
4398
|
+
if (!dimension) return;
|
|
4399
|
+
return updateDrilldown({
|
|
4400
|
+
...drilldownItem,
|
|
4401
|
+
dimType: dimension.dimensionType,
|
|
4402
|
+
memberCount: members.length,
|
|
4403
|
+
members
|
|
4404
|
+
});
|
|
4405
|
+
});
|
|
4406
|
+
}, []);
|
|
4407
|
+
return (item, subtopic) => () => onSelectCube(item, subtopic).then(({ cube, measures, dimensions }) => {
|
|
4408
|
+
const [measure] = Object.values(measures);
|
|
4409
|
+
const drilldowns = deriveDrilldowns(dimensions);
|
|
4410
|
+
if (measure && drilldowns.length > 0) {
|
|
4411
|
+
updateMeasure({ ...measure, active: true });
|
|
4412
|
+
for (const level of drilldowns) {
|
|
4413
|
+
addDrilldown(level, dimensions);
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
});
|
|
4417
|
+
}
|
|
4418
|
+
|
|
4419
|
+
// src/components/Results.tsx
|
|
4336
4420
|
function Results(props) {
|
|
4337
4421
|
const { onSelectCube, graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2 } = props;
|
|
4338
4422
|
const { classes } = useStyles3();
|
|
4339
4423
|
const { setExpanded, setInput, map } = useSideBar();
|
|
4424
|
+
const callback = useSelectCube(onSelectCube);
|
|
4340
4425
|
const result = [];
|
|
4341
4426
|
if (map) {
|
|
4342
4427
|
for (let [key, items] of map) {
|
|
@@ -4351,7 +4436,7 @@ function Results(props) {
|
|
|
4351
4436
|
fz: "xs",
|
|
4352
4437
|
className: isSelected2(selectedItem, cube) ? `${classes.link} ${classes.linkActive}` : classes.link,
|
|
4353
4438
|
onClick: () => {
|
|
4354
|
-
|
|
4439
|
+
callback(item, subtopic)();
|
|
4355
4440
|
setExpanded(false);
|
|
4356
4441
|
setInput("");
|
|
4357
4442
|
}
|
|
@@ -4604,28 +4689,8 @@ function CubeButton({
|
|
|
4604
4689
|
locale,
|
|
4605
4690
|
parent
|
|
4606
4691
|
}) {
|
|
4607
|
-
const
|
|
4692
|
+
const callback = useSelectCube(onSelectCube);
|
|
4608
4693
|
const { classes } = useStyles3();
|
|
4609
|
-
const createCutHandler2 = React10__default.useCallback((level) => {
|
|
4610
|
-
const cutItem = buildCut({ ...level });
|
|
4611
|
-
cutItem.active = false;
|
|
4612
|
-
updateCut(cutItem);
|
|
4613
|
-
}, []);
|
|
4614
|
-
const addDrilldown = useCallback((level, dimensions) => {
|
|
4615
|
-
const drilldownItem = buildDrilldown(level);
|
|
4616
|
-
createCutHandler2(level);
|
|
4617
|
-
updateDrilldown(drilldownItem);
|
|
4618
|
-
return willFetchMembers2({ ...level, level: level.name }).then((members) => {
|
|
4619
|
-
const dimension = dimensions.find((dim) => dim.name === level.dimension);
|
|
4620
|
-
if (!dimension) return;
|
|
4621
|
-
return updateDrilldown({
|
|
4622
|
-
...drilldownItem,
|
|
4623
|
-
dimType: dimension.dimensionType,
|
|
4624
|
-
memberCount: members.length,
|
|
4625
|
-
members
|
|
4626
|
-
});
|
|
4627
|
-
});
|
|
4628
|
-
}, []);
|
|
4629
4694
|
const table = item;
|
|
4630
4695
|
const subtopic = parent != null ? parent : "";
|
|
4631
4696
|
return /* @__PURE__ */ React10__default.createElement(
|
|
@@ -4642,18 +4707,7 @@ function CubeButton({
|
|
|
4642
4707
|
background: isSelected(selectedItem, getCube(graph.items, table, subtopic, locale)) ? t.fn.primaryColor() : t.colorScheme === "dark" ? t.colors.dark[6] : t.colors.gray[3],
|
|
4643
4708
|
overflow: "hidden"
|
|
4644
4709
|
}),
|
|
4645
|
-
onClick: ()
|
|
4646
|
-
onSelectCube(item, subtopic).then(({ cube, measures, dimensions }) => {
|
|
4647
|
-
const [measure] = Object.values(measures);
|
|
4648
|
-
const drilldowns = deriveDrilldowns(dimensions);
|
|
4649
|
-
if (measure && drilldowns.length > 0) {
|
|
4650
|
-
updateMeasure({ ...measure, active: true });
|
|
4651
|
-
for (const level of drilldowns) {
|
|
4652
|
-
addDrilldown(level, dimensions);
|
|
4653
|
-
}
|
|
4654
|
-
}
|
|
4655
|
-
});
|
|
4656
|
-
}
|
|
4710
|
+
onClick: callback(item, subtopic)
|
|
4657
4711
|
},
|
|
4658
4712
|
item
|
|
4659
4713
|
);
|
|
@@ -4765,7 +4819,7 @@ function ExplorerContent(props) {
|
|
|
4765
4819
|
const SplashComponent = props.splash;
|
|
4766
4820
|
return SplashComponent ? /* @__PURE__ */ React10__default.createElement(SplashComponent, { translation }) : /* @__PURE__ */ React10__default.createElement(Center, { h: "100%", sx: { flex: 1 } }, /* @__PURE__ */ React10__default.createElement(AnimatedCube, null));
|
|
4767
4821
|
}, [props.splash]);
|
|
4768
|
-
return /* @__PURE__ */ React10__default.createElement("div", { className: classes.container }, /* @__PURE__ */ React10__default.createElement(
|
|
4822
|
+
return /* @__PURE__ */ React10__default.createElement("div", { className: classes.container }, /* @__PURE__ */ React10__default.createElement("div", { className: classes.root }, /* @__PURE__ */ React10__default.createElement(AppProviders, null, /* @__PURE__ */ React10__default.createElement(SideBarProvider, null, /* @__PURE__ */ React10__default.createElement(SideBar_default, null, /* @__PURE__ */ React10__default.createElement(SideBarItem, null, /* @__PURE__ */ React10__default.createElement(ParamsExplorer_default, null)))), /* @__PURE__ */ React10__default.createElement(ExplorerResults, { className: classes.flexCol, panels: props.panels, splash }))));
|
|
4769
4823
|
}
|
|
4770
4824
|
|
|
4771
4825
|
// src/components/PivotView.tsx
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datawheel/data-explorer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"import": "./dist/main.js"
|
|
@@ -37,6 +37,8 @@
|
|
|
37
37
|
"postcss-modules": "^6.0.0",
|
|
38
38
|
"react-redux": "^7.0.0",
|
|
39
39
|
"react-viewport-list": "^3.0.0",
|
|
40
|
+
"stylis": "^4.3.4",
|
|
41
|
+
"stylis-plugin-rtl": "^2.1.1",
|
|
40
42
|
"yn": "^5.0.0"
|
|
41
43
|
},
|
|
42
44
|
"peerDependencies": {
|