@datawheel/data-explorer 1.1.9 → 1.1.11

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 +557 -411
  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,8 @@ 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(`(max-width: ${theme.breakpoints.md})`);
2894
2949
  const columns = useMemo(() => {
2895
2950
  const indexColumn = {
2896
2951
  id: "#",
@@ -2938,7 +2993,8 @@ function useTable({
2938
2993
  },
2939
2994
  Header: ({ column: column2 }) => {
2940
2995
  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(
2996
+ const isMobile = useMediaQuery(`(max-width: ${theme.breakpoints.sm})`);
2997
+ const actionSort = /* @__PURE__ */ React13__default.createElement(
2942
2998
  ActionIcon,
2943
2999
  {
2944
3000
  key: `sort-${header}`,
@@ -2983,29 +3039,39 @@ function useTable({
2983
3039
  }
2984
3040
  },
2985
3041
  getSortIcon(isSorted ? sortDir : false, entityType)
2986
- ))), showTrashIcon(finalKeys, entityType) && /* @__PURE__ */ React13__default.createElement(
2987
- CustomActionIcon_default,
3042
+ );
3043
+ return /* @__PURE__ */ React13__default.createElement(Box, { mb: rem(5), key: "header" }, /* @__PURE__ */ React13__default.createElement(
3044
+ Flex,
2988
3045
  {
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)
3046
+ justify: "center",
3047
+ align: { base: "flex-start", sm: "center" },
3048
+ direction: { base: "column", sm: "row" }
3006
3049
  },
3007
- /* @__PURE__ */ React13__default.createElement(IconTrash, null)
3008
- )));
3050
+ /* @__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)),
3051
+ /* @__PURE__ */ React13__default.createElement(Group, { position: "apart", w: "100%" }, isMobile && actionSort, showTrashIcon(finalKeys, entityType) && /* @__PURE__ */ React13__default.createElement(
3052
+ CustomActionIcon_default,
3053
+ {
3054
+ label: `At least one ${getEntityText(entityType)} is required.`,
3055
+ key: `remove-${column2.columnDef.header}`,
3056
+ disabled: !showTrashIcon(finalKeys, entityType) || isLoading || isFetching,
3057
+ onClick: () => {
3058
+ removeColumn(
3059
+ actions2,
3060
+ entity,
3061
+ measures,
3062
+ drilldowns,
3063
+ entityType,
3064
+ queryItem,
3065
+ updateURL
3066
+ );
3067
+ },
3068
+ showTooltip: !showTrashIcon(finalKeys, entityType),
3069
+ size: 25,
3070
+ ml: rem(5)
3071
+ },
3072
+ /* @__PURE__ */ React13__default.createElement(IconTrash, null)
3073
+ ))
3074
+ ));
3009
3075
  },
3010
3076
  formatter: formatter2,
3011
3077
  formatterKey,
