@datawheel/data-explorer 1.0.18 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.d.mts CHANGED
@@ -1194,6 +1194,7 @@ type TableView = {
1194
1194
  table: MRT_TableInstance<TData>;
1195
1195
  getColumn(id: string): AnyResultColumn | undefined;
1196
1196
  columns: AnyResultColumn[];
1197
+ setPagination: (pagination: MRT_PaginationState) => void;
1197
1198
  } & ViewProps;
1198
1199
  declare function TableView({ table, isError, isLoading, data, pagination, setPagination, result }: TableView): React.JSX.Element;
1199
1200
  declare namespace TableView {
package/dist/main.mjs CHANGED
@@ -1879,7 +1879,8 @@ function useUpdateUrl() {
1879
1879
  return useCallback(
1880
1880
  (query) => {
1881
1881
  const currPermalink = window.location.search.slice(1);
1882
- const nextPermalink = serializePermalink(query || queryItem);
1882
+ const q = query != null ? query : queryItem;
1883
+ const nextPermalink = serializePermalink(q);
1883
1884
  if (currPermalink !== nextPermalink) {
1884
1885
  navigate(`?${nextPermalink}`, { replace: true });
1885
1886
  }
@@ -2153,61 +2154,6 @@ function useAsync(initialState4) {
2153
2154
  };
2154
2155
  }
2155
2156
 
2156
- // src/components/Select.tsx
2157
- init_esm_shims();
2158
- var SelectObject = forwardRef(function(props, ref) {
2159
- var _a;
2160
- const {
2161
- getLabel,
2162
- getValue = identity,
2163
- items,
2164
- onItemSelect,
2165
- selectedItem,
2166
- selectProps = {}
2167
- } = props;
2168
- const [itemList, itemMap] = useMemo(() => {
2169
- const valueAccessor = accesorFactory(getValue);
2170
- const labelAccessor = getLabel ? accesorFactory(getLabel) : valueAccessor;
2171
- const list = items.map((item) => ({
2172
- label: labelAccessor(item),
2173
- value: valueAccessor(item),
2174
- item
2175
- }));
2176
- return [list, keyBy(list, (option) => option.value)];
2177
- }, [items, getLabel, getValue]);
2178
- const selected = useMemo(() => {
2179
- if (selectedItem == null) return null;
2180
- if (typeof selectedItem === "string") return selectedItem;
2181
- const valueAccessor = accesorFactory(getValue);
2182
- return valueAccessor(selectedItem);
2183
- }, [selectedItem, getValue]);
2184
- const itemSelectHandler = (value) => {
2185
- onItemSelect && onItemSelect(itemMap[value].item);
2186
- };
2187
- if (items.length === 0 || !selected) {
2188
- return null;
2189
- }
2190
- return /* @__PURE__ */ React13__default.createElement(
2191
- Select,
2192
- {
2193
- ref,
2194
- data: itemList,
2195
- disabled: props.loading || props.disabled,
2196
- hidden: props.hidden,
2197
- label: props.label,
2198
- onChange: itemSelectHandler,
2199
- onClick: inputFocusHandler,
2200
- onFocus: inputFocusHandler,
2201
- searchable: (_a = props.searchable) != null ? _a : props.items.length > 6,
2202
- value: selected,
2203
- ...selectProps
2204
- }
2205
- );
2206
- });
2207
- function inputFocusHandler(event) {
2208
- if (event.target instanceof HTMLInputElement) event.target.select();
2209
- }
2210
-
2211
2157
  // src/components/CubeSource.tsx
2212
2158
  init_esm_shims();
2213
2159
 
@@ -2331,7 +2277,8 @@ function useDownloadQuery() {
2331
2277
  extension: format2.replace(/json\w+/, "json"),
2332
2278
  name: `${params.cube}_${(/* @__PURE__ */ new Date()).toISOString()}`
2333
2279
  };
2334
- }
2280
+ },
2281
+ throwOnError: false
2335
2282
  });
2336
2283
  }
