@datawheel/bespoke 0.1.31 → 0.1.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,11 +16,11 @@ 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, useMantineTheme, Flex, packSx, Tooltip, ActionIcon, Center, Modal, Button, SegmentedControl, Select, MultiSelect, Title, TextInput, Switch, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container, Loader, Alert, Collapse, Card, Space, Code, Textarea, rem, Paper, Grid, Input, Popover, Checkbox, Radio, Drawer, Overlay, SimpleGrid, Autocomplete, Tabs, Header, px, Image, FileInput, Accordion, HoverCard, CopyButton, NumberInput, Col } from '@mantine/core';
19
+ import { Stack, Text, Badge, Group, useMantineTheme, Flex, packSx, Title, Tooltip, ActionIcon, Center, Modal, Button, SegmentedControl, Select, MultiSelect, TextInput, Switch, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container, Loader, Alert, Collapse, Card, Space, Code, Textarea, rem, Paper, Grid, Input, Popover, Checkbox, Radio, Drawer, Overlay, SimpleGrid, Autocomplete, Tabs, Header, px, Image, FileInput, Accordion, HoverCard, CopyButton, NumberInput, Col } from '@mantine/core';
20
20
  import { dataConcat } from 'd3plus-viz';
21
21
  import * as d3plus from 'd3plus-react';
22
22
  import Router, { useRouter } from 'next/router';
23
- import { IconInfoCircle, IconRefresh, IconSearch, IconAlignLeft, IconAlignCenter, IconAlignRight, IconBoxMargin, IconTable, IconMathFunction, IconUsers, IconLogout, IconTrash, IconUserCircle, IconEdit, IconDatabase, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconAlarmFilled, IconBox, IconLink, IconCircleX, IconFlag, IconCirclePlus, IconFileAnalytics, IconPlus, IconX, IconChevronDown, IconCamera, IconShare, IconCircleDashed, IconListSearch, IconExternalLink, IconSettings, IconFileOff, IconFilesOff, IconHierarchy3, IconMenu, IconPolaroid, IconCircleMinus, IconEyeOff, IconChevronLeft, IconChevronRight, IconLogin, IconWorld, IconLock, IconVariable, IconArrowRightCircle, IconDownload, IconTemplate, IconChartBar, IconCode, IconUpload, IconCodePlus, IconClipboardCheck, IconClipboardCopy, IconPalette, IconEye, IconMinimize, IconMaximize, IconRss, IconGlobe } from '@tabler/icons-react';
23
+ import { IconInfoCircle, IconRefresh, IconSearch, IconAlignLeft, IconAlignCenter, IconAlignRight, IconBoxMargin, IconTable, IconMathFunction, IconUsers, IconLogout, IconTrash, IconUserCircle, IconEdit, IconDatabase, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconAlarmFilled, IconBox, IconLink, IconCircleX, IconFlag, IconCirclePlus, IconFileAnalytics, IconPlus, IconX, IconChevronDown, IconCamera, IconShare, IconCircleDashed, IconListSearch, IconExternalLink, IconSettings, IconFileOff, IconFilesOff, IconHierarchy3, IconMenu, IconApi, IconPolaroid, IconCircleMinus, IconEyeOff, IconChevronLeft, IconChevronRight, IconLogin, IconWorld, IconLock, IconVariable, IconArrowRightCircle, IconDownload, IconTemplate, IconChartBar, IconCode, IconUpload, IconCodePlus, IconClipboardCheck, IconClipboardCopy, IconPalette, IconEye, IconMinimize, IconMaximize, IconRss, IconGlobe } from '@tabler/icons-react';
24
24
  import { useMediaQuery, useDisclosure, useDebouncedValue, useHotkeys, useFullscreen, getHotkeyHandler } from '@mantine/hooks';
25
25
  import dynamic from 'next/dynamic';
26
26
  import Link from 'next/link';
