@datawheel/bespoke 0.3.13 → 0.3.15-noauth.0

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 (3) hide show
  1. package/dist/index.js +132 -1130
  2. package/dist/server.js +95 -668
  3. package/package.json +1 -3
package/dist/index.js CHANGED
@@ -19,16 +19,15 @@ import { Notifications, notifications } from '@mantine/notifications';
19
19
  import React, { forwardRef, createContext, useState, useCallback, useRef, useEffect, useMemo, useContext, memo, Fragment as Fragment$1, createElement } from 'react';
20
20
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
21
21
  import { useDispatch, useSelector } from 'react-redux';
22
- import { Stack, Text, Badge, Group, Image, Flex, packSx, useMantineTheme, List, Modal, Button, Tooltip, ActionIcon, SegmentedControl, Select, MultiSelect, Center, Grid, Title, Radio, NumberInput, TextInput, Switch, Box, Menu, Anchor, Input, MantineProvider, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Card, Container, Loader, Alert, Burger, Collapse, Checkbox, Accordion, Space, Code, Divider, Textarea, Paper, Autocomplete, Popover, Drawer, rem, Overlay, Header, px, Tabs, FileInput, SimpleGrid, HoverCard, CopyButton, Col } from '@mantine/core';
22
+ import { Stack, Text, Badge, Group, Image, Flex, packSx, useMantineTheme, List, Modal, Button, Tooltip, ActionIcon, SegmentedControl, Select, MultiSelect, Center, Grid, Title, Radio, NumberInput, TextInput, Switch, Box, Menu, Anchor, Input, MantineProvider, Navbar, ScrollArea, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Card, Container, Loader, Alert, Burger, Collapse, Checkbox, Accordion, Space, Code, Divider, Textarea, Paper, Autocomplete, Popover, Drawer, rem, Overlay, Avatar, Header, px, Tabs, FileInput, SimpleGrid, HoverCard, CopyButton, Col } from '@mantine/core';
23
23
  import { dataConcat, dataLoad } from 'd3plus-viz';
24
24
  import * as d3plus from 'd3plus-react';
25
- import Router, { useRouter } from 'next/router';
25
+ import { useRouter } from 'next/router';
26
26
  import { useMediaQuery, useClickOutside, useDisclosure, useDebouncedValue, useSetState, useHotkeys, useFullscreen, getHotkeyHandler } from '@mantine/hooks';
27
- import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconInfoCircle, IconRefresh, IconSearch, IconPlus, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconAlignCenter, IconAlignRight, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconTrash, IconX, IconPhotoFilled, IconFileUpload, IconUserCircle, IconEdit, IconCircleDashed, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconCircleX, IconFlag, IconFileAnalytics, IconHome, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconPolaroid, IconCircleMinus, IconTable, IconCamera, IconShare, IconCirclePlus, IconLogin, IconWorld, IconLock, IconBinaryTree, IconVariable, IconArrowRightCircle, IconIndentIncrease, IconCodeDots, IconUpload, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconDownload, IconTemplate, IconCode, IconPalette, IconSettings, IconMinimize, IconMaximize, IconRss, IconGlobe, IconLinkOff } from '@tabler/icons-react';
27
+ import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconInfoCircle, IconRefresh, IconSearch, IconPlus, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconAlignCenter, IconAlignRight, IconTrash, IconX, IconPhotoFilled, IconFileUpload, IconCircleDashed, IconDatabase, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconCircleX, IconFlag, IconFileAnalytics, IconBallpen, IconMathFunction, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconPolaroid, IconCircleMinus, IconTable, IconCamera, IconShare, IconCirclePlus, IconLogout, IconLogin, IconWorld, IconLock, IconBinaryTree, IconVariable, IconArrowRightCircle, IconIndentIncrease, IconCodeDots, IconUpload, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconTemplate, IconCode, IconDownload, IconPalette, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconSettings, IconMinimize, IconMaximize, IconRss, IconGlobe, IconLinkOff } from '@tabler/icons-react';
28
28
  import dynamic from 'next/dynamic';
29
29
  import Link from 'next/link';
30
30
  import parse2, { Element, domToReact, Text as Text$1 } from 'html-react-parser';
31
- import { UserProvider, withPageAuthRequired, useUser } from '@auth0/nextjs-auth0/client';
32
31
  import { Prism } from '@mantine/prism';
33
32
  import JSZip from 'jszip';
34
33
  import { saveAs } from 'file-saver';
@@ -212,14 +211,8 @@ function apiFactory(baseURL) {
212
211
  readMetadata: httpGET(axios8, "read/metadata"),
213
212
  regenerateSearch: httpPOST(axios8, "search/regenerate"),
214
213
  urlProxy: httpGET(axios8, "url/proxy"),
215
- searchRole: httpGET(axios8, "auth/search/roles"),
216
- searchUser: httpGET(axios8, "auth/search/users"),
217
- readUser: httpGET(axios8, "auth/read/user"),
218
- updateUser: httpPOST(axios8, "auth/update/user"),
219
- addNewReportToCurrentUser: httpPOST(axios8, "auth/update/me"),
220
214
  revalidateReport: httpGET(axios8, "revalidate/report"),
221
215
  revalidateUrl: httpGET(axios8, "revalidate/url"),
222
- readPrivateBlocks: httpPOST(axios8, "read/blocks/private"),
223
216
  listTablerIcons: httpListIconsFactory(axios8, "tabler"),
224
217
  readTablerIcon: httpReadIconFactory(axios8, "tabler")
225
218
  };
