@datawheel/bespoke 0.1.20 → 0.1.22

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 +487 -295
  2. package/dist/server.js +137 -42
  3. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -12,17 +12,17 @@ import toposort from 'toposort';
12
12
  import { schema, normalize } from 'normalizr';
13
13
  import { createSlice, configureStore } from '@reduxjs/toolkit';
14
14
  import { HYDRATE, createWrapper } from 'next-redux-wrapper';
15
- import { NotificationsProvider, showNotification } from '@mantine/notifications';
15
+ import { Notifications, notifications } from '@mantine/notifications';
16
16
  import React, { forwardRef, useMemo, useState, useCallback, useContext, useEffect, createContext, useRef, Fragment as Fragment$1, createElement } from 'react';
17
17
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
18
18
  import { useDispatch, useSelector } from 'react-redux';
19
- import { Stack, Text, Badge, Group, Tooltip, ActionIcon, Center, useMantineTheme, Modal, Button, Flex, Title, Select, SegmentedControl, MultiSelect, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container, TextInput, Loader, Alert, Autocomplete, Card, Space, Code, Textarea, Overlay, Grid, Input, Popover, Checkbox, Radio, Switch, Drawer, Tabs, Header, SimpleGrid, Image, FileInput, Accordion, CopyButton, Paper, NumberInput, Col } from '@mantine/core';
19
+ import { Stack, Text, Badge, Group, Tooltip, ActionIcon, Center, useMantineTheme, Modal, Button, Flex, Title, Select, SegmentedControl, MultiSelect, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container, TextInput, Loader, Alert, Autocomplete, Card, Space, Code, Textarea, Overlay, Grid, Input, Popover, Checkbox, Radio, Switch, Drawer, Tabs, Header, px, SimpleGrid, Image, Paper, FileInput, Accordion, CopyButton, NumberInput, Col, rem } from '@mantine/core';
20
20
  import { dataConcat } from 'd3plus-viz';
21
21
  import * as d3plus from 'd3plus-react';
22
- import { IconInfoCircle, IconBoxMargin, IconTable, IconMathFunction, IconUsers, IconLogout, IconSearch, IconTrash, IconUserCircle, IconDatabase, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconCirclePlus, IconCircleX, IconFlag, IconFileAnalytics, IconPlus, IconCamera, IconShare, IconCircleDashed, IconListSearch, IconRefreshAlert, IconSettings, IconMenu, IconRefresh, IconPolaroid, IconCircleMinus, IconEyeOff, IconAlignLeft, IconAlignCenter, IconAlignRight, IconLogin, IconWorld, IconLock, IconVariable, IconArrowRightCircle, IconExternalLink, IconDownload, IconTemplate, IconChartBar, IconCode, IconUpload, IconLink, IconClipboardCheck, IconClipboardCopy, IconPalette, IconEye, IconRss, IconGlobe } from '@tabler/icons';
23
- import { useDisclosure, useDebouncedValue, useMediaQuery, useHotkeys, getHotkeyHandler } from '@mantine/hooks';
24
- import Link from 'next/link';
25
22
  import Router, { useRouter } from 'next/router';
23
+ import { IconInfoCircle, IconBoxMargin, IconTable, IconMathFunction, IconUsers, IconLogout, IconSearch, IconTrash, IconUserCircle, IconEdit, IconDatabase, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconCirclePlus, IconCircleX, IconFlag, IconFileAnalytics, IconPlus, IconCamera, IconShare, IconCircleDashed, IconListSearch, IconExternalLink, IconSettings, IconFileOff, IconFilesOff, IconMenu, IconRefresh, IconPolaroid, IconCircleMinus, IconEyeOff, IconAlignLeft, IconAlignCenter, IconAlignRight, IconLogin, IconWorld, IconLock, IconVariable, IconArrowRightCircle, IconDownload, IconTemplate, IconChartBar, IconCode, IconUpload, IconLink, IconClipboardCheck, IconClipboardCopy, IconPalette, IconEye, IconMinimize, IconMaximize, IconRss, IconGlobe } from '@tabler/icons';
24
+ import { useDisclosure, useDebouncedValue, useMediaQuery, useHotkeys, useFullscreen, getHotkeyHandler } from '@mantine/hooks';
25
+ import Link from 'next/link';
26
26
  import dynamic from 'next/dynamic';
27
27
  import { UserProvider, withPageAuthRequired, useUser } from '@auth0/nextjs-auth0/client';
28
28
  import { Prism } from '@mantine/prism';
@@ -35,7 +35,7 @@ import { saveElement } from 'd3plus-export';
35
35
  import slugifyFn from 'slugify';
36
36
  import { FacebookShareButton, FacebookIcon, TwitterShareButton, TwitterIcon, TelegramShareButton, TelegramIcon, WhatsappShareButton, WhatsappIcon, LinkedinShareButton, LinkedinIcon, RedditShareButton, RedditIcon, EmailShareButton, EmailIcon } from 'react-share';
37
37
  import Head from 'next/head';
38
- import { DragDropContext, Droppable, Draggable } from 'react-beautiful-dnd';
38
+ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
39
39
  import Editor, { useMonaco } from '@monaco-editor/react';
40
40
  import { format } from 'pretty-format';
41
41
  import { Editor as Editor$1 } from '@tinymce/tinymce-react';
@@ -58,8 +58,8 @@ var init_esm_shims = __esm({
58
58
  });
59
59
 
60
60
  // api/http/lib.ts