@@ -1302,7 +1302,6 @@ var init_runConsumers = __esm({
1302
1302
  );
1303
1303
  if (inputNotAllowed) {
1304
1304
  statusById[bid2] = {
1305
- log: [],
1306
1305
  allowed: false,
1307
1306
  hiddenByCascade: statusById[inputNotAllowed].hiddenByCascade || inputNotAllowed
1308
1307
  };
@@ -1318,8 +1317,12 @@ var init_runConsumers = __esm({
1318
1317
  },
1319
1318
  readMemberFn
1320
1319
  ).then(({ outputVariables, status }) => {
1321
- variablesById[bid2] = outputVariables;
1322
- statusById[bid2] = status;
1320
+ if (
1321
+ // store output variables for block that:
1322
+ block.consumers.length > 0 && status.allowed && Object.keys(outputVariables).length > 0
1323
+ )
1324
+ variablesById[bid2] = outputVariables;
1325
+ statusById[bid2] = mode === "report" ? { allowed: status.allowed } : status;
1323
1326
  });
1324
1327
  const endBlock = /* @__PURE__ */ new Date();
1325
1328
  const blockTime = (endBlock.getTime() - startBlock.getTime()) / 1e3;
@@ -1873,15 +1876,12 @@ var init_recordsSlice = __esm({
1873
1876
  */
1874
1877
  setReadRequest(state, action) {
1875
1878
  const req = action.payload;
1876
- state.requests[req.type][req.key] = req;
1879
+ if (req.type !== "report")
1880
+ state.requests[req.type][req.key] = req;
1877
1881
  if (req.status === "SUCCESS" /* SUCCESS */) {
1878
1882
  const newEntities = normalizeEntity(req.type, req.data);
1879
1883
  const nextEntities = combineRecords(state.entities, newEntities);
1880
1884
  state.entities = nextEntities;
1881
- if (req.type === "report") {
1882
- state.reports = Object.values(nextEntities.report).map((item) => item.id);
1883
- state.tree = req.data;
1884
- }
1885
1885
  }
1886
1886
  },
1887
1887
  /**
@@ -2929,38 +2929,51 @@ function Viz(config) {
2929
2929
  const Visualization = vizTypes[fallbackType];
2930
2930
  const { _data, ...vizPropsConfig } = vizProps.config;
2931
2931
  const vizConfig = { locale, variables, ...vizPropsConfig, ...configOverride };
2932
- return /* @__PURE__ */ jsx(
2933
- "div",
2934
- {
2935
- style: {
2936
- display: "flex",
2937
- flex: "1 1 100%",
2938
- minHeight: 400
2939
- },
2940
- children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx("p", { children: "Error in d3plus viz config." }), children: /* @__PURE__ */ jsx(
2941
- Visualization,
2942
- {
2943
- style: { flex: 1 },
2944
- dataFormat: (resp) => {
2945
- vizProps.data && Array.isArray(vizProps.data) && vizProps.data.length > 1 && vizProps.data.some((d) => typeof d === "string");
2946
- let data;
2947
- try {
2948
- data = vizProps.dataFormat(resp);
2949
- } catch (e) {
2950
- console.log("Error in dataFormat: ", e);
2951
- data = [];
2952
- }
2953
- return data;
2954
- },
2955
- linksFormat: vizProps.linksFormat,
2956
- nodesFormat: vizProps.nodesFormat,
2957
- topojsonFormat: vizProps.topojsonFormat,
2958
- config: { ...defaultConfig_default, ...vizConfig, sectionVariables: sectionVariablesStr }
2932
+ const { title } = vizConfig;
2933
+ return /* @__PURE__ */ jsxs("div", { className: "bespoke-Viz", children: [
2934
+ title && /* @__PURE__ */ jsx(
2935
+ Title,
2936
+ {
2937
+ className: "bespoke-Viz-title",
2938
+ order: 4,
2939
+ size: "h6",
2940
+ align: "center",
2941
+ dangerouslySetInnerHTML: { __html: title }
2942
+ }
2943
+ ),
2944
+ /* @__PURE__ */ jsx(
2945
+ "div",
2946
+ {
2947
+ style: {
2948
+ display: "flex",
2949
+ flex: "1 1 100%",
2950
+ minHeight: 400
2959
2951
  },
2960
- "viz-key"
2961
- ) })
2962
- }
2963
- );
2952
+ children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx("p", { children: "Error in d3plus viz config." }), children: /* @__PURE__ */ jsx(
2953
+ Visualization,
2954
+ {
2955
+ style: { flex: 1 },
2956
+ dataFormat: (resp) => {
2957
+ vizProps.data && Array.isArray(vizProps.data) && vizProps.data.length > 1 && vizProps.data.some((d) => typeof d === "string");
2958
+ let data;
2959
+ try {
2960
+ data = vizProps.dataFormat(resp);
2961
+ } catch (e) {
2962
+ console.log("Error in dataFormat: ", e);
2963
+ data = [];
2964
+ }
2965
+ return data;
2966
+ },
2967
+ linksFormat: vizProps.linksFormat,
2968
+ nodesFormat: vizProps.nodesFormat,
2969
+ topojsonFormat: vizProps.topojsonFormat,
2970
+ config: { ...defaultConfig_default, ...vizConfig, sectionVariables: sectionVariablesStr, title: void 0 }
2971
+ },
2972
+ "viz-key"
2973
+ ) })
2974
+ }
2975
+ )
2976
+ ] });
2964
2977
  }
2965
2978
  var vizTypes;
2966
2979
  var init_Viz = __esm({
@@ -5164,11 +5177,16 @@ function InputMenuItem({
5164
5177
  ] }) }) });
5165
5178
  }
5166
5179
  var InputMenuItem_default = InputMenuItem;
5167
- function Generator2({ outputVariables, debug: debug2 }) {
5168
- return debug2 ? /* @__PURE__ */ jsxs(Fragment, { children: [
5180
+ function Generator2({ outputVariables, status, hasAPI = false, debug: debug2 }) {
5181
+ const loading = hasAPI && !Object.keys(outputVariables).length && !status.error;
5182
+ const preview = loading ? /* @__PURE__ */ jsxs(Stack, { align: "center", children: [
5183
+ /* @__PURE__ */ jsx(Loader, {}),
5184
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: "Loading Generator" })
5185
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
5169
5186
  /* @__PURE__ */ jsx(Divider, { label: "Output Variables", labelPosition: "center" }),
5170
5187
  /* @__PURE__ */ jsx(InputMenuItem_default, { variables: outputVariables })
5171
- ] }) : /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: "GENERATOR" }, "type") });
5188
+ ] });
5189
+ return debug2 ? preview : /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: "GENERATOR" }, "type") });
5172
5190
  }
