@datawheel/data-explorer 1.0.21 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/main.mjs +119 -152
  2. package/package.json +11 -7
package/dist/main.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { keyframes, createStyles, Select, rem, Input, Box, Text, Stack, Group, Button, SimpleGrid, Flex, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, NumberInput, Menu, ActionIcon, UnstyledButton, Loader, Container, Title, useMantineTheme, TextInput, CopyButton, Alert, MantineProvider, Modal, Space, useComponentDefaultProps, Paper, Anchor, Accordion, Tooltip, Tabs, Switch, ThemeIcon, CloseButton, Drawer, Divider, Checkbox, packSx, Affix, Popover } from '@mantine/core';
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
2
  import { useClipboard, useFullscreen, useDebouncedState, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
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';
4
4
  import * as React13 from 'react';
@@ -12,6 +12,7 @@ import { MRT_ProgressBar, flexRender, MRT_TableBodyCell, MRT_ToolbarAlertBanner,
12
12
  import { formatAbbreviate, format } from 'd3plus-format';
13
13
  import { QueryClient, useQuery, QueryClientProvider, keepPreviousData, useMutation } from '@tanstack/react-query';
14
14
  import _, { debounce } from 'lodash';
15
+ import { debounce as debounce$1 } from 'lodash-es';
15
16
  import { TourProvider, useTour } from '@reactour/tour';
16
17
  import yn from 'yn';
17
18
  import { matchSorter } from 'match-sorter';
@@ -2217,7 +2218,8 @@ function useServerSchema() {
2217
2218
  url: serverURL
2218
2219
  };
2219
2220
  }
2220
- }
2221
+ },
2222
+ staleTime: 3e5
2221
2223
  });
2222
2224
  }
