@datawheel/bespoke 0.6.0-rc.9 → 0.7.0-rc.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 +817 -705
  2. package/dist/server.js +266 -312
  3. package/package.json +2 -4
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Group, Stack, Text, useMantineTheme, List, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, Tabs, TextInput, Code, Loader, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Container, Grid, Tooltip, createStyles, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, NumberInput, Autocomplete, Notification, Image, Accordion, Header, px, FileInput, SimpleGrid, Burger, Collapse, CopyButton, HoverCard, Breadcrumbs, Col } from '@mantine/core';
1
+ import { Group, Stack, Text, useMantineTheme, List, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, Tabs, TextInput, Code, NumberInput, Loader, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Container, Grid, Tooltip, createStyles, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, Autocomplete, Notification, Image, Accordion, Header, px, Pagination, FileInput, SimpleGrid, Burger, Collapse, CopyButton, HoverCard, Breadcrumbs, Col } from '@mantine/core';
2
2
  import React, { forwardRef, useState, useCallback, useRef, useEffect, createContext, useContext, useMemo, Fragment as Fragment$1, createElement, memo, useImperativeHandle } from 'react';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
  import axios from 'axios';
@@ -20,13 +20,12 @@ import { createSlice, configureStore } from '@reduxjs/toolkit';
20
20
  import { HYDRATE, createWrapper } from 'next-redux-wrapper';
21
21
  import { Notifications, notifications } from '@mantine/notifications';
22
22
  import { useDispatch, useSelector } from 'react-redux';
23
+ import { useDebouncedValue, useClickOutside, useDisclosure, useSetState, useUncontrolled, useHotkeys, useListState, randomId, getHotkeyHandler, useMediaQuery, useMergedRef, useFullscreen } from '@mantine/hooks';
23
24
  import Router, { useRouter } from 'next/router';
24
- import { useClickOutside, useDisclosure, useDebouncedValue, useSetState, useUncontrolled, useHotkeys, useListState, randomId, getHotkeyHandler, useMediaQuery, useMergedRef, useFullscreen } from '@mantine/hooks';
25
- import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconTable, IconUserCircle, IconEdit, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconDownload, IconCircleDashed, IconLanguage, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconListCheck, IconPolaroid, IconCircleMinus, IconInfoCircle, IconGripVertical, IconCamera, IconShare, IconQuestionMark, IconCirclePlus, IconLogin, IconWorld, IconLock, IconCopy, IconBinaryTree, IconVariable, IconArrowRightCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCheck, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconPalette, IconBold, IconItalic, IconUnderline, IconAlignCenter, IconAlignRight, IconAlignJustified, IconArrowBackUp, IconArrowForwardUp, IconLanguageOff, IconTriangleInvertedFilled, IconCode, IconDeviceFloppy, IconSettings, IconMinimize, IconMaximize, IconGlobe, IconLinkOff } from '@tabler/icons-react';
25
+ import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconTable, IconUserCircle, IconEdit, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconDownload, IconCircleDashed, IconLanguage, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconListCheck, IconPolaroid, IconCircleMinus, IconInfoCircle, IconGripVertical, IconCamera, IconShare, IconQuestionMark, IconCirclePlus, IconLogin, IconWorld, IconLock, IconCopy, IconBinaryTree, IconVariable, IconArrowRightCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCheck, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconCode, IconPalette, IconBold, IconItalic, IconUnderline, IconAlignCenter, IconAlignRight, IconAlignJustified, IconArrowBackUp, IconArrowForwardUp, IconLanguageOff, IconTriangleInvertedFilled, IconDeviceFloppy, IconSettings, IconMinimize, IconMaximize, IconGlobe, IconLinkOff } from '@tabler/icons-react';
26
26
  import Link from 'next/link';
27
27
  import parse2, { Element as Element$1, domToReact, Text as Text$1 } from 'html-react-parser';
28
28
  import { UserProvider, withPageAuthRequired, useUser } from '@auth0/nextjs-auth0/client';
29
- import { initFrameAndPoll, Framer } from '@newswire/frames';
30
29
  import { MantineReactTable } from 'mantine-react-table';
31
30
  import { dataConcat, dataLoad } from 'd3plus-viz';
32
31
  import * as d3plus from 'd3plus-react';
@@ -51,9 +50,9 @@ import { Prism } from '@mantine/prism';
51
50
  import slugifyFn from 'slugify';
52
51
  import JSZip from 'jszip';
53
52
  import { saveAs } from 'file-saver';
54
- import { FacebookShareButton, FacebookIcon, TwitterShareButton, TwitterIcon, TelegramShareButton, TelegramIcon, WhatsappShareButton, WhatsappIcon, LinkedinShareButton, LinkedinIcon, RedditShareButton, RedditIcon, EmailShareButton, EmailIcon } from 'react-share';
55
53
  import { select } from 'd3-selection';
56
- import { toPng } from 'html-to-image';
54
+ import { saveElement } from 'd3plus-export';
55
+ import { FacebookShareButton, FacebookIcon, TwitterShareButton, TwitterIcon, TelegramShareButton, TelegramIcon, WhatsappShareButton, WhatsappIcon, LinkedinShareButton, LinkedinIcon, RedditShareButton, RedditIcon, EmailShareButton, EmailIcon } from 'react-share';
57
56
  import Head from 'next/head';
58
57
  import Editor, { useMonaco } from '@monaco-editor/react';
59
58
  import { format } from 'pretty-format';
@@ -162,107 +161,6 @@ var init_Dialog = __esm({
162
161
  DialogContext = React.createContext(void 0);
163
162
  }
164
163
  });
165
- function ExploreFilters({ metadata, onFilter, initialReportId, initialVariantId, translations }) {
166
- const [showSelectors, setShowSelectors] = useState(false);
167
- const [selectors, setSelectors] = useState([]);
168
- const [filters, setFilters] = useState({ profile: void 0, variant: void 0 });
169
- const [selectedProfile, setSelectedProfile] = useState();
170
- const [selectedVariant, setSelectedVariant] = useState();
171
- const allMember = { id: void 0, name: translations["filters_all"] };
172
- const getVariantsCombinatory = (variantsArrays) => {
173
- const combinatory = variantsArrays.reduce((a2, b2) => a2.reduce((r2, v2) => r2.concat(b2.map((w2) => [].concat(v2, w2))), [])).map((combination) => {
174
- if (!Array.isArray(combination))
175
- return combination;
176
- return {
177
- id: combination.map((c2) => c2.id).join(","),
178
- name: combination.map((c2) => c2.name).join(" / ")
179
- };
180
- });
181
- return [allMember, ...combinatory];
182
- };
183
- const onClickProfile = (profile) => {
184
- if (profile !== selectedProfile) {
185
- setSelectedProfile(profile);
186
- setSelectedVariant(allMember);
187
- }
188
- };
189
- const onClickVariant = (variant) => {
190
- if (variant !== selectedVariant) {
191
- setSelectedVariant(variant);
192
- }
193
- };
194
- useEffect(() => {
195
- const newFilters = {};
196
- if (selectedProfile) {
197
- newFilters.profile = selectedProfile.id;
198
- }
199
- if (selectedVariant) {
200
- newFilters.variant = selectedVariant.id;
201
- }
202
- setFilters({ ...filters, ...newFilters });
203
- }, [selectedProfile, selectedVariant]);
204
- useEffect(() => {
205
- onFilter(filters);
206
- }, [filters]);
207
- useEffect(() => {
208
- if (metadata) {
209
- let worthShowSelectors = false;
210
- const selectorStructure = metadata.filter((profile) => profile.dimensions.length > 0).map((profile) => {
211
- const combinatory = getVariantsCombinatory(profile.dimensions.map((d2) => d2.variants));
212
- if (!worthShowSelectors && combinatory && combinatory.length > 2) {
213
- worthShowSelectors = true;
214
- }
215
- return {
216
- id: profile.id,
217
- name: profile.dimensions.map((d2) => d2.name).join(" / "),
218
- variants: combinatory
219
- };
220
- });
221
- setSelectors([allMember, ...selectorStructure]);
222
- setShowSelectors(worthShowSelectors ? true : selectorStructure.length > 1);
223
- if (initialReportId || initialVariantId) {
224
- if (initialReportId) {
225
- const initialReport = selectorStructure.find((ss) => ss.id === initialReportId);
226
- setSelectedProfile(initialReport);
227
- if (initialVariantId && initialReport) {
228
- setSelectedVariant(initialReport.variants.find((v2) => v2.id === initialVariantId));
229
- }
230
- }
231
- }
232
- }
233
- }, [metadata, initialReportId, initialVariantId]);
234
- return /* @__PURE__ */ jsxs(Fragment, { children: [
235
- showSelectors && /* @__PURE__ */ jsx(Group, { position: "center", className: "bespoke-explore-reports-selector", mb: "md", children: selectors.map((s2) => /* @__PURE__ */ jsx(
236
- Button,
237
- {
238
- "data-selected": s2.id === selectedProfile?.id ? "true" : "false",
239
- "data-report-name": s2.name,
240
- variant: s2.id === selectedProfile?.id ? "outline" : "subtle",
241
- onClick: () => onClickProfile(s2),
242
- children: translations?.dimension[s2.name] ?? s2.name
243
- },
244
- `p-${s2.id}`
245
- )) }),
246
- selectedProfile && selectedProfile.variants && selectedProfile.variants.length > 2 && /* @__PURE__ */ jsx(Group, { position: "center", style: { minHeight: "36px" }, className: "bespoke-explore-variant-selector", mb: "md", children: selectedProfile.variants.map((v2) => /* @__PURE__ */ jsx(
247
- Button,
248
- {
249
- "data-selected": v2.id === selectedVariant?.id ? "true" : "false",
250
- "data-variant-name": v2.name,
251
- variant: v2.id === selectedVariant?.id ? "outline" : "subtle",
252
- onClick: () => onClickVariant(v2),
253
- children: translations?.dimension[v2.name] ?? v2.name
254
- },
255
- `v-${v2.id}`
256
- )) })
257
- ] });
258
- }
259
- var ExploreFilters_default;
260
- var init_ExploreFilters = __esm({
261
- "frontend/components/explore/ExploreFilters.tsx"() {
262
- init_esm_shims();
263
- ExploreFilters_default = ExploreFilters;
264
- }
265
- });
266
164
 
267
165
  // api/http/lib.ts
268
166
  function http(axios10, config) {
@@ -2571,26 +2469,6 @@ var init_recordsSlice = __esm({
2571
2469
  }
2572
2470
  }
2573
2471
  };
2574
- },
2575
- normalizeSection: (state, action) => {
2576
- const sectionId = action.payload.section;
2577
- const section = state.entities.section[sectionId];
2578
- return {
2579
- ...state,
2580
- entities: {
2581
- ...state.entities,
2582
- section: {
2583
- // ...state.entities.section,
2584
- [sectionId]: {
2585
- ...section,
2586
- settings: {
2587
- ...section.settings,
2588
- width: "full"
2589
- }
2590
- }
2591
- }
2592
- }
2593
- };
2594
2472
  }
2595
2473
  },
2596
2474
  extraReducers: {
@@ -3522,7 +3400,6 @@ __export(actions_exports, {
3522
3400
  createEntity: () => createEntity,
3523
3401
  deleteEntity: () => deleteEntity,
3524
3402
  deleteQueryParam: () => deleteQueryParam,
3525
- normalizeSectionLayout: () => normalizeSectionLayout,
3526
3403
  readEntity: () => readEntity,
3527
3404
  readMember: () => readMember,
3528
3405
  readMetadata: () => readMetadata,
@@ -3719,12 +3596,6 @@ function removeBlocksFromState(privateBlockIds) {
3719
3596
  await dispatch(removeBlocks(privateBlockIds));
3720
3597
  };
3721
3598
  }
3722
- function normalizeSectionLayout(sectionId) {
3723
- const { normalizeSection } = recordsSlice.actions;
3724
- return async (dispatch) => {
3725
- await dispatch(normalizeSection(sectionId));
3726
- };
3727
- }
3728
3599
  function addBlockToState(newBlocks) {
3729
3600
  const { addBlocks } = recordsSlice.actions;
3730
3601
  return async (dispatch) => {
@@ -4095,7 +3966,7 @@ var init_store = __esm({
4095
3966
  storeWrapper = createWrapper(storeFactory);
4096
3967
  }
4097
3968
  });
4098
- function withFetcher(Component, useRef16) {
3969
+ function withFetcher(Component, useRef14) {
4099
3970
  const ComponentWithFetcher = (props) => {
4100
3971
  const {
4101
3972
  id,
@@ -4103,7 +3974,7 @@ function withFetcher(Component, useRef16) {
4103
3974
  skelWidth,
4104
3975
  ...otherProps
4105
3976
  } = props;
4106
- const ref = useRef16(id);
3977
+ const ref = useRef14(id);
4107
3978
  if (ref.isUninitialized || ref.isFetching) {
4108
3979
  return /* @__PURE__ */ jsx(Skeleton, { width: skelWidth, height: skelHeight });
4109
3980
  }
@@ -4131,6 +4002,314 @@ var init_store2 = __esm({
4131
4002
  init_withFetcher();
4132
4003
  }
4133
4004
  });
4005
+ function ExploreProvider({ children, explorePageSize }) {
4006
+ const pageSize = explorePageSize || 10;
4007
+ const defaultFilters = {
4008
+ // initial reportIds should go here to avoid multiple unnecesary requests
4009
+ profile: void 0,
4010
+ variant: void 0
4011
+ };
4012
+ const [metadata, setMetadata] = useState([]);
4013
+ const [loading, setLoading] = useState(false);
4014
+ const [resultCount, setResultCount] = useState({});
4015
+ const [totalCount, setTotalCount] = useState({});
4016
+ const [activePage, setActivePage] = useState(1);
4017
+ const [filters, setFilters] = useState(defaultFilters);
4018
+ const [query, setQuery] = useState("");
4019
+ const [debouncedQuery] = useDebouncedValue(query, 500);
4020
+ const [results, setResults] = useState([]);
4021
+ const [translations, setTranslations] = useState(DEFAULT_TRANSLATIONS);
4022
+ const [showSelectors, setShowSelectors] = useState(false);
4023
+ const [initialized, setInitialized] = useState(false);
4024
+ const dispatch = useAppDispatch();
4025
+ const { locale } = useRouter();
4026
+ const fetchMetadata = async () => {
4027
+ try {
4028
+ setLoading(true);
4029
+ dispatch(actions_exports.readMetadata({})).then((resp) => {
4030
+ const metadataCount = resp.data.reduce((acc, report) => {
4031
+ if (report.dimensions) {
4032
+ report.dimensions.forEach((dimension) => {
4033
+ if (dimension.variants) {
4034
+ dimension.variants.forEach((variant) => {
4035
+ acc[variant.id] = variant.members_count || 0;
4036
+ });
4037
+ }
4038
+ });
4039
+ }
4040
+ return acc;
4041
+ }, {});
4042
+ setMetadata(resp.data);
4043
+ setLoading(false);
4044
+ setResultCount(metadataCount);
4045
+ setTotalCount(metadataCount);
4046
+ setInitialized(true);
4047
+ }, (err) => {
4048
+ console.error(err);
4049
+ });
4050
+ } catch (error) {
4051
+ console.error("Error fetching metadata:", error);
4052
+ setMetadata([]);
4053
+ setLoading(false);
4054
+ setResultCount({});
4055
+ setTotalCount({});
4056
+ }
4057
+ };
4058
+ const setResultCountInternal = (totalPerVariant) => {
4059
+ if (totalPerVariant) {
4060
+ setResultCount(totalPerVariant);
4061
+ } else {
4062
+ setResultCount(totalCount);
4063
+ }
4064
+ };
4065
+ const initExplore = async (initialReportId, initialVariantId) => {
4066
+ if (!initialized && metadata.length === 0) {
4067
+ await fetchMetadata();
4068
+ }
4069
+ setFilters({
4070
+ profile: initialReportId,
4071
+ variant: initialVariantId
4072
+ });
4073
+ };
4074
+ useEffect(() => {
4075
+ let cancelled = false;
4076
+ if (initialized) {
4077
+ setLoading(true);
4078
+ setActivePage(1);
4079
+ doQuery(cancelled, 0);
4080
+ }
4081
+ return () => {
4082
+ cancelled = false;
4083
+ };
4084
+ }, [debouncedQuery, filters, initialized]);
4085
+ useEffect(() => {
4086
+ if (initialized) {
4087
+ const newOffset = (activePage - 1) * pageSize;
4088
+ doQuery(false, newOffset);
4089
+ }
4090
+ }, [activePage]);
4091
+ const doQuery = async (cancelled, newOffset) => {
4092
+ const filterProfile = filters.profile && !Number.isNaN(filters.profile) ? [filters.profile] : [];
4093
+ const filterVariant = filters.variant && !Number.isNaN(filters.variant) ? [filters.variant] : [];
4094
+ const params = {
4095
+ query: debouncedQuery,
4096
+ format: "profiles",
4097
+ locale,
4098
+ limit: pageSize,
4099
+ offset: newOffset,
4100
+ visible: true,
4101
+ includes: true,
4102
+ noImage: false,
4103
+ variant: filterVariant,
4104
+ dimension: [],
4105
+ report: filterProfile,
4106
+ all: false
4107
+ };
4108
+ dispatch(actions_exports.reportSearch(params)).then((resp) => {
4109
+ if (resp && resp.results && !cancelled) {
4110
+ const mergedResults = resp.results;
4111
+ setResults(mergedResults);
4112
+ setResultCount(query === "" ? false : resp.meta.variantCount);
4113
+ }
4114
+ setLoading(false);
4115
+ }).catch((e) => {
4116
+ console.error(e);
4117
+ setLoading(false);
4118
+ });
4119
+ };
4120
+ const counts = resultCount || totalCount;
4121
+ const allMember = { id: void 0, name: translations["filters_all"] || "ALL" };
4122
+ const getVariantsCombinatory = (variantsArrays) => {
4123
+ const combinatory = variantsArrays.reduce((a2, b2) => a2.reduce((r2, v2) => r2.concat(b2.map((w2) => [].concat(v2, w2))), [])).map((combination) => {
4124
+ let final;
4125
+ if (!Array.isArray(combination)) {
4126
+ combination.members_count = counts[combination.id] || 0;
4127
+ final = {
4128
+ ...combination,
4129
+ members_count: counts[combination.id] || 0
4130
+ };
4131
+ } else {
4132
+ final = {
4133
+ id: combination.map((c2) => c2.id).join(","),
4134
+ name: combination.map((c2) => c2.name).join(" / "),
4135
+ members_count: combination.reduce((t2, q2) => t2 * (counts[q2.id] || 1), 0)
4136
+ };
4137
+ }
4138
+ return final;
4139
+ });
4140
+ const allTotal = combinatory.reduce((t2, q2) => t2 + (q2.members_count || 0), 0);
4141
+ return [
4142
+ { ...allMember, members_count: allTotal },
4143
+ ...combinatory
4144
+ ];
4145
+ };
4146
+ const selectorStructure = useMemo(() => {
4147
+ let temp = [];
4148
+ if (!loading && metadata.length > 0 && counts) {
4149
+ let worthShowSelectors = false;
4150
+ const selectors = [...metadata].filter((profile) => profile.dimensions.length > 0).map((profile) => {
4151
+ const combinatory = getVariantsCombinatory(profile.dimensions.map((d2) => d2.variants));
4152
+ if (!worthShowSelectors && combinatory && combinatory.length > 2) {
4153
+ worthShowSelectors = true;
4154
+ }
4155
+ return {
4156
+ id: profile.id,
4157
+ name: profile.dimensions.map((d2) => d2.name).join(" / "),
4158
+ variants: combinatory,
4159
+ members_count: combinatory.filter((v2) => v2.id).reduce((t2, q2) => t2 + (q2.members_count || 0), 0)
4160
+ };
4161
+ });
4162
+ temp = [
4163
+ { ...allMember, members_count: selectors.reduce((t2, q2) => t2 + (q2.members_count || 0), 0) },
4164
+ ...selectors
4165
+ ];
4166
+ setShowSelectors(worthShowSelectors ? true : selectorStructure.length > 1);
4167
+ }
4168
+ return temp;
4169
+ }, [loading, counts, metadata]);
4170
+ const currentPageTotal = useMemo(() => {
4171
+ let selector;
4172
+ if (selectorStructure) {
4173
+ if (!filters.profile) {
4174
+ selector = selectorStructure.find((p2) => !p2.id);
4175
+ } else if (filters.profile) {
4176
+ selector = selectorStructure.find((p2) => p2.id === filters.profile);
4177
+ if (selector && filters.variant && selector.variants) {
4178
+ selector = selector.variants.find((p2) => p2.id === filters.variant);
4179
+ }
4180
+ }
4181
+ }
4182
+ return selector ? selector.members_count : pageSize;
4183
+ }, [filters, selectorStructure]);
4184
+ const state = {
4185
+ metadata,
4186
+ loading,
4187
+ setLoading,
4188
+ resultCount,
4189
+ totalCount,
4190
+ setResultCount: setResultCountInternal,
4191
+ activePage,
4192
+ setActivePage,
4193
+ pageSize,
4194
+ filters,
4195
+ setFilters,
4196
+ doQuery,
4197
+ query,
4198
+ setQuery,
4199
+ debouncedQuery,
4200
+ results,
4201
+ currentPageTotal,
4202
+ selectorStructure,
4203
+ translations,
4204
+ setTranslations: (t2) => {
4205
+ setTranslations({ ...DEFAULT_TRANSLATIONS, ...t2 });
4206
+ },
4207
+ showSelectors,
4208
+ initExplore
4209
+ };
4210
+ return /* @__PURE__ */ jsx(ExploreContext.Provider, { value: state, children });
4211
+ }
4212
+ var DEFAULT_TRANSLATIONS, ExploreContext, useExplore;
4213
+ var init_ExploreProvider = __esm({
4214
+ "frontend/components/report/context/ExploreProvider.tsx"() {
4215
+ init_esm_shims();
4216
+ init_store2();
4217
+ DEFAULT_TRANSLATIONS = {
4218
+ "try_another": "Try another search or filter.",
4219
+ "search": "Search",
4220
+ "filters_all": "All",
4221
+ "no_results": "No Results",
4222
+ "load_more": "Load more",
4223
+ report: {},
4224
+ dimension: {},
4225
+ variant: {}
4226
+ };
4227
+ ExploreContext = createContext({
4228
+ metadata: [],
4229
+ loading: false,
4230
+ setLoading: () => null,
4231
+ resultCount: {},
4232
+ totalCount: {},
4233
+ setResultCount: () => null,
4234
+ activePage: 1,
4235
+ setActivePage: () => null,
4236
+ pageSize: 10,
4237
+ results: [],
4238
+ filters: {},
4239
+ doQuery: () => null,
4240
+ setFilters: () => null,
4241
+ query: "",
4242
+ setQuery: () => null,
4243
+ debouncedQuery: "",
4244
+ currentPageTotal: 10,
4245
+ selectorStructure: [],
4246
+ translations: DEFAULT_TRANSLATIONS,
4247
+ setTranslations: () => null,
4248
+ showSelectors: true,
4249
+ initExplore: (p2, v2) => null
4250
+ });
4251
+ useExplore = () => useContext(ExploreContext);
4252
+ }
4253
+ });
4254
+ function ExploreFilters({ initialReportId, initialVariantId, translations }) {
4255
+ const { loading, setFilters, selectorStructure, filters, showSelectors } = useExplore();
4256
+ const onClickProfile = (profileId) => {
4257
+ if (profileId !== filters.profile) {
4258
+ setFilters({
4259
+ profile: profileId,
4260
+ variant: void 0
4261
+ });
4262
+ }
4263
+ };
4264
+ const onClickVariant = (variantId) => {
4265
+ if (variantId !== filters.variant) {
4266
+ setFilters({
4267
+ ...filters,
4268
+ variant: variantId
4269
+ });
4270
+ }
4271
+ };
4272
+ const selectedProfileObj = filters.profile ? selectorStructure.find((p2) => p2.id === filters.profile) : void 0;
4273
+ const selectedVariantObj = selectedProfileObj && selectedProfileObj.variants && filters.variant ? selectedProfileObj.variants.find((p2) => p2.id === filters.variant) : void 0;
4274
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
4275
+ showSelectors && /* @__PURE__ */ jsx(Group, { position: "center", className: "bespoke-explore-reports-selector", mb: "md", children: selectorStructure.map((s2) => /* @__PURE__ */ jsxs(
4276
+ Button,
4277
+ {
4278
+ "data-selected": s2.id === selectedProfileObj?.id ? "true" : "false",
4279
+ "data-report-name": s2.name,
4280
+ variant: s2.id === selectedProfileObj?.id ? "outline" : "subtle",
4281
+ onClick: () => onClickProfile(s2.id),
4282
+ children: [
4283
+ translations?.dimension[s2.name] ?? s2.name,
4284
+ !loading && /* @__PURE__ */ jsx(Text, { span: true, size: "xs", ml: "0.2rem", children: `(${s2.members_count})` })
4285
+ ]
4286
+ },
4287
+ `p-${s2.id}`
4288
+ )) }),
4289
+ selectedProfileObj && selectedProfileObj.variants && selectedProfileObj.variants.length > 2 && /* @__PURE__ */ jsx(Group, { position: "center", style: { minHeight: "36px" }, className: "bespoke-explore-variant-selector", mb: "md", children: selectedProfileObj.variants.map((v2) => /* @__PURE__ */ jsxs(
4290
+ Button,
4291
+ {
4292
+ "data-selected": v2.id === selectedVariantObj?.id ? "true" : "false",
4293
+ "data-variant-name": v2.name,
4294
+ variant: v2.id === selectedVariantObj?.id ? "outline" : "subtle",
4295
+ onClick: () => onClickVariant(v2.id),
4296
+ children: [
4297
+ translations?.dimension[v2.name] ?? v2.name,
4298
+ !loading && /* @__PURE__ */ jsx(Text, { span: true, size: "xs", ml: "0.2rem", children: `(${v2.members_count})` })
4299
+ ]
4300
+ },
4301
+ `v-${v2.id}`
4302
+ )) })
4303
+ ] });
4304
+ }
4305
+ var ExploreFilters_default;
4306
+ var init_ExploreFilters = __esm({
4307
+ "frontend/components/explore/ExploreFilters.tsx"() {
4308
+ init_esm_shims();
4309
+ init_ExploreProvider();
4310
+ ExploreFilters_default = ExploreFilters;
4311
+ }
4312
+ });
4134
4313
  function useBespokeStyles() {
4135
4314
  const theme = useMantineTheme();
4136
4315
  return theme.other.bespokeStyles ?? {};
@@ -4217,11 +4396,16 @@ var init_ExploreTile = __esm({
4217
4396
  ExploreTile_default = ExploreTile;
4218
4397
  }
4219
4398
  });
4220
- function ExploreResults({ results = [], profilePrefix, onSelect = () => void 0, reportTile }) {
4399
+ function ExploreResults({
4400
+ profilePrefix,
4401
+ onSelect = () => void 0,
4402
+ reportTile
4403
+ }) {
4221
4404
  const [scrollSize, setScrollSize] = useState(500);
4222
4405
  const scrollAreaRef = useRef(null);
4406
+ const { results } = useExplore();
4223
4407
  const offset2 = scrollAreaRef.current?.offsetTop || 0;
4224
- const gap = 30;
4408
+ const gap = 50;
4225
4409
  useEffect(() => {
4226
4410
  const { innerHeight } = window;
4227
4411
  setScrollSize(innerHeight - offset2 - gap);
@@ -4244,80 +4428,73 @@ var init_ExploreResults = __esm({
4244
4428
  "frontend/components/explore/ExploreResults.tsx"() {
4245
4429
  init_esm_shims();
4246
4430
  init_ExploreTile();
4431
+ init_ExploreProvider();
4247
4432
  ExploreResults_default = ExploreResults;
4248
4433
  }
4249
4434
  });
4435
+ function ExplorePagination() {
4436
+ const {
4437
+ activePage,
4438
+ setActivePage,
4439
+ pageSize,
4440
+ currentPageTotal
4441
+ } = useExplore();
4442
+ const onChangePage = (page) => {
4443
+ setActivePage(page);
4444
+ };
4445
+ return /* @__PURE__ */ jsx(Group, { position: "center", children: /* @__PURE__ */ jsx(
4446
+ Pagination,
4447
+ {
4448
+ value: activePage,
4449
+ onChange: onChangePage,
4450
+ total: Math.ceil(currentPageTotal / pageSize),
4451
+ size: "sm",
4452
+ py: "xs"
4453
+ }
4454
+ ) });
4455
+ }
4456
+ var ExplorePagination_default;
4457
+ var init_ExplorePagination = __esm({
4458
+ "frontend/components/explore/ExplorePagination.tsx"() {
4459
+ init_esm_shims();
4460
+ init_ExploreProvider();
4461
+ ExplorePagination_default = ExplorePagination;
4462
+ }
4463
+ });
4250
4464
  function BespokeExplore({
4251
- locale,
4252
4465
  profilePrefix,
4253
4466
  initialReportId,
4254
4467
  initialVariantId,
4255
- translations = DEFAULT_TRANSLATIONS,
4468
+ translations,
4256
4469
  onSelect,
4257
4470
  reportTile
4258
4471
  }) {
4259
- const dispatch = useAppDispatch();
4260
- const defaultFilters = {
4261
- // initial reportIds should go here to avoid multiple unnecesary requests
4262
- profile: void 0,
4263
- variant: void 0
4264
- };
4265
- const [query, setQuery] = useState("");
4266
- const [debouncedQuery] = useDebouncedValue(query, 500);
4267
- const [results, setResults] = useState([]);
4268
- const [loading, setLoading] = useState(false);
4269
- const [filters, setFilters] = useState(defaultFilters);
4270
- const [metadata, setMetadata] = useState();
4271
4472
  const inputRef = useRef();
4473
+ const {
4474
+ query,
4475
+ setQuery,
4476
+ results,
4477
+ loading,
4478
+ translations: exploreTranslations,
4479
+ setTranslations,
4480
+ initExplore
4481
+ } = useExplore();
4272
4482
  useEffect(() => {
4273
- setLoading(true);
4274
- dispatch(actions_exports.readMetadata({})).then((resp) => {
4275
- setMetadata(resp.data);
4276
- }, (err) => {
4277
- console.error(err);
4278
- });
4483
+ initExplore(initialReportId, initialVariantId);
4279
4484
  }, []);
4280
4485
  useEffect(() => {
4281
- let cancelled = false;
4282
- if (metadata) {
4283
- setLoading(true);
4284
- const filterProfile = filters.profile && !Number.isNaN(filters.profile) ? filters.profile : [];
4285
- const filterVariant = filters.variant && !Number.isNaN(filters.variant) ? filters.variant : [];
4286
- const params = {
4287
- query: debouncedQuery,
4288
- format: "profiles",
4289
- locale,
4290
- limit: 25,
4291
- visible: true,
4292
- includes: true,
4293
- noImage: false,
4294
- variant: filterVariant,
4295
- dimension: [],
4296
- report: filterProfile,
4297
- all: false
4298
- };
4299
- dispatch(actions_exports.reportSearch(params)).then((resp) => {
4300
- if (resp && resp.results && !cancelled) {
4301
- setResults(resp.results);
4302
- }
4303
- setLoading(false);
4304
- inputRef.current?.focus();
4305
- }).catch((e) => {
4306
- console.error(e);
4307
- setLoading(false);
4308
- });
4486
+ if (!loading) {
4487
+ inputRef.current?.focus();
4309
4488
  }
4310
- return () => {
4311
- cancelled = false;
4312
- };
4313
- }, [debouncedQuery, filters, metadata]);
4314
- const onFilterChange = (newFilters) => {
4315
- setFilters(newFilters);
4316
- };
4489
+ }, [loading]);
4490
+ useEffect(() => {
4491
+ if (translations) {
4492
+ setTranslations(translations);
4493
+ }
4494
+ }, [translations]);
4317
4495
  const onClearInput = () => {
4318
4496
  setQuery("");
4319
4497
  };
4320
- const exploreTranslations = { ...DEFAULT_TRANSLATIONS, ...translations };
4321
4498
  return /* @__PURE__ */ jsxs(Container, { fluid: true, pt: "1em", children: [
4322
4499
  /* @__PURE__ */ jsx(
4323
4500
  TextInput,
@@ -4346,8 +4523,6 @@ function BespokeExplore({
4346
4523
  /* @__PURE__ */ jsx(
4347
4524
  ExploreFilters_default,
4348
4525
  {
4349
- metadata,
4350
- onFilter: onFilterChange,
4351
4526
  initialReportId,
4352
4527
  initialVariantId,
4353
4528
  translations: exploreTranslations
@@ -4355,25 +4530,25 @@ function BespokeExplore({
4355
4530
  ),
4356
4531
  /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading }),
4357
4532
  !loading && results.length === 0 && /* @__PURE__ */ jsx(Alert, { title: exploreTranslations["no_results"], color: "blue", children: exploreTranslations["try_another"] }),
4358
- !loading && /* @__PURE__ */ jsx(ExploreResults_default, { results, profilePrefix, onSelect, reportTile })
4533
+ !loading && /* @__PURE__ */ jsx(
4534
+ ExploreResults_default,
4535
+ {
4536
+ profilePrefix,
4537
+ onSelect,
4538
+ reportTile
4539
+ }
4540
+ ),
4541
+ /* @__PURE__ */ jsx(ExplorePagination_default, {})
4359
4542
  ] });
4360
4543
  }
4361
- var DEFAULT_TRANSLATIONS, Explore_default;
4544
+ var Explore_default;
4362
4545
  var init_Explore = __esm({
4363
4546
  "frontend/components/explore/Explore.tsx"() {
4364
4547
  init_esm_shims();
4365
4548
  init_ExploreFilters();
4366
4549
  init_ExploreResults();
4367
- init_store2();
4368
- DEFAULT_TRANSLATIONS = {
4369
- "try_another": "Try another search or filter.",
4370
- "search": "Search",
4371
- "filters_all": "All",
4372
- "no_results": "No Results",
4373
- report: {},
4374
- dimension: {},
4375
- variant: {}
4376
- };
4550
+ init_ExplorePagination();
4551
+ init_ExploreProvider();
4377
4552
  Explore_default = BespokeExplore;
4378
4553
  }
4379
4554
  });
@@ -4417,7 +4592,7 @@ function BespokeExploreModal({
4417
4592
  target = /* @__PURE__ */ jsx(Tooltip, { label: tooltipText, ...tooltipProps, children: target });
4418
4593
  }
4419
4594
  return /* @__PURE__ */ jsxs(Fragment, { children: [
4420
- /* @__PURE__ */ jsx(Modal, { ...mdlConfig, ...modalProps, children: /* @__PURE__ */ jsx(Explore_default, { ...exploreProps, onSelect: () => setOpened(false) }) }),
4595
+ /* @__PURE__ */ jsx(Modal, { ...mdlConfig, ...modalProps, children: opened && /* @__PURE__ */ jsx(Explore_default, { ...exploreProps, onSelect: () => setOpened(false) }) }),
4421
4596
  /* @__PURE__ */ jsx("div", { onClick: () => setOpened(true), children: children ? target : /* @__PURE__ */ jsx(Fragment, { children: actionIcon }) })
4422
4597
  ] });
4423
4598
  }
@@ -4764,10 +4939,10 @@ var init_RichText = __esm({
4764
4939
  });
4765
4940
  function InnerTooltip(props) {
4766
4941
  const { content, style = {} } = props;
4767
- const { isPrint } = useMode();
4942
+ const print = usePrint();
4768
4943
  const contentObj = /* @__PURE__ */ jsx(RichText, { component: "span", html: content, isPreview: true });
4769
4944
  const element = useMemo(() => {
4770
- return isPrint ? /* @__PURE__ */ jsx("div", { className: "bespoke-inner-tooltip-notification", children: /* @__PURE__ */ jsx(
4945
+ return print ? /* @__PURE__ */ jsx("div", { className: "bespoke-inner-tooltip-notification", children: /* @__PURE__ */ jsx(
4771
4946
  Notification,
4772
4947
  {
4773
4948
  icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: "1.1rem" }),
@@ -5309,7 +5484,7 @@ function TitleView({
5309
5484
  _iconPadding,
5310
5485
  asComparison = false
5311
5486
  }) {
5312
- const { isPrint } = useMode();
5487
+ const print = usePrint();
5313
5488
  const titleHTML = sanitizeBlockContent_default(title) || "<span class='cr-block-placeholder'>Title</span>";
5314
5489
  const intOrder = settings && settings.order ? parseInt(settings.order, 10) : 1;
5315
5490
  const order2 = intOrder <= 6 ? intOrder : 1;
@@ -5352,7 +5527,7 @@ function TitleView({
5352
5527
  position: getAlignForGroup(align),
5353
5528
  children: [
5354
5529
  /* @__PURE__ */ jsxs("div", { children: [
5355
- isPrint ? titleElement : finalElement,
5530
+ print ? titleElement : finalElement,
5356
5531
  displayName && /* @__PURE__ */ jsx(Text, { className: "bespoke-comparison-title", children: memberName })
5357
5532
  ] }),
5358
5533
  tooltip && /* @__PURE__ */ jsx(InnerTooltip, { content: tooltip })
@@ -5473,7 +5648,7 @@ var init_useOnChangeSelector = __esm({
5473
5648
  });
5474
5649
  function Selector(config) {
5475
5650
  const { name, settings, options, id, defaultValue, section, component, asComparison, hideLabel } = config;
5476
- const { isPrint } = useMode();
5651
+ const print = usePrint();
5477
5652
  const selectorIdentifier = getSelectorIdentifier(id);
5478
5653
  const callback = useOnChangeSelector(id, section, selectorIdentifier, asComparison);
5479
5654
  const selectorIdentifierParam = asComparison ? `${selectorIdentifier}Compare` : selectorIdentifier;
@@ -5484,9 +5659,9 @@ function Selector(config) {
5484
5659
  (d2) => ({ value: d2.id, label: d2.label })
5485
5660
  ), [optDependency]);
5486
5661
  const printValue = useMemo(() => {
5487
- const optionsString = isPrint ? options.filter((o2) => multiValue.includes(o2.id)).map((o2) => o2.label).join(", ") : "";
5662
+ const optionsString = print ? options.filter((o2) => multiValue.includes(o2.id)).map((o2) => o2.label).join(", ") : "";
5488
5663
  return optionsString;
5489
- }, [isPrint]);
5664
+ }, [print]);
5490
5665
  const label = config.hideLabel === "true" ? /* @__PURE__ */ jsx(Fragment, {}) : /* @__PURE__ */ jsx(RichText, { component: "div", html: name, size: "sm", style: settings });
5491
5666
  useEffect(() => {
5492
5667
  const searchParams = new URLSearchParams(window.location.search);
@@ -5541,7 +5716,7 @@ function Selector(config) {
5541
5716
  }
5542
5717
  )
5543
5718
  }[config.type] }) }),
5544
- isPrint && /* @__PURE__ */ jsxs(Text, { children: [
5719
+ print && /* @__PURE__ */ jsxs(Text, { children: [
5545
5720
  label,
5546
5721
  ": ",
5547
5722
  printValue
@@ -5597,7 +5772,7 @@ var init_Image = __esm({
5597
5772
  init_block2();
5598
5773
  }
5599
5774
  });
5600
- function useInitialState(pathSegmentsKey, mode) {
5775
+ function useInitialState(pathSegmentsKey) {
5601
5776
  const { asPath, locale, defaultLocale } = useRouter();
5602
5777
  const [loading, setLoading] = useState(true);
5603
5778
  const { user, isLoading } = useUser();
@@ -5640,41 +5815,39 @@ function useInitialState(pathSegmentsKey, mode) {
5640
5815
  }
5641
5816
  }, [user, isLoading]);
5642
5817
  useEffect(() => {
5643
- if (mode !== "embed") {
5644
- const hasParams = Object.keys(query).some((key) => key !== pathSegmentsKey);
5645
- if ((hasParams || privateBlocks.blocks.length > 0) && privateBlocks.resolved) {
5646
- const selectorIds = Object.keys(query).map((d2) => Number(d2.match(/\d+/)));
5647
- const revalidateBlocks = selectorIds.filter((id) => id !== 0).concat(privateBlocks.blocks);
5648
- Promise.all(
5649
- revalidateBlocks.map((bid) => {
5650
- const block = blockRecords[bid];
5651
- const inputVariablesFlat = block.consumers.reduce((inputVars, cid) => ({ ...inputVars, ...variables[cid] }), {});
5652
- const blockContext = {
5653
- locale: localeDefault4,
5654
- query,
5655
- variables: {
5656
- ...inputVariablesFlat,
5657
- ...attributes
5658
- }
5659
- };
5660
- return runConsumersV2(
5661
- blockRecords,
5662
- void 0,
5663
- bid,
5664
- formatters2,
5665
- blockContext,
5666
- { variables, status },
5667
- readMemberFn,
5668
- "report"
5669
- );
5670
- })
5671
- ).then((d2) => {
5672
- setLoading(false);
5673
- d2.map((data) => dispatch(variablesActions.setVariableChange({ ...data, attributes })));
5674
- });
5675
- }
5818
+ const hasParams = Object.keys(query).some((key) => key !== pathSegmentsKey);
5819
+ if ((hasParams || privateBlocks.blocks.length > 0) && privateBlocks.resolved) {
5820
+ const selectorIds = Object.keys(query).map((d2) => Number(d2.match(/\d+/)));
5821
+ const revalidateBlocks = selectorIds.filter((id) => id !== 0).concat(privateBlocks.blocks);
5822
+ Promise.all(
5823
+ revalidateBlocks.map((bid) => {
5824
+ const block = blockRecords[bid];
5825
+ const inputVariablesFlat = block.consumers.reduce((inputVars, cid) => ({ ...inputVars, ...variables[cid] }), {});
5826
+ const blockContext = {
5827
+ locale: localeDefault4,
5828
+ query,
5829
+ variables: {
5830
+ ...inputVariablesFlat,
5831
+ ...attributes
5832
+ }
5833
+ };
5834
+ return runConsumersV2(
5835
+ blockRecords,
5836
+ void 0,
5837
+ bid,
5838
+ formatters2,
5839
+ blockContext,
5840
+ { variables, status },
5841
+ readMemberFn,
5842
+ "report"
5843
+ );
5844
+ })
5845
+ ).then((d2) => {
5846
+ setLoading(false);
5847
+ d2.map((data) => dispatch(variablesActions.setVariableChange({ ...data, attributes })));
5848
+ });
5676
5849
  }
5677
- }, [privateBlocks.resolved, mode]);
5850
+ }, [privateBlocks.resolved]);
5678
5851
  return loading || !privateBlocks.resolved;
5679
5852
  }
5680
5853
  var init_useInitialState = __esm({
@@ -5727,41 +5900,6 @@ var init_useScrollToAnchor = __esm({
5727
5900
  init_esm_shims();
5728
5901
  }
5729
5902
  });
5730
- function useEmbed() {
5731
- const loaded = useRef(false);
5732
- useEffect(() => {
5733
- let prevRequests = 0;
5734
- let thresholdCount = 0;
5735
- const interval = setInterval(() => {
5736
- const resources = performance.getEntriesByType("resource");
5737
- const allRequestsComplete = resources.every((resource) => resource.responseEnd > 0);
5738
- if (prevRequests === resources.length && allRequestsComplete && thresholdCount > 3) {
5739
- clearInterval(interval);
5740
- if (!loaded.current) {
5741
- setTimeout(() => {
5742
- window.parent.postMessage("iframe-loaded", "*");
5743
- }, 500);
5744
- loaded.current = true;
5745
- }
5746
- } else {
5747
- if (resources.length > prevRequests) {
5748
- thresholdCount = 0;
5749
- } else {
5750
- thresholdCount++;
5751
- }
5752
- prevRequests = resources.length;
5753
- }
5754
- }, 300);
5755
- if (typeof document !== "undefined") {
5756
- initFrameAndPoll();
5757
- }
5758
- }, []);
5759
- }
5760
- var init_useEmbed = __esm({
5761
- "frontend/hooks/useEmbed.ts"() {
5762
- init_esm_shims();
5763
- }
5764
- });
5765
5903
  function createOutline(elements, variables) {
5766
5904
  const roots = [];
5767
5905
  const nodes = {};
@@ -5879,7 +6017,6 @@ var init_hooks2 = __esm({
5879
6017
  init_useInitialState();
5880
6018
  init_useOnChangeSelector();
5881
6019
  init_useScrollToAnchor();
5882
- init_useEmbed();
5883
6020
  init_useContentOutline();
5884
6021
  }
5885
6022
  });
@@ -6303,7 +6440,7 @@ __export(Viz_exports, {
6303
6440
  default: () => Viz
6304
6441
  });
6305
6442
  function Viz(config) {
6306
- const { isPrint, isEmbed } = useMode();
6443
+ const print = usePrint();
6307
6444
  const { block, active, locale, variables, configOverride = {} } = config;
6308
6445
  const content = getBlockContent(block);
6309
6446
  const formatterFunctions = useFormatterFunctionsForLocale(locale);
@@ -6332,8 +6469,8 @@ function Viz(config) {
6332
6469
  const Visualization = vizTypes[fallbackType];
6333
6470
  const vizPropsConfig = useMemo(() => {
6334
6471
  const { _data, ...vizPropsInnerConfig } = vizProps.config;
6335
- return printOverrides(vizPropsInnerConfig, isPrint || isEmbed);
6336
- }, [vizProps, isPrint, isEmbed]);
6472
+ return printOverrides(vizPropsInnerConfig, print);
6473
+ }, [vizProps, print]);
6337
6474
  const vizConfig = { locale, variables, ...vizPropsConfig, ...configOverride };
6338
6475
  return /* @__PURE__ */ jsx("div", { className: "bespoke-Viz", children: /* @__PURE__ */ jsx(
6339
6476
  "div",
@@ -15979,265 +16116,161 @@ var init_DataTab = __esm({
15979
16116
  };
15980
16117
  }
15981
16118
  });
15982
- function useLocalePrefix() {
15983
- const { locales: locales4 } = useRouter();
15984
- const locale = location && location.pathname.split("/").filter((segment) => segment.length > 0)[0];
15985
- return locales4?.includes(locale);
15986
- }
15987
- var init_useLocalePrefix = __esm({
15988
- "frontend/hooks/useLocalePrefix.ts"() {
15989
- init_esm_shims();
15990
- }
15991
- });
15992
- function CopyInput(props) {
15993
- const { title, url, disabled = false } = props;
15994
- const Icon = disabled ? IconCode : IconLink;
15995
- return /* @__PURE__ */ jsx(Input.Wrapper, { label: title, children: /* @__PURE__ */ jsx(
15996
- Input,
15997
- {
15998
- icon: /* @__PURE__ */ jsx(Icon, {}),
15999
- value: url,
16000
- disabled,
16001
- readOnly: true,
16002
- rightSection: /* @__PURE__ */ jsx(CopyButton, { value: url, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: true, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { variant: copied ? "filled" : "subtle", onClick: copy, disabled, children: copied ? /* @__PURE__ */ jsx(IconClipboardCheck, { size: 16 }) : /* @__PURE__ */ jsx(IconClipboardCopy, { size: 16 }) }) }) })
16003
- }
16004
- ) });
16005
- }
16006
- var init_CopyInput = __esm({
16007
- "components/options/CopyInput.tsx"() {
16008
- init_esm_shims();
16009
- }
16010
- });
16011
- function useEmbedPath(sectionId, vizId = void 0, queryParams = {}) {
16012
- const { query, locale } = useRouter();
16013
- const prefixLocale = useLocalePrefix();
16014
- const { pathSegment } = useBespoke();
16015
- const slugs = query[pathSegment];
16016
- if (slugs && Array.isArray(slugs)) {
16017
- const search = new URLSearchParams({ section: sectionId, ...queryParams });
16018
- if (vizId) {
16019
- search.set("viz", vizId);
16020
- }
16021
- const embed = `/embed/${slugs.join("/")}`;
16022
- const url = new URL(
16023
- prefixLocale ? `/${locale}${embed}` : `${embed}`,
16024
- location.href
16025
- );
16026
- url.search = search.toString();
16027
- return url.href;
16028
- }
16029
- return void 0;
16030
- }
16031
- function ShareTab(props) {
16032
- const { section } = props;
16033
- const [shareUrl, setShareUrl] = useState("");
16034
- const [title, setTitle] = useState("");
16035
- const [includeSection, setIncludeSection] = useState(true);
16036
- const optionsTranslations = useBespokeTranslations("options");
16037
- const embedPath = useEmbedPath(section.id);
16038
- const iframeStr = `<iframe width="100%" height="500px" frameborder="0" src="${embedPath}"></iframe>`;
16039
- const translations = { ...DEFAULT_TRANSLATIONS3, ...optionsTranslations["share_tab"] };
16040
- useEffect(() => {
16041
- setTitle(document.title);
16042
- const { origin, pathname } = window.location;
16043
- const url = `${origin}${pathname}`;
16044
- const sectionAnchor = includeSection ? `#section-${section.id}` : "";
16045
- setShareUrl(`${url}${sectionAnchor}`);
16046
- }, [includeSection]);
16047
- return /* @__PURE__ */ jsxs(Stack, { className: "cms-section-options-share", children: [
16048
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
16049
- /* @__PURE__ */ jsx(CopyInput, { title: `${translations["title"]}: ${title}`, url: shareUrl }),
16050
- /* @__PURE__ */ jsx(
16051
- Checkbox,
16052
- {
16053
- checked: includeSection,
16054
- label: translations["include_section"],
16055
- onChange: () => setIncludeSection(!includeSection),
16056
- radius: "xl"
16057
- }
16058
- ),
16059
- /* @__PURE__ */ jsx(CopyInput, { title: translations["embed"], url: iframeStr }),
16060
- /* @__PURE__ */ jsxs(Group, { position: "center", children: [
16061
- /* @__PURE__ */ jsx(
16062
- FacebookShareButton,
16063
- {
16064
- url: shareUrl,
16065
- quote: title,
16066
- children: /* @__PURE__ */ jsx(FacebookIcon, { size: 32, round: true })
16067
- }
16068
- ),
16069
- /* @__PURE__ */ jsx(
16070
- TwitterShareButton,
16071
- {
16072
- url: shareUrl,
16073
- title,
16074
- children: /* @__PURE__ */ jsx(TwitterIcon, { size: 32, round: true })
16075
- }
16076
- ),
16077
- /* @__PURE__ */ jsx(
16078
- TelegramShareButton,
16079
- {
16080
- url: shareUrl,
16081
- title,
16082
- children: /* @__PURE__ */ jsx(TelegramIcon, { size: 32, round: true })
16083
- }
16084
- ),
16085
- /* @__PURE__ */ jsx(
16086
- WhatsappShareButton,
16087
- {
16088
- url: shareUrl,
16089
- title,
16090
- separator: ":: ",
16091
- children: /* @__PURE__ */ jsx(WhatsappIcon, { size: 32, round: true })
16092
- }
16093
- ),
16094
- /* @__PURE__ */ jsx(LinkedinShareButton, { url: shareUrl, children: /* @__PURE__ */ jsx(LinkedinIcon, { size: 32, round: true }) }),
16095
- /* @__PURE__ */ jsx(
16096
- RedditShareButton,
16097
- {
16098
- url: shareUrl,
16099
- title,
16100
- windowWidth: 660,
16101
- windowHeight: 460,
16102
- children: /* @__PURE__ */ jsx(RedditIcon, { size: 32, round: true })
16103
- }
16104
- ),
16105
- /* @__PURE__ */ jsx(
16106
- EmailShareButton,
16107
- {
16108
- url: shareUrl,
16109
- subject: title,
16110
- children: /* @__PURE__ */ jsx(EmailIcon, { size: 32, round: true })
16111
- }
16112
- )
16113
- ] })
16114
- ] });
16115
- }
16116
- var DEFAULT_TRANSLATIONS3;
16117
- var init_ShareTab = __esm({
16118
- "components/options/tabs/ShareTab.tsx"() {
16119
- init_esm_shims();
16120
- init_CopyInput();
16121
- init_TranslationsProvider();
16122
- init_useLocalePrefix();
16123
- init_ResourceProvider();
16124
- DEFAULT_TRANSLATIONS3 = {
16125
- "title": "Title",
16126
- "include_section": "Include Section",
16127
- "embed": "Embed"
16128
- };
16129
- }
16130
- });
16131
- function exportSVG(svg) {
16132
- const serializer = new XMLSerializer();
16133
- let source = serializer.serializeToString(svg);
16134
- if (!source.match(/^<svg[^>]+xmlns="http\:\/\/www\.w3\.org\/2000\/svg"/)) {
16135
- source = source.replace(/^<svg/, '<svg xmlns="http://www.w3.org/2000/svg"');
16136
- }
16137
- if (!source.match(/^<svg[^>]+"http\:\/\/www\.w3\.org\/1999\/xlink"/)) {
16138
- source = source.replace(/^<svg/, '<svg xmlns:xlink="http://www.w3.org/1999/xlink"');
16139
- }
16140
- source = '<?xml version="1.0" standalone="no"?>\r\n' + source;
16141
- const url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(source);
16142
- const a2 = document.createElement("a");
16143
- const e = new MouseEvent("click");
16144
- a2.download = "image.svg";
16145
- a2.href = url;
16146
- a2.dispatchEvent(e);
16147
- }
16148
16119
  function ImageTab(props) {
16149
16120
  const { section } = props;
16150
16121
  const blocksIds = section.blocks || [];
16151
- const framer = useRef();
16152
- useRouter();
16153
- useLocalePrefix();
16154
- useBespoke();
16155
16122
  const vizAvailable = useAppSelector((state) => blocksIds.map((blockId) => state.records.entities.block[blockId]).filter((block) => block.type === "visualization" && state.variables.status[block.id].allowed));
16156
16123
  const [imageContext, setImageContext] = useState(contextOptions.section);
16157
16124
  const [imageFormat, setImageFormat] = useState(formatOptions2.png);
16158
16125
  const [imageProcessing, setImageProcessing] = useState(false);
16126
+ const [svgAvailable, setSvgAvailable] = useState(false);
16159
16127
  const [vizPreviews, setVizPreviews] = useState([]);
16160
16128
  const [vizSelected, setVizSelected] = useState(vizAvailable.length > 0 ? vizAvailable[0].id : null);
16161
- const [transparentBackground, setTransparentBackground] = useState(false);
16129
+ const [transparentBackground, setTransparentBackground] = useState(true);
16162
16130
  const [loadingPreviews, setLoadingPreviews] = useState(false);
16163
16131
  const optionsTranslations = useBespokeTranslations("options");
16164
- const translations = { ...DEFAULT_TRANSLATIONS4, ...optionsTranslations["image_tab"] };
16165
- const search = Object.fromEntries(new URLSearchParams(location.search));
16166
- const selectors = Object.fromEntries(
16167
- Object.entries(search).filter(([key]) => key.match(/selector\d+id/))
16168
- );
16169
- const sectionId = slugify_default(section?.settings?.name) || `section-${section.id}`;
16170
- const embedPath = useEmbedPath(section.id, imageContext === contextOptions.viz ? vizSelected : void 0, selectors);
16132
+ const translations = { ...DEFAULT_TRANSLATIONS3, ...optionsTranslations["image_tab"] };
16133
+ const { siteProps } = useBespoke();
16134
+ const includeLogo = siteProps?.logoSrc && typeof siteProps.logoSrc === "string";
16135
+ const sectionId = section?.settings?.name || `section-${section.id}`;
16136
+ const sectionHash = `#${sectionId}`;
16137
+ const theme = useMantineTheme();
16138
+ const vizSelectedHasSVG = () => {
16139
+ const vizNode = getVizNode(vizSelected);
16140
+ const svgCount = select(vizNode).select("svg").size();
16141
+ return svgCount === 1;
16142
+ };
16143
+ const getFileName = () => `${slugify_default(sectionId)}`;
16144
+ const getSectionNode = () => {
16145
+ const sectionNode = document.getElementById(sectionId);
16146
+ return select(sectionNode).select(".bespoke-section-content").node();
16147
+ };
16148
+ const getVizNode = (vizId) => {
16149
+ const sectionNode = getSectionNode();
16150
+ return select(sectionNode).select(`#bespoke-visualization-${vizId}.bespoke-block-area`).node();
16151
+ };
16152
+ const getSelectedNode = () => new Promise((resolve) => {
16153
+ let node;
16154
+ if (imageContext === contextOptions.section) {
16155
+ node = getSectionNode();
16156
+ } else if (imageContext === contextOptions.viz) {
16157
+ node = getVizNode(vizSelected);
16158
+ }
16159
+ const sourceContainer = document.createElement("div");
16160
+ sourceContainer.style.display = "flex";
16161
+ sourceContainer.style.justifyContent = "space-between";
16162
+ sourceContainer.classList.add("bespoke-Viz-source");
16163
+ sourceContainer.style.padding = theme.spacing.xs;
16164
+ sourceContainer.style.width = "100%";
16165
+ const sourceNode = document.createElement("div");
16166
+ sourceNode.innerText = translations["source"].replace("{src}", `${window.location}${sectionHash}`);
16167
+ sourceNode.style.fontSize = theme.fontSizes.xs;
16168
+ sourceContainer.appendChild(sourceNode);
16169
+ if (includeLogo) {
16170
+ const sourceImage = document.createElement("img");
16171
+ sourceImage.src = siteProps.logoSrc;
16172
+ sourceImage.style.height = "30px";
16173
+ sourceImage.onload = () => resolve(node);
16174
+ sourceImage.onerror = () => {
16175
+ sourceImage.remove();
16176
+ resolve(node);
16177
+ };
16178
+ sourceContainer.appendChild(sourceImage);
16179
+ node.appendChild(sourceContainer);
16180
+ } else {
16181
+ node.appendChild(sourceContainer);
16182
+ resolve(node);
16183
+ }
16184
+ });
16185
+ const getBackground = (elem) => {
16186
+ if (transparentBackground)
16187
+ return "transparent";
16188
+ const color = select(elem).style("background-color");
16189
+ if (color !== "rgba(0, 0, 0, 0)" && color !== "transparent")
16190
+ return color;
16191
+ if (elem === document.body)
16192
+ return "white";
16193
+ return getBackground(elem.parentNode);
16194
+ };
16195
+ const exportPng = async (node, config) => {
16196
+ const { toPng } = await import('html-to-image');
16197
+ toPng(
16198
+ node,
16199
+ {
16200
+ backgroundColor: config.background,
16201
+ cacheBust: true,
16202
+ filter: (innerNode) => {
16203
+ if (innerNode && innerNode.classList) {
16204
+ return !config.exclusionClasses.some((classname) => innerNode.classList.contains(classname));
16205
+ }
16206
+ return true;
16207
+ }
16208
+ }
16209
+ ).then((dataUrl) => {
16210
+ const link = document.createElement("a");
16211
+ link.download = `${config.filename}.png`;
16212
+ link.href = dataUrl;
16213
+ link.click();
16214
+ cleanDOM();
16215
+ setImageProcessing(false);
16216
+ }).catch((err) => {
16217
+ console.log(err);
16218
+ });
16219
+ };
16220
+ const exportSvg = (node, config) => {
16221
+ saveElement(
16222
+ node,
16223
+ { filename: config.filename, type: "svg", callback: () => setImageProcessing(false) },
16224
+ { background: config.background }
16225
+ );
16226
+ };
16227
+ const onSaveClick = async () => {
16228
+ setImageProcessing(true);
16229
+ const node = await getSelectedNode();
16230
+ const exportConfig = {
16231
+ background: getBackground(node),
16232
+ exclusionClasses: ["export-hidden"],
16233
+ filename: getFileName()
16234
+ };
16235
+ const exportFunction = imageFormat === formatOptions2.png ? exportPng : exportSvg;
16236
+ try {
16237
+ if (node) {
16238
+ exportFunction(node, exportConfig);
16239
+ } else {
16240
+ throw new Error(translations["wrong_node"]);
16241
+ }
16242
+ } catch (error) {
16243
+ setImageProcessing(false);
16244
+ }
16245
+ };
16171
16246
  const generatePreviews = async () => {
16172
16247
  const { toCanvas } = await import('html-to-image');
16173
16248
  Promise.all(
16174
- vizAvailable.map((viz) => toCanvas(getVizNode(viz.id, sectionId)))
16249
+ vizAvailable.map((viz) => toCanvas(getVizNode(viz.id)))
16175
16250
  ).then((canvases) => {
16176
16251
  setVizPreviews(canvases.map((canvas) => canvas.toDataURL()));
16177
16252
  setLoadingPreviews(false);
16178
16253
  });
16179
16254
  };
16180
- const handleContextChange = (newValue) => {
16181
- setImageContext(newValue);
16182
- if (newValue === contextOptions.section) {
16183
- setImageFormat(formatOptions2.png);
16184
- }
16185
- if (newValue === contextOptions.viz && vizAvailable.length > 0) {
16255
+ useEffect(() => {
16256
+ if (imageContext === contextOptions.viz && vizAvailable.length > 0) {
16186
16257
  setVizSelected(vizAvailable[0].id);
16187
16258
  setLoadingPreviews(true);
16188
16259
  generatePreviews();
16189
- } else if (newValue === contextOptions.section) {
16260
+ } else if (imageContext === contextOptions.section) {
16190
16261
  setVizPreviews([]);
16191
16262
  }
16192
- };
16193
- const onSelectViz = (vizId) => () => {
16194
- setVizSelected(vizId);
16195
- };
16196
- const onDownloadIframe = () => {
16197
- setImageProcessing(true);
16198
- const container = document.getElementById("iframe-preview");
16199
- framer.current = new Framer(container, { src: embedPath });
16200
- };
16263
+ }, [imageContext]);
16201
16264
  useEffect(() => {
16202
- const onIframeLoad = (e) => {
16203
- if (e.data === "iframe-loaded") {
16204
- console.log("Downloading image");
16205
- const node = document.getElementById("iframe-preview");
16206
- if (imageFormat === formatOptions2.png) {
16207
- toPng(
16208
- node,
16209
- {
16210
- backgroundColor: transparentBackground ? "transparent" : "white",
16211
- cacheBust: true
16212
- }
16213
- ).then(function(dataUrl) {
16214
- const link = document.createElement("a");
16215
- link.href = dataUrl;
16216
- link.setAttribute("download", "image.png");
16217
- document.body.appendChild(link);
16218
- link.click();
16219
- document.body.removeChild(link);
16220
- setImageProcessing(false);
16221
- if (typeof framer.current?.remove === "function") {
16222
- framer.current.remove();
16223
- }
16224
- }).catch(function(error) {
16225
- console.error("oops, something went wrong!", error);
16226
- setImageProcessing(false);
16227
- });
16228
- } else {
16229
- const iframe = document.querySelector("#iframe-preview > iframe");
16230
- const doc = iframe.contentDocument;
16231
- const svg = doc?.querySelector("svg.d3plus-viz");
16232
- console.log(svg.innerHtml);
16233
- if (svg)
16234
- exportSVG(svg);
16235
- }
16265
+ if (vizSelected) {
16266
+ if (vizSelectedHasSVG()) {
16267
+ setSvgAvailable(true);
16268
+ } else {
16269
+ setSvgAvailable(false);
16270
+ setImageFormat(formatOptions2.png);
16236
16271
  }
16237
- };
16238
- window.addEventListener("message", onIframeLoad);
16239
- return () => window.removeEventListener("message", onIframeLoad);
16240
- }, [transparentBackground]);
16272
+ }
16273
+ }, [vizSelected]);
16241
16274
  return /* @__PURE__ */ jsxs(Stack, { className: "cms-section-options-image", children: [
16242
16275
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
16243
16276
  vizAvailable.length > 0 ? /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_area"]}:`, children: /* @__PURE__ */ jsx(
@@ -16261,7 +16294,12 @@ function ImageTab(props) {
16261
16294
  ] })
16262
16295
  }
16263
16296
  ],
16264
- onChange: handleContextChange
16297
+ onChange: (newValue) => {
16298
+ setImageContext(newValue);
16299
+ if (newValue === contextOptions.section) {
16300
+ setImageFormat(formatOptions2.png);
16301
+ }
16302
+ }
16265
16303
  }
16266
16304
  ) }) : /* @__PURE__ */ jsx(Text, { fw: "700", color: "gray.7", children: `${translations["entire_section"]}:` }),
16267
16305
  imageContext === contextOptions.viz && vizAvailable.length > 0 && /* @__PURE__ */ jsxs(
@@ -16271,21 +16309,49 @@ function ImageTab(props) {
16271
16309
  style: { minHeight: "161px", position: "relative" },
16272
16310
  children: [
16273
16311
  !loadingPreviews && vizPreviews.length > 0 && /* @__PURE__ */ jsx(ScrollArea, { style: { height: 250 }, children: /* @__PURE__ */ jsx(SimpleGrid, { cols: 3, children: vizAvailable.map((vizOption, ix) => /* @__PURE__ */ jsx(
16274
- VizPreview2,
16312
+ Image,
16275
16313
  {
16276
- vizId: vizOption.id,
16277
- isSelected: vizOption.id === vizSelected,
16278
- onClick: () => onSelectViz(vizAvailable[ix].id),
16279
- src: vizPreviews[ix]
16314
+ alt: `Viz ${vizOption.id}`,
16315
+ onClick: () => {
16316
+ setVizSelected(vizOption.id);
16317
+ },
16318
+ style: {
16319
+ cursor: "pointer",
16320
+ border: vizSelected === vizOption.id ? "4px solid #228be6" : "4px solid #eee"
16321
+ },
16322
+ radius: 0,
16323
+ src: vizPreviews[ix],
16324
+ withPlaceholder: true
16280
16325
  },
16281
- vizOption.id
16326
+ `viz-option-${vizOption.id}`
16282
16327
  )) }) }),
16283
16328
  /* @__PURE__ */ jsx(LoadingOverlay, { visible: loadingPreviews })
16284
16329
  ]
16285
16330
  }
16286
16331
  ),
16287
- /* @__PURE__ */ jsx("div", { style: { height: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx("div", { id: "iframe-preview", "data-frame-src": embedPath, style: { width: 1e3 } }) }),
16288
- imageFormat !== formatOptions2.svg && /* @__PURE__ */ jsx(
16332
+ svgAvailable && imageContext !== contextOptions.section && /* @__PURE__ */ jsx(Input.Wrapper, { label: `${translations["choose_format"]}:`, children: /* @__PURE__ */ jsxs(Button.Group, { children: [
16333
+ /* @__PURE__ */ jsx(
16334
+ Button,
16335
+ {
16336
+ leftIcon: /* @__PURE__ */ jsx(IconPolaroid, { size: 16 }),
16337
+ onClick: () => setImageFormat(formatOptions2.png),
16338
+ variant: imageFormat === formatOptions2.png ? "filled" : "default",
16339
+ fullWidth: true,
16340
+ children: formatOptions2.png
16341
+ }
16342
+ ),
16343
+ /* @__PURE__ */ jsx(
16344
+ Button,
16345
+ {
16346
+ leftIcon: /* @__PURE__ */ jsx(IconCode, { size: 16 }),
16347
+ onClick: () => setImageFormat(formatOptions2.svg),
16348
+ variant: imageFormat === formatOptions2.svg ? "filled" : "default",
16349
+ fullWidth: true,
16350
+ children: formatOptions2.svg
16351
+ }
16352
+ )
16353
+ ] }) }),
16354
+ /* @__PURE__ */ jsx(
16289
16355
  Checkbox,
16290
16356
  {
16291
16357
  checked: transparentBackground,
@@ -16299,14 +16365,14 @@ function ImageTab(props) {
16299
16365
  {
16300
16366
  leftIcon: /* @__PURE__ */ jsx(IconDownload, { size: 16 }),
16301
16367
  loading: imageProcessing,
16302
- onClick: onDownloadIframe,
16368
+ onClick: onSaveClick,
16303
16369
  fullWidth: true,
16304
16370
  children: /* @__PURE__ */ jsx("span", { children: imageProcessing ? translations["processing"] : translations["download"].replace("{imageFormat}", imageFormat) })
16305
16371
  }
16306
16372
  )
16307
16373
  ] });
16308
16374
  }
16309
- var contextOptions, formatOptions2, VizPreview2, DEFAULT_TRANSLATIONS4, getSectionNode, getVizNode;
16375
+ var contextOptions, formatOptions2, cleanDOM, DEFAULT_TRANSLATIONS3;
16310
16376
  var init_ImageTab = __esm({
16311
16377
  "components/options/tabs/ImageTab.tsx"() {
16312
16378
  init_esm_shims();
@@ -16314,12 +16380,6 @@ var init_ImageTab = __esm({
16314
16380
  init_store2();
16315
16381
  init_TranslationsProvider();
16316
16382
  init_ResourceProvider();
16317
- init_useLocalePrefix();
16318
- init_d3plusPropify();
16319
- init_varSwapRecursive();
16320
- init_getBlockContent();
16321
- init_hooks();
16322
- init_ShareTab();
16323
16383
  contextOptions = {
16324
16384
  viz: "viz",
16325
16385
  section: "section"
@@ -16328,52 +16388,11 @@ var init_ImageTab = __esm({
16328
16388
  png: "PNG",
16329
16389
  svg: "SVG"
16330
16390
  };
16331
- VizPreview2 = ({ vizId, isSelected = false, onClick = () => void 0, src = void 0 }) => {
16332
- const router = useRouter();
16333
- const { locale } = router;
16334
- const variables = useInputVariablesFlat(vizId);
16335
- const block = useBlockRef(vizId).data;
16336
- const content = getBlockContent(block);
16337
- const formatterFunctions = useFormatterFunctionsForLocale(locale);
16338
- const blockContext = { variables };
16339
- const transpiledLogic = varSwapRecursive_default({ logic: content.logic }, formatterFunctions, blockContext).logic;
16340
- const globals = {
16341
- router
16342
- };
16343
- const props = d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, vizId, {}, globals);
16344
- const { title } = props.config;
16345
- return /* @__PURE__ */ jsxs(Stack, { align: "center", spacing: "xs", children: [
16346
- /* @__PURE__ */ jsx(
16347
- Image,
16348
- {
16349
- alt: `Viz ${vizId}`,
16350
- onClick,
16351
- style: {
16352
- cursor: "pointer",
16353
- border: isSelected ? "4px solid #228be6" : "4px solid #eee"
16354
- },
16355
- radius: 0,
16356
- src,
16357
- withPlaceholder: true
16358
- },
16359
- `viz-option-${vizId}`
16360
- ),
16361
- title && /* @__PURE__ */ jsx(
16362
- Text,
16363
- {
16364
- fz: "0.8rem",
16365
- fw: 700,
16366
- bg: isSelected ? "rgba(0, 0, 0, 0.2)" : "transparent",
16367
- w: "fit-content",
16368
- px: "xs",
16369
- sx: { borderRadius: "0.3rem" },
16370
- ta: "center",
16371
- children: title
16372
- }
16373
- )
16374
- ] });
16391
+ cleanDOM = () => {
16392
+ const sourceNodes = document.getElementsByClassName("bespoke-Viz-source");
16393
+ Array.from(sourceNodes).forEach((node) => node.remove());
16375
16394
  };
16376
- DEFAULT_TRANSLATIONS4 = {
16395
+ DEFAULT_TRANSLATIONS3 = {
16377
16396
  "wrong_node": "Wrong node in export",
16378
16397
  "choose_area": "Choose image area",
16379
16398
  "choose_viz": "Choose visualization",
@@ -16385,14 +16404,118 @@ var init_ImageTab = __esm({
16385
16404
  "viz_only": "Visualization only",
16386
16405
  "source": "Source: {src}"
16387
16406
  };
16388
- getSectionNode = (sectionId) => {
16389
- console.log({ sectionId });
16390
- const sectionNode = document.getElementById(sectionId);
16391
- return select(sectionNode).select(".bespoke-section-content").node();
16392
- };
16393
- getVizNode = (vizId, sectionId) => {
16394
- const sectionNode = getSectionNode(sectionId);
16395
- return select(sectionNode).select(`#bespoke-visualization-${vizId}.bespoke-block-area`).node();
16407
+ }
16408
+ });
16409
+ function CopyInput(props) {
16410
+ const { title, url, disabled = false } = props;
16411
+ const Icon = disabled ? IconCode : IconLink;
16412
+ return /* @__PURE__ */ jsx(Input.Wrapper, { label: title, children: /* @__PURE__ */ jsx(
16413
+ Input,
16414
+ {
16415
+ icon: /* @__PURE__ */ jsx(Icon, {}),
16416
+ value: url,
16417
+ disabled,
16418
+ readOnly: true,
16419
+ rightSection: /* @__PURE__ */ jsx(CopyButton, { value: url, timeout: 2e3, children: ({ copied, copy }) => /* @__PURE__ */ jsx(Tooltip, { label: copied ? "Copied" : "Copy", withArrow: true, position: "right", children: /* @__PURE__ */ jsx(ActionIcon, { variant: copied ? "filled" : "subtle", onClick: copy, disabled, children: copied ? /* @__PURE__ */ jsx(IconClipboardCheck, { size: 16 }) : /* @__PURE__ */ jsx(IconClipboardCopy, { size: 16 }) }) }) })
16420
+ }
16421
+ ) });
16422
+ }
16423
+ var init_CopyInput = __esm({
16424
+ "components/options/CopyInput.tsx"() {
16425
+ init_esm_shims();
16426
+ }
16427
+ });
16428
+ function ShareTab(props) {
16429
+ const { section } = props;
16430
+ const [shareUrl, setShareUrl] = useState("");
16431
+ const [title, setTitle] = useState("");
16432
+ const [includeSection, setIncludeSection] = useState(true);
16433
+ const optionsTranslations = useBespokeTranslations("options");
16434
+ const translations = { ...DEFAULT_TRANSLATIONS4, ...optionsTranslations["share_tab"] };
16435
+ useEffect(() => {
16436
+ setTitle(document.title);
16437
+ const { origin, pathname } = window.location;
16438
+ const url = `${origin}${pathname}`;
16439
+ const sectionAnchor = includeSection ? `#section-${section.id}` : "";
16440
+ setShareUrl(`${url}${sectionAnchor}`);
16441
+ }, [includeSection]);
16442
+ return /* @__PURE__ */ jsxs(Stack, { className: "cms-section-options-share", children: [
16443
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
16444
+ /* @__PURE__ */ jsx(CopyInput, { title: `${translations["title"]}: ${title}`, url: shareUrl }),
16445
+ /* @__PURE__ */ jsx(
16446
+ Checkbox,
16447
+ {
16448
+ checked: includeSection,
16449
+ label: translations["include_section"],
16450
+ onChange: () => setIncludeSection(!includeSection),
16451
+ radius: "xl"
16452
+ }
16453
+ ),
16454
+ /* @__PURE__ */ jsxs(Group, { position: "center", children: [
16455
+ /* @__PURE__ */ jsx(
16456
+ FacebookShareButton,
16457
+ {
16458
+ url: shareUrl,
16459
+ quote: title,
16460
+ children: /* @__PURE__ */ jsx(FacebookIcon, { size: 32, round: true })
16461
+ }
16462
+ ),
16463
+ /* @__PURE__ */ jsx(
16464
+ TwitterShareButton,
16465
+ {
16466
+ url: shareUrl,
16467
+ title,
16468
+ children: /* @__PURE__ */ jsx(TwitterIcon, { size: 32, round: true })
16469
+ }
16470
+ ),
16471
+ /* @__PURE__ */ jsx(
16472
+ TelegramShareButton,
16473
+ {
16474
+ url: shareUrl,
16475
+ title,
16476
+ children: /* @__PURE__ */ jsx(TelegramIcon, { size: 32, round: true })
16477
+ }
16478
+ ),
16479
+ /* @__PURE__ */ jsx(
16480
+ WhatsappShareButton,
16481
+ {
16482
+ url: shareUrl,
16483
+ title,
16484
+ separator: ":: ",
16485
+ children: /* @__PURE__ */ jsx(WhatsappIcon, { size: 32, round: true })
16486
+ }
16487
+ ),
16488
+ /* @__PURE__ */ jsx(LinkedinShareButton, { url: shareUrl, children: /* @__PURE__ */ jsx(LinkedinIcon, { size: 32, round: true }) }),
16489
+ /* @__PURE__ */ jsx(
16490
+ RedditShareButton,
16491
+ {
16492
+ url: shareUrl,
16493
+ title,
16494
+ windowWidth: 660,
16495
+ windowHeight: 460,
16496
+ children: /* @__PURE__ */ jsx(RedditIcon, { size: 32, round: true })
16497
+ }
16498
+ ),
16499
+ /* @__PURE__ */ jsx(
16500
+ EmailShareButton,
16501
+ {
16502
+ url: shareUrl,
16503
+ subject: title,
16504
+ children: /* @__PURE__ */ jsx(EmailIcon, { size: 32, round: true })
16505
+ }
16506
+ )
16507
+ ] })
16508
+ ] });
16509
+ }
16510
+ var DEFAULT_TRANSLATIONS4;
16511
+ var init_ShareTab = __esm({
16512
+ "components/options/tabs/ShareTab.tsx"() {
16513
+ init_esm_shims();
16514
+ init_CopyInput();
16515
+ init_TranslationsProvider();
16516
+ DEFAULT_TRANSLATIONS4 = {
16517
+ "title": "Title",
16518
+ "include_section": "Include Section"
16396
16519
  };
16397
16520
  }
16398
16521
  });
@@ -17192,7 +17315,7 @@ var init_site = __esm({
17192
17315
  }
17193
17316
  });
17194
17317
  function ImageCredits({ previews, translations }) {
17195
- const { isPrint } = useMode();
17318
+ const print = usePrint();
17196
17319
  const credits = useMemo(() => previews.map(
17197
17320
  ({ image, name }, idx) => (image?.author || image?.url) && /* @__PURE__ */ jsxs(Stack, { spacing: 0, children: [
17198
17321
  image.author && /* @__PURE__ */ jsxs(Text, { size: "xs", children: [
@@ -17217,7 +17340,7 @@ function ImageCredits({ previews, translations }) {
17217
17340
  idx + 1 < previews.length && /* @__PURE__ */ jsx(Divider, {})
17218
17341
  ] }, image.id)
17219
17342
  ), [previews]);
17220
- return /* @__PURE__ */ jsx(Fragment, { children: isPrint ? /* @__PURE__ */ jsx(Fragment, { children: credits }) : /* @__PURE__ */ jsxs(Popover, { position: "right", children: [
17343
+ return /* @__PURE__ */ jsx(Fragment, { children: print ? /* @__PURE__ */ jsx(Fragment, { children: credits }) : /* @__PURE__ */ jsxs(Popover, { position: "right", children: [
17221
17344
  /* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { variant: "light", radius: "xl", children: /* @__PURE__ */ jsx(IconPhoto, { size: 20 }) }) }),
17222
17345
  /* @__PURE__ */ jsx(Popover.Dropdown, { children: credits })
17223
17346
  ] }) });
@@ -17237,7 +17360,7 @@ function SectionWrapper({
17237
17360
  previews,
17238
17361
  translations
17239
17362
  }) {
17240
- const { isPrint, isEmbed } = useMode();
17363
+ const print = usePrint();
17241
17364
  const showCredits = sectionSettings2.memberImageBg && previews.some(({ image }) => image && (image.url || image.author));
17242
17365
  return /* @__PURE__ */ jsxs(
17243
17366
  PositionWrapper,
@@ -17253,12 +17376,12 @@ function SectionWrapper({
17253
17376
  className: `bespoke-Section-${id} bespoke-Section-container `,
17254
17377
  settings: sectionSettings2,
17255
17378
  styles: sectionStyles?.container,
17256
- id: slugify_default(name) || `section-${id}`,
17379
+ id: name || `section-${id}`,
17257
17380
  pos: "relative",
17258
17381
  children: [
17259
- !isPrint && /* @__PURE__ */ jsxs(Group, { position: "right", mb: "xs", children: [
17382
+ !print && /* @__PURE__ */ jsxs(Group, { position: "right", mb: "xs", children: [
17260
17383
  /* @__PURE__ */ jsx(SectionResetButton, { id }),
17261
- sectionSettings2.optionsMenu && !isEmbed && /* @__PURE__ */ jsx(Options, { sectionId: id, disabled: false })
17384
+ sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: id, disabled: false })
17262
17385
  ] }),
17263
17386
  /* @__PURE__ */ jsxs(
17264
17387
  StyleWrapper,
@@ -17285,21 +17408,14 @@ function Section({ section }) {
17285
17408
  ...defaultSectionSettings,
17286
17409
  ...settings
17287
17410
  };
17288
- const { query } = useRouter();
17289
17411
  const comparison = useComparison();
17290
- const { isEmbed } = useMode();
17291
17412
  const state = useAppSelector((state2) => state2);
17292
17413
  const status = useAppSelector((state2) => state2.variables.status);
17293
17414
  const previews = useAppSelector((state2) => state2.status.previews);
17294
17415
  const comparisonPreviews = comparison.active && comparison.status ? previews.concat(comparison.status?.previews || []) : previews;
17295
17416
  const sectionStyles = useBespokeStyles()["Section"];
17296
17417
  const blockRecords = selectBlockRecords(state);
17297
- let sectionBlocks = [];
17298
- if (isEmbed && query.viz) {
17299
- sectionBlocks = Object.values(blockRecords || {}).filter((d2) => d2.section_id === id && d2.id === Number(query.viz));
17300
- } else {
17301
- sectionBlocks = Object.values(blockRecords || {}).filter((d2) => d2.section_id === id);
17302
- }
17418
+ const sectionBlocks = Object.values(blockRecords || {}).filter((d2) => d2.section_id === id);
17303
17419
  const sectionTranslations = useBespokeTranslations("sections");
17304
17420
  const translations = { ...DEFAULT_TRANSLATIONS6, ...sectionTranslations };
17305
17421
  const allowedSection = sectionBlocks.some((b2) => {
@@ -17407,7 +17523,7 @@ function Section({ section }) {
17407
17523
  );
17408
17524
  });
17409
17525
  }
17410
- return /* @__PURE__ */ jsxs(
17526
+ return /* @__PURE__ */ jsx(
17411
17527
  SectionWrapper,
17412
17528
  {
17413
17529
  id,
@@ -17416,24 +17532,21 @@ function Section({ section }) {
17416
17532
  sectionSettings: sectionSettings2,
17417
17533
  sectionStyles,
17418
17534
  translations,
17419
- children: [
17420
- /* @__PURE__ */ jsx(
17421
- ColumnsWrapper,
17422
- {
17423
- containerProps: {
17424
- gap: sectionSettings2.columnGutter || "md",
17425
- wrap: comparison.active ? "nowrap" : "wrap",
17426
- sx: { zIndex: 20 }
17427
- },
17428
- children: sectionColumns
17429
- }
17430
- ),
17431
- isEmbed && /* @__PURE__ */ jsx(EmbedSectionSrc, {})
17432
- ]
17535
+ children: /* @__PURE__ */ jsx(
17536
+ ColumnsWrapper,
17537
+ {
17538
+ containerProps: {
17539
+ gap: sectionSettings2.columnGutter || "md",
17540
+ wrap: comparison.active ? "nowrap" : "wrap",
17541
+ sx: { zIndex: 20 }
17542
+ },
17543
+ children: sectionColumns
17544
+ }
17545
+ )
17433
17546
  }
17434
17547
  );
17435
17548
  }
17436
- var DEFAULT_TRANSLATIONS6, getStyles, PositionWrapper, WidthWrapper, StyleWrapper, EmbedSectionSrc, Section_default;
17549
+ var DEFAULT_TRANSLATIONS6, getStyles, PositionWrapper, WidthWrapper, StyleWrapper, Section_default;
17437
17550
  var init_Section = __esm({
17438
17551
  "frontend/components/report/Section.tsx"() {
17439
17552
  init_esm_shims();
@@ -17454,9 +17567,6 @@ var init_Section = __esm({
17454
17567
  init_TranslationsProvider();
17455
17568
  init_ImageCredits();
17456
17569
  init_ComparisonProvider();
17457
- init_ResourceProvider();
17458
- init_useLocalePrefix();
17459
- init_slugify();
17460
17570
  DEFAULT_TRANSLATIONS6 = {
17461
17571
  "image_by": "image by"
17462
17572
  };
@@ -17517,56 +17627,18 @@ var init_Section = __esm({
17517
17627
  const sx = [defaultStyles[variant], getStyles(styles, settings)];
17518
17628
  return /* @__PURE__ */ jsx(Paper, { sx, ...defaultProps2[variant], ...props, children });
17519
17629
  };
17520
- EmbedSectionSrc = () => {
17521
- const router = useRouter();
17522
- const { query, locale } = router;
17523
- const { siteProps, profilePrefix, pathSegment } = useBespoke();
17524
- const querySlugs = query[pathSegment];
17525
- const slugs = Array.isArray(querySlugs) ? querySlugs?.join("/") : [];
17526
- const prefixLocale = useLocalePrefix();
17527
- let path = prefixLocale ? `/${locale}` : "";
17528
- path += `/${profilePrefix}/${slugs}/`;
17529
- const link = new URL(path, window?.location.href).href;
17530
- return /* @__PURE__ */ jsxs(Group, { position: "apart", noWrap: true, sx: { flexGrow: 1 }, children: [
17531
- /* @__PURE__ */ jsx(Anchor, { href: link, target: "_blank", children: link }),
17532
- /* @__PURE__ */ jsx(
17533
- "img",
17534
- {
17535
- src: siteProps.logoSrc,
17536
- width: "auto",
17537
- height: 40,
17538
- alt: "Site Logo"
17539
- }
17540
- )
17541
- ] });
17542
- };
17543
17630
  Section_default = Section;
17544
17631
  }
17545
17632
  });
17546
- function useMode() {
17547
- const mode = useContext(ModeContext);
17548
- return {
17549
- mode,
17550
- isPrint: mode === MODES.print,
17551
- isEmbed: mode === MODES.embed,
17552
- isReport: mode === MODES.report
17553
- };
17633
+ function usePrint() {
17634
+ return useContext(PrintContext);
17554
17635
  }
17555
- function Report({ pathSegmentsKey = "bespoke", mode = "report" }) {
17556
- const router = useRouter();
17557
- const { asPath, query } = router;
17636
+ function Report({ pathSegmentsKey = "bespoke" }) {
17637
+ const { asPath, query } = useRouter();
17558
17638
  const sectionList = useSectionList();
17559
17639
  const comparison = useComparison();
17560
- const [reportMode, setReportMode] = useState(mode);
17561
- useEffect(() => {
17562
- if (router.isReady) {
17563
- const { mode: mode2 } = router.query;
17564
- if (mode2 && typeof mode2 === "string" && Object.values(MODES).includes(mode2)) {
17565
- setReportMode(mode2);
17566
- }
17567
- }
17568
- }, [router.isReady, router.query]);
17569
- const printBtn = yn4(router.query.printBtn) ?? false;
17640
+ const print = yn4(query.print) ?? false;
17641
+ const printBtn = yn4(query.printBtn) ?? false;
17570
17642
  const [downloadLoading, setDownloadLoading] = useState(false);
17571
17643
  const printReport = () => {
17572
17644
  setDownloadLoading(true);
@@ -17581,8 +17653,8 @@ function Report({ pathSegmentsKey = "bespoke", mode = "report" }) {
17581
17653
  });
17582
17654
  };
17583
17655
  useScrollToAnchor();
17584
- return /* @__PURE__ */ jsxs(ModeContext.Provider, { value: reportMode, children: [
17585
- mode === MODES.print && /* @__PURE__ */ jsx(MediaQuery, { query: "print", styles: { display: "block" }, children: /* @__PURE__ */ jsx(Title, { display: "none", children: "This is the report header" }) }),
17656
+ return /* @__PURE__ */ jsxs(PrintContext.Provider, { value: print, children: [
17657
+ print && /* @__PURE__ */ jsx(MediaQuery, { query: "print", styles: { display: "block" }, children: /* @__PURE__ */ jsx(Title, { display: "none", children: "This is the report header" }) }),
17586
17658
  /* @__PURE__ */ jsxs(Container, { id: "bespoke-report", className: comparison.comparisonLoaded ? "compare" : "", p: 0, pos: "relative", fluid: true, children: [
17587
17659
  sectionList.isSuccess && sectionList.data.sort(orderSort).map((section) => /* @__PURE__ */ jsx(Section_default, { section }, section.id)),
17588
17660
  /*pdf.active*/
@@ -17590,7 +17662,7 @@ function Report({ pathSegmentsKey = "bespoke", mode = "report" }) {
17590
17662
  ] })
17591
17663
  ] });
17592
17664
  }
17593
- var MODES, ModeContext, Report_default;
17665
+ var PrintContext, Report_default;
17594
17666
  var init_Report = __esm({
17595
17667
  "frontend/components/report/Report.tsx"() {
17596
17668
  init_esm_shims();
@@ -17599,12 +17671,7 @@ var init_Report = __esm({
17599
17671
  init_Section();
17600
17672
  init_ComparisonProvider();
17601
17673
  init_useScrollToAnchor();
17602
- MODES = {
17603
- report: "report",
17604
- print: "print",
17605
- embed: "embed"
17606
- };
17607
- ModeContext = createContext("report");
17674
+ PrintContext = createContext(false);
17608
17675
  Report_default = Report;
17609
17676
  }
17610
17677
  });
@@ -17730,7 +17797,7 @@ init_esm_shims();
17730
17797
  var UserProvider_default = UserProvider;
17731
17798
 
17732
17799
  // frontend/index.ts
17733
- init_hooks2();
17800
+ init_ExploreProvider();
17734
17801
 
17735
17802
  // frontend/components/auth/withPageRoleAuthRequired.tsx
17736
17803
  init_esm_shims();
@@ -18057,7 +18124,8 @@ function parseSearchMemberParams(query) {
18057
18124
  report,
18058
18125
  all: localeIsAll,
18059
18126
  sort: normalizeList(query.sort)[0],
18060
- direction: normalizeList(query.direction)[0]
18127
+ direction: normalizeList(query.direction)[0],
18128
+ offset: Number(query.offset || 0)
18061
18129
  };
18062
18130
  }
18063
18131
 
@@ -18318,7 +18386,7 @@ function VariantSelector(props) {
18318
18386
  const showAsLabel = variantsData.length === 1 || !active;
18319
18387
  const [_variant, setVariant] = useUncontrolled({
18320
18388
  value: value ? String(value) : void 0,
18321
- defaultValue: variantsData[0].value,
18389
+ defaultValue: variantsData[0] ? variantsData[0].value : "",
18322
18390
  finalValue: void 0,
18323
18391
  onChange: onChange ? (v2) => onChange(Number(v2)) : void 0
18324
18392
  });
@@ -18329,7 +18397,7 @@ function VariantSelector(props) {
18329
18397
  {
18330
18398
  onClick: () => setActive(true),
18331
18399
  clickable: variantsData.length > 1,
18332
- children: displayValue.label
18400
+ children: displayValue ? displayValue.label : "No Variant"
18333
18401
  }
18334
18402
  ) : /* @__PURE__ */ jsx(
18335
18403
  Select,
@@ -18357,7 +18425,7 @@ function DimensionAutocomplete(props) {
18357
18425
  const [_variant, setVariant] = useUncontrolled({
18358
18426
  value: void 0,
18359
18427
  defaultValue: value?.variantId,
18360
- finalValue: Number(variantsData[0].value),
18428
+ finalValue: variantsData[0] ? Number(variantsData[0].value) : 0,
18361
18429
  onChange: () => {
18362
18430
  setMember({});
18363
18431
  }
@@ -18734,6 +18802,18 @@ init_esm_shims();
18734
18802
  init_EntityDeleteButton();
18735
18803
  init_Dialog();
18736
18804
  init_store2();
18805
+
18806
+ // libs/settings/variant.tsx
18807
+ init_esm_shims();
18808
+ var getVariantSettingsDefaults = (settings) => ({
18809
+ overrideNames: settings && typeof settings.overrideNames !== "undefined" ? settings.overrideNames : false,
18810
+ overrideRelevance: settings && typeof settings.overrideRelevance !== "undefined" ? settings.overrideRelevance : false,
18811
+ regenerateSlugs: settings && typeof settings.regenerateSlugs !== "undefined" ? settings.regenerateSlugs : false,
18812
+ keepOldMembers: settings && typeof settings.keepOldMembers !== "undefined" ? settings.keepOldMembers : true,
18813
+ doIngest: settings && typeof settings.doIngest !== "undefined" ? settings.doIngest : false,
18814
+ overrideAttributes: settings && typeof settings.overrideAttributes !== "undefined" ? settings.overrideAttributes : false,
18815
+ order: settings && typeof settings.order !== "undefined" ? settings.order : 0
18816
+ });
18737
18817
  function VariantCard({ for: variant, onEdit }) {
18738
18818
  const theme = useMantineTheme();
18739
18819
  const { newConfirmation } = useDialog();
@@ -18750,13 +18830,18 @@ function VariantCard({ for: variant, onEdit }) {
18750
18830
  console.debug("Variant edition aborted.");
18751
18831
  }
18752
18832
  }, [onEdit]);
18753
- const { slug, name } = variant;
18833
+ const { slug, name, settings } = variant;
18834
+ const variantSettings = getVariantSettingsDefaults(settings);
18754
18835
  return /* @__PURE__ */ jsxs(Card, { shadow: "xs", withBorder: true, style: { margin: theme.spacing.sm }, children: [
18755
18836
  /* @__PURE__ */ jsxs(Group, { position: "apart", children: [
18756
18837
  /* @__PURE__ */ jsxs(Center, { children: [
18757
18838
  /* @__PURE__ */ jsx(IconServer, { size: 22 }),
18758
18839
  /* @__PURE__ */ jsx(Space, { w: "xs" }),
18759
- /* @__PURE__ */ jsx(Text, { weight: "bold", children: name })
18840
+ /* @__PURE__ */ jsx(Text, { weight: "bold", children: name }),
18841
+ /* @__PURE__ */ jsxs(Text, { size: "xs", ml: "xs", children: [
18842
+ "Order: ",
18843
+ variantSettings.order
18844
+ ] })
18760
18845
  ] }),
18761
18846
  /* @__PURE__ */ jsxs(Badge, { variant: "light", children: [
18762
18847
  "/",
@@ -19017,17 +19102,6 @@ function MembersTable({ members, onClickEdit, onSort, colsToRender = [], dataTab
19017
19102
  );
19018
19103
  }
19019
19104
 
19020
- // libs/settings/variant.tsx
19021
- init_esm_shims();
19022
- var getVariantSettingsDefaults = (settings) => ({
19023
- overrideNames: settings && typeof settings.overrideNames !== "undefined" ? settings.overrideNames : false,
19024
- overrideRelevance: settings && typeof settings.overrideRelevance !== "undefined" ? settings.overrideRelevance : false,
19025
- regenerateSlugs: settings && typeof settings.regenerateSlugs !== "undefined" ? settings.regenerateSlugs : false,
19026
- keepOldMembers: settings && typeof settings.keepOldMembers !== "undefined" ? settings.keepOldMembers : true,
19027
- doIngest: settings && typeof settings.doIngest !== "undefined" ? settings.doIngest : false,
19028
- overrideAttributes: settings && typeof settings.overrideAttributes !== "undefined" ? settings.overrideAttributes : false
19029
- });
19030
-
19031
19105
  // components/builder/components/SwitchWithTooltip.tsx
19032
19106
  init_esm_shims();
19033
19107
  function SwitchWithTooltip({ switchProps, yesText, noText }) {
@@ -19312,6 +19386,7 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
19312
19386
  };
19313
19387
  const onSubmit = () => {
19314
19388
  setLoading(true);
19389
+ console.log(variantConfig.settings);
19315
19390
  dispatch(actions_exports.updateEntity("variant", variantConfig)).then(() => {
19316
19391
  setLoading(false);
19317
19392
  closeHandler();
@@ -19415,6 +19490,19 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
19415
19490
  ] }) : false,
19416
19491
  onChange: (e) => onChange("slug", e.target.value)
19417
19492
  }
19493
+ ),
19494
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
19495
+ /* @__PURE__ */ jsx(
19496
+ NumberInput,
19497
+ {
19498
+ value: variantSettings.order || 0,
19499
+ description: "It affects on explore options order",
19500
+ placeholder: "Order",
19501
+ label: "Order",
19502
+ onChange: (v2) => {
19503
+ onChangeSettings("order", v2);
19504
+ }
19505
+ }
19418
19506
  )
19419
19507
  ] }),
19420
19508
  /* @__PURE__ */ jsxs(Tabs.Panel, { value: "members", py: "md", children: [
@@ -19770,11 +19858,23 @@ function ReportEditor({ id, onClose: closeHandler }) {
19770
19858
  const onChange = useCallback((field, value) => {
19771
19859
  setConfig({ ...config, [field]: value });
19772
19860
  }, []);
19861
+ const onChangeSettings = (field, value) => {
19862
+ setConfig({
19863
+ ...config,
19864
+ //config: configUpdate,
19865
+ settings: {
19866
+ ...config.settings,
19867
+ [field]: value
19868
+ }
19869
+ });
19870
+ };
19773
19871
  if (isEditing) {
19774
19872
  return /* @__PURE__ */ jsx(DimensionEditor, { id: isEditing, onClose: () => setEditing(null) });
19775
19873
  }
19776
19874
  const loading = ref.isFetching;
19777
19875
  const dimensions = ref.isSuccess ? ref.data.dimensions : [];
19876
+ const settings = config.settings;
19877
+ const order2 = settings && settings.order ? settings.order : 0;
19778
19878
  return /* @__PURE__ */ jsx(
19779
19879
  DrawerContentWithScroll,
19780
19880
  {
@@ -19789,7 +19889,20 @@ function ReportEditor({ id, onClose: closeHandler }) {
19789
19889
  onChange: (e) => onChange("name", e.target.value)
19790
19890
  }
19791
19891
  ),
19792
- /* @__PURE__ */ jsx(Divider, { my: "xl" }),
19892
+ /* @__PURE__ */ jsx(Divider, { my: "sm" }),
19893
+ /* @__PURE__ */ jsx(
19894
+ NumberInput,
19895
+ {
19896
+ value: order2 || 0,
19897
+ description: "It affects on explore options order",
19898
+ placeholder: "Order",
19899
+ label: "Order",
19900
+ onChange: (v2) => {
19901
+ onChangeSettings("order", v2);
19902
+ }
19903
+ }
19904
+ ),
19905
+ /* @__PURE__ */ jsx(Divider, { my: "sm" }),
19793
19906
  /* @__PURE__ */ jsx(IconTitle, { icon: /* @__PURE__ */ jsx(IconDatabase, { size: 22 }), children: /* @__PURE__ */ jsx(Title, { order: 2, size: "h4", children: "Dimensions" }) }),
19794
19907
  /* @__PURE__ */ jsx(Grid, { children: dimensions.map((d2) => /* @__PURE__ */ jsx(Grid.Col, { span: 6, children: /* @__PURE__ */ jsx(DimensionCardWithFetcher, { id: d2, onEdit: setEditing }) }, d2)) }),
19795
19908
  /* @__PURE__ */ jsx(
@@ -25844,16 +25957,15 @@ function BespokeRenderer({
25844
25957
  siteProps,
25845
25958
  profilePrefix = "/defaultPath",
25846
25959
  loader = /* @__PURE__ */ jsx(LoadingOverlay, { visible: true }),
25847
- mode = "report",
25848
25960
  mantineProviderProps = {}
25849
25961
  }) {
25850
- const loading = useInitialState(pathSegmentsKey, mode);
25962
+ const loading = useInitialState(pathSegmentsKey);
25851
25963
  if (loading)
25852
25964
  return /* @__PURE__ */ jsx(Fragment, { children: loader });
25853
- return /* @__PURE__ */ jsx(MantineProvider, { ...mantineProviderProps, theme: { other: { bespokeStyles } }, inherit: true, children: /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment: pathSegmentsKey, profilePrefix, siteProps, children: [
25854
- /* @__PURE__ */ jsx(TranslationsProvider, { translations, children: /* @__PURE__ */ jsx(ComparisonProvider, { children: /* @__PURE__ */ jsx(PdfProvider, { children: /* @__PURE__ */ jsx(Report_default, { pathSegmentsKey, mode }) }) }) }),
25855
- /* @__PURE__ */ jsx("small", { className: "bespoke-timestamp", hidden: true, children: buildTime })
25965
+ return /* @__PURE__ */ jsx(MantineProvider, { ...mantineProviderProps, theme: { other: { bespokeStyles } }, inherit: true, children: /* @__PURE__ */ jsxs(ResourceProvider, { pathSegment: "bespoke", profilePrefix, siteProps, children: [
25966
+ /* @__PURE__ */ jsx(TranslationsProvider, { translations, children: /* @__PURE__ */ jsx(ComparisonProvider, { children: /* @__PURE__ */ jsx(PdfProvider, { children: /* @__PURE__ */ jsx(Report_default, {}) }) }) }),
25967
+ /* @__PURE__ */ jsx("small", { className: "bespoke-timestamp", children: buildTime })
25856
25968
  ] }) });
25857
25969
  }
25858
25970
 
25859
- 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, useEmbed };
25971
+ export { Explore_default as BespokeExplore, ExploreModal_default as BespokeExploreModal, ExploreProvider as BespokeExploreProvider, 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, useExplore as useBespokeExplore, useAppSelector as useBespokeSelector, useUser_default as useBespokeUser, useDialog };