5173
5191
  var Generator_default = Generator2;
5174
5192
 
@@ -5601,35 +5619,50 @@ function SectionBackground() {
5601
5619
  key: member ? `bg-${member.content_id}` : `bg-${ix}`,
5602
5620
  src: member ? `/api/cms/member/image.png?member=${member.content_id}&size=splash` : ""
5603
5621
  }));
5604
- return /* @__PURE__ */ jsx(
5605
- Group,
5606
- {
5607
- className: "cms-section-bg",
5608
- grow: true,
5609
- spacing: 0,
5610
- style: {
5611
- background: "white",
5612
- position: "absolute",
5613
- width: "100%",
5614
- height: "100%",
5615
- opacity: 0.5
5616
- },
5617
- children: images.map((image) => /* @__PURE__ */ jsx(
5618
- "div",
5619
- {
5620
- className: "cms-section-member-bg",
5621
- style: {
5622
- backgroundImage: `url(${image.src})`,
5623
- backgroundSize: "cover",
5624
- backgroundPosition: "center center",
5625
- height: "100%",
5626
- width: "100%"
5627
- }
5622
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5623
+ /* @__PURE__ */ jsx(
5624
+ "div",
5625
+ {
5626
+ className: "cms-section-gradient-bg",
5627
+ style: {
5628
+ background: "white",
5629
+ position: "absolute",
5630
+ width: "100%",
5631
+ height: "100%",
5632
+ opacity: 0.33,
5633
+ zIndex: 1
5634
+ }
5635
+ }
5636
+ ),
5637
+ /* @__PURE__ */ jsx(
5638
+ Group,
5639
+ {
5640
+ className: "cms-section-bg",
5641
+ grow: true,
5642
+ spacing: 0,
5643
+ style: {
5644
+ position: "absolute",
5645
+ width: "100%",
5646
+ height: "100%",
5647
+ zIndex: 0
5628
5648
  },
5629
- image.key
5630
- ))
5631
- }
5632
- );
5649
+ children: images.map((image) => /* @__PURE__ */ jsx(
5650
+ "div",
5651
+ {
5652
+ className: "cms-section-member-bg",
5653
+ style: {
5654
+ backgroundImage: `url(${image.src})`,
5655
+ backgroundSize: "cover",
5656
+ backgroundPosition: "center center",
5657
+ height: "100%",
5658
+ width: "100%"
5659
+ }
5660
+ },
5661
+ image.key
5662
+ ))
5663
+ }
5664
+ )
5665
+ ] });
5633
5666
  }
5634
5667
 
5635
5668
  // components/options/Options.tsx
