@datawheel/data-explorer 1.1.10 → 1.1.12

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.
Files changed (2) hide show
  1. package/dist/main.mjs +569 -413
  2. package/package.json +1 -1
package/dist/main.mjs CHANGED
@@ -1,6 +1,6 @@
1
- import { keyframes, createStyles, Select, Center, Text, rem, Input, Box, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay, Table, MultiSelect, NumberInput, Menu, ActionIcon, UnstyledButton, Loader, Container, Title, useMantineTheme, TextInput, CopyButton, Alert, MantineProvider, Modal, Space, useComponentDefaultProps, Paper, Anchor, Skeleton, Accordion, Tooltip, Tabs, Switch, ThemeIcon, CloseButton, Divider, Drawer, Checkbox, packSx, Affix, Popover } from '@mantine/core';
2
- import { useClipboard, useFullscreen, useDebouncedState, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
- import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconBox, IconArrowRight, IconArrowLeft, IconBrandGithub, IconCheck, IconShare, IconLanguage, IconTrash, IconInfoCircleFilled, IconChevronLeft, IconChevronRight, IconSearch, IconArrowsMinimize, IconArrowsMaximize, IconCircleOff, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconAdjustments, IconClock, IconHelpCircle, IconPhotoDown, IconVectorTriangle } from '@tabler/icons-react';
1
+ import { keyframes, createStyles, Select, Center, Text, rem, Input, Box, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay, Table, MultiSelect, NumberInput, Menu, ActionIcon, UnstyledButton, Loader, Container, Title, useMantineTheme, TextInput, CopyButton, Alert, MantineProvider, Modal, Space, useComponentDefaultProps, Paper, Anchor, Skeleton, Accordion, Tooltip, Tabs, Switch, ThemeIcon, CloseButton, packSx, Divider, Drawer, Checkbox, Popover } from '@mantine/core';
2
+ import { useClipboard, useDebouncedState, useFullscreen, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
+ import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconBox, IconArrowRight, IconArrowLeft, IconBrandGithub, IconCheck, IconShare, IconLanguage, IconTrash, IconInfoCircleFilled, IconX, IconChevronLeft, IconChevronRight, IconSearch, IconArrowsMinimize, IconArrowsMaximize, IconCircleOff, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconAdjustments, IconClock, IconHelpCircle, IconPhotoDown, IconVectorTriangle } from '@tabler/icons-react';
4
4
  import * as React13 from 'react';
5
5
  import React13__default, { createContext, forwardRef, useMemo, useCallback, useContext, useRef, useEffect, useState, Suspense, Component, useLayoutEffect } from 'react';
6
6
  import { translationFactory } from '@datawheel/use-translation';