2223
2225
  var useMeasureItems = () => {
@@ -2285,6 +2287,7 @@ function useFetchQuery(queryParams, queryLink, options) {
2285
2287
  const { tesseract } = useLogicLayer();
2286
2288
  const { limit = 0, offset = 0, withoutPagination = false } = options || {};
2287
2289
  const key = withoutPagination ? ["table", queryLink, "withoutPagination"] : ["table", queryLink];
2290
+ const { data: schema } = useServerSchema();
2288
2291
  return useQuery({
2289
2292
  queryKey: key,
2290
2293
  queryFn: async () => {
@@ -2307,10 +2310,10 @@ function useFetchQuery(queryParams, queryLink, options) {
2307
2310
  if (!response.ok) {
2308
2311
  throw new Error(`Backend Error: ${content.detail}`);
2309
2312
  }
2310
- const cubeData = await tesseract.fetchCube({
2311
- cube: queryParams.cube,
2312
- locale: queryParams.locale
2313
- });
2313
+ if (!(schema == null ? void 0 : schema.cubeMap[queryParams.cube])) {
2314
+ throw new Error("Cube not found");
2315
+ }
2316
+ const cubeData = schema == null ? void 0 : schema.cubeMap[queryParams.cube];
2314
2317
  return {
2315
2318
  data: content.data,
2316
2319
  page: content.page,
@@ -2979,31 +2982,6 @@ function getFiltersConditions(fn, value) {
2979
2982
  ]);
2980
2983
  return (_a = comparisonMap.get(fn)) == null ? void 0 : _a(value);
2981
2984
  }
2982
- var TableRefreshContext = React13__default.createContext(void 0);
2983
- function TableRefreshProvider({
2984
- children,
2985
- serverURL
2986
- }) {
2987
- const [isQueryEnabled, setQueryEnabled] = useState(true);
2988
- useEffect(() => {
2989
- setQueryEnabled(true);
2990
- }, [serverURL]);
2991
- const value = useMemo(
2992
- () => ({
2993
- isQueryEnabled,
2994
- setQueryEnabled
2995
- }),
2996
- [isQueryEnabled]
2997
- );
2998
- return /* @__PURE__ */ React13__default.createElement(TableRefreshContext.Provider, { value }, children);
2999
- }
3000
- function useTableRefresh() {
3001
- const context = useContext(TableRefreshContext);
3002
- if (context === void 0) {
3003
- throw new Error("useTableRefresh must be used within a TableRefreshProvider");
3004
- }
3005
- return context;
3006
- }
3007
2985
  function useTableData({ pagination }) {
3008
2986
  const queryItem = useSelector$1(selectCurrentQueryItem);
3009
2987
  const queryLink = queryItem.link;
@@ -3041,32 +3019,6 @@ function useTable({
3041
3019
  const { limit, offset } = useSelector$1(selectPaginationParams);
3042
3020
  const queryItem = useSelector$1(selectCurrentQueryItem);
3043
3021
  const updateURL = useUpdateUrl();
3044
- const pagination = {
3045
- pageIndex: Math.floor(offset / (limit || 1)),
3046
- pageSize: limit
3047
- };
3048
- const handlePaginationChange = (updatedPagination) => {
3049
- const paginationUpdated = updatedPagination(pagination);
3050
- actions2.updatePagination({
3051
- limit: paginationUpdated.pageSize,
3052
- offset: paginationUpdated.pageIndex * paginationUpdated.pageSize
3053
- });
3054
- updateURL({
3055
- ...queryItem,
3056
- params: {
3057
- ...queryItem.params,
3058
- pagiOffset: paginationUpdated.pageIndex * paginationUpdated.pageSize,
3059
- pagiLimit: paginationUpdated.pageSize
3060
- }
3061
- });
3062
- };
3063
- const finalUniqueKeys = useMemo(
3064
- () => [
3065
- ...measures.map((m) => m.active ? m.name : null),
3066
- ...drilldowns.map((d) => d.active ? d.level : null)
3067
- ].filter((a) => a !== null),
3068
- [measures, drilldowns]
3069
- );
3070
3022
  const handlerCreateMeasure = useCallback((data2) => {
3071
3023
  const measure = buildMeasure(data2);
3072
3024
  actions2.updateMeasure(measure);
@@ -3096,6 +3048,32 @@ function useTable({
3096
3048
  handlerCreateFilter,
3097
3049
  handlerCreateMeasure
3098
3050
  ]);
3051
+ const pagination = {
3052
+ pageIndex: Math.floor(offset / (limit || 1)),
3053
+ pageSize: limit
3054
+ };
3055
+ const handlePaginationChange = (updatedPagination) => {
3056
+ const paginationUpdated = updatedPagination(pagination);
3057
+ actions2.updatePagination({
3058
+ limit: paginationUpdated.pageSize,
3059
+ offset: paginationUpdated.pageIndex * paginationUpdated.pageSize
3060
+ });
3061
+ updateURL({
3062
+ ...queryItem,
3063
+ params: {
3064
+ ...queryItem.params,
3065
+ pagiOffset: paginationUpdated.pageIndex * paginationUpdated.pageSize,
3066
+ pagiLimit: paginationUpdated.pageSize
3067
+ }
3068
+ });
3069
+ };
3070
+ const finalUniqueKeys = useMemo(
3071
+ () => [
3072
+ ...measures.map((m) => m.active ? m.name : null),
3073
+ ...drilldowns.map((d) => d.active ? d.level : null)
3074
+ ].filter((a) => a !== null),
3075
+ [measures, drilldowns]
3076
+ );
3099
3077
  const { isLoading, isFetching, isError, data } = useTableData({
3100
3078
  columns: finalUniqueKeys,
3101
3079
  pagination,
@@ -3333,6 +3311,7 @@ function useTable({
3333
3311
  manualFiltering: true,
3334
3312
  manualPagination: true,
3335
3313
  manualSorting: true,
3314
+ enableRowVirtualization: false,
3336
3315
  rowCount: totalRowCount,
3337
3316
  state: {
3338
3317
  isLoading,
@@ -3367,6 +3346,7 @@ function TableView({
3367
3346
  const viewport = useRef(null);
3368
3347
  const rowRef = useRef(null);
3369
3348
  const url = (result == null ? void 0 : result.url) || "";
3349
+ useSelector$1(selectLocale);
3370
3350
  useEffect(() => {
3371
3351
  var _a;
3372
3352
  (_a = viewport.current) == null ? void 0 : _a.scrollTo({ top: 0, behavior: "smooth" });
@@ -3493,8 +3473,9 @@ var ColumnFilterCell = ({
3493
3473
  if (isNumeric) {
3494
3474
  return /* @__PURE__ */ React13__default.createElement(NumericFilter, { header });
3495
3475
  }
3476
+ return null;
3496
3477
  };
3497
- function NumericFilter({ header }) {
3478
+ var NumericFilter = ({ header }) => {
3498
3479
  const filters = useSelector$1(selectFilterItems);
3499
3480
  const { translate: t } = useTranslation();
3500
3481
  const filter = filters.find((f) => f.measure === header.column.id);
@@ -3504,11 +3485,13 @@ function NumericFilter({ header }) {
3504
3485
  const isBetween = filterFn === "between";
3505
3486
  return /* @__PURE__ */ React13__default.createElement(Flex, { gap: "xs", style: { fontWeight: "normal" } }, /* @__PURE__ */ React13__default.createElement(Box, { sx: { flex: "1 1 auto" } }, isBetween ? /* @__PURE__ */ React13__default.createElement(MinMax, { filter, hideControls: true }) : /* @__PURE__ */ React13__default.createElement(NumberInputComponent, { text, filter })), /* @__PURE__ */ React13__default.createElement(Box, { sx: { alignSelf: "flex-end" } }, /* @__PURE__ */ React13__default.createElement(FilterFnsMenu, { filter })));
3506
3487
  }
3507
- }
3508
- function MultiFilter({ header }) {
3488
+ return null;
3489
+ };
3490
+ var MultiFilter = ({ header }) => {
3509
3491
  const { translate: t } = useTranslation();
3510
3492
  const cutItems = useSelector$1(selectCutItems);
3511
3493
  const drilldownItems = useSelector$1(selectDrilldownItems);
3494
+ useSelector$1(selectLocale);
3512
3495
  header.column.id;
3513
3496
  const localeLabel = header.column.columnDef.header;
3514
3497
  const drilldown = drilldownItems.find((d) => d.level === header.column.id);
@@ -3540,7 +3523,8 @@ function MultiFilter({ header }) {
3540
3523
  [actions2]
3541
3524
  );
3542
3525
  const query = useSelector$1(selectCurrentQueryItem);
3543
- return drilldown && cut && /* @__PURE__ */ React13__default.createElement(Box, { pt: "md", style: { fontWeight: "normal" } }, /* @__PURE__ */ React13__default.createElement(
3526
+ if (!drilldown || !cut) return null;
3527
+ return /* @__PURE__ */ React13__default.createElement(Box, { pt: "md", style: { fontWeight: "normal" } }, /* @__PURE__ */ React13__default.createElement(
3544
3528
  MultiSelect,
3545
3529
  {
3546
3530
  sx: { flex: "1 1 100%" },
@@ -3569,10 +3553,10 @@ function MultiFilter({ header }) {
3569
3553
  size: "xs"
3570
3554
  }
3571
3555
  ));
3572
- }
3573
- var NoRecords = () => {
3574
- return /* @__PURE__ */ React13__default.createElement(Center, { style: { height: "calc(100% - 210px)" } }, /* @__PURE__ */ React13__default.createElement(Text, { size: "xl", color: "gray", italic: true }, "No records to display."));
3575
3556
  };
3557
+ var NoRecords = React13__default.memo(() => {
3558
+ return /* @__PURE__ */ React13__default.createElement(Center, { style: { height: "calc(100% - 210px)" } }, /* @__PURE__ */ React13__default.createElement(Text, { size: "xl", color: "gray", italic: true }, "No records to display."));
3559
+ });
3576
3560
  TableView.displayName = "TesseractExplorer:TableView";
3577
3561
  var styles = (t) => ({
3578
3562
  header: {
@@ -3898,7 +3882,7 @@ function NumberInputComponent({ text, filter }) {
3898
3882
  const updateUrl = useUpdateUrl();
3899
3883
  const queryItem = useSelector$1(selectCurrentQueryItem);
3900
3884
  const debouncedUpdateUrl = useMemo(
3901
- () => debounce((query) => {
3885
+ () => debounce$1((query) => {
3902
3886
  updateUrl(query);
3903
3887
  }, 1e3),
3904
3888
  []
@@ -3935,7 +3919,6 @@ function NumberInputComponent({ text, filter }) {
3935
3919
  }
3936
3920
  var MinMax = ({ filter, hideControls, ...rest }) => {
3937
3921
  const actions2 = useActions();
3938
- useTableRefresh();
3939
3922
  function onInputChangeMinMax(props) {
3940
3923
  const { filter: filter2, min: min2, max: max2 } = props;
3941
3924
  const conditions = getFiltersConditions(getFilterFn(filter2) || "greaterThan", [Number(min2), Number(max2)]) || {};
@@ -4259,12 +4242,7 @@ function QueryProvider({ children, defaultCube }) {
4259
4242
  function fetchMembers(level, localeStr, cubeName) {
4260
4243
  return tesseract.fetchMembers({ request: { cube: cubeName || "", level, locale: localeStr } });
4261
4244
  }
4262
- const {
4263
- run: runFetchMembers,
4264
- data: membersData,
4265
- isSuccess: isMembersSuccess,
4266
- isLoading: membersLoading
4267
- } = useAsync();
4245
+ const { run: runFetchMembers, isLoading: membersLoading } = useAsync();
4268
4246
  const [transintionLocaleLoading, setTransintionLocaleLoading] = React13__default.useState(false);
4269
4247
  useEffect(() => {
4270
4248
  if (schemaLoading) {
@@ -4612,14 +4590,14 @@ init_esm_shims();
4612
4590
  init_esm_shims();
4613
4591
  var createContext4 = (name4) => {
4614
4592
  const Context = React13__default.createContext(void 0);
4615
- const useContext5 = () => {
4593
+ const useContext4 = () => {
4616
4594
  const ctx = React13__default.useContext(Context);
4617
4595
  if (ctx === void 0) {
4618
4596
  throw new Error(`useContext for must be inside a ${name4}Provider with a value`);
4619
4597
  }
4620
4598
  return ctx;
4621
4599
  };
4622
- return [useContext5, Context.Provider];
4600
+ return [useContext4, Context.Provider];
4623
4601
  };
4624
4602
 
4625
4603
  // src/hooks/buildGraph.tsx
@@ -4804,8 +4782,7 @@ function useBuildGraph(locale) {
4804
4782
 
4805
4783
  // src/hooks/cubeSearch.tsx
4806
4784
  init_esm_shims();
4807
- function useCubeSearch(input, graph) {
4808
- const { code: locale } = useSelector(selectLocale);
4785
+ function useCubeSearch(graph, input, locale) {
4809
4786
  const results = useMemo(() => {
4810
4787
  if (graph.items.length > 0) {
4811
4788
  const { matches, map } = graph.filter(locale, input);
@@ -4818,17 +4795,17 @@ function useCubeSearch(input, graph) {
4818
4795
  results: [],
4819
4796
  map: /* @__PURE__ */ new Map()
4820
4797
  };
4821
- }, [input, graph]);
4798
+ }, [graph, input, locale]);
4822
4799
  return results;
4823
4800
  }
4824
4801
 
4825
4802
  // src/components/SideBar.tsx
4826
4803
  var [useSideBar, Provider] = createContext4("SideBar");
4827
4804
  function SideBarProvider(props) {
4828
- const [input, setInput] = useDebouncedState("", 200);
4805
+ const [input, setInput] = useDebouncedState("", 150, { leading: true });
4829
4806
  const [expanded, setExpanded] = useState(true);
4830
4807
  const graph = useBuildGraph(props.locale);
4831
- const { results, map } = useCubeSearch(input, graph);
4808
+ const { results, map } = useCubeSearch(graph, input, props.locale);
4832
4809
  return /* @__PURE__ */ React13__default.createElement(
4833
4810
  Provider,
4834
4811
  {
@@ -4876,7 +4853,7 @@ function SideBarControlBtnFixed() {
4876
4853
  return /* @__PURE__ */ React13__default.createElement(Affix, { position: { left: "1rem", bottom: 150 } }, /* @__PURE__ */ React13__default.createElement(SideBarControlBtn, { actionIconProps }));
4877
4854
  }
4878
4855
  function SideBar(props) {
4879
- const { expanded, setExpanded } = useSideBar();
4856
+ const { expanded, input, setExpanded, setInput } = useSideBar();
4880
4857
  const { translate: t } = useTranslation();
4881
4858
  const theme = useMantineTheme();
4882
4859
  const smallerThanMd = useMediaQuery(`(max-width: ${theme.breakpoints.md})`);
@@ -4930,7 +4907,7 @@ function SideBar(props) {
4930
4907
  width: expanded ? "100%" : 0
4931
4908
  }
4932
4909
  },
4933
- /* @__PURE__ */ React13__default.createElement(Auto, null)
4910
+ /* @__PURE__ */ React13__default.createElement(CubeSearchInput, { expanded, input, setInput })
4934
4911
  ), /* @__PURE__ */ React13__default.createElement(Box, { sx: { flexGrow: 1 } }))), /* @__PURE__ */ React13__default.createElement(
4935
4912
  ScrollArea,
4936
4913
  {
@@ -4967,7 +4944,7 @@ function SideBar(props) {
4967
4944
  ));
4968
4945
  }
4969
4946
  var SideBar_default = SideBar;
4970
- function SideBarItem({ children }) {
4947
+ function SideBarItem(props) {
4971
4948
  const { expanded } = useSideBar();
4972
4949
  return /* @__PURE__ */ React13__default.createElement(
4973
4950
  Box,
@@ -4979,15 +4956,15 @@ function SideBarItem({ children }) {
4979
4956
  transition: "width 0.2s cubic-bezier(0.4, 0, 0.2, 1)"
4980
4957
  }
4981
4958
  },
4982
- children
4959
+ props.children
4983
4960
  );
4984
4961
  }
4985
- function Auto() {
4962
+ function CubeSearchInput(props) {
4963
+ const { expanded, input, setInput } = props;
4986
4964
  const { translate: t } = useTranslation();
4987
- const { expanded, input, setInput } = useSideBar();
4988
4965
  const [inputValue, setInputValue] = useState(input);
4989
4966
  return /* @__PURE__ */ React13__default.createElement(
4990
- Input,
4967
+ TextInput,
4991
4968
  {
4992
4969
  icon: /* @__PURE__ */ React13__default.createElement(IconSearch, null),
4993
4970
  id: "dex-search",
@@ -5030,49 +5007,48 @@ init_esm_shims();
5030
5007
  // src/components/Results.tsx
5031
5008
  init_esm_shims();
5032
5009
  function Results(props) {
5033
- const { graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2, isSelectionInProgress } = props;
5010
+ const { graph, selectedItem, locale, getCube: getCube2, isSelected: isSelected2 } = props;
5034
5011
  const { classes } = useStyles3();
5035
5012
  const { setExpanded, setInput, map } = useSideBar();
5036
5013
  const { onChangeCube } = useQueryItem();
5037
- const result = [];
5038
- if (map) {
5039
- for (let [key, items] of map) {
5040
- const [topic, subtopic] = key.split(" - ");
5041
- const component = /* @__PURE__ */ React13__default.createElement("div", { key }, /* @__PURE__ */ React13__default.createElement(Divider, { my: "xs", label: key }), items.map((item) => {
5042
- const cube = getCube2(graph.items, item, subtopic, locale);
5043
- if (!cube) return null;
5044
- const table = getAnnotation(cube, "table", locale);
5045
- const isItemSelected = isSelected2(selectedItem, cube);
5046
- const handleClick = () => {
5047
- if (!isSelectionInProgress) {
5048
- onChangeCube(item, subtopic);
5049
- setExpanded(false);
5050
- setInput("");
5051
- }
5052
- };
5053
- return /* @__PURE__ */ React13__default.createElement(
5054
- Text,
5055
- {
5056
- key: cube.name,
5057
- component: "a",
5058
- fz: "xs",
5059
- className: isItemSelected ? `${classes.link} ${classes.linkActive}` : classes.link,
5060
- sx: (theme) => ({
5061
- opacity: isSelectionInProgress ? 0.5 : 1,
5062
- cursor: isSelectionInProgress ? "not-allowed" : "pointer",
5063
- transition: "opacity 0.2s ease",
5064
- pointerEvents: isSelectionInProgress ? "none" : "auto"
5065
- }),
5066
- onClick: handleClick
5067
- },
5068
- table
5069
- );
5070
- }));
5071
- result.push(component);
5072
- }
5073
- }
5074
- return /* @__PURE__ */ React13__default.createElement(Box, { px: "sm" }, result);
5014
+ const results = [...map].flatMap((entry) => {
5015
+ const [key, items] = entry;
5016
+ const [topic, subtopic] = key.split(" - ");
5017
+ const topicResults = items.map((item) => {
5018
+ const cube = getCube2(graph.items, item, subtopic, locale);
5019
+ if (!cube) return null;
5020
+ const table = getAnnotation(cube, "table", locale);
5021
+ const isItemSelected = isSelected2(selectedItem, cube);
5022
+ const handleClick = () => {
5023
+ onChangeCube(item, subtopic);
5024
+ setExpanded(false);
5025
+ setInput("");
5026
+ };
5027
+ return /* @__PURE__ */ React13__default.createElement(
5028
+ Text,
5029
+ {
5030
+ key: cube.name,
5031
+ component: "a",
5032
+ fz: "xs",
5033
+ className: isItemSelected ? `${classes.link} ${classes.linkActive}` : classes.link,
5034
+ sx: (theme) => ({
5035
+ opacity: 1,
5036
+ cursor: "pointer",
5037
+ transition: "opacity 0.2s ease",
5038
+ pointerEvents: "auto"
5039
+ }),
5040
+ onClick: handleClick
5041
+ },
5042
+ table
5043
+ );
5044
+ }).filter(Boolean);
5045
+ if (topicResults.length === 0) return [];
5046
+ const label = `${topic} - ${subtopic}`;
5047
+ return [/* @__PURE__ */ React13__default.createElement(Divider, { key: label, my: "xs", label }), ...topicResults];
5048
+ });
5049
+ return /* @__PURE__ */ React13__default.createElement(Box, { px: "sm" }, results.length ? results : "No results");
5075
5050
  }
5051
+ Results.displayName = "SearchResults";
5076
5052
  var useStyles3 = createStyles((t) => ({
5077
5053
  link: {
5078
5054
  ...t.fn.focusStyles(),
@@ -5097,12 +5073,18 @@ var useStyles3 = createStyles((t) => ({
5097
5073
  fontWeight: 500
5098
5074
  }
5099
5075
  }));
5100
- var Results_default = Results;
5101
5076
 
5102
5077
  // src/components/SelectCubes.tsx
5078
+ var loadingCubes = Array.from({ length: 10 }, (v, index) => ({
5079
+ id: `loading-cube-${index}`
5080
+ }));
5103
5081
  function SelectCubes({ locale }) {
5104
5082
  const items = useCubeItems();
5105
5083
  const selectedItem = useSelectedItem();
5084
+ const { schemaLoading } = useQueryItem();
5085
+ if (schemaLoading) {
5086
+ return loadingCubes.map((cube) => /* @__PURE__ */ React13__default.createElement(Skeleton, { m: 15, h: 40, w: "100%", animate: true, key: cube.id }));
5087
+ }
5106
5088
  if (items.length === 1) {
5107
5089
  return null;
5108
5090
  }
@@ -5132,20 +5114,18 @@ function isSelected(selectedItem, currentItem) {
5132
5114
  return selectedItem.name === currentItem.name;
5133
5115
  }
5134
5116
  }
5135
- function getCube(items, table, subtopic, locale) {
5117
+ function getCube(items, name4, subtopic, locale) {
5136
5118
  const cube = items.find(
5137
- (item) => item.name === table && getAnnotation(item, "subtopic", locale) === subtopic
5119
+ (item) => item.name === name4 && getAnnotation(item, "subtopic", locale) === subtopic
5138
5120
  );
5139
5121
  return cube;
5140
5122
  }
5141
5123
  function CubeTree({
5142
- items,
5143
5124
  locale,
5144
5125
  selectedItem
5145
5126
  }) {
5146
5127
  const { map, input, graph } = useSideBar();
5147
5128
  const { translate: t } = useTranslation();
5148
- const [isSelectionInProgress, setIsSelectionInProgress] = useState(false);
5149
5129
  let topics = useMemo(
5150
5130
  () => getKeys2(graph.items, "topic", locale),
5151
5131
  [graph.items, locale]
@@ -5154,25 +5134,15 @@ function CubeTree({
5154
5134
  return /* @__PURE__ */ React13__default.createElement(Text, { ta: "center", fz: "xs", my: "sm", italic: true }, t("params.label_no_results"));
5155
5135
  }
5156
5136
  return map && map.size > 0 ? /* @__PURE__ */ React13__default.createElement(
5157
- Results_default,
5137
+ Results,
5158
5138
  {
5159
5139
  selectedItem,
5160
5140
  getCube,
5161
5141
  isSelected,
5162
5142
  graph,
5163
- locale,
5164
- isSelectionInProgress
5165
- }
5166
- ) : graph.items.length > 0 && /* @__PURE__ */ React13__default.createElement(
5167
- RootAccordions,
5168
- {
5169
- items: topics,
5170
- graph,
5171
- selectedItem,
5172
- locale,
5173
- isSelectionInProgress
5143
+ locale
5174
5144
  }
5175
- );
5145
+ ) : graph.items.length > 0 && /* @__PURE__ */ React13__default.createElement(RootAccordions, { items: topics, graph, selectedItem, locale });
5176
5146
  }
5177
5147
  function useAccordionValue(key, locale) {
5178
5148
  const selectedItem = useSelectedItem();
@@ -5185,7 +5155,7 @@ function useAccordionValue(key, locale) {
5185
5155
  }, [key, selectedItem, locale]);
5186
5156
  return { value, setValue };
5187
5157
  }
5188
- function RootAccordions({ items, graph, locale, selectedItem, isSelectionInProgress }) {
5158
+ function RootAccordions({ items, graph, locale, selectedItem }) {
5189
5159
  const { value, setValue } = useAccordionValue("topic", locale);
5190
5160
  return /* @__PURE__ */ React13__default.createElement(
5191
5161
  Accordion,
@@ -5226,8 +5196,7 @@ function RootAccordions({ items, graph, locale, selectedItem, isSelectionInProgr
5226
5196
  items: graph.adjList[item],
5227
5197
  key: item,
5228
5198
  locale,
5229
- selectedItem,
5230
- isSelectionInProgress
5199
+ selectedItem
5231
5200
  }
5232
5201
  )));
5233
5202
  })
@@ -5277,8 +5246,7 @@ function SubtopicAccordion({
5277
5246
  graph,
5278
5247
  parent,
5279
5248
  selectedItem,
5280
- locale,
5281
- isSelectionInProgress
5249
+ locale
5282
5250
  }) {
5283
5251
  const { value, setValue } = useAccordionValue("subtopic", locale);
5284
5252
  return /* @__PURE__ */ React13__default.createElement(
@@ -5317,8 +5285,7 @@ function SubtopicAccordion({
5317
5285
  item: table,
5318
5286
  locale,
5319
5287
  selectedItem,
5320
- parent: item,
5321
- isSelectionInProgress
5288
+ parent: item
5322
5289
  }
5323
5290
  ))));
5324
5291
  })
@@ -6361,7 +6328,7 @@ function AppProviders({ children }) {
6361
6328
  updateUrl({ ...queryItem, params: { ...queryItem.params, locale: defaultLocale } });
6362
6329
  setLocale(defaultLocale);
6363
6330
  }, [defaultLocale, setLocale, actions2]);
6364
- return /* @__PURE__ */ React13.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React13.createElement(TableRefreshProvider, { serverURL }, /* @__PURE__ */ React13.createElement(
6331
+ return /* @__PURE__ */ React13.createElement(QueryClientProvider, { client: queryClient }, /* @__PURE__ */ React13.createElement(
6365
6332
  LogicLayerProvider,
6366
6333
  {
6367
6334
  serverURL,
@@ -6369,7 +6336,7 @@ function AppProviders({ children }) {
6369
6336
  defaultDataLocale
6370
6337
  },
6371
6338
  /* @__PURE__ */ React13.createElement(QueryProvider, { defaultCube, serverURL }, children)
6372
- )));
6339
+ ));
6373
6340
  }
6374
6341
  var defaultTourConfig = {
6375
6342
  extraSteps: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.0.21",
3
+ "version": "1.2.0",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [
@@ -8,11 +8,14 @@
8
8
  "README.md"
9
9
  ],
10
10
  "scripts": {
11
- "prepublishOnly": "npm run build",
12
- "build": "tsup",
13
- "dev": "vite serve",
14
- "preview": "vite preview",
15
- "static": "vite build --mode staging"
11
+ "dev": "vite",
12
+ "build:app": "vite build --mode staging",
13
+ "build:lib": "tsup",
14
+ "build": "npm run build:lib && npm run build:app",
15
+ "prepublishOnly": "npm run build:lib",
16
+ "pretest": "npm run build:lib",
17
+ "start": "vite serve",
18
+ "test": "echo 'no tests defined yet'"
16
19
  },
17
20
  "dependencies": {
18
21
  "@datawheel/use-translation": "^0.2.0",
@@ -30,6 +33,7 @@
30
33
  "iso-639-1": "^2.1.0",
31
34
  "lodash": "^4.17.21",
32
35
  "lodash.debounce": "^4.0.8",
36
+ "lodash-es": "^4.17.21",
33
37
  "mantine-react-table": "^1.3.0",
34
38
  "match-sorter": "^6.3.4",
35
39
  "postcss-modules": "^6.0.0",
@@ -72,4 +76,4 @@
72
76
  "vite": "^5.0.0",
73
77
  "wrangler": "^3.59.0"
74
78
  }
75
- }
79
+ }