@@ -3013,7 +3079,9 @@ function useTable({
3013
3079
  dataType: valueType,
3014
3080
  Cell: isNumeric ? ({ cell }) => {
3015
3081
  return /* @__PURE__ */ React13__default.createElement("span", { style: { display: "block", textAlign: "right" } }, formatter2(cell.getValue(), locale));
3016
- } : ({ cell, renderedCellValue, row }) => {
3082
+ } : ({ cell }) => {
3083
+ const cellValue = cell.getValue();
3084
+ const row = cell.row;
3017
3085
  const cellId = row.original[`${cell.column.id} ID`];
3018
3086
  const idFormatter = idFormatters[`${column.localeLabel} ID`];
3019
3087
  return /* @__PURE__ */ React13__default.createElement(Flex, { justify: "space-between", sx: { width: "100%", maxWidth: 400 }, gap: "sm" }, /* @__PURE__ */ React13__default.createElement(
@@ -3026,7 +3094,7 @@ function useTable({
3026
3094
  textOverflow: "ellipsis"
3027
3095
  }
3028
3096
  },
3029
- renderedCellValue
3097
+ cellValue
3030
3098
  ), /* @__PURE__ */ React13__default.createElement(Box, null, cellId && /* @__PURE__ */ React13__default.createElement(Text, { color: "dimmed" }, idFormatter ? idFormatter(cellId) : cellId)));
3031
3099
  }
3032
3100
  };
@@ -3045,9 +3113,10 @@ function useTable({
3045
3113
  enableFilterMatchHighlighting: true,
3046
3114
  enableGlobalFilter: true,
3047
3115
  mantinePaginationProps: {
3116
+ rowsPerPageOptions: ["10", "25", "50", "100"],
3048
3117
  showRowsPerPage: false
3049
3118
  },
3050
- paginationDisplayMode: "pages",
3119
+ paginationDisplayMode: isSmallerThanMd ? "default" : "pages",
3051
3120
  globalFilterFn: "contains",
3052
3121
  initialState: {
3053
3122
  density: "xs"
@@ -3067,12 +3136,12 @@ function useTable({
3067
3136
  mantinePaperProps: {
3068
3137
  id: "query-results-table-view",
3069
3138
  withBorder: false,
3070
- sx: (theme) => ({
3139
+ sx: (theme2) => ({
3071
3140
  height: "100%",
3072
3141
  display: "flex",
3073
3142
  flexFlow: "column nowrap",
3074
- padding: `0 ${theme.spacing.sm}`,
3075
- [theme.fn.largerThan("md")]: {
3143
+ padding: `0 ${theme2.spacing.sm}`,
3144
+ [theme2.fn.largerThan("md")]: {
3076
3145
  padding: 0
3077
3146
  }
3078
3147
  })
@@ -3105,7 +3174,7 @@ function useTable({
3105
3174
  );
3106
3175
  }
3107
3176
  }),
3108
- [isError, t]
3177
+ [isError, t, isSmallerThanMd]
3109
3178
  );
3110
3179
  const table = useMantineReactTable({
3111
3180
  columns,
@@ -3179,11 +3248,14 @@ function TableView({
3179
3248
  verticalSpacing: "xs",
3180
3249
  withBorder: true,
3181
3250
  withColumnBorders: true,
3182
- sx: {
3251
+ sx: (t) => ({
3183
3252
  "thead > tr > th": {
3184
- padding: "0.5rem 1rem"
3253
+ padding: "0.5rem 1rem",
3254
+ [t.fn.smallerThan("sm")]: {
3255
+ padding: "0.25rem 0.6rem"
3256
+ }
3185
3257
  }
3186
- }
3258
+ })
3187
3259
  },
3188
3260
  /* @__PURE__ */ React13__default.createElement(
3189
3261
  Box,
@@ -3209,14 +3281,22 @@ function TableView({
3209
3281
  position: "sticky",
3210
3282
  fontSize: theme.fontSizes.sm,
3211
3283
  top: 0,
3212
- display: "table-cell"
3284
+ display: "table-cell",
3285
+ [theme.fn.smallerThan("sm")]: {
3286
+ minWidth: 180,
3287
+ width: 180
3288
+ }
3213
3289
  });
3214
3290
  const index = (theme) => ({
3215
3291
  ...base(theme),
3216
3292
  minWidth: 10,
3217
3293
  width: 10,
3218
3294
  maxWidth: 10,
3219
- size: 10
3295
+ size: 10,
3296
+ [theme.fn.smallerThan("sm")]: {
3297
+ minWidth: 5,
3298
+ width: 5
3299
+ }
3220
3300
  });
3221
3301
  return /* @__PURE__ */ React13__default.createElement(
3222
3302
  Box,
@@ -3244,16 +3324,33 @@ function TableView({
3244
3324
  );
3245
3325
  })))
3246
3326
  ),
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,
3327
+ isData && /* @__PURE__ */ React13__default.createElement(
3328
+ Box,
3249
3329
  {
3250
- key: cell.id,
3251
- cell,
3252
- rowIndex: row.index,
3253
- table,
3254
- rowRef
3255
- }
3256
- )))))
3330
+ component: "tbody",
3331
+ sx: (t) => ({
3332
+ td: {
3333
+ padding: "0.5rem 1rem !important",
3334
+ fontSize: `${t.fontSizes.sm} !important`
3335
+ },
3336
+ "td:first-of-type": {
3337
+ paddingLeft: "0.5rem !important",
3338
+ paddingRight: "0.5rem !important",
3339
+ minWidth: "0px !important"
3340
+ }
3341
+ })
3342
+ },
3343
+ table.getRowModel().rows.map((row) => /* @__PURE__ */ React13__default.createElement("tr", { key: row.id, ref: rowRef }, row.getVisibleCells().map((cell) => /* @__PURE__ */ React13__default.createElement(
3344
+ MRT_TableBodyCell,
3345
+ {
3346
+ key: cell.id,
3347
+ cell,
3348
+ rowIndex: row.index,
3349
+ table,
3350
+ rowRef
3351
+ }
3352
+ ))))
3353
+ )
3257
3354
  ),
3258
3355
  !isData && !isError && !isLoading && /* @__PURE__ */ React13__default.createElement(NoRecords, null)
3259
3356
  ), /* @__PURE__ */ React13__default.createElement(MRT_ToolbarAlertBanner, { stackAlertBanner: true, table }), /* @__PURE__ */ React13__default.createElement(
@@ -3420,8 +3517,8 @@ var AddColumnsDrawer = () => {
3420
3517
  id: "dex-column-btn",
3421
3518
  leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }),