61
- function http(axios7, config) {
62
- return axios7.request(config).then((response) => {
61
+ function http(axios6, config) {
62
+ return axios6.request(config).then((response) => {
63
63
  const { status, data } = response;
64
64
  return "error" in data ? { ok: false, status, error: data.error } : { ok: true, status, data: data.data };
65
65
  }, (err) => {
@@ -70,25 +70,25 @@ function http(axios7, config) {
70
70
  return { ok: false, status: 500, error: err.message };
71
71
  });
72
72
  }
73
- function httpGET(axios7, request, transformParams) {
73
+ function httpGET(axios6, request, transformParams) {
74
74
  const config = typeof request === "string" ? { url: request } : request;
75
- return (params) => http(axios7, {
75
+ return (params) => http(axios6, {
76
76
  ...config,
77
77
  method: "GET",
78
78
  params: transformParams ? transformParams(params) : params
79
79
  });
80
80
  }
81
- function httpPOST(axios7, request, transformPayload) {
81
+ function httpPOST(axios6, request, transformPayload) {
82
82
  const config = typeof request === "string" ? { url: request } : request;
83
- return (payload) => http(axios7, {
83
+ return (payload) => http(axios6, {
84
84
  ...config,
85
85
  method: "POST",
86
86
  data: transformPayload ? transformPayload(payload) : payload
87
87
  });
88
88
  }
89
- function httpDELETE(axios7, request, transformPayload) {
89
+ function httpDELETE(axios6, request, transformPayload) {
90
90
  const config = typeof request === "string" ? { url: request } : request;
91
- return (payload) => http(axios7, {
91
+ return (payload) => http(axios6, {
92
92
  ...config,
93
93
  method: "DELETE",
94
94
  data: transformPayload ? transformPayload(payload) : payload
@@ -101,8 +101,8 @@ var init_lib = __esm({
101
101
  });
102
102
 
103
103
  // api/http/image/imageSave.ts
104
- function httpImageSaveFactory(axios7, provider) {
105
- return (params) => http(axios7, {
104
+ function httpImageSaveFactory(axios6, provider) {
105
+ return (params) => http(axios6, {
106
106
  method: "GET",
107
107
  url: `search/images/${provider}`,
108
108
  params: { prompt: params.prompt, provider }
@@ -116,8 +116,8 @@ var init_imageSave = __esm({
116
116
  });
117
117
 
118
118
  // api/http/image/imageSearch.ts
119
- function httpImageSearchFactory(axios7, provider) {
120
- return (params) => http(axios7, {
119
+ function httpImageSearchFactory(axios6, provider) {
120
+ return (params) => http(axios6, {
121
121
  method: "GET",
122
122
  url: `search/images/${provider}`,
123
123
  params: { prompt: params.prompt, provider }
@@ -130,58 +130,59 @@ var init_imageSearch = __esm({
130
130
  }
131
131
  });
132
132
  function apiFactory(baseURL) {
133
- const axios7 = axios.create({ baseURL });
133
+ const axios6 = axios.create({ baseURL });
134
134
  return {
135
- createBlock: httpPOST(axios7, "create/block"),
136
- createDimension: httpPOST(axios7, "create/dimension"),
137
- createFormatter: httpPOST(axios7, "create/formatter"),
138
- createReport: httpPOST(axios7, "create/report"),
139
- createSection: httpPOST(axios7, "create/section"),
140
- createVariant: httpPOST(axios7, "create/variant"),
141
- deleteBlock: httpDELETE(axios7, "delete/block", transformDeletePayload),
142
- deleteDimension: httpDELETE(axios7, "delete/dimension", transformDeletePayload),
143
- deleteFormatter: httpDELETE(axios7, "delete/formatter", transformDeletePayload),
144
- deleteReport: httpDELETE(axios7, "delete/report", transformDeletePayload),
145
- deleteSection: httpDELETE(axios7, "delete/section", transformDeletePayload),
146
- deleteVariant: httpDELETE(axios7, "delete/variant", transformDeletePayload),
147
- readBlock: httpGET(axios7, "read/block"),
148
- readDimension: httpGET(axios7, "read/dimension"),
149
- readFormatter: httpGET(axios7, "read/formatter"),
150
- readReport: httpGET(axios7, "read/report"),
151
- readSection: httpGET(axios7, "read/section"),
152
- readVariant: httpGET(axios7, "read/variant"),
153
- updateBlock: httpPOST(axios7, "update/block"),
154
- updateDimension: httpPOST(axios7, "update/dimension"),
155
- updateFormatter: httpPOST(axios7, "update/formatter"),
156
- updateReport: httpPOST(axios7, "update/report"),
157
- updateSection: httpPOST(axios7, "update/section"),
158
- updateVariant: httpPOST(axios7, "update/variant"),
159
- searchReport: httpGET(axios7, "search/reports"),
160
- validateVariantSlug: httpGET(axios7, "validate/variant"),
161
- readMember: httpGET(axios7, "read/members", transformReadMembers),
162
- readMemberImage: httpGET(axios7, {
135
+ createBlock: httpPOST(axios6, "create/block"),
136
+ createDimension: httpPOST(axios6, "create/dimension"),
137
+ createFormatter: httpPOST(axios6, "create/formatter"),
138
+ createReport: httpPOST(axios6, "create/report"),
139
+ createSection: httpPOST(axios6, "create/section"),
140
+ createVariant: httpPOST(axios6, "create/variant"),
141
+ deleteBlock: httpDELETE(axios6, "delete/block", transformDeletePayload),
142
+ deleteDimension: httpDELETE(axios6, "delete/dimension", transformDeletePayload),
143
+ deleteFormatter: httpDELETE(axios6, "delete/formatter", transformDeletePayload),
144
+ deleteReport: httpDELETE(axios6, "delete/report", transformDeletePayload),
145
+ deleteSection: httpDELETE(axios6, "delete/section", transformDeletePayload),
146
+ deleteVariant: httpDELETE(axios6, "delete/variant", transformDeletePayload),
147
+ readBlock: httpGET(axios6, "read/block"),
148
+ readDimension: httpGET(axios6, "read/dimension"),
149
+ readFormatter: httpGET(axios6, "read/formatter"),
150
+ readReport: httpGET(axios6, "read/report"),
151
+ readSection: httpGET(axios6, "read/section"),
152
+ readVariant: httpGET(axios6, "read/variant"),
153
+ updateBlock: httpPOST(axios6, "update/block"),
154
+ updateDimension: httpPOST(axios6, "update/dimension"),
155
+ updateFormatter: httpPOST(axios6, "update/formatter"),
156
+ updateReport: httpPOST(axios6, "update/report"),
157
+ updateSection: httpPOST(axios6, "update/section"),
158
+ updateVariant: httpPOST(axios6, "update/variant"),
159
+ searchReport: httpGET(axios6, "search/reports"),
160
+ validateVariantSlug: httpGET(axios6, "validate/variant"),
161
+ readMember: httpGET(axios6, "read/members", transformReadMembers),
162
+ readMemberImage: httpGET(axios6, {
163
163
  url: "member/image.png",
164
164
  responseType: "blob"
165
165
  }),
166
- searchMember: httpGET(axios7, "search/members"),
167
- updateMember: httpGET(axios7, "update/members"),
168
- imageLocalSearch: httpImageSearchFactory(axios7, "local"),
169
- imageLocalSave: httpImageSaveFactory(axios7, "local"),
170
- imageFlickrSearch: httpImageSearchFactory(axios7, "flickr"),
171
- imageFlickrSave: httpImageSaveFactory(axios7, "flickr"),
172
- imageUnsplashSearch: httpImageSearchFactory(axios7, "unsplash"),
173
- imageUnsplashSave: httpImageSaveFactory(axios7, "unsplash"),
174
- imageUploadSave: httpImageSaveFactory(axios7, "upload"),
175
- readMetadata: httpGET(axios7, "read/metadata"),
176
- regenerateSearch: httpPOST(axios7, "search/regenerate"),
177
- urlProxy: httpGET(axios7, "url/proxy"),
178
- searchRole: httpGET(axios7, "auth/search/roles"),
179
- searchUser: httpGET(axios7, "auth/search/users"),
180
- readUser: httpGET(axios7, "auth/read/user"),
181
- updateUser: httpPOST(axios7, "auth/update/user"),
182
- addNewReportToCurrentUser: httpPOST(axios7, "auth/update/me"),
183
- revalidate: httpGET(axios7, "revalidate/report"),
184
- readPrivateBlocks: httpPOST(axios7, "read/blocks/private")
166
+ searchMember: httpGET(axios6, "search/members"),
167
+ updateMember: httpGET(axios6, "update/members"),
168
+ imageLocalSearch: httpImageSearchFactory(axios6, "local"),
169
+ imageLocalSave: httpImageSaveFactory(axios6, "local"),
170
+ imageFlickrSearch: httpImageSearchFactory(axios6, "flickr"),
171
+ imageFlickrSave: httpImageSaveFactory(axios6, "flickr"),
172
+ imageUnsplashSearch: httpImageSearchFactory(axios6, "unsplash"),
173
+ imageUnsplashSave: httpImageSaveFactory(axios6, "unsplash"),
174
+ imageUploadSave: httpImageSaveFactory(axios6, "upload"),
175
+ readMetadata: httpGET(axios6, "read/metadata"),
176
+ regenerateSearch: httpPOST(axios6, "search/regenerate"),
177
+ urlProxy: httpGET(axios6, "url/proxy"),
178
+ searchRole: httpGET(axios6, "auth/search/roles"),
179
+ searchUser: httpGET(axios6, "auth/search/users"),
180
+ readUser: httpGET(axios6, "auth/read/user"),
181
+ updateUser: httpPOST(axios6, "auth/update/user"),
182
+ addNewReportToCurrentUser: httpPOST(axios6, "auth/update/me"),
183
+ revalidateReport: httpGET(axios6, "revalidate/report"),
184
+ revalidateUrl: httpGET(axios6, "revalidate/url"),
185
+ readPrivateBlocks: httpPOST(axios6, "read/blocks/private")
185
186
  };
186
187
  }
187
188
  var transformDeletePayload, transformReadMembers;
@@ -1111,9 +1112,9 @@ var init_runConsumers = __esm({
1111
1112
  if (rootBlock.consumers.length && crawlDown) {
1112
1113
  rootBlock.consumers.forEach((cid) => {
1113
1114
  const rel = `${bid}-${cid}`;
1114
- if (!acc.includes(rel))
1115
+ if (!acc.includes(rel) && blocks[cid].section_id === blocks[bid].section_id)
1115
1116
  acc.push(rel);
1116
- rootBlock.consumers.forEach((cid2) => getDependencies(cid2, blocks, acc, crawlUp, crawlDown));
1117
+ rootBlock.consumers.filter((cid2) => blocks[cid2].section_id === blocks[bid].section_id).forEach((cid2) => getDependencies(cid2, blocks, acc, crawlUp, crawlDown));
1117
1118
  });
1118
1119
  }
1119
1120
  return acc;
@@ -1310,13 +1311,14 @@ var init_FUNC = __esm({
1310
1311
  "libs/FUNC.js"() {
1311
1312
  init_esm_shims();
1312
1313
  init_libs();
1313
- parse = (config, formatters = {}, locale = "en", actions = {}) => {
1314
+ parse = (config, formatters = {}, locale = "en", actions = {}, extraGlobals = {}) => {
1314
1315
  const globals = {
1315
1316
  setVariables: actions.onSetVariables ? actions.onSetVariables : (d) => d,
1316
1317
  openModal: actions.onOpenModal ? actions.onOpenModal : (d) => d,
1317
1318
  formatters,
1318
1319
  libs: libraries,
1319
- locale
1320
+ locale,
1321
+ ...extraGlobals
1320
1322
  };
1321
1323
  function parseFunction(obj) {
1322
1324
  return Function("globals", ...obj.vars, `with (globals) { ${obj.logic} }`).bind(globals, globals);
@@ -1848,7 +1850,7 @@ function rpcAnnounce(entity, key) {
1848
1850
  function rpcFailure(entity, key, code, message) {
1849
1851
  return (dispatch) => {
1850
1852
  if (typeof window === "object") {
1851
- showNotification({
1853
+ notifications.show({
1852
1854
  autoClose: 3e3,
1853
1855
  color: "red",
1854
1856
  id: key,
@@ -2035,6 +2037,8 @@ __export(actions_exports, {
2035
2037
  recalculateVariables: () => recalculateVariables,
2036
2038
  removeBlocksFromState: () => removeBlocksFromState,
2037
2039
  reportSearch: () => reportSearch,
2040
+ revalidateReport: () => revalidateReport,
2041
+ revalidateUrl: () => revalidateUrl,
2038
2042
  searchMember: () => searchMember,
2039
2043
  searchRegenerate: () => searchRegenerate,
2040
2044
  searchRole: () => searchRole,
@@ -2130,6 +2134,7 @@ function recalculateVariables(resource, params) {
2130
2134
  locale: currentLocale
2131
2135
  };
2132
2136
  const section = state.records.entities.section[sid];
2137
+ console.log(section?.blocks);
2133
2138
  const data = await runConsumersV2(
2134
2139
  blocks,
2135
2140
  section && [section],
@@ -2225,6 +2230,26 @@ function readPrivateBlocks(params) {
2225
2230
  return result.data;
2226
2231
  };
2227
2232
  }
2233
+ function revalidateUrl(params) {
2234
+ return async (_, __, api) => {
2235
+ const result = await api.revalidateUrl({ target: params.target });
2236
+ if ("error" in result) {
2237
+ throw new Error(result.error);
2238
+ }
2239
+ return result.data;
2240
+ };
2241
+ }
2242
+ function revalidateReport(params) {
2243
+ return async (_, __, api) => {
2244
+ const result = await api.revalidateReport(
2245
+ { reportId: params.reportId, profilePrefix: params.profilePrefix }
2246
+ );
2247
+ if ("error" in result) {
2248
+ throw new Error(result.error);
2249
+ }
2250
+ return result.data;
2251
+ };
2252
+ }
2228
2253
  var setStatus, setPreviews;
2229
2254
  var init_actions = __esm({
2230
2255
  "store/actions.ts"() {
@@ -2311,7 +2336,7 @@ function entityRefHookFactory(entity) {
2311
2336
  }, [key]);
2312
2337
  const value = useAppSelector(selector);
2313
2338
  useEffect(() => {
2314
- if (value.isUninitialized) {
2339
+ if (value.isUninitialized && id !== null) {
2315
2340
  dispatch(readEntity(entity, { id, include: true }));
2316
2341
  }
2317
2342
  return () => {
@@ -2381,6 +2406,7 @@ var init_hooks = __esm({
2381
2406
  return result;
2382
2407
  };
2383
2408
  useInputVariablesHash = (id) => {
2409
+ console.log("useInputVariablesHash", id);
2384
2410
  const block = useBlockRef(id).data;
2385
2411
  const variables = useAppSelector((state) => state.variables.variables);
2386
2412
  const attributes = useAppSelector((state) => state.variables.attributes);
@@ -2510,7 +2536,7 @@ var init_sanitizeBlockContent = __esm({
2510
2536
  sanitizeBlockContent_default = sanitizeBlockContent;
2511
2537
  }
2512
2538
  });
2513
- var localeDefault7, frontEndMessage, errorStub, d3plusPropify_default;
2539
+ var localeDefault7, frontEndMessage, errorStub, propify, d3plusPropify_default;
2514
2540
  var init_d3plusPropify = __esm({
2515
2541
  "libs/d3plusPropify.ts"() {
2516
2542
  init_esm_shims();
@@ -2525,10 +2551,10 @@ var init_d3plusPropify = __esm({
2525
2551
  <strong>${frontEndMessage}</strong>
2526
2552
  </p>`
2527
2553
  };
2528
- d3plusPropify_default = (logic, formatters, variables = {}, locale = localeDefault7, id = null, actions = {}) => {
2554
+ propify = (logic, formatters, variables = {}, locale = localeDefault7, id = null, actions = {}, globals = {}) => {
2529
2555
  let config;
2530
2556
  try {
2531
- config = parse({ vars: ["variables"], logic }, formatters, locale, actions)(variables);
2557
+ config = parse({ vars: ["variables"], logic }, formatters, locale, actions, globals)(variables);
2532
2558
  } catch (e) {
2533
2559
  console.error(`Parsing Error in propify (ID: ${id})`);
2534
2560
  console.error(`Error message: ${e.message}`);
@@ -2563,6 +2589,7 @@ var init_d3plusPropify = __esm({
2563
2589
  topojsonFormat
2564
2590
  };
2565
2591
  };
2592
+ d3plusPropify_default = propify;
2566
2593
  }
2567
2594
  });
2568
2595
 
@@ -2608,11 +2635,12 @@ function Viz(config) {
2608
2635
  const content = getBlockContent(block);
2609
2636
  const formatterFunctions = useFormatterFunctionsForLocale(locale);
2610
2637
  const blockContext = { variables };
2638
+ const router = useRouter();
2611
2639
  const vizProps = useMemo(() => {
2612
2640
  if (!content?.logic)
2613
2641
  return { error: "Add a Configuration" };
2614
2642
  const transpiledLogic = varSwapRecursive_default({ logic: content.logic }, formatterFunctions, blockContext).logic;
2615
- return d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, block.id, {});
2643
+ return d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, block.id, {}, { router });
2616
2644
  }, [block, active, variables]);
2617
2645
  const { type } = vizProps.config || {};
2618
2646
  const fallbackType = type && vizTypes[type] ? type : "Treemap";
@@ -2818,13 +2846,14 @@ function Viz2({
2818
2846
  const content = getBlockContent(block);
2819
2847
  const formatterFunctions = useFormatterFunctionsForLocale(locale);
2820
2848
  const blockContext = { variables };
2849
+ const router = useRouter();
2821
2850
  const vizProps = useMemo(() => {
2822
2851
  if (!active)
2823
2852
  return { error: "Activate to View" };
2824
2853
  if (!content?.logic)
2825
2854
  return { error: "Add a Configuration" };
2826
2855
  const transpiledLogic = varSwapRecursive_default({ logic: content.logic }, formatterFunctions, blockContext).logic;
2827
- return d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, block.id, {});
2856
+ return d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, block.id, {}, { router });
2828
2857
  }, [block, active, variables]);
2829
2858
  useMemo(() => {
2830
2859
  if (!active || !content?.logic)
@@ -3724,16 +3753,12 @@ function createOutline(elements, variables) {
3724
3753
  }
3725
3754
  return roots;
3726
3755
  }
3727
- function useContentOutline(min = 1, max = 6) {
3728
- if (!min)
3729
- min = 1;
3730
- if (!max)
3731
- max = 6;
3756
+ function useContentOutline(min = 1, max = 6, headings = []) {
3732
3757
  const state = useAppSelector((state2) => state2);
3733
3758
  const variables = useAppSelector((state2) => state2.variables.variables);
3734
3759
  const sectionList = useSectionList();
3735
3760
  const titleList = selectBlockList(state).filter((block) => {
3736
- return block.type === BLOCK_TYPES.TITLE;
3761
+ return block.type === BLOCK_TYPES.TITLE && headings.includes(block.id);
3737
3762
  });
3738
3763
  const titleBlocks = Object.fromEntries(titleList.map((block) => [block.id, block]));
3739
3764
  const titleVariables = Object.fromEntries(titleList.map((block) => [block.id, variables[block.id]]));
@@ -3757,30 +3782,30 @@ function useContentOutline(min = 1, max = 6) {
3757
3782
  return currentOrder >= min && currentOrder <= max;
3758
3783
  });
3759
3784
  }
3760
- }, [min, max, sectionList, titleBlocks]);
3785
+ }, [headings, sectionList, titleBlocks]);
3761
3786
  return useMemo(() => {
3762
3787
  if (titlesSorted && titlesSorted?.length > 0) {
3763
3788
  return createOutline(titlesSorted, titleVariables);
3764
3789
  }
3765
3790
  }, [titlesSorted, titleVariables]);
3766
3791
  }
3767
- function NavView({ settings }) {
3792
+ function NavView({ headings, settings }) {
3768
3793
  const { type, min, max } = settings;
3769
- const contentOutline = useContentOutline(parseInt(min, 10), parseInt(max, 10));
3794
+ const contentOutline = useContentOutline(parseInt(min, 10), parseInt(max, 10), headings);
3770
3795
  const renderMenu = (nodes) => {
3771
3796
  if (!nodes || !nodes?.length) {
3772
3797
  return null;
3773
3798
  }
3774
- return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxs(Fragment, { children: [
3799
+ return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
3775
3800
  /* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsx(
3776
3801
  Anchor,
3777
3802
  {
3778
3803
  href: `#bespoke-title-${node.id}`,
3779
- children: node.label
3804
+ dangerouslySetInnerHTML: { __html: node.label }
3780
3805
  }
3781
- ) }, node.id),
3806
+ ) }),
3782
3807
  /* @__PURE__ */ jsx(Box, { pl: "xs", children: renderMenu(node.children) })
3783
- ] })) });
3808
+ ] }, node.id)) });
3784
3809
  };
3785
3810
  return /* @__PURE__ */ jsx(Box, { component: "nav", children: /* @__PURE__ */ jsx(
3786
3811
  List,
@@ -3793,7 +3818,7 @@ function NavView({ settings }) {
3793
3818
  }),
3794
3819
  children: contentOutline?.map(
3795
3820
  (node) => /* @__PURE__ */ jsx(List.Item, { children: /* @__PURE__ */ jsxs(Menu, { trigger: "hover", openDelay: 100, closeDelay: 400, children: [
3796
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Anchor, { href: `#bespoke-title-${node.id}`, children: node.label }) }),
3821
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Anchor, { href: `#bespoke-title-${node.id}`, dangerouslySetInnerHTML: { __html: node.label } }) }),
3797
3822
  node?.children?.length ? /* @__PURE__ */ jsx(Menu.Dropdown, { children: renderMenu(node.children) }) : null
3798
3823
  ] }) }, node.id)
3799
3824
  )
@@ -4221,9 +4246,16 @@ function SelectorUI(props) {
4221
4246
  }
4222
4247
  var SelectorUI_default = SelectorUI;
4223
4248
 
4249
+ // components/blocks/types/simpleEditors/NavUI.tsx
4250
+ init_esm_shims();
4251
+ function NavUI() {
4252
+ return /* @__PURE__ */ jsx(Title, { order: 4, children: "Nav UI" });
4253
+ }
4254
+
4224
4255
  // components/blocks/types/simpleEditors/index.js
4225
4256
  var simpleEditors_default = {
4226
- [BLOCK_TYPES.SELECTOR]: SelectorUI_default
4257
+ [BLOCK_TYPES.SELECTOR]: SelectorUI_default,
4258
+ [BLOCK_TYPES.NAV]: NavUI
4227
4259
  };
4228
4260
 
4229
4261
  // components/blocks/types/renderers/index.tsx
@@ -4577,14 +4609,14 @@ function stringifyPreview(member) {
4577
4609
  const variant = "variant_slug" in member ? member.variant_slug : member.variant.slug;
4578
4610
  return `${variant}/${member.slug}`;
4579
4611
  }
4580
- function NavPreview({ settings }) {
4612
+ function NavPreview({ headings, settings }) {
4581
4613
  const { type, min, max } = settings;
4582
- const contentOutline = useContentOutline(parseInt(min, 10), parseInt(max, 10));
4614
+ const contentOutline = useContentOutline(parseInt(min, 10), parseInt(max, 10), headings);
4583
4615
  const renderMenu = (nodes) => {
4584
4616
  if (!nodes || !nodes?.length) {
4585
4617
  return null;
4586
4618
  }
4587
- return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxs(Fragment, { children: [
4619
+ return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
4588
4620
  /* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsxs(
4589
4621
  Anchor,
4590
4622
  {
@@ -4596,7 +4628,7 @@ function NavPreview({ settings }) {
4596
4628
  }
4597
4629
  ) }, node.id),
4598
4630
  /* @__PURE__ */ jsx(Box, { pl: "xs", children: renderMenu(node.children) })
4599
- ] })) });
4631
+ ] }, node.id)) });
4600
4632
  };
4601
4633
  return /* @__PURE__ */ jsxs(Box, { pos: "relative", children: [
4602
4634
  /* @__PURE__ */ jsx(Tooltip, { label: `
@@ -4729,7 +4761,7 @@ function Block({ blockId, active = true }) {
4729
4761
  locale
4730
4762
  };
4731
4763
  const [content, setContent] = useState(() => {
4732
- if (![BLOCK_TYPES.GENERATOR, BLOCK_TYPES.VIZ].includes(block?.type)) {
4764
+ if (![BLOCK_TYPES.GENERATOR, BLOCK_TYPES.VIZ, BLOCK_TYPES.NAV].includes(block?.type)) {
4733
4765
  if (block?.type === BLOCK_TYPES.SELECTOR) {
4734
4766
  const blockContent2 = getBlockContent(block, locale);
4735
4767
  const { config: renderVariables } = runSelector_default(blockContent2?.logic, formatterFunctions, blockContext);
@@ -4793,12 +4825,21 @@ function Block({ blockId, active = true }) {
4793
4825
  return;
4794
4826
  }
4795
4827
  if (block.type === BLOCK_TYPES.SELECTOR) {
4796
- const blockContent2 = getBlockContent(block);
4828
+ const blockContent2 = getBlockContent(block, locale);
4797
4829
  const { config: renderVariables } = runSelector_default(blockContent2.logic, formatterFunctions, blockContext);
4798
4830
  const content2 = renderVariables;
4799
4831
  setContent({ ...content2, id: block.id, section: block.section_id });
4800
4832
  return;
4801
4833
  }
4834
+ if (block.type === BLOCK_TYPES.NAV) {
4835
+ setContent({
4836
+ id: block.id,
4837
+ headings: block.inputs,
4838
+ section: block.section_id,
4839
+ settings: block.settings
4840
+ });
4841
+ return;
4842
+ }
4802
4843
  const swappedLogic = varSwap_default(blockContent?.logic, formatterFunctions, blockContext);
4803
4844
  const { vars } = mortarEval_default(
4804
4845
  "variables",
@@ -4814,9 +4855,9 @@ function Block({ blockId, active = true }) {
4814
4855
  fetch();
4815
4856
  }, [blockContent, variables]);
4816
4857
  if (!block || !content || !allowed)
4817
- return;
4858
+ return null;
4818
4859
  const Renderer = blocks_default[block.type];
4819
- return /* @__PURE__ */ jsx("div", { id: `bespoke-${block.type}-${block.id}`, className: `cms-block-wrapper cms-block-${blockId}`, children: /* @__PURE__ */ jsx(Renderer, { ...content, settings: block.settings }) });
4860
+ return /* @__PURE__ */ jsx("div", { id: `bespoke-${block.type}-${block.id}`, className: `cms-block-wrapper cms-block-${blockId}`, children: /* @__PURE__ */ jsx(Renderer, { ...content }) });
4820
4861
  }
4821
4862
 
4822
4863
  // libs/settings/section.tsx
@@ -5523,35 +5564,69 @@ function Options(props) {
5523
5564
  )
5524
5565
  ] });
5525
5566
  }
5526
- var OuterWrappers = {
5527
- "sticky": ({ children, ...props }) => /* @__PURE__ */ jsx(
5528
- Paper,
5529
- {
5530
- pos: "sticky",
5567
+
5568
+ // frontend/hooks/useBespokeStyles.ts
5569
+ init_esm_shims();
5570
+ function useBespokeStyles() {
5571
+ const theme = useMantineTheme();
5572
+ return theme.other.bespokeStyles || {};
5573
+ }
5574
+ var getStyles = (styles, settings) => (theme) => styles ? styles(theme, settings) : {};
5575
+ var PositionWrapper = ({ settings, styles, children, ...props }) => {
5576
+ const { position } = settings;
5577
+ const defaultStyles = {
5578
+ "normal": {
5579
+ position: "relative",
5580
+ backgroundColor: "transparent",
5581
+ borderRadius: 0
5582
+ },
5583
+ "sticky": {
5584
+ position: "sticky",
5585
+ zIndex: 3,
5531
5586
  top: 0,
5587
+ borderRadius: 0,
5588
+ borderTop: "none",
5589
+ borderLeft: "none",
5590
+ borderRight: "none"
5591
+ }
5592
+ };
5593
+ const defaultProps = {
5594
+ "normal": {
5595
+ radius: 0
5596
+ },
5597
+ "sticky": {
5532
5598
  radius: 0,
5533
- sx: { zIndex: 3, borderTop: "none", borderLeft: "none", borderRight: "none" },
5534
- ...props,
5535
- withBorder: true,
5536
- children
5599
+ withBorder: true
5537
5600
  }
5538
- ),
5539
- "normal": ({ children, ...props }) => /* @__PURE__ */ jsx(Box, { pos: "relative", ...props, children })
5540
- };
5541
- var WidthWrappers = {
5542
- "full": ({ children, ...props }) => /* @__PURE__ */ jsx(Container, { ...props, fluid: true, p: "md", children }),
5543
- "center": ({ children, ...props }) => /* @__PURE__ */ jsx(Container, { ...props, p: "md", children })
5601
+ };
5602
+ const sx = [defaultStyles[position], getStyles(styles, settings)];
5603
+ return /* @__PURE__ */ jsx(Paper, { component: "section", sx, ...defaultProps[position], ...props, children });
5544
5604
  };
5545
- var StyleWrappers = {
5546
- "none": ({ children, ...props }) => /* @__PURE__ */ jsx(Box, { ...props, children }),
5547
- "card": ({ children, ...props }) => /* @__PURE__ */ jsx(Paper, { ...props, shadow: "lg", p: "md", radius: "md", children })
5605
+ var WidthWrapper = ({ settings, styles, children, ...props }) => {
5606
+ const { width: container } = settings;
5607
+ const defaultStyles = {
5608
+ "center": {},
5609
+ "full": {}
5610
+ };
5611
+ const defaultProps = {
5612
+ "center": { size: "md", p: "sm", fluid: false },
5613
+ "full": { fluid: true, p: "md" }
5614
+ };
5615
+ const sx = [defaultStyles[container], getStyles(styles, settings)];
5616
+ return /* @__PURE__ */ jsx(Container, { sx, ...defaultProps[container], ...props, children });
5548
5617
  };
5549
- var getWrappers = (settings) => {
5550
- return {
5551
- Outer: OuterWrappers[settings.position],
5552
- Container: WidthWrappers[settings.width],
5553
- Wrapper: StyleWrappers[settings.style]
5554
- };
5618
+ var StyleWrapper = ({ settings, styles, children, ...props }) => {
5619
+ const { style: variant } = settings;
5620
+ const defaultStyles = {
5621
+ "none": {},
5622
+ "card": {}
5623
+ };
5624
+ const defaultProps = {
5625
+ "none": { bg: "transparent" },
5626
+ "card": { shadow: "lg", p: "md", radius: "md" }
5627
+ };
5628
+ const sx = [defaultStyles[variant], getStyles(styles, settings)];
5629
+ return /* @__PURE__ */ jsx(Paper, { sx, ...defaultProps[variant], ...props, children });
5555
5630
  };
5556
5631
  function Section({ section }) {
5557
5632
  const { id, settings } = section;
@@ -5560,6 +5635,7 @@ function Section({ section }) {
5560
5635
  ...settings
5561
5636
  };
5562
5637
  const state = useAppSelector((state2) => state2);
5638
+ const sectionStyles = useBespokeStyles()["Section"];
5563
5639
  const blockRecords = selectBlockRecords(state);
5564
5640
  const theme = useMantineTheme();
5565
5641
  const smallScreen = useMediaQuery(`(max-width: ${theme.breakpoints.sm}px)`);
@@ -5571,55 +5647,62 @@ function Section({ section }) {
5571
5647
  }
5572
5648
  return acc;
5573
5649
  }, {});
5574
- const Wrappers = getWrappers(sectionSettings2);
5575
- return /* @__PURE__ */ jsxs(Wrappers.Outer, { component: "section", children: [
5576
- sectionSettings2.memberImageBg && /* @__PURE__ */ jsx(SectionBackground, {}),
5577
- /* @__PURE__ */ jsx(
5578
- Wrappers.Container,
5579
- {
5580
- className: `cms-section-${id}`,
5581
- pos: "relative",
5582
- p: 0,
5583
- children: /* @__PURE__ */ jsx(Wrappers.Wrapper, { children: /* @__PURE__ */ jsxs(
5584
- Flex,
5650
+ return /* @__PURE__ */ jsxs(
5651
+ PositionWrapper,
5652
+ {
5653
+ settings: sectionSettings2,
5654
+ styles: sectionStyles?.root || void 0,
5655
+ children: [
5656
+ sectionSettings2.memberImageBg && /* @__PURE__ */ jsx(SectionBackground, {}),
5657
+ /* @__PURE__ */ jsx(
5658
+ WidthWrapper,
5585
5659
  {
5586
- className: "cms-section-content",
5587
- align: "stretch",
5588
- direction: smallScreen ? "column" : "row",
5660
+ settings: sectionSettings2,
5661
+ styles: sectionStyles?.container,
5662
+ className: `cms-section-${id}`,
5589
5663
  pos: "relative",
5590
- gap: "md",
5591
- children: [
5592
- sectionSettings2.optionsMenu && /* @__PURE__ */ jsx("div", { style: {
5593
- position: "absolute",
5594
- right: 10,
5595
- top: 10,
5596
- zIndex: 100
5597
- }, children: /* @__PURE__ */ jsx(Options, { sectionId: section.id }) }),
5598
- Object.keys(columns).sort((a, b) => orderSort(a, b, "blockcol")).map((columnIndex) => {
5599
- const column = columns[columnIndex];
5600
- const staticWidths = Object.values(column).map(({ id: id2 }) => parseFloat(blockRecords[id2]?.settings?.width)).filter((d) => !Number.isNaN(d));
5601
- return /* @__PURE__ */ jsx(
5602
- Stack,
5603
- {
5604
- className: "cms-section-col",
5605
- sx: {
5606
- flex: "1 1 100%",
5607
- maxWidth: staticWidths.length ? Math.max(...staticWidths) : "none"
5608
- },
5609
- children: Object.values(column).sort((a, b) => orderSort(a, b, "blockrow")).map((item) => {
5610
- if (item.id)
5611
- return /* @__PURE__ */ jsx(Block, { blockId: item.id }, item.id);
5612
- })
5613
- },
5614
- columnIndex
5615
- );
5616
- })
5617
- ]
5664
+ children: /* @__PURE__ */ jsx(StyleWrapper, { settings: sectionSettings2, styles: sectionStyles?.content, children: /* @__PURE__ */ jsxs(
5665
+ Flex,
5666
+ {
5667
+ className: "cms-section-content",
5668
+ align: "stretch",
5669
+ direction: smallScreen ? "column" : "row",
5670
+ pos: "relative",
5671
+ gap: "md",
5672
+ children: [
5673
+ sectionSettings2.optionsMenu && /* @__PURE__ */ jsx("div", { style: {
5674
+ position: "absolute",
5675
+ right: 10,
5676
+ top: 10,
5677
+ zIndex: 100
5678
+ }, children: /* @__PURE__ */ jsx(Options, { sectionId: section.id }) }),
5679
+ Object.keys(columns).sort((a, b) => orderSort(a, b, "blockcol")).map((columnIndex) => {
5680
+ const column = columns[columnIndex];
5681
+ const staticWidths = Object.values(column).map(({ id: id2 }) => parseFloat(blockRecords[id2]?.settings?.width || "none")).filter((d) => !Number.isNaN(d));
5682
+ return /* @__PURE__ */ jsx(
5683
+ Stack,
5684
+ {
5685
+ className: "cms-section-col",
5686
+ sx: {
5687
+ flex: "1 1 100%",
5688
+ maxWidth: staticWidths.length ? Math.max(...staticWidths) : "none"
5689
+ },
5690
+ children: Object.values(column).sort((a, b) => orderSort(a, b, "blockrow")).map((item) => {
5691
+ if (item.id)
5692
+ return /* @__PURE__ */ jsx(Block, { blockId: item.id }, item.id);
5693
+ })
5694
+ },
5695
+ columnIndex
5696
+ );
5697
+ })
5698
+ ]
5699
+ }
5700
+ ) })
5618
5701
  }
5619
- ) })
5620
- }
5621
- )
5622
- ] });
5702
+ )
5703
+ ]
5704
+ }
5705
+ );
5623
5706
  }
5624
5707
  var Section_default = Section;
5625
5708
  function Report() {
@@ -5630,30 +5713,68 @@ var Report_default = Report;
5630
5713
 
5631
5714
  // frontend/components/auth/LoginButton.tsx
5632
5715
  init_esm_shims();
5716
+
5717
+ // types/auth.ts
5718
+ init_esm_shims();
5719
+ var CMS_ROLES = {
5720
+ ADMIN: "Admin",
5721
+ EDITOR: "Editor",
5722
+ WRITER: "Writer"
5723
+ };
5633
5724
  function BespokeLoginBtn({
5634
- options = "",
5635
5725
  buttonProps = {},
5636
- menuProps = {}
5726
+ editorMenuItemProps = {},
5727
+ editorMenuItemRoute = "/cms",
5728
+ logoutButtonProps = {},
5729
+ menuProps = {},
5730
+ options = "",
5731
+ optionsPosition = "bottom",
5732
+ translations = {},
5733
+ withEditorMenuItem = true,
5734
+ withSession = true
5637
5735
  }) {
5638
5736
  const { user, error, isLoading } = useUser();
5737
+ const userRoles = useMemo(() => user?.bespoke_roles || [], [user]);
5738
+ const isCMSUser = useMemo(() => CMS_ROLES && Object.keys(CMS_ROLES).length > 0 && Object.keys(CMS_ROLES).some((role) => userRoles.includes(CMS_ROLES[role])), [userRoles]);
5639
5739
  const buttonConfig = {
5640
5740
  leftIcon: /* @__PURE__ */ jsx(IconUserCircle, {}),
5641
5741
  ...buttonProps
5642
5742
  };
5643
5743
  if (user && !error && !isLoading) {
5744
+ const editorMenuItemConfig = {
5745
+ ...editorMenuItemProps
5746
+ };
5747
+ const logoutButtonConfig = {
5748
+ color: "red",
5749
+ fullWidth: true,
5750
+ leftIcon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
5751
+ size: "xs",
5752
+ variant: "subtle",
5753
+ ...logoutButtonProps
5754
+ };
5644
5755
  const menuConfig = {
5645
5756
  shadow: "md",
5646
5757
  width: "auto",
5647
5758
  position: "bottom",
5648
5759
  ...menuProps
5649
5760
  };
5761
+ const cmsButton = /* @__PURE__ */ jsx(Link, { href: editorMenuItemRoute, passHref: true, children: /* @__PURE__ */ jsx(
5762
+ Menu.Item,
5763
+ {
5764
+ icon: /* @__PURE__ */ jsx(IconEdit, { size: 14 }),
5765
+ ...editorMenuItemConfig,
5766
+ children: translations["Go to editor"] || "Go to editor"
5767
+ }
5768
+ ) });
5650
5769
  return /* @__PURE__ */ jsxs(Menu, { ...menuConfig, children: [
5651
- /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Button, { ...buttonConfig, children: `Hi, ${user.name || user.email}!` }) }),
5770
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Button, { ...buttonConfig, children: `${translations["Welcome message"] || `Hi, ${user.name || user.email}`}` }) }),
5652
5771
  /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
5653
- options,
5654
- options && /* @__PURE__ */ jsx(Menu.Divider, {}),
5655
- /* @__PURE__ */ jsx(Menu.Label, { children: "Session" }),
5656
- /* @__PURE__ */ jsxs(
5772
+ optionsPosition === "top" && /* @__PURE__ */ jsxs(Fragment, { children: [
5773
+ withEditorMenuItem && isCMSUser && cmsButton,
5774
+ options,
5775
+ (options || withEditorMenuItem && isCMSUser) && /* @__PURE__ */ jsx(Menu.Divider, {})
5776
+ ] }),
5777
+ withSession && /* @__PURE__ */ jsxs(
5657
5778
  Menu.Item,
5658
5779
  {
5659
5780
  component: "span",
@@ -5666,14 +5787,19 @@ function BespokeLoginBtn({
5666
5787
  }
5667
5788
  ),
5668
5789
  /* @__PURE__ */ jsx(
5669
- Menu.Item,
5790
+ Button,
5670
5791
  {
5671
5792
  component: "a",
5672
5793
  href: "/api/auth/logout",
5673
- icon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
5674
- children: "Disconnect"
5794
+ ...logoutButtonConfig,
5795
+ children: translations["Disconnect"] || "Disconnect"
5675
5796
  }
5676
- )
5797
+ ),
5798
+ optionsPosition === "bottom" && /* @__PURE__ */ jsxs(Fragment, { children: [
5799
+ (options || withEditorMenuItem && isCMSUser) && /* @__PURE__ */ jsx(Menu.Divider, {}),
5800
+ withEditorMenuItem && isCMSUser && cmsButton,
5801
+ options
5802
+ ] })
5677
5803
  ] })
5678
5804
  ] });
5679
5805
  }
@@ -5684,7 +5810,7 @@ function BespokeLoginBtn({
5684
5810
  href: "/api/auth/login",
5685
5811
  loading: isLoading,
5686
5812
  ...buttonConfig,
5687
- children: isLoading ? "Signing in..." : "Sign in"
5813
+ children: isLoading ? translations["Signing in"] || "Signing in..." : translations["Sign in"] || "Sign in"
5688
5814
  }
5689
5815
  );
5690
5816
  }
@@ -5824,14 +5950,6 @@ function normalizeList(value) {
5824
5950
  return value.toString().split(",");
5825
5951
  }
5826
5952
 
5827
- // types/auth.ts
5828
- init_esm_shims();
5829
- var CMS_ROLES = {
5830
- ADMIN: "Admin",
5831
- EDITOR: "Editor",
5832
- WRITER: "Writer"
5833
- };
5834
-
5835
5953
  // api/endpoints/member.ts
5836
5954
  var { localeDefault: localeDefault8 } = getLocales_default();
5837
5955
  function parseReadMemberParams(query) {
@@ -7016,21 +7134,15 @@ function CMSHeader(props) {
7016
7134
  const { report: currentReport, profilePrefix } = props;
7017
7135
  const { id } = currentReport;
7018
7136
  const { newConfirmation } = useDialog();
7019
- const location = useManagerLocation();
7020
7137
  const dispatch = useAppDispatch();
7021
7138
  const resource = useContext(ResourceContext);
7022
7139
  const currentLocale = useAppSelector((state) => state.status.currentLocale);
7023
7140
  const localeDefault9 = useAppSelector((state) => state.status.localeDefault);
7024
7141
  const localeOptions = useAppSelector(selectLocaleOptions);
7025
- const reportList = useReportList();
7142
+ const previewsFromState = useAppSelector((state) => state.status.previews);
7026
7143
  const [opened, handlers] = useDisclosure(false);
7027
7144
  const { user } = useUser();
7028
7145
  const castedUser = user;
7029
- const reportOptions = useMemo(() => {
7030
- if (!reportList.isSuccess)
7031
- return [];
7032
- return reportList.data.map((d) => ({ value: `${d.id}`, label: d.name }));
7033
- }, [reportList.status]);
7034
7146
  const dimensions = useMemo(() => {
7035
7147
  return currentReport && currentReport.dimensions ? currentReport.dimensions : [];
7036
7148
  }, [currentReport]);
@@ -7039,9 +7151,14 @@ function CMSHeader(props) {
7039
7151
  }, [dimensions]);
7040
7152
  const [previewMembers, setPreviewMembers] = useState([]);
7041
7153
  const [initialFavorites, setInitialFavorites] = useState([]);
7042
- const onChangeReport = useCallback((value) => {
7043
- location.push(`/reports/${value}`);
7044
- }, [location]);
7154
+ const previewPath = previewsFromState.reduce((acc, member) => {
7155
+ return acc.concat([member.variant_slug, member.slug]);
7156
+ }, []);
7157
+ const previewName = previewsFromState.reduce((acc, member) => {
7158
+ return acc.concat([member.name]);
7159
+ }, []).join(" / ");
7160
+ const localePrefix = currentLocale === localeDefault9 ? "" : `/${currentLocale}`;
7161
+ const realPath = `${localePrefix}${profilePrefix}/${previewPath.join("/")}`;
7045
7162
  const onSelectPreview = (previewMember) => {
7046
7163
  const newPreviews = currentReport.dimensions.map((dId) => {
7047
7164
  let member;
@@ -7059,18 +7176,16 @@ function CMSHeader(props) {
7059
7176
  });
7060
7177
  setPreviewMembers(newPreviews);
7061
7178
  };
7062
- const maybeRevalidate = useCallback(async () => {
7179
+ const maybeRevalidateUrl = useCallback(async () => {
7063
7180
  try {
7064
7181
  await newConfirmation({
7065
7182
  title: "Are you sure?",
7066
- message: "Revalidate action will force to regenerate all the cached instances of this report type.",
7183
+ message: `Revalidate action will force to regenerate page: ${realPath}.`,
7067
7184
  confirmText: "Revalidate now!"
7068
7185
  });
7069
- const revalidateUrl = `/api/cms/revalidate/report?profilePrefix=${profilePrefix}&reportId=${id}`;
7070
- await axios.get(revalidateUrl).then((response) => {
7071
- const resp = response.data.data.data;
7072
- const message = `Revalidated ${resp.revalidated} pages of report ID ${resp.reportId}, like ${resp.samples.join(", ")}.`;
7073
- showNotification({
7186
+ await dispatch(actions_exports.revalidateUrl({ target: realPath })).then((response) => {
7187
+ const message = `Revalidated page ${response.target} you will see the changes in the following minutes.`;
7188
+ notifications.show({
7074
7189
  autoClose: false,
7075
7190
  color: "green",
7076
7191
  id: "revalidate-results",
@@ -7078,7 +7193,39 @@ function CMSHeader(props) {
7078
7193
  title: "Revalidate Results"
7079
7194
  });
7080
7195
  }).catch((error) => {
7081
- showNotification({
7196
+ notifications.show({
7197
+ autoClose: false,
7198
+ color: "red",
7199
+ id: "revalidate-error",
7200
+ message: error.message,
7201
+ title: "Revalidate Error"
7202
+ });
7203
+ });
7204
+ } catch {
7205
+ console.debug("Revalidate error.");
7206
+ }
7207
+ }, [realPath]);
7208
+ const maybeRevalidateReport = useCallback(async () => {
7209
+ try {
7210
+ await newConfirmation({
7211
+ title: "Are you sure?",
7212
+ message: `Revalidate action will force to regenerate all the cached instances of '${currentReport.name}' report type.`,
7213
+ confirmText: "Revalidate now!"
7214
+ });
7215
+ await dispatch(actions_exports.revalidateReport({
7216
+ profilePrefix,
7217
+ reportId: id
7218
+ })).then((response) => {
7219
+ const message = `Revalidated ${response.revalidated} pages of report ${currentReport.name}(ID ${response.reportId}), you will see the changes in the following minutes. Examples: ${response.samples.join(", ")}.`;
7220
+ notifications.show({
7221
+ autoClose: false,
7222
+ color: "green",
7223
+ id: "revalidate-results",
7224
+ message,
7225
+ title: "Revalidate Results"
7226
+ });
7227
+ }).catch((error) => {
7228
+ notifications.show({
7082
7229
  autoClose: false,
7083
7230
  color: "red",
7084
7231
  id: "revalidate-error",
@@ -7089,10 +7236,15 @@ function CMSHeader(props) {
7089
7236
  } catch {
7090
7237
  console.debug("Revalidate edition.");
7091
7238
  }
7092
- }, []);
7239
+ }, [id]);
7093
7240
  useEffect(() => {
7094
7241
  setPreviewMembers([]);
7095
7242
  }, [dimensions]);
7243
+ useEffect(() => {
7244
+ if (previewsFromState && previewsFromState.length > 0) {
7245
+ setInitialFavorites(previewsFromState.map((ps) => ({ variantId: ps.variant_id, contentId: ps.content_id })));
7246
+ }
7247
+ }, [previewsFromState]);
7096
7248
  useEffect(() => {
7097
7249
  if (previewMembers.length > 0) {
7098
7250
  dispatch(actions_exports.recalculateVariables(resource, {
@@ -7124,17 +7276,8 @@ function CMSHeader(props) {
7124
7276
  onChange: (value) => dispatch(statusActions.setStatus({ currentLocale: value || localeDefault9 }))
7125
7277
  }
7126
7278
  ),
7127
- /* @__PURE__ */ jsx(
7128
- Select,
7129
- {
7130
- style: { width: 100 },
7131
- size: "xs",
7132
- data: reportOptions,
7133
- value: String(id),
7134
- onChange: onChangeReport
7135
- }
7136
- ),
7137
- showPreviewSelector && dimensions.map((dId, ix) => /* @__PURE__ */ jsx(
7279
+ /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }),
7280
+ showPreviewSelector && dimensions.map((dId, ix) => /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx(
7138
7281
  DimensionAutocomplete,
7139
7282
  {
7140
7283
  id: dId,
@@ -7143,34 +7286,53 @@ function CMSHeader(props) {
7143
7286
  locale: currentLocale
7144
7287
  },
7145
7288
  dId
7146
- )),
7147
- !showPreviewSelector && /* @__PURE__ */ jsx(
7148
- Button,
7149
- {
7150
- size: "xs",
7151
- variant: "outline",
7152
- onClick: handlers.open,
7153
- children: "Import Data"
7154
- }
7155
- )
7156
- ] }),
7157
- right: /* @__PURE__ */ jsxs(Group, { children: [
7158
- /* @__PURE__ */ jsx(ActionIcon, { onClick: maybeRevalidate, color: "blue", variant: "filled", children: /* @__PURE__ */ jsx(IconRefreshAlert, { size: 20 }) }),
7159
- /* @__PURE__ */ jsxs(ActionIcon, { color: "blue", variant: "filled", children: [
7160
- /* @__PURE__ */ jsx(IconSettings, { onClick: handlers.open, size: 20 }),
7289
+ ) })),
7290
+ previewsFromState.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
7291
+ /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }),
7292
+ /* @__PURE__ */ jsx(ActionIcon, { component: "a", href: realPath, target: "_blank", variant: "subtle", title: "Open report in new tab", children: /* @__PURE__ */ jsx(IconExternalLink, { size: 20 }) })
7293
+ ] }),
7294
+ !showPreviewSelector && /* @__PURE__ */ jsxs(Fragment, { children: [
7295
+ /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }),
7161
7296
  /* @__PURE__ */ jsx(
7162
- Drawer,
7297
+ Button,
7163
7298
  {
7164
- opened,
7165
- onClose: handlers.close,
7166
- title: /* @__PURE__ */ jsx(IconTitle, { icon: /* @__PURE__ */ jsx(IconFileAnalytics, { size: 24 }), children: `Editing Report: ${currentReport ? currentReport.name : ""}` }),
7167
- size: "50%",
7168
- padding: "xl",
7169
- position: "right",
7170
- children: /* @__PURE__ */ jsx(ReportEditor, { id, onClose: handlers.close })
7299
+ size: "xs",
7300
+ variant: "outline",
7301
+ onClick: handlers.open,
7302
+ children: "Import Data"
7171
7303
  }
7172
7304
  )
7173
7305
  ] })
7306
+ ] }),
7307
+ right: /* @__PURE__ */ jsxs(Group, { spacing: "xs", children: [
7308
+ /* @__PURE__ */ jsxs(Menu, { shadow: "md", children: [
7309
+ /* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { color: "blue", variant: "filled", children: /* @__PURE__ */ jsx(IconSettings, { size: 20 }) }) }),
7310
+ /* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
7311
+ /* @__PURE__ */ jsx(Menu.Label, { children: "Revalidate" }),
7312
+ /* @__PURE__ */ jsx(Menu.Item, { onClick: maybeRevalidateUrl, icon: /* @__PURE__ */ jsx(IconFileOff, { size: 20 }), children: /* @__PURE__ */ jsxs(Text, { children: [
7313
+ "Revalidate ",
7314
+ /* @__PURE__ */ jsx(Text, { fw: 700, children: previewName })
7315
+ ] }) }),
7316
+ /* @__PURE__ */ jsx(Menu.Item, { onClick: maybeRevalidateReport, icon: /* @__PURE__ */ jsx(IconFilesOff, { size: 20 }), children: /* @__PURE__ */ jsxs(Text, { children: [
7317
+ "Revalidate ALL ",
7318
+ /* @__PURE__ */ jsx(Text, { fw: 700, children: currentReport.name })
7319
+ ] }) }),
7320
+ /* @__PURE__ */ jsx(Menu.Label, { children: "Settings" }),
7321
+ /* @__PURE__ */ jsx(Menu.Item, { onClick: handlers.open, icon: /* @__PURE__ */ jsx(IconSettings, { size: 20 }), children: "Report settings" })
7322
+ ] })
7323
+ ] }),
7324
+ /* @__PURE__ */ jsx(
7325
+ Drawer,
7326
+ {
7327
+ opened,
7328
+ onClose: handlers.close,
7329
+ title: /* @__PURE__ */ jsx(IconTitle, { icon: /* @__PURE__ */ jsx(IconFileAnalytics, { size: 24 }), children: `Editing Report: ${currentReport ? currentReport.name : ""}` }),
7330
+ size: "50%",
7331
+ padding: "xl",
7332
+ position: "right",
7333
+ children: /* @__PURE__ */ jsx(ReportEditor, { id, onClose: handlers.close })
7334
+ }
7335
+ )
7174
7336
  ] })
7175
7337
  }
7176
7338
  );
@@ -7492,13 +7654,13 @@ function MonacoWrapper({ monacoOptions, variables = {} }) {
7492
7654
  }
7493
7655
  }, [monaco]);
7494
7656
  return /* @__PURE__ */ jsx(
7495
- "div",
7657
+ Box,
7496
7658
  {
7497
7659
  className: "cr-monaco-container",
7660
+ w: "100%",
7498
7661
  children: /* @__PURE__ */ jsx(
7499
7662
  Editor,
7500
7663
  {
7501
- height: "50vh",
7502
7664
  defaultLanguage: "javascript",
7503
7665
  theme: "Monokai",
7504
7666
  ...monacoOptions
@@ -7527,6 +7689,7 @@ var emptyStatus = {
7527
7689
  };
7528
7690
  function BlockPreview(props) {
7529
7691
  const {
7692
+ id,
7530
7693
  active,
7531
7694
  allowed,
7532
7695
  blockStateContent,
@@ -7573,6 +7736,10 @@ function BlockPreview(props) {
7573
7736
  setStatus2(status2);
7574
7737
  return;
7575
7738
  }
7739
+ if (block.type === BLOCK_TYPES.NAV) {
7740
+ setContent({ headings: block.inputs, settings: block.settings });
7741
+ return;
7742
+ }
7576
7743
  const swappedLogic = varSwap_default(blockContent?.logic, formatterFunctions, blockContext);
7577
7744
  const { vars, error: error2, log: log2 } = mortarEval_default(
7578
7745
  "variables",
@@ -7609,10 +7776,10 @@ function BlockPreview(props) {
7609
7776
  {
7610
7777
  id: `${block.type}-${block.id}`,
7611
7778
  className: "cms-block-preview",
7612
- style: { width: "100%", minHeight: block.type === BLOCK_TYPES.VIZ && 300 },
7779
+ style: { width: "100%", minHeight: block.type === BLOCK_TYPES.VIZ ? 300 : "auto" },
7613
7780
  children: [
7614
7781
  !allowed && allowedOverlay,
7615
- Renderer ? /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Renderer, { debug, ...content, settings: block.settings }) }, "renderer") : /* @__PURE__ */ jsx(Center, { style: { minHeight: 100 }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: block.type }, "type") }),
7782
+ Renderer ? /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Renderer, { id: block.id, debug, ...content }) }, "renderer") : /* @__PURE__ */ jsx(Center, { style: { minHeight: 100 }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: block.type }, "type") }),
7616
7783
  debug && textLog && /* @__PURE__ */ jsx(
7617
7784
  Textarea,
7618
7785
  {
@@ -8069,7 +8236,7 @@ function VariableList({ id, setInlineId }) {
8069
8236
  disabled: !isGenerator,
8070
8237
  label: "Edit this Generator",
8071
8238
  style: { position: "absolute", right: 0, top: 0 },
8072
- transition: "pop",
8239
+ transitionProps: { transition: "pop" },
8073
8240
  withArrow: true,
8074
8241
  children: /* @__PURE__ */ jsx(ActionIcon, { size: "xs", onClick: () => setInlineId(vid), variant: "filled", children: /* @__PURE__ */ jsx(IconSettings, {}) })
8075
8242
  }
@@ -8099,6 +8266,7 @@ function BlockEditor({
8099
8266
  const status = useBlockStatus(id);
8100
8267
  const resp = status?.resp;
8101
8268
  const variables = useInputVariablesFlat(id);
8269
+ const { ref, toggle, fullscreen } = useFullscreen();
8102
8270
  const onChangeCode = (logic, locale2) => setBlockContent({ logic }, locale2);
8103
8271
  const onChangeAPI = (api) => setBlockContent({ api });
8104
8272
  const blockPreview = /* @__PURE__ */ jsx(
@@ -8118,7 +8286,9 @@ function BlockEditor({
8118
8286
  {
8119
8287
  monacoOptions: {
8120
8288
  onChange: (logic) => onChangeCode(logic, locale),
8121
- value: blockContent?.logic || ""
8289
+ value: blockContent?.logic || "",
8290
+ height: fullscreen ? "90vh" : "58vh",
8291
+ width: "100%"
8122
8292
  },
8123
8293
  variables
8124
8294
  },
@@ -8168,7 +8338,7 @@ function BlockEditor({
8168
8338
  maxHeight: 200,
8169
8339
  overflowY: "scroll"
8170
8340
  },
8171
- children: /* @__PURE__ */ jsx(InputMenuItem_default, { variables: resp })
8341
+ children: /* @__PURE__ */ jsx(InputMenuItem_default, { id, variables: resp })
8172
8342
  }
8173
8343
  )
8174
8344
  ] })
@@ -8196,35 +8366,52 @@ function BlockEditor({
8196
8366
  {
8197
8367
  value: tab,
8198
8368
  onTabChange: setTab,
8199
- styles: {
8200
- root: {
8201
- display: "flex",
8202
- flex: 1,
8203
- flexDirection: "column",
8204
- width: "100%",
8205
- body: {
8206
- display: "flex",
8207
- flex: "1 1 100%"
8208
- }
8209
- }
8210
- },
8211
- variant: "pills",
8212
8369
  children: [
8213
- /* @__PURE__ */ jsxs(Tabs.List, { position: "center", children: [
8214
- /* @__PURE__ */ jsx(Tabs.Tab, { value: "Content", icon: /* @__PURE__ */ jsx(IconEye, {}) }),
8215
- /* @__PURE__ */ jsx(Tabs.Tab, { value: "Settings", icon: /* @__PURE__ */ jsx(IconSettings, {}) })
8370
+ /* @__PURE__ */ jsxs(Tabs.List, { position: "left", children: [
8371
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "Content", icon: /* @__PURE__ */ jsx(IconEye, {}), children: "Edit" }),
8372
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "Settings", icon: /* @__PURE__ */ jsx(IconSettings, {}), children: "Settings" })
8216
8373
  ] }),
8217
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "Content", children: /* @__PURE__ */ jsxs(Grid, { className: "cr-block-output", style: { flex: 1, width: "100%" }, children: [
8218
- /* @__PURE__ */ jsxs(Col, { span: 9, className: `cr-block-output-editor ${currentMode}`, children: [
8219
- currentMode === "code" && /* @__PURE__ */ jsxs(Fragment, { children: [
8220
- codeEditor,
8221
- executeButton
8222
- ] }),
8223
- currentMode !== "code" && uiEditor
8224
- ] }, "content-col"),
8225
- /* @__PURE__ */ jsx(Col, { span: 3, style: { display: "flex", flexDirection: "column" }, children: blockPreview })
8226
- ] }) }),
8227
- /* @__PURE__ */ jsx(Tabs.Panel, { value: "Settings", children: /* @__PURE__ */ jsx(
8374
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "Content", pt: "xs", children: /* @__PURE__ */ jsx(Box, { ref, pos: "relative", bg: "white", children: /* @__PURE__ */ jsxs(
8375
+ Grid,
8376
+ {
8377
+ className: "cr-block-output",
8378
+ style: { flex: 1, width: "100%", height: fullscreen ? "100vh" : "auto", margin: 0 },
8379
+ children: [
8380
+ /* @__PURE__ */ jsxs(Col, { span: 9, bg: "#272822", className: `cr-block-output-editor ${currentMode}`, children: [
8381
+ currentMode === "code" && /* @__PURE__ */ jsxs(Fragment, { children: [
8382
+ /* @__PURE__ */ jsxs(Alert, { p: "xs", mb: "xs", icon: /* @__PURE__ */ jsx(IconInfoCircle, {}), color: "gray", children: [
8383
+ "You can access ",
8384
+ /* @__PURE__ */ jsx(Code, { children: "variables" }),
8385
+ ",",
8386
+ /* @__PURE__ */ jsx(Code, { children: "resp" }),
8387
+ ", and ",
8388
+ /* @__PURE__ */ jsx(Code, { children: "router" }),
8389
+ " in the scope of this generator."
8390
+ ] }),
8391
+ codeEditor,
8392
+ /* @__PURE__ */ jsx(Divider, { my: "sm", color: "gray.8" }),
8393
+ /* @__PURE__ */ jsxs(Group, { px: "xs", h: "fit-content", position: "right", children: [
8394
+ /* @__PURE__ */ jsx(
8395
+ Button,
8396
+ {
8397
+ variant: "light",
8398
+ color: "grey",
8399
+ onClick: toggle,
8400
+ leftIcon: fullscreen ? /* @__PURE__ */ jsx(IconMinimize, { size: rem(12) }) : /* @__PURE__ */ jsx(IconMaximize, { size: rem(12) }),
8401
+ compact: true,
8402
+ children: fullscreen ? "Minimize" : "Maximize"
8403
+ }
8404
+ ),
8405
+ executeButton
8406
+ ] })
8407
+ ] }),
8408
+ currentMode !== "code" && uiEditor
8409
+ ] }, "content-col"),
8410
+ /* @__PURE__ */ jsx(Col, { span: 3, style: { display: "flex", flexDirection: "column" }, children: blockPreview })
8411
+ ]
8412
+ }
8413
+ ) }) }),
8414
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "Settings", pt: "xs", children: /* @__PURE__ */ jsx(
8228
8415
  BlockSettings_default,
8229
8416
  {
8230
8417
  id,
@@ -8253,7 +8440,7 @@ function ConsumerMenu({ id }) {
8253
8440
  Menu,
8254
8441
  {
8255
8442
  position: "top",
8256
- transition: "pop",
8443
+ transitionProps: { transition: "pop" },
8257
8444
  trigger: "hover",
8258
8445
  zIndex: 1001,
8259
8446
  children: [
@@ -8386,9 +8573,10 @@ function Block2({
8386
8573
  const executeButton = /* @__PURE__ */ jsx(
8387
8574
  Button,
8388
8575
  {
8389
- style: { minHeight: 40 },
8390
8576
  disabled: !isValid,
8391
8577
  onClick: () => onSave(true),
8578
+ size: "sm",
8579
+ compact: true,
8392
8580
  children: "Save & Execute"
8393
8581
  }
8394
8582
  );
@@ -8529,7 +8717,7 @@ function BlockElement({
8529
8717
  onClose: maybeCloseWithoutSaving,
8530
8718
  overflow: "inside",
8531
8719
  padding: theme.spacing.sm,
8532
- size: "90%"
8720
+ size: "95%"
8533
8721
  };
8534
8722
  const hoverActions = {
8535
8723
  onMouseEnter: () => setHoverBlock(id),
@@ -8572,8 +8760,8 @@ function BlockElement({
8572
8760
  className: "cr-block-controls export-hidden",
8573
8761
  style: {
8574
8762
  position: "absolute",
8575
- right: theme.spacing.xs / 2,
8576
- top: theme.spacing.xs / 2,
8763
+ right: px(theme.spacing.xs) / 2,
8764
+ top: px(theme.spacing.xs) / 2,
8577
8765
  backgroundColor: theme.colors.gray[2],
8578
8766
  borderRadius: theme.radius.sm
8579
8767
  },
@@ -8884,7 +9072,7 @@ function SectionEditor({
8884
9072
  className: "cms-section-column",
8885
9073
  style: {
8886
9074
  flex: "1 1 100%",
8887
- maxWidth: staticWidths.length ? Math.max(...staticWidths) : "none",
9075
+ maxWidth: staticWidths.length ? Math.max(...staticWidths) : "100%",
8888
9076
  padding: site_default.column.padding
8889
9077
  },
8890
9078
  children: /* @__PURE__ */ jsx(Droppable, { droppableId: columnIndex, children: (provided, snapshot) => /* @__PURE__ */ jsxs(
@@ -8902,7 +9090,8 @@ function SectionEditor({
8902
9090
  flexWrap: Object.values(column).find(
8903
9091
  (item) => blocks[item.id]?.settings?.display === "inline"
8904
9092
  ) ? "wrap" : "nowrap",
8905
- height: "100%"
9093
+ height: "100%",
9094
+ maxWidth: "100%"
8906
9095
  },
8907
9096
  children: [
8908
9097
  Object.values(column).sort((a, b) => orderSort(a, b, "blockrow")).map((item, rowIndex) => {
@@ -9049,10 +9238,7 @@ function InteractiveReport(props) {
9049
9238
  const sectionMap = useAppSelector(selectSectionRecords);
9050
9239
  const currentLocale = useAppSelector((state) => state.status.currentLocale);
9051
9240
  const [activeSection, setActiveSection] = useState(null);
9052
- const [sectionOrder, setSectionOrder] = useState(report.sections);
9053
- useEffect(() => {
9054
- setSectionOrder(report.sections);
9055
- }, [report.sections]);
9241
+ const sectionOrder = useMemo(() => report.sections, [report.sections]);
9056
9242
  const maybeActivate = useCallback((sectionId) => {
9057
9243
  const onActivate = () => {
9058
9244
  setActiveSection(sectionId);
@@ -9071,6 +9257,7 @@ function InteractiveReport(props) {
9071
9257
  }
9072
9258
  }, [report.dimensions, previews]);
9073
9259
  const onDragEnd = useCallback((result) => {
9260
+ console.log("----onDragEnd", result);
9074
9261
  if (!result.destination || result.source.index === result.destination.index)
9075
9262
  return;
9076
9263
  const id = Number.parseInt(result.draggableId, 10);
@@ -9079,12 +9266,10 @@ function InteractiveReport(props) {
9079
9266
  const newOrder = sectionOrder.slice();
9080
9267
  const changed = newOrder.splice(result.source.index, 1);
9081
9268
  newOrder.splice(result.destination.index, 0, ...changed);
9082
- setSectionOrder(newOrder);
9083
9269
  dispatch(actions_exports.updateEntity("section", { id, ordering })).then(() => {
9084
9270
  dispatch(actions_exports.readEntity("report", { id: report.id, include: true }));
9085
9271
  });
9086
9272
  }, [sectionMap, sectionOrder]);
9087
- console.log(sectionOrder);
9088
9273
  const droppableChild = useCallback((droppableProvided) => /* @__PURE__ */ jsxs(
9089
9274
  "div",
9090
9275
  {
@@ -11377,7 +11562,7 @@ function BespokeManager(options) {
11377
11562
  locale = localeDefault4,
11378
11563
  profilePrefix
11379
11564
  } = options;
11380
- const notifications = {
11565
+ const notifications3 = {
11381
11566
  position: "bottom-center",
11382
11567
  ...options.notifications
11383
11568
  };
@@ -11389,7 +11574,10 @@ function BespokeManager(options) {
11389
11574
  function BespokeManagerPage() {
11390
11575
  return /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment, children: [
11391
11576
  /* @__PURE__ */ jsx(Head, { children: /* @__PURE__ */ jsx("title", { children: title }) }),
11392
- /* @__PURE__ */ jsx(MantineProvider, { inherit: false, children: /* @__PURE__ */ jsx(NotificationsProvider, { ...notifications, children: /* @__PURE__ */ jsx(DialogProvider, { children: /* @__PURE__ */ jsx(BespokeManagerShell, { locale, profilePrefix }) }) }) })
11577
+ /* @__PURE__ */ jsxs(MantineProvider, { inherit: false, children: [
11578
+ /* @__PURE__ */ jsx(Notifications, { ...notifications3 }),
11579
+ /* @__PURE__ */ jsx(DialogProvider, { children: /* @__PURE__ */ jsx(BespokeManagerShell, { locale, profilePrefix }) })
11580
+ ] })
11393
11581
  ] });
11394
11582
  }
11395
11583
  }
@@ -11568,14 +11756,18 @@ function MainLink({ item, disabled }) {
11568
11756
  // views/BespokeRenderer.tsx
11569
11757
  init_esm_shims();
11570
11758
  init_ResourceProvider();
11571
- function BespokeRenderer({ pathSegmentsKey = "bespoke", buildTime }) {
11759
+ function BespokeRenderer({
11760
+ pathSegmentsKey = "bespoke",
11761
+ bespokeStyles,
11762
+ buildTime
11763
+ }) {
11572
11764
  const loading = useInitialState(pathSegmentsKey);
11573
11765
  if (loading)
11574
11766
  return /* @__PURE__ */ jsx(LoadingOverlay, { visible: true });
11575
- return /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment: "bespoke", children: [
11767
+ return /* @__PURE__ */ jsx(MantineProvider, { theme: { other: { bespokeStyles } }, inherit: true, children: /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment: "bespoke", children: [
11576
11768
  /* @__PURE__ */ jsx(Report_default, {}),
11577
11769
  /* @__PURE__ */ jsx("small", { children: buildTime })
11578
- ] });
11770
+ ] }) });
11579
11771
  }
11580
11772
 
11581
11773
  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 };