@datawheel/data-explorer 0.2.10 → 0.2.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.js +107 -14
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { keyframes, createStyles, Select, rem, Flex, Title, Text, Group, Button, Input, Box, Stack, SimpleGrid, ScrollArea, LoadingOverlay, Table, MultiSelect, Center, NumberInput, Menu, ActionIcon, UnstyledButton, Alert, Loader, Container, Modal, useMantineTheme, MantineProvider, Paper, useComponentDefaultProps, Anchor, Tabs, Switch, ThemeIcon, Tooltip, CloseButton, Drawer, Divider, Checkbox, packSx, Affix, Accordion, Popover } from '@mantine/core';
2
2
  import { useClipboard, useClickOutside, useFullscreen, useDebouncedState, useMediaQuery, useDisclosure } from '@mantine/hooks';
3
- import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconArrowRight, IconArrowLeft, IconArrowsMinimize, IconArrowsMaximize, IconTrash, IconInfoCircleFilled, IconSearch, IconPhotoDown, IconVectorTriangle, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconBox, IconClock, IconHelpCircle, IconLanguage } from '@tabler/icons-react';
3
+ import { IconWorld, IconExternalLink, IconClipboard, IconSettings, IconMathGreater, IconMathLower, IconArrowsLeftRight, IconAlertCircle, IconAlertTriangle, IconCopy, IconDownload, IconDotsVertical, IconArrowRight, IconArrowLeft, IconArrowsMinimize, IconArrowsMaximize, IconTrash, IconInfoCircleFilled, IconSearch, IconPhotoDown, IconVectorTriangle, IconArrowsSort, IconSortDescendingNumbers, IconSortDescendingLetters, IconSortAscendingNumbers, IconSortAscendingLetters, IconPlus, IconStack3, IconFilterOff, IconFilter, IconAdjustments, IconBox, IconClock, IconHelpCircle, IconLanguage } 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, useLayoutEffect } from 'react';
6
6
  import { translationFactory } from '@datawheel/use-translation';
@@ -235,6 +235,7 @@ var defaultTranslation = {
235
235
  message_default: "Please wait..."
236
236
  },
237
237
  params: {
238
+ add_metadata: "Add metadata",
238
239
  action_clear: "Clear query",
239
240
  action_clear_description: "Clear all parameters from your current query",
240
241
  action_execute: "Execute query",
@@ -2197,7 +2198,7 @@ createSelector(
2197
2198
  selectOlapDimensionItems,
2198
2199
  (dimensions) => Object.fromEntries(dimensions.map((item) => [item.name, item]))
2199
2200
  );
2200
- createSelector(
2201
+ var selectLevelTriadMap = createSelector(
2201
2202
  selectOlapCube,
2202
2203
  (cube) => cube ? mapDimensionHierarchyLevels(cube) : {}
2203
2204
  );
@@ -2804,7 +2805,16 @@ function FullScreenSVG() {
2804
2805
  function isColumnSorted(column, key) {
2805
2806
  return column == key;
2806
2807
  }
2807
- var removeColumn = (actions2, entity, measures, drilldowns) => {
2808
+ var propertiesUpdateHandler = (actions2, item, activeProps) => {
2809
+ const properties = item.properties.map(
2810
+ (prop) => buildProperty({
2811
+ ...prop,
2812
+ active: activeProps.includes(prop.key)
2813
+ })
2814
+ );
2815
+ actions2.updateDrilldown({ ...item, properties });
2816
+ };
2817
+ var removeColumn = (actions2, entity, measures, drilldowns, type) => {
2808
2818
  if ("aggregator" in entity) {
2809
2819
  const measure = measures.find((d) => d.name === entity.name);
2810
2820
  measure && actions2.updateMeasure({ ...measure, active: false });
@@ -2813,10 +2823,21 @@ var removeColumn = (actions2, entity, measures, drilldowns) => {
2813
2823
  const drilldown = drilldowns.find((d) => d.level === entity.name);
2814
2824
  drilldown && actions2.updateDrilldown({ ...drilldown, active: false });
2815
2825
  }
2826
+ if (isProperty(type)) {
2827
+ const activeDrilldowns = drilldowns.filter((d) => d.active);
2828
+ const drilldown = activeDrilldowns.find(
2829
+ (dd) => dd.properties.some((property) => property.name === entity.name)
2830
+ );
2831
+ const activeProperties = drilldown == null ? void 0 : drilldown.properties.filter((p) => p.active).filter((p) => p.name !== entity.name).filter((p) => p.active).map((p) => p.name);
2832
+ if (drilldown && activeProperties) {
2833
+ propertiesUpdateHandler(actions2, drilldown, activeProperties);
2834
+ }
2835
+ }
2816
2836
  };
2837
+ var isProperty = (entity) => entity === "property";
2817
2838
  function showTrashIcon(columns, type) {
2818
2839
  const result = columns.filter((c) => c.entityType === type);
2819
- return result.length > 1;
2840
+ return result.length > 1 || isProperty(type);
2820
2841
  }
2821
2842
  var getActionIcon = (entityType) => {
2822
2843
  if (entityType === "measure") {
@@ -2831,6 +2852,8 @@ var getEntityText = (entityType) => {
2831
2852
  return "Metric";
2832
2853
  case "level":
2833
2854
  return "Dimension";
2855
+ case "property":
2856
+ return "Property";
2834
2857
  default:
2835
2858
  return "";
2836
2859
  }
@@ -3100,7 +3123,7 @@ function useTable({
3100
3123
  label: `At least one ${getEntityText(entityType)} is required.`,
3101
3124
  key: `remove-${column2.columnDef.header}`,
3102
3125
  disabled: !showTrashIcon(finalKeys, entityType),
3103
- onClick: () => removeColumn(actions2, entity, measures, drilldowns),
3126
+ onClick: () => removeColumn(actions2, entity, measures, drilldowns, entityType),
3104
3127
  showTooltip: !showTrashIcon(finalKeys, entityType),
3105
3128
  size: 25,
3106
3129
  ml: rem(5)
@@ -3449,7 +3472,17 @@ function AddColumnsDrawer() {
3449
3472
  },
3450
3473
  /* @__PURE__ */ React13__default.createElement(MeasuresOptions, null),
3451
3474
  /* @__PURE__ */ React13__default.createElement(DrillDownOptions, null)
3452
- ), /* @__PURE__ */ React13__default.createElement(Group, { position: "center", sx: { flexWrap: "nowrap" } }, smallerThanMd ? /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React13__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React13__default.createElement(Button, { id: "dex-column-btn", leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }), onClick: open, m: "md", size: "sm" }, t("params.add_columns"))));
3475
+ ), /* @__PURE__ */ React13__default.createElement(Group, { position: "center", sx: { flexWrap: "nowrap" } }, smallerThanMd ? /* @__PURE__ */ React13__default.createElement(ActionIcon, { onClick: open, size: "md", variant: "filled", color: theme.primaryColor }, /* @__PURE__ */ React13__default.createElement(IconStack3, { size: "0.75rem" })) : /* @__PURE__ */ React13__default.createElement(
3476
+ Button,
3477
+ {
3478
+ id: "dex-column-btn",
3479
+ leftIcon: /* @__PURE__ */ React13__default.createElement(IconPlus, { size: "1.2rem" }),
3480
+ onClick: open,
3481
+ m: "md",
3482
+ size: "sm"
3483
+ },
3484
+ t("params.add_columns")
3485
+ )));
3453
3486
  }
3454
3487
  function DrillDownOptions() {
3455
3488
  const locale = useSelector$1(selectLocale);
@@ -3487,13 +3520,22 @@ function DimensionItem({
3487
3520
  activeItems
3488
3521
  }
3489
3522
  ));
3490
- return /* @__PURE__ */ React13__default.createElement("div", { key: dimension.name, className: "dex-dimension-control", id: `dex-dimension-${dimension.name}` }, /* @__PURE__ */ React13__default.createElement(
3491
- Divider,
3523
+ return /* @__PURE__ */ React13__default.createElement(
3524
+ "div",
3492
3525
  {
3493
- my: "md",
3494
- label: /* @__PURE__ */ React13__default.createElement(Group, null, getIconForDimensionType(dimension.type), /* @__PURE__ */ React13__default.createElement(Text, { italic: true }, getCaption(dimension, locale)))
3495
- }
3496
- ), options);
3526
+ key: dimension.name,
3527
+ className: "dex-dimension-control",
3528
+ id: `dex-dimension-${dimension.name}`
3529
+ },
3530
+ /* @__PURE__ */ React13__default.createElement(
3531
+ Divider,
3532
+ {
3533
+ my: "md",
3534
+ label: /* @__PURE__ */ React13__default.createElement(Group, null, getIconForDimensionType(dimension.type), /* @__PURE__ */ React13__default.createElement(Text, { italic: true }, getCaption(dimension, locale)))
3535
+ }
3536
+ ),
3537
+ options
3538
+ );
3497
3539
  }
3498
3540
  function HierarchyItem({
3499
3541
  dimension,
@@ -3543,6 +3585,7 @@ function LevelItem({
3543
3585
  depth = 0
3544
3586
  }) {
3545
3587
  const [activeFilter, setActiveFilter] = useState(false);
3588
+ const [activePropertiesFilter, setActiveProperties] = useState(false);
3546
3589
  const { translate: t } = useTranslation();
3547
3590
  const actions2 = useActions();
3548
3591
  const cutItems = useSelector$1(selectCutItems);
@@ -3603,6 +3646,7 @@ function LevelItem({
3603
3646
  const isDisabled = isOtherHierarchySelected && !checked;
3604
3647
  if (!currentDrilldown) return;
3605
3648
  const paddingLeft = `${5 * depth + 5}px`;
3649
+ const properities = currentDrilldown.properties.length ? currentDrilldown.properties : null;
3606
3650
  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(
3607
3651
  Checkbox,
3608
3652
  {
@@ -3631,7 +3675,7 @@ function LevelItem({
3631
3675
  disabled: isDisabled
3632
3676
  },
3633
3677
  activeFilter ? /* @__PURE__ */ React13__default.createElement(IconFilterOff, null) : /* @__PURE__ */ React13__default.createElement(IconFilter, null)
3634
- ), /* @__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(
3678
+ ), 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(
3635
3679
  MultiSelect,
3636
3680
  {
3637
3681
  sx: { flex: "1 1 100%" },
@@ -3655,7 +3699,56 @@ function LevelItem({
3655
3699
  nothingFound: "Nothing found",
3656
3700
  disabled: isDisabled
3657
3701
  }
3658
- )));
3702
+ )), activePropertiesFilter && /* @__PURE__ */ React13__default.createElement(PropertiesMultiSelect, { item: currentDrilldown }));
3703
+ }
3704
+ function PropertiesMultiSelect({ item }) {
3705
+ const levelTriadMap = useSelector$1(selectLevelTriadMap);
3706
+ const locale = useSelector$1(selectLocale);
3707
+ const actions2 = useActions();
3708
+ const { translate: t } = useTranslation();
3709
+ const propertiesUpdateHandler2 = useCallback(
3710
+ (activeProps) => {
3711
+ const properties = item.properties.map(
3712
+ (prop) => buildProperty({
3713
+ ...prop,
3714
+ active: activeProps.includes(prop.key)
3715
+ })
3716
+ );
3717
+ actions2.updateDrilldown({ ...item, properties });
3718
+ },
3719
+ [item]
3720
+ );
3721
+ const activeProperties = filterMap(
3722
+ item.properties,
3723
+ (item2) => isActiveItem(item2) ? item2.key : null
3724
+ );
3725
+ const label = useMemo(() => {
3726
+ const triad = levelTriadMap[`${item.level}`];
3727
+ const triadCaptions = triad.map((item2) => getCaption(item2, locale.code));
3728
+ return t("params.tag_drilldowns", {
3729
+ abbr: abbreviateFullName(triadCaptions, t("params.tag_drilldowns_abbrjoint")),
3730
+ dimension: triadCaptions[0],
3731
+ hierarchy: triadCaptions[1],
3732
+ level: triadCaptions[2],
3733
+ propCount: activeProperties.length
3734
+ });
3735
+ }, [activeProperties.join("-"), item, locale.code]);
3736
+ return /* @__PURE__ */ React13__default.createElement(Box, { pt: "md" }, /* @__PURE__ */ React13__default.createElement(
3737
+ MultiSelect,
3738
+ {
3739
+ sx: { flex: "1 1 100%" },
3740
+ searchable: true,
3741
+ onChange: propertiesUpdateHandler2,
3742
+ value: activeProperties || [],
3743
+ placeholder: `Filter by ${label}`,
3744
+ data: item.properties.map((property) => ({
3745
+ value: String(property.key),
3746
+ label: property.name
3747
+ })),
3748
+ clearable: true,
3749
+ nothingFound: "Nothing found"
3750
+ }
3751
+ ));
3659
3752
  }
3660
3753
  function getFilterfnKey(type) {
3661
3754
  switch (type) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/data-explorer",
3
- "version": "0.2.10",
3
+ "version": "0.2.11",
4
4
  "exports": {
5
5
  ".": {
6
6
  "import": "./dist/main.js"