@@ -7016,8 +7049,8 @@ var PositionWrapper = ({ settings, styles, children, ...props }) => {
7016
7049
  var WidthWrapper = ({ settings, styles, children, ...props }) => {
7017
7050
  const { width: container } = settings;
7018
7051
  const defaultStyles = {
7019
- "center": {},
7020
- "full": {}
7052
+ "center": { zIndex: 1 },
7053
+ "full": { zIndex: 1 }
7021
7054
  };
7022
7055
  const defaultProps = {
7023
7056
  "center": { size: "lg", p: "sm", fluid: false },
@@ -7057,7 +7090,7 @@ function Section({ section }) {
7057
7090
  return b.settings.allowed === "always";
7058
7091
  }
7059
7092
  });
7060
- const columns = sectionBlocks.reduce((acc, d) => {
7093
+ const columns = sectionBlocks.filter((d) => d.type !== BLOCK_TYPES.GENERATOR).reduce((acc, d) => {
7061
7094
  if (!acc[d.blockcol]) {
7062
7095
  acc[d.blockcol] = { [d.blockrow]: d };
7063
7096
  } else {
@@ -7073,6 +7106,7 @@ function Section({ section }) {
7073
7106
  return /* @__PURE__ */ jsxs(
7074
7107
  PositionWrapper,
7075
7108
  {
7109
+ className: `bespoke-Section-${id} bespoke-Section-root `,
7076
7110
  settings: sectionSettings2,
7077
7111
  styles: sectionStyles?.root || void 0,
7078
7112
  children: [
@@ -7080,6 +7114,7 @@ function Section({ section }) {
7080
7114
  /* @__PURE__ */ jsxs(
7081
7115
  WidthWrapper,
7082
7116
  {
7117
+ className: `bespoke-Section-${id} bespoke-Section-container `,
7083
7118
  settings: sectionSettings2,
7084
7119
  styles: sectionStyles?.container,
7085
7120
  id: `section-${id}`,
@@ -7089,34 +7124,52 @@ function Section({ section }) {
7089
7124
  /* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
7090
7125
  sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: section.id })
7091
7126
  ] }),
7092
- /* @__PURE__ */ jsx(StyleWrapper, { className: "bespoke-section-content", settings: sectionSettings2, styles: sectionStyles?.content, children: /* @__PURE__ */ jsx(ColumnsWrapper, { children: Object.keys(columns).sort((a, b) => orderSort(a, b, "blockcol")).map((columnIndex) => {
7093
- const column = columns[columnIndex];
7094
- const columnSettings = settings.columnSettings ? settings.columnSettings[columnIndex] : {};
7095
- return /* @__PURE__ */ jsx(
7096
- SectionColumn,
7097
- {
7098
- column,
7099
- columnSettings,
7100
- sx: { flexBasis: `${100 / colsQty}%` },
7101
- children: Object.values(column).sort((a, b) => orderSort(a, b, "blockrow")).map((item) => {
7102
- if (!item.id)
7103
- return null;
7104
- const { settings: settings2, type } = blockRecords[item.id];
7105
- const blockWidth = settings2.width && !settings2.width.stretch && settings2.width.unit ? formatters[settings2.width.unit](settings2.width.value) : settings2.display === "inline" ? "auto" : "100%";
7106
- const blockStyles = {
7107
- alignSelf: type === "visualization" ? "stretch" : "flex-start",
7108
- flexGrow: 0,
7109
- margin: "0",
7110
- textAlign: settings2.align || blockSettings.align.defaultValue,
7111
- width: blockWidth,
7112
- minWidth: 300
7113
- };
7114
- return /* @__PURE__ */ jsx(Box, { sx: blockStyles, py: site_default.block.padding, children: /* @__PURE__ */ jsx(Block, { blockId: item.id }, item.id) }, item.id);
7115
- })
7116
- },
7117
- columnIndex
7118
- );
7119
- }) }) })
7127
+ /* @__PURE__ */ jsx(
7128
+ StyleWrapper,
7129
+ {
7130
+ className: `bespoke-Section-${id} bespoke-Section-container`,
7131
+ settings: sectionSettings2,
7132
+ styles: sectionStyles?.content,
7133
+ children: /* @__PURE__ */ jsx(ColumnsWrapper, { children: Object.keys(columns).sort((a, b) => orderSort(a, b, "blockcol")).map((columnIndex) => {
7134
+ const column = columns[columnIndex];
7135
+ const columnSettings = settings.columnSettings ? settings.columnSettings[columnIndex] : {};
7136
+ return /* @__PURE__ */ jsx(
7137
+ SectionColumn,
7138
+ {
7139
+ column,
7140
+ columnSettings,
7141
+ sx: { flexBasis: `${100 / colsQty}%` },
7142
+ children: Object.values(column).sort((a, b) => orderSort(a, b, "blockrow")).map((item) => {
7143
+ if (!item.id || !status[item.id].allowed)
7144
+ return null;
7145
+ const { settings: settings2, type } = blockRecords[item.id];
7146
+ const blockWidth = settings2.width && !settings2.width.stretch && settings2.width.unit ? formatters[settings2.width.unit](settings2.width.value) : settings2.display === "inline" ? "auto" : "100%";
7147
+ const blockStyles = {
7148
+ alignSelf: type === "visualization" ? "stretch" : "flex-start",
7149
+ flexGrow: 0,
7150
+ margin: "0",
7151
+ textAlign: settings2.align || blockSettings.align.defaultValue,
7152
+ width: blockWidth,
7153
+ minWidth: 300
7154
+ };
7155
+ return /* @__PURE__ */ jsx(
7156
+ Box,
7157
+ {
7158
+ className: "bespoke-Block-wrapper",
7159
+ id: `bespoke-Block-${item.id}`,
7160
+ sx: blockStyles,
7161
+ py: site_default.block.padding,
7162
+ children: /* @__PURE__ */ jsx(Block, { blockId: item.id }, item.id)
7163
+ },
7164
+ item.id
7165
+ );
7166
+ })
7167
+ },
7168
+ columnIndex
7169
+ );
7170
+ }) })
7171
+ }
7172
+ )
7120
7173
  ]
7121
7174
  }
7122
7175
  )
@@ -9082,7 +9135,8 @@ function BlockPreview(props) {
9082
9135
  return;
9083
9136
  }
9084
9137
  if (block.type === BLOCK_TYPES.GENERATOR) {
9085
- setContent({ outputVariables: generatorVariables });
9138
+ const hasAPI = Boolean(block.contentByLocale?.logic?.content?.api);
9139
+ setContent({ outputVariables: generatorVariables, hasAPI });
9086
9140
  setStatus2(generatorStatus);
9087
9141
  return;
9088
9142
  }
@@ -9140,7 +9194,7 @@ function BlockPreview(props) {
9140
9194
  style: { width: "100%", minHeight: block.type === BLOCK_TYPES.VIZ ? 400 : "auto" },
9141
9195
  children: [
9142
9196
  !allowed && allowedOverlay,
9143
- Renderer ? /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Renderer, { id: block.id, debug: debug2, ...content, settings: block.settings }) }, "renderer") : /* @__PURE__ */ jsx(Center, { style: { minHeight: 100 }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: block.type }, "type") }),
9197
+ Renderer ? /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Renderer, { id: block.id, debug: debug2, ...content, settings: block.settings, status }) }, "renderer") : /* @__PURE__ */ jsx(Center, { style: { minHeight: 100 }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: block.type }, "type") }),
9144
9198
  debug2 && textLog && /* @__PURE__ */ jsx(
9145
9199
  Textarea,
9146
9200
  {
@@ -10308,6 +10362,28 @@ init_getBlockContent();
10308
10362
 
10309
10363
  // components/sections/SectionHeader.tsx
10310
10364
  init_esm_shims();
10365
+ init_store2();
10366
+ init_cms();
10367
+ init_getBlockContent();
10368
+ function AddGeneratorButton({ section_id, onCreate = () => {
10369
+ } }) {
10370
+ const dispatch = useAppDispatch();
10371
+ const createGenerator = () => {
10372
+ const { locales: locales4 } = getLocaleDerived({ type: BLOCK_TYPES.GENERATOR });
10373
+ dispatch(actions_exports.createEntity("block", {
10374
+ blockrow: void 0,
10375
+ blockcol: void 0,
10376
+ type: BLOCK_TYPES.GENERATOR,
10377
+ section_id,
10378
+ locales: locales4
10379
+ }));
10380
+ onCreate();
10381
+ };
10382
+ return /* @__PURE__ */ jsxs(Group, { spacing: "xs", ml: "sm", children: [
10383
+ /* @__PURE__ */ jsx(ActionIcon, { color: "blue", size: "xs", radius: "lg", variant: "light", onClick: createGenerator, children: /* @__PURE__ */ jsx(IconApi, { size: "0.8rem" }) }),
10384
+ /* @__PURE__ */ jsx(Text, { size: "xs", c: "dimmed", onClick: createGenerator, children: "Add generator" })
10385
+ ] });
10386
+ }
10311
10387
  function SectionHeader({
10312
10388
  active,
10313
10389
  isDragging,
@@ -10329,18 +10405,35 @@ function SectionHeader({
10329
10405
  id || "hello"
10330
10406
  ] }, "s1"),
10331
10407
  /* @__PURE__ */ jsx(ActionIcon, { ...dragHandleProps, children: /* @__PURE__ */ jsx(IconMenu, { size: 16 }) }, "b1"),
10332
- /* @__PURE__ */ jsx(
10408
+ generators.hasGenerators && active && /* @__PURE__ */ jsx(
10333
10409
  Switch,
10334
10410
  {
10335
10411
  size: "xs",
10336
- label: "Show generators",
10412
+ label: /* @__PURE__ */ jsxs(Text, { c: "dimmed", size: "xs", children: [
10413
+ generators.showGenerators ? "Hide" : "Show",
10414
+ " generators"
10415
+ ] }),
10337
10416
  color: "green",
10338
10417
  checked: generators.showGenerators,
10418
+ onLabel: /* @__PURE__ */ jsx(IconApi, { size: "0.8rem" }),
10419
+ offLabel: /* @__PURE__ */ jsx(IconApi, { size: "0.8rem" }),
10339
10420
  onChange: (e) => generators.setShowGenerators(e.currentTarget.checked)
10340
10421
  }
10341
- )
10422
+ ),
10423
+ (!generators.hasGenerators || generators.showGenerators) && active && /* @__PURE__ */ jsx(AddGeneratorButton, { section_id: id, onCreate: () => generators.setShowGenerators(true) })
10342
10424
  ] }),
10343
- hidden && /* @__PURE__ */ jsx(Text, { size: "xs", fw: 600, color: "dark.3", children: "Section will be hidden on the frontend" }),
10425
+ hidden && /* @__PURE__ */ jsx(
10426
+ Text,
10427
+ {
10428
+ size: "xs",
10429
+ fw: 600,
10430
+ pos: "absolute",
10431
+ sx: { transform: "translateX(-50%)" },
10432
+ left: "50%",
10433
+ color: "dark.3",
10434
+ children: "Section will be hidden on the frontend"
10435
+ }
10436
+ ),
10344
10437
  /* @__PURE__ */ jsx(SectionMenu_default, { sectionId: id })
10345
10438
  ]
10346
10439
  }
@@ -10377,7 +10470,7 @@ var CreateBlockButton = ({ columns, columnIndex, section }) => {
10377
10470
  type: "select",
10378
10471
  name: "type",
10379
10472
  label: "Block Type",
10380
- options: blockTypes.map((d) => ({ label: d, value: d }))
10473
+ options: blockTypes.filter((d) => d !== BLOCK_TYPES.GENERATOR).map((d) => ({ label: d, value: d }))
10381
10474
  }],