3422
3519
  onClick: open,
3423
- m: "md",
3424
- size: "sm"
3520
+ m: "xs",
3521
+ size: "xs"
3425
3522
  },
3426
3523
  t("params.add_columns")
3427
3524
  )));
@@ -3902,7 +3999,8 @@ var getIconForDimensionType = (dimensionType) => {
3902
3999
  var DrawerMenu_default = AddColumnsDrawer;
3903
4000
  var tabsStyles = (t) => ({
3904
4001
  root: {
3905
- alignSelf: "flex-end"
4002
+ alignSelf: "flex-start",
4003
+ width: "100%"
3906
4004
  },
3907
4005
  tab: {
3908
4006
  fontWeight: 700,
@@ -3916,12 +4014,17 @@ var tabsStyles = (t) => ({
3916
4014
  }
3917
4015
  }
3918
4016
  });
3919
- function ExplorerTabs({
3920
- panels,
3921
- onChange,
3922
- value
3923
- }) {
4017
+ function ExplorerTabs({ panels, onChange, value }) {
3924
4018
  const { translate: t } = useTranslation();
4019
+ const [menuOpened, setMenuOpened] = useState(false);
4020
+ const theme = useMantineTheme();
4021
+ const isMobile = useMediaQuery(`(max-width: ${theme.breakpoints.xs})`);
4022
+ const visiblePanels = isMobile ? panels.slice(0, 2) : panels;
4023
+ const menuPanels = isMobile ? panels.slice(2) : [];
4024
+ const handleMenuItemClick = (panelKey) => {
4025
+ onChange(panelKey);
4026
+ setMenuOpened(false);
4027
+ };
3925
4028
  return /* @__PURE__ */ React13__default.createElement(
3926
4029
  Tabs,
3927
4030
  {
@@ -3931,7 +4034,25 @@ function ExplorerTabs({
3931
4034
  value,
3932
4035
  styles: tabsStyles
3933
4036
  },
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))))
4037
+ /* @__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(
4038
+ ActionIcon,
4039
+ {
4040
+ size: "lg",
4041
+ variant: "subtle",
4042
+ color: theme.primaryColor,
4043
+ sx: { display: "flex", alignItems: "center", height: "100%", marginLeft: "auto" }
4044
+ },
4045
+ /* @__PURE__ */ React13__default.createElement(IconDotsVertical, { size: "1.2rem" })
4046
+ )), /* @__PURE__ */ React13__default.createElement(Menu.Dropdown, null, menuPanels.map((panel) => /* @__PURE__ */ React13__default.createElement(
4047
+ Menu.Item,
4048
+ {
4049
+ key: panel.key,
4050
+ onClick: () => handleMenuItemClick(panel.key),
4051
+ color: value === panel.key ? theme.primaryColor : void 0,
4052
+ fw: value === panel.key ? 700 : void 0
4053
+ },
4054
+ t(panel.label)
4055
+ )))))
3935
4056
  );