@@ -2515,15 +2508,12 @@ var init_recordsActions = __esm({
2515
2508
  var actions_exports = {};
2516
2509
  __export(actions_exports, {
2517
2510
  addBlockToState: () => addBlockToState,
2518
- addNewReportToCurrentUser: () => addNewReportToCurrentUser,
2519
2511
  createEntity: () => createEntity,
2520
2512
  deleteEntity: () => deleteEntity,
2521
2513
  deleteQueryParam: () => deleteQueryParam,
2522
2514
  readEntity: () => readEntity,
2523
2515
  readMember: () => readMember,
2524
2516
  readMetadata: () => readMetadata,
2525
- readPrivateBlocks: () => readPrivateBlocks,
2526
- readUser: () => readUser,
2527
2517
  recalculateVariables: () => recalculateVariables,
2528
2518
  removeBlocksFromState: () => removeBlocksFromState,
2529
2519
  reportSearch: () => reportSearch,
@@ -2532,15 +2522,12 @@ __export(actions_exports, {
2532
2522
  revalidateUrl: () => revalidateUrl,
2533
2523
  searchMember: () => searchMember,
2534
2524
  searchRegenerate: () => searchRegenerate,
2535
- searchRole: () => searchRole,
2536
- searchUser: () => searchUser,
2537
2525
  setCurrentLocale: () => setCurrentLocale,
2538
2526
  setPreviews: () => setPreviews,
2539
2527
  setQueryParam: () => setQueryParam,
2540
2528
  setSectionState: () => setSectionState,
2541
2529
  setStatus: () => setStatus,
2542
2530
  updateEntity: () => updateEntity,
2543
- updateUser: () => updateUser,
2544
2531
  urlProxy: () => urlProxy2,
2545
2532
  variantValidateSlug: () => variantValidateSlug
2546
2533
  });
@@ -2667,51 +2654,6 @@ function urlProxy2(url) {
2667
2654
  return result.data;
2668
2655
  };
2669
2656
  }
2670
- function searchRole() {
2671
- return async (_, __, api) => {
2672
- const result = await api.searchRole("");
2673
- if ("error" in result) {
2674
- throw new Error(result.error);
2675
- }
2676
- return result.data;
2677
- };
2678
- }
2679
- function searchUser(filters) {
2680
- return async (_, __, api) => {
2681
- const result = await api.searchUser(filters);
2682
- if ("error" in result) {
2683
- throw new Error(result.error);
2684
- }
2685
- return result.data;
2686
- };
2687
- }
2688
- function readUser(userId) {
2689
- return async (_, __, api) => {
2690
- const result = await api.readUser({ user_id: userId });
2691
- if ("error" in result) {
2692
- throw new Error(result.error);
2693
- }
2694
- return result.data;
2695
- };
2696
- }
2697
- function updateUser({ user }) {
2698
- return async (_, __, api) => {
2699
- const result = await api.updateUser(user);
2700
- if ("error" in result) {
2701
- throw new Error(result.error);
2702
- }
2703
- return result.data;
2704
- };
2705
- }
2706
- function addNewReportToCurrentUser(params) {
2707
- return async (_, __, api) => {
2708
- const result = await api.addNewReportToCurrentUser(params);
2709
- if ("error" in result) {
2710
- throw new Error(result.error);
2711
- }
2712
- return result.data;
2713
- };
2714
- }
2715
2657
  function removeBlocksFromState(privateBlockIds) {
2716
2658
  const { removeBlocks } = recordsSlice.actions;
2717
2659
  return async (dispatch) => {
@@ -2724,15 +2666,6 @@ function addBlockToState(newBlocks) {
2724
2666
  await dispatch(addBlocks(newBlocks));
2725
2667
  };
2726
2668
  }
2727
- function readPrivateBlocks(params) {
2728
- return async (_, __, api) => {
2729
- const result = await api.readPrivateBlocks({ ...params, roles: [] });
2730
- if ("error" in result) {
2731
- throw new Error(result.error);
2732
- }
2733
- return result.data;
2734
- };
2735
- }
2736
2669
  function revalidateUrl(params) {
2737
2670
  return async (_, __, api) => {
2738
2671
  const result = await api.revalidateUrl({ target: params.target });
@@ -4675,16 +4608,12 @@ init_runConsumers();
4675
4608
  init_store2();
4676
4609
  init_variablesSlice();
4677
4610
  function useInitialState(pathSegmentsKey) {
4678
- const { asPath, locale, defaultLocale } = useRouter();
4611
+ const { asPath, locale } = useRouter();
4679
4612
  const [loading, setLoading] = useState(true);
4680
- const { user, isLoading } = useUser();
4681
- const [privateBlocks, setPrivateBlocks] = useState({ resolved: false, blocks: [] });
4682
4613
  const dispatch = useAppDispatch();
4683
4614
  const [, search] = asPath.split("?");
4684
4615
  const query = search ? JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}') : {};
4685
4616
  const state = useAppSelector((state2) => state2);
4686
- const reports = useReportList().data;
4687
- const report_id = reports && reports[0].id;
4688
4617
  const attributes = useAppSelector((state2) => state2.variables.attributes);
4689
4618
  const blockRecords = selectBlockRecords(state);
4690
4619
  const formatterList = selectFormatterList(state);
@@ -4692,35 +4621,11 @@ function useInitialState(pathSegmentsKey) {
4692
4621
  const variables = useAppSelector((state2) => state2.variables.variables);
4693
4622
  const status = useAppSelector((state2) => state2.variables.status);
4694
4623
  const readMemberFn = useReadMemberFn();
4695
- useEffect(() => {
4696
- if (!isLoading && user && report_id) {
4697
- dispatch(actions_exports.readPrivateBlocks({
4698
- report_id,
4699
- locale: locale || defaultLocale || "en"
4700
- })).then((response) => {
4701
- if (response.data && response.data.length) {
4702
- const blocks = response.data.reduce((normalizedBlocks, block) => ({ ...normalizedBlocks, [block.id]: block }), []);
4703
- dispatch(actions_exports.addBlockToState(blocks)).then(() => {
4704
- setPrivateBlocks({ resolved: true, blocks: response.data.map((block) => block.id) });
4705
- });
4706
- }
4707
- setPrivateBlocks({ resolved: true, blocks: [] });
4708
- setLoading(false);
4709
- }).catch(() => {
4710
- setPrivateBlocks({ resolved: true, blocks: [] });
4711
- setLoading(false);
4712
- });
4713
- }
4714
- if (!isLoading && !user) {
4715
- setPrivateBlocks({ resolved: true, blocks: [] });
4716
- setLoading(false);
4717
- }
4718
- }, [user, isLoading]);
4719
4624
  useEffect(() => {
4720
4625
  const hasParams = Object.keys(query).some((key) => key !== pathSegmentsKey);
4721
- if ((hasParams || privateBlocks.blocks.length > 0) && privateBlocks.resolved) {
4626
+ if (hasParams) {
4722
4627
  const selectorIds = Object.keys(query).map((d) => Number(d.match(/\d+/)));
4723
- const revalidateBlocks = selectorIds.filter((id) => id !== 0).concat(privateBlocks.blocks);
4628
+ const revalidateBlocks = selectorIds.filter((id) => id !== 0);
4724
4629
  Promise.all(
4725
4630
  revalidateBlocks.map((bid) => {
4726
4631
  const block = blockRecords[bid];
@@ -4748,9 +4653,11 @@ function useInitialState(pathSegmentsKey) {
4748
4653
  setLoading(false);
4749
4654
  d.map((data) => dispatch(variablesActions.setVariableChange({ ...data, attributes })));
4750
4655
  });
4656
+ } else {
4657
+ setLoading(false);
4751
4658
  }
4752
- }, [privateBlocks.resolved]);
4753
- return loading || !privateBlocks.resolved;
4659
+ }, []);
4660
+ return loading;
4754
4661
  }
4755
4662
 
4756
4663
  // frontend/hooks/useScrollToAnchor.ts
@@ -7272,9 +7179,18 @@ init_varSwapRecursive();
7272
7179
  init_runConsumers();
7273
7180
  init_consts();
7274
7181
  var formatOptions = {
7275
- csv: "CSV",
7276
- json: "JSON",
7277
- xlsx: "XLSX"
7182
+ csv: {
7183
+ extension: "CSV",
7184
+ icon: IconFileTypeCsv
7185
+ },
7186
+ json: {
7187
+ extension: "JSON",
7188
+ icon: IconFileTypeJs
7189
+ },
7190
+ xlsx: {
7191
+ extension: "XLSX",
7192
+ icon: IconFileTypeXls
7193
+ }
7278
7194
  };
7279
7195
  var DEFAULT_TRANSLATIONS2 = {
7280
7196
  "data_source": "Data Source",
@@ -7293,7 +7209,7 @@ var DEFAULT_TRANSLATIONS2 = {
7293
7209
  "rows_preview": "(First {nrows} rows as preview)",
7294
7210
  "choose_format": "Choose format",
7295
7211
  "processing_file": "Processing file...",
7296
- "download": "Download full selected dataset in {fmt} format",
7212
+ "download": "Download data as",
7297
7213
  "preview": "Preview",
7298
7214
  "copy": "Click to copy",
7299
7215
  "copied": "Copied!"
@@ -7330,9 +7246,9 @@ function DataTab(props) {
7330
7246
  const [selectedSource, setSelectedSource] = useState();
7331
7247
  const [selectedDataset, setSelectedDataset] = useState();
7332
7248
  const [fileProcessing, setFileProcessing] = useState(false);
7333
- const [fileFormat, setFileFormat] = useState(formatOptions.csv);
7334
7249
  const [previewsSource, setPreviewsSource] = useState({});
7335
- const [loadingPreview, setLoadingPreview] = useState(false);
7250
+ const [loadingPreview, setLoadingPreview] = useState(true);
7251
+ const [loadingSources, setLoadingSources] = useState(true);
7336
7252
  const { sectionVariables, setSectionVariables, resetSectionVariables } = useSectionVariables(section.id);
7337
7253
  const blockIds = section.blocks || [];
7338
7254
  const state = useAppSelector((state2) => state2);
@@ -7461,6 +7377,7 @@ function DataTab(props) {
7461
7377
  }
7462
7378
  }
7463
7379
  }
7380
+ setLoadingSources(false);
7464
7381
  }
7465
7382
  }, [blocksData]);
7466
7383
  useEffect(() => {
@@ -7502,28 +7419,28 @@ function DataTab(props) {
7502
7419
  }
7503
7420
  }
7504
7421
  }, [selectedDataset, selectedSource]);
7505
- const getFileName = (nameformat, fileFormat2) => {
7506
- const finalNameFormat = nameformat === fileFormat2 ? "" : `-${nameformat}`.toLowerCase();
7422
+ const getFileName = (nameformat, fileFormat) => {
7423
+ const finalNameFormat = nameformat === fileFormat ? "" : `-${nameformat}`.toLowerCase();
7507
7424
  if (selectedSource) {
7508
7425
  const fileIndex = selectedSource.data.length > 1 && selectedDataset ? `-${parseInt(selectedDataset, 10) + 1}` : "";
7509
- return `${slugify_default(selectedSource.fileName)}${finalNameFormat}${fileIndex}.${fileFormat2.toLowerCase()}`;
7426
+ return `${slugify_default(selectedSource.fileName)}${finalNameFormat}${fileIndex}.${fileFormat.toLowerCase()}`;
7510
7427
  }
7511
- return `${finalNameFormat}.${fileFormat2}`;
7428
+ return `${finalNameFormat}.${fileFormat}`;
7512
7429
  };
7513
- const onSaveClick = async () => {
7430
+ const onSaveClick = async (fileFormat) => {
7514
7431
  if (selectedSource) {
7515
7432
  setFileProcessing(true);
7516
7433
  const zipFile = new JSZip();
7517
7434
  const filename = getFileName(fileFormat, fileFormat);
7518
7435
  try {
7519
7436
  switch (fileFormat) {
7520
- case formatOptions.json:
7437
+ case formatOptions.json.extension:
7521
7438
  zipFile.file(filename, JSON.stringify(currentPreview));
7522
7439
  break;
7523
- case formatOptions.csv:
7440
+ case formatOptions.csv.extension:
7524
7441
  zipFile.file(filename, csvFormat(currentPreview));
7525
7442
  break;
7526
- case formatOptions.xlsx:
7443
+ case formatOptions.xlsx.extension:
7527
7444
  const { utils, write } = await import('xlsx');
7528
7445
  const wb = utils.book_new();
7529
7446
  utils.book_append_sheet(
@@ -7570,8 +7487,9 @@ function DataTab(props) {
7570
7487
  )), [sourcesOptions, selectedSource, sourcesToLoad]);
7571
7488
  return /* @__PURE__ */ jsxs(Stack, { className: "cms-section-options-data", children: [
7572
7489
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
7573
- sourcesOptions.length === 0 && /* @__PURE__ */ jsx("p", { children: "No data sources defined." }),
7574
- sourcesOptions.length > 1 && /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_data_src"]}:`, children: /* @__PURE__ */ jsx(Group, { spacing: "xs", children: sourcesButtons }) }),
7490
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loadingSources, overlayBlur: 2 }),
7491
+ sourcesOptions.length === 0 && !loadingSources && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconAlertCircle, { size: "1rem" }), title: "Oops!", children: translations["no_data_src"] }),
7492
+ sourcesOptions.length > 1 && sourcesOptions.length === sourcesToLoad.length && !loadingSources && /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_data_src"]}:`, children: /* @__PURE__ */ jsx(Group, { spacing: "xs", children: sourcesButtons }) }),
7575
7493
  selectedSource && selectedDataset && /* @__PURE__ */ jsx(Stack, { spacing: "xs", children: /* @__PURE__ */ jsx(
7576
7494
  Input.Wrapper,
7577
7495
  {
@@ -7596,7 +7514,7 @@ function DataTab(props) {
7596
7514
  /* @__PURE__ */ jsx(
7597
7515
  CopyButton,
7598
7516
  {
7599
- value: selectedSource.data[selectedDataset] === "string" ? selectedSource.data[selectedDataset] : "",
7517
+ value: typeof selectedSource.data[selectedDataset] === "string" ? selectedSource.data[selectedDataset] : "",
7600
7518
  timeout: 2e3,
7601
7519
  children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? translations["copied"] : translations["copy"], withArrow: true, position: "top", children: /* @__PURE__ */ jsx(
7602
7520
  ActionIcon,
@@ -7621,32 +7539,21 @@ function DataTab(props) {
7621
7539
  children: translations["open_in_window"].replace("{src}", selectedSource.title)
7622
7540
  }
7623
7541
  ) }),
7624
- /* @__PURE__ */ jsxs(Stack, { pos: "relative", mih: "450px", children: [
7625
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loadingPreview }),
7542
+ /* @__PURE__ */ jsxs(Stack, { pos: "relative", mih: "430px", children: [
7543
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loadingPreview && sourcesOptions.length > 0, overlayBlur: 2 }),
7626
7544
  selectedSource && !loadingPreview && currentPreview.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
7627
- /* @__PURE__ */ jsx(Box, { h: "300px", children: /* @__PURE__ */ jsx(SortableTable, { data: currentPreview.slice(0, PREVIEW_SIZE) }) }),
7628
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
7629
- /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_format"]}: ${getFileName(fileFormat, fileFormat)}`, children: /* @__PURE__ */ jsx(Button.Group, { children: Object.keys(formatOptions).map((format2) => /* @__PURE__ */ jsx(
7630
- Button,
7631
- {
7632
- leftIcon: /* @__PURE__ */ jsx(IconTable, { size: 16 }),
7633
- onClick: () => setFileFormat(formatOptions[format2]),
7634
- variant: fileFormat === formatOptions[format2] ? "filled" : "default",
7635
- fullWidth: true,
7636
- children: formatOptions[format2]
7637
- },
7638
- `format-${format2}`
7639
- )) }) }),
7640
- /* @__PURE__ */ jsx(
7545
+ /* @__PURE__ */ jsx(Box, { h: "350px", children: /* @__PURE__ */ jsx(SortableTable, { data: currentPreview.slice(0, PREVIEW_SIZE) }) }),
7546
+ /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["download"]}:`, children: /* @__PURE__ */ jsx(Button.Group, { children: Object.values(formatOptions).map((format2) => /* @__PURE__ */ jsx(
7641
7547
  Button,
7642
7548
  {
7643
- leftIcon: /* @__PURE__ */ jsx(IconDownload, { size: 16 }),
7549
+ leftIcon: /* @__PURE__ */ jsx(format2.icon, { size: 24 }),
7550
+ onClick: () => onSaveClick(format2.extension),
7644
7551
  loading: fileProcessing,
7645
- onClick: onSaveClick,
7646
7552
  fullWidth: true,
7647
- children: /* @__PURE__ */ jsx("span", { children: fileProcessing ? translations["processing_file"] : translations["download"].replace("{fmt}", fileFormat) })
7648
- }
7649
- )
7553
+ children: format2.extension
7554
+ },
7555
+ `format-${format2.extension}`
7556
+ )) }) })
7650
7557
  ] })
7651
7558
  ] })
7652
7559
  ] });
@@ -7677,7 +7584,7 @@ var DEFAULT_TRANSLATIONS3 = {
7677
7584
  function ImageTab(props) {
7678
7585
  const { section } = props;
7679
7586
  const blocksIds = section.blocks || [];
7680
- const vizBlocks = useAppSelector((state) => blocksIds.map((blockId) => state.records.entities.block[blockId]).filter((block) => block.type === "visualization"));
7587
+ const vizBlocks = useAppSelector((state) => blocksIds.map((blockId) => state.records.entities.block[blockId]).filter((block) => block.type === "visualization" && state.variables.status[block.id].allowed));
7681
7588
  const [imageContext, setImageContext] = useState(contextOptions.section);
7682
7589
  const [imageFormat, setImageFormat] = useState(formatOptions2.png);
7683
7590
  const [imageProcessing, setImageProcessing] = useState(false);
@@ -7805,31 +7712,35 @@ function ImageTab(props) {
7805
7712
  }, [vizSelected]);
7806
7713
  return /* @__PURE__ */ jsxs(Stack, { className: "cms-section-options-image", children: [
7807
7714
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
7808
- /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_area"]}:`, children: /* @__PURE__ */ jsxs(Button.Group, { children: [
7809
- /* @__PURE__ */ jsx(
7810
- Button,
7811
- {
7812
- leftIcon: /* @__PURE__ */ jsx(IconTemplate, { size: 16 }),
7813
- onClick: () => {
7814
- setImageContext(contextOptions.section);
7815
- setImageFormat(formatOptions2.png);
7715
+ /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_area"]}:`, children: /* @__PURE__ */ jsx(
7716
+ SegmentedControl,
7717
+ {
7718
+ fullWidth: true,
7719
+ value: imageContext,
7720
+ data: [
7721
+ {
7722
+ value: contextOptions.section,
7723
+ label: /* @__PURE__ */ jsxs(Center, { children: [
7724
+ /* @__PURE__ */ jsx(IconTemplate, { size: "1rem" }),
7725
+ /* @__PURE__ */ jsx(Box, { ml: 10, children: translations["entire_section"] })
7726
+ ] })
7816
7727
  },
7817
- variant: imageContext === contextOptions.section ? "filled" : "default",
7818
- fullWidth: true,
7819
- children: translations["entire_section"]
7820
- }
7821
- ),
7822
- vizAvailable.length > 0 && /* @__PURE__ */ jsx(
7823
- Button,
7824
- {
7825
- leftIcon: /* @__PURE__ */ jsx(IconChartBar, { size: 16 }),
7826
- onClick: () => setImageContext(contextOptions.viz),
7827
- variant: imageContext === contextOptions.viz ? "filled" : "default",
7828
- fullWidth: true,
7829
- children: translations["viz_only"]
7728
+ {
7729
+ value: contextOptions.viz,
7730
+ label: /* @__PURE__ */ jsxs(Center, { children: [
7731
+ /* @__PURE__ */ jsx(IconChartBar, { size: "1rem" }),
7732
+ /* @__PURE__ */ jsx(Box, { ml: 10, children: translations["viz_only"] })
7733
+ ] })
7734
+ }
7735
+ ],
7736
+ onChange: (newValue) => {
7737
+ setImageContext(newValue);
7738
+ if (newValue === contextOptions.section) {
7739
+ setImageFormat(formatOptions2.png);
7740
+ }
7830
7741
  }
7831
- )
7832
- ] }) }),
7742
+ }
7743
+ ) }),
7833
7744
  imageContext === contextOptions.viz && vizAvailable.length > 0 && /* @__PURE__ */ jsxs(
7834
7745
  Input.Wrapper,
7835
7746
  {
@@ -8530,8 +8441,8 @@ init_esm_shims();
8530
8441
  init_store2();
8531
8442
  var ALLOWED_UNITS = ["px", "%"];
8532
8443
  var formatters = {
8533
- px: (value) => !Number.isNaN(parseFloat(value)) ? `${value}px`.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",") : "px",
8534
- ["%"]: (value) => !Number.isNaN(parseFloat(value)) ? `${value}%`.replace(/\B(?<!\.\d*)(?=(\d{3})+(?!\d))/g, ",") : "%"
8444
+ px: (value) => !Number.isNaN(parseFloat(value)) ? `${value}px`.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,") : "px",
8445
+ "%": (value) => !Number.isNaN(parseFloat(value)) ? `${value}%`.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,") : "%"
8535
8446
  };
8536
8447
  var WidthInputProps = {
8537
8448
  "px": {
@@ -8986,135 +8897,6 @@ function Report() {
8986
8897
  }
8987
8898
  var Report_default = Report;
8988
8899
 
8989
- // frontend/components/auth/LoginButton.tsx
8990
- init_esm_shims();
8991
-
8992
- // types/auth.ts
8993
- init_esm_shims();
8994
- var CMS_ROLES = {
8995
- ADMIN: "Admin",
8996
- EDITOR: "Editor",
8997
- WRITER: "Writer"
8998
- };
8999
- function BespokeLoginBtn({
9000
- buttonProps = {},
9001
- editorMenuItemProps = {},
9002
- editorMenuItemRoute = "/cms",
9003
- logoutButtonProps = {},
9004
- menuProps = {},
9005
- options = "",
9006
- optionsPosition = "bottom",
9007
- translations = {},
9008
- withEditorMenuItem = true,
9009
- withSession = true
9010
- }) {
9011
- const { user, error, isLoading } = useUser();
9012
- const userRoles = useMemo(() => user?.bespoke_roles || [], [user]);
9013
- const isCMSUser = useMemo(() => CMS_ROLES && Object.keys(CMS_ROLES).length > 0 && Object.keys(CMS_ROLES).some((role) => userRoles.includes(CMS_ROLES[role])), [userRoles]);
9014
- const buttonConfig = {
9015
- leftIcon: /* @__PURE__ */ jsx(IconUserCircle, {}),
9016
- ...buttonProps
9017
- };
9018
- if (user && !error && !isLoading) {
9019
- const editorMenuItemConfig = {
9020
- ...editorMenuItemProps
9021
- };
9022
- const logoutButtonConfig = {
9023
- color: "red",
9024
- fullWidth: true,
9025
- leftIcon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
9026
- size: "xs",
9027
- variant: "subtle",
9028
- ...logoutButtonProps
9029
- };
9030
- const menuConfig = {
9031
- shadow: "md",
9032
- width: "auto",
9033
- position: "bottom",
9034
- ...menuProps
9035
- };
9036
- const cmsButton = /* @__PURE__ */ jsx(Link, { href: editorMenuItemRoute, passHref: true, children: /* @__PURE__ */ jsx(
9037
- Menu.Item,
9038
- {
9039
- icon: /* @__PURE__ */ jsx(IconEdit, { size: 14 }),
9040
- ...editorMenuItemConfig,
9041
- children: translations["Go to editor"] || "Go to editor"
9042
- }
9043
- ) });
9044
- return /* @__PURE__ */ jsxs(Menu, { ...menuConfig, children: [
9045
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Button, { ...buttonConfig, children: `${translations["Welcome message"] || `Hi, ${user.name || user.email}`}` }) }),
9046
- /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
9047
- optionsPosition === "top" && /* @__PURE__ */ jsxs(Fragment, { children: [
9048
- withEditorMenuItem && isCMSUser && cmsButton,
9049
- options,
9050
- (options || withEditorMenuItem && isCMSUser) && /* @__PURE__ */ jsx(Menu.Divider, {})
9051
- ] }),
9052
- withSession && /* @__PURE__ */ jsxs(
9053
- Menu.Item,
9054
- {
9055
- component: "span",
9056
- style: { pointerEvents: "none" },
9057
- icon: /* @__PURE__ */ jsx(Avatar, { src: user.picture, radius: "md" }),
9058
- children: [
9059
- /* @__PURE__ */ jsx(Text, { size: "sm", weight: 500, children: user.name }),
9060
- /* @__PURE__ */ jsx(Text, { color: "dimmed", size: "xs", children: user.email })
9061
- ]
9062
- }
9063
- ),
9064
- /* @__PURE__ */ jsx(
9065
- Button,
9066
- {
9067
- component: "a",
9068
- href: "/api/auth/logout",
9069
- ...logoutButtonConfig,
9070
- children: translations["Disconnect"] || "Disconnect"
9071
- }
9072
- ),
9073
- optionsPosition === "bottom" && /* @__PURE__ */ jsxs(Fragment, { children: [
9074
- (options || withEditorMenuItem && isCMSUser) && /* @__PURE__ */ jsx(Menu.Divider, {}),
9075
- withEditorMenuItem && isCMSUser && cmsButton,
9076
- options
9077
- ] })
9078
- ] })
9079
- ] });
9080
- }
9081
- return /* @__PURE__ */ jsx(
9082
- Button,
9083
- {
9084
- component: "a",
9085
- href: "/api/auth/login",
9086
- loading: isLoading,
9087
- ...buttonConfig,
9088
- children: isLoading ? translations["Signing in"] || "Signing in..." : translations["Sign in"] || "Sign in"
9089
- }
9090
- );
9091
- }
9092
- var LoginButton_default = BespokeLoginBtn;
9093
-
9094
- // frontend/components/auth/UserProvider.tsx
9095
- init_esm_shims();
9096
- var UserProvider_default = UserProvider;
9097
-
9098
- // frontend/components/auth/withPageRoleAuthRequired.tsx
9099
- init_esm_shims();
9100
- function withPageRoleAuthRequired(params) {
9101
- const { SuccessComponent, FailureComponent, options } = params;
9102
- const allowedRoles = new Set(params.allowedRoles);
9103
- return withPageAuthRequired(({ user, ...props }) => {
9104
- return useMemo(() => {
9105
- const userRoles = user.bespoke_roles || [];
9106
- if (allowedRoles.size === 0 || userRoles.some((role) => allowedRoles.has(role))) {
9107
- return /* @__PURE__ */ jsx(SuccessComponent, { user, ...props });
9108
- }
9109
- return /* @__PURE__ */ jsx(FailureComponent, { ...props });
9110
- }, [user, props]);
9111
- }, options);
9112
- }
9113
-
9114
- // frontend/components/auth/useUser.tsx
9115
- init_esm_shims();
9116
- var useUser_default = useUser;
9117
-
9118
8900
  // index.ts
9119
8901
  init_store2();
9120
8902
 
@@ -10323,7 +10105,6 @@ function HeaderLayout(props) {
10323
10105
  init_hooks();
10324
10106
  function CMSHeader(props) {
10325
10107
  const { report: currentReport } = props;
10326
- const { id } = currentReport;
10327
10108
  const { newConfirmation } = useDialog();
10328
10109
  const dispatch = useAppDispatch();
10329
10110
  const { selectEntity } = useActiveEntity();
@@ -10338,8 +10119,6 @@ function CMSHeader(props) {
10338
10119
  const previewsFromState = useAppSelector((state) => state.status.previews);
10339
10120
  const settings = useSidebar("settings");
10340
10121
  const reportEditor = useSidebar("reportEditor");
10341
- const { user } = useUser();
10342
- const castedUser = user;
10343
10122
  const dimensions = useMemo(() => {
10344
10123
  return currentReport && currentReport.dimensions ? currentReport.dimensions : [];
10345
10124
  }, [currentReport]);
@@ -10423,16 +10202,6 @@ function CMSHeader(props) {
10423
10202
  setInitialFavorites(previewsFromState.map((ps) => ({ variantId: ps.variant_id, contentId: ps.content_id })));
10424
10203
  }
10425
10204
  }, [previewsFromState]);
10426
- useEffect(() => {
10427
- if (castedUser) {
10428
- if (castedUser.bespoke_app_metadata && castedUser.bespoke_app_metadata.reports && Array.isArray(castedUser.bespoke_app_metadata.reports)) {
10429
- const currentReportConfig = castedUser.bespoke_app_metadata.reports.find((r) => r.reportId === id);
10430
- if (currentReportConfig && currentReportConfig.favorites) {
10431
- setInitialFavorites(currentReportConfig.favorites);
10432
- }
10433
- }
10434
- }
10435
- }, [castedUser, id, previewsFromState]);
10436
10205
  return /* @__PURE__ */ jsxs(Fragment, { children: [
10437
10206
  /* @__PURE__ */ jsx(
10438
10207
  HeaderLayout,
@@ -10908,34 +10677,12 @@ function BlockSettings({ id, setBlockSettings, setBlockContent }) {
10908
10677
  const { newConfirmation } = useDialog();
10909
10678
  const dispatch = useAppDispatch();
10910
10679
  const block = useBlockRef(id).data;
10911
- const [accessSelected, setAccessSelected] = useState(block.settings[BLOCK_SETTINGS.ACCESS] || ["public"]);
10912
- const [roles, setRoles] = useState([]);
10913
10680
  const variables = useInputVariablesFlat(id);
10914
10681
  const allowedOptions = useMemo(() => [
10915
10682
  { value: "always", label: "always", group: "Static" },
10916
10683
  { value: "never", label: "never", group: "Static" }
10917
10684
  ].concat(Object.keys(variables).map((d) => ({ value: d, label: `${d}: ${variables[d]}`, group: "Based on variable" }))), [variables]);
10918
- const accessOptions = useMemo(() => [
10919
- { value: "public", label: "Public block, (all visitors)", group: "Exclusive" },
10920
- { value: "guest", label: "Guest only block, (non logged visitors)", group: "Exclusive" },
10921
- { value: "private", label: "Private block, (session required, any role)", group: "Exclusive" }
10922
- ], []);
10923
- const rolesOptions = useMemo(
10924
- () => roles.map((r) => ({ value: `role.${r.name}`, label: `Role ${r.name} (${r.type})`, group: `${r.type} Roles` })),
10925
- [roles]
10926
- );
10927
10685
  const shared = [{ label: "Section-wide", value: "false" }, { label: "Report-wide", value: "true" }];
10928
- useEffect(() => {
10929
- dispatch(actions_exports.searchRole()).then((response) => {
10930
- setRoles(response.roles);
10931
- });
10932
- }, []);
10933
- useEffect(() => {
10934
- setBlockSettings({
10935
- [BLOCK_SETTINGS.ACCESS]: accessSelected
10936
- //[BLOCK_SETTINGS.ACCESS_LOGIC]: allowedLogic,
10937
- });
10938
- }, [accessSelected]);
10939
10686
  const maybeDelete = async () => {
10940
10687
  try {
10941
10688
  await newConfirmation({
@@ -10954,18 +10701,6 @@ function BlockSettings({ id, setBlockSettings, setBlockContent }) {
10954
10701
  }
10955
10702
  );
10956
10703
  };
10957
- const handleAccessChange = (selectedAccessOptions) => {
10958
- let newSelectedAccess = [];
10959
- if (selectedAccessOptions.length === 0) {
10960
- newSelectedAccess = selectedAccessOptions.length === 0 ? [accessOptions[0].value] : selectedAccessOptions;
10961
- } else {
10962
- const last = selectedAccessOptions.slice(-1)[0];
10963
- const exclusiveSelections = accessOptions.map((ao) => ao.value);
10964
- const lastIsExclusive = exclusiveSelections.includes(last);
10965
- newSelectedAccess = lastIsExclusive ? [last] : selectedAccessOptions.filter((so) => !exclusiveSelections.includes(so));
10966
- }
10967
- setAccessSelected(newSelectedAccess);
10968
- };
10969
10704
  const handleChangeAllowedDropdown = (allowed) => {
10970
10705
  let allowedLogic = `return variables.${allowed}`;
10971
10706
  if (allowed === "always")
@@ -11017,16 +10752,6 @@ function BlockSettings({ id, setBlockSettings, setBlockContent }) {
11017
10752
  onChange: handleChangeCascadeDropdown
11018
10753
  }
11019
10754
  ),
11020
- /* @__PURE__ */ jsx(
11021
- MultiSelect,
11022
- {
11023
- label: "Privacy",
11024
- description: "This block will be shown based on the selected auth0 roles.",
11025
- data: [...accessOptions, ...rolesOptions],
11026
- value: accessSelected,
11027
- onChange: handleAccessChange
11028
- }
11029
- ),
11030
10755
  /* @__PURE__ */ jsx(Title, { order: 4, children: "Output" }),
11031
10756
  isShared && block.shared && /* @__PURE__ */ jsxs(Text, { size: "xs", color: "red.4", sx: { display: "flex", alignItems: "flex-start", gap: "0.4rem" }, children: [
11032
10757
  /* @__PURE__ */ jsx(IconAlertCircle, { size: "1.2rem" }),
@@ -14058,7 +13783,6 @@ function FormatterEditor() {
14058
13783
  // views/HelloView.tsx
14059
13784
  init_esm_shims();
14060
13785
  function HelloView() {
14061
- const { user } = useUser();
14062
13786
  return /* @__PURE__ */ jsxs(
14063
13787
  Flex,
14064
13788
  {
@@ -14069,11 +13793,7 @@ function HelloView() {
14069
13793
  direction: "column",
14070
13794
  wrap: "wrap",
14071
13795
  children: [
14072
- /* @__PURE__ */ jsxs(Title, { children: [
14073
- "Hi, ",
14074
- user.name,
14075
- "!"
14076
- ] }),
13796
+ /* @__PURE__ */ jsx(Title, { children: "Hi, editor!" }),
14077
13797
  /* @__PURE__ */ jsx(Text, { children: "Welcome to Bespoke CMS. Have fun creating some amazing automated reports here!" })
14078
13798
  ]
14079
13799
  }
@@ -15038,7 +14758,6 @@ function MetadataEditor() {
15038
14758
  // views/NotFoundView.tsx
15039
14759
  init_esm_shims();
15040
14760
  function NotFoundView() {
15041
- const { user } = useUser();
15042
14761
  const textStyle = { color: "#000" };
15043
14762
  return /* @__PURE__ */ jsxs(
15044
14763
  Flex,
@@ -15052,11 +14771,7 @@ function NotFoundView() {
15052
14771
  style: { background: "white" },
15053
14772
  children: [
15054
14773
  /* @__PURE__ */ jsx(Title, { style: textStyle, children: "Not found." }),
15055
- /* @__PURE__ */ jsxs(Title, { order: 2, style: textStyle, children: [
15056
- "Sorry, ",
15057
- user?.name,
15058
- "!"
15059
- ] }),
14774
+ /* @__PURE__ */ jsx(Title, { order: 2, style: textStyle, children: "Sorry!" }),
15060
14775
  /* @__PURE__ */ jsx(Text, { style: textStyle, children: "The page you are looking for is not here." }),
15061
14776
  /* @__PURE__ */ jsx(Button, { component: "a", href: "/", children: "Back to homepage" })
15062
14777
  ]
@@ -15096,28 +14811,14 @@ withFetcher(ReportCard, useReportRef);
15096
14811
  // views/PickReport.tsx
15097
14812
  init_store2();
15098
14813
  init_hooks();
15099
-
15100
- // libs/auth/utils.ts
15101
- init_esm_shims();
15102
- var getReportAccess = (user) => {
15103
- const reportsMetadata = user && user.bespoke_app_metadata && user.bespoke_app_metadata.reports && Array.isArray(user.bespoke_app_metadata.reports) ? user.bespoke_app_metadata.reports : [];
15104
- return reportsMetadata.map((rm) => rm.reportId);
15105
- };
15106
14814
  function ReportPicker() {
15107
14815
  const dispatch = useAppDispatch();
15108
14816
  const [createLoading, setCreateLoading] = useState(false);
15109
- const { user } = useUser();
15110
- const reportAccess = getReportAccess(user);
15111
14817
  const ref = useReportList();
15112
14818
  const createHandler = useCallback((value) => {
15113
14819
  setCreateLoading(true);
15114
14820
  dispatch(actions_exports.createEntity("report", value)).then((response) => {
15115
- if (response.ok && reportAccess.length > 0) {
15116
- dispatch(actions_exports.addNewReportToCurrentUser({ report_id: response.data.id })).then(() => {
15117
- Router.reload();
15118
- setCreateLoading(false);
15119
- });
15120
- } else {
14821
+ if (response.ok) {
15121
14822
  setCreateLoading(false);
15122
14823
  }
15123
14824
  });
@@ -15137,12 +14838,12 @@ function ReportPicker() {
15137
14838
  ReportCard,
15138
14839
  {
15139
14840
  for: report,
15140
- enabled: reportAccess.length === 0 || reportAccess.includes(report.id) ? true : false
14841
+ enabled: true
15141
14842
  },
15142
14843
  report.id
15143
14844
  )
15144
14845
  ) });
15145
- }, [ref.data, ref.error, ref.status, reportAccess]);
14846
+ }, [ref.data, ref.error, ref.status]);
15146
14847
  return /* @__PURE__ */ jsxs(Container, { size: "xl", children: [
15147
14848
  /* @__PURE__ */ jsx("h1", { children: "Reports" }),
15148
14849
  /* @__PURE__ */ jsx(LoadingOverlay, { visible: createLoading, overlayBlur: 2, overlayOpacity: 50 }),
@@ -15164,670 +14865,23 @@ function ReportPicker() {
15164
14865
  ] });
15165
14866
  }
15166
14867
 
15167
- // views/UnathorizeView.tsx
15168
- init_esm_shims();
15169
- function UnauthorizeView() {
15170
- const { user } = useUser();
15171
- const textStyle = { color: "#000" };
15172
- return /* @__PURE__ */ jsxs(
15173
- Flex,
15174
- {
15175
- mih: "100vh",
15176
- gap: "md",
15177
- justify: "center",
15178
- align: "center",
15179
- direction: "column",
15180
- wrap: "wrap",
15181
- style: { background: "white" },
15182
- children: [
15183
- /* @__PURE__ */ jsx(Title, { style: textStyle, children: "Unauthorize or forbidden access." }),
15184
- /* @__PURE__ */ jsxs(Title, { style: textStyle, order: 2, children: [
15185
- "Sorry, ",
15186
- user?.name,
15187
- "!"
15188
- ] }),
15189
- /* @__PURE__ */ jsx(Text, { style: textStyle, children: "Your session or your user's roles doesn't satisfy the needs of the requested view. Please, ask your administrator to allow you." }),
15190
- /* @__PURE__ */ jsxs(Group, { children: [
15191
- /* @__PURE__ */ jsx(
15192
- Button,
15193
- {
15194
- component: "a",
15195
- href: "/",
15196
- leftIcon: /* @__PURE__ */ jsx(IconHome, { size: 14 }),
15197
- variant: "outline",
15198
- color: "dark",
15199
- children: "Back to homepage"
15200
- }
15201
- ),
15202
- /* @__PURE__ */ jsx(
15203
- Button,
15204
- {
15205
- component: "a",
15206
- href: "/api/auth/logout",
15207
- leftIcon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
15208
- variant: "outline",
15209
- color: "dark",
15210
- children: "Disconnect"
15211
- }
15212
- )
15213
- ] })
15214
- ]
15215
- }
15216
- );
15217
- }
15218
-
15219
- // views/UsersEditor.tsx
15220
- init_esm_shims();
14868
+ // views/BespokeManager.tsx
14869
+ init_ErrorBoundary();
14870
+ init_envvars();
14871
+ init_statusSlice();
15221
14872
  init_store2();
15222
-
15223
- // components/users/FilterSidebar.tsx
15224
- init_esm_shims();
15225
- var allOption3 = { value: "all", label: "All" };
15226
- var buildOptions2 = (options) => {
15227
- if (!options)
15228
- return [];
15229
- const selectOptions = options.map((d) => ({ value: String(d.id), label: `${d.name} (${d.type})` }));
15230
- return [allOption3, ...selectOptions];
15231
- };
15232
- function FilterSidebar3({ onChange, loading, roles }) {
15233
- const initialFilterState = {
15234
- role_id: allOption3.value,
15235
- query: "",
15236
- page: 0
15237
- };
15238
- const [filters, setFilters] = useState(initialFilterState);
15239
- const [debouncedQuery] = useDebouncedValue(filters.query, 500);
15240
- const options = useMemo(() => ({
15241
- roles: buildOptions2(roles)
15242
- }), [roles]);
15243
- const onChangeFilter = useCallback((key, value) => {
15244
- const newFilters = {
15245
- ...filters,
15246
- [key]: value
15247
- };
15248
- setFilters(newFilters);
15249
- }, [filters]);
15250
- const onClearFilters = () => {
15251
- setFilters(initialFilterState);
14873
+ function BespokeManager(options) {
14874
+ const {
14875
+ title = "Bespoke CMS",
14876
+ pathSegment = "bespoke",
14877
+ locale = localeDefault4,
14878
+ profilePrefix = "/profilePathManager"
14879
+ } = options;
14880
+ const notifications5 = {
14881
+ position: "bottom-center",
14882
+ ...options.notifications
15252
14883
  };
15253
- useEffect(() => {
15254
- onChange({ ...filters, query: debouncedQuery });
15255
- }, [filters.role_id, filters.page, debouncedQuery]);
15256
- return /* @__PURE__ */ jsxs("div", { children: [
15257
- /* @__PURE__ */ jsx(
15258
- Select,
15259
- {
15260
- label: "Roles",
15261
- data: options.roles,
15262
- value: filters.role_id,
15263
- onChange: (value) => onChangeFilter("role_id", value),
15264
- disabled: loading
15265
- }
15266
- ),
15267
- /* @__PURE__ */ jsx(
15268
- TextInput,
15269
- {
15270
- label: "Search by name or email",
15271
- value: filters.role_id !== "all" ? "" : filters.query,
15272
- onChange: (event) => onChangeFilter("query", event.currentTarget.value),
15273
- disabled: loading || filters.role_id !== "all"
15274
- }
15275
- ),
15276
- /* @__PURE__ */ jsx(Space, { h: "md" }),
15277
- /* @__PURE__ */ jsx(
15278
- Button,
15279
- {
15280
- fullWidth: true,
15281
- disabled: loading,
15282
- leftIcon: /* @__PURE__ */ jsx(IconCircleX, {}),
15283
- onClick: onClearFilters,
15284
- children: "Clear filters"
15285
- }
15286
- )
15287
- ] });
15288
- }
15289
-
15290
- // components/users/UserForm.tsx
15291
- init_esm_shims();
15292
-
15293
- // components/users/FavoriteMemberSelector.tsx
15294
- init_esm_shims();
15295
- init_store2();
15296
- function FavoriteMemberSelector({ reportId, initialFavorites = [], onSelectFavorites, onClickDelete }) {
15297
- const reportRef = useReportRef(reportId);
15298
- const localeDefault10 = useAppSelector((state) => state.status.localeDefault);
15299
- const currentReport = reportRef.data;
15300
- const [selectedMembers, setSelectedMembers] = useState(
15301
- currentReport ? currentReport.dimensions.map((d) => void 0) : [void 0]
15302
- );
15303
- const onSelectPreview = (ix, selectedPreview) => {
15304
- const newSelectedMembers = [...selectedMembers];
15305
- newSelectedMembers[ix] = selectedPreview ? {
15306
- variantId: parseInt(selectedPreview.variant_id, 10),
15307
- contentId: parseInt(selectedPreview.content_id, 10)
15308
- } : void 0;
15309
- setSelectedMembers(newSelectedMembers);
15310
- if (!newSelectedMembers.some((nsm) => typeof nsm === "undefined")) {
15311
- onSelectFavorites(reportId, newSelectedMembers);
15312
- }
15313
- };
15314
- useEffect(() => {
15315
- if (reportRef.isError) {
15316
- onClickDelete(reportId);
15317
- }
15318
- }, [reportRef.isError]);
15319
- return /* @__PURE__ */ jsx(Stack, { children: currentReport && /* @__PURE__ */ jsxs(Fragment, { children: [
15320
- /* @__PURE__ */ jsxs(Group, { children: [
15321
- /* @__PURE__ */ jsxs(Text, { children: [
15322
- "Report: ",
15323
- currentReport.name
15324
- ] }),
15325
- /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickDelete(reportId), children: /* @__PURE__ */ jsx(IconTrash, {}) })
15326
- ] }),
15327
- currentReport.dimensions.length === 0 && /* @__PURE__ */ jsx(Group, { children: /* @__PURE__ */ jsxs(Text, { c: "dimmed", fz: "sm", children: [
15328
- "No dimensions created in report ",
15329
- currentReport.name,
15330
- " yet."
15331
- ] }) }),
15332
- currentReport.dimensions.map((dId, ix) => /* @__PURE__ */ jsx(Group, { children: /* @__PURE__ */ jsx(
15333
- DimensionAutocomplete,
15334
- {
15335
- id: dId,
15336
- initialSelection: initialFavorites[ix] ? initialFavorites[ix] : void 0,
15337
- onSelect: (selectedPreview) => onSelectPreview(ix, selectedPreview),
15338
- locale: localeDefault10
15339
- }
15340
- ) }, dId))
15341
- ] }) });
15342
- }
15343
-
15344
- // components/users/UserForm.tsx
15345
- init_store2();
15346
-
15347
- // components/builder/ReportSelect.tsx
15348
- init_esm_shims();
15349
- init_store2();
15350
- function ReportSelect({ selectedReportId = "", onChangeReport, exclude = [] }) {
15351
- const reportList = useReportList();
15352
- const onChangeReportAction = (value) => {
15353
- onChangeReport(value);
15354
- };
15355
- const reportOptions = useMemo(() => {
15356
- if (!reportList.isSuccess)
15357
- return [];
15358
- return reportList.data.map((d) => ({ value: `${d.id}`, label: d.name }));
15359
- }, [reportList.status]);
15360
- const availableOptions = reportOptions.filter((ro) => !exclude.includes(ro.value));
15361
- return /* @__PURE__ */ jsx(
15362
- Select,
15363
- {
15364
- style: { width: 100 },
15365
- size: "xs",
15366
- placeholder: "Choose a report",
15367
- data: availableOptions,
15368
- value: String(selectedReportId),
15369
- onChange: onChangeReportAction,
15370
- disabled: availableOptions.length === 0
15371
- }
15372
- );
15373
- }
15374
- var buildOptions3 = (options) => {
15375
- if (!options)
15376
- return [];
15377
- return options.map((d) => ({ value: String(d.id), label: d.name, group: d.type }));
15378
- };
15379
- function UserForm({ userId, onEditEnd, roles }) {
15380
- const dispatch = useAppDispatch();
15381
- const { user } = useUser();
15382
- const [userData, setUserData] = useState(null);
15383
- const [loading, setLoading] = useState(true);
15384
- const [error, setError] = useState(false);
15385
- const [multiselectError, setMultiselectError] = useState("");
15386
- const [editAll, setEditAll] = useState(true);
15387
- const [selectedReportId, setSelectedReportId] = useState("");
15388
- const mainForm = useForm();
15389
- const isYou = useMemo(() => {
15390
- return user && user.sub === userId ? true : false;
15391
- }, [user]);
15392
- const opened = !!userId;
15393
- const options = useMemo(() => ({
15394
- roles: buildOptions3(roles)
15395
- }), [roles]);
15396
- const reportsMetadata = userData && userData.app_metadata && userData.app_metadata.reports ? userData.app_metadata.reports : [];
15397
- const reportsMetadataIds = reportsMetadata.map((rm) => String(rm.reportId));
15398
- const fetchUserData = async () => {
15399
- setLoading(true);
15400
- setError(false);
15401
- const userRecord = await dispatch(actions_exports.readUser(userId)).then((response) => {
15402
- return response;
15403
- });
15404
- setUserData(userRecord);
15405
- mainForm.setValues(userRecord);
15406
- const reportList = userRecord && userRecord.app_metadata && userRecord.app_metadata.reports ? userRecord.app_metadata.reports : [];
15407
- setEditAll(reportList.length === 0);
15408
- setLoading(false);
15409
- };
15410
- useEffect(() => {
15411
- if (userId) {
15412
- fetchUserData();
15413
- } else {
15414
- setUserData(null);
15415
- }
15416
- }, [userId]);
15417
- const onSave = async () => {
15418
- setLoading(true);
15419
- if (userData) {
15420
- await dispatch(actions_exports.updateUser({ user: {
15421
- user_id: userData.user_id,
15422
- roles: userData.roles,
15423
- app_metadata: userData.app_metadata
15424
- } })).then((response) => {
15425
- if (isYou) {
15426
- console.log("its YOU! Refreshing page to grab new change on session");
15427
- Router.reload();
15428
- } else {
15429
- setLoading(false);
15430
- onEditEnd();
15431
- }
15432
- });
15433
- }
15434
- };
15435
- const onRolesChanges = (newRolesIds) => {
15436
- const hydratedRoles = newRolesIds.map((nr) => roles.find((r) => r.id === nr)).filter((r) => r);
15437
- const hasEditor = hydratedRoles.find((hr) => hr.name === CMS_ROLES.EDITOR);
15438
- const hasAdmin = hydratedRoles.find((hr) => hr.name === CMS_ROLES.ADMIN);
15439
- let metadata = userData ? userData.app_metadata : {};
15440
- if (!hasEditor) {
15441
- metadata = {
15442
- ...metadata,
15443
- reports: []
15444
- };
15445
- setEditAll(true);
15446
- }
15447
- if (isYou && !hasAdmin) {
15448
- setMultiselectError("You can't remove Admin role from yourself.");
15449
- } else {
15450
- setMultiselectError("");
15451
- setUserData({
15452
- ...userData,
15453
- roles: hydratedRoles,
15454
- app_metadata: metadata
15455
- });
15456
- }
15457
- };
15458
- const onChangeReport = (value) => {
15459
- setSelectedReportId(value);
15460
- };
15461
- const addReportType = () => {
15462
- if (userData && selectedReportId) {
15463
- const reports = userData.app_metadata && userData.app_metadata.reports ? userData.app_metadata.reports : [];
15464
- reports.push({ reportId: parseInt(selectedReportId, 10), favorites: [] });
15465
- setUserData({
15466
- ...userData,
15467
- app_metadata: {
15468
- ...userData.app_metadata,
15469
- reports
15470
- }
15471
- });
15472
- setSelectedReportId("");
15473
- }
15474
- };
15475
- const removeReportType = (reportId) => {
15476
- if (userData && reportId) {
15477
- const reports = userData.app_metadata && userData.app_metadata.reports ? userData.app_metadata.reports : [];
15478
- setUserData({
15479
- ...userData,
15480
- app_metadata: {
15481
- ...userData.app_metadata,
15482
- reports: reports.filter((r) => parseInt(`${r.reportId}`, 10) !== parseInt(reportId, 10))
15483
- }
15484
- });
15485
- }
15486
- };
15487
- const editAllSwitched = (event) => {
15488
- setEditAll(event.currentTarget.checked);
15489
- if (userData) {
15490
- setUserData({
15491
- ...userData,
15492
- app_metadata: {
15493
- ...userData.app_metadata,
15494
- reports: []
15495
- }
15496
- });
15497
- }
15498
- };
15499
- const onSelectFavorites = (reportId, favorites) => {
15500
- if (userData) {
15501
- const reports = userData.app_metadata && userData.app_metadata.reports ? [...userData.app_metadata.reports] : [];
15502
- const newReports = reports.map((report) => {
15503
- if (report.reportId === reportId) {
15504
- report.favorites = favorites;
15505
- }
15506
- return report;
15507
- });
15508
- setUserData({
15509
- ...userData,
15510
- app_metadata: {
15511
- ...userData.app_metadata,
15512
- reports: newReports
15513
- }
15514
- });
15515
- }
15516
- };
15517
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
15518
- Drawer,
15519
- {
15520
- opened,
15521
- onClose: () => onEditEnd(),
15522
- title: /* @__PURE__ */ jsxs(Fragment, { children: [
15523
- "Edit user ID ",
15524
- userId,
15525
- " ",
15526
- isYou ? /* @__PURE__ */ jsx(Badge, { children: "YOU" }) : ""
15527
- ] }),
15528
- padding: "lg",
15529
- closeOnClickOutside: false,
15530
- closeOnEscape: false,
15531
- position: "right",
15532
- size: "50%",
15533
- lockScroll: true,
15534
- withCloseButton: false,
15535
- children: /* @__PURE__ */ jsx(
15536
- DrawerContentWithScroll,
15537
- {
15538
- content: /* @__PURE__ */ jsxs(Fragment, { children: [
15539
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
15540
- error && /* @__PURE__ */ jsx(Alert, { title: "Member Form", color: "red", children: "Error, please try again." }),
15541
- user && !error && /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
15542
- /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15543
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Name", ...mainForm.getInputProps("name") }),
15544
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "email", ...mainForm.getInputProps("email") })
15545
- ] }),
15546
- /* @__PURE__ */ jsxs(Stack, { children: [
15547
- /* @__PURE__ */ jsx(Title, { order: 2, children: "Roles:" }),
15548
- /* @__PURE__ */ jsx(
15549
- MultiSelect,
15550
- {
15551
- data: options.roles,
15552
- onChange: onRolesChanges,
15553
- value: userData?.roles.map((r) => r.id),
15554
- error: multiselectError
15555
- }
15556
- )
15557
- ] }),
15558
- userData && userData.roles.map((r) => r.name).includes(CMS_ROLES.EDITOR) && /* @__PURE__ */ jsxs(Stack, { children: [
15559
- /* @__PURE__ */ jsx(Title, { order: 4, children: "Editor settings:" }),
15560
- /* @__PURE__ */ jsxs(Group, { children: [
15561
- /* @__PURE__ */ jsx(Text, { children: "Edit selected reports only" }),
15562
- /* @__PURE__ */ jsx(
15563
- Switch,
15564
- {
15565
- label: "",
15566
- checked: editAll,
15567
- onChange: editAllSwitched
15568
- }
15569
- ),
15570
- /* @__PURE__ */ jsx(Text, { children: "Edit all reports" })
15571
- ] }),
15572
- !editAll && /* @__PURE__ */ jsxs(Fragment, { children: [
15573
- /* @__PURE__ */ jsxs(Group, { grow: true, children: [
15574
- /* @__PURE__ */ jsx(
15575
- ReportSelect,
15576
- {
15577
- selectedReportId,
15578
- onChangeReport,
15579
- exclude: reportsMetadataIds
15580
- }
15581
- ),
15582
- /* @__PURE__ */ jsx(
15583
- Button,
15584
- {
15585
- variant: "outline",
15586
- disabled: loading || !selectedReportId && selectedReportId === "",
15587
- onClick: addReportType,
15588
- children: "Add Report"
15589
- }
15590
- )
15591
- ] }),
15592
- reportsMetadata.map((rm) => /* @__PURE__ */ jsx(Stack, { children: /* @__PURE__ */ jsx(
15593
- FavoriteMemberSelector,
15594
- {
15595
- reportId: rm.reportId,
15596
- initialFavorites: rm.favorites,
15597
- onSelectFavorites,
15598
- onClickDelete: removeReportType
15599
- }
15600
- ) }, rm.reportId))
15601
- ] })
15602
- ] })
15603
- ] })
15604
- ] }),
15605
- buttons: /* @__PURE__ */ jsxs(Fragment, { children: [
15606
- /* @__PURE__ */ jsx(
15607
- Button,
15608
- {
15609
- variant: "outline",
15610
- disabled: loading,
15611
- onClick: () => onEditEnd(),
15612
- children: "Cancel"
15613
- }
15614
- ),
15615
- /* @__PURE__ */ jsx(
15616
- Button,
15617
- {
15618
- onClick: onSave,
15619
- loading,
15620
- disabled: loading,
15621
- children: "Save User"
15622
- }
15623
- )
15624
- ] }),
15625
- size: 165
15626
- }
15627
- )
15628
- }
15629
- ) });
15630
- }
15631
-
15632
- // components/users/UsersTable.tsx
15633
- init_esm_shims();
15634
- init_store2();
15635
- function UsersTable({ response, onClickEdit, onSort, onPageChange }) {
15636
- const [sortStatus, setSortStatus] = useState();
15637
- const [records, setRecords] = useState([]);
15638
- const [paginationStatus, setPaginationStatus] = useState({
15639
- start: 0,
15640
- limit: 1,
15641
- total: 0,
15642
- page: 0
15643
- });
15644
- useEffect(() => {
15645
- if (sortStatus) {
15646
- onSort(sortStatus);
15647
- }
15648
- }, [sortStatus]);
15649
- useEffect(() => {
15650
- if (response) {
15651
- setRecords(response.users);
15652
- setPaginationStatus({
15653
- start: response.start,
15654
- limit: response.limit,
15655
- total: response.total,
15656
- page: response.start / response.limit + 1
15657
- });
15658
- }
15659
- }, [response]);
15660
- useEffect(() => {
15661
- setRecords(response);
15662
- }, []);
15663
- useAppSelector((state) => state.status.localeDefault);
15664
- const cols = [
15665
- {
15666
- title: "",
15667
- accessor: "image",
15668
- width: 50,
15669
- render: (member) => /* @__PURE__ */ jsx(Avatar, { src: member.picture, alt: "it's me", radius: 20 })
15670
- },
15671
- {
15672
- title: "Name",
15673
- accessor: "name"
15674
- },
15675
- {
15676
- title: "Email",
15677
- accessor: "email"
15678
- },
15679
- /*{
15680
- title: `Keywords ${localeDefault.toUpperCase()}`,
15681
- accessor: "keywords",
15682
- render: ({contentByLocale}) => {
15683
- const defaultLocalized = contentByLocale.find((item) => item.locale === localeDefault);
15684
- const othersLocalized = contentByLocale.filter((item) => item.locale !== localeDefault);
15685
- const keywords = (defaultLocalized.keywords ? defaultLocalized.keywords : [])
15686
- .map((k) => <Badge key={k}>{k}</Badge>);
15687
- const keywordsTooltipContent = othersLocalized.reduce((acc, item) => {
15688
- const otherKeywords = item.keywords || [];
15689
- const extraKeywords = `${item.locale.toUpperCase()}: ${otherKeywords.length > 0
15690
- ? otherKeywords.join(",")
15691
- : "None"
15692
- }`;
15693
- const newLine = acc !== "" ? "\n" : "";
15694
- return `${acc}${newLine}${extraKeywords}`;
15695
- }, "");
15696
- return (
15697
- <Group>
15698
- <span>{keywords.length > 0 ? keywords : <Badge color="gray">None</Badge>}</span>
15699
- {othersLocalized.length > 0 && (
15700
- <Tooltip label={keywordsTooltipContent}>
15701
- <Avatar size="sm" color="pink" radius="xl">
15702
- +
15703
- {othersLocalized.length}
15704
- </Avatar>
15705
- </Tooltip>
15706
- )}
15707
- </Group>
15708
- );
15709
- },
15710
- },*/
15711
- {
15712
- title: "",
15713
- accessor: "actions",
15714
- render: (member) => /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(member), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit")
15715
- }
15716
- ];
15717
- return /* @__PURE__ */ jsx(
15718
- DataTable,
15719
- {
15720
- striped: true,
15721
- minHeight: 150,
15722
- records,
15723
- columns: cols,
15724
- sortStatus,
15725
- onSortStatusChange: (s) => setSortStatus(s),
15726
- idAccessor: "email",
15727
- withBorder: true,
15728
- totalRecords: paginationStatus.total,
15729
- recordsPerPage: paginationStatus.limit,
15730
- page: paginationStatus.page,
15731
- onPageChange
15732
- }
15733
- );
15734
- }
15735
- function UsersEditor() {
15736
- const [editingId, setEditingId] = useState(null);
15737
- const [results, setResults] = useState([]);
15738
- const [roles, setRoles] = useState([]);
15739
- const [loading, setLoading] = useState(true);
15740
- const [internalFilters, setInternalFilters] = useState({ query: "" });
15741
- const [internalSort, setInternalSort] = useState();
15742
- const dispatch = useAppDispatch();
15743
- const onChangeFilters = (filters) => {
15744
- setInternalFilters(filters);
15745
- };
15746
- const onChangeSort = (sort) => {
15747
- setInternalSort(sort);
15748
- };
15749
- const onPageChange = (page) => {
15750
- setInternalFilters({
15751
- ...internalFilters,
15752
- page
15753
- });
15754
- };
15755
- const setEditUser = (user) => {
15756
- setEditingId(user.user_id);
15757
- };
15758
- const onEditClose = () => {
15759
- setEditingId(null);
15760
- doSearch();
15761
- };
15762
- const doSearch = async () => {
15763
- setLoading(true);
15764
- const params = {
15765
- query: internalFilters.query
15766
- };
15767
- if (internalFilters.role_id && internalFilters.role_id !== "all") {
15768
- params.role_id = internalFilters.role_id;
15769
- }
15770
- params.page = internalFilters.page ? internalFilters.page - 1 : 0;
15771
- dispatch(actions_exports.searchUser(params)).then((response) => {
15772
- setResults(response);
15773
- setLoading(false);
15774
- });
15775
- };
15776
- useEffect(() => {
15777
- setLoading(true);
15778
- dispatch(actions_exports.searchRole()).then((response) => {
15779
- setRoles(response.roles);
15780
- setLoading(false);
15781
- });
15782
- }, [dispatch]);
15783
- useEffect(() => {
15784
- doSearch();
15785
- }, [internalFilters, internalSort]);
15786
- return /* @__PURE__ */ jsxs(Container, { fluid: true, children: [
15787
- /* @__PURE__ */ jsxs(Grid, { children: [
15788
- /* @__PURE__ */ jsxs(Grid.Col, { span: 2, children: [
15789
- /* @__PURE__ */ jsx(Text, { ml: "xl", my: "sm", weight: "bold", children: "Users Management" }),
15790
- /* @__PURE__ */ jsx(FilterSidebar3, { onChange: onChangeFilters, loading, roles })
15791
- ] }),
15792
- /* @__PURE__ */ jsxs(Grid.Col, { span: 10, style: { height: "100vh", position: "relative" }, children: [
15793
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
15794
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
15795
- /* @__PURE__ */ jsx(
15796
- UsersTable,
15797
- {
15798
- response: results,
15799
- onClickEdit: setEditUser,
15800
- onSort: onChangeSort,
15801
- onPageChange
15802
- }
15803
- )
15804
- ] })
15805
- ] }),
15806
- editingId && /* @__PURE__ */ jsx(UserForm, { userId: editingId, onEditEnd: onEditClose, roles })
15807
- ] });
15808
- }
15809
-
15810
- // views/BespokeManager.tsx
15811
- init_ErrorBoundary();
15812
- init_envvars();
15813
- init_statusSlice();
15814
- init_store2();
15815
- function BespokeManager(options) {
15816
- const {
15817
- title = "Bespoke CMS",
15818
- pathSegment = "bespoke",
15819
- locale = localeDefault4,
15820
- profilePrefix = "/profilePathManager"
15821
- } = options;
15822
- const notifications5 = {
15823
- position: "bottom-center",
15824
- ...options.notifications
15825
- };
15826
- return withPageRoleAuthRequired({
15827
- allowedRoles: [CMS_ROLES.ADMIN, CMS_ROLES.EDITOR, CMS_ROLES.WRITER],
15828
- SuccessComponent: BespokeManagerPage,
15829
- FailureComponent: UnauthorizeView
15830
- });
14884
+ return BespokeManagerPage;
15831
14885
  function BespokeManagerPage() {
15832
14886
  return /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment, profilePrefix, children: [
15833
14887
  /* @__PURE__ */ jsx(Head, { children: /* @__PURE__ */ jsx("title", { children: title }) }),
@@ -15838,43 +14892,28 @@ function BespokeManager(options) {
15838
14892
  ] });
15839
14893
  }
15840
14894
  }
15841
- var links = [
15842
- {
15843
- icon: /* @__PURE__ */ jsx(IconBallpen, { size: 24 }),
15844
- color: "blue",
15845
- label: "Reports Builder",
15846
- href: "reports",
15847
- roleRequired: CMS_ROLES.EDITOR
15848
- },
15849
- {
15850
- icon: /* @__PURE__ */ jsx(IconDatabase, { size: 24 }),
15851
- color: "teal",
15852
- label: "Metadata Editor",
15853
- href: "metadata",
15854
- roleRequired: CMS_ROLES.EDITOR
15855
- },
15856
- {
15857
- icon: /* @__PURE__ */ jsx(IconMathFunction, { size: 24 }),
15858
- color: "violet",
15859
- label: "Formatters List",
15860
- href: "formatters",
15861
- roleRequired: CMS_ROLES.EDITOR
15862
- },
15863
- {
15864
- icon: /* @__PURE__ */ jsx(IconUsers, { size: 24 }),
15865
- color: "pink",
15866
- label: "Users Management",
15867
- href: "users",
15868
- roleRequired: CMS_ROLES.ADMIN
15869
- }
15870
- ];
14895
+ var links = [{
14896
+ icon: /* @__PURE__ */ jsx(IconBallpen, { size: 24 }),
14897
+ color: "blue",
14898
+ label: "Reports Builder",
14899
+ href: "reports"
14900
+ }, {
14901
+ icon: /* @__PURE__ */ jsx(IconDatabase, { size: 24 }),
14902
+ color: "teal",
14903
+ label: "Metadata Editor",
14904
+ href: "metadata"
14905
+ }, {
14906
+ icon: /* @__PURE__ */ jsx(IconMathFunction, { size: 24 }),
14907
+ color: "violet",
14908
+ label: "Formatters List",
14909
+ href: "formatters"
14910
+ }];
15871
14911
  function BespokeManagerShell(props) {
15872
14912
  const { locale } = props;
15873
14913
  const action = useRef(null);
15874
14914
  const [opened, { open, close }] = useDisclosure(false);
15875
- const { user, error, isLoading } = useUser();
15876
14915
  const location = useManagerLocation();
15877
- const buildLinks = useCallback((user2) => {
14916
+ const buildLinks = useCallback(() => {
15878
14917
  const menuLinks = [];
15879
14918
  links.forEach((link) => {
15880
14919
  menuLinks.push(
@@ -15882,7 +14921,7 @@ function BespokeManagerShell(props) {
15882
14921
  MainLink,
15883
14922
  {
15884
14923
  item: link,
15885
- disabled: !user2.bespoke_roles.includes(link.roleRequired)
14924
+ disabled: false
15886
14925
  },
15887
14926
  link.label
15888
14927
  )
@@ -15891,7 +14930,7 @@ function BespokeManagerShell(props) {
15891
14930
  return menuLinks;
15892
14931
  }, []);
15893
14932
  const navbar = useMemo(() => {
15894
- const linkButtons = buildLinks(user);
14933
+ const linkButtons = buildLinks();
15895
14934
  return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
15896
14935
  Box,
15897
14936
  {
@@ -15938,69 +14977,32 @@ function BespokeManagerShell(props) {
15938
14977
  withBorder: false,
15939
14978
  children: [
15940
14979
  /* @__PURE__ */ jsx(Navbar.Section, { style: { position: "relative" }, children: /* @__PURE__ */ jsx(BespokeLogo, { href: location.href(""), onlyIcon: !opened }) }),
15941
- /* @__PURE__ */ jsx(Navbar.Section, { grow: true, component: ScrollArea, children: /* @__PURE__ */ jsx(Stack, { spacing: 0, children: linkButtons }) }),
15942
- /* @__PURE__ */ jsx(Navbar.Section, { children: user && !error && !isLoading && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Stack, { px: 13, children: [
15943
- /* @__PURE__ */ jsxs(Group, { children: [
15944
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
15945
- Avatar,
15946
- {
15947
- src: user.picture,
15948
- radius: "xl",
15949
- size: "sm"
15950
- }
15951
- ) }),
15952
- opened && /* @__PURE__ */ jsxs(Box, { sx: { flex: 1 }, children: [
15953
- /* @__PURE__ */ jsx(Text, { size: "sm", weight: 500, children: user.name }),
15954
- /* @__PURE__ */ jsx(Text, { color: "dimmed", size: "xs", children: user.email })
15955
- ] })
15956
- ] }),
15957
- opened && /* @__PURE__ */ jsx(
15958
- Button,
15959
- {
15960
- px: 13,
15961
- component: "a",
15962
- href: "/api/auth/logout",
15963
- compact: true,
15964
- size: "xs",
15965
- variant: "outline",
15966
- leftIcon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
15967
- children: "Disconnect"
15968
- }
15969
- )
15970
- ] }) }) })
14980
+ /* @__PURE__ */ jsx(Navbar.Section, { grow: true, component: ScrollArea, children: /* @__PURE__ */ jsx(Stack, { spacing: 0, children: linkButtons }) })
15971
14981
  ]
15972
14982
  }
15973
14983
  )
15974
14984
  }
15975
14985
  ) });
15976
- }, [location, opened, user]);
14986
+ }, [location, opened]);
15977
14987
  const route = useMemo(() => {
15978
- const item = links.find((page) => page.href.includes(location.page));
15979
14988
  if (location.page === "welcome") {
15980
14989
  return /* @__PURE__ */ jsx(HelloView, {});
15981
14990
  }
15982
- if (user && Array.isArray(user.bespoke_roles) && user.bespoke_roles.includes(item?.roleRequired)) {
15983
- if (location.page === "metadata") {
15984
- return /* @__PURE__ */ jsx(MetadataEditor, {});
15985
- }
15986
- if (location.page === "formatters") {
15987
- return /* @__PURE__ */ jsx(FormatterEditor, {});
15988
- }
15989
- if (location.page === "reports") {
15990
- if (location.params.length > 0) {
15991
- const reportId = Number.parseInt(location.params[0]);
15992
- return /* @__PURE__ */ jsx(BuilderEditor, { id: reportId, locale });
15993
- }
15994
- return /* @__PURE__ */ jsx(ReportPicker, {});
15995
- }
15996
- if (location.page === "users") {
15997
- return /* @__PURE__ */ jsx(UsersEditor, {});
14991
+ if (location.page === "metadata") {
14992
+ return /* @__PURE__ */ jsx(MetadataEditor, {});
14993
+ }
14994
+ if (location.page === "formatters") {
14995
+ return /* @__PURE__ */ jsx(FormatterEditor, {});
14996
+ }
14997
+ if (location.page === "reports") {
14998
+ if (location.params.length > 0) {
14999
+ const reportId = Number.parseInt(location.params[0]);
15000
+ return /* @__PURE__ */ jsx(BuilderEditor, { id: reportId, locale });
15998
15001
  }
15999
- } else {
16000
- return /* @__PURE__ */ jsx(UnauthorizeView, {});
15002
+ return /* @__PURE__ */ jsx(ReportPicker, {});
16001
15003
  }
16002
15004
  return /* @__PURE__ */ jsx(NotFoundView, {});
16003
- }, [location, user]);
15005
+ }, [location]);
16004
15006
  const dispatch = useAppDispatch();
16005
15007
  useEffect(() => {
16006
15008
  dispatch(statusActions.setStatus({ isCMS: true }));
@@ -16071,4 +15073,4 @@ function BespokeRenderer({
16071
15073
  ] }) });
16072
15074
  }
16073
15075
 
16074
- export { Explore_default as BespokeExplore, ExploreModal_default as BespokeExploreModal, LoginButton_default as BespokeLoginBtn, BespokeManager, BespokeRenderer, Report_default as BespokeReport, Search_default as BespokeSearch, UserProvider_default as BespokeUserProvider, withPageRoleAuthRequired as BespokeWithPageRoleAuthRequired, CMS_ROLES, DialogProvider, actions_exports as actions, storeWrapper, useAppDispatch as useBespokeDispatch, useAppSelector as useBespokeSelector, useUser_default as useBespokeUser, useDialog };
15076
+ export { Explore_default as BespokeExplore, ExploreModal_default as BespokeExploreModal, BespokeManager, BespokeRenderer, Report_default as BespokeReport, Search_default as BespokeSearch, DialogProvider, actions_exports as actions, storeWrapper, useAppDispatch as useBespokeDispatch, useAppSelector as useBespokeSelector, useDialog };