10382
10475
  onSubmit: (value) => addBlock(value.type, columnIndex),
10383
10476
  target: /* @__PURE__ */ jsx(ActionIcon, { size: "md", radius: "lg", children: /* @__PURE__ */ jsx(IconCirclePlus, { size: 20 }) })
@@ -10434,21 +10527,29 @@ var ClickToEditOverlay = ({ onActivate, section, show = false }) => {
10434
10527
  );
10435
10528
  };
10436
10529
  var GeneratorsPanel = ({ generators, show = false }) => {
10437
- return /* @__PURE__ */ jsxs(Collapse, { in: show, p: "sm", children: [
10438
- /* @__PURE__ */ jsx(Title, { order: 5, align: "center", children: "Generators" }),
10439
- /* @__PURE__ */ jsx(
10440
- SimpleGrid,
10441
- {
10442
- cols: generators.length > 3 ? 3 : generators.length,
10443
- breakpoints: [
10444
- { maxWidth: "md", cols: 3, spacing: "md" },
10445
- { maxWidth: "sm", cols: 2, spacing: "sm" },
10446
- { maxWidth: "xs", cols: 1, spacing: "sm" }
10447
- ],
10448
- children: generators
10449
- }
10450
- )
10451
- ] });
10530
+ return /* @__PURE__ */ jsx(Collapse, { in: show, p: "sm", children: /* @__PURE__ */ jsx(
10531
+ Box,
10532
+ {
10533
+ sx: (theme) => ({
10534
+ backgroundColor: theme.colors.gray[1],
10535
+ padding: theme.spacing.xl,
10536
+ borderRadius: theme.radius.md
10537
+ }),
10538
+ children: /* @__PURE__ */ jsx(
10539
+ SimpleGrid,
10540
+ {
10541
+ cols: generators.length > 3 ? 3 : generators.length,
10542
+ mt: "md",
10543
+ breakpoints: [
10544
+ { maxWidth: "md", cols: 3, spacing: "md" },
10545
+ { maxWidth: "sm", cols: 2, spacing: "sm" },
10546
+ { maxWidth: "xs", cols: 1, spacing: "sm" }
10547
+ ],
10548
+ children: generators
10549
+ }
10550
+ )
10551
+ }
10552
+ ) });
10452
10553
  };
10453
10554
  function SectionEditor({
10454
10555
  for: section,
@@ -10542,134 +10643,144 @@ function SectionEditor({
10542
10643
  dragHandleProps,
10543
10644
  generators: {
10544
10645
  showGenerators,
10545
- setShowGenerators
10646
+ setShowGenerators,
10647
+ hasGenerators: Boolean(generators.length)
10546
10648
  }
10547
10649
  }
10548
10650
  ),
10549
- memberImageBg && /* @__PURE__ */ jsx(SectionBackground, {}),
10550
- optionsMenu && /* @__PURE__ */ jsxs(Flex, { justify: "flex-end", mx: 16, align: "center", gap: "xs", children: [
10551
- /* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
10552
- /* @__PURE__ */ jsx(Options, { sectionId: section.id })
10553
- ] }),
10554
- /* @__PURE__ */ jsx(
10555
- GeneratorsPanel,
10556
- {
10557
- show: showGenerators,
10558
- generators: generators.map((item) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
10559
- BlockElement_default,
10560
- {
10561
- id: Number(item.id),
10562
- active: isActive,
10563
- isInput: inputs.includes(Number(item.id)),
10564
- isConsumer: consumers.includes(Number(item.id)),
10565
- setHoverBlock
10566
- }
10567
- ) }, `block-${item.id}`))
10568
- }
10569
- ),
10570
- /* @__PURE__ */ jsxs(
10571
- ColumnsWrapper,
10572
- {
10573
- ref: columnContainer,
10574
- containerProps: {
10575
- mih: !isActive || !columnsQty ? 120 : "none",
10576
- p: "md"
10577
- },
10578
- children: [
10579
- /* @__PURE__ */ jsxs(DragDropContext, { onDragEnd, onDragStart, children: [
10580
- orderedCols.map((columnIndex) => {
10581
- const orderedBlocks = Object.values(columns[columnIndex]).sort((a, b) => orderSort(a, b, "blockrow"));
10582
- return /* @__PURE__ */ jsx(Droppable, { droppableId: columnIndex, children: (provided, snapshot) => /* @__PURE__ */ jsxs(
10583
- SectionColumn,
10584
- {
10585
- column: columns[columnIndex],
10586
- columnSettings: columnSettings[columnIndex],
10587
- ref: provided.innerRef,
10588
- sx: {
10589
- // extra styles for columns on editor
10590
- flexBasis: `${100 / columnsQty}%`,
10591
- background: snapshot.isDraggingOver ? theme.colors[theme.primaryColor][0] : "inherit",
10592
- border: "1px solid transparent",
10593
- "& .bespoke-resize-col": {
10594
- visibility: "hidden"
10595
- },
10596
- "&:hover .bespoke-resize-col": {
10597
- visibility: "visible"
10598
- },
10599
- "&:hover": {
10600
- border: `1px solid ${theme.colors.teal[1]}`
10601
- }
10602
- },
10603
- ...provided.droppableProps,
10604
- children: [
10605
- /* @__PURE__ */ jsx(
10606
- ResizeColumnInput,
10607
- {
10608
- sectionId: section.id,
10609
- columnIndex
10651
+ /* @__PURE__ */ jsxs(Box, { pos: "relative", children: [
10652
+ optionsMenu && /* @__PURE__ */ jsxs(Flex, { justify: "flex-end", mx: 16, align: "center", gap: "xs", children: [
10653
+ /* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
10654
+ /* @__PURE__ */ jsx(Options, { sectionId: section.id })
10655
+ ] }),
10656
+ /* @__PURE__ */ jsx(
10657
+ GeneratorsPanel,
10658
+ {
10659
+ show: showGenerators && Boolean(generators.length),
10660
+ generators: generators.map((item) => /* @__PURE__ */ jsxs("div", { children: [
10661
+ /* @__PURE__ */ jsxs(Title, { order: 6, children: [
10662
+ "Generator ",
10663
+ item.id
10664
+ ] }),
10665
+ /* @__PURE__ */ jsx(
10666
+ BlockElement_default,
10667
+ {
10668
+ id: Number(item.id),
10669
+ active: isActive,
10670
+ isInput: inputs.includes(Number(item.id)),
10671
+ isConsumer: consumers.includes(Number(item.id)),
10672
+ setHoverBlock
10673
+ }
10674
+ )
10675
+ ] }, `block-${item.id}`))
10676
+ }
10677
+ ),
10678
+ memberImageBg && /* @__PURE__ */ jsx(SectionBackground, {}),
10679
+ /* @__PURE__ */ jsxs(
10680
+ ColumnsWrapper,
10681
+ {
10682
+ ref: columnContainer,
10683
+ containerProps: {
10684
+ mih: !isActive || !columnsQty ? 120 : "none",
10685
+ p: "md",
10686
+ style: { zIndex: 1 }
10687
+ },
10688
+ children: [
10689
+ /* @__PURE__ */ jsxs(DragDropContext, { onDragEnd, onDragStart, children: [
10690
+ orderedCols.map((columnIndex) => {
10691
+ const orderedBlocks = Object.values(columns[columnIndex]).sort((a, b) => orderSort(a, b, "blockrow"));
10692
+ return /* @__PURE__ */ jsx(Droppable, { droppableId: columnIndex, children: (provided, snapshot) => /* @__PURE__ */ jsxs(
10693
+ SectionColumn,
10694
+ {
10695
+ column: columns[columnIndex],
10696
+ columnSettings: columnSettings[columnIndex],
10697
+ ref: provided.innerRef,
10698
+ sx: {
10699
+ // extra styles for columns on editor
10700
+ flexBasis: `${100 / columnsQty}%`,
10701
+ background: snapshot.isDraggingOver ? theme.colors[theme.primaryColor][0] : "inherit",
10702
+ border: "1px solid transparent",
10703
+ "& .bespoke-resize-col": {
10704
+ visibility: "hidden"
10705
+ },
10706
+ "&:hover .bespoke-resize-col": {
10707
+ visibility: "visible"
10708
+ },
10709
+ "&:hover": {
10710
+ border: `1px solid ${theme.colors.teal[1]}`
10610
10711
  }
10611
- ),
10612
- orderedBlocks.map((item, rowIndex) => {
10613
- if (!blocks[item.id])
10614
- return null;
10615
- const { settings, type } = blocks[item.id];
10616
- const blockWidth = settings.width && !settings.width.stretch && settings.width.unit ? formatters[settings.width.unit](settings.width.value) : settings.display === "inline" ? "auto" : "100%";
10617
- const blockStyles = {
10618
- alignSelf: type === "visualization" ? "stretch" : "flex-start",
10619
- flexGrow: 0,
10620
- margin: "0",
10621
- textAlign: settings.align || blockSettings.align.defaultValue,
10622
- width: blockWidth,
10623
- minWidth: 120
10624
- };
10625
- return /* @__PURE__ */ jsx(
10626
- Draggable,
10712
+ },
10713
+ ...provided.droppableProps,
10714
+ children: [
10715
+ /* @__PURE__ */ jsx(
10716
+ ResizeColumnInput,
10627
10717
  {
10628
- draggableId: String(item.id),
10629
- index: rowIndex,
10630
- children: (provided2, snapshot2) => /* @__PURE__ */ jsx(
10631
- Box,
10632
- {
10633
- ref: provided2.innerRef,
10634
- ...provided2.draggableProps,
10635
- ...provided2.dragHandleProps,
10636
- sx: [
10637
- blockStyles,
10638
- {
10639
- boxShadow: snapshot2.isDragging ? theme.shadows.lg : "none",
10640
- ...provided2.draggableProps.style
10641
- }
10642
- ],
10643
- children: /* @__PURE__ */ jsx(
10644
- BlockElement_default,
10645
- {
10646
- id: Number(item.id),
10647
- active: isActive,
10648
- isInput: inputs.includes(Number(item.id)),
10649
- isConsumer: consumers.includes(Number(item.id)),
10650
- setHoverBlock
10651
- },
10652
- `block-${item.id}`
10653
- )
10654
- }
10655
- )
10656
- },
10657
- item.id
10658
- );
10659
- }),
10660
- isActive && /* @__PURE__ */ jsx(CreateBlockButton, { section, columnIndex, columns }),
10661
- provided.placeholder
10662
- ]
10663
- }
10664
- ) }, columnIndex);
10665
- }),
10666
- /* @__PURE__ */ jsx(CreateColumnArea, { active: draggingBlock && isActive })
10667
- ] }),
10668
- /* @__PURE__ */ jsx(FirstBlockButton, { columns, section, show: isActive && !columnsQty })
10669
- ]
10670
- }
10671
- ),
10672
- /* @__PURE__ */ jsx(ClickToEditOverlay, { onActivate, section, show: !isActive })
10718
+ sectionId: section.id,
10719
+ columnIndex
10720
+ }
10721
+ ),
10722
+ orderedBlocks.map((item, rowIndex) => {
10723
+ if (!blocks[item.id])
10724
+ return null;
10725
+ const { settings, type } = blocks[item.id];
10726
+ const blockWidth = settings.width && !settings.width.stretch && settings.width.unit ? formatters[settings.width.unit](settings.width.value) : settings.display === "inline" ? "auto" : "100%";
10727
+ const blockStyles = {
10728
+ alignSelf: type === "visualization" ? "stretch" : "flex-start",
10729
+ flexGrow: 0,
10730
+ margin: "0",
10731
+ textAlign: settings.align || blockSettings.align.defaultValue,
10732
+ width: blockWidth,
10733
+ minWidth: 120
10734
+ };
10735
+ return /* @__PURE__ */ jsx(
10736
+ Draggable,
10737
+ {
10738
+ draggableId: String(item.id),
10739
+ index: rowIndex,
10740
+ children: (provided2, snapshot2) => /* @__PURE__ */ jsx(
10741
+ Box,
10742
+ {
10743
+ ref: provided2.innerRef,
10744
+ ...provided2.draggableProps,
10745
+ ...provided2.dragHandleProps,
10746
+ sx: [
10747
+ blockStyles,
10748
+ {
10749
+ boxShadow: snapshot2.isDragging ? theme.shadows.lg : "none",
10750
+ ...provided2.draggableProps.style
10751
+ }
10752
+ ],
10753
+ children: /* @__PURE__ */ jsx(
10754
+ BlockElement_default,
10755
+ {
10756
+ id: Number(item.id),
10757
+ active: isActive,
10758
+ isInput: inputs.includes(Number(item.id)),
10759
+ isConsumer: consumers.includes(Number(item.id)),
10760
+ setHoverBlock
10761
+ },
10762
+ `block-${item.id}`
10763
+ )
10764
+ }
10765
+ )
10766
+ },
10767
+ item.id
10768
+ );
10769
+ }),
10770
+ isActive && /* @__PURE__ */ jsx(CreateBlockButton, { section, columnIndex, columns }),
10771
+ provided.placeholder
10772
+ ]
10773
+ }
10774
+ ) }, columnIndex);
10775
+ }),
10776
+ /* @__PURE__ */ jsx(CreateColumnArea, { active: draggingBlock && isActive })
10777
+ ] }),
10778
+ /* @__PURE__ */ jsx(FirstBlockButton, { columns, section, show: isActive && !columnsQty })
10779
+ ]
10780
+ }
10781
+ ),
10782
+ /* @__PURE__ */ jsx(ClickToEditOverlay, { onActivate, section, show: !isActive })
10783
+ ] })
10673
10784
  ]