3936
4057
  }
3937
4058
  var PreviewModeSwitch = (props) => {
@@ -3976,7 +4097,10 @@ var PreviewModeSwitch = (props) => {
3976
4097
  var toolbarSx = (t) => ({
3977
4098
  background: t.colorScheme === "dark" ? t.black : t.white,
3978
4099
  borderRadius: t.radius.xl,
3979
- height: "fit-content"
4100
+ height: "fit-content",
4101
+ svg: {
4102
+ height: 15
4103
+ }
3980
4104
  });
3981
4105
  function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3982
4106
  const { toolbarConfig } = useSettings();
@@ -3987,7 +4111,7 @@ function ToolbarButton({ icon, label, onClick = () => void 0 }) {
3987
4111
  py: { base: "0.2rem", md: 0 },
3988
4112
  sx: (t) => ({ "& svg path": { stroke: t.colorScheme === "dark" ? "white" : "black" } })
3989
4113
  },
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))
4114
+ /* @__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
4115
  );
3992
4116
  }
3993
4117
  function TourButton() {
@@ -4012,15 +4136,17 @@ function Toolbar({
4012
4136
  }) {
4013
4137
  const { translate: t } = useTranslation();
4014
4138
  const theme = useMantineTheme();
4015
- const smallerThanLg = useMediaQuery(`(max-width: ${theme.breakpoints.lg}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.lg) ? "" : "px"})`);
4139
+ const smallerThanLg = useMediaQuery(
4140
+ `(max-width: ${theme.breakpoints.xs}${/(?:px|em|rem|vh|vw|%)$/.test(theme.breakpoints.xs) ? "" : "px"})`
4141
+ );
4016
4142
  const { toolbarConfig } = useSettings();
4017
4143
  const settings = /* @__PURE__ */ React13__default.createElement(
4018
4144
  Flex,
4019
4145
  {
4020
- direction: { base: "column", lg: "row" },
4146
+ direction: { base: "column", xs: "row" },
4021
4147
  justify: "flex-start",
4022
4148
  sx: toolbarSx,
4023
- p: "0.325rem",
4149
+ p: "0.25rem",
4024
4150
  px: "md",
4025
4151
  wrap: "nowrap",
4026
4152
  gap: "xs"
@@ -4036,7 +4162,7 @@ function Toolbar({
4036
4162
  }
4037
4163
  )
4038
4164
  );
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;
4165
+ 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
4166
  }
4041
4167
  var QueryContext = createContext(void 0);
4042
4168
  function QueryProvider({ children, defaultCube }) {
@@ -4214,267 +4340,85 @@ function useQueryItem() {
4214
4340
  }
4215
4341
  return context;
4216
4342
  }
