@datawheel/data-explorer 1.4.0 → 1.4.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 +6 -0
- package/dist/main.mjs +103 -23
- package/package.json +1 -1
package/dist/main.d.mts
CHANGED
|
@@ -463,6 +463,7 @@ interface PropertyItem extends QueryParamsItem {
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
type Formatter = (value: number | null, locale?: string) => string;
|
|
466
|
+
type DrilldownFormatter = (value: string | null, locale?: string) => string;
|
|
466
467
|
interface PanelDescriptor {
|
|
467
468
|
key: string;
|
|
468
469
|
label: string;
|
|
@@ -1146,6 +1147,10 @@ declare function ExplorerComponent<Locale extends string>(props: {
|
|
|
1146
1147
|
* that are displayed next to the value.
|
|
1147
1148
|
* */
|
|
1148
1149
|
idFormatters?: Record<string, Formatter>;
|
|
1150
|
+
/**
|
|
1151
|
+
* Defines an index of formatter functions available for drilldowns.
|
|
1152
|
+
* */
|
|
1153
|
+
drilldownFormatters?: Record<string, DrilldownFormatter>;
|
|
1149
1154
|
/**
|
|
1150
1155
|
* Defines an alternative height for the component structure.
|
|
1151
1156
|
* @default "100vh"
|
|
@@ -1333,6 +1338,7 @@ interface SettingsContextProps {
|
|
|
1333
1338
|
defaultMembersFilter: "id" | "name" | "any";
|
|
1334
1339
|
formatters: Record<string, Formatter>;
|
|
1335
1340
|
idFormatters: Record<string, Formatter>;
|
|
1341
|
+
drilldownFormatters: Record<string, DrilldownFormatter>;
|
|
1336
1342
|
previewLimit: number;
|
|
1337
1343
|
panels: PanelDescriptor[];
|
|
1338
1344
|
paginationConfig: Pagination;
|
package/dist/main.mjs
CHANGED
|
@@ -600,6 +600,7 @@ function SettingsProvider(props) {
|
|
|
600
600
|
defaultMembersFilter: props.defaultMembersFilter || "id",
|
|
601
601
|
formatters: props.formatters || {},
|
|
602
602
|
idFormatters: props.idFormatters || {},
|
|
603
|
+
drilldownFormatters: props.drilldownFormatters || {},
|
|
603
604
|
panels: props.panels,
|
|
604
605
|
previewLimit: props.previewLimit || 50,
|
|
605
606
|
paginationConfig: (_a = props.pagination) != null ? _a : { rowsLimits: [100, 300, 500, 1e3], defaultLimit: 100 },
|
|
@@ -713,6 +714,10 @@ function useidFormatters() {
|
|
|
713
714
|
const { idFormatters } = useSettings();
|
|
714
715
|
return { idFormatters };
|
|
715
716
|
}
|
|
717
|
+
function useDrilldownFormatters() {
|
|
718
|
+
const { drilldownFormatters } = useSettings();
|
|
719
|
+
return { drilldownFormatters };
|
|
720
|
+
}
|
|
716
721
|
|
|
717
722
|
// src/utils/structs.ts
|
|
718
723
|
function buildQuery(props) {
|
|
@@ -3318,6 +3323,7 @@ function useTable({
|
|
|
3318
3323
|
const { translate: t } = useTranslation();
|
|
3319
3324
|
const { getFormat, getFormatter } = useFormatter();
|
|
3320
3325
|
const { idFormatters } = useidFormatters();
|
|
3326
|
+
const { drilldownFormatters } = useDrilldownFormatters();
|
|
3321
3327
|
const { sortKey, sortDir } = useSelector$1(selectSortingParams);
|
|
3322
3328
|
const theme = useMantineTheme();
|
|
3323
3329
|
const isSmallerThanMd = useMediaQuery(
|
|
@@ -3471,6 +3477,8 @@ function useTable({
|
|
|
3471
3477
|
const row = cell.row;
|
|
3472
3478
|
const cellId = row.original[`${cell.column.id} ID`];
|
|
3473
3479
|
const idFormatter = idFormatters[`${keyCol.localeLabel} ID`];
|
|
3480
|
+
const drilldownFormatter = drilldownFormatters[`${keyCol.localeLabel}`] || drilldownFormatters[`${entity.name}`];
|
|
3481
|
+
const formattedValue = drilldownFormatter ? drilldownFormatter(cellValue, locale) : cellValue;
|
|
3474
3482
|
return /* @__PURE__ */ React15__default.createElement(Flex, { justify: "space-between", sx: { width: "100%", maxWidth: 400 }, gap: "sm" }, /* @__PURE__ */ React15__default.createElement(
|
|
3475
3483
|
Text,
|
|
3476
3484
|
{
|
|
@@ -3481,7 +3489,7 @@ function useTable({
|
|
|
3481
3489
|
textOverflow: "ellipsis"
|
|
3482
3490
|
}
|
|
3483
3491
|
},
|
|
3484
|
-
|
|
3492
|
+
formattedValue
|
|
3485
3493
|
), /* @__PURE__ */ React15__default.createElement(Box, null, cellId && /* @__PURE__ */ React15__default.createElement(Text, { color: "dimmed" }, idFormatter ? idFormatter(cellId) : cellId)));
|
|
3486
3494
|
}
|
|
3487
3495
|
};
|
|
@@ -3782,12 +3790,13 @@ var MultiFilter = ({ header }) => {
|
|
|
3782
3790
|
const { translate: t } = useTranslation();
|
|
3783
3791
|
const cutItems = useSelector$1(selectCutItems);
|
|
3784
3792
|
const drilldownItems = useSelector$1(selectDrilldownItems);
|
|
3785
|
-
useSelector$1(selectLocale);
|
|
3786
|
-
header.column.id;
|
|
3793
|
+
const locale = useSelector$1(selectLocale);
|
|
3794
|
+
const label = header.column.id;
|
|
3787
3795
|
const localeLabel = header.column.columnDef.header;
|
|
3788
3796
|
const drilldown = drilldownItems.find((d) => d.level === header.column.id);
|
|
3789
3797
|
const actions2 = useActions();
|
|
3790
3798
|
const { idFormatters } = useidFormatters();
|
|
3799
|
+
const { drilldownFormatters } = useDrilldownFormatters();
|
|
3791
3800
|
const navigate = useNavigate();
|
|
3792
3801
|
const debouncedUpdateUrl = useMemo(
|
|
3793
3802
|
() => debounce((query2) => {
|
|
@@ -3831,11 +3840,13 @@ var MultiFilter = ({ header }) => {
|
|
|
3831
3840
|
value: cut.members || [],
|
|
3832
3841
|
data: drilldown.members.map((m) => {
|
|
3833
3842
|
const idFormatter = idFormatters[`${localeLabel} ID`];
|
|
3843
|
+
const drilldownFormatter = drilldownFormatters[`${localeLabel}`] || drilldownFormatters[`${label}`];
|
|
3834
3844
|
const formattedKey = idFormatter ? idFormatter(m.key) : m.key;
|
|
3835
3845
|
const key = formattedKey ? `(${formattedKey})` : formattedKey;
|
|
3846
|
+
const formattedCaption = drilldownFormatter ? drilldownFormatter(m.caption || m.key, locale.code) : m.caption;
|
|
3836
3847
|
return {
|
|
3837
3848
|
value: `${m.key}`,
|
|
3838
|
-
label:
|
|
3849
|
+
label: formattedCaption ? `${formattedCaption} ${key}` : `${key}`
|
|
3839
3850
|
};
|
|
3840
3851
|
}),
|
|
3841
3852
|
clearButtonProps: { "aria-label": "Clear selection" },
|
|
@@ -4008,6 +4019,7 @@ function LevelItem({
|
|
|
4008
4019
|
const drilldowns = useSelector$1(selectDrilldownMap);
|
|
4009
4020
|
useSelector$1(selectDrilldownItems);
|
|
4010
4021
|
const { idFormatters } = useidFormatters();
|
|
4022
|
+
const { drilldownFormatters } = useDrilldownFormatters();
|
|
4011
4023
|
const label = useMemo(() => {
|
|
4012
4024
|
const captions = [
|
|
4013
4025
|
getCaption(dimension, locale),
|
|
@@ -4116,11 +4128,13 @@ function LevelItem({
|
|
|
4116
4128
|
value: (cut == null ? void 0 : cut.members) || [],
|
|
4117
4129
|
data: currentDrilldown.members.map((m) => {
|
|
4118
4130
|
const idFormatter = idFormatters[`${label} ID`];
|
|
4131
|
+
const drilldownFormatter = drilldownFormatters[`${label}`];
|
|
4119
4132
|
const formattedKey = idFormatter ? idFormatter(m.key) : m.key;
|
|
4120
4133
|
const key = formattedKey ? `(${formattedKey})` : formattedKey;
|
|
4134
|
+
const formattedCaption = drilldownFormatter ? drilldownFormatter(m.caption || m.key, locale) : m.caption;
|
|
4121
4135
|
return {
|
|
4122
4136
|
value: `${m.key}`,
|
|
4123
|
-
label:
|
|
4137
|
+
label: formattedCaption ? `${formattedCaption} ${key}` : `${key}`
|
|
4124
4138
|
};
|
|
4125
4139
|
}),
|
|
4126
4140
|
clearable: true,
|
|
@@ -4797,10 +4811,15 @@ function useBuildGraph(locale) {
|
|
|
4797
4811
|
const hide = getAnnotation(item, "hide_in_ui", locale);
|
|
4798
4812
|
if (!yn(hide)) {
|
|
4799
4813
|
graph2.addNode(topic);
|
|
4800
|
-
graph2.addNode(subtopic);
|
|
4801
4814
|
graph2.addNode(name4);
|
|
4802
|
-
|
|
4803
|
-
|
|
4815
|
+
if (subtopic) {
|
|
4816
|
+
const uniqueSubtopic = `${topic} - ${subtopic}`;
|
|
4817
|
+
graph2.addNode(uniqueSubtopic);
|
|
4818
|
+
graph2.addEdge(topic, uniqueSubtopic);
|
|
4819
|
+
graph2.addEdge(uniqueSubtopic, name4);
|
|
4820
|
+
} else {
|
|
4821
|
+
graph2.addEdge(topic, name4);
|
|
4822
|
+
}
|
|
4804
4823
|
if (topic_order) {
|
|
4805
4824
|
graph2.addTopicOrder(topic, topic_order);
|
|
4806
4825
|
}
|
|
@@ -5416,8 +5435,16 @@ function useAccordionValue(key, locale) {
|
|
|
5416
5435
|
const [value, setValue] = useState(null);
|
|
5417
5436
|
useEffect(() => {
|
|
5418
5437
|
if (selectedItem) {
|
|
5419
|
-
const
|
|
5420
|
-
|
|
5438
|
+
const topic = getAnnotation(selectedItem, "topic", locale);
|
|
5439
|
+
const subtopic = getAnnotation(selectedItem, "subtopic", locale);
|
|
5440
|
+
if (key === "subtopic" && subtopic) {
|
|
5441
|
+
setValue(`${key}-${topic} - ${subtopic}`);
|
|
5442
|
+
} else if (key === "topic") {
|
|
5443
|
+
setValue(`${key}-${topic}`);
|
|
5444
|
+
} else {
|
|
5445
|
+
const val = getAnnotation(selectedItem, key, locale);
|
|
5446
|
+
setValue(`${key}-${val}`);
|
|
5447
|
+
}
|
|
5421
5448
|
}
|
|
5422
5449
|
}, [key, selectedItem, locale]);
|
|
5423
5450
|
return { value, setValue };
|
|
@@ -5458,19 +5485,18 @@ function RootAccordions({ items, sortItems, graph, locale, selectedItem, sortLoc
|
|
|
5458
5485
|
const sortItem = sortItems.find(
|
|
5459
5486
|
(topic) => graph.topicOrder[topic] === graph.topicOrder[item]
|
|
5460
5487
|
) || item;
|
|
5461
|
-
return /* @__PURE__ */ React15__default.createElement(Accordion.Item, { value: `topic-${item}`, key: `topic-${item}` }, /* @__PURE__ */ React15__default.createElement(AccordionControl, null, item), /* @__PURE__ */ React15__default.createElement(Accordion.Panel, null, /* @__PURE__ */ React15__default.createElement(
|
|
5462
|
-
|
|
5488
|
+
return /* @__PURE__ */ React15__default.createElement(Accordion.Item, { value: `topic-${item}`, key: `topic-${item}` }, /* @__PURE__ */ React15__default.createElement(AccordionControl, null, item), /* @__PURE__ */ React15__default.createElement(Accordion.Panel, null, /* @__PURE__ */ React15__default.createElement("div", { style: { display: "flex", flexDirection: "column" } }, /* @__PURE__ */ React15__default.createElement(
|
|
5489
|
+
TopicChildren,
|
|
5463
5490
|
{
|
|
5464
5491
|
graph,
|
|
5465
5492
|
parent: item,
|
|
5466
5493
|
sortParent: sortItem,
|
|
5467
5494
|
items: graph.adjList[item],
|
|
5468
|
-
key: item,
|
|
5469
5495
|
locale,
|
|
5470
5496
|
sortLocale,
|
|
5471
5497
|
selectedItem
|
|
5472
5498
|
}
|
|
5473
|
-
)));
|
|
5499
|
+
))));
|
|
5474
5500
|
})
|
|
5475
5501
|
);
|
|
5476
5502
|
}
|
|
@@ -5514,6 +5540,56 @@ function CubeButton({
|
|
|
5514
5540
|
table != null ? table : item
|
|
5515
5541
|
);
|
|
5516
5542
|
}
|
|
5543
|
+
function TopicChildren({
|
|
5544
|
+
items,
|
|
5545
|
+
graph,
|
|
5546
|
+
parent,
|
|
5547
|
+
sortParent,
|
|
5548
|
+
selectedItem,
|
|
5549
|
+
locale,
|
|
5550
|
+
sortLocale
|
|
5551
|
+
}) {
|
|
5552
|
+
const { directCubes, subtopics } = useMemo(() => {
|
|
5553
|
+
const cubes = [];
|
|
5554
|
+
const folders = [];
|
|
5555
|
+
items.forEach((item) => {
|
|
5556
|
+
const cube = graph.items.find((c) => c.name === item);
|
|
5557
|
+
if (cube) {
|
|
5558
|
+
cubes.push(item);
|
|
5559
|
+
} else {
|
|
5560
|
+
folders.push(item);
|
|
5561
|
+
}
|
|
5562
|
+
});
|
|
5563
|
+
return { directCubes: cubes, subtopics: folders };
|
|
5564
|
+
}, [items, graph]);
|
|
5565
|
+
return /* @__PURE__ */ React15__default.createElement(React15__default.Fragment, null, directCubes.sort((a, b) => {
|
|
5566
|
+
const aLabel = graph.getName(a, sortLocale);
|
|
5567
|
+
const bLabel = graph.getName(b, sortLocale);
|
|
5568
|
+
return aLabel.localeCompare(bLabel, sortLocale, { sensitivity: "base" });
|
|
5569
|
+
}).map((cube, index) => /* @__PURE__ */ React15__default.createElement(
|
|
5570
|
+
CubeButton,
|
|
5571
|
+
{
|
|
5572
|
+
key: `direct-${cube}-${index}`,
|
|
5573
|
+
graph,
|
|
5574
|
+
item: cube,
|
|
5575
|
+
locale,
|
|
5576
|
+
sortLocale,
|
|
5577
|
+
selectedItem,
|
|
5578
|
+
parent: ""
|
|
5579
|
+
}
|
|
5580
|
+
)), subtopics.length > 0 && /* @__PURE__ */ React15__default.createElement(
|
|
5581
|
+
SubtopicAccordion,
|
|
5582
|
+
{
|
|
5583
|
+
items: subtopics,
|
|
5584
|
+
graph,
|
|
5585
|
+
parent,
|
|
5586
|
+
sortParent,
|
|
5587
|
+
selectedItem,
|
|
5588
|
+
locale,
|
|
5589
|
+
sortLocale
|
|
5590
|
+
}
|
|
5591
|
+
));
|
|
5592
|
+
}
|
|
5517
5593
|
function SubtopicAccordion({
|
|
5518
5594
|
items,
|
|
5519
5595
|
graph,
|
|
@@ -5551,29 +5627,32 @@ function SubtopicAccordion({
|
|
|
5551
5627
|
})
|
|
5552
5628
|
},
|
|
5553
5629
|
[...items].sort((a, b) => {
|
|
5630
|
+
const aName = a.split(" - ").pop();
|
|
5631
|
+
const bName = b.split(" - ").pop();
|
|
5554
5632
|
const aLabel = graph.items.find(
|
|
5555
|
-
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) ===
|
|
5633
|
+
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) === aName
|
|
5556
5634
|
);
|
|
5557
5635
|
const bLabel = graph.items.find(
|
|
5558
|
-
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) ===
|
|
5636
|
+
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) === bName
|
|
5559
5637
|
);
|
|
5560
|
-
const aSort = aLabel ? getAnnotation(aLabel, "subtopic", sortLocale) ||
|
|
5561
|
-
const bSort = bLabel ? getAnnotation(bLabel, "subtopic", sortLocale) ||
|
|
5638
|
+
const aSort = (aLabel ? getAnnotation(aLabel, "subtopic", sortLocale) : null) || aName || "";
|
|
5639
|
+
const bSort = (bLabel ? getAnnotation(bLabel, "subtopic", sortLocale) : null) || bName || "";
|
|
5562
5640
|
return aSort.localeCompare(bSort, sortLocale, { sensitivity: "base" });
|
|
5563
5641
|
}).map((item, index) => {
|
|
5564
5642
|
let sortSubtopic = item;
|
|
5643
|
+
const itemName = item.split(" - ").pop();
|
|
5565
5644
|
if (sortParent && item) {
|
|
5566
5645
|
const hasCubeInLocale = graph.items.some(
|
|
5567
|
-
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) ===
|
|
5646
|
+
(cube) => getAnnotation(cube, "topic", locale) === parent && getAnnotation(cube, "subtopic", locale) === itemName
|
|
5568
5647
|
);
|
|
5569
5648
|
if (hasCubeInLocale) {
|
|
5570
5649
|
const matchingCube = graph.items.find(
|
|
5571
|
-
(cube) => getAnnotation(cube, "topic", sortLocale) === sortParent && getAnnotation(cube, "subtopic", locale) ===
|
|
5650
|
+
(cube) => getAnnotation(cube, "topic", sortLocale) === sortParent && getAnnotation(cube, "subtopic", locale) === itemName
|
|
5572
5651
|
);
|
|
5573
5652
|
if (matchingCube) {
|
|
5574
5653
|
const annotatedSubtopic = getAnnotation(matchingCube, "subtopic", sortLocale);
|
|
5575
5654
|
if (annotatedSubtopic) {
|
|
5576
|
-
sortSubtopic = annotatedSubtopic
|
|
5655
|
+
sortSubtopic = `${sortParent} - ${annotatedSubtopic}`;
|
|
5577
5656
|
}
|
|
5578
5657
|
}
|
|
5579
5658
|
}
|
|
@@ -5586,7 +5665,7 @@ function SubtopicAccordion({
|
|
|
5586
5665
|
const bSort = bLabel ? getAnnotation(bLabel, "table", sortLocale) || b : b;
|
|
5587
5666
|
return aSort.localeCompare(bSort, sortLocale, { sensitivity: "base" });
|
|
5588
5667
|
}) : [];
|
|
5589
|
-
return /* @__PURE__ */ React15__default.createElement(Accordion.Item, { value: `subtopic-${item}`, key: `subtopic-${item}-${index}` }, /* @__PURE__ */ React15__default.createElement(AccordionControl, null, item), /* @__PURE__ */ React15__default.createElement(Accordion.Panel, null, filtered.map((table, index2) => /* @__PURE__ */ React15__default.createElement(
|
|
5668
|
+
return /* @__PURE__ */ React15__default.createElement(Accordion.Item, { value: `subtopic-${item}`, key: `subtopic-${item}-${index}` }, /* @__PURE__ */ React15__default.createElement(AccordionControl, null, item.split(" - ").pop()), /* @__PURE__ */ React15__default.createElement(Accordion.Panel, null, filtered.map((table, index2) => /* @__PURE__ */ React15__default.createElement(
|
|
5590
5669
|
CubeButton,
|
|
5591
5670
|
{
|
|
5592
5671
|
key: index2,
|
|
@@ -5595,7 +5674,7 @@ function SubtopicAccordion({
|
|
|
5595
5674
|
locale,
|
|
5596
5675
|
sortLocale,
|
|
5597
5676
|
selectedItem,
|
|
5598
|
-
parent: item
|
|
5677
|
+
parent: item.split(" - ").pop()
|
|
5599
5678
|
}
|
|
5600
5679
|
))));
|
|
5601
5680
|
})
|
|
@@ -6624,6 +6703,7 @@ function ExplorerComponent(props) {
|
|
|
6624
6703
|
defaultMembersFilter: props.defaultMembersFilter,
|
|
6625
6704
|
formatters: props.formatters,
|
|
6626
6705
|
idFormatters: props.idFormatters,
|
|
6706
|
+
drilldownFormatters: props.drilldownFormatters,
|
|
6627
6707
|
withPermalink: props.withPermalink,
|
|
6628
6708
|
panels,
|
|
6629
6709
|
pagination,
|