@@ -2238,7 +2238,7 @@ var localeSelectorStyle = (theme) => ({
2238
2238
  color: theme.colorScheme === "dark" ? theme.fn.lighten(theme.fn.primaryColor(), 0.7) : theme.fn.primaryColor(),
2239
2239
  fontSize: 12,
2240
2240
  fontWeight: 700,
2241
- width: 94,
2241
+ width: 84,
2242
2242
  textTransform: "uppercase"
2243
2243
  },
2244
2244
  item: {
@@ -2297,6 +2297,7 @@ function LocaleSelector() {
2297
2297
  onItemSelect: localeChangeHandler,
2298
2298
  selectedItem: currentCode,
2299
2299
  selectProps: {
2300
+ size: "xs",
2300
2301
  styles: localeSelectorStyle,
2301
2302
  icon: /* @__PURE__ */ React13__default.createElement(
2302
2303
  IconLanguage,
@@ -2351,38 +2352,80 @@ function TableFooter(props) {
2351
2352
  },
2352
2353
  [pagination]
2353
2354
  );
2354
- return /* @__PURE__ */ React13__default.createElement(Box, { w: "100%", sx: { flex: "0 0 70px" } }, /* @__PURE__ */ React13__default.createElement(
2355
- Flex,
2355
+ return /* @__PURE__ */ React13__default.createElement(
2356
+ Box,
2356
2357
  {
2357
- p: "md",
2358
- justify: "space-between",
2359
- align: "center",
2360
- direction: { base: "column-reverse", md: "row" },
2361
- gap: "sm"
2358
+ w: "100%",
2359
+ sx: (t2) => ({
2360
+ flex: "0 0 70px",
2361
+ maxWidth: "100vw",
2362
+ [t2.fn.smallerThan("md")]: {
2363
+ flex: "0 0 180px"
2364
+ },
2365
+ [t2.fn.smallerThan("xs")]: {
2366
+ flex: "0 0 200px"
2367
+ },
2368
+ [t2.fn.smallerThan(345)]: {
2369
+ flex: "0 0 240px"
2370
+ }
2371
+ })
2362
2372
  },
2363
- /* @__PURE__ */ React13__default.createElement(CubeSource, null),
2364
- !isLoading && /* @__PURE__ */ React13__default.createElement(Group, { position: "right", spacing: "sm" }, /* @__PURE__ */ React13__default.createElement(LocaleSelector, null), /* @__PURE__ */ React13__default.createElement(Box, { maw: "7rem", miw: "fit" }, /* @__PURE__ */ React13__default.createElement(
2365
- Select,
2373
+ /* @__PURE__ */ React13__default.createElement(
2374
+ Flex,
2366
2375
  {
2367
- data: items,
2368
- defaultValue: String(queryItem.params.pagiLimit),
2369
- onChange: (value) => {
2370
- const item = items.find((i) => i.value === value);
2371
- if (item) onItemSelect(item);
2372
- }
2373
- }
2374
- )), totalRowCount && /* @__PURE__ */ React13__default.createElement(Text, { c: "dimmed" }, t("results.count_rows_plural", { n: formatter.format(totalRowCount) })), showPagination && /* @__PURE__ */ React13__default.createElement(MRT_TablePagination, { table }), /* @__PURE__ */ React13__default.createElement(ApiAndCsvButtons, { copied, copyHandler, url, data }))
2375
- ));
2376
+ id: "dex-table-footer",
2377
+ px: "sm",
2378
+ pt: { base: 0, xs: "sm" },
2379
+ justify: "space-between",
2380
+ align: "flex-start",
2381
+ direction: { base: "column-reverse", xs: "row" },
2382
+ gap: "xs"
2383
+ },
2384
+ /* @__PURE__ */ React13__default.createElement(CubeSource, null),
2385
+ !isLoading && /* @__PURE__ */ React13__default.createElement(
2386
+ Flex,
2387
+ {
2388
+ justify: { base: "space-between", md: "flex-end" },
2389
+ gap: "xs",
2390
+ w: "100%",
2391
+ direction: { base: "column", md: "row" },
2392
+ align: { base: "flex-end", md: "flex-start", lg: "center" }
2393
+ },
2394
+ /* @__PURE__ */ React13__default.createElement(Box, { display: { base: "none", md: "block" } }, /* @__PURE__ */ React13__default.createElement(LocaleSelector, null)),
2395
+ /* @__PURE__ */ React13__default.createElement(Flex, { align: "center", direction: { base: "column", lg: "row" }, gap: "xs" }, /* @__PURE__ */ React13__default.createElement(Group, { display: { base: "none", md: "flex" }, noWrap: true }, /* @__PURE__ */ React13__default.createElement(Box, { maw: "7rem", miw: "fit", display: { base: "none", md: "block" } }, /* @__PURE__ */ React13__default.createElement(
2396
+ Select,
2397
+ {
2398
+ data: items,
2399
+ defaultValue: String(queryItem.params.pagiLimit),
2400
+ size: "xs",
2401
+ onChange: (value) => {
2402
+ const item = items.find((i) => i.value === value);
2403
+ if (item) onItemSelect(item);
2404
+ }
2405
+ }
2406
+ )), totalRowCount && /* @__PURE__ */ React13__default.createElement(
2407
+ Text,
2408
+ {
2409
+ c: "dimmed",
2410
+ display: { base: "none", md: "block" },
2411
+ sx: { whiteSpace: "nowrap" }
2412
+ },
2413
+ t("results.count_rows_plural", { n: formatter.format(totalRowCount) })
2414
+ )), showPagination && /* @__PURE__ */ React13__default.createElement(MRT_TablePagination, { table })),
2415
+ /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", position: "right" }, /* @__PURE__ */ React13__default.createElement(Box, { display: { base: "block", md: "none" } }, /* @__PURE__ */ React13__default.createElement(LocaleSelector, null)), /* @__PURE__ */ React13__default.createElement(ApiAndCsvButtons, { copied, copyHandler, url, data }))
2416
+ )
2417
+ )
2418
+ );
2376
2419
  }
2377
2420
  var ApiAndCsvButtons = (props) => {
2378
2421
  const { copied, copyHandler, url, data } = props;
2379
2422
  const { translate: t } = useTranslation();
2380
- return /* @__PURE__ */ React13__default.createElement(Box, { id: "query-results-debug-view" }, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs" }, url && /* @__PURE__ */ React13__default.createElement(
2423
+ return /* @__PURE__ */ React13__default.createElement(Box, { id: "query-results-debug-view" }, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, url && /* @__PURE__ */ React13__default.createElement(
2381
2424
  Button,
2382
2425
  {
2383
2426
  id: "dex-api-btn",
2384
2427
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconCopy, { size: 20 }),
2385
- sx: { height: 30 },
2428
+ sx: { height: 28 },
2386
2429
  onClick: copyHandler
2387
2430
  },
2388
2431
  copied ? t("action_copy_done") : t("action_copy"),
@@ -2435,7 +2478,7 @@ var DownloadQuery = ({ data }) => {
2435
2478
  ButtonDownload,
2436
2479
  {
2437
2480
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconDownload, { size: 20 }),
2438
- sx: { height: 30, position: "relative" },
2481
+ sx: { height: 28, position: "relative" },
2439
2482
  key: "download_csv",
2440
2483
  provider: () => downloadQuery({ format: "csv" })
2441
2484
  },
@@ -2445,7 +2488,7 @@ var DownloadQuery = ({ data }) => {
2445
2488
  if (components.length === 0 || data.length === 0) {
2446
2489
  return null;
2447
2490
  }
2448
- return /* @__PURE__ */ React13__default.createElement(Box, { id: "dex-btn-group-download", sx: { position: "relative" } }, errorAlert, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs" }, components, /* @__PURE__ */ React13__default.createElement(MenuOpts, { formats: formats.filter((f) => f !== "csv") })));
2491
+ return /* @__PURE__ */ React13__default.createElement(Box, { id: "dex-btn-group-download", sx: { position: "relative" } }, errorAlert, /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, components, /* @__PURE__ */ React13__default.createElement(MenuOpts, { formats: formats.filter((f) => f !== "csv") })));
2449
2492
  };
2450
2493
  var mimeTypes = {
2451
2494
  csv: "text/csv",
@@ -2626,42 +2669,52 @@ function BarsSVG() {
2626
2669
  );
2627
2670
  }
2628
2671
  function FullScreenSVG() {
2629
- return /* @__PURE__ */ React13__default.createElement("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", xmlns: "http://www.w3.org/2000/svg", strokeWidth: 1.5 }, /* @__PURE__ */ React13__default.createElement("g", { clipPath: "url(#clip0_905_15763)" }, /* @__PURE__ */ React13__default.createElement(
2630
- "path",
2631
- {
2632
- d: "M3.33325 6.66668V5.00001C3.33325 4.55798 3.50885 4.13406 3.82141 3.8215C4.13397 3.50894 4.55789 3.33334 4.99992 3.33334H6.66659",
2633
- stroke: "black",
2634
- strokeLinecap: "round",
2635
- strokeLinejoin: "round"
2636
- }
2637
- ), /* @__PURE__ */ React13__default.createElement(
2638
- "path",
2639
- {
2640
- d: "M3.33325 13.3333V15C3.33325 15.442 3.50885 15.866 3.82141 16.1785C4.13397 16.4911 4.55789 16.6667 4.99992 16.6667H6.66659",
2641
- stroke: "black",
2642
- strokeLinecap: "round",
2643
- strokeLinejoin: "round"
2644
- }
2645
- ), /* @__PURE__ */ React13__default.createElement(
2646
- "path",
2647
- {
2648
- d: "M13.3333 3.33334H14.9999C15.4419 3.33334 15.8659 3.50894 16.1784 3.8215C16.491 4.13406 16.6666 4.55798 16.6666 5.00001V6.66668",
2649
- stroke: "black",
2650
- strokeLinecap: "round",
2651
- strokeLinejoin: "round"
2652
- }
2653
- ), /* @__PURE__ */ React13__default.createElement(
2654
- "path",
2672
+ return /* @__PURE__ */ React13__default.createElement(
2673
+ "svg",
2655
2674
  {
2656
- d: "M13.3333 16.6667H14.9999C15.4419 16.6667 15.8659 16.4911 16.1784 16.1785C16.491 15.866 16.6666 15.442 16.6666 15V13.3333",
2657
- stroke: "black",
2658
- strokeLinecap: "round",
2659
- strokeLinejoin: "round"
2660
- }
2661
- )), /* @__PURE__ */ React13__default.createElement("defs", null, /* @__PURE__ */ React13__default.createElement("clipPath", { id: "clip0_905_15763" }, /* @__PURE__ */ React13__default.createElement("rect", { width: "20", height: "20", fill: "white" }))));
2675
+ width: "20",
2676
+ height: "20",
2677
+ viewBox: "0 0 20 20",
2678
+ fill: "none",
2679
+ xmlns: "http://www.w3.org/2000/svg",
2680
+ strokeWidth: 1.5
2681
+ },
2682
+ /* @__PURE__ */ React13__default.createElement("g", { clipPath: "url(#clip0_905_15763)" }, /* @__PURE__ */ React13__default.createElement(
2683
+ "path",
2684
+ {
2685
+ d: "M3.33325 6.66668V5.00001C3.33325 4.55798 3.50885 4.13406 3.82141 3.8215C4.13397 3.50894 4.55789 3.33334 4.99992 3.33334H6.66659",
2686
+ stroke: "black",
2687
+ strokeLinecap: "round",
2688
+ strokeLinejoin: "round"
2689
+ }
2690
+ ), /* @__PURE__ */ React13__default.createElement(
2691
+ "path",
2692
+ {
2693
+ d: "M3.33325 13.3333V15C3.33325 15.442 3.50885 15.866 3.82141 16.1785C4.13397 16.4911 4.55789 16.6667 4.99992 16.6667H6.66659",
2694
+ stroke: "black",
2695
+ strokeLinecap: "round",
2696
+ strokeLinejoin: "round"
2697
+ }
2698
+ ), /* @__PURE__ */ React13__default.createElement(
2699
+ "path",
2700
+ {
2701
+ d: "M13.3333 3.33334H14.9999C15.4419 3.33334 15.8659 3.50894 16.1784 3.8215C16.491 4.13406 16.6666 4.55798 16.6666 5.00001V6.66668",
2702
+ stroke: "black",
2703
+ strokeLinecap: "round",
2704
+ strokeLinejoin: "round"
2705
+ }
2706
+ ), /* @__PURE__ */ React13__default.createElement(
2707
+ "path",
2708
+ {
2709
+ d: "M13.3333 16.6667H14.9999C15.4419 16.6667 15.8659 16.4911 16.1784 16.1785C16.491 15.866 16.6666 15.442 16.6666 15V13.3333",
2710
+ stroke: "black",
2711
+ strokeLinecap: "round",
2712
+ strokeLinejoin: "round"
2713
+ }
2714
+ )),
2715
+ /* @__PURE__ */ React13__default.createElement("defs", null, /* @__PURE__ */ React13__default.createElement("clipPath", { id: "clip0_905_15763" }, /* @__PURE__ */ React13__default.createElement("rect", { width: "20", height: "20", fill: "white" })))
2716
+ );
2662
2717
  }
2663
-
2664
- // src/components/TableView.tsx
2665
2718
  function isColumnSorted(column, key) {
2666
2719
  return column == key;
2667
2720
  }
@@ -2891,6 +2944,10 @@ function useTable({
2891
2944
  const { getFormat, getFormatter } = useFormatter();
2892
2945
  const { idFormatters } = useidFormatters();
2893
2946
  const { sortKey, sortDir } = useSelector$1(selectSortingParams);
2947
+ const theme = useMantineTheme();
2948
+ const isSmallerThanMd = useMediaQuery(
2949
+ `(max-width: ${theme.breakpoints.md}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
2950
+ );
2894
2951
  const columns = useMemo(() => {
2895
2952
  const indexColumn = {
2896
2953
  id: "#",
@@ -2938,7 +2995,10 @@ function useTable({
2938
2995
  },
2939
2996
  Header: ({ column: column2 }) => {
2940
2997
  const isSorted = isColumnSorted(entity.name, sortKey);
2941
- return /* @__PURE__ */ React13__default.createElement(Box, { mb: rem(5), key: "header" }, /* @__PURE__ */ React13__default.createElement(Flex, { justify: "center", align: "center" }, /* @__PURE__ */ React13__default.createElement(Box, { sx: { flexGrow: 1 } }, /* @__PURE__ */ React13__default.createElement(Flex, { gap: "xs", align: "center" }, getActionIcon(entityType), /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, header), /* @__PURE__ */ React13__default.createElement(
2998
+ const isMobile = useMediaQuery(
2999
+ `(max-width: ${theme.breakpoints.sm}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
3000
+ );
3001
+ const actionSort = /* @__PURE__ */ React13__default.createElement(
2942
3002
  ActionIcon,
2943
3003
  {
2944
3004
  key: `sort-${header}`,
@@ -2983,29 +3043,39 @@ function useTable({
2983
3043
  }
2984
3044
  },
2985
3045
  getSortIcon(isSorted ? sortDir : false, entityType)
2986
- ))), showTrashIcon(finalKeys, entityType) && /* @__PURE__ */ React13__default.createElement(
2987
- CustomActionIcon_default,
3046
+ );
3047
+ return /* @__PURE__ */ React13__default.createElement(Box, { mb: rem(5), key: "header" }, /* @__PURE__ */ React13__default.createElement(
3048
+ Flex,
2988
3049
  {
2989
- label: `At least one ${getEntityText(entityType)} is required.`,
2990
- key: `remove-${column2.columnDef.header}`,
2991
- disabled: !showTrashIcon(finalKeys, entityType) || isLoading || isFetching,
2992
- onClick: () => {
2993
- removeColumn(
2994
- actions2,
2995
- entity,
2996
- measures,
2997
- drilldowns,
2998
- entityType,
2999
- queryItem,
3000
- updateURL
3001
- );
3002
- },
3003
- showTooltip: !showTrashIcon(finalKeys, entityType),
3004
- size: 25,
3005
- ml: rem(5)
3050
+ justify: "center",
3051
+ align: { base: "flex-start", sm: "center" },
3052
+ direction: { base: "column", sm: "row" }
3006
3053
  },
3007
- /* @__PURE__ */ React13__default.createElement(IconTrash, null)
3008
- )));
3054
+ /* @__PURE__ */ React13__default.createElement(Box, { sx: { flexGrow: 1 }, w: { base: "100%", sm: "auto" } }, /* @__PURE__ */ React13__default.createElement(Flex, { gap: { base: 0, sm: "xs" }, align: "center" }, getActionIcon(entityType), /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, header), !isMobile && actionSort)),
3055
+ /* @__PURE__ */ React13__default.createElement(Group, { position: "apart", w: "100%" }, isMobile && actionSort, showTrashIcon(finalKeys, entityType) && /* @__PURE__ */ React13__default.createElement(
3056
+ CustomActionIcon_default,
3057
+ {
3058
+ label: `At least one ${getEntityText(entityType)} is required.`,
3059
+ key: `remove-${column2.columnDef.header}`,
3060
+ disabled: !showTrashIcon(finalKeys, entityType) || isLoading || isFetching,
3061
+ onClick: () => {
3062
+ removeColumn(
3063
+ actions2,
3064
+ entity,
3065
+ measures,
3066
+ drilldowns,
3067
+ entityType,
3068
+ queryItem,
3069
+ updateURL
3070
+ );
3071
+ },
3072
+ showTooltip: !showTrashIcon(finalKeys, entityType),
3073
+ size: 25,
3074
+ ml: rem(5)
3075
+ },
3076
+ /* @__PURE__ */ React13__default.createElement(IconTrash, null)
3077
+ ))
3078
+ ));
3009
3079
  },
3010
3080
  formatter: formatter2,
3011
3081
  formatterKey,
@@ -3013,7 +3083,9 @@ function useTable({
3013
3083
  dataType: valueType,
3014
3084
  Cell: isNumeric ? ({ cell }) => {
3015
3085
  return /* @__PURE__ */ React13__default.createElement("span", { style: { display: "block", textAlign: "right" } }, formatter2(cell.getValue(), locale));
3016
- } : ({ cell, renderedCellValue, row }) => {
3086
+ } : ({ cell }) => {
3087
+ const cellValue = cell.getValue();
3088
+ const row = cell.row;
3017
3089
  const cellId = row.original[`${cell.column.id} ID`];
3018
3090
  const idFormatter = idFormatters[`${column.localeLabel} ID`];
3019
3091
  return /* @__PURE__ */ React13__default.createElement(Flex, { justify: "space-between", sx: { width: "100%", maxWidth: 400 }, gap: "sm" }, /* @__PURE__ */ React13__default.createElement(
@@ -3026,7 +3098,7 @@ function useTable({
3026
3098
  textOverflow: "ellipsis"
3027
3099
  }
3028
3100
  },
3029
- renderedCellValue
3101
+ cellValue
3030
3102
  ), /* @__PURE__ */ React13__default.createElement(Box, null, cellId && /* @__PURE__ */ React13__default.createElement(Text, { color: "dimmed" }, idFormatter ? idFormatter(cellId) : cellId)));
3031
3103
  }
3032
3104
  };
@@ -3045,9 +3117,10 @@ function useTable({
3045
3117
  enableFilterMatchHighlighting: true,
3046
3118
  enableGlobalFilter: true,
3047
3119
  mantinePaginationProps: {
3120
+ rowsPerPageOptions: ["10", "25", "50", "100"],
3048
3121
  showRowsPerPage: false
3049
3122
  },
3050
- paginationDisplayMode: "pages",
3123
+ paginationDisplayMode: isSmallerThanMd ? "default" : "pages",
3051
3124
  globalFilterFn: "contains",
3052
3125
  initialState: {
3053
3126
  density: "xs"
@@ -3067,12 +3140,12 @@ function useTable({
3067
3140
  mantinePaperProps: {
3068
3141
  id: "query-results-table-view",
3069
3142
  withBorder: false,
3070
- sx: (theme) => ({
3143
+ sx: (theme2) => ({
3071
3144
  height: "100%",
3072
3145
  display: "flex",
3073
3146
  flexFlow: "column nowrap",
3074
- padding: `0 ${theme.spacing.sm}`,
3075
- [theme.fn.largerThan("md")]: {
3147
+ padding: `0 ${theme2.spacing.sm}`,
3148
+ [theme2.fn.largerThan("md")]: {
3076
3149
  padding: 0
3077
3150
  }
3078
3151
  })
@@ -3105,7 +3178,7 @@ function useTable({
3105
3178
  );
3106
3179
  }
3107
3180
  }),
3108
- [isError, t]
3181
+ [isError, t, isSmallerThanMd]
3109
3182
  );
3110
3183
  const table = useMantineReactTable({
3111
3184
  columns,
@@ -3179,11 +3252,14 @@ function TableView({
3179
3252
  verticalSpacing: "xs",
3180
3253
  withBorder: true,
3181
3254
  withColumnBorders: true,
3182
- sx: {
3255
+ sx: (t) => ({
3183
3256
  "thead > tr > th": {
3184
- padding: "0.5rem 1rem"
3257
+ padding: "0.5rem 1rem",
3258
+ [t.fn.smallerThan("sm")]: {
3259
+ padding: "0.25rem 0.6rem"
3260
+ }
3185
3261
  }
3186
- }
3262
+ })
3187
3263
  },
3188
3264
  /* @__PURE__ */ React13__default.createElement(
3189
3265
  Box,
@@ -3209,14 +3285,22 @@ function TableView({
3209
3285
  position: "sticky",
3210
3286
  fontSize: theme.fontSizes.sm,
3211
3287
  top: 0,
3212
- display: "table-cell"
3288
+ display: "table-cell",
3289
+ [theme.fn.smallerThan("sm")]: {
3290
+ minWidth: 180,
3291
+ width: 180
3292
+ }
3213
3293
  });
3214
3294
  const index = (theme) => ({
3215
3295
  ...base(theme),
3216
3296
  minWidth: 10,
3217
3297
  width: 10,
3218
3298
  maxWidth: 10,
3219
- size: 10
3299
+ size: 10,
3300
+ [theme.fn.smallerThan("sm")]: {
3301
+ minWidth: 5,
3302
+ width: 5
3303
+ }
3220
3304
  });
3221
3305
  return /* @__PURE__ */ React13__default.createElement(
3222
3306
  Box,
@@ -3244,16 +3328,33 @@ function TableView({
3244
3328
  );
3245
3329
  })))
3246
3330
  ),
3247
- isData && /* @__PURE__ */ React13__default.createElement(Box, { component: "tbody" }, table.getRowModel().rows.map((row) => /* @__PURE__ */ React13__default.createElement("tr", { key: row.id, ref: rowRef }, row.getVisibleCells().map((cell) => /* @__PURE__ */ React13__default.createElement(
3248
- MRT_TableBodyCell,
3331
+ isData && /* @__PURE__ */ React13__default.createElement(
3332
+ Box,
3249
3333
  {
3250
- key: cell.id,
3251
- cell,
3252
- rowIndex: row.index,
3253
- table,
3254
- rowRef
3255
- }
3256
- )))))
3334
+ component: "tbody",
3335
+ sx: (t) => ({
3336
+ td: {
3337
+ padding: "0.5rem 1rem !important",
3338
+ fontSize: `${t.fontSizes.sm} !important`
3339
+ },
3340
+ "td:first-of-type": {
3341
+ paddingLeft: "0.5rem !important",
3342
+ paddingRight: "0.5rem !important",
3343
+ minWidth: "0px !important"
3344
+ }
3345
+ })
3346
+ },
3347
+ table.getRowModel().rows.map((row) => /* @__PURE__ */ React13__default.createElement("tr", { key: row.id, ref: rowRef }, row.getVisibleCells().map((cell) => /* @__PURE__ */ React13__default.createElement(
3348
+ MRT_TableBodyCell,
3349
+ {
3350
+ key: cell.id,
3351
+ cell,
3352
+ rowIndex: row.index,
3353
+ table,
3354
+ rowRef
3355
+ }
3356
+ ))))
3357
+ )
3257
3358
  ),
3258
3359
  !isData && !isError && !isLoading && /* @__PURE__ */ React13__default.createElement(NoRecords, null)
3259
3360
  ), /* @__PURE__ */ React13__default.createElement(MRT_ToolbarAlertBanner, { stackAlertBanner: true, table }), /* @__PURE__ */ React13__default.createElement(
@@ -3380,7 +3481,9 @@ var AddColumnsDrawer = () => {
3380
3481
  const updateUrl = useUpdateUrl();
3381
3482
  const { translate: t } = useTranslation();
3382
3483
  const theme = useMantineTheme();
3383
- const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
3484
+ const smallerThanMd = useMediaQuery(
3485
+ `(max-width: ${theme.breakpoints.md}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
3486
+ );
3384
3487
  return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(
3385
3488
  Drawer,
3386
3489
  {
@@ -3420,8 +3523,8 @@ var AddColumnsDrawer = () => {
3420
3523
  id: "dex-column-btn",
3421
3524
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }),
3422
3525
  onClick: open,
3423
- m: "md",
3424
- size: "sm"
3526
+ m: "xs",
3527
+ size: "xs"
3425
3528
  },
3426
3529
  t("params.add_columns")
3427
3530
  )));
@@ -3902,7 +4005,8 @@ var getIconForDimensionType = (dimensionType) => {
3902
4005
  var DrawerMenu_default = AddColumnsDrawer;
3903
4006
  var tabsStyles = (t) => ({
3904
4007
  root: {
3905
- alignSelf: "flex-end"
4008
+ alignSelf: "flex-start",
4009
+ width: "100%"
3906
4010
  },
3907
4011
  tab: {
3908
4012
  fontWeight: 700,
@@ -3916,12 +4020,19 @@ var tabsStyles = (t) => ({
3916
4020
  }
3917
4021
  }
3918
4022
  });
3919
- function ExplorerTabs({
3920
- panels,
3921
- onChange,
3922
- value
3923
- }) {
4023
+ function ExplorerTabs({ panels, onChange, value }) {
3924
4024
  const { translate: t } = useTranslation();
4025
+ const [menuOpened, setMenuOpened] = useState(false);
4026
+ const theme = useMantineTheme();
4027
+ const isMobile = useMediaQuery(
4028
+ `(max-width: ${theme.breakpoints.xs}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
4029
+ );
4030
+ const visiblePanels = isMobile ? panels.slice(0, 2) : panels;
4031
+ const menuPanels = isMobile ? panels.slice(2) : [];
4032
+ const handleMenuItemClick = (panelKey) => {
4033
+ onChange(panelKey);
4034
+ setMenuOpened(false);
4035
+ };
3925
4036
  return /* @__PURE__ */ React13__default.createElement(
3926
4037
  Tabs,
3927
4038
  {
@@ -3931,7 +4042,25 @@ function ExplorerTabs({
3931
4042
  value,
3932
4043
  styles: tabsStyles
3933
4044
  },
3934
- /* @__PURE__ */ React13__default.createElement(Tabs.List, null, panels.map((panel) => /* @__PURE__ */ React13__default.createElement(Tabs.Tab, { key: panel.key, id: panel.key, value: panel.key, h: 56 }, t(panel.label))))
4045
+ /* @__PURE__ */ React13__default.createElement(Tabs.List, { sx: { flexWrap: "nowrap", alignItems: "center", justifyContent: "space-between" } }, /* @__PURE__ */ React13__default.createElement("div", { style: { display: "flex" } }, visiblePanels.map((panel) => /* @__PURE__ */ React13__default.createElement(Tabs.Tab, { key: panel.key, id: panel.key, value: panel.key, h: 56 }, t(panel.label)))), menuPanels.length > 0 && /* @__PURE__ */ React13__default.createElement(Menu, { opened: menuOpened, onChange: setMenuOpened, withinPortal: true }, /* @__PURE__ */ React13__default.createElement(Menu.Target, null, /* @__PURE__ */ React13__default.createElement(
4046
+ ActionIcon,
4047
+ {
4048
+ size: "lg",
4049
+ variant: "subtle",
4050
+ color: theme.primaryColor,
4051
+ sx: { display: "flex", alignItems: "center", height: "100%", marginLeft: "auto" }
4052
+ },
4053
+ /* @__PURE__ */ React13__default.createElement(IconDotsVertical, { size: "1.2rem" })
4054
+ )), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, menuPanels.map((panel) => /* @__PURE__ */ React13__default.createElement(
4055
+ Menu.Item,
4056
+ {
4057
+ key: panel.key,
4058
+ onClick: () => handleMenuItemClick(panel.key),
4059
+ color: value === panel.key ? theme.primaryColor : void 0,
4060
+ fw: value === panel.key ? 700 : void 0
4061
+ },
4062
+ t(panel.label)
4063
+ )))))
3935
4064
  );
3936
4065
  }
3937
4066
  var PreviewModeSwitch = (props) => {
@@ -3976,7 +4105,10 @@ var PreviewModeSwitch = (props) => {
3976
4105
  var toolbarSx = (t) => ({
3977
4106
  background: t.colorScheme === "dark" ? t.black : t.white,
3978
4107
  borderRadius: t.radius.xl,
3979
- height: "fit-content"
4108
+ height: "fit-content",
4109
+ svg: {
4110
+ height: 15
4111
+ }
3980
4112
  });
3981
4113
  function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3982
4114
  const { toolbarConfig } = useSettings();
@@ -3987,7 +4119,7 @@ function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3987
4119
  py: { base: "0.2rem", md: 0 },
3988
4120
  sx: (t) => ({ "& svg path": { stroke: t.colorScheme === "dark" ? "white" : "black" } })
3989
4121
  },
3990
- /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, icon, (toolbarConfig == null ? void 0 : toolbarConfig.showLabels) && label && /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, label))
4122
+ /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", noWrap: true }, icon, (toolbarConfig == null ? void 0 : toolbarConfig.showLabels) && label && /* @__PURE__ */ React13__default.createElement(Text, { size: "sm", sx: { whiteSpace: "nowrap" }, color: "dimmed" }, label))
3991
4123
  );
3992
4124
  }
3993
4125
  function TourButton() {
@@ -4012,15 +4144,17 @@ function Toolbar({
4012
4144
  }) {
4013
4145
  const { translate: t } = useTranslation();
4014
4146
  const theme = useMantineTheme();
4015
- const smallerThanLg = useMediaQuery(`(max-width: ${theme.breakpoints.lg}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.lg) ? "" : "px"})`);
4147
+ const smallerThanLg = useMediaQuery(
4148
+ `(max-width: ${theme.breakpoints.xs}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
4149
+ );
4016
4150
  const { toolbarConfig } = useSettings();
4017
4151
  const settings = /* @__PURE__ */ React13__default.createElement(
4018
4152
  Flex,
4019
4153
  {
4020
- direction: { base: "column", lg: "row" },
4154
+ direction: { base: "column", xs: "row" },
4021
4155
  justify: "flex-start",
4022
4156
  sx: toolbarSx,
4023
- p: "0.325rem",
4157
+ p: "0.25rem",
4024
4158
  px: "md",
4025
4159
  wrap: "nowrap",
4026
4160
  gap: "xs"
@@ -4036,7 +4170,7 @@ function Toolbar({
4036
4170
  }
4037
4171
  )
4038
4172
  );
4039
- return smallerThanLg ? /* @__PURE__ */ React13__default.createElement(Menu, null, /* @__PURE__ */ React13__default.createElement(Menu.Target, null, /* @__PURE__ */ React13__default.createElement(ActionIcon, null, /* @__PURE__ */ React13__default.createElement(IconSettings, null))), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, settings)) : settings;
4173
+ return smallerThanLg ? /* @__PURE__ */ React13__default.createElement(Menu, null, /* @__PURE__ */ React13__default.createElement(Menu.Target, null, /* @__PURE__ */ React13__default.createElement(ActionIcon, { size: "md" }, /* @__PURE__ */ React13__default.createElement(IconSettings, null))), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, settings)) : settings;
4040
4174
  }
4041
4175
  var QueryContext = createContext(void 0);
4042
4176
  function QueryProvider({ children, defaultCube }) {
@@ -4214,267 +4348,85 @@ function useQueryItem() {
4214
4348
  }
4215
4349
  return context;
4216
4350
  }
4217
-
4218
- // src/components/ExplorerResults.tsx
4219
- var useStyles2 = createStyles(() => ({
4220
- container: {
4221
- minHeight: "40vh",
4222
- display: "flex",
4223
- flexFlow: "column nowrap"
4351
+ var createContext4 = (name4) => {
4352
+ const Context = React13__default.createContext(void 0);
4353
+ const useContext4 = () => {
4354
+ const ctx = React13__default.useContext(Context);
4355
+ if (ctx === void 0) {
4356
+ throw new Error(`useContext for must be inside a ${name4}Provider with a value`);
4357
+ }
4358
+ return ctx;
4359
+ };
4360
+ return [useContext4, Context.Provider];
4361
+ };
4362
+ var Graph = class {
4363
+ constructor() {
4364
+ this.nodes = /* @__PURE__ */ new Set([]);
4365
+ this.adjList = {};
4366
+ this.items = [];
4367
+ this.topicOrder = {};
4224
4368
  }
4225
- }));
4226
- function ExplorerResults(props) {
4227
- const {
4228
- data: schema,
4229
- isLoading: schemaLoading,
4230
- isError: schemaError,
4231
- error: schemaErrorDetail
4232
- } = useServerSchema();
4233
- const { transintionLocaleLoading } = useQueryItem();
4234
- const { params } = useSelector$1(selectCurrentQueryItem);
4235
- const cubeMap = (schema == null ? void 0 : schema.cubeMap) || {};
4236
- const cube = cubeMap[params.cube];
4237
- const { online: isServerOnline, url: serverUrl } = schema || {};
4238
- const { translate: t } = useTranslation();
4239
- const { classes, cx } = useStyles2();
4240
- if (typeof window === "object" && window.navigator.onLine === false) {
4241
- return /* @__PURE__ */ React13__default.createElement(
4242
- FailureResult,
4243
- {
4244
- className: cx(classes.container, props.className),
4245
- icon: /* @__PURE__ */ React13__default.createElement(IconWorld, { color: "orange", size: "5rem" }),
4246
- title: t("results.error_disconnected_title")
4247
- }
4248
- );
4369
+ addTopicOrder(topic, order) {
4370
+ this.topicOrder[topic] = Number(order);
4249
4371
  }
4250
- if (isServerOnline === false) {
4251
- return /* @__PURE__ */ React13__default.createElement(
4252
- FailureResult,
4253
- {
4254
- className: cx(classes.container, props.className),
4255
- icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" }),
4256
- title: t("results.error_serveroffline_title"),
4257
- description: /* @__PURE__ */ React13__default.createElement(Text, { span: true }, t("results.error_serveroffline_detail"), /* @__PURE__ */ React13__default.createElement(Anchor, { href: serverUrl, target: "_blank", rel: "noopener noreferrer" }, serverUrl), ".")
4372
+ getTopicOrder(topic) {
4373
+ return this.topicOrder[topic] || 0;
4374
+ }
4375
+ addNode(node) {
4376
+ this.nodes.add(node);
4377
+ if (!this.adjList[node]) this.adjList[node] = /* @__PURE__ */ new Set([]);
4378
+ }
4379
+ addEdge(node1, node2) {
4380
+ this.adjList[node1].add(node2);
4381
+ this.adjList[node2].add(node1);
4382
+ }
4383
+ removeEdge(node1, node2) {
4384
+ const indexOfNode2 = this.adjList[node1] && this.adjList[node1].indexOf(node2);
4385
+ const indexOfNode1 = this.adjList[node2] && this.adjList[node2].indexOf(node1);
4386
+ const badIndices = this.adjList[node1] === void 0 || this.adjList[node2] === void 0;
4387
+ if (badIndices) {
4388
+ return "Please pass in valid indices";
4389
+ } else {
4390
+ this.adjList[node1].splice(indexOfNode2, 1);
4391
+ this.adjList[node2].splice(indexOfNode1, 1);
4392
+ }
4393
+ }
4394
+ isType(locale, node, type) {
4395
+ return this.items.find((item) => getAnnotation(item, type, locale) == node);
4396
+ }
4397
+ isTable(locale, node) {
4398
+ return this.items.filter((item) => getAnnotation(item, "table", locale) == node);
4399
+ }
4400
+ getTopic(startingNode, locale) {
4401
+ let found = false;
4402
+ let topic = null;
4403
+ this.breadthFirstTraversal(startingNode, (node) => {
4404
+ if (this.isType(locale, node, "topic")) {
4405
+ if (!found) {
4406
+ found = true;
4407
+ topic = node;
4408
+ }
4258
4409
  }
4259
- );
4410
+ });
4411
+ return topic;
4260
4412
  }
4261
- if (isServerOnline == null || !cube || schemaLoading || transintionLocaleLoading) {
4262
- return /* @__PURE__ */ React13__default.createElement(
4263
- Paper,
4264
- {
4265
- className: cx(classes.container, props.className),
4266
- id: "query-results-transient",
4267
- radius: 0
4268
- },
4269
- props.splash || null
4270
- );
4413
+ getName(node, locale) {
4414
+ const item = this.items.find((item2) => item2.name === node);
4415
+ const name4 = item ? getAnnotation(item, "table", locale) : node;
4416
+ return name4;
4271
4417
  }
4272
- if (schemaError) {
4273
- return /* @__PURE__ */ React13__default.createElement(
4274
- FailureResult,
4275
- {
4276
- className: cx(classes.container, props.className),
4277
- description: /* @__PURE__ */ React13__default.createElement(Stack, { align: "center", spacing: "xs" }, /* @__PURE__ */ React13__default.createElement(Text, null, t("results.error_execquery_detail")), /* @__PURE__ */ React13__default.createElement(Text, null, schemaErrorDetail.message)),
4278
- icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" })
4418
+ getSubtopic(startingNode, locale) {
4419
+ let found = false;
4420
+ let subtopic = null;
4421
+ this.breadthFirstTraversal(startingNode, (node) => {
4422
+ if (this.isType(locale, node, "subtopic")) {
4423
+ if (!found) {
4424
+ found = true;
4425
+ subtopic = node;
4426
+ }
4279
4427
  }
4280
- );
4281
- }
4282
- return /* @__PURE__ */ React13__default.createElement(
4283
- SuccessResult,
4284
- {
4285
- className: cx(classes.container, props.className),
4286
- cube,
4287
- panels: props.panels,
4288
- params,
4289
- panelKey: null
4290
- },
4291
- props.splash
4292
- );
4293
- }
4294
- function FailureResult(props) {
4295
- return /* @__PURE__ */ React13__default.createElement(
4296
- Paper,
4297
- {
4298
- id: "query-results-failure",
4299
- className: props.className,
4300
- radius: 0,
4301
- withBorder: true,
4302
- sx: { justifyContent: "center" }
4303
- },
4304
- /* @__PURE__ */ React13__default.createElement(Stack, { align: "center", spacing: "xs" }, props.icon && props.icon, props.title && /* @__PURE__ */ React13__default.createElement(Title, { order: 5 }, props.title), props.description && /* @__PURE__ */ React13__default.createElement(Text, null, props.description), props.children && props.children, props.action && props.action)
4305
- );
4306
- }
4307
- function SuccessResult(props) {
4308
- const updateUrl = useUpdateUrl();
4309
- const { cube, panels, params } = props;
4310
- const { translate: t } = useTranslation();
4311
- const { previewLimit, actions: actions2 } = useSettings();
4312
- const queryItem = useSelector$1(selectCurrentQueryItem);
4313
- const isPreviewMode = useSelector$1(selectIsPreviewMode);
4314
- const fullscreen = useFullscreen();
4315
- const { classes, cx } = useStyles2();
4316
- const [CurrentComponent, panelKey, panelMeta] = useMemo(() => {
4317
- const currentPanel = queryItem.panel || `${panels[0].key}-`;
4318
- const [panelKey2, ...panelMeta2] = currentPanel.split("-");
4319
- const panel = panels.find((item) => item.key === panelKey2) || panels[0];
4320
- return [panel.component, panel.key, panelMeta2.join("-")];
4321
- }, [panels, queryItem.panel]);
4322
- const tabHandler = (newTab) => {
4323
- actions2.switchPanel(newTab);
4324
- updateUrl({ ...queryItem, panel: newTab });
4325
- };
4326
- const { table, isError, isLoading, data, columns, result, pagination, isFetching } = useTable({
4327
- cube
4328
- });
4329
- if ((data == null ? void 0 : data.length) === 0 && !isLoading && !isError) {
4330
- return /* @__PURE__ */ React13__default.createElement(
4331
- FailureResult,
4332
- {
4333
- className: cx(classes.container, props.className),
4334
- icon: /* @__PURE__ */ React13__default.createElement(IconBox, { color: "orange", size: "5rem" }),
4335
- title: t("results.error_emptyresult_title"),
4336
- description: t("results.error_emptyresult_detail")
4337
- }
4338
- );
4339
- }
4340
- return /* @__PURE__ */ React13__default.createElement(
4341
- Flex,
4342
- {
4343
- gap: "xs",
4344
- direction: "column",
4345
- w: "100%",
4346
- className: props.className,
4347
- h: "100%",
4348
- sx: { overflow: "hidden" }
4349
- },
4350
- /* @__PURE__ */ React13__default.createElement(
4351
- Paper,
4352
- {
4353
- ref: fullscreen.ref,
4354
- id: "query-results-success",
4355
- h: "100%",
4356
- sx: { display: "flex", flexDirection: "column", overflow: "hidden" }
4357
- },
4358
- /* @__PURE__ */ React13__default.createElement(
4359
- Flex,
4360
- {
4361
- sx: (t2) => ({
4362
- alignItems: "center",
4363
- background: t2.colorScheme === "dark" ? t2.colors.dark[7] : t2.colors.gray[1],
4364
- justifyContent: "space-between"
4365
- }),
4366
- w: "100%",
4367
- h: "fit-content"
4368
- },
4369
- /* @__PURE__ */ React13__default.createElement(ExplorerTabs, { panels, onChange: tabHandler, value: panelKey }),
4370
- (!queryItem.panel || queryItem.panel === "table") && /* @__PURE__ */ React13__default.createElement(Group, { sx: { display: "flex", flex: "0 1 auto", gap: "0.5rem" }, mr: "sm", noWrap: true }, table && /* @__PURE__ */ React13__default.createElement(Toolbar, { table, fullscreen }), /* @__PURE__ */ React13__default.createElement(DrawerMenu_default, null))
4371
- ),
4372
- isPreviewMode && /* @__PURE__ */ React13__default.createElement(Alert, { id: "alert-load-all-results", color: "yellow", radius: 0, sx: { flex: "0 0 auto" } }, /* @__PURE__ */ React13__default.createElement(Group, { position: "apart" }, /* @__PURE__ */ React13__default.createElement(Text, null, /* @__PURE__ */ React13__default.createElement(Text, { fw: 700, span: true }, t("previewMode.title_preview"), ":", " "), /* @__PURE__ */ React13__default.createElement(Text, { span: true }, t("previewMode.description_preview", { limit: previewLimit }))), /* @__PURE__ */ React13__default.createElement(PreviewModeSwitch, null))),
4373
- /* @__PURE__ */ React13__default.createElement(
4374
- Box,
4375
- {
4376
- id: "query-results-content",
4377
- sx: { flex: "1 1 calc(100% - 70px)", maxHeight: "calc(100% - 70px)" }
4378
- },
4379
- /* @__PURE__ */ React13__default.createElement(Suspense, { fallback: props.children }, /* @__PURE__ */ React13__default.createElement(Flex, { h: "100%" }, /* @__PURE__ */ React13__default.createElement(Box, { sx: { flex: "1 1", overflowX: "scroll" } }, /* @__PURE__ */ React13__default.createElement(
4380
- CurrentComponent,
4381
- {
4382
- panelKey: `${panelKey}-${panelMeta}`,
4383
- cube,
4384
- params,
4385
- data,
4386
- result,
4387
- table,
4388
- isError,
4389
- isLoading,
4390
- columns,
4391
- pagination,
4392
- isFetching
4393
- }
4394
- ))))
4395
- )
4396
- )
4397
- );
4398
- }
4399
- var createContext4 = (name4) => {
4400
- const Context = React13__default.createContext(void 0);
4401
- const useContext4 = () => {
4402
- const ctx = React13__default.useContext(Context);
4403
- if (ctx === void 0) {
4404
- throw new Error(`useContext for must be inside a ${name4}Provider with a value`);
4405
- }
4406
- return ctx;
4407
- };
4408
- return [useContext4, Context.Provider];
4409
- };
4410
- var Graph = class {
4411
- constructor() {
4412
- this.nodes = /* @__PURE__ */ new Set([]);
4413
- this.adjList = {};
4414
- this.items = [];
4415
- this.topicOrder = {};
4416
- }
4417
- addTopicOrder(topic, order) {
4418
- this.topicOrder[topic] = Number(order);
4419
- }
4420
- getTopicOrder(topic) {
4421
- return this.topicOrder[topic] || 0;
4422
- }
4423
- addNode(node) {
4424
- this.nodes.add(node);
4425
- if (!this.adjList[node]) this.adjList[node] = /* @__PURE__ */ new Set([]);
4426
- }
4427
- addEdge(node1, node2) {
4428
- this.adjList[node1].add(node2);
4429
- this.adjList[node2].add(node1);
4430
- }
4431
- removeEdge(node1, node2) {
4432
- const indexOfNode2 = this.adjList[node1] && this.adjList[node1].indexOf(node2);
4433
- const indexOfNode1 = this.adjList[node2] && this.adjList[node2].indexOf(node1);
4434
- const badIndices = this.adjList[node1] === void 0 || this.adjList[node2] === void 0;
4435
- if (badIndices) {
4436
- return "Please pass in valid indices";
4437
- } else {
4438
- this.adjList[node1].splice(indexOfNode2, 1);
4439
- this.adjList[node2].splice(indexOfNode1, 1);
4440
- }
4441
- }
4442
- isType(locale, node, type) {
4443
- return this.items.find((item) => getAnnotation(item, type, locale) == node);
4444
- }
4445
- isTable(locale, node) {
4446
- return this.items.filter((item) => getAnnotation(item, "table", locale) == node);
4447
- }
4448
- getTopic(startingNode, locale) {
4449
- let found = false;
4450
- let topic = null;
4451
- this.breadthFirstTraversal(startingNode, (node) => {
4452
- if (this.isType(locale, node, "topic")) {
4453
- if (!found) {
4454
- found = true;
4455
- topic = node;
4456
- }
4457
- }
4458
- });
4459
- return topic;
4460
- }
4461
- getName(node, locale) {
4462
- const item = this.items.find((item2) => item2.name === node);
4463
- const name4 = item ? getAnnotation(item, "table", locale) : node;
4464
- return name4;
4465
- }
4466
- getSubtopic(startingNode, locale) {
4467
- let found = false;
4468
- let subtopic = null;
4469
- this.breadthFirstTraversal(startingNode, (node) => {
4470
- if (this.isType(locale, node, "subtopic")) {
4471
- if (!found) {
4472
- found = true;
4473
- subtopic = node;
4474
- }
4475
- }
4476
- });
4477
- return subtopic;
4428
+ });
4429
+ return subtopic;
4478
4430
  }
4479
4431
  filter(locale, filter) {
4480
4432
  function addItemToSubtopic(map2, subtopic, item) {
@@ -4639,24 +4591,14 @@ function SideBarControlBtn({ actionIconProps = {} }) {
4639
4591
  /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4640
4592
  );
4641
4593
  }
4642
- function SideBarControlBtnFixed() {
4643
- const actionIconProps = {
4644
- sx: (t) => ({
4645
- backgroundColor: `${t.colorScheme === "dark" ? t.colors.dark[8] : t.colors.gray[1]} !important`,
4646
- padding: `calc(${t.spacing.xs} / 2)`,
4647
- borderRadius: t.radius.xl,
4648
- width: 50,
4649
- height: 50
4650
- })
4651
- };
4652
- return /* @__PURE__ */ React13__default.createElement(Affix, { position: { left: "1rem", bottom: 150 } }, /* @__PURE__ */ React13__default.createElement(SideBarControlBtn, { actionIconProps }));
4653
- }
4654
4594
  function SideBar(props) {
4655
4595
  const { expanded, input, setExpanded, setInput } = useSideBar();
4656
4596
  const { translate: t } = useTranslation();
4657
4597
  const theme = useMantineTheme();
4658
- const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
4659
- return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, smallerThanMd && /* @__PURE__ */ React13__default.createElement(SideBarControlBtnFixed, null), /* @__PURE__ */ React13__default.createElement(
4598
+ const smallerThanMd = useMediaQuery(
4599
+ `(max-width: ${theme.breakpoints.md}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
4600
+ );
4601
+ return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(
4660
4602
  Box,
4661
4603
  {
4662
4604
  id: "dex-sidebar",
@@ -4686,6 +4628,7 @@ function SideBar(props) {
4686
4628
  Group,
4687
4629
  {
4688
4630
  position: "apart",
4631
+ align: "center",
4689
4632
  noWrap: true,
4690
4633
  sx: {
4691
4634
  overflow: "hidden",
@@ -4694,7 +4637,18 @@ function SideBar(props) {
4694
4637
  width: expanded ? 300 : 0
4695
4638
  }
4696
4639
  },
4697
- /* @__PURE__ */ React13__default.createElement(Text, { sx: (t2) => ({ color: t2.colorScheme === "dark" ? t2.white : t2.black }), ml: "sm" }, t("params.label_dataset"))
4640
+ /* @__PURE__ */ React13__default.createElement(Text, { sx: (t2) => ({ color: t2.colorScheme === "dark" ? t2.white : t2.black }), ml: "sm" }, t("params.label_dataset")),
4641
+ /* @__PURE__ */ React13__default.createElement(
4642
+ ActionIcon,
4643
+ {
4644
+ onClick: () => setExpanded(!expanded),
4645
+ variant: "subtle",
4646
+ mt: "auto",
4647
+ color: "primaryColor",
4648
+ sx: (t2) => ({ alignSelf: "flex-end" })
4649
+ },
4650
+ expanded ? smallerThanMd ? /* @__PURE__ */ React13__default.createElement(IconX, { size: "1.5rem" }) : /* @__PURE__ */ React13__default.createElement(IconChevronLeft, { size: "1.5rem" }) : /* @__PURE__ */ React13__default.createElement(IconChevronRight, { size: "1.5rem" })
4651
+ )
4698
4652
  )), /* @__PURE__ */ React13__default.createElement(
4699
4653
  Box,
4700
4654
  {
@@ -4718,27 +4672,6 @@ function SideBar(props) {
4718
4672
  })
4719
4673
  },
4720
4674
  /* @__PURE__ */ React13__default.createElement(Box, { h: expanded ? "auto" : "0px" }, props.children)
4721
- ), /* @__PURE__ */ React13__default.createElement(
4722
- Group,
4723
- {
4724
- align: "center",
4725
- position: expanded ? "right" : "center",
4726
- w: "100%",
4727
- p: "md",
4728
- sx: { alignSelf: "flex-end", marginTop: "auto" },
4729
- noWrap: true
4730
- },
4731
- /* @__PURE__ */ React13__default.createElement(
4732
- ActionIcon,
4733
- {
4734
- onClick: () => setExpanded(!expanded),
4735
- variant: "subtle",
4736
- mt: "auto",
4737
- color: "primaryColor",
4738
- sx: (t2) => ({ alignSelf: "flex-end" })
4739
- },
4740
- expanded ? /* @__PURE__ */ React13__default.createElement(IconChevronLeft, { size: "1.5rem" }) : /* @__PURE__ */ React13__default.createElement(IconChevronRight, { size: "1.5rem" })
4741
- )
4742
4675
  ))
4743
4676
  ));
4744
4677
  }
@@ -4799,6 +4732,229 @@ function CubeSearchInput(props) {
4799
4732
  }
4800
4733
  );
4801
4734
  }
4735
+
4736
+ // src/components/ExplorerResults.tsx
4737
+ function SideBarControlBtn2({ actionIconProps = {} }) {
4738
+ const { expanded, setExpanded } = useSideBar();
4739
+ const sx = (t) => ({
4740
+ alignSelf: "center",
4741
+ color: t.colorScheme === "dark" ? t.white : t.colors.gray[7]
4742
+ });
4743
+ return /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", display: { base: "flex", md: "none" }, align: "center" }, /* @__PURE__ */ React13__default.createElement(
4744
+ ActionIcon,
4745
+ {
4746
+ onClick: () => setExpanded(!expanded),
4747
+ variant: "subtle",
4748
+ ...actionIconProps,
4749
+ sx: [sx, ...packSx(actionIconProps.sx)]
4750
+ },
4751
+ /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4752
+ ), /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, "Select Dataset"));
4753
+ }
4754
+ var useStyles2 = createStyles(() => ({
4755
+ container: {
4756
+ minHeight: "40vh",
4757
+ display: "flex",
4758
+ flexFlow: "column nowrap"
4759
+ }
4760
+ }));
4761
+ function ExplorerResults(props) {
4762
+ const {
4763
+ data: schema,
4764
+ isLoading: schemaLoading,
4765
+ isError: schemaError,
4766
+ error: schemaErrorDetail
4767
+ } = useServerSchema();
4768
+ const { transintionLocaleLoading } = useQueryItem();
4769
+ const { params } = useSelector$1(selectCurrentQueryItem);
4770
+ const cubeMap = (schema == null ? void 0 : schema.cubeMap) || {};
4771
+ const cube = cubeMap[params.cube];
4772
+ const { online: isServerOnline, url: serverUrl } = schema || {};
4773
+ const { translate: t } = useTranslation();
4774
+ const { classes, cx } = useStyles2();
4775
+ if (typeof window === "object" && window.navigator.onLine === false) {
4776
+ return /* @__PURE__ */ React13__default.createElement(
4777
+ FailureResult,
4778
+ {
4779
+ className: cx(classes.container, props.className),
4780
+ icon: /* @__PURE__ */ React13__default.createElement(IconWorld, { color: "orange", size: "5rem" }),
4781
+ title: t("results.error_disconnected_title")
4782
+ }
4783
+ );
4784
+ }
4785
+ if (isServerOnline === false) {
4786
+ return /* @__PURE__ */ React13__default.createElement(
4787
+ FailureResult,
4788
+ {
4789
+ className: cx(classes.container, props.className),
4790
+ icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" }),
4791
+ title: t("results.error_serveroffline_title"),
4792
+ description: /* @__PURE__ */ React13__default.createElement(Text, { span: true }, t("results.error_serveroffline_detail"), /* @__PURE__ */ React13__default.createElement(Anchor, { href: serverUrl, target: "_blank", rel: "noopener noreferrer" }, serverUrl), ".")
4793
+ }
4794
+ );
4795
+ }
4796
+ if (isServerOnline == null || !cube || schemaLoading || transintionLocaleLoading) {
4797
+ return /* @__PURE__ */ React13__default.createElement(
4798
+ Paper,
4799
+ {
4800
+ className: cx(classes.container, props.className),
4801
+ id: "query-results-transient",
4802
+ radius: 0
4803
+ },
4804
+ props.splash || null
4805
+ );
4806
+ }
4807
+ if (schemaError) {
4808
+ return /* @__PURE__ */ React13__default.createElement(
4809
+ FailureResult,
4810
+ {
4811
+ className: cx(classes.container, props.className),
4812
+ description: /* @__PURE__ */ React13__default.createElement(Stack, { align: "center", spacing: "xs" }, /* @__PURE__ */ React13__default.createElement(Text, null, t("results.error_execquery_detail")), /* @__PURE__ */ React13__default.createElement(Text, null, schemaErrorDetail.message)),
4813
+ icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" })
4814
+ }
4815
+ );
4816
+ }
4817
+ return /* @__PURE__ */ React13__default.createElement(
4818
+ SuccessResult,
4819
+ {
4820
+ className: cx(classes.container, props.className),
4821
+ cube,
4822
+ panels: props.panels,
4823
+ params,
4824
+ panelKey: null
4825
+ },
4826
+ props.splash
4827
+ );
4828
+ }
4829
+ function FailureResult(props) {
4830
+ return /* @__PURE__ */ React13__default.createElement(
4831
+ Paper,
4832
+ {
4833
+ id: "query-results-failure",
4834
+ className: props.className,
4835
+ radius: 0,
4836
+ withBorder: true,
4837
+ sx: { justifyContent: "center" }
4838
+ },
4839
+ /* @__PURE__ */ React13__default.createElement(Stack, { align: "center", spacing: "xs" }, props.icon && props.icon, props.title && /* @__PURE__ */ React13__default.createElement(Title, { order: 5 }, props.title), props.description && /* @__PURE__ */ React13__default.createElement(Text, null, props.description), props.children && props.children, props.action && props.action)
4840
+ );
4841
+ }
4842
+ function SuccessResult(props) {
4843
+ const updateUrl = useUpdateUrl();
4844
+ const { cube, panels, params } = props;
4845
+ const { translate: t } = useTranslation();
4846
+ const { previewLimit, actions: actions2 } = useSettings();
4847
+ const queryItem = useSelector$1(selectCurrentQueryItem);
4848
+ const isPreviewMode = useSelector$1(selectIsPreviewMode);
4849
+ const fullscreen = useFullscreen();
4850
+ const { classes, cx } = useStyles2();
4851
+ const [CurrentComponent, panelKey, panelMeta] = useMemo(() => {
4852
+ const currentPanel = queryItem.panel || `${panels[0].key}-`;
4853
+ const [panelKey2, ...panelMeta2] = currentPanel.split("-");
4854
+ const panel = panels.find((item) => item.key === panelKey2) || panels[0];
4855
+ return [panel.component, panel.key, panelMeta2.join("-")];
4856
+ }, [panels, queryItem.panel]);
4857
+ const tabHandler = (newTab) => {
4858
+ actions2.switchPanel(newTab);
4859
+ updateUrl({ ...queryItem, panel: newTab });
4860
+ };
4861
+ const { table, isError, isLoading, data, columns, result, pagination, isFetching } = useTable({
4862
+ cube
4863
+ });
4864
+ if ((data == null ? void 0 : data.length) === 0 && !isLoading && !isError) {
4865
+ return /* @__PURE__ */ React13__default.createElement(
4866
+ FailureResult,
4867
+ {
4868
+ className: cx(classes.container, props.className),
4869
+ icon: /* @__PURE__ */ React13__default.createElement(IconBox, { color: "orange", size: "5rem" }),
4870
+ title: t("results.error_emptyresult_title"),
4871
+ description: t("results.error_emptyresult_detail")
4872
+ }
4873
+ );
4874
+ }
4875
+ return /* @__PURE__ */ React13__default.createElement(
4876
+ Flex,
4877
+ {
4878
+ gap: "xs",
4879
+ direction: "column",
4880
+ w: "100%",
4881
+ className: props.className,
4882
+ h: "100%",
4883
+ sx: { overflow: "hidden" }
4884
+ },
4885
+ /* @__PURE__ */ React13__default.createElement(
4886
+ Paper,
4887
+ {
4888
+ ref: fullscreen.ref,
4889
+ id: "query-results-success",
4890
+ h: "100%",
4891
+ sx: { display: "flex", flexDirection: "column", overflow: "hidden" }
4892
+ },
4893
+ /* @__PURE__ */ React13__default.createElement(
4894
+ Flex,
4895
+ {
4896
+ sx: (t2) => ({
4897
+ alignItems: "center",
4898
+ background: t2.colorScheme === "dark" ? t2.colors.dark[7] : t2.colors.gray[1],
4899
+ justifyContent: "space-between",
4900
+ [t2.fn.smallerThan("md")]: {
4901
+ flexDirection: "column",
4902
+ justifyContent: "flex-start",
4903
+ alignItems: "flex-start"
4904
+ }
4905
+ }),
4906
+ w: "100%",
4907
+ h: "fit-content"
4908
+ },
4909
+ /* @__PURE__ */ React13__default.createElement(ExplorerTabs, { panels, onChange: tabHandler, value: panelKey }),
4910
+ (!queryItem.panel || queryItem.panel === "table") && /* @__PURE__ */ React13__default.createElement(
4911
+ Group,
4912
+ {
4913
+ sx: (t2) => ({
4914
+ display: "flex",
4915
+ flex: "0 1 auto",
4916
+ gap: "0.5rem",
4917
+ [t2.fn.smallerThan("md")]: {
4918
+ width: "100%",
4919
+ order: -1,
4920
+ padding: t2.spacing.sm,
4921
+ justifyContent: "space-between"
4922
+ }
4923
+ }),
4924
+ mr: "sm",
4925
+ noWrap: true
4926
+ },
4927
+ /* @__PURE__ */ React13__default.createElement(SideBarControlBtn2, null),
4928
+ /* @__PURE__ */ React13__default.createElement(Flex, { direction: "row", gap: "xs", align: "center" }, table && /* @__PURE__ */ React13__default.createElement(Toolbar, { table, fullscreen }), /* @__PURE__ */ React13__default.createElement(DrawerMenu_default, null))
4929
+ )
4930
+ ),
4931
+ isPreviewMode && /* @__PURE__ */ React13__default.createElement(Alert, { id: "alert-load-all-results", color: "yellow", radius: 0, sx: { flex: "0 0 auto" } }, /* @__PURE__ */ React13__default.createElement(Group, { position: "apart" }, /* @__PURE__ */ React13__default.createElement(Text, null, /* @__PURE__ */ React13__default.createElement(Text, { fw: 700, span: true }, t("previewMode.title_preview"), ":", " "), /* @__PURE__ */ React13__default.createElement(Text, { span: true }, t("previewMode.description_preview", { limit: previewLimit }))), /* @__PURE__ */ React13__default.createElement(PreviewModeSwitch, null))),
4932
+ /* @__PURE__ */ React13__default.createElement(
4933
+ Box,
4934
+ {
4935
+ id: "query-results-content",
4936
+ sx: { flex: "1 1 calc(100% - 70px)", maxHeight: "calc(100% - 70px)" }
4937
+ },
4938
+ /* @__PURE__ */ React13__default.createElement(Suspense, { fallback: props.children }, /* @__PURE__ */ React13__default.createElement(Flex, { h: "100%" }, /* @__PURE__ */ React13__default.createElement(Box, { sx: { flex: "1 1", overflowX: "scroll" } }, /* @__PURE__ */ React13__default.createElement(
4939
+ CurrentComponent,
4940
+ {
4941
+ panelKey: `${panelKey}-${panelMeta}`,
4942
+ cube,
4943
+ params,
4944
+ data,
4945
+ result,
4946
+ table,
4947
+ isError,
4948
+ isLoading,
4949
+ columns,
4950
+ pagination,
4951
+ isFetching
4952
+ }
4953
+ ))))
4954
+ )
4955
+ )
4956
+ );
4957
+ }
4802
4958
  function Results(props) {
4803
4959
  const { graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2 } = props;
4804
4960
  const { classes } = useStyles3();
@@ -5120,7 +5276,7 @@ function ExplorerContent(props) {
5120
5276
  const SplashComponent = props.splash;
5121
5277
  return SplashComponent ? /* @__PURE__ */ React13__default.createElement(SplashComponent, { translation }) : /* @__PURE__ */ React13__default.createElement(Center, { h: "100%", sx: { flex: 1 } }, /* @__PURE__ */ React13__default.createElement(AnimatedCube, null));
5122
5278
  }, [props.splash, translation]);
5123
- return /* @__PURE__ */ React13__default.createElement("div", { className: classes.container }, /* @__PURE__ */ React13__default.createElement("div", { className: classes.root }, /* @__PURE__ */ React13__default.createElement(SideBarProvider, { locale: defaultLocale }, /* @__PURE__ */ React13__default.createElement(SideBar_default, null, /* @__PURE__ */ React13__default.createElement(SideBarItem, null, /* @__PURE__ */ React13__default.createElement(SelectCubes, { locale: defaultLocale })))), /* @__PURE__ */ React13__default.createElement(
5279
+ return /* @__PURE__ */ React13__default.createElement("div", { className: classes.container }, /* @__PURE__ */ React13__default.createElement("div", { className: classes.root }, /* @__PURE__ */ React13__default.createElement(SideBarProvider, { locale: defaultLocale }, /* @__PURE__ */ React13__default.createElement(SideBar_default, null, /* @__PURE__ */ React13__default.createElement(SideBarItem, null, /* @__PURE__ */ React13__default.createElement(SelectCubes, { locale: defaultLocale }))), /* @__PURE__ */ React13__default.createElement(
5124
5280
  ExplorerResults,
5125
5281
  {
5126
5282
  className: classes.flexCol,
@@ -5128,7 +5284,7 @@ function ExplorerContent(props) {
5128
5284
  splash,
5129
5285
  serverURL: props.serverURL
5130
5286
  }
5131
- )));
5287
+ ))));
5132
5288
  }
5133
5289
  function usePivotTableData() {
5134
5290
  const queryItem = useSelector$1(selectCurrentQueryItem);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [