@datawheel/bespoke 0.5.0 → 0.5.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/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { Group, Stack, Text, useMantineTheme, List, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, Tabs, TextInput, Code, Loader, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Container, Grid, Tooltip, createStyles, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, NumberInput, Autocomplete, Notification, Image, Header, px, Accordion, FileInput, SimpleGrid, Burger, Collapse, HoverCard, CopyButton, Breadcrumbs, Col } from '@mantine/core';
2
- import React, { forwardRef, useState, useCallback, useRef, useEffect, createContext, useContext, useMemo, Fragment as Fragment$1, memo, useImperativeHandle } from 'react';
1
+ import { Group, Stack, Text, useMantineTheme, List, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, Tabs, TextInput, Code, Loader, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Container, Grid, Tooltip, createStyles, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, NumberInput, Autocomplete, Notification, Image, Accordion, Header, px, FileInput, SimpleGrid, Burger, Collapse, CopyButton, HoverCard, Breadcrumbs, Col } from '@mantine/core';
2
+ import React, { forwardRef, useState, useCallback, useRef, useEffect, createContext, useContext, useMemo, Fragment as Fragment$1, createElement, memo, useImperativeHandle } from 'react';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
  import axios from 'axios';
5
5
  import * as d3Array from 'd3-array';
@@ -21,11 +21,12 @@ import { HYDRATE, createWrapper } from 'next-redux-wrapper';
21
21
  import { Notifications, notifications } from '@mantine/notifications';
22
22
  import { useDispatch, useSelector } from 'react-redux';
23
23
  import Router, { useRouter } from 'next/router';
24
- import { useClickOutside, useDisclosure, useDebouncedValue, useSetState, useUncontrolled, useHotkeys, getHotkeyHandler, useMediaQuery, useMergedRef, useFullscreen } from '@mantine/hooks';
25
- import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconUserCircle, IconEdit, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconDownload, IconCircleDashed, IconLanguage, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconListCheck, IconPolaroid, IconCircleMinus, IconInfoCircle, IconTable, IconCamera, IconShare, IconQuestionMark, IconCirclePlus, IconLogin, IconWorld, IconLock, IconCopy, IconBinaryTree, IconVariable, IconArrowRightCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconCode, IconPalette, IconBold, IconItalic, IconUnderline, IconAlignCenter, IconAlignRight, IconAlignJustified, IconArrowBackUp, IconArrowForwardUp, IconCheck, IconLanguageOff, IconTriangleInvertedFilled, IconDeviceFloppy, IconSettings, IconMinimize, IconMaximize, IconGlobe, IconLinkOff } from '@tabler/icons-react';
24
+ import { useClickOutside, useDisclosure, useDebouncedValue, useSetState, useUncontrolled, useHotkeys, useListState, randomId, getHotkeyHandler, useMediaQuery, useMergedRef, useFullscreen } from '@mantine/hooks';
25
+ import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconTable, IconUserCircle, IconEdit, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconDownload, IconCircleDashed, IconLanguage, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconListCheck, IconPolaroid, IconCircleMinus, IconInfoCircle, IconGripVertical, IconCamera, IconShare, IconQuestionMark, IconCirclePlus, IconLogin, IconWorld, IconLock, IconCopy, IconBinaryTree, IconVariable, IconArrowRightCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCheck, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconCode, IconPalette, IconBold, IconItalic, IconUnderline, IconAlignCenter, IconAlignRight, IconAlignJustified, IconArrowBackUp, IconArrowForwardUp, IconLanguageOff, IconTriangleInvertedFilled, IconDeviceFloppy, IconSettings, IconMinimize, IconMaximize, IconGlobe, IconLinkOff } from '@tabler/icons-react';
26
26
  import Link from 'next/link';
27
27
  import parse2, { Element as Element$1, domToReact, Text as Text$1 } from 'html-react-parser';
28
28
  import { UserProvider, withPageAuthRequired, useUser } from '@auth0/nextjs-auth0/client';
29
+ import { MantineReactTable } from 'mantine-react-table';
29
30
  import { dataConcat, dataLoad } from 'd3plus-viz';
30
31
  import * as d3plus from 'd3plus-react';
31
32
  import dynamic from 'next/dynamic';
@@ -44,8 +45,8 @@ import HardBreak from '@tiptap/extension-hard-break';
44
45
  import TextAlign from '@tiptap/extension-text-align';
45
46
  import Placeholder from '@tiptap/extension-placeholder';
46
47
  import Typography from '@tiptap/extension-typography';
48
+ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
47
49
  import { Prism } from '@mantine/prism';
48
- import { MantineReactTable } from 'mantine-react-table';
49
50
  import slugifyFn from 'slugify';
50
51
  import JSZip from 'jszip';
51
52
  import { saveAs } from 'file-saver';
@@ -53,7 +54,6 @@ import { select } from 'd3-selection';
53
54
  import { saveElement } from 'd3plus-export';
54
55
  import { FacebookShareButton, FacebookIcon, TwitterShareButton, TwitterIcon, TelegramShareButton, TelegramIcon, WhatsappShareButton, WhatsappIcon, LinkedinShareButton, LinkedinIcon, RedditShareButton, RedditIcon, EmailShareButton, EmailIcon } from 'react-share';
55
56
  import Head from 'next/head';
56
- import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
57
57
  import Editor, { useMonaco } from '@monaco-editor/react';
58
58
  import { format } from 'pretty-format';
59
59
  import * as d3 from 'd3';
@@ -602,7 +602,8 @@ var init_cms = __esm({
602
602
  NAV: "nav",
603
603
  // todo1.0, how to put custom blocks in here?
604
604
  RESET_BUTTON: "reset_button",
605
- COMPARISON_BUTTON: "comparison_button"
605
+ COMPARISON_BUTTON: "comparison_button",
606
+ TABLE: "table"
606
607
  };
607
608
  BLOCK_LOGIC_TYPES = {
608
609
  GENERATOR: "generator",
@@ -615,7 +616,8 @@ var init_cms = __esm({
615
616
  BLOCK_TYPES.GENERATOR,
616
617
  BLOCK_TYPES.SELECTOR,
617
618
  BLOCK_TYPES.VIZ,
618
- BLOCK_TYPES.IMAGE
619
+ BLOCK_TYPES.IMAGE,
620
+ BLOCK_TYPES.TABLE
619
621
  ];
620
622
  BLOCK_FIELDS = {
621
623
  ALT: "alt",
@@ -635,6 +637,7 @@ var init_cms = __esm({
635
637
  SRC: "src",
636
638
  SLUG: "slug",
637
639
  SUBTITLE: "subtitle",
640
+ TABLE: "table",
638
641
  TITLE: "title",
639
642
  TOOLTIP: "tooltip",
640
643
  TWITTER: "twitter",
@@ -772,7 +775,8 @@ var init_cms = __esm({
772
775
  }
773
776
  ],
774
777
  [BLOCK_TYPES.GENERATOR]: [],
775
- [BLOCK_TYPES.VIZ]: []
778
+ [BLOCK_TYPES.VIZ]: [],
779
+ [BLOCK_TYPES.TABLE]: []
776
780
  };
777
781
  BLOCK_SETTINGS = {
778
782
  NAME: "name",
@@ -1365,7 +1369,7 @@ function ApiFetchException(message) {
1365
1369
  this.message = message;
1366
1370
  this.name = "ApiFetchException";
1367
1371
  }
1368
- async function apiFetch(url, settings, readMemberFn, locale = "en") {
1372
+ async function apiFetch(url, readMemberFn, locale = "en", block) {
1369
1373
  const start2 = Date.now();
1370
1374
  let finalUrl = url;
1371
1375
  let finalData;
@@ -1375,6 +1379,7 @@ async function apiFetch(url, settings, readMemberFn, locale = "en") {
1375
1379
  const slugRegex = new RegExp(`[?&]bespoke_slugs=${parsedQuery.get("bespoke_slugs")}`, "g");
1376
1380
  finalUrl = finalUrl.replace(slugRegex, "");
1377
1381
  }
1382
+ const settings = block ? block.settings : {};
1378
1383
  const useProxy = settings && settings.useProxy && settings.useProxy === "true" ? true : false;
1379
1384
  if (typeof window === "object" && useProxy) {
1380
1385
  const result = await urlProxy({ url: finalUrl, timeout: apiFetchTimeout });
@@ -1433,7 +1438,12 @@ async function apiFetch(url, settings, readMemberFn, locale = "en") {
1433
1438
  }
1434
1439
  return data && Array.isArray(data) ? data : [];
1435
1440
  }).catch((err) => {
1436
- console.log("Error hydrating slugs", err);
1441
+ console.error(`Error hydrating slugs for Variant: ${variantId}, Key: ${keyId}, Accessor: ${accessor}`);
1442
+ console.error(` Url ${url}`);
1443
+ if (block) {
1444
+ console.error(` From Section ${block.section_id} and Block ${block.id}`);
1445
+ }
1446
+ console.error(err);
1437
1447
  return [];
1438
1448
  });
1439
1449
  if (bespokeMembers) {
@@ -1486,9 +1496,9 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
1486
1496
  apiPromisesList.push(
1487
1497
  apiFetch(
1488
1498
  apiUrl,
1489
- block.settings,
1490
1499
  readMemberFn,
1491
- locale
1500
+ locale,
1501
+ block
1492
1502
  ).catch(
1493
1503
  (e) => {
1494
1504
  throw new BlockException(` Excecution of ${block.type}-${block.id} in section ${block.section_id} in report ${variables.report_name} (${variables.report_id}) failed.
@@ -1888,6 +1898,7 @@ function previewsToAttributes(previews = []) {
1888
1898
  const i2 = index + 1;
1889
1899
  attributes[`id${i2}`] = preview.id;
1890
1900
  attributes[`name${i2}`] = preview.name;
1901
+ attributes[`slug${i2}`] = preview.slug;
1891
1902
  if ("attributes" in preview) {
1892
1903
  Object.keys(preview.attributes).forEach((key) => {
1893
1904
  attributes[`attr_${key}${i2}`] = preview.attributes[key];
@@ -1895,6 +1906,7 @@ function previewsToAttributes(previews = []) {
1895
1906
  }
1896
1907
  attributes[`variant_id${i2}`] = preview.variant_id;
1897
1908
  attributes[`variant_name${i2}`] = preview.variant_name;
1909
+ attributes[`variant_slug${i2}`] = preview.variant_slug;
1898
1910
  attributes[`dimension_id${i2}`] = preview.dimension_id;
1899
1911
  attributes[`dimension_name${i2}`] = preview.dimension_name;
1900
1912
  attributes["report_id"] = preview.report_id;
@@ -4620,10 +4632,11 @@ function RichText({
4620
4632
  size = "md",
4621
4633
  html,
4622
4634
  style = {},
4623
- append = /* @__PURE__ */ jsx(Fragment, {})
4635
+ append = /* @__PURE__ */ jsx(Fragment, {}),
4636
+ isPreview = false
4624
4637
  }) {
4625
4638
  const parentProps = getParentNodeProps(html);
4626
- const paragraphHTML = replaceTags(html);
4639
+ const paragraphHTML = replaceTags(html, isPreview);
4627
4640
  const textAlign = style && style.align ? String(style.align) : "left";
4628
4641
  let Wrapper = Text;
4629
4642
  let extraProps = {};
@@ -4666,7 +4679,7 @@ var init_RichText = __esm({
4666
4679
  parse2(htmlString, options);
4667
4680
  return parentProps;
4668
4681
  };
4669
- replaceTags = (stringHTML = "-Empty text-") => {
4682
+ replaceTags = (stringHTML = "", isPreview = false) => {
4670
4683
  const options = {
4671
4684
  replace: (domNode) => {
4672
4685
  const { type } = domNode;
@@ -4676,16 +4689,26 @@ var init_RichText = __esm({
4676
4689
  return /* @__PURE__ */ jsx(Fragment, { children: domToReact(children, options) });
4677
4690
  }
4678
4691
  if (name === "a") {
4679
- const { href } = attribs;
4692
+ const { href, target } = attribs;
4680
4693
  const isExternal = href.indexOf("http") === 0 ? true : false;
4681
- return /* @__PURE__ */ jsx(
4694
+ const isBlank = target && target === "_blank" ? true : false;
4695
+ const anchorElement = /* @__PURE__ */ jsx(
4696
+ Anchor,
4697
+ {
4698
+ ...attribs,
4699
+ href: attribs.href,
4700
+ target: "_blank",
4701
+ children: domToReact(children, options)
4702
+ }
4703
+ );
4704
+ return isExternal || isBlank || isPreview ? anchorElement : /* @__PURE__ */ jsx(
4682
4705
  Link,
4683
4706
  {
4684
4707
  ...attribs,
4685
4708
  href: attribs.href,
4686
- target: isExternal ? "_blank" : void 0,
4687
4709
  prefetch: false,
4688
- children: domToReact(children, options)
4710
+ passHref: true,
4711
+ children: anchorElement
4689
4712
  }
4690
4713
  );
4691
4714
  } else if (name === "strong") {
@@ -4712,7 +4735,7 @@ var init_RichText = __esm({
4712
4735
  function InnerTooltip(props) {
4713
4736
  const { content, style = {} } = props;
4714
4737
  const print = usePrint();
4715
- const contentObj = /* @__PURE__ */ jsx(RichText, { component: "span", html: content });
4738
+ const contentObj = /* @__PURE__ */ jsx(RichText, { component: "span", html: content, isPreview: true });
4716
4739
  const element = useMemo(() => {
4717
4740
  return print ? /* @__PURE__ */ jsx("div", { className: "bespoke-inner-tooltip-notification", children: /* @__PURE__ */ jsx(
4718
4741
  Notification,
@@ -5445,7 +5468,7 @@ function Selector(config) {
5445
5468
  setMultiValue(parseMultiValue(value2, defaultValue));
5446
5469
  }
5447
5470
  }
5448
- }, [window.location.search]);
5471
+ }, [window.location.search, defaultValue]);
5449
5472
  return /* @__PURE__ */ jsxs(Fragment, { children: [
5450
5473
  /* @__PURE__ */ jsx(MediaQuery, { query: "print", styles: { display: "none" }, children: /* @__PURE__ */ jsx(Box, { children: {
5451
5474
  [SELECTOR_TYPES.SINGLE]: component === SELECTOR_COMPONENTS.SEGMENTED_CONTROL ? /* @__PURE__ */ jsxs("div", { children: [
@@ -6046,6 +6069,68 @@ var init_ComparisonButton = __esm({
6046
6069
  init_ComparisonProvider();
6047
6070
  }
6048
6071
  });
6072
+ function Table({ columns = [], data = [], tableProps = {}, sectionId = null }) {
6073
+ const [isFullScreen, setIsFullScreen] = useState(false);
6074
+ const [translations, setTranslations] = useState({});
6075
+ const columnsKeys = useMemo(() => columns.map((column) => column.accessorKey), [columns]);
6076
+ const filteredData = useMemo(() => data.filter(
6077
+ (item) => typeof item === "object" && item !== null && !Array.isArray(item) && Object.keys(item).some((val) => columnsKeys.includes(val))
6078
+ ), [columnsKeys, data]);
6079
+ const richColumns = useMemo(() => columns.map((column) => ({
6080
+ ...column,
6081
+ Cell: ({ renderedCellValue }) => /* @__PURE__ */ jsx(RichText, { html: `${renderedCellValue}` }),
6082
+ filterFn: "contains"
6083
+ })), [columns]);
6084
+ const { locale } = useRouter();
6085
+ useEffect(() => {
6086
+ const loadLocalizedComponent = async () => {
6087
+ try {
6088
+ const lang = locale || "en";
6089
+ const componentName = `${lang.toUpperCase()}`;
6090
+ const componentModule = await import(`mantine-react-table/locales/${lang}.js`);
6091
+ setTranslations(componentModule[`MRT_Localization_${componentName}`]);
6092
+ } catch (error) {
6093
+ console.error("Error loading translations:", error);
6094
+ }
6095
+ };
6096
+ loadLocalizedComponent();
6097
+ }, [locale]);
6098
+ return /* @__PURE__ */ jsx(
6099
+ MantineReactTable,
6100
+ {
6101
+ ...tableProps,
6102
+ autoResetPageIndex: false,
6103
+ columns: richColumns,
6104
+ data: filteredData,
6105
+ enableColumnFilterModes: true,
6106
+ enableFilterMatchHighlighting: false,
6107
+ globalFilterFn: "contains",
6108
+ layoutMode: "grid",
6109
+ localization: translations,
6110
+ onIsFullScreenChange: (val) => {
6111
+ const element = document.getElementById(`section-${sectionId}`);
6112
+ if (element) {
6113
+ if (val) {
6114
+ element.style.zIndex = "10";
6115
+ } else {
6116
+ element.style.zIndex = "1";
6117
+ }
6118
+ }
6119
+ setIsFullScreen(val);
6120
+ },
6121
+ state: {
6122
+ ...tableProps.state,
6123
+ isFullScreen
6124
+ }
6125
+ }
6126
+ );
6127
+ }
6128
+ var init_Table = __esm({
6129
+ "frontend/components/report/blocks/Table.tsx"() {
6130
+ init_esm_shims();
6131
+ init_RichText();
6132
+ }
6133
+ });
6049
6134
  var localeDefault8, frontEndMessage, errorStub, propify, d3plusPropify_default;
6050
6135
  var init_d3plusPropify = __esm({
6051
6136
  "libs/d3plusPropify.ts"() {
@@ -6264,6 +6349,7 @@ var init_blocks = __esm({
6264
6349
  init_Related();
6265
6350
  init_ResetButton();
6266
6351
  init_ComparisonButton();
6352
+ init_Table();
6267
6353
  VizView = dynamic(
6268
6354
  () => Promise.resolve().then(() => (init_Viz(), Viz_exports)),
6269
6355
  { ssr: false }
@@ -6280,7 +6366,8 @@ var init_blocks = __esm({
6280
6366
  [BLOCK_TYPES.NAV]: NavView,
6281
6367
  [BLOCK_TYPES.RELATED]: RelatedView,
6282
6368
  [BLOCK_TYPES.RESET_BUTTON]: ResetButtonView,
6283
- [BLOCK_TYPES.COMPARISON_BUTTON]: ComparisonButtonPreview
6369
+ [BLOCK_TYPES.COMPARISON_BUTTON]: ComparisonButtonPreview,
6370
+ [BLOCK_TYPES.TABLE]: Table
6284
6371
  };
6285
6372
  blocks_default = TypeRenderers;
6286
6373
  }
@@ -6361,10 +6448,12 @@ var init_stringifyObject = __esm({
6361
6448
  str += "false";
6362
6449
  else if (val === void 0)
6363
6450
  str = null;
6451
+ else if (["boolean", "number"].includes(typeof val))
6452
+ str += val;
6364
6453
  else
6365
6454
  str += `"${val}"`;
6366
6455
  return str;
6367
- }).filter(Boolean).join(`,${newLine(depth + 1)}`)}${newLine(depth)}${isArray ? "]" : "}"}`;
6456
+ }).filter((val) => val !== null).join(`,${newLine(depth + 1)}`)}${newLine(depth)}${isArray ? "]" : "}"}`;
6368
6457
  };
6369
6458
  stringifyObject_default = stringifyObject;
6370
6459
  }
@@ -12441,14 +12530,17 @@ function TranslationHeader({ locale, content }) {
12441
12530
  children: locale.toUpperCase()
12442
12531
  }
12443
12532
  ),
12444
- /* @__PURE__ */ jsx(CopyButton, { value: content, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: true, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { size: "xs", color: copied ? "teal" : "gray", variant: "subtle", onClick: () => {
12445
- copy();
12446
- const blobInput = new Blob([content], { type: "text/html" });
12447
- const clipboardItemInput = new ClipboardItem({ "text/html": blobInput });
12448
- navigator.clipboard.write([clipboardItemInput]);
12449
- }, children: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }) }) }) })
12533
+ /* @__PURE__ */ jsx(CopyBtn, { content })
12450
12534
  ] });
12451
12535
  }
12536
+ function CopyBtn({ content }) {
12537
+ return /* @__PURE__ */ jsx(CopyButton, { value: content, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: true, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { size: "xs", color: copied ? "teal" : "gray", variant: "subtle", onClick: () => {
12538
+ copy();
12539
+ const blobInput = new Blob([content], { type: "text/html" });
12540
+ const clipboardItemInput = new ClipboardItem({ "text/html": blobInput });
12541
+ navigator.clipboard.write([clipboardItemInput]);
12542
+ }, children: copied ? /* @__PURE__ */ jsx(IconCheck, { style: { width: rem(16) } }) : /* @__PURE__ */ jsx(IconCopy, { style: { width: rem(16) } }) }) }) });
12543
+ }
12452
12544
  function ReferenceTranslation({ referenceLocale, referenceContent }) {
12453
12545
  return /* @__PURE__ */ jsx(Stack, { spacing: "xs", children: /* @__PURE__ */ jsx(
12454
12546
  BespokeTextEditor,
@@ -12493,6 +12585,7 @@ function FieldWithTranslation({
12493
12585
  children: titleCase(field)
12494
12586
  }
12495
12587
  ),
12588
+ toolbarRightSection: /* @__PURE__ */ jsx(CopyBtn, { content: value }),
12496
12589
  toolbarOptions: {
12497
12590
  history: true,
12498
12591
  alignment: field !== "tooltip",
@@ -12837,6 +12930,7 @@ function SelectorUI(props) {
12837
12930
  type: selectorType,
12838
12931
  component: selectorComponent,
12839
12932
  hideLabel,
12933
+ defaultValue,
12840
12934
  optionsType,
12841
12935
  options
12842
12936
  };
@@ -13431,6 +13525,520 @@ var init_StatUI = __esm({
13431
13525
  init_cms();
13432
13526
  }
13433
13527
  });
13528
+ function TableUI(props) {
13529
+ const { executeButton, id, onChange, referenceContent = {}, referenceLocale, simpleState } = props;
13530
+ const { columns: referenceColumns } = referenceContent;
13531
+ const locale = useCurrentLocale();
13532
+ const isActiveRefenceContent = useMemo(
13533
+ () => locale !== referenceLocale && referenceContent && Object.keys(referenceContent).length > 0,
13534
+ [locale, referenceContent, referenceLocale]
13535
+ );
13536
+ const variables = useInputVariablesFlat(id);
13537
+ const [columnOrder, setColumnOrder] = useState([]);
13538
+ const [customLabels, customLabelsHandler] = useListState([]);
13539
+ const [defaultVariableList, setDefaultVariableList] = useState([]);
13540
+ const [isInvalidStructure, setIsInvalidStructure] = useState(false);
13541
+ const [optionVariableMap, setOptionVariableMap] = useState({});
13542
+ const [paginationState, setPaginationState] = useState(defaultPaginationState);
13543
+ const [paginationProps, setPaginationProps] = useState({ rowsPerPageOptions: defaultPageSizes });
13544
+ const [selectedColumns, selectedColumnsHandler] = useListState([]);
13545
+ const [selectedVariable, setSelectedVariable] = useState(null);
13546
+ const [tableProps, setTableProps] = useSetState(defaultTableGlobalProps);
13547
+ const [initialTableState, setInitialTableState] = useState(defaultInitialStateProps);
13548
+ const [tableState, setTableState] = useState({});
13549
+ const allChecked = useMemo(() => selectedColumns.every((column) => column.checked), [selectedColumns]);
13550
+ const indeterminate = useMemo(() => {
13551
+ return selectedColumns.some((column) => column.checked) && !allChecked;
13552
+ }, [allChecked, selectedColumns]);
13553
+ useEffect(() => {
13554
+ if (!simpleState || !Object.keys(simpleState).length)
13555
+ return;
13556
+ const variableContent = variables[simpleState.variable] || [];
13557
+ const columns = /* @__PURE__ */ new Set();
13558
+ variableContent.filter((item) => typeof item === "object" && item !== null).forEach((item) => {
13559
+ Object.keys(item).forEach((key) => columns.add(key));
13560
+ });
13561
+ const stateColumns = {};
13562
+ const variableColumns = [];
13563
+ if (simpleState.columns && Object.keys(simpleState.columns)) {
13564
+ simpleState.columns.forEach((column) => {
13565
+ stateColumns[column.accessorKey] = column.header;
13566
+ });
13567
+ }
13568
+ const keyList = [];
13569
+ const keyLabels = [];
13570
+ Array.from(columns).forEach((key) => {
13571
+ keyLabels.push({
13572
+ key,
13573
+ label: stateColumns[key] || key
13574
+ });
13575
+ keyList.push({
13576
+ checked: stateColumns[key] ? true : false,
13577
+ key: randomId(),
13578
+ label: key
13579
+ });
13580
+ variableColumns.push(key);
13581
+ });
13582
+ customLabelsHandler.setState(keyLabels);
13583
+ selectedColumnsHandler.setState(keyList);
13584
+ const { initialState: initialState4 = {}, state = {}, mantinePaginationProps = {}, ...props2 } = simpleState.tableProps || {};
13585
+ const currentColumnOrder = state.columnOrder.filter((col) => variableColumns.includes(col));
13586
+ currentColumnOrder.push(variableColumns.filter((col) => !state.columnOrder.includes(col)));
13587
+ setColumnOrder(currentColumnOrder.flat() || []);
13588
+ setPaginationProps(mantinePaginationProps);
13589
+ setPaginationState(initialState4.pagination);
13590
+ setTableProps({ ...props2 });
13591
+ setTableState(state);
13592
+ setInitialTableState(initialState4);
13593
+ setSelectedVariable(simpleState.variable || "");
13594
+ }, []);
13595
+ useEffect(() => {
13596
+ if (!variables) {
13597
+ setOptionVariableMap({});
13598
+ return;
13599
+ }
13600
+ const validVariableMap = Object.entries(variables).filter(([_2, variableContent]) => isValidSelectorOptionsArray2(variableContent)).reduce((acc, [variableName, variableContent]) => {
13601
+ acc[variableName] = variableContent;
13602
+ return acc;
13603
+ }, {});
13604
+ setOptionVariableMap(validVariableMap);
13605
+ const validDefaultIdList = Object.keys(validVariableMap);
13606
+ setDefaultVariableList(validDefaultIdList);
13607
+ }, [variables]);
13608
+ const handleVariableSelect = (value) => {
13609
+ setSelectedVariable(value);
13610
+ if (!value || !isValidSelectorOptionsArray2(optionVariableMap[value])) {
13611
+ setIsInvalidStructure(false);
13612
+ selectedColumnsHandler.setState([]);
13613
+ return;
13614
+ }
13615
+ const items = optionVariableMap[value];
13616
+ if (items.every((item) => typeof item === "object" && item === null)) {
13617
+ setIsInvalidStructure(false);
13618
+ selectedColumnsHandler.setState([]);
13619
+ return;
13620
+ }
13621
+ if (items.every((item) => typeof item === "object" && item !== null)) {
13622
+ setIsInvalidStructure(false);
13623
+ } else {
13624
+ setIsInvalidStructure(true);
13625
+ }
13626
+ const uniqueKeys = /* @__PURE__ */ new Set();
13627
+ items.filter((item) => typeof item === "object" && item !== null).forEach((item) => {
13628
+ Object.keys(item).forEach((key) => uniqueKeys.add(key));
13629
+ });
13630
+ const keyList = [];
13631
+ const keyLabels = [];
13632
+ const columns = [];
13633
+ Array.from(uniqueKeys).forEach((key) => {
13634
+ keyList.push({
13635
+ checked: true,
13636
+ key: randomId(),
13637
+ label: key
13638
+ });
13639
+ keyLabels.push({
13640
+ key,
13641
+ label: key
13642
+ });
13643
+ columns.push(key);
13644
+ });
13645
+ selectedColumnsHandler.setState(keyList);
13646
+ customLabelsHandler.setState(keyLabels);
13647
+ setColumnOrder(columns);
13648
+ };
13649
+ useEffect(() => {
13650
+ const columnLabelsMap = {};
13651
+ customLabels.forEach((column) => {
13652
+ columnLabelsMap[column.key] = column.label;
13653
+ });
13654
+ const columns = selectedColumns.filter((column) => column.checked).map((column) => ({
13655
+ accessorKey: column.label,
13656
+ header: columnLabelsMap[column.label]
13657
+ }));
13658
+ const extendedInitialTableState = {
13659
+ ...initialTableState,
13660
+ pagination: paginationState
13661
+ };
13662
+ const extendedTableState = {
13663
+ ...tableState,
13664
+ columnOrder
13665
+ };
13666
+ const logicObj = {
13667
+ columns,
13668
+ data: selectedVariable ? `variables["${selectedVariable}"]` : [],
13669
+ tableProps: {
13670
+ ...tableProps,
13671
+ initialState: extendedInitialTableState,
13672
+ state: extendedTableState,
13673
+ mantinePaginationProps: paginationProps
13674
+ },
13675
+ variable: selectedVariable || ""
13676
+ };
13677
+ const logic = `return ${stringifyObject_default(logicObj)};`;
13678
+ const simpleState2 = {
13679
+ columns,
13680
+ data: selectedVariable ? `variables["${selectedVariable}"]` : [],
13681
+ tableProps: {
13682
+ ...tableProps,
13683
+ initialState: extendedInitialTableState,
13684
+ state: extendedTableState,
13685
+ mantinePaginationProps: paginationProps
13686
+ },
13687
+ variable: selectedVariable || ""
13688
+ };
13689
+ onChange(simpleState2, logic);
13690
+ }, [
13691
+ columnOrder,
13692
+ customLabels,
13693
+ paginationProps,
13694
+ paginationState,
13695
+ selectedColumns,
13696
+ selectedVariable,
13697
+ tableProps,
13698
+ tableState,
13699
+ initialTableState
13700
+ ]);
13701
+ const onDragEnd = useCallback((result) => {
13702
+ if (!result.destination || result.source.index === result.destination.index)
13703
+ return;
13704
+ const newOrder = [...columnOrder];
13705
+ const [draggedItem] = newOrder.splice(result.source.index, 1);
13706
+ newOrder.splice(result.destination.index, 0, draggedItem);
13707
+ setColumnOrder(newOrder);
13708
+ setTableState((current) => {
13709
+ const newState = current;
13710
+ newState["columnOrder"] = newOrder;
13711
+ return newState;
13712
+ });
13713
+ }, [columnOrder]);
13714
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
13715
+ /* @__PURE__ */ jsxs(Stack, { mb: "sm", children: [
13716
+ /* @__PURE__ */ jsx(
13717
+ Select,
13718
+ {
13719
+ clearable: true,
13720
+ data: defaultVariableList,
13721
+ description: "Select an array of data available in the block inputs to use as data input for the table.",
13722
+ label: "Data input",
13723
+ onChange: (value) => handleVariableSelect(value),
13724
+ searchable: true,
13725
+ value: selectedVariable
13726
+ }
13727
+ ),
13728
+ selectedVariable && optionVariableMap[selectedVariable] && selectedColumns.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
13729
+ /* @__PURE__ */ jsx(
13730
+ Input.Wrapper,
13731
+ {
13732
+ description: "Select the columns to display in the table.",
13733
+ error: isInvalidStructure && "There is a mix of types in the input data. Only object types rows will be kept.",
13734
+ label: "Selected columns",
13735
+ children: /* @__PURE__ */ jsxs(Stack, { mt: "xs", children: [
13736
+ /* @__PURE__ */ jsxs(Group, { grow: true, children: [
13737
+ /* @__PURE__ */ jsx(Text, { fz: "xs", children: "Selected" }),
13738
+ /* @__PURE__ */ jsx(Text, { fz: "xs", children: "Label" }),
13739
+ isActiveRefenceContent && /* @__PURE__ */ jsxs(Group, { spacing: "xs", children: [
13740
+ /* @__PURE__ */ jsx(Text, { fz: "xs", children: "Reference Label" }),
13741
+ /* @__PURE__ */ jsx(
13742
+ Badge,
13743
+ {
13744
+ variant: "light",
13745
+ size: "xs",
13746
+ rightSection: /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(IconLanguage, { size: rem(12) }) }),
13747
+ children: referenceLocale.toUpperCase()
13748
+ }
13749
+ )
13750
+ ] })
13751
+ ] }),
13752
+ /* @__PURE__ */ jsx(
13753
+ Checkbox,
13754
+ {
13755
+ checked: allChecked,
13756
+ indeterminate,
13757
+ label: "All",
13758
+ onChange: () => selectedColumnsHandler.setState((current) => current.map((value) => ({ ...value, checked: !allChecked })))
13759
+ }
13760
+ ),
13761
+ /* @__PURE__ */ jsx(ScrollArea.Autosize, { mah: 300, children: /* @__PURE__ */ jsx(DragDropContext, { onDragEnd, children: /* @__PURE__ */ jsx(Droppable, { droppableId: "columns", children: (droppableProvided) => /* @__PURE__ */ jsx("div", { ref: droppableProvided.innerRef, ...droppableProvided.droppableProps, children: columnOrder.map((option, index) => {
13762
+ const columnIndex = selectedColumns.findIndex((col) => col.label === option);
13763
+ const column = selectedColumns[columnIndex];
13764
+ return /* @__PURE__ */ jsx(
13765
+ Draggable,
13766
+ {
13767
+ draggableId: `${column.label}`,
13768
+ index,
13769
+ isDragDisabled: !column.checked,
13770
+ children: (draggableProvided) => /* @__PURE__ */ jsx(
13771
+ ColumnRenderer,
13772
+ {
13773
+ customLabels,
13774
+ customLabelsHandler,
13775
+ index: columnIndex,
13776
+ isActiveRefenceContent,
13777
+ option: column,
13778
+ ref: draggableProvided.innerRef,
13779
+ referenceColumns,
13780
+ selectedColumnsHandler,
13781
+ ...draggableProvided.draggableProps,
13782
+ ...draggableProvided.dragHandleProps
13783
+ }
13784
+ )
13785
+ },
13786
+ column.label
13787
+ );
13788
+ }) }) }) }) })
13789
+ ] })
13790
+ }
13791
+ ),
13792
+ /* @__PURE__ */ jsx(Accordion, { variant: "separated", children: /* @__PURE__ */ jsxs(Accordion.Item, { value: "custom-props", children: [
13793
+ /* @__PURE__ */ jsx(Accordion.Control, { children: "Custom properties" }),
13794
+ /* @__PURE__ */ jsx(Accordion.Panel, { children: /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsxs(
13795
+ Input.Wrapper,
13796
+ {
13797
+ description: "Select the needed table options.",
13798
+ label: "Table options",
13799
+ children: [
13800
+ /* @__PURE__ */ jsx(Group, { mt: "xs", children: Object.keys(tableProps).map((prop) => /* @__PURE__ */ jsx(
13801
+ Checkbox,
13802
+ {
13803
+ checked: tableProps[prop],
13804
+ label: /* @__PURE__ */ jsx(
13805
+ Tooltip,
13806
+ {
13807
+ label: tableGlobalPropsDesc[prop]?.desc || prop,
13808
+ multiline: true,
13809
+ children: /* @__PURE__ */ jsx(Text, { children: tableGlobalPropsDesc[prop]?.label || prop })
13810
+ }
13811
+ ),
13812
+ onChange: () => setTableProps({ [prop]: !tableProps[prop] })
13813
+ },
13814
+ `table-prop-${prop}`
13815
+ )) }),
13816
+ tableProps?.enablePagination && /* @__PURE__ */ jsxs(Fragment, { children: [
13817
+ /* @__PURE__ */ jsx(Divider, { mt: "xs" }),
13818
+ /* @__PURE__ */ jsxs(
13819
+ Input.Wrapper,
13820
+ {
13821
+ description: "Customize initial pagination properties.",
13822
+ label: "Pagination props",
13823
+ mt: "xs",
13824
+ children: [
13825
+ /* @__PURE__ */ jsxs(Group, { grow: true, children: [
13826
+ /* @__PURE__ */ jsx(
13827
+ NumberInput,
13828
+ {
13829
+ label: "Initial page",
13830
+ min: 0,
13831
+ onChange: (value) => {
13832
+ setPaginationState((current) => ({
13833
+ ...current,
13834
+ pageIndex: value
13835
+ }));
13836
+ },
13837
+ value: paginationState.pageIndex
13838
+ }
13839
+ ),
13840
+ /* @__PURE__ */ jsx(
13841
+ Select,
13842
+ {
13843
+ data: paginationProps.rowsPerPageOptions || [],
13844
+ getCreateLabel: (value) => `+ Create ${value}`,
13845
+ label: "Initial page size",
13846
+ onChange: (value) => {
13847
+ setPaginationState((current) => ({
13848
+ ...current,
13849
+ pageSize: parseInt(value, 10)
13850
+ }));
13851
+ },
13852
+ searchable: true,
13853
+ value: paginationState.pageSize.toString()
13854
+ }
13855
+ )
13856
+ ] }),
13857
+ /* @__PURE__ */ jsxs(Group, { align: "flex-end", grow: true, children: [
13858
+ /* @__PURE__ */ jsx(
13859
+ MultiSelect,
13860
+ {
13861
+ clearable: true,
13862
+ creatable: true,
13863
+ data: paginationProps.rowsPerPageOptions || [],
13864
+ getCreateLabel: (value) => `+ Create ${value}`,
13865
+ label: "Page size options",
13866
+ onChange: (value) => {
13867
+ setPaginationProps((current) => ({
13868
+ ...current,
13869
+ rowsPerPageOptions: value.sort((a2, b2) => parseInt(a2, 10) - parseInt(b2, 10))
13870
+ }));
13871
+ if (value && value.length > 0 && !value.includes(paginationState.pageSize.toString())) {
13872
+ setPaginationState((current) => ({
13873
+ ...current,
13874
+ pageSize: parseInt(value[0], 10)
13875
+ }));
13876
+ }
13877
+ },
13878
+ onCreate: (value) => {
13879
+ setPaginationProps((current) => ({
13880
+ ...current,
13881
+ rowsPerPageOptions: [...current.rowsPerPageOptions || [], value].sort((a2, b2) => parseInt(a2, 10) - parseInt(b2, 10))
13882
+ }));
13883
+ return value;
13884
+ },
13885
+ searchable: true,
13886
+ value: paginationProps.rowsPerPageOptions || []
13887
+ }
13888
+ ),
13889
+ /* @__PURE__ */ jsx(
13890
+ Button,
13891
+ {
13892
+ color: "yellow",
13893
+ onClick: () => {
13894
+ setPaginationProps((current) => ({
13895
+ ...current,
13896
+ rowsPerPageOptions: defaultPageSizes
13897
+ }));
13898
+ setPaginationState(defaultPaginationState);
13899
+ },
13900
+ children: "Reset page sizes values"
13901
+ }
13902
+ )
13903
+ ] })
13904
+ ]
13905
+ }
13906
+ )
13907
+ ] })
13908
+ ]
13909
+ }
13910
+ ) }) })
13911
+ ] }) })
13912
+ ] })
13913
+ ] }),
13914
+ executeButton
13915
+ ] });
13916
+ }
13917
+ var defaultTableGlobalProps, tableGlobalPropsDesc, defaultInitialStateProps, defaultPageSizes, defaultPaginationState, isValidSelectorOptionsArray2, ColumnRenderer;
13918
+ var init_TableUI = __esm({
13919
+ "components/blocks/types/simpleEditors/TableUI.tsx"() {
13920
+ init_esm_shims();
13921
+ init_stringifyObject();
13922
+ init_hooks();
13923
+ defaultTableGlobalProps = {
13924
+ enableBottomToolbar: true,
13925
+ enableColumnActions: true,
13926
+ enableColumnFilters: true,
13927
+ enableColumnResizing: true,
13928
+ enableDensityToggle: true,
13929
+ enableFullScreenToggle: false,
13930
+ enableGlobalFilter: true,
13931
+ enableHiding: true,
13932
+ enablePagination: true,
13933
+ enableSorting: true,
13934
+ enableStickyHeader: true,
13935
+ enableTopToolbar: true
13936
+ };
13937
+ tableGlobalPropsDesc = {
13938
+ enableBottomToolbar: {
13939
+ label: "Enable bottom toolbar",
13940
+ desc: "Show or hide the bottom toolbar. By disabling it, pagination will also be hidden."
13941
+ },
13942
+ enableColumnActions: {
13943
+ label: "Enable column actions",
13944
+ desc: "Enables or disables column actions for all columns. Column actions include sort, filter, show/hide column and reset column size."
13945
+ },
13946
+ enableColumnFilters: {
13947
+ label: "Enable column filters",
13948
+ desc: "Enables or disables the filter options available on columns."
13949
+ },
13950
+ enableColumnResizing: {
13951
+ label: "Enable column resizing",
13952
+ desc: "Enables the column resizing feature for all columns."
13953
+ },
13954
+ enableDensityToggle: {
13955
+ label: "Enable density toggle",
13956
+ desc: "Enable the density toggle that allows users to modify the height of each row. Disabling it will hide the density toggle button in the top toolbar."
13957
+ },
13958
+ enableFullScreenToggle: {
13959
+ label: "Enable full screen toggle",
13960
+ desc: "Enable or disable the full screen toggle feature. Disabling it will hide the full screen toggle button in the top toolbar."
13961
+ },
13962
+ enableGlobalFilter: {
13963
+ label: "Enable global filter",
13964
+ desc: "Enable global filter feature to filter data on all columns and rows. Disabling it will hide the global filter button in the top toolbar."
13965
+ },
13966
+ enableHiding: {
13967
+ label: "Enable hiding",
13968
+ desc: "Enable hiding columns feature. Disabling it will hide the hiding button in the top toolbar."
13969
+ },
13970
+ enablePagination: {
13971
+ label: "Enable pagination",
13972
+ desc: "Enable pagination feature. Disabling it will hide the pagination options in the bottom toolbar."
13973
+ },
13974
+ enableSorting: {
13975
+ label: "Enable sorting",
13976
+ desc: "Enable sorting feature for all columns."
13977
+ },
13978
+ enableStickyHeader: {
13979
+ label: "Enable sticky header",
13980
+ desc: "Allows you to maintain the column headers when scrolling through the rows of the table."
13981
+ },
13982
+ enableTopToolbar: {
13983
+ label: "Enable top toolbar",
13984
+ desc: "Show or hide the top toolbar. By disabling it, globar filter, hiding, density and full screen toggles will also be hidden."
13985
+ }
13986
+ };
13987
+ defaultInitialStateProps = {
13988
+ density: "xs"
13989
+ };
13990
+ defaultPageSizes = ["5", "10", "15", "20", "25", "30", "50", "100"];
13991
+ defaultPaginationState = {
13992
+ pageIndex: 0,
13993
+ pageSize: 10
13994
+ };
13995
+ isValidSelectorOptionsArray2 = (variable) => variable && Array.isArray(variable) && variable.some((elemento) => typeof elemento === "object" && elemento !== null);
13996
+ ColumnRenderer = forwardRef(
13997
+ function ColumnRendererComponent({
13998
+ customLabels,
13999
+ customLabelsHandler,
14000
+ index,
14001
+ isActiveRefenceContent = false,
14002
+ option,
14003
+ referenceColumns = [],
14004
+ selectedColumnsHandler,
14005
+ ...rest
14006
+ }, ref) {
14007
+ const customLabel = customLabels.find((label) => label.key === option.label)?.label || "";
14008
+ const referenceColumn = referenceColumns.find((column) => column.accessorKey === option.label);
14009
+ const referenceColumnLabel = referenceColumn?.header || option.label;
14010
+ return /* @__PURE__ */ jsxs(Group, { grow: true, ref, ...rest, children: [
14011
+ /* @__PURE__ */ jsxs(Group, { children: [
14012
+ /* @__PURE__ */ jsx(IconGripVertical, {}),
14013
+ /* @__PURE__ */ jsx(
14014
+ Checkbox,
14015
+ {
14016
+ checked: option.checked,
14017
+ label: option.label,
14018
+ onChange: (event) => selectedColumnsHandler.setItemProp(index, "checked", event.currentTarget.checked)
14019
+ }
14020
+ )
14021
+ ] }),
14022
+ /* @__PURE__ */ jsx(
14023
+ Input,
14024
+ {
14025
+ disabled: !option.checked,
14026
+ onChange: (event) => customLabelsHandler.setItemProp(index, "label", event.currentTarget.value),
14027
+ value: customLabel
14028
+ }
14029
+ ),
14030
+ isActiveRefenceContent && /* @__PURE__ */ jsx(
14031
+ Input,
14032
+ {
14033
+ disabled: true,
14034
+ value: referenceColumnLabel
14035
+ }
14036
+ )
14037
+ ] }, `table-group-${option.label}-${index}`);
14038
+ }
14039
+ );
14040
+ }
14041
+ });
13434
14042
 
13435
14043
  // components/blocks/types/simpleEditors/index.js
13436
14044
  var simpleEditors, simpleEditors_default;
@@ -13445,6 +14053,7 @@ var init_simpleEditors = __esm({
13445
14053
  init_TitleUI();
13446
14054
  init_ComparisonButtonUI();
13447
14055
  init_StatUI();
14056
+ init_TableUI();
13448
14057
  simpleEditors = {
13449
14058
  [BLOCK_TYPES.SELECTOR]: SelectorUI_default,
13450
14059
  [BLOCK_TYPES.NAV]: NavUI,
@@ -13452,7 +14061,8 @@ var init_simpleEditors = __esm({
13452
14061
  [BLOCK_TYPES.RESET_BUTTON]: ResetButtonUI,
13453
14062
  [BLOCK_TYPES.COMPARISON_BUTTON]: ComparisonButtonUI,
13454
14063
  [BLOCK_TYPES.TITLE]: TitleUI,
13455
- [BLOCK_TYPES.STAT]: StatUI
14064
+ [BLOCK_TYPES.STAT]: StatUI,
14065
+ [BLOCK_TYPES.TABLE]: TableUI
13456
14066
  };
13457
14067
  simpleEditors_default = simpleEditors;
13458
14068
  }
@@ -13471,7 +14081,8 @@ function ParagraphPreview({ paragraph, tooltip, settings }) {
13471
14081
  component: "p",
13472
14082
  html: paragraphHTML,
13473
14083
  style: settings,
13474
- append: tooltipObj
14084
+ append: tooltipObj,
14085
+ isPreview: true
13475
14086
  }
13476
14087
  );
13477
14088
  }
@@ -13513,9 +14124,9 @@ function StatPreview({
13513
14124
  }
13514
14125
  ),
13515
14126
  /* @__PURE__ */ jsxs("div", { className: "bespoke-Stat-wrapper", children: [
13516
- /* @__PURE__ */ jsx(RichText, { component: "div", size: "md", html: titleHTML, style: settings }),
13517
- /* @__PURE__ */ jsx(RichText, { component: "div", size: "xl", html: valueHTML, style: settings }),
13518
- /* @__PURE__ */ jsx(RichText, { component: "div", size: "sm", html: subtitleHTML, style: settings })
14127
+ /* @__PURE__ */ jsx(RichText, { component: "div", size: "md", html: titleHTML, style: settings, isPreview: true }),
14128
+ /* @__PURE__ */ jsx(RichText, { component: "div", size: "xl", html: valueHTML, style: settings, isPreview: true }),
14129
+ /* @__PURE__ */ jsx(RichText, { component: "div", size: "sm", html: subtitleHTML, style: settings, isPreview: true })
13519
14130
  ] }, "stat"),
13520
14131
  tooltip && /* @__PURE__ */ jsx(InnerTooltip, { content: tooltip })
13521
14132
  ] }) });
@@ -13533,7 +14144,7 @@ function SubtitlePreview({ subtitle, tooltip, settings }) {
13533
14144
  const subtitleHTML = sanitizeBlockContent_default(subtitle) || "<span class='cr-block-placeholder'>Small subtitle.</span>";
13534
14145
  const align = settings && settings.align ? settings.align : "left";
13535
14146
  return /* @__PURE__ */ jsxs(Group, { spacing: "sm", position: getAlignForGroup(align), children: [
13536
- /* @__PURE__ */ jsx(RichText, { size: "sm", html: subtitleHTML }),
14147
+ /* @__PURE__ */ jsx(RichText, { size: "sm", html: subtitleHTML, isPreview: true }),
13537
14148
  tooltip && /* @__PURE__ */ jsx(InnerTooltip, { content: tooltip, style: { display: "inline-flex" } })
13538
14149
  ] });
13539
14150
  }
@@ -13582,7 +14193,8 @@ function TitlePreview({
13582
14193
  component: "h",
13583
14194
  order: order2,
13584
14195
  style: settings,
13585
- html: titleHTML
14196
+ html: titleHTML,
14197
+ isPreview: true
13586
14198
  }
13587
14199
  ),
13588
14200
  searchOnClick && /* @__PURE__ */ jsx(Tooltip, { label: `Click will open '${searchType}' report search`, children: /* @__PURE__ */ jsx(ActionIcon, { variant: "light", children: /* @__PURE__ */ jsx(IconSearch, { size: 20 }) }) }),
@@ -13633,7 +14245,7 @@ function SelectorPreview(config) {
13633
14245
  dispatch(setQueryParam(resource, selectorIdentifier, e.join()));
13634
14246
  };
13635
14247
  const { name, settings } = config;
13636
- const label = config.hideLabel === "true" ? /* @__PURE__ */ jsx(Fragment, {}) : /* @__PURE__ */ jsx(RichText, { component: "div", html: name, size: "sm", style: settings });
14248
+ const label = config.hideLabel === "true" ? /* @__PURE__ */ jsx(Fragment, {}) : /* @__PURE__ */ jsx(RichText, { component: "div", html: name, size: "sm", style: settings, isPreview: true });
13637
14249
  return {
13638
14250
  [SELECTOR_TYPES.SINGLE]: config.component === SELECTOR_COMPONENTS.SEGMENTED_CONTROL ? /* @__PURE__ */ jsxs("div", { children: [
13639
14251
  label,
@@ -13941,9 +14553,9 @@ function ImagePreview(props) {
13941
14553
  const align = settings && settings.align ? String(settings.align) : "left";
13942
14554
  if (descText && descText.length || title && title.length) {
13943
14555
  element = /* @__PURE__ */ jsxs(Stack, { className: "bespoke-Image-wrapper", align: getAlignForStack(align), spacing: "sm", children: [
13944
- title && /* @__PURE__ */ jsx(RichText, { component: "p", html: title, style: settings }),
14556
+ title && /* @__PURE__ */ jsx(RichText, { component: "p", html: title, style: settings, isPreview: true }),
13945
14557
  element,
13946
- desc && /* @__PURE__ */ jsx(RichText, { component: "p", size: "sm", html: desc, style: settings })
14558
+ desc && /* @__PURE__ */ jsx(RichText, { component: "p", size: "sm", html: desc, style: settings, isPreview: true })
13947
14559
  ] });
13948
14560
  }
13949
14561
  return srcText && altText ? element : /* @__PURE__ */ jsx(Center, { mih: 100, bg: "white", children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: "IMAGE" }, "type") });
@@ -14017,7 +14629,7 @@ function useCurrentLocale2() {
14017
14629
  if (paramLocale && paramLocale !== "" && locales4.includes(paramLocale) && paramLocale !== currentLocale) {
14018
14630
  dispatch(actions_exports.setCurrentLocale(paramLocale));
14019
14631
  }
14020
- }, [paramLocale]);
14632
+ }, []);
14021
14633
  return currentLocale;
14022
14634
  }
14023
14635
  var init_useCurrentLocale = __esm({
@@ -14158,6 +14770,63 @@ var init_ComparisonButton2 = __esm({
14158
14770
  init_esm_shims();
14159
14771
  }
14160
14772
  });
14773
+ function TablePreview({ columns = [], id, data = [], tableProps = {} }) {
14774
+ const [translations, setTranslations] = useState({});
14775
+ const { initialState: initialState4 } = tableProps;
14776
+ const pageIndex = initialState4?.pagination?.pageIndex;
14777
+ const pageSize = initialState4?.pagination?.pageSize;
14778
+ const tableId = `table-${[id, pageIndex, pageSize].filter((d2) => d2).join("-")}`;
14779
+ const columnsKeys = useMemo(() => columns.map((column) => column.accessorKey), [columns]);
14780
+ const filteredData = useMemo(() => data.filter(
14781
+ (item) => typeof item === "object" && item !== null && !Array.isArray(item) && Object.keys(item).some((val) => columnsKeys.includes(val))
14782
+ ), [columnsKeys, data]);
14783
+ const richColumns = useMemo(() => columns.map((column) => ({
14784
+ ...column,
14785
+ Cell: ({ renderedCellValue }) => /* @__PURE__ */ jsx(RichText, { html: `${renderedCellValue}`, isPreview: true }),
14786
+ filterFn: "contains"
14787
+ })), [columns]);
14788
+ const locale = useCurrentLocale();
14789
+ useEffect(() => {
14790
+ const loadLocalizedComponent = async () => {
14791
+ try {
14792
+ const lang = locale || "en";
14793
+ const componentName = `${lang.toUpperCase()}`;
14794
+ const componentModule = await import(`mantine-react-table/locales/${lang}.js`);
14795
+ setTranslations(componentModule[`MRT_Localization_${componentName}`]);
14796
+ } catch (error) {
14797
+ console.error("Error loading translations:", error);
14798
+ }
14799
+ };
14800
+ loadLocalizedComponent();
14801
+ }, [locale]);
14802
+ return /* @__PURE__ */ createElement(
14803
+ MantineReactTable,
14804
+ {
14805
+ ...tableProps,
14806
+ autoResetPageIndex: false,
14807
+ columns: richColumns,
14808
+ data: filteredData,
14809
+ enableColumnFilterModes: true,
14810
+ enableFilterMatchHighlighting: false,
14811
+ globalFilterFn: "contains",
14812
+ key: tableId,
14813
+ layoutMode: "grid",
14814
+ localization: translations,
14815
+ state: {
14816
+ ...tableProps.state,
14817
+ // prevents the user from getting the full screen table overlay error on cms
14818
+ isFullScreen: false
14819
+ }
14820
+ }
14821
+ );
14822
+ }
14823
+ var init_Table2 = __esm({
14824
+ "components/blocks/types/renderers/Table.tsx"() {
14825
+ init_esm_shims();
14826
+ init_RichText();
14827
+ init_hooks();
14828
+ }
14829
+ });
14161
14830
 
14162
14831
  // components/blocks/types/renderers/Viz.tsx
14163
14832
  var Viz_exports2 = {};
@@ -14288,6 +14957,7 @@ var init_renderers = __esm({
14288
14957
  init_Related2();
14289
14958
  init_ResetButton2();
14290
14959
  init_ComparisonButton2();
14960
+ init_Table2();
14291
14961
  VizPreview = dynamic(
14292
14962
  () => Promise.resolve().then(() => (init_Viz2(), Viz_exports2)),
14293
14963
  { ssr: false }
@@ -14304,7 +14974,8 @@ var init_renderers = __esm({
14304
14974
  [BLOCK_TYPES.NAV]: NavPreview,
14305
14975
  [BLOCK_TYPES.RELATED]: RelatedPreview,
14306
14976
  [BLOCK_TYPES.RESET_BUTTON]: ResetButtonPreview,
14307
- [BLOCK_TYPES.COMPARISON_BUTTON]: ComparisonButtonPreview2
14977
+ [BLOCK_TYPES.COMPARISON_BUTTON]: ComparisonButtonPreview2,
14978
+ [BLOCK_TYPES.TABLE]: TablePreview
14308
14979
  };
14309
14980
  renderers_default = renderersMap;
14310
14981
  }
@@ -14323,7 +14994,8 @@ var init_icons = __esm({
14323
14994
  "visualization": IconChartBar,
14324
14995
  "paragraph": IconAlignLeft,
14325
14996
  "selector": IconSelector,
14326
- "image": IconPhoto
14997
+ "image": IconPhoto,
14998
+ "table": IconTable
14327
14999
  };
14328
15000
  }
14329
15001
  });
@@ -14350,7 +15022,8 @@ var init_labels = __esm({
14350
15022
  "related": "Related Reports",
14351
15023
  // (?)
14352
15024
  "nav": "Navigation",
14353
- "image": "Image"
15025
+ "image": "Image",
15026
+ "table": "Table"
14354
15027
  };
14355
15028
  }
14356
15029
  });
@@ -14446,6 +15119,12 @@ var init_types = __esm({
14446
15119
  renderer: renderers_default[BLOCK_TYPES.COMPARISON_BUTTON],
14447
15120
  renderPreviewOnEdit: true,
14448
15121
  evalWhenNonActive: true
15122
+ },
15123
+ [BLOCK_TYPES.TABLE]: {
15124
+ type: BLOCK_TYPES.TABLE,
15125
+ renderer: renderers_default[BLOCK_TYPES.TABLE],
15126
+ renderPreviewOnEdit: false,
15127
+ evalWhenNonActive: false
14449
15128
  }
14450
15129
  };
14451
15130
  types_default = allBlocks;
@@ -14553,6 +15232,13 @@ function Block({ blockId, active = true, asComparison = false }) {
14553
15232
  void 0,
14554
15233
  blockContext
14555
15234
  );
15235
+ if (block.type === BLOCK_TYPES.TABLE) {
15236
+ setContent3({
15237
+ sectionId: block.section_id,
15238
+ ...vars
15239
+ });
15240
+ return;
15241
+ }
14556
15242
  setContent3(vars);
14557
15243
  return;
14558
15244
  };
@@ -14588,7 +15274,7 @@ var init_Block = __esm({
14588
15274
  });
14589
15275
 
14590
15276
  // libs/settings/section.tsx
14591
- var sectionSettings, defaultSettings2, defaultSectionSettings;
15277
+ var sectionSettings, defaultSettings2, defaultSectionSettings, getOptionsSettings;
14592
15278
  var init_section2 = __esm({
14593
15279
  "libs/settings/section.tsx"() {
14594
15280
  init_esm_shims();
@@ -14645,8 +15331,16 @@ var init_section2 = __esm({
14645
15331
  defaultSectionSettings = {
14646
15332
  memberImageBg: false,
14647
15333
  optionsMenu: false,
15334
+ optionData: true,
15335
+ optionImage: true,
15336
+ optionShare: true,
14648
15337
  ...defaultSettings2
14649
15338
  };
15339
+ getOptionsSettings = (settings) => ({
15340
+ data: typeof settings.optionData === "boolean" ? settings.optionData : true,
15341
+ image: typeof settings.optionImage === "boolean" ? settings.optionImage : true,
15342
+ share: typeof settings.optionShare === "boolean" ? settings.optionShare : true
15343
+ });
14650
15344
  }
14651
15345
  });
14652
15346
  function SectionBackground({ previews }) {
@@ -14968,7 +15662,7 @@ function DataTab(props) {
14968
15662
  setLoadingPreview(true);
14969
15663
  const dataItem = selectedSource.data[selectedDataset];
14970
15664
  if (typeof dataItem === "string") {
14971
- apiFetch(dataItem, {}, readMemberFn, locale).then((response) => {
15665
+ apiFetch(dataItem, readMemberFn, locale).then((response) => {
14972
15666
  const dataToShare = guessResponse(response);
14973
15667
  setPreviewsSource({
14974
15668
  ...previewsSource,
@@ -15668,7 +16362,7 @@ var init_OptionsModal = __esm({
15668
16362
  }
15669
16363
  });
15670
16364
  function Options(props) {
15671
- const { sectionId, disabled = false } = props;
16365
+ const { sectionId, disabled = false, optionsSettings } = props;
15672
16366
  const [opened, setOpened] = useState(false);
15673
16367
  const [mode, setMode] = useState("data");
15674
16368
  const sectionRef = useSectionRef(sectionId);
@@ -15683,7 +16377,7 @@ function Options(props) {
15683
16377
  };
15684
16378
  return /* @__PURE__ */ jsxs("div", { className: "cms-section-options", children: [
15685
16379
  /* @__PURE__ */ jsxs(Button.Group, { children: [
15686
- /* @__PURE__ */ jsx(
16380
+ optionsSettings.data && /* @__PURE__ */ jsx(
15687
16381
  Button,
15688
16382
  {
15689
16383
  variant: "default",
@@ -15695,7 +16389,7 @@ function Options(props) {
15695
16389
  children: /* @__PURE__ */ jsx(IconTable, { size: 16 })
15696
16390
  }
15697
16391
  ),
15698
- /* @__PURE__ */ jsx(
16392
+ optionsSettings.image && /* @__PURE__ */ jsx(
15699
16393
  Button,
15700
16394
  {
15701
16395
  variant: "default",
@@ -15707,7 +16401,7 @@ function Options(props) {
15707
16401
  children: /* @__PURE__ */ jsx(IconCamera, { size: 16 })
15708
16402
  }
15709
16403
  ),
15710
- /* @__PURE__ */ jsx(
16404
+ optionsSettings.share && /* @__PURE__ */ jsx(
15711
16405
  Button,
15712
16406
  {
15713
16407
  variant: "default",
@@ -16460,7 +17154,14 @@ function SectionWrapper({
16460
17154
  children: [
16461
17155
  !print && /* @__PURE__ */ jsxs(Group, { position: "right", mb: "xs", children: [
16462
17156
  /* @__PURE__ */ jsx(SectionResetButton, { id }),
16463
- sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: id, disabled: false })
17157
+ sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(
17158
+ Options,
17159
+ {
17160
+ sectionId: id,
17161
+ disabled: false,
17162
+ optionsSettings: getOptionsSettings(sectionSettings2)
17163
+ }
17164
+ )
16464
17165
  ] }),
16465
17166
  /* @__PURE__ */ jsxs(
16466
17167
  StyleWrapper,
@@ -17541,7 +18242,7 @@ function DimensionAutocomplete(props) {
17541
18242
  value: _variant,
17542
18243
  onChange: setVariant
17543
18244
  },
17544
- dimensionId
18245
+ `dimension-${dimensionId}`
17545
18246
  ),
17546
18247
  /* @__PURE__ */ jsx(
17547
18248
  Text,
@@ -17562,7 +18263,7 @@ function DimensionAutocomplete(props) {
17562
18263
  onChange: setMember,
17563
18264
  locale
17564
18265
  },
17565
- _variant
18266
+ `variant-${_variant}`
17566
18267
  )
17567
18268
  ] });
17568
18269
  }
@@ -18988,6 +19689,7 @@ function CMSHeader(props) {
18988
19689
  locale: previewLocale,
18989
19690
  output: "full"
18990
19691
  })).then(({ results }) => {
19692
+ dispatch(actions_exports.setCurrentLocale(previewLocale));
18991
19693
  if (results && results.length === dimensions.length && dimensions.length) {
18992
19694
  dispatch(actions_exports.recalculateVariables(resource, { previews: results }));
18993
19695
  } else {
@@ -20333,6 +21035,11 @@ var unlocalizedKeys = {
20333
21035
  ],
20334
21036
  [BLOCK_TYPES.STAT]: [
20335
21037
  ...UNLOCALIZED_ICON_KEYS
21038
+ ],
21039
+ [BLOCK_TYPES.TABLE]: [
21040
+ "data",
21041
+ "tableProps",
21042
+ "variable"
20336
21043
  ]
20337
21044
  };
20338
21045
  var reduceContent = (acc, d2) => ({ ...acc, [d2.locale]: { ...d2, content: d2.content } });
@@ -20433,10 +21140,14 @@ function Block2({ id, modified, callbacks, inline }) {
20433
21140
  newSimple[key] = unlocalizedContent.simple[key];
20434
21141
  }
20435
21142
  });
21143
+ const logicObj = { ...newSimple };
21144
+ if (block.type === BLOCK_TYPES.SELECTOR) {
21145
+ logicObj.options = logicObj.options[logicObj.optionsType];
21146
+ }
20436
21147
  newContentByLocale[locale].content = {
20437
21148
  ...newContentByLocale[locale].content,
20438
21149
  simple: newSimple,
20439
- logic: `return ${stringifyObject_default(newSimple)}`
21150
+ logic: `return ${stringifyObject_default(logicObj)}`
20440
21151
  };
20441
21152
  });
20442
21153
  return newContentByLocale;
@@ -20715,7 +21426,6 @@ function BlockElement({
20715
21426
  !allowed && /* @__PURE__ */ jsx(Tooltip, { withArrow: true, label: allowedMessage, children: /* @__PURE__ */ jsx(ActionIcon, { variant: "transparent", children: /* @__PURE__ */ jsx(IconEyeOff, { size: 20 }) }) }, "allowed"),
20716
21427
  block.type !== "generator" && /* @__PURE__ */ jsx(StyleMenu_default, { id, display: "button" }, "design"),
20717
21428
  /* @__PURE__ */ jsx(ActionIcon, { onClick: () => setOpened(true), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit"),
20718
- /* @__PURE__ */ jsx(DeleteButton_default, { type: ENTITY_TYPES.BLOCK, id }, "cog"),
20719
21429
  /* @__PURE__ */ jsx(
20720
21430
  ActionIcon,
20721
21431
  {
@@ -20723,7 +21433,8 @@ function BlockElement({
20723
21433
  children: /* @__PURE__ */ jsx(IconCopy, { size: 20 })
20724
21434
  },
20725
21435
  "copy"
20726
- )
21436
+ ),
21437
+ /* @__PURE__ */ jsx(DeleteButton_default, { type: ENTITY_TYPES.BLOCK, id }, "cog")
20727
21438
  ]
20728
21439
  },
20729
21440
  "bc"
@@ -20760,14 +21471,15 @@ init_cms();
20760
21471
  init_getBlockContent();
20761
21472
  init_Options();
20762
21473
  init_SectionMenu();
21474
+ init_section2();
20763
21475
  function SectionHeader({
20764
21476
  active,
20765
21477
  isDragging,
20766
21478
  id,
20767
21479
  dragHandleProps,
20768
21480
  hidden,
20769
- optionsMenu,
20770
- onActivate
21481
+ onActivate,
21482
+ sectionSettings: sectionSettings2
20771
21483
  }) {
20772
21484
  const section = useAppSelector((state) => state.records.entities.section[id] || null);
20773
21485
  if (!section)
@@ -20800,9 +21512,9 @@ function SectionHeader({
20800
21512
  )
20801
21513
  ] }) }),
20802
21514
  /* @__PURE__ */ jsxs(Group, { children: [
20803
- optionsMenu && /* @__PURE__ */ jsxs(Flex, { justify: "flex-end", mx: 16, align: "center", gap: "xs", children: [
21515
+ sectionSettings2.optionsMenu && /* @__PURE__ */ jsxs(Flex, { justify: "flex-end", mx: 16, align: "center", gap: "xs", children: [
20804
21516
  /* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
20805
- /* @__PURE__ */ jsx(Options, { sectionId: section.id, disabled: !active })
21517
+ /* @__PURE__ */ jsx(Options, { sectionId: section.id, disabled: !active, optionsSettings: getOptionsSettings(sectionSettings2) })
20806
21518
  ] }),
20807
21519
  /* @__PURE__ */ jsx(SectionMenu_default, { sectionId: id, onActivate })
20808
21520
  ] })
@@ -20860,7 +21572,7 @@ var CreateBlockButton = ({ columns, columnIndex, section }) => {
20860
21572
  },
20861
21573
  sx: { ":hover": { backgroundColor: "#EBEBEB" } },
20862
21574
  children: /* @__PURE__ */ jsxs(Group, { spacing: "xs", children: [
20863
- /* @__PURE__ */ jsx(ActionIcon, { color: "blue", variant: "filled", size: "sm", radius: "xl", children: /* @__PURE__ */ jsx(BlockIcon2, { size: "0.8rem" }) }),
21575
+ /* @__PURE__ */ jsx(ThemeIcon, { color: "blue", variant: "filled", size: "sm", radius: "xl", children: /* @__PURE__ */ jsx(BlockIcon2, { size: "0.8rem" }) }),
20864
21576
  /* @__PURE__ */ jsx(Text, { size: "xs", children: getBlockLabel(d2) || d2 })
20865
21577
  ] })
20866
21578
  }
@@ -20976,7 +21688,7 @@ function SectionEditor({
20976
21688
  const blocks = useAppSelector((state) => state.records.entities.block);
20977
21689
  const previews = useAppSelector((state) => state.status.previews);
20978
21690
  const cloneState = useCloneStatusSelector("section", section.id);
20979
- const { memberImageBg, optionsMenu, hidden, columnSettings = {} } = section.settings;
21691
+ const { memberImageBg, hidden, columnSettings = {} } = section.settings;
20980
21692
  const isActive = activeEntity.type === "section" && activeEntity.id === section.id;
20981
21693
  const { inputs, consumers } = useMemo(() => {
20982
21694
  if (hoverBlock) {
@@ -21068,7 +21780,7 @@ function SectionEditor({
21068
21780
  setShowGenerators,
21069
21781
  hasGenerators: Boolean(generators.length)
21070
21782
  },
21071
- optionsMenu
21783
+ sectionSettings: section.settings
21072
21784
  }
21073
21785
  ),
21074
21786
  /* @__PURE__ */ jsxs(
@@ -21844,35 +22556,54 @@ function SectionSettingsPanel() {
21844
22556
  const report = useAppSelector((state) => activeSection && state.records.entities.report[section.report_id]);
21845
22557
  const reportSettings = report?.settings;
21846
22558
  const { settings, updateSettings } = useSectionSettings(activeSection);
22559
+ const optionsMenu = useMemo(() => [
22560
+ { key: "optionData", label: "Download data (csv, xls, json)" },
22561
+ { key: "optionImage", label: "Save Image" },
22562
+ { key: "optionShare", label: "Share link" }
22563
+ ], []);
22564
+ const optionsList = useMemo(() => optionsMenu.map((om) => /* @__PURE__ */ jsxs(List.Item, { children: [
22565
+ om.label,
22566
+ "."
22567
+ ] }, `item-${om.key}`)), [optionsMenu]);
21847
22568
  if (activeEntity.type !== "section" || !activeEntity.id)
21848
22569
  return null;
21849
22570
  return /* @__PURE__ */ jsxs("div", { children: [
21850
22571
  /* @__PURE__ */ jsx(NameInput, { activeSection }),
21851
22572
  /* @__PURE__ */ jsx(Divider, { my: "sm" }),
21852
22573
  /* @__PURE__ */ jsxs(Stack, { mt: "sm", children: [
21853
- /* @__PURE__ */ jsx(
21854
- BespokeInfoTooltip,
21855
- {
21856
- target: /* @__PURE__ */ jsx(
22574
+ /* @__PURE__ */ jsxs(Stack, { spacing: "0.4rem", children: [
22575
+ /* @__PURE__ */ jsx(
22576
+ BespokeInfoTooltip,
22577
+ {
22578
+ target: /* @__PURE__ */ jsx(
22579
+ Switch,
22580
+ {
22581
+ radius: "sm",
22582
+ label: "Show export menu.",
22583
+ checked: settings.optionsMenu,
22584
+ onChange: (e) => updateSettings("optionsMenu", e.currentTarget.checked)
22585
+ }
22586
+ ),
22587
+ dropdown: /* @__PURE__ */ jsxs(Box, { children: [
22588
+ /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Export Menu" }),
22589
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: "The Export Menu will allow users to:" }),
22590
+ /* @__PURE__ */ jsx(List, { withPadding: true, size: "sm", children: optionsList })
22591
+ ] })
22592
+ }
22593
+ ),
22594
+ settings.optionsMenu && /* @__PURE__ */ jsx(Stack, { spacing: "0.5rem", pl: "md", children: optionsMenu.map(
22595
+ (optionMenu) => /* @__PURE__ */ jsx(
21857
22596
  Switch,
21858
22597
  {
21859
22598
  radius: "sm",
21860
- label: "Show export menu.",
21861
- checked: settings.optionsMenu,
21862
- onChange: (e) => updateSettings("optionsMenu", e.currentTarget.checked)
21863
- }
21864
- ),
21865
- dropdown: /* @__PURE__ */ jsxs(Box, { children: [
21866
- /* @__PURE__ */ jsx(Text, { size: "sm", fw: 700, children: "Export Menu" }),
21867
- /* @__PURE__ */ jsx(Text, { size: "sm", children: "The Export Menu will allow users to:" }),
21868
- /* @__PURE__ */ jsxs(List, { withPadding: true, size: "sm", children: [
21869
- /* @__PURE__ */ jsx(List.Item, { children: "Download data (csv, xls, json)." }),
21870
- /* @__PURE__ */ jsx(List.Item, { children: "Save Image" }),
21871
- /* @__PURE__ */ jsx(List.Item, { children: "Share Link" })
21872
- ] })
21873
- ] })
21874
- }
21875
- ),
22599
+ label: optionMenu.label,
22600
+ checked: typeof settings[optionMenu.key] === "undefined" ? settings.optionsMenu : settings[optionMenu.key],
22601
+ onChange: (e) => updateSettings(optionMenu.key, e.currentTarget.checked)
22602
+ },
22603
+ optionMenu.key
22604
+ )
22605
+ ) })
22606
+ ] }),
21876
22607
  /* @__PURE__ */ jsx(
21877
22608
  BespokeInfoTooltip,
21878
22609
  {