10674
10785
  }
10675
10786
  );
package/dist/server.js CHANGED
@@ -4916,7 +4916,6 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
4916
4916
  );
4917
4917
  if (inputNotAllowed) {
4918
4918
  statusById[bid2] = {
4919
- log: [],
4920
4919
  allowed: false,
4921
4920
  hiddenByCascade: statusById[inputNotAllowed].hiddenByCascade || inputNotAllowed
4922
4921
  };
@@ -4932,8 +4931,12 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
4932
4931
  },
4933
4932
  readMemberFn
4934
4933
  ).then(({ outputVariables, status }) => {
4935
- variablesById[bid2] = outputVariables;
4936
- statusById[bid2] = status;
4934
+ if (
4935
+ // store output variables for block that:
4936
+ block.consumers.length > 0 && status.allowed && Object.keys(outputVariables).length > 0
4937
+ )
4938
+ variablesById[bid2] = outputVariables;
4939
+ statusById[bid2] = mode === "report" ? { allowed: status.allowed } : status;
4937
4940
  });
4938
4941
  const endBlock = /* @__PURE__ */ new Date();
4939
4942
  const blockTime = (endBlock.getTime() - startBlock.getTime()) / 1e3;
@@ -5296,15 +5299,12 @@ var recordsSlice = createSlice({
5296
5299
  */
5297
5300
  setReadRequest(state, action) {
5298
5301
  const req = action.payload;
5299
- state.requests[req.type][req.key] = req;
5302
+ if (req.type !== "report")
5303
+ state.requests[req.type][req.key] = req;
5300
5304
  if (req.status === "SUCCESS" /* SUCCESS */) {
5301
5305
  const newEntities = normalizeEntity(req.type, req.data);
5302
5306
  const nextEntities = combineRecords(state.entities, newEntities);
5303
5307
  state.entities = nextEntities;
5304
- if (req.type === "report") {
5305
- state.reports = Object.values(nextEntities.report).map((item) => item.id);
5306
- state.tree = req.data;
5307
- }
5308
5308
  }
5309
5309
  },
5310
5310
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datawheel/bespoke",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Content management system for creating automated data reports",
5
5
  "exports": {
6
6
  ".": {