2337
2284
  function useFetchQuery(queryParams, queryLink, options) {
@@ -2420,6 +2367,61 @@ function CubeSource() {
2420
2367
 
2421
2368
  // src/components/LocaleSelector.tsx
2422
2369
  init_esm_shims();
2370
+
2371
+ // src/components/Select.tsx
2372
+ init_esm_shims();
2373
+ var SelectObject = forwardRef(function(props, ref) {
2374
+ var _a;
2375
+ const {
2376
+ getLabel,
2377
+ getValue = identity,
2378
+ items,
2379
+ onItemSelect,
2380
+ selectedItem,
2381
+ selectProps = {}
2382
+ } = props;
2383
+ const [itemList, itemMap] = useMemo(() => {
2384
+ const valueAccessor = accesorFactory(getValue);
2385
+ const labelAccessor = getLabel ? accesorFactory(getLabel) : valueAccessor;
2386
+ const list = items.map((item) => ({
2387
+ label: labelAccessor(item),
2388
+ value: valueAccessor(item),
2389
+ item
2390
+ }));
2391
+ return [list, keyBy(list, (option) => option.value)];
2392
+ }, [items, getLabel, getValue]);
2393
+ const selected = useMemo(() => {
2394
+ if (selectedItem == null) return null;
2395
+ if (typeof selectedItem === "string") return selectedItem;
2396
+ const valueAccessor = accesorFactory(getValue);
2397
+ return valueAccessor(selectedItem);
2398
+ }, [selectedItem, getValue]);
2399
+ const itemSelectHandler = (value) => {
2400
+ onItemSelect && onItemSelect(itemMap[value].item);
2401
+ };
2402
+ if (items.length === 0 || !selected) {
2403
+ return null;
2404
+ }
2405
+ return /* @__PURE__ */ React13__default.createElement(
2406
+ Select,
2407
+ {
2408
+ ref,
2409
+ data: itemList,
2410
+ disabled: props.loading || props.disabled,
2411
+ hidden: props.hidden,
2412
+ label: props.label,
2413
+ onChange: itemSelectHandler,
2414
+ onClick: inputFocusHandler,
2415
+ onFocus: inputFocusHandler,
2416
+ searchable: (_a = props.searchable) != null ? _a : props.items.length > 6,
2417
+ value: selected,
2418
+ ...selectProps
2419
+ }
2420
+ );
2421
+ });
2422
+ function inputFocusHandler(event) {
2423
+ if (event.target instanceof HTMLInputElement) event.target.select();
2424
+ }
2423
2425
  var localeSelectorStyle = (theme) => ({
2424
2426
  input: {
2425
2427
  border: "none",
@@ -2506,10 +2508,12 @@ var formatter = new Intl.NumberFormat("en-US", {
2506
2508
  });
2507
2509
  function TableFooter(props) {
2508
2510
  const { paginationConfig } = useSettings();
2509
- const { table, data = [], isLoading, pagination, setPagination, url } = props;
2511
+ const { table, data = [], isLoading, pagination, url } = props;
2510
2512
  const { translate: t } = useTranslation();
2511
2513
  const { copy, copied } = useClipboard({ timeout: 1e3 });
2512
2514
  const copyHandler = useCallback(() => copy(url), [url]);
2515
+ const updateURL = useUpdateUrl();
2516
+ const queryItem = useSelector(selectCurrentQueryItem);
2513
2517
  const totalRowCount = table.options.rowCount;
2514
2518
  const {
2515
2519
  pagination: { pageSize }
@@ -2525,22 +2529,19 @@ function TableFooter(props) {
2525
2529
  },
2526
2530
  [paginationConfig == null ? void 0 : paginationConfig.rowsLimits]
2527
2531
  );
2528
- const selectedItem = useMemo(
2529
- () => items.find((item) => Number(item.value) === pageSize),
2530
- [items, pageSize]
2531
- );
2532
2532
  const onItemSelect = useCallback(
2533
2533
  (item) => {
2534
2534
  const newPageSize = Number(item.value);
2535
- if (setPagination) {
2536
- setPagination({
2537
- ...pagination,
2538
- pageSize: newPageSize,
2539
- pageIndex: 0
2540
- });
2541
- }
2535
+ updateURL({
2536
+ ...queryItem,
2537
+ params: {
2538
+ ...queryItem.params,
2539
+ pagiOffset: 0,
2540
+ pagiLimit: newPageSize
2541
+ }
2542
+ });
2542
2543
  },
2543
- [pagination, setPagination]
2544
+ [pagination]
2544
2545
  );
2545
2546
  return /* @__PURE__ */ React13__default.createElement(Box, { w: "100%", sx: { flex: "0 0 70px" } }, /* @__PURE__ */ React13__default.createElement(
2546
2547
  Flex,
@@ -2553,13 +2554,14 @@ function TableFooter(props) {
2553
2554
  },
2554
2555
  /* @__PURE__ */ React13__default.createElement(CubeSource, null),
2555
2556
  !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(
2556
- SelectObject,
2557
+ Select,
2557
2558
  {
2558
- getValue: (item) => item.value,
2559
- getLabel: (item) => item.label,
2560
- items,
2561
- selectedItem,
2562
- onItemSelect
2559
+ data: items,
2560
+ defaultValue: String(queryItem.params.pagiLimit),
2561
+ onChange: (value) => {
2562
+ const item = items.find((i) => i.value === value);
2563
+ if (item) onItemSelect(item);
2564
+ }
2563
2565
  }
2564
2566
  )), 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 }))
2565
2567
  ));
@@ -2672,11 +2674,6 @@ function useDownload(props) {
2672
2674
  }
2673
2675
  }
2674
2676
  }, [file]);
2675
- useEffect(() => {
2676
- if (error) {
2677
- console.error("Download error:", error);
2678
- }
2679
- }, [error]);
2680
2677
  const onClick = useCallback(
2681
2678
  (evt, cb = () => {
2682
2679
  }) => {
@@ -3042,13 +3039,12 @@ function useTable({
3042
3039
  const { limit, offset } = useSelector$1(selectPaginationParams);
3043
3040
  const queryItem = useSelector$1(selectCurrentQueryItem);
3044
3041
  const updateURL = useUpdateUrl();
3045
- const [pagination, setPagination] = useState({
3042
+ const pagination = {
3046
3043
  pageIndex: Math.floor(offset / (limit || 1)),
3047
3044
  pageSize: limit
3048
- });
3045
+ };
3049
3046
  const handlePaginationChange = (updatedPagination) => {
3050
3047
  const paginationUpdated = updatedPagination(pagination);
3051
- setPagination(updatedPagination);
3052
3048
  actions2.updatePagination({
3053
3049
  limit: paginationUpdated.pageSize,
3054
3050
  offset: paginationUpdated.pageIndex * paginationUpdated.pageSize
@@ -3268,7 +3264,6 @@ function useTable({
3268
3264
  showRowsPerPage: false
3269
3265
  },
3270
3266
  paginationDisplayMode: "pages",
3271
- enableRowVirtualization: false,
3272
3267
  globalFilterFn: "contains",
3273
3268
  initialState: {
3274
3269
  density: "xs"
@@ -3354,8 +3349,7 @@ function useTable({
3354
3349
  isFetching,
3355
3350
  data: tableData,
3356
3351
  columns,
3357
- pagination,
3358
- setPagination: handlePaginationChange
3352
+ pagination
3359
3353
  };
3360
3354
  }
3361
3355
  function TableView({
@@ -3731,7 +3725,7 @@ function LevelItem({
3731
3725
  const actions2 = useActions();
3732
3726
  const cutItems = useSelector$1(selectCutItems);
3733
3727
  let drilldowns = useSelector$1(selectDrilldownMap);
3734
- const ditems = useSelector$1(selectDrilldownItems);
3728
+ useSelector$1(selectDrilldownItems);
3735
3729
  const { idFormatters } = useidFormatters();
3736
3730
  const label = useMemo(() => {
3737
3731
  const captions = [
@@ -3749,49 +3743,27 @@ function LevelItem({
3749
3743
  level: captions[2]
3750
3744
  });
3751
3745
  }, [locale, dimension, hierarchy, level, isSubMenu, t]);
3752
- const createCutHandler = useCallback((level2) => {
3753
- const cutItem = buildCut({ ...level2, members: [], active: false });
3754
- actions2.updateCut(cutItem);
3755
- }, []);
3756
- function createDrilldown(level2, cuts) {
3757
- const drilldown = buildDrilldown({ ...level2, key: level2.name, active: false });
3758
- actions2.updateDrilldown(drilldown);
3759
- const cut2 = cuts.find((cut3) => cut3.level === drilldown.level);
3760
- if (!cut2) {
3761
- createCutHandler(level2);
3762
- }
3763
- return drilldown;
3764
- }
3765
3746
  const currentDrilldown = drilldowns[level.name];
3766
3747
  const isOtherHierarchySelected = activeItems.some(
3767
3748
  (activeItem) => activeItem.dimension === dimension.name && activeItem.hierarchy !== hierarchy.name
3768
3749
  );
3769
- useLayoutEffect(() => {
3770
- if (!drilldowns[level.name] && !ditems.find((d) => d.level === level.name)) {
3771
- createDrilldown(level, cutItems);
3772
- }
3773
- }, [level, ditems]);
3774
3750
  const cut = cutItems.find((cut2) => {
3775
3751
  return cut2.level === (currentDrilldown == null ? void 0 : currentDrilldown.level);
3776
3752
  });
3777
- const updatecutHandler = React13__default.useCallback((item, members) => {
3753
+ const updatecutHandler = (item, members) => {
3778
3754
  actions2.updateCut({ ...item, members });
3779
- }, []);
3755
+ };
3780
3756
  const checked = activeItems.map((i) => i.level).includes(level.name);
3781
3757
  const disableUncheck = activeItems.length === 1 && checked;
3782
3758
  const isDisabled = isOtherHierarchySelected && !checked;
3783
3759
  if (!currentDrilldown) return;
3784
3760
  const paddingLeft = `${5 * depth + 5}px`;
3785
- const properities = currentDrilldown.properties.length ? currentDrilldown.properties : null;
3761
+ const properties = currentDrilldown.properties.length ? currentDrilldown.properties : null;
3786
3762
  return currentDrilldown && /* @__PURE__ */ React13__default.createElement(React13__default.Fragment, null, /* @__PURE__ */ React13__default.createElement(Group, { className: "dex-level-control", mt: "sm", position: "apart", key: level.name, noWrap: true }, /* @__PURE__ */ React13__default.createElement(
3787
3763
  Checkbox,
3788
3764
  {
3789
3765
  sx: { cursor: "pointer", paddingLeft },
3790
3766
  onChange: () => {
3791
- if (cut) {
3792
- const active = checked ? false : !!cut.members.length;
3793
- actions2.updateCut({ ...cut, active });
3794
- }
3795
3767
  actions2.updateDrilldown({
3796
3768
  ...currentDrilldown,
3797
3769
  active: !currentDrilldown.active
@@ -3811,7 +3783,7 @@ function LevelItem({
3811
3783
  disabled: isDisabled
3812
3784
  },
3813
3785
  activeFilter ? /* @__PURE__ */ React13__default.createElement(IconFilterOff, null) : /* @__PURE__ */ React13__default.createElement(IconFilter, null)
3814
- ), properities && /* @__PURE__ */ React13__default.createElement(Tooltip, { label: t("params.add_metadata") }, /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: () => setActiveProperties((value) => !value) }, /* @__PURE__ */ React13__default.createElement(IconAdjustments, null))), /* @__PURE__ */ React13__default.createElement(ThemeIcon, { size: "xs", color: "gray", variant: "light", bg: "transparent" }, /* @__PURE__ */ React13__default.createElement(StackSVG, null)))), activeFilter && /* @__PURE__ */ React13__default.createElement(Box, { pt: "md" }, /* @__PURE__ */ React13__default.createElement(
3786
+ ), properties && /* @__PURE__ */ React13__default.createElement(Tooltip, { label: t("params.add_metadata") }, /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: () => setActiveProperties((value) => !value) }, /* @__PURE__ */ React13__default.createElement(IconAdjustments, null))), /* @__PURE__ */ React13__default.createElement(ThemeIcon, { size: "xs", color: "gray", variant: "light", bg: "transparent" }, /* @__PURE__ */ React13__default.createElement(StackSVG, null)))), activeFilter && /* @__PURE__ */ React13__default.createElement(Box, { pt: "md" }, /* @__PURE__ */ React13__default.createElement(
3815
3787
  MultiSelect,
3816
3788
  {
3817
3789
  sx: { flex: "1 1 100%" },
@@ -4272,8 +4244,13 @@ function QueryProvider({ children, defaultCube }) {
4272
4244
  const { tesseract } = useLogicLayer();
4273
4245
  const location2 = useLocation();
4274
4246
  const { updateCurrentQuery } = useActions();
4275
- const { paginationConfig, measuresActive, serverURL, defaultLocale } = useSettings();
4276
- const { data: schema, isLoading: schemaLoading, isError: schemaError } = useServerSchema();
4247
+ const { measuresActive, serverURL, defaultLocale } = useSettings();
4248
+ const {
4249
+ data: schema,
4250
+ isLoading: schemaLoading,
4251
+ isFetching: schemaFetching,
4252
+ isError: schemaError
4253
+ } = useServerSchema();
4277
4254
  const updateUrl = useUpdateUrl();
4278
4255
  const queryItem = useSelector$1(selectCurrentQueryItem);
4279
4256
  const prevLocaleRef = useRef();
@@ -4294,7 +4271,7 @@ function QueryProvider({ children, defaultCube }) {
4294
4271
  const searchParams = new URLSearchParams(location2.search);
4295
4272
  const cube = searchParams.get("cube");
4296
4273
  const cubeMap = (schema == null ? void 0 : schema.cubeMap) || void 0;
4297
- if (cube && cubeMap && serverURL && cubeMap[cube] && (schema == null ? void 0 : schema.online)) {
4274
+ if (cube && cubeMap && serverURL && cubeMap[cube] && (schema == null ? void 0 : schema.online) && !schemaFetching) {
4298
4275
  let newQuery = parsePermalink(cubeMap[cube], searchParams);
4299
4276
  newQuery = isValidQuery(newQuery == null ? void 0 : newQuery.params) ? newQuery : buildQuery({ params: { cube } });
4300
4277
  newQuery.params.locale = defaultLocale || newQuery.params.locale;
@@ -4321,7 +4298,8 @@ function QueryProvider({ children, defaultCube }) {
4321
4298
  key: lvl.name,
4322
4299
  dimension: dimensions[name4],
4323
4300
  hierarchy: hierarchies[name4],
4324
- level: name4
4301
+ level: name4,
4302
+ properties: lvl.properties.map((prop) => buildProperty({ level: lvl.name, name: prop.name }))
4325
4303
  });
4326
4304
  });
4327
4305
  if (newQuery) {
@@ -4329,7 +4307,7 @@ function QueryProvider({ children, defaultCube }) {
4329
4307
  (dd) => {
4330
4308
  const currentDrilldown = queryItem.params.drilldowns[dd.key];
4331
4309
  const localeChanged = prevLocaleRef.current !== (newQuery == null ? void 0 : newQuery.params.locale);
4332
- if (currentDrilldown && currentDrilldown.members && currentDrilldown.members.length > 0 && !localeChanged) {
4310
+ if (currentDrilldown && currentDrilldown.members && currentDrilldown.members.length > 0 && !localeChanged && cube === queryItem.params.cube) {
4333
4311
  return Promise.resolve({
4334
4312
  drilldown: currentDrilldown,
4335
4313
  cut: buildCut({ ...currentDrilldown, active: false })
@@ -4371,7 +4349,15 @@ function QueryProvider({ children, defaultCube }) {
4371
4349
  const cubeDefault = defaultCube && hasProperty(cubeMap, defaultCube) ? defaultCube : Object.keys(cubeMap)[0];
4372
4350
  setDefaultValues(cubeMap[cubeDefault]);
4373
4351
  }
4374
- }, [location2.search, runFetchMembers, schema, schemaLoading, serverURL, defaultLocale]);
4352
+ }, [
4353
+ location2.search,
4354
+ runFetchMembers,
4355
+ schema,
4356
+ schemaLoading,
4357
+ schemaFetching,
4358
+ serverURL,
4359
+ defaultLocale
4360
+ ]);
4375
4361
  const onChangeCube = (table, subtopic) => {
4376
4362
  const locale = defaultLocale || queryItem.params.locale;
4377
4363
  const cubeMap = (schema == null ? void 0 : schema.cubeMap) || {};
@@ -4416,18 +4402,16 @@ function QueryProvider({ children, defaultCube }) {
4416
4402
  });
4417
4403
  updateUrl(query);
4418
4404
  }
4419
- return /* @__PURE__ */ React13__default.createElement(
4420
- QueryContext.Provider,
4421
- {
4422
- value: {
4423
- onChangeCube,
4424
- schemaLoading,
4425
- membersLoading,
4426
- transintionLocaleLoading
4427
- }
4428
- },
4429
- children
4405
+ const contextValue = React13__default.useMemo(
4406
+ () => ({
4407
+ onChangeCube,
4408
+ schemaLoading,
4409
+ membersLoading,
4410
+ transintionLocaleLoading
4411
+ }),
4412
+ [onChangeCube, schemaLoading, membersLoading, transintionLocaleLoading]
4430
4413
  );
4414
+ return /* @__PURE__ */ React13__default.createElement(QueryContext.Provider, { value: contextValue }, children);
4431
4415
  }
4432
4416
  function useQueryItem() {
4433
4417
  const context = useContext(QueryContext);
@@ -4545,7 +4529,7 @@ function SuccessResult(props) {
4545
4529
  actions2.switchPanel(newTab);
4546
4530
  updateUrl({ ...queryItem, panel: newTab });
4547
4531
  };
4548
- const { table, isError, isLoading, data, columns, result, pagination, isFetching, setPagination } = useTable({
4532
+ const { table, isError, isLoading, data, columns, result, pagination, isFetching } = useTable({
4549
4533
  cube
4550
4534
  });
4551
4535
  if ((data == null ? void 0 : data.length) === 0 && !isLoading && !isError) {
@@ -4611,7 +4595,6 @@ function SuccessResult(props) {
4611
4595
  isLoading,
4612
4596
  columns,
4613
4597
  pagination,
4614
- setPagination,
4615
4598
  isFetching
4616
4599
  }
4617
4600
  ))))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [