@datawheel/bespoke 0.1.30 → 0.1.31
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 +198 -70
- package/dist/server.js +91 -64
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
-
import
|
|
2
|
+
import yn4 from 'yn';
|
|
3
3
|
import * as d3Array from 'd3-array';
|
|
4
4
|
import * as d3Collection from 'd3-collection';
|
|
5
5
|
import * as d3Format from 'd3-format';
|
|
@@ -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, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container,
|
|
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';
|
|
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, 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,
|
|
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';
|
|
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';
|
|
@@ -354,8 +354,9 @@ var init_cms = __esm({
|
|
|
354
354
|
STAT: "stat",
|
|
355
355
|
SUBTITLE: "subtitle",
|
|
356
356
|
TITLE: "title",
|
|
357
|
-
NAV: "nav"
|
|
357
|
+
NAV: "nav",
|
|
358
358
|
// todo1.0, how to put custom blocks in here?
|
|
359
|
+
RESET_BUTTON: "reset_button"
|
|
359
360
|
};
|
|
360
361
|
BLOCK_LOGIC_TYPES = {
|
|
361
362
|
GENERATOR: "generator",
|
|
@@ -472,7 +473,7 @@ var getLogging_default;
|
|
|
472
473
|
var init_getLogging = __esm({
|
|
473
474
|
"libs/configs/getLogging.ts"() {
|
|
474
475
|
init_esm_shims();
|
|
475
|
-
getLogging_default = (env = process.env) =>
|
|
476
|
+
getLogging_default = (env = process.env) => yn4(env.REPORTS_LOGGING);
|
|
476
477
|
}
|
|
477
478
|
});
|
|
478
479
|
|
|
@@ -740,7 +741,7 @@ var init_mortarEval = __esm({
|
|
|
740
741
|
init_esm_shims();
|
|
741
742
|
init_block();
|
|
742
743
|
init_libs();
|
|
743
|
-
verbose =
|
|
744
|
+
verbose = yn4(process.env.REPORTS_LOGGING);
|
|
744
745
|
mortarEval_default = mortarEval;
|
|
745
746
|
}
|
|
746
747
|
});
|
|
@@ -969,7 +970,7 @@ function getRootBlocksForSection(sid, blocks) {
|
|
|
969
970
|
blockList.filter((block) => block.section_id === sid && // leave blocks belonging to this section
|
|
970
971
|
// that don't depend on any other blocks OR
|
|
971
972
|
(block.inputs.length === 0 || // that depend only on blocks from other sections
|
|
972
|
-
block.inputs.
|
|
973
|
+
block.inputs.some((id) => nonNativeBlocks.includes(id)))).map((block) => [block.id, block])
|
|
973
974
|
// then convert them to entries
|
|
974
975
|
);
|
|
975
976
|
}
|
|
@@ -1095,14 +1096,7 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
1095
1096
|
return {
|
|
1096
1097
|
outputVariables: {},
|
|
1097
1098
|
renderVariables: {},
|
|
1098
|
-
status: {
|
|
1099
|
-
api: null,
|
|
1100
|
-
duration: null,
|
|
1101
|
-
resp: null,
|
|
1102
|
-
log: [],
|
|
1103
|
-
error: null,
|
|
1104
|
-
allowed: false
|
|
1105
|
-
}
|
|
1099
|
+
status: { allowed: false }
|
|
1106
1100
|
};
|
|
1107
1101
|
}
|
|
1108
1102
|
if (unswappedAPI) {
|
|
@@ -1133,9 +1127,6 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
1133
1127
|
outputVariables: selectorQueryToVariable_default(block.id, query, config),
|
|
1134
1128
|
renderVariables: config,
|
|
1135
1129
|
status: {
|
|
1136
|
-
api: null,
|
|
1137
|
-
duration: null,
|
|
1138
|
-
resp: null,
|
|
1139
1130
|
log: log2,
|
|
1140
1131
|
error: error2,
|
|
1141
1132
|
allowed
|
|
@@ -1148,11 +1139,8 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
1148
1139
|
// todo1.0 this will have to be materialized click-variables
|
|
1149
1140
|
renderVariables: block.contentByLocale.logic.content,
|
|
1150
1141
|
status: {
|
|
1151
|
-
api: null,
|
|
1152
|
-
duration: null,
|
|
1153
|
-
resp: null,
|
|
1154
1142
|
log: [],
|
|
1155
|
-
|
|
1143
|
+
// todo: see if we can remove this safely
|
|
1156
1144
|
allowed
|
|
1157
1145
|
}
|
|
1158
1146
|
};
|
|
@@ -1189,7 +1177,7 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
1189
1177
|
}
|
|
1190
1178
|
};
|
|
1191
1179
|
}
|
|
1192
|
-
var verbose2, ORIGIN, swapAPI, urlProxy, getDependencies, isBlockAllowed, runConsumersV2, getDurationColor, getSizeColor;
|
|
1180
|
+
var verbose2, debug, ORIGIN, swapAPI, urlProxy, getDependencies, isBlockAllowed, runConsumersV2, getDurationColor, getSizeColor;
|
|
1193
1181
|
var init_runConsumers = __esm({
|
|
1194
1182
|
"libs/blocks/runConsumers.ts"() {
|
|
1195
1183
|
init_esm_shims();
|
|
@@ -1205,6 +1193,7 @@ var init_runConsumers = __esm({
|
|
|
1205
1193
|
init_getRootBlocksForSection();
|
|
1206
1194
|
init_arrayUtils();
|
|
1207
1195
|
verbose2 = getLogging_default();
|
|
1196
|
+
debug = yn4(process.env.NEXT_PUBLIC_REPORTS_DEBUG);
|
|
1208
1197
|
ORIGIN = process.env.REPORTS_ORIGIN || "";
|
|
1209
1198
|
axios.interceptors.request.use((config) => ({
|
|
1210
1199
|
...config,
|
|
@@ -1224,10 +1213,7 @@ var init_runConsumers = __esm({
|
|
|
1224
1213
|
getDependencies = (bid, blocks, acc = [], crawlUp = true, crawlDown = true, withinSection = true, visited = []) => {
|
|
1225
1214
|
if (visited.includes(bid))
|
|
1226
1215
|
return [];
|
|
1227
|
-
|
|
1228
|
-
visited.push(bid);
|
|
1229
|
-
if (verbose2)
|
|
1230
|
-
console.log("%cpassing through block", "color:green", bid);
|
|
1216
|
+
visited.push(bid);
|
|
1231
1217
|
const rootBlock = blocks[bid];
|
|
1232
1218
|
if (rootBlock.inputs.length && crawlUp) {
|
|
1233
1219
|
rootBlock.inputs.forEach((iid) => {
|
|
@@ -1244,7 +1230,7 @@ var init_runConsumers = __esm({
|
|
|
1244
1230
|
if (!acc.includes(rel) && (blocks[cid].section_id === blocks[bid].section_id || !withinSection)) {
|
|
1245
1231
|
acc.push(rel);
|
|
1246
1232
|
}
|
|
1247
|
-
rootBlock.consumers.filter((cid2) => blocks[cid2].section_id === blocks[bid].section_id || !withinSection).forEach((cid2) => getDependencies(cid2, blocks, acc,
|
|
1233
|
+
rootBlock.consumers.filter((cid2) => blocks[cid2].section_id === blocks[bid].section_id || !withinSection).forEach((cid2) => getDependencies(cid2, blocks, acc, false, crawlDown, withinSection, visited));
|
|
1248
1234
|
});
|
|
1249
1235
|
}
|
|
1250
1236
|
return acc;
|
|
@@ -1277,22 +1263,31 @@ var init_runConsumers = __esm({
|
|
|
1277
1263
|
const statusById = { ...initialState4.status ?? {} };
|
|
1278
1264
|
const parsedBlockContext = parseBlockContext(blockContext);
|
|
1279
1265
|
const attributes = parsedBlockContext.variables;
|
|
1280
|
-
const rootBlocks = bid ? { [bid]: blocks[bid] } : sections.reduce((rootBlocks2, { id }) => ({ ...rootBlocks2, ...getRootBlocksForSection_default(id, blocks) }), {});
|
|
1281
|
-
if (
|
|
1282
|
-
console.log("%crunConsumers: running root blocks", "color:
|
|
1266
|
+
const rootBlocks = bid ? { [bid]: blocks[bid] } : (sections ?? []).reduce((rootBlocks2, { id }) => ({ ...rootBlocks2, ...getRootBlocksForSection_default(id, blocks) }), {});
|
|
1267
|
+
if (debug)
|
|
1268
|
+
console.log("%crunConsumers: running root blocks", "color:purple", Object.keys(rootBlocks));
|
|
1283
1269
|
const withinSection = mode === "section";
|
|
1284
1270
|
const blockDeps = Object.keys(rootBlocks).reduce((deps, id) => {
|
|
1285
|
-
|
|
1286
|
-
console.log("%cresolving dependencies for", "color:red", id);
|
|
1271
|
+
const start = /* @__PURE__ */ new Date();
|
|
1287
1272
|
const dependencies = getDependencies(Number(id), blocks, [], !bid, true, withinSection).map((rel) => rel.split("-"));
|
|
1273
|
+
const end = /* @__PURE__ */ new Date();
|
|
1274
|
+
const elapsedTime = (end.getTime() - start.getTime()) / 1e3;
|
|
1275
|
+
if (debug)
|
|
1276
|
+
console.log(
|
|
1277
|
+
`%cResolved dependencies for ${id} (${elapsedTime.toFixed(2)}s)`,
|
|
1278
|
+
"color:blue"
|
|
1279
|
+
);
|
|
1288
1280
|
return [...deps, ...dependencies];
|
|
1289
1281
|
}, []);
|
|
1282
|
+
const startToposort = /* @__PURE__ */ new Date();
|
|
1290
1283
|
const orderedDAG = Object.keys(rootBlocks).reduce(
|
|
1291
1284
|
(orderedDAG2, bid2) => orderedDAG2.includes(bid2) ? [...orderedDAG2] : [bid2, ...orderedDAG2],
|
|
1292
1285
|
toposort(blockDeps)
|
|
1293
1286
|
);
|
|
1294
|
-
|
|
1295
|
-
|
|
1287
|
+
const endToposort = /* @__PURE__ */ new Date();
|
|
1288
|
+
const toposortTime = (endToposort.getTime() - startToposort.getTime()) / 1e3;
|
|
1289
|
+
if (debug)
|
|
1290
|
+
console.log(`%cResolved DAG (${toposortTime.toFixed(2)}s): `, "color:green", orderedDAG);
|
|
1296
1291
|
async function runTasksInParallel(executionOrder, blocks2) {
|
|
1297
1292
|
const runningBlocks = /* @__PURE__ */ new Map();
|
|
1298
1293
|
for (const bid2 of executionOrder) {
|
|
@@ -1300,22 +1295,21 @@ var init_runConsumers = __esm({
|
|
|
1300
1295
|
const dependenciesDone = Promise.all(
|
|
1301
1296
|
block.inputs.filter((iid) => executionOrder.includes(String(iid))).map((iid) => runningBlocks.get(Number(iid)))
|
|
1302
1297
|
);
|
|
1303
|
-
const runningTask = dependenciesDone.then(() => {
|
|
1298
|
+
const runningTask = dependenciesDone.then(async () => {
|
|
1304
1299
|
const variables = block.inputs.reduce((acc, d) => ({ ...acc, ...variablesById[d] }), attributes);
|
|
1305
|
-
const inputNotAllowed = block.inputs.find(
|
|
1300
|
+
const inputNotAllowed = block.inputs.find(
|
|
1301
|
+
(iid) => !statusById[iid].allowed || statusById[iid].hiddenByCascade
|
|
1302
|
+
);
|
|
1306
1303
|
if (inputNotAllowed) {
|
|
1307
1304
|
statusById[bid2] = {
|
|
1308
|
-
api: null,
|
|
1309
|
-
duration: null,
|
|
1310
|
-
resp: null,
|
|
1311
1305
|
log: [],
|
|
1312
|
-
error: null,
|
|
1313
1306
|
allowed: false,
|
|
1314
1307
|
hiddenByCascade: statusById[inputNotAllowed].hiddenByCascade || inputNotAllowed
|
|
1315
1308
|
};
|
|
1316
1309
|
return;
|
|
1317
1310
|
}
|
|
1318
|
-
|
|
1311
|
+
const startBlock = /* @__PURE__ */ new Date();
|
|
1312
|
+
const blockResult = await runSingleBlock(
|
|
1319
1313
|
block,
|
|
1320
1314
|
formatterFunctions,
|
|
1321
1315
|
{
|
|
@@ -1327,12 +1321,25 @@ var init_runConsumers = __esm({
|
|
|
1327
1321
|
variablesById[bid2] = outputVariables;
|
|
1328
1322
|
statusById[bid2] = status;
|
|
1329
1323
|
});
|
|
1324
|
+
const endBlock = /* @__PURE__ */ new Date();
|
|
1325
|
+
const blockTime = (endBlock.getTime() - startBlock.getTime()) / 1e3;
|
|
1326
|
+
if (debug)
|
|
1327
|
+
console.log(
|
|
1328
|
+
`%cBlock ${block.id} resolved in ${blockTime.toFixed(3)}s`,
|
|
1329
|
+
blockTime > 500 ? "color:red" : "color:green"
|
|
1330
|
+
);
|
|
1331
|
+
return blockResult;
|
|
1330
1332
|
});
|
|
1331
1333
|
runningBlocks.set(Number(bid2), runningTask);
|
|
1332
1334
|
}
|
|
1333
1335
|
await Promise.all(Array.from(runningBlocks.values()));
|
|
1334
1336
|
}
|
|
1337
|
+
const startVariables = /* @__PURE__ */ new Date();
|
|
1335
1338
|
await runTasksInParallel(orderedDAG, blocks);
|
|
1339
|
+
const endVariables = /* @__PURE__ */ new Date();
|
|
1340
|
+
const variablesTime = (endVariables.getTime() - startVariables.getTime()) / 1e3;
|
|
1341
|
+
if (debug)
|
|
1342
|
+
console.log(`%cResolved Variables (${variablesTime.toFixed(2)}s): `, "color:green");
|
|
1336
1343
|
return {
|
|
1337
1344
|
variables: { ...initialState4.variables ?? {}, ...variablesById },
|
|
1338
1345
|
status: { ...initialState4.status ?? {}, ...statusById }
|
|
@@ -2900,6 +2907,7 @@ function Viz(config) {
|
|
|
2900
2907
|
const blockContext = { variables };
|
|
2901
2908
|
const router = useRouter();
|
|
2902
2909
|
const { sectionVariables, setSectionVariables, resetSectionVariables } = useSectionVariables(block.section_id);
|
|
2910
|
+
const sectionVariablesStr = JSON.stringify(sectionVariables);
|
|
2903
2911
|
const vizProps = useMemo(() => {
|
|
2904
2912
|
if (!content?.logic)
|
|
2905
2913
|
return { error: "Add a Configuration" };
|
|
@@ -2913,7 +2921,7 @@ function Viz(config) {
|
|
|
2913
2921
|
}
|
|
2914
2922
|
};
|
|
2915
2923
|
return d3plusPropify_default(transpiledLogic, formatterFunctions, variables, locale, block.id, {}, globals);
|
|
2916
|
-
}, [block, active, variables,
|
|
2924
|
+
}, [block, active, variables, sectionVariablesStr]);
|
|
2917
2925
|
const { type } = vizProps.config || {};
|
|
2918
2926
|
const fallbackType = type && vizTypes[type] ? type : "Treemap";
|
|
2919
2927
|
if (!vizTypes[type])
|
|
@@ -2947,7 +2955,7 @@ function Viz(config) {
|
|
|
2947
2955
|
linksFormat: vizProps.linksFormat,
|
|
2948
2956
|
nodesFormat: vizProps.nodesFormat,
|
|
2949
2957
|
topojsonFormat: vizProps.topojsonFormat,
|
|
2950
|
-
config: { ...defaultConfig_default, ...vizConfig }
|
|
2958
|
+
config: { ...defaultConfig_default, ...vizConfig, sectionVariables: sectionVariablesStr }
|
|
2951
2959
|
},
|
|
2952
2960
|
"viz-key"
|
|
2953
2961
|
) })
|
|
@@ -3113,7 +3121,7 @@ function Viz2({
|
|
|
3113
3121
|
active,
|
|
3114
3122
|
locale,
|
|
3115
3123
|
variables,
|
|
3116
|
-
debug,
|
|
3124
|
+
debug: debug2,
|
|
3117
3125
|
configOverride = {}
|
|
3118
3126
|
}) {
|
|
3119
3127
|
const context = useAppContext();
|
|
@@ -3483,6 +3491,7 @@ function BespokeExplore({
|
|
|
3483
3491
|
const [metadata, setMetadata] = useState();
|
|
3484
3492
|
const inputRef = useRef();
|
|
3485
3493
|
useEffect(() => {
|
|
3494
|
+
setLoading(true);
|
|
3486
3495
|
dispatch(actions_exports.readMetadata({})).then((resp) => {
|
|
3487
3496
|
setMetadata(resp.data);
|
|
3488
3497
|
}, (err) => {
|
|
@@ -4343,6 +4352,30 @@ function NavView({ headings, settings }) {
|
|
|
4343
4352
|
return smallerThanMd ? /* @__PURE__ */ jsx(MobileNav, { contentOutline }) : /* @__PURE__ */ jsx(DesktopNav, { contentOutline });
|
|
4344
4353
|
}
|
|
4345
4354
|
|
|
4355
|
+
// frontend/components/report/blocks/ResetButton.tsx
|
|
4356
|
+
init_esm_shims();
|
|
4357
|
+
init_hooks();
|
|
4358
|
+
init_hooks();
|
|
4359
|
+
function ResetButtonView({ id, label, showIcon, fullWidth, showWhenDisabled }) {
|
|
4360
|
+
const block = useBlockRef(id).data;
|
|
4361
|
+
const { sectionVariables, resetSectionVariables } = useSectionVariables(block?.section_id);
|
|
4362
|
+
const hasVariables = Boolean(Object.keys(sectionVariables).length);
|
|
4363
|
+
if (!hasVariables && !showWhenDisabled)
|
|
4364
|
+
return null;
|
|
4365
|
+
return /* @__PURE__ */ jsx(
|
|
4366
|
+
Button,
|
|
4367
|
+
{
|
|
4368
|
+
onClick: () => resetSectionVariables(),
|
|
4369
|
+
disabled: !hasVariables,
|
|
4370
|
+
fullWidth,
|
|
4371
|
+
children: /* @__PURE__ */ jsxs(Group, { align: "center", children: [
|
|
4372
|
+
label,
|
|
4373
|
+
showIcon && /* @__PURE__ */ jsx(IconRefresh, {})
|
|
4374
|
+
] })
|
|
4375
|
+
}
|
|
4376
|
+
);
|
|
4377
|
+
}
|
|
4378
|
+
|
|
4346
4379
|
// frontend/components/report/blocks/index.tsx
|
|
4347
4380
|
var VizView = dynamic(
|
|
4348
4381
|
() => Promise.resolve().then(() => (init_Viz(), Viz_exports)),
|
|
@@ -4357,7 +4390,8 @@ var TypeRenderers = {
|
|
|
4357
4390
|
[BLOCK_TYPES.VIZ]: VizView,
|
|
4358
4391
|
[BLOCK_TYPES.GENERATOR]: Generator,
|
|
4359
4392
|
[BLOCK_TYPES.IMAGE]: ImageView,
|
|
4360
|
-
[BLOCK_TYPES.NAV]: NavView
|
|
4393
|
+
[BLOCK_TYPES.NAV]: NavView,
|
|
4394
|
+
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonView
|
|
4361
4395
|
};
|
|
4362
4396
|
var blocks_default = TypeRenderers;
|
|
4363
4397
|
|
|
@@ -4789,10 +4823,67 @@ function NavUI() {
|
|
|
4789
4823
|
return /* @__PURE__ */ jsx(Title, { order: 4, children: "Nav UI" });
|
|
4790
4824
|
}
|
|
4791
4825
|
|
|
4826
|
+
// components/blocks/types/simpleEditors/ResetButtonUI.tsx
|
|
4827
|
+
init_esm_shims();
|
|
4828
|
+
function ResetButtonUI({ id, locale, executeButton, onChange, simpleState }) {
|
|
4829
|
+
const [label, setLabel] = useState(simpleState?.label ?? "");
|
|
4830
|
+
const [showIcon, setShowIcon] = useState(simpleState?.showIcon ?? true);
|
|
4831
|
+
const [fullWidth, setFullwidth] = useState(simpleState?.fullWidth ?? false);
|
|
4832
|
+
const [showWhenDisabled, setShowWhenDisabled] = useState(simpleState?.showWhenDisabled ?? false);
|
|
4833
|
+
useEffect(() => {
|
|
4834
|
+
const simpleState2 = {
|
|
4835
|
+
label,
|
|
4836
|
+
showIcon,
|
|
4837
|
+
fullWidth,
|
|
4838
|
+
showWhenDisabled
|
|
4839
|
+
};
|
|
4840
|
+
onChange(simpleState2);
|
|
4841
|
+
}, [label, showIcon, fullWidth, showWhenDisabled, onChange]);
|
|
4842
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
4843
|
+
/* @__PURE__ */ jsx(
|
|
4844
|
+
TextInput,
|
|
4845
|
+
{
|
|
4846
|
+
placeholder: "Label for reset section state button",
|
|
4847
|
+
value: label,
|
|
4848
|
+
onChange: (e) => setLabel(e.target.value),
|
|
4849
|
+
label: "Label"
|
|
4850
|
+
}
|
|
4851
|
+
),
|
|
4852
|
+
/* @__PURE__ */ jsxs(Group, { children: [
|
|
4853
|
+
/* @__PURE__ */ jsx(
|
|
4854
|
+
Switch,
|
|
4855
|
+
{
|
|
4856
|
+
checked: showIcon,
|
|
4857
|
+
label: "Show icon",
|
|
4858
|
+
onChange: (e) => setShowIcon(e.currentTarget.checked)
|
|
4859
|
+
}
|
|
4860
|
+
),
|
|
4861
|
+
/* @__PURE__ */ jsx(
|
|
4862
|
+
Switch,
|
|
4863
|
+
{
|
|
4864
|
+
checked: fullWidth,
|
|
4865
|
+
label: "Full width",
|
|
4866
|
+
onChange: (e) => setFullwidth(e.currentTarget.checked)
|
|
4867
|
+
}
|
|
4868
|
+
),
|
|
4869
|
+
/* @__PURE__ */ jsx(
|
|
4870
|
+
Switch,
|
|
4871
|
+
{
|
|
4872
|
+
checked: showWhenDisabled,
|
|
4873
|
+
label: "Show when disabled",
|
|
4874
|
+
onChange: (e) => setShowWhenDisabled(e.currentTarget.checked)
|
|
4875
|
+
}
|
|
4876
|
+
)
|
|
4877
|
+
] }),
|
|
4878
|
+
executeButton
|
|
4879
|
+
] });
|
|
4880
|
+
}
|
|
4881
|
+
|
|
4792
4882
|
// components/blocks/types/simpleEditors/index.js
|
|
4793
4883
|
var simpleEditors_default = {
|
|
4794
4884
|
[BLOCK_TYPES.SELECTOR]: SelectorUI_default,
|
|
4795
|
-
[BLOCK_TYPES.NAV]: NavUI
|
|
4885
|
+
[BLOCK_TYPES.NAV]: NavUI,
|
|
4886
|
+
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonUI
|
|
4796
4887
|
};
|
|
4797
4888
|
|
|
4798
4889
|
// components/blocks/types/renderers/index.tsx
|
|
@@ -5073,8 +5164,8 @@ function InputMenuItem({
|
|
|
5073
5164
|
] }) }) });
|
|
5074
5165
|
}
|
|
5075
5166
|
var InputMenuItem_default = InputMenuItem;
|
|
5076
|
-
function Generator2({ outputVariables, debug }) {
|
|
5077
|
-
return
|
|
5167
|
+
function Generator2({ outputVariables, debug: debug2 }) {
|
|
5168
|
+
return debug2 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5078
5169
|
/* @__PURE__ */ jsx(Divider, { label: "Output Variables", labelPosition: "center" }),
|
|
5079
5170
|
/* @__PURE__ */ jsx(InputMenuItem_default, { variables: outputVariables })
|
|
5080
5171
|
] }) : /* @__PURE__ */ jsx(Center, { children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: "GENERATOR" }, "type") });
|
|
@@ -5233,6 +5324,31 @@ function NavPreview({ headings, settings }) {
|
|
|
5233
5324
|
] });
|
|
5234
5325
|
}
|
|
5235
5326
|
|
|
5327
|
+
// components/blocks/types/renderers/ResetButton.tsx
|
|
5328
|
+
init_esm_shims();
|
|
5329
|
+
init_hooks();
|
|
5330
|
+
init_hooks();
|
|
5331
|
+
function ResetButtonPreview({ id, label, showIcon, fullWidth, showWhenDisabled }) {
|
|
5332
|
+
const block = useBlockRef(id).data;
|
|
5333
|
+
const { sectionVariables, resetSectionVariables } = useSectionVariables(block?.section_id);
|
|
5334
|
+
const hasVariables = Boolean(Object.keys(sectionVariables).length);
|
|
5335
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5336
|
+
!hasVariables && !showWhenDisabled && /* @__PURE__ */ jsx(Text, { size: "xs", children: "Reset button will not be shown on its disabled state" }),
|
|
5337
|
+
/* @__PURE__ */ jsx(
|
|
5338
|
+
Button,
|
|
5339
|
+
{
|
|
5340
|
+
onClick: () => resetSectionVariables(),
|
|
5341
|
+
disabled: !hasVariables,
|
|
5342
|
+
fullWidth,
|
|
5343
|
+
children: /* @__PURE__ */ jsxs(Group, { align: "center", children: [
|
|
5344
|
+
label,
|
|
5345
|
+
showIcon && /* @__PURE__ */ jsx(IconRefresh, {})
|
|
5346
|
+
] })
|
|
5347
|
+
}
|
|
5348
|
+
)
|
|
5349
|
+
] });
|
|
5350
|
+
}
|
|
5351
|
+
|
|
5236
5352
|
// components/blocks/types/renderers/index.tsx
|
|
5237
5353
|
var VizPreview = dynamic(
|
|
5238
5354
|
() => Promise.resolve().then(() => (init_Viz2(), Viz_exports2)),
|
|
@@ -5247,7 +5363,8 @@ var renderersMap = {
|
|
|
5247
5363
|
[BLOCK_TYPES.VIZ]: VizPreview,
|
|
5248
5364
|
[BLOCK_TYPES.GENERATOR]: Generator_default,
|
|
5249
5365
|
[BLOCK_TYPES.IMAGE]: ImagePreview,
|
|
5250
|
-
[BLOCK_TYPES.NAV]: NavPreview
|
|
5366
|
+
[BLOCK_TYPES.NAV]: NavPreview,
|
|
5367
|
+
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonPreview
|
|
5251
5368
|
};
|
|
5252
5369
|
var renderers_default = renderersMap;
|
|
5253
5370
|
|
|
@@ -5311,6 +5428,12 @@ var allBlocks = {
|
|
|
5311
5428
|
renderer: renderers_default[BLOCK_TYPES.NAV],
|
|
5312
5429
|
renderPreviewOnEdit: true,
|
|
5313
5430
|
evalWhenNonActive: true
|
|
5431
|
+
},
|
|
5432
|
+
[BLOCK_TYPES.RESET_BUTTON]: {
|
|
5433
|
+
type: BLOCK_TYPES.RESET_BUTTON,
|
|
5434
|
+
renderer: renderers_default[BLOCK_TYPES.RESET_BUTTON],
|
|
5435
|
+
renderPreviewOnEdit: true,
|
|
5436
|
+
evalWhenNonActive: true
|
|
5314
5437
|
}
|
|
5315
5438
|
};
|
|
5316
5439
|
var types_default = allBlocks;
|
|
@@ -5396,6 +5519,10 @@ function Block({ blockId, active = true }) {
|
|
|
5396
5519
|
});
|
|
5397
5520
|
return;
|
|
5398
5521
|
}
|
|
5522
|
+
if (block.type === BLOCK_TYPES.RESET_BUTTON) {
|
|
5523
|
+
setContent({ id: block.id, ...blockContent.simple });
|
|
5524
|
+
return;
|
|
5525
|
+
}
|
|
5399
5526
|
const swappedLogic = varSwap_default(blockContent?.logic, formatterFunctions, blockContext);
|
|
5400
5527
|
const { vars } = mortarEval_default(
|
|
5401
5528
|
"variables",
|
|
@@ -6445,7 +6572,7 @@ var SectionResetButton = ({ id }) => {
|
|
|
6445
6572
|
const hasVariables = Boolean(Object.keys(sectionVariables).length);
|
|
6446
6573
|
if (!hasVariables)
|
|
6447
6574
|
return null;
|
|
6448
|
-
return /* @__PURE__ */ jsx(ActionIcon, { disabled: !hasVariables, onClick: resetSectionVariables, children: /* @__PURE__ */ jsx(IconRefresh, { size: 20 }) });
|
|
6575
|
+
return /* @__PURE__ */ jsx(ActionIcon, { disabled: !hasVariables, onClick: resetSectionVariables, variant: "filled", size: "xs", children: /* @__PURE__ */ jsx(IconRefresh, { size: 20 }) });
|
|
6449
6576
|
};
|
|
6450
6577
|
function SectionMenu({ sectionId }) {
|
|
6451
6578
|
const theme = useMantineTheme();
|
|
@@ -6454,8 +6581,7 @@ function SectionMenu({ sectionId }) {
|
|
|
6454
6581
|
borderRadius: theme.radius.sm
|
|
6455
6582
|
}, children: [
|
|
6456
6583
|
/* @__PURE__ */ jsx(DesignSectionMenu, { sectionId }),
|
|
6457
|
-
/* @__PURE__ */ jsx(EntityDeleteButton, { type: "section", id: sectionId })
|
|
6458
|
-
/* @__PURE__ */ jsx(SectionResetButton, { id: sectionId })
|
|
6584
|
+
/* @__PURE__ */ jsx(EntityDeleteButton, { type: "section", id: sectionId })
|
|
6459
6585
|
] });
|
|
6460
6586
|
}
|
|
6461
6587
|
var SectionMenu_default = SectionMenu;
|
|
@@ -6959,14 +7085,9 @@ function Section({ section }) {
|
|
|
6959
7085
|
id: `section-${id}`,
|
|
6960
7086
|
pos: "relative",
|
|
6961
7087
|
children: [
|
|
6962
|
-
/* @__PURE__ */ jsxs("
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
top: 10,
|
|
6966
|
-
zIndex: 3
|
|
6967
|
-
}, children: [
|
|
6968
|
-
sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: section.id }),
|
|
6969
|
-
/* @__PURE__ */ jsx(SectionResetButton, { id: section.id })
|
|
7088
|
+
/* @__PURE__ */ jsxs(Group, { position: "right", mb: "xs", children: [
|
|
7089
|
+
/* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
|
|
7090
|
+
sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: section.id })
|
|
6970
7091
|
] }),
|
|
6971
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) => {
|
|
6972
7093
|
const column = columns[columnIndex];
|
|
@@ -7258,7 +7379,7 @@ function normalizeList(value) {
|
|
|
7258
7379
|
var { localeDefault: localeDefault8 } = getLocales_default();
|
|
7259
7380
|
function parseReadMemberParams(query) {
|
|
7260
7381
|
const locale = normalizeList(query.locale)[0] || localeDefault8 || "en";
|
|
7261
|
-
const all = locale === "all" ||
|
|
7382
|
+
const all = locale === "all" || yn4(query.all);
|
|
7262
7383
|
const mode = normalizeList(query.mode)[0];
|
|
7263
7384
|
const outputParam = normalizeList(query.output)[0] || "full";
|
|
7264
7385
|
const output = outputParam === "lite" ? "lite" : "full";
|
|
@@ -7323,9 +7444,9 @@ function parseSearchMemberParams(query) {
|
|
|
7323
7444
|
locale: localeIsAll ? localeDefault8 : locale,
|
|
7324
7445
|
limit: normalizeList(query.limit).map(parseFiniteNumber)[0] ?? 5,
|
|
7325
7446
|
format: formatIsNested ? "nested" : "plain",
|
|
7326
|
-
includes:
|
|
7327
|
-
visible:
|
|
7328
|
-
noImage:
|
|
7447
|
+
includes: yn4(query.includes, { default: true }),
|
|
7448
|
+
visible: yn4(query.visible, { default: true }),
|
|
7449
|
+
noImage: yn4(query.noImage, { default: false }),
|
|
7329
7450
|
variant,
|
|
7330
7451
|
dimension,
|
|
7331
7452
|
report,
|
|
@@ -8907,7 +9028,7 @@ function BlockPreview(props) {
|
|
|
8907
9028
|
active,
|
|
8908
9029
|
allowed,
|
|
8909
9030
|
blockStateContent,
|
|
8910
|
-
debug,
|
|
9031
|
+
debug: debug2,
|
|
8911
9032
|
for: block,
|
|
8912
9033
|
locale
|
|
8913
9034
|
} = props;
|
|
@@ -8976,6 +9097,10 @@ function BlockPreview(props) {
|
|
|
8976
9097
|
setContent({ headings: block.inputs, settings: block.settings });
|
|
8977
9098
|
return;
|
|
8978
9099
|
}
|
|
9100
|
+
if (block.type === BLOCK_TYPES.RESET_BUTTON) {
|
|
9101
|
+
setContent(blockContent.simple);
|
|
9102
|
+
return;
|
|
9103
|
+
}
|
|
8979
9104
|
const swappedLogic = varSwap_default(blockContent?.logic, formatterFunctions, blockContext);
|
|
8980
9105
|
const { vars, error: error2, log: log2 } = mortarEval_default(
|
|
8981
9106
|
"variables",
|
|
@@ -9015,8 +9140,8 @@ function BlockPreview(props) {
|
|
|
9015
9140
|
style: { width: "100%", minHeight: block.type === BLOCK_TYPES.VIZ ? 400 : "auto" },
|
|
9016
9141
|
children: [
|
|
9017
9142
|
!allowed && allowedOverlay,
|
|
9018
|
-
Renderer ? /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Renderer, { id: block.id, debug, ...content, settings: block.settings }) }, "renderer") : /* @__PURE__ */ jsx(Center, { style: { minHeight: 100 }, children: /* @__PURE__ */ jsx(Badge, { color: "gray", variant: "outline", children: block.type }, "type") }),
|
|
9019
|
-
|
|
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") }),
|
|
9144
|
+
debug2 && textLog && /* @__PURE__ */ jsx(
|
|
9020
9145
|
Textarea,
|
|
9021
9146
|
{
|
|
9022
9147
|
label: "Console",
|
|
@@ -9026,7 +9151,7 @@ function BlockPreview(props) {
|
|
|
9026
9151
|
error
|
|
9027
9152
|
}
|
|
9028
9153
|
),
|
|
9029
|
-
|
|
9154
|
+
debug2 && error && /* @__PURE__ */ jsx(Textarea, { label: "Error", readOnly: true, minRows: 3, value: error }),
|
|
9030
9155
|
block.type === BLOCK_TYPES.GENERATOR && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9031
9156
|
/* @__PURE__ */ jsxs(Group, { spacing: "xs", my: "xs", children: [
|
|
9032
9157
|
status.duration && /* @__PURE__ */ jsxs(
|
|
@@ -10422,7 +10547,10 @@ function SectionEditor({
|
|
|
10422
10547
|
}
|
|
10423
10548
|
),
|
|
10424
10549
|
memberImageBg && /* @__PURE__ */ jsx(SectionBackground, {}),
|
|
10425
|
-
optionsMenu && /* @__PURE__ */
|
|
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
|
+
] }),
|
|
10426
10554
|
/* @__PURE__ */ jsx(
|
|
10427
10555
|
GeneratorsPanel,
|
|
10428
10556
|
{
|
package/dist/server.js
CHANGED
|
@@ -500,8 +500,9 @@ var BLOCK_CONTENT_TYPES = {
|
|
|
500
500
|
STAT: "stat",
|
|
501
501
|
SUBTITLE: "subtitle",
|
|
502
502
|
TITLE: "title",
|
|
503
|
-
NAV: "nav"
|
|
503
|
+
NAV: "nav",
|
|
504
504
|
// todo1.0, how to put custom blocks in here?
|
|
505
|
+
RESET_BUTTON: "reset_button"
|
|
505
506
|
};
|
|
506
507
|
var BLOCK_LOGIC_TYPES = {
|
|
507
508
|
GENERATOR: "generator",
|
|
@@ -2115,20 +2116,26 @@ var whitelist = [
|
|
|
2115
2116
|
"vi",
|
|
2116
2117
|
"zh"
|
|
2117
2118
|
];
|
|
2118
|
-
getLogging_default();
|
|
2119
|
+
var verbose3 = getLogging_default();
|
|
2119
2120
|
var { locales } = getLocales_default();
|
|
2120
2121
|
var enabledLocales = locales.filter((d) => whitelist.includes(d));
|
|
2121
2122
|
var initializing = false;
|
|
2122
2123
|
var getSearchIndexByLocale = async (db, forceRegenerate = false) => {
|
|
2123
2124
|
if (forceRegenerate) {
|
|
2125
|
+
if (verbose3)
|
|
2126
|
+
console.log("0\uFE0F\u20E3 CLEARING SEARCH INDEX");
|
|
2124
2127
|
global.lunrsearch = void 0;
|
|
2125
2128
|
initializing = false;
|
|
2126
2129
|
}
|
|
2127
2130
|
if (global.lunrsearch) {
|
|
2131
|
+
if (verbose3)
|
|
2132
|
+
console.log("\u{1F501} RE-UTILIZING SEARCH INDEX");
|
|
2128
2133
|
return global.lunrsearch;
|
|
2129
2134
|
}
|
|
2130
2135
|
try {
|
|
2131
2136
|
if (!initializing) {
|
|
2137
|
+
if (verbose3)
|
|
2138
|
+
console.log("1\uFE0F\u20E3 INITIALIZING SEARCH INDEX");
|
|
2132
2139
|
initializing = true;
|
|
2133
2140
|
global.lunrsearch = await newSearchIndex(db);
|
|
2134
2141
|
}
|
|
@@ -2146,34 +2153,46 @@ async function newSearchIndex(db) {
|
|
|
2146
2153
|
include: [{ association: "contentByLocale" }]
|
|
2147
2154
|
});
|
|
2148
2155
|
const setups = enabledLocales.map(async (locale) => {
|
|
2149
|
-
if (!lunr[locale] &&
|
|
2156
|
+
if (!lunr[locale] && locale !== "en") {
|
|
2150
2157
|
const lunrLang = (await import(`lunr-languages/lunr.${locale}`)).default;
|
|
2151
2158
|
lunrLang(lunr);
|
|
2159
|
+
lunrStemmer(lunr);
|
|
2160
|
+
if (verbose3)
|
|
2161
|
+
console.log(`\u{1F3F3}\uFE0F INITIALIZING SEARCH ${locale} LOCALE`);
|
|
2152
2162
|
}
|
|
2153
|
-
return [
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2163
|
+
return [
|
|
2164
|
+
locale,
|
|
2165
|
+
{
|
|
2166
|
+
tokenizer: lunr.tokenizer,
|
|
2167
|
+
query: lunr.Query,
|
|
2168
|
+
index: await lunr(
|
|
2169
|
+
function() {
|
|
2170
|
+
if (locale && locale !== "en")
|
|
2171
|
+
this.use(lunr[locale]);
|
|
2172
|
+
this.ref("content_id");
|
|
2173
|
+
this.field("id");
|
|
2174
|
+
this.field("name");
|
|
2175
|
+
this.field("keywords");
|
|
2176
|
+
this.field("attributes");
|
|
2177
|
+
this.pipeline.reset();
|
|
2178
|
+
this.searchPipeline.reset();
|
|
2179
|
+
results.forEach((result) => {
|
|
2180
|
+
const content = result.contentByLocale.find((d) => d.locale === locale);
|
|
2181
|
+
if (content) {
|
|
2182
|
+
const payload = {
|
|
2183
|
+
id: result.id,
|
|
2184
|
+
content_id: result.content_id,
|
|
2185
|
+
name: content.name,
|
|
2186
|
+
keywords: content.keywords,
|
|
2187
|
+
attributes: content.attributes
|
|
2188
|
+
};
|
|
2189
|
+
this.add(payload, { boost: result.zvalue });
|
|
2190
|
+
}
|
|
2191
|
+
}, this);
|
|
2192
|
+
}
|
|
2193
|
+
)
|
|
2194
|
+
}
|
|
2195
|
+
];
|
|
2177
2196
|
});
|
|
2178
2197
|
return Object.fromEntries(
|
|
2179
2198
|
await Promise.all(setups)
|
|
@@ -2205,8 +2224,10 @@ function dbSearchMemberFactory(db) {
|
|
|
2205
2224
|
direction = "ASC"
|
|
2206
2225
|
} = params;
|
|
2207
2226
|
if (query && query !== "" && searchIndexByLocale[locale]) {
|
|
2208
|
-
const terms = query.split(" ").
|
|
2209
|
-
|
|
2227
|
+
const terms = query.split(" ").filter((d) => d.trim() !== "").map((d) => {
|
|
2228
|
+
return `+${d}~2*`;
|
|
2229
|
+
}).join(" ");
|
|
2230
|
+
const lunrResults = searchIndexByLocale[locale].index.search(terms);
|
|
2210
2231
|
resultsIds = lunrResults.map((d) => parseInt(d.ref, 10));
|
|
2211
2232
|
}
|
|
2212
2233
|
const whereClause = {
|
|
@@ -4612,12 +4633,13 @@ function getRootBlocksForSection(sid, blocks) {
|
|
|
4612
4633
|
blockList.filter((block) => block.section_id === sid && // leave blocks belonging to this section
|
|
4613
4634
|
// that don't depend on any other blocks OR
|
|
4614
4635
|
(block.inputs.length === 0 || // that depend only on blocks from other sections
|
|
4615
|
-
block.inputs.
|
|
4636
|
+
block.inputs.some((id) => nonNativeBlocks.includes(id)))).map((block) => [block.id, block])
|
|
4616
4637
|
// then convert them to entries
|
|
4617
4638
|
);
|
|
4618
4639
|
}
|
|
4619
4640
|
var getRootBlocksForSection_default = getRootBlocksForSection;
|
|
4620
4641
|
var verbose7 = getLogging_default();
|
|
4642
|
+
var debug = yn3(process.env.NEXT_PUBLIC_REPORTS_DEBUG);
|
|
4621
4643
|
var ORIGIN = process.env.REPORTS_ORIGIN || "";
|
|
4622
4644
|
axios5.interceptors.request.use((config) => ({
|
|
4623
4645
|
...config,
|
|
@@ -4721,14 +4743,7 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
4721
4743
|
return {
|
|
4722
4744
|
outputVariables: {},
|
|
4723
4745
|
renderVariables: {},
|
|
4724
|
-
status: {
|
|
4725
|
-
api: null,
|
|
4726
|
-
duration: null,
|
|
4727
|
-
resp: null,
|
|
4728
|
-
log: [],
|
|
4729
|
-
error: null,
|
|
4730
|
-
allowed: false
|
|
4731
|
-
}
|
|
4746
|
+
status: { allowed: false }
|
|
4732
4747
|
};
|
|
4733
4748
|
}
|
|
4734
4749
|
if (unswappedAPI) {
|
|
@@ -4759,9 +4774,6 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
4759
4774
|
outputVariables: selectorQueryToVariable_default(block.id, query, config),
|
|
4760
4775
|
renderVariables: config,
|
|
4761
4776
|
status: {
|
|
4762
|
-
api: null,
|
|
4763
|
-
duration: null,
|
|
4764
|
-
resp: null,
|
|
4765
4777
|
log: log2,
|
|
4766
4778
|
error: error2,
|
|
4767
4779
|
allowed
|
|
@@ -4774,11 +4786,8 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
4774
4786
|
// todo1.0 this will have to be materialized click-variables
|
|
4775
4787
|
renderVariables: block.contentByLocale.logic.content,
|
|
4776
4788
|
status: {
|
|
4777
|
-
api: null,
|
|
4778
|
-
duration: null,
|
|
4779
|
-
resp: null,
|
|
4780
4789
|
log: [],
|
|
4781
|
-
|
|
4790
|
+
// todo: see if we can remove this safely
|
|
4782
4791
|
allowed
|
|
4783
4792
|
}
|
|
4784
4793
|
};
|
|
@@ -4818,10 +4827,7 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
4818
4827
|
var getDependencies = (bid, blocks, acc = [], crawlUp = true, crawlDown2 = true, withinSection = true, visited = []) => {
|
|
4819
4828
|
if (visited.includes(bid))
|
|
4820
4829
|
return [];
|
|
4821
|
-
|
|
4822
|
-
visited.push(bid);
|
|
4823
|
-
if (verbose7)
|
|
4824
|
-
console.log("%cpassing through block", "color:green", bid);
|
|
4830
|
+
visited.push(bid);
|
|
4825
4831
|
const rootBlock = blocks[bid];
|
|
4826
4832
|
if (rootBlock.inputs.length && crawlUp) {
|
|
4827
4833
|
rootBlock.inputs.forEach((iid) => {
|
|
@@ -4838,7 +4844,7 @@ var getDependencies = (bid, blocks, acc = [], crawlUp = true, crawlDown2 = true,
|
|
|
4838
4844
|
if (!acc.includes(rel) && (blocks[cid].section_id === blocks[bid].section_id || !withinSection)) {
|
|
4839
4845
|
acc.push(rel);
|
|
4840
4846
|
}
|
|
4841
|
-
rootBlock.consumers.filter((cid2) => blocks[cid2].section_id === blocks[bid].section_id || !withinSection).forEach((cid2) => getDependencies(cid2, blocks, acc,
|
|
4847
|
+
rootBlock.consumers.filter((cid2) => blocks[cid2].section_id === blocks[bid].section_id || !withinSection).forEach((cid2) => getDependencies(cid2, blocks, acc, false, crawlDown2, withinSection, visited));
|
|
4842
4848
|
});
|
|
4843
4849
|
}
|
|
4844
4850
|
return acc;
|
|
@@ -4871,22 +4877,31 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
|
|
|
4871
4877
|
const statusById = { ...initialState4.status ?? {} };
|
|
4872
4878
|
const parsedBlockContext = parseBlockContext(blockContext);
|
|
4873
4879
|
const attributes = parsedBlockContext.variables;
|
|
4874
|
-
const rootBlocks = bid ? { [bid]: blocks[bid] } : sections.reduce((rootBlocks2, { id }) => ({ ...rootBlocks2, ...getRootBlocksForSection_default(id, blocks) }), {});
|
|
4875
|
-
if (
|
|
4876
|
-
console.log("%crunConsumers: running root blocks", "color:
|
|
4880
|
+
const rootBlocks = bid ? { [bid]: blocks[bid] } : (sections ?? []).reduce((rootBlocks2, { id }) => ({ ...rootBlocks2, ...getRootBlocksForSection_default(id, blocks) }), {});
|
|
4881
|
+
if (debug)
|
|
4882
|
+
console.log("%crunConsumers: running root blocks", "color:purple", Object.keys(rootBlocks));
|
|
4877
4883
|
const withinSection = mode === "section";
|
|
4878
4884
|
const blockDeps = Object.keys(rootBlocks).reduce((deps, id) => {
|
|
4879
|
-
|
|
4880
|
-
console.log("%cresolving dependencies for", "color:red", id);
|
|
4885
|
+
const start = /* @__PURE__ */ new Date();
|
|
4881
4886
|
const dependencies = getDependencies(Number(id), blocks, [], !bid, true, withinSection).map((rel) => rel.split("-"));
|
|
4887
|
+
const end = /* @__PURE__ */ new Date();
|
|
4888
|
+
const elapsedTime = (end.getTime() - start.getTime()) / 1e3;
|
|
4889
|
+
if (debug)
|
|
4890
|
+
console.log(
|
|
4891
|
+
`%cResolved dependencies for ${id} (${elapsedTime.toFixed(2)}s)`,
|
|
4892
|
+
"color:blue"
|
|
4893
|
+
);
|
|
4882
4894
|
return [...deps, ...dependencies];
|
|
4883
4895
|
}, []);
|
|
4896
|
+
const startToposort = /* @__PURE__ */ new Date();
|
|
4884
4897
|
const orderedDAG = Object.keys(rootBlocks).reduce(
|
|
4885
4898
|
(orderedDAG2, bid2) => orderedDAG2.includes(bid2) ? [...orderedDAG2] : [bid2, ...orderedDAG2],
|
|
4886
4899
|
toposort(blockDeps)
|
|
4887
4900
|
);
|
|
4888
|
-
|
|
4889
|
-
|
|
4901
|
+
const endToposort = /* @__PURE__ */ new Date();
|
|
4902
|
+
const toposortTime = (endToposort.getTime() - startToposort.getTime()) / 1e3;
|
|
4903
|
+
if (debug)
|
|
4904
|
+
console.log(`%cResolved DAG (${toposortTime.toFixed(2)}s): `, "color:green", orderedDAG);
|
|
4890
4905
|
async function runTasksInParallel(executionOrder, blocks2) {
|
|
4891
4906
|
const runningBlocks = /* @__PURE__ */ new Map();
|
|
4892
4907
|
for (const bid2 of executionOrder) {
|
|
@@ -4894,22 +4909,21 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
|
|
|
4894
4909
|
const dependenciesDone = Promise.all(
|
|
4895
4910
|
block.inputs.filter((iid) => executionOrder.includes(String(iid))).map((iid) => runningBlocks.get(Number(iid)))
|
|
4896
4911
|
);
|
|
4897
|
-
const runningTask = dependenciesDone.then(() => {
|
|
4912
|
+
const runningTask = dependenciesDone.then(async () => {
|
|
4898
4913
|
const variables = block.inputs.reduce((acc, d) => ({ ...acc, ...variablesById[d] }), attributes);
|
|
4899
|
-
const inputNotAllowed = block.inputs.find(
|
|
4914
|
+
const inputNotAllowed = block.inputs.find(
|
|
4915
|
+
(iid) => !statusById[iid].allowed || statusById[iid].hiddenByCascade
|
|
4916
|
+
);
|
|
4900
4917
|
if (inputNotAllowed) {
|
|
4901
4918
|
statusById[bid2] = {
|
|
4902
|
-
api: null,
|
|
4903
|
-
duration: null,
|
|
4904
|
-
resp: null,
|
|
4905
4919
|
log: [],
|
|
4906
|
-
error: null,
|
|
4907
4920
|
allowed: false,
|
|
4908
4921
|
hiddenByCascade: statusById[inputNotAllowed].hiddenByCascade || inputNotAllowed
|
|
4909
4922
|
};
|
|
4910
4923
|
return;
|
|
4911
4924
|
}
|
|
4912
|
-
|
|
4925
|
+
const startBlock = /* @__PURE__ */ new Date();
|
|
4926
|
+
const blockResult = await runSingleBlock(
|
|
4913
4927
|
block,
|
|
4914
4928
|
formatterFunctions,
|
|
4915
4929
|
{
|
|
@@ -4921,12 +4935,25 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
|
|
|
4921
4935
|
variablesById[bid2] = outputVariables;
|
|
4922
4936
|
statusById[bid2] = status;
|
|
4923
4937
|
});
|
|
4938
|
+
const endBlock = /* @__PURE__ */ new Date();
|
|
4939
|
+
const blockTime = (endBlock.getTime() - startBlock.getTime()) / 1e3;
|
|
4940
|
+
if (debug)
|
|
4941
|
+
console.log(
|
|
4942
|
+
`%cBlock ${block.id} resolved in ${blockTime.toFixed(3)}s`,
|
|
4943
|
+
blockTime > 500 ? "color:red" : "color:green"
|
|
4944
|
+
);
|
|
4945
|
+
return blockResult;
|
|
4924
4946
|
});
|
|
4925
4947
|
runningBlocks.set(Number(bid2), runningTask);
|
|
4926
4948
|
}
|
|
4927
4949
|
await Promise.all(Array.from(runningBlocks.values()));
|
|
4928
4950
|
}
|
|
4951
|
+
const startVariables = /* @__PURE__ */ new Date();
|
|
4929
4952
|
await runTasksInParallel(orderedDAG, blocks);
|
|
4953
|
+
const endVariables = /* @__PURE__ */ new Date();
|
|
4954
|
+
const variablesTime = (endVariables.getTime() - startVariables.getTime()) / 1e3;
|
|
4955
|
+
if (debug)
|
|
4956
|
+
console.log(`%cResolved Variables (${variablesTime.toFixed(2)}s): `, "color:green");
|
|
4930
4957
|
return {
|
|
4931
4958
|
variables: { ...initialState4.variables ?? {}, ...variablesById },
|
|
4932
4959
|
status: { ...initialState4.status ?? {}, ...statusById }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datawheel/bespoke",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.31",
|
|
4
4
|
"description": "Content management system for creating automated data reports",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
"slugify": "^1.6.5",
|
|
104
104
|
"toposort": "^2.0.2",
|
|
105
105
|
"unsplash-js": "^7.0.15",
|
|
106
|
-
"xlsx": "
|
|
106
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz",
|
|
107
107
|
"yn": "^5.0.0"
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|