@datawheel/data-explorer 1.3.0 → 1.3.2

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
@@ -220,6 +220,7 @@ interface TesseractLevel {
220
220
  properties: TesseractProperty[];
221
221
  type?: "geo" | "time" | string;
222
222
  count?: number;
223
+ time_scale?: string;
223
224
  }
224
225
  interface TesseractProperty {
225
226
  name: string;
@@ -475,6 +476,7 @@ interface ViewProps<TData extends Record<string, any> = Record<string, string |
475
476
  table?: MRT_TableInstance<TData & Record<string, any>>;
476
477
  isError?: boolean;
477
478
  isLoading?: boolean;
479
+ isFetching?: boolean;
478
480
  data?: Record<string, string | number>[];
479
481
  columns?: MRT_ColumnDef<TData>[];
480
482
  pagination?: MRT_PaginationState;
package/dist/main.mjs CHANGED
@@ -1,6 +1,6 @@
1
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, MantineProvider, Alert, Space, Modal, Tooltip, useComponentDefaultProps, Skeleton, Anchor, Paper, packSx, CloseButton, Tabs, ThemeIcon, Drawer, Switch, Divider, Accordion, Popover, Checkbox } from '@mantine/core';
2
2
  import { useClipboard, useDebouncedState, useMediaQuery, useFullscreen, useDisclosure } from '@mantine/hooks';
3
- import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconAlertCircle, IconAlertTriangle, IconLanguage, IconCopy, IconArrowLeft, IconArrowRight, IconX, IconChevronLeft, IconChevronRight, IconVectorTriangle, IconPhotoDown, IconDownload, IconArrowsMinimize, IconArrowsMaximize, IconCheck, IconShare, IconSearch, IconBox, IconDotsVertical, IconTrash, IconPlus, IconStack3, IconInfoCircleFilled, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconHelpCircle, IconFilterOff, IconFilter, IconClock, IconAdjustments } from '@tabler/icons-react';
3
+ import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconWorldWww, IconClipboardCheck, IconAlertCircle, IconAlertTriangle, IconLanguage, IconCopy, IconArrowLeft, IconArrowRight, IconX, IconChevronLeft, IconChevronRight, IconVectorTriangle, IconPhotoDown, IconDownload, IconArrowsMinimize, IconArrowsMaximize, IconCheck, IconShare, IconSearch, IconDotsVertical, IconTrash, IconPlus, IconStack3, IconInfoCircleFilled, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconHelpCircle, IconFilterOff, IconFilter, IconBox, IconClock, IconAdjustments } from '@tabler/icons-react';
4
4
  import * as React15 from 'react';
5
5
  import React15__default, { createContext, forwardRef, useMemo, useCallback, useContext, useRef, useEffect, useState, Suspense, useLayoutEffect } from 'react';
6
6
  import { translationFactory } from '@datawheel/use-translation';
@@ -1179,18 +1179,31 @@ function describeData(cube, params, result) {
1179
1179
  const entityResult = entityFinder(cube, column);
1180
1180
  if (!entityResult) return null;
1181
1181
  const [entity] = entityResult;
1182
+ let entityType;
1183
+ if (hasProperty(entity, "aggregator")) {
1184
+ entityType = "measure";
1185
+ } else if (hasProperty(entity, "depth")) {
1186
+ entityType = "level";
1187
+ } else {
1188
+ entityType = "property";
1189
+ }
1182
1190
  const typeSet = new Set(result.data.map((item) => typeof item[column]));
1183
- const valueType = typeSet.size === 1 ? typeSet.has("number") ? "number" : typeSet.has("boolean") ? "boolean" : (
1184
- /* else */
1185
- "string"
1186
- ) : typeSet.has("number") ? "number" : "string";
1191
+ let valueType;
1192
+ if (entityType === "measure" || typeSet.has("number")) {
1193
+ valueType = "number";
1194
+ } else if (typeSet.size === 1 && typeSet.has("boolean")) {
1195
+ valueType = "boolean";
1196
+ } else {
1197
+ valueType = "string";
1198
+ }
1187
1199
  const isId = column !== entity.name;
1188
- const entityType = hasProperty(entity, "aggregator") ? "measure" : hasProperty(entity, "depth") ? "level" : "property";
1200
+ const caption = getCaption(entity, locale) || column;
1201
+ const localeLabel = isId ? `${caption} ID` : caption;
1189
1202
  return [
1190
1203
  column,
1191
1204
  {
1192
1205
  label: column,
1193
- localeLabel: getCaption(entity, locale) + (isId ? " ID" : "") || column,
1206
+ localeLabel,
1194
1207
  entity,
1195
1208
  entityType,
1196
1209
  isId,
@@ -1974,12 +1987,8 @@ function pickDefaultDrilldowns(dimensions, cube) {
1974
1987
  for (const dimension of dimensions) {
1975
1988
  if (dimension.type === "time" || requiredDimensions.includes(dimension.name) || levels.length < 4) {
1976
1989
  const hierarchy = findDefaultHierarchy(dimension);
1977
- const hierarchyDepth = Math.max(...hierarchy.levels.map((l) => l.depth));
1978
1990
  const levelIndex = dimension.type === "geo" ? hierarchy.levels.length - 1 : 0;
1979
1991
  const defaultLevel = hierarchy.levels[levelIndex];
1980
- if (dimension.type === "time" && dimension.annotations.de_time_complete === "true" && defaultLevel.depth < hierarchyDepth) {
1981
- timeComplete = defaultLevel.name;
1982
- }
1983
1992
  levels.push({ ...defaultLevel, type: dimension.type });
1984
1993
  }
1985
1994
  }
@@ -2004,6 +2013,25 @@ function pickDefaultDrilldowns(dimensions, cube) {
2004
2013
  }
2005
2014
  }
2006
2015
  }
2016
+ for (const dimension of dimensions) {
2017
+ if (dimension.annotations.de_time_complete === "true") {
2018
+ const hierarchy = findDefaultHierarchy(dimension);
2019
+ const hierarchyLevels = hierarchy.levels;
2020
+ const availableLevels = hierarchyLevels.filter((hl) => levels.some((l) => l.name === hl.name));
2021
+ if (availableLevels.length > 0) {
2022
+ const timeCompleteLevel = availableLevels.reduce(
2023
+ (prev, curr) => curr.depth < prev.depth ? curr : prev
2024
+ );
2025
+ const deepestLevel = hierarchyLevels.reduce(
2026
+ (prev, curr) => curr.depth > prev.depth ? curr : prev
2027
+ );
2028
+ const deepestLevelSelected = availableLevels.some((l) => l.depth === deepestLevel.depth);
2029
+ if (timeCompleteLevel.depth < deepestLevel.depth && !deepestLevelSelected) {
2030
+ timeComplete = timeCompleteLevel.name;
2031
+ }
2032
+ }
2033
+ }
2034
+ }
2007
2035
  let totalCount = calcMaxMemberCount(levels.map((l) => l.count));
2008
2036
  while (totalCount > 5e6) {
2009
2037
  const geoIndex = levels.findIndex((level) => level.type === "geo");
@@ -3258,7 +3286,8 @@ function useTable({
3258
3286
  range,
3259
3287
  isId
3260
3288
  } = keyCol;
3261
- const isNumeric = valueType === "number" && !/Year/i.test(columnKey);
3289
+ const isYearDrilldown = entityType === "level" && entity.time_scale && /Year/i.test(columnKey);
3290
+ const isNumeric = valueType === "number" && !isYearDrilldown;
3262
3291
  const formatterKey = getFormat(
3263
3292
  "aggregator" in entity ? entity : columnKey,
3264
3293
  isNumeric ? "Decimal" : "identity"
@@ -3758,7 +3787,8 @@ var MultiFilter = ({ header }) => {
3758
3787
  ));
3759
3788
  };
3760
3789
  var NoRecords = React15__default.memo(() => {
3761
- return /* @__PURE__ */ React15__default.createElement(Center, { style: { height: "calc(100% - 210px)" } }, /* @__PURE__ */ React15__default.createElement(Text, { size: "xl", color: "gray", italic: true }, "No records to display."));
3790
+ const { translate: t } = useTranslation();
3791
+ return /* @__PURE__ */ React15__default.createElement(Center, { style: { height: "calc(100% - 210px)" }, my: "xl" }, /* @__PURE__ */ React15__default.createElement(Text, { size: "md", color: "gray", italic: true }, t("results.error_emptyresult_detail")));
3762
3792
  });
3763
3793
  TableView.displayName = "TesseractExplorer:TableView";
3764
3794
 
@@ -4310,7 +4340,9 @@ function FilterItem2({
4310
4340
  onChange: () => {
4311
4341
  if (!isLastSelected) {
4312
4342
  actions2.updateMeasure({ ...measure, active: !measure.active });
4313
- actions2.updateFilter({ ...filter, active: !checked });
4343
+ if (checked) {
4344
+ actions2.updateFilter({ ...filter, active: false });
4345
+ }
4314
4346
  }
4315
4347
  },
4316
4348
  checked,
@@ -5022,17 +5054,6 @@ function SuccessResult(props) {
5022
5054
  const { table, isError, isLoading, data, columns, result, pagination, isFetching } = useTable({
5023
5055
  cube
5024
5056
  });
5025
- if ((data == null ? void 0 : data.length) === 0 && !isLoading && !isError) {
5026
- return /* @__PURE__ */ React15__default.createElement(
5027
- FailureResult,
5028
- {
5029
- className: cx(classes.container, props.className),
5030
- icon: /* @__PURE__ */ React15__default.createElement(IconBox, { color: "orange", size: "5rem" }),
5031
- title: t("results.error_emptyresult_title"),
5032
- description: t("results.error_emptyresult_detail")
5033
- }
5034
- );
5035
- }
5036
5057
  return /* @__PURE__ */ React15__default.createElement(
5037
5058
  Flex,
5038
5059
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "main": "./dist/main.mjs",
5
5
  "types": "./dist/main.d.mts",
6
6
  "files": [