4217
-
4218
- // src/components/ExplorerResults.tsx
4219
- var useStyles2 = createStyles(() => ({
4220
- container: {
4221
- minHeight: "40vh",
4222
- display: "flex",
4223
- flexFlow: "column nowrap"
4343
+ var createContext4 = (name4) => {
4344
+ const Context = React13__default.createContext(void 0);
4345
+ const useContext4 = () => {
4346
+ const ctx = React13__default.useContext(Context);
4347
+ if (ctx === void 0) {
4348
+ throw new Error(`useContext for must be inside a ${name4}Provider with a value`);
4349
+ }
4350
+ return ctx;
4351
+ };
4352
+ return [useContext4, Context.Provider];
4353
+ };
4354
+ var Graph = class {
4355
+ constructor() {
4356
+ this.nodes = /* @__PURE__ */ new Set([]);
4357
+ this.adjList = {};
4358
+ this.items = [];
4359
+ this.topicOrder = {};
4224
4360
  }
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
- );
4361
+ addTopicOrder(topic, order) {
4362
+ this.topicOrder[topic] = Number(order);
4249
4363
  }
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), ".")
4364
+ getTopicOrder(topic) {
4365
+ return this.topicOrder[topic] || 0;
4366
+ }
4367
+ addNode(node) {
4368
+ this.nodes.add(node);
4369
+ if (!this.adjList[node]) this.adjList[node] = /* @__PURE__ */ new Set([]);
4370
+ }
4371
+ addEdge(node1, node2) {
4372
+ this.adjList[node1].add(node2);
4373
+ this.adjList[node2].add(node1);
4374
+ }
4375
+ removeEdge(node1, node2) {
4376
+ const indexOfNode2 = this.adjList[node1] && this.adjList[node1].indexOf(node2);
4377
+ const indexOfNode1 = this.adjList[node2] && this.adjList[node2].indexOf(node1);
4378
+ const badIndices = this.adjList[node1] === void 0 || this.adjList[node2] === void 0;
4379
+ if (badIndices) {
4380
+ return "Please pass in valid indices";
4381
+ } else {
4382
+ this.adjList[node1].splice(indexOfNode2, 1);
4383
+ this.adjList[node2].splice(indexOfNode1, 1);
4384
+ }
4385
+ }
4386
+ isType(locale, node, type) {
4387
+ return this.items.find((item) => getAnnotation(item, type, locale) == node);
4388
+ }
4389
+ isTable(locale, node) {
4390
+ return this.items.filter((item) => getAnnotation(item, "table", locale) == node);
4391
+ }
4392
+ getTopic(startingNode, locale) {
4393
+ let found = false;
4394
+ let topic = null;
4395
+ this.breadthFirstTraversal(startingNode, (node) => {
4396
+ if (this.isType(locale, node, "topic")) {
4397
+ if (!found) {
4398
+ found = true;
4399
+ topic = node;
4400
+ }
4258
4401
  }
4259
- );
4402
+ });
4403
+ return topic;
4260
4404
  }
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
- );
4405
+ getName(node, locale) {
4406
+ const item = this.items.find((item2) => item2.name === node);
4407
+ const name4 = item ? getAnnotation(item, "table", locale) : node;
4408
+ return name4;
4271
4409
  }
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" })
4410
+ getSubtopic(startingNode, locale) {
4411
+ let found = false;
4412
+ let subtopic = null;
4413
+ this.breadthFirstTraversal(startingNode, (node) => {
4414
+ if (this.isType(locale, node, "subtopic")) {
4415
+ if (!found) {
4416
+ found = true;
4417
+ subtopic = node;
4418
+ }
4279
4419
  }
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;
4420
+ });
4421
+ return subtopic;
4478
4422
  }
4479
4423
  filter(locale, filter) {
4480
4424
  function addItemToSubtopic(map2, subtopic, item) {
@@ -4639,24 +4583,12 @@ function SideBarControlBtn({ actionIconProps = {} }) {
4639
4583
  /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4640
4584
  );
4641
4585
  }
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
4586
  function SideBar(props) {
4655
4587
  const { expanded, input, setExpanded, setInput } = useSideBar();
4656
4588
  const { translate: t } = useTranslation();
4657
4589
  const theme = useMantineTheme();
4658
4590
  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(
4591
+ return /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(
4660
4592
  Box,
4661
4593
  {
4662
4594
  id: "dex-sidebar",
@@ -4686,6 +4618,7 @@ function SideBar(props) {
4686
4618
  Group,
4687
4619
  {
4688
4620
  position: "apart",
4621
+ align: "center",
4689
4622
  noWrap: true,
4690
4623
  sx: {
4691
4624
  overflow: "hidden",
@@ -4694,7 +4627,18 @@ function SideBar(props) {
4694
4627
  width: expanded ? 300 : 0
4695
4628
  }
4696
4629
  },
4697
- /* @__PURE__ */ React13__default.createElement(Text, { sx: (t2) => ({ color: t2.colorScheme === "dark" ? t2.white : t2.black }), ml: "sm" }, t("params.label_dataset"))
4630
+ /* @__PURE__ */ React13__default.createElement(Text, { sx: (t2) => ({ color: t2.colorScheme === "dark" ? t2.white : t2.black }), ml: "sm" }, t("params.label_dataset")),
4631
+ /* @__PURE__ */ React13__default.createElement(
4632
+ ActionIcon,
4633
+ {
4634
+ onClick: () => setExpanded(!expanded),
4635
+ variant: "subtle",
4636
+ mt: "auto",
4637
+ color: "primaryColor",
4638
+ sx: (t2) => ({ alignSelf: "flex-end" })
4639
+ },
4640
+ 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" })
4641
+ )
4698
4642
  )), /* @__PURE__ */ React13__default.createElement(
4699
4643
  Box,
4700
4644
  {
@@ -4718,27 +4662,6 @@ function SideBar(props) {
4718
4662
  })
4719
4663
  },
4720
4664
  /* @__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
4665
  ))
4743
4666
  ));
4744
4667
  }
@@ -4799,6 +4722,229 @@ function CubeSearchInput(props) {
4799
4722
  }
4800
4723
  );
4801
4724
  }
4725
+
4726
+ // src/components/ExplorerResults.tsx
4727
+ function SideBarControlBtn2({ actionIconProps = {} }) {
4728
+ const { expanded, setExpanded } = useSideBar();
4729
+ const sx = (t) => ({
4730
+ alignSelf: "center",
4731
+ color: t.colorScheme === "dark" ? t.white : t.colors.gray[7]
4732
+ });
4733
+ return /* @__PURE__ */ React13__default.createElement(Group, { spacing: "xs", display: { base: "flex", md: "none" }, align: "center" }, /* @__PURE__ */ React13__default.createElement(
4734
+ ActionIcon,
4735
+ {
4736
+ onClick: () => setExpanded(!expanded),
4737
+ variant: "subtle",
4738
+ ...actionIconProps,
4739
+ sx: [sx, ...packSx(actionIconProps.sx)]
4740
+ },
4741
+ /* @__PURE__ */ React13__default.createElement(DataSetSVG, null)
4742
+ ), /* @__PURE__ */ React13__default.createElement(Text, { size: "sm" }, "Select Dataset"));
4743
+ }
4744
+ var useStyles2 = createStyles(() => ({
4745
+ container: {
4746
+ minHeight: "40vh",
4747
+ display: "flex",
4748
+ flexFlow: "column nowrap"
4749
+ }
4750
+ }));
4751
+ function ExplorerResults(props) {
4752
+ const {
4753
+ data: schema,
4754
+ isLoading: schemaLoading,
4755
+ isError: schemaError,
4756
+ error: schemaErrorDetail
4757
+ } = useServerSchema();
4758
+ const { transintionLocaleLoading } = useQueryItem();
4759
+ const { params } = useSelector$1(selectCurrentQueryItem);
4760
+ const cubeMap = (schema == null ? void 0 : schema.cubeMap) || {};
4761
+ const cube = cubeMap[params.cube];
4762
+ const { online: isServerOnline, url: serverUrl } = schema || {};
4763
+ const { translate: t } = useTranslation();
4764
+ const { classes, cx } = useStyles2();
4765
+ if (typeof window === "object" && window.navigator.onLine === false) {
4766
+ return /* @__PURE__ */ React13__default.createElement(
4767
+ FailureResult,
4768
+ {
4769
+ className: cx(classes.container, props.className),
4770
+ icon: /* @__PURE__ */ React13__default.createElement(IconWorld, { color: "orange", size: "5rem" }),
4771
+ title: t("results.error_disconnected_title")
4772
+ }
4773
+ );
4774
+ }
4775
+ if (isServerOnline === false) {
4776
+ return /* @__PURE__ */ React13__default.createElement(
4777
+ FailureResult,
4778
+ {
4779
+ className: cx(classes.container, props.className),
4780
+ icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" }),
4781
+ title: t("results.error_serveroffline_title"),
4782
+ 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), ".")
4783
+ }
4784
+ );
4785
+ }
4786
+ if (isServerOnline == null || !cube || schemaLoading || transintionLocaleLoading) {
4787
+ return /* @__PURE__ */ React13__default.createElement(
4788
+ Paper,
4789
+ {
4790
+ className: cx(classes.container, props.className),
4791
+ id: "query-results-transient",
4792
+ radius: 0
4793
+ },
4794
+ props.splash || null
4795
+ );
4796
+ }
4797
+ if (schemaError) {
4798
+ return /* @__PURE__ */ React13__default.createElement(
4799
+ FailureResult,
4800
+ {
4801
+ className: cx(classes.container, props.className),
4802
+ 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)),
4803
+ icon: /* @__PURE__ */ React13__default.createElement(IconAlertTriangle, { color: "orange", size: "5rem" })
4804
+ }
4805
+ );
4806
+ }
4807
+ return /* @__PURE__ */ React13__default.createElement(
4808
+ SuccessResult,
4809
+ {
4810
+ className: cx(classes.container, props.className),
4811
+ cube,
4812
+ panels: props.panels,
4813
+ params,
4814
+ panelKey: null
4815
+ },
4816
+ props.splash
4817
+ );
4818
+ }
4819
+ function FailureResult(props) {
4820
+ return /* @__PURE__ */ React13__default.createElement(
4821
+ Paper,
4822
+ {
4823
+ id: "query-results-failure",
4824
+ className: props.className,
4825
+ radius: 0,
4826
+ withBorder: true,
4827
+ sx: { justifyContent: "center" }
4828
+ },
4829
+ /* @__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)
4830
+ );
4831
+ }
4832
+ function SuccessResult(props) {
4833
+ const updateUrl = useUpdateUrl();
4834
+ const { cube, panels, params } = props;
4835
+ const { translate: t } = useTranslation();
4836
+ const { previewLimit, actions: actions2 } = useSettings();
4837
+ const queryItem = useSelector$1(selectCurrentQueryItem);
4838
+ const isPreviewMode = useSelector$1(selectIsPreviewMode);
4839
+ const fullscreen = useFullscreen();
4840
+ const { classes, cx } = useStyles2();
4841
+ const [CurrentComponent, panelKey, panelMeta] = useMemo(() => {
4842
+ const currentPanel = queryItem.panel || `${panels[0].key}-`;
4843
+ const [panelKey2, ...panelMeta2] = currentPanel.split("-");
4844
+ const panel = panels.find((item) => item.key === panelKey2) || panels[0];
4845
+ return [panel.component, panel.key, panelMeta2.join("-")];
4846
+ }, [panels, queryItem.panel]);
4847
+ const tabHandler = (newTab) => {
4848
+ actions2.switchPanel(newTab);
4849
+ updateUrl({ ...queryItem, panel: newTab });
4850
+ };
4851
+ const { table, isError, isLoading, data, columns, result, pagination, isFetching } = useTable({
4852
+ cube
4853
+ });
4854
+ if ((data == null ? void 0 : data.length) === 0 && !isLoading && !isError) {
4855
+ return /* @__PURE__ */ React13__default.createElement(
4856
+ FailureResult,
4857
+ {
4858
+ className: cx(classes.container, props.className),
4859
+ icon: /* @__PURE__ */ React13__default.createElement(IconBox, { color: "orange", size: "5rem" }),
4860
+ title: t("results.error_emptyresult_title"),
4861
+ description: t("results.error_emptyresult_detail")
4862
+ }
4863
+ );
4864
+ }
4865
+ return /* @__PURE__ */ React13__default.createElement(
4866
+ Flex,
4867
+ {
4868
+ gap: "xs",
4869
+ direction: "column",
4870
+ w: "100%",
4871
+ className: props.className,
4872
+ h: "100%",
4873
+ sx: { overflow: "hidden" }
4874
+ },
4875
+ /* @__PURE__ */ React13__default.createElement(
4876
+ Paper,
4877
+ {
4878
+ ref: fullscreen.ref,
4879
+ id: "query-results-success",
4880
+ h: "100%",
4881
+ sx: { display: "flex", flexDirection: "column", overflow: "hidden" }
4882
+ },
4883
+ /* @__PURE__ */ React13__default.createElement(
4884
+ Flex,
4885
+ {
4886
+ sx: (t2) => ({
4887
+ alignItems: "center",
4888
+ background: t2.colorScheme === "dark" ? t2.colors.dark[7] : t2.colors.gray[1],
4889
+ justifyContent: "space-between",
4890
+ [t2.fn.smallerThan("md")]: {
4891
+ flexDirection: "column",
4892
+ justifyContent: "flex-start",
4893
+ alignItems: "flex-start"
4894
+ }
4895
+ }),
4896
+ w: "100%",
4897
+ h: "fit-content"
4898
+ },
4899
+ /* @__PURE__ */ React13__default.createElement(ExplorerTabs, { panels, onChange: tabHandler, value: panelKey }),
4900
+ (!queryItem.panel || queryItem.panel === "table") && /* @__PURE__ */ React13__default.createElement(
4901
+ Group,
4902
+ {
4903
+ sx: (t2) => ({
4904
+ display: "flex",
4905
+ flex: "0 1 auto",
4906
+ gap: "0.5rem",
4907
+ [t2.fn.smallerThan("md")]: {
4908
+ width: "100%",
4909
+ order: -1,
4910
+ padding: t2.spacing.sm,
4911
+ justifyContent: "space-between"
4912
+ }
4913
+ }),
4914
+ mr: "sm",
4915
+ noWrap: true
4916
+ },
4917
+ /* @__PURE__ */ React13__default.createElement(SideBarControlBtn2, null),
4918
+ /* @__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))
4919
+ )
4920
+ ),
4921
+ 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))),
4922
+ /* @__PURE__ */ React13__default.createElement(
4923
+ Box,
4924
+ {
4925
+ id: "query-results-content",
4926
+ sx: { flex: "1 1 calc(100% - 70px)", maxHeight: "calc(100% - 70px)" }
4927
+ },
4928
+ /* @__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(
4929
+ CurrentComponent,
4930
+ {
4931
+ panelKey: `${panelKey}-${panelMeta}`,
4932
+ cube,
4933
+ params,
4934
+ data,
4935
+ result,
4936
+ table,
4937
+ isError,
4938
+ isLoading,
4939
+ columns,
4940
+ pagination,
4941
+ isFetching
4942
+ }
4943
+ ))))
4944
+ )
4945
+ )
4946
+ );
4947
+ }
4802
4948
  function Results(props) {
4803
4949
  const { graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2 } = props;
4804
4950
  const { classes } = useStyles3();
@@ -5120,7 +5266,7 @@ function ExplorerContent(props) {
5120
5266
  const SplashComponent = props.splash;
5121
5267
  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
5268
  }, [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(
5269
+ 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
5270
  ExplorerResults,
5125
5271
  {
5126
5272
  className: classes.flexCol,
@@ -5128,7 +5274,7 @@ function ExplorerContent(props) {
5128
5274
  splash,
5129
5275
  serverURL: props.serverURL
5130
5276
  }
5131
- )));
5277
+ ))));
5132
5278
  }
5133
5279
  function usePivotTableData() {
5134
5280
  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.9",
3
+ "version": "1.1.11",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [