@datawheel/bespoke 0.1.38 → 0.2.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.
- package/dist/index.js +394 -75
- package/dist/server.js +117 -5
- package/package.json +1 -1
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, 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,
|
|
19
|
+
import { Stack, Text, Badge, Group, useMantineTheme, Flex, packSx, Title, Tooltip, ActionIcon, Center, Modal, Button, SegmentedControl, Select, MultiSelect, Grid, Card, Image, Radio, NumberInput, TextInput, Switch, Box, List, Menu, Anchor, MantineProvider, Divider, Burger, Navbar, ScrollArea, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Container, Loader, Alert, Collapse, Space, Code, Textarea, rem, Paper, Input, Popover, Checkbox, Drawer, Overlay, SimpleGrid, Autocomplete, Tabs, Header, px, FileInput, Accordion, HoverCard, CopyButton, 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, 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, IconLinkOff } 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, IconHome, IconX, IconChevronDown, IconCamera, IconShare, IconCircleDashed, IconListSearch, IconExternalLink, IconSettings, IconFileOff, IconFilesOff, IconHierarchy3, IconMenu, IconApi, IconPolaroid, IconCircleMinus, IconEyeOff, IconPhoto, IconChevronLeft, IconChevronRight, IconLogin, IconWorld, IconLock, IconVariable, IconArrowRightCircle, IconDownload, IconTemplate, IconChartBar, IconCode, IconUpload, IconCodePlus, IconClipboardCheck, IconClipboardCopy, IconPalette, IconEye, IconMinimize, IconMaximize, IconRss, IconGlobe, IconLinkOff } 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';
|
|
@@ -205,6 +205,9 @@ var init_http = __esm({
|
|
|
205
205
|
).join(",");
|
|
206
206
|
return { ...params, slugs };
|
|
207
207
|
}
|
|
208
|
+
if (params.mode === "related") {
|
|
209
|
+
return { ...params };
|
|
210
|
+
}
|
|
208
211
|
return { ...params, [params.mode]: params[params.mode].join(",") };
|
|
209
212
|
};
|
|
210
213
|
}
|
|
@@ -360,6 +363,7 @@ var init_cms = __esm({
|
|
|
360
363
|
};
|
|
361
364
|
BLOCK_LOGIC_TYPES = {
|
|
362
365
|
GENERATOR: "generator",
|
|
366
|
+
RELATED: "related",
|
|
363
367
|
VIZ: "visualization"
|
|
364
368
|
};
|
|
365
369
|
BLOCK_LOGIC_LOCALE = "logic";
|
|
@@ -1168,6 +1172,80 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
1168
1172
|
}
|
|
1169
1173
|
};
|
|
1170
1174
|
}
|
|
1175
|
+
if (block.type === BLOCK_TYPES.RELATED) {
|
|
1176
|
+
const relatedCompare = block.contentByLocale?.logic?.content?.simple?.compare || "variant";
|
|
1177
|
+
const relatedLimit = block.contentByLocale?.logic?.content?.simple?.limit || 4;
|
|
1178
|
+
const reportIds = Object.keys(variables).filter((key) => key.startsWith("report_id")).map((key) => variables[key]);
|
|
1179
|
+
const dimensionIds = Object.keys(variables).filter((key) => key.startsWith("dimension_id")).map((key) => variables[key]);
|
|
1180
|
+
const variantIds = Object.keys(variables).filter((key) => key.startsWith("variant_id")).map((key) => variables[key]);
|
|
1181
|
+
const memberIds = Object.keys(variables).filter((key) => key.startsWith("id")).map((key) => variables[key]);
|
|
1182
|
+
if (!memberIds.length)
|
|
1183
|
+
return {
|
|
1184
|
+
outputVariables: { related_reports: [] },
|
|
1185
|
+
renderVariables: {},
|
|
1186
|
+
status: {
|
|
1187
|
+
log: [],
|
|
1188
|
+
allowed: false
|
|
1189
|
+
}
|
|
1190
|
+
};
|
|
1191
|
+
const membersContentIds = await readMemberFn({
|
|
1192
|
+
mode: "ids",
|
|
1193
|
+
locale,
|
|
1194
|
+
ids: memberIds,
|
|
1195
|
+
output: "lite"
|
|
1196
|
+
}).then((response) => {
|
|
1197
|
+
let data = [];
|
|
1198
|
+
if (isResult(response)) {
|
|
1199
|
+
if (response.ok) {
|
|
1200
|
+
data = response.data.results;
|
|
1201
|
+
}
|
|
1202
|
+
} else {
|
|
1203
|
+
data = response.results;
|
|
1204
|
+
}
|
|
1205
|
+
return data && Array.isArray(data) ? data : [];
|
|
1206
|
+
}).catch((err) => {
|
|
1207
|
+
console.log("Error getting related members", err);
|
|
1208
|
+
return [];
|
|
1209
|
+
});
|
|
1210
|
+
const current_ids = membersContentIds.map((member) => member.content_id);
|
|
1211
|
+
const memberParams = {
|
|
1212
|
+
mode: "related",
|
|
1213
|
+
locale,
|
|
1214
|
+
related: relatedLimit ?? 4,
|
|
1215
|
+
current_ids,
|
|
1216
|
+
output: "full"
|
|
1217
|
+
};
|
|
1218
|
+
if (relatedCompare) {
|
|
1219
|
+
if (relatedCompare === "report")
|
|
1220
|
+
memberParams.report_ids = reportIds;
|
|
1221
|
+
else if (relatedCompare === "dimension")
|
|
1222
|
+
memberParams.dimension_ids = dimensionIds;
|
|
1223
|
+
else
|
|
1224
|
+
memberParams.variant_ids = variantIds;
|
|
1225
|
+
}
|
|
1226
|
+
const bespokeMembers = await readMemberFn(memberParams).then((response) => {
|
|
1227
|
+
let data = [];
|
|
1228
|
+
if (isResult(response)) {
|
|
1229
|
+
if (response.ok) {
|
|
1230
|
+
data = response.data.results;
|
|
1231
|
+
}
|
|
1232
|
+
} else {
|
|
1233
|
+
data = response.results;
|
|
1234
|
+
}
|
|
1235
|
+
return data && Array.isArray(data) ? data : [];
|
|
1236
|
+
}).catch((err) => {
|
|
1237
|
+
console.log("Error getting related members", err);
|
|
1238
|
+
return [];
|
|
1239
|
+
});
|
|
1240
|
+
return {
|
|
1241
|
+
outputVariables: { related_reports: bespokeMembers },
|
|
1242
|
+
renderVariables: {},
|
|
1243
|
+
status: {
|
|
1244
|
+
log: [],
|
|
1245
|
+
allowed: bespokeMembers.length > 0
|
|
1246
|
+
}
|
|
1247
|
+
};
|
|
1248
|
+
}
|
|
1171
1249
|
const { logic } = getBlockContent(block, locale);
|
|
1172
1250
|
const swappedLogic = varSwap_default(logic, formatterFunctions, blockContext);
|
|
1173
1251
|
const evalResults = mortarEval_default("resp", resp || {}, swappedLogic, formatterFunctions, variables, blockContext);
|
|
@@ -1345,7 +1423,7 @@ var init_runConsumers = __esm({
|
|
|
1345
1423
|
).then(({ outputVariables, status }) => {
|
|
1346
1424
|
if (
|
|
1347
1425
|
// store output variables for block that:
|
|
1348
|
-
(block.consumers.length > 0 ||
|
|
1426
|
+
(block.consumers.length > 0 || [BLOCK_TYPES.GENERATOR, BLOCK_TYPES.RELATED].includes(block.type)) && status.allowed && Object.keys(outputVariables).length > 0
|
|
1349
1427
|
)
|
|
1350
1428
|
variablesById[bid2] = outputVariables;
|
|
1351
1429
|
if (mode === "report") {
|
|
@@ -4276,9 +4354,11 @@ function useContentOutline(min = 1, max = 6, headings = []) {
|
|
|
4276
4354
|
blocks.sort((a, b) => orderSort(a, b, "blockrow"))
|
|
4277
4355
|
);
|
|
4278
4356
|
});
|
|
4357
|
+
if (!Object.keys(status).length)
|
|
4358
|
+
return [];
|
|
4279
4359
|
return titleBlocksNormalized.filter((title) => {
|
|
4280
4360
|
const currentOrder = parseInt(title.settings.order || "1", 10);
|
|
4281
|
-
return currentOrder >= min && currentOrder <= max && titleStatus[title.id]
|
|
4361
|
+
return currentOrder >= min && currentOrder <= max && titleStatus[title.id]?.allowed && !titleStatus[title.id]?.hiddenByCascade;
|
|
4282
4362
|
});
|
|
4283
4363
|
}
|
|
4284
4364
|
}, [headings, sectionList, titleBlocks, titleStatus]);
|
|
@@ -4399,6 +4479,54 @@ function NavView({ headings, settings }) {
|
|
|
4399
4479
|
return smallerThanMd ? /* @__PURE__ */ jsx(MobileNav, { contentOutline }) : /* @__PURE__ */ jsx(DesktopNav, { contentOutline });
|
|
4400
4480
|
}
|
|
4401
4481
|
|
|
4482
|
+
// frontend/components/report/blocks/Related.tsx
|
|
4483
|
+
init_esm_shims();
|
|
4484
|
+
init_store2();
|
|
4485
|
+
init_hooks();
|
|
4486
|
+
function RelatedView(props) {
|
|
4487
|
+
const { related_reports } = props;
|
|
4488
|
+
const currentLocale = useAppSelector((state) => state.status.currentLocale);
|
|
4489
|
+
const localeDefault9 = useAppSelector((state) => state.status.localeDefault);
|
|
4490
|
+
const profilePrefix = useProfilePrefix();
|
|
4491
|
+
const router = useRouter();
|
|
4492
|
+
if (!related_reports?.length)
|
|
4493
|
+
return;
|
|
4494
|
+
const localePrefix = currentLocale === localeDefault9 ? "" : `/${currentLocale}`;
|
|
4495
|
+
const onItemSubmit = (innerUrl) => {
|
|
4496
|
+
router.push(`${innerUrl}`);
|
|
4497
|
+
};
|
|
4498
|
+
return /* @__PURE__ */ jsx(Grid, { children: related_reports.map((report) => {
|
|
4499
|
+
const url = `${localePrefix}${profilePrefix}/${report.variant_slug}/${report.slug}`;
|
|
4500
|
+
return /* @__PURE__ */ jsx(Grid.Col, { xs: 12, sm: 6, md: 4, lg: 4, xl: 3, children: /* @__PURE__ */ jsxs(Card, { shadow: "sm", p: "lg", radius: "md", withBorder: true, children: [
|
|
4501
|
+
/* @__PURE__ */ jsx(Card.Section, { children: /* @__PURE__ */ jsx(Group, { grow: true, spacing: 0, children: /* @__PURE__ */ jsx(
|
|
4502
|
+
Image,
|
|
4503
|
+
{
|
|
4504
|
+
src: `/api/cms/member/image.png?member=${report.content_id}&size=thumb`,
|
|
4505
|
+
height: 160,
|
|
4506
|
+
imageProps: { loading: "lazy" },
|
|
4507
|
+
alt: report.name
|
|
4508
|
+
},
|
|
4509
|
+
report.content_id
|
|
4510
|
+
) }) }),
|
|
4511
|
+
/* @__PURE__ */ jsx(Group, { position: "apart", mt: "md", mb: "xs", children: /* @__PURE__ */ jsxs(Stack, { children: [
|
|
4512
|
+
/* @__PURE__ */ jsx(Text, { weight: 500, children: report.name }),
|
|
4513
|
+
/* @__PURE__ */ jsx(Badge, { color: "green", variant: "light", children: report.variant_name })
|
|
4514
|
+
] }, report.content_id) }),
|
|
4515
|
+
/* @__PURE__ */ jsx(
|
|
4516
|
+
"a",
|
|
4517
|
+
{
|
|
4518
|
+
href: url,
|
|
4519
|
+
onClick: (evt) => {
|
|
4520
|
+
evt.preventDefault();
|
|
4521
|
+
onItemSubmit(url);
|
|
4522
|
+
},
|
|
4523
|
+
children: /* @__PURE__ */ jsx(Button, { variant: "light", color: "blue", fullWidth: true, mt: "md", radius: "md", children: `See ${report.name} Report` })
|
|
4524
|
+
}
|
|
4525
|
+
)
|
|
4526
|
+
] }) }, report.content_id);
|
|
4527
|
+
}) });
|
|
4528
|
+
}
|
|
4529
|
+
|
|
4402
4530
|
// frontend/components/report/blocks/ResetButton.tsx
|
|
4403
4531
|
init_esm_shims();
|
|
4404
4532
|
init_hooks();
|
|
@@ -4438,6 +4566,7 @@ var TypeRenderers = {
|
|
|
4438
4566
|
[BLOCK_TYPES.GENERATOR]: Generator,
|
|
4439
4567
|
[BLOCK_TYPES.IMAGE]: ImageView,
|
|
4440
4568
|
[BLOCK_TYPES.NAV]: NavView,
|
|
4569
|
+
[BLOCK_TYPES.RELATED]: RelatedView,
|
|
4441
4570
|
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonView
|
|
4442
4571
|
};
|
|
4443
4572
|
var blocks_default = TypeRenderers;
|
|
@@ -4870,6 +4999,46 @@ function NavUI() {
|
|
|
4870
4999
|
return /* @__PURE__ */ jsx(Title, { order: 4, children: "Nav UI" });
|
|
4871
5000
|
}
|
|
4872
5001
|
|
|
5002
|
+
// components/blocks/types/simpleEditors/RelatedUI.tsx
|
|
5003
|
+
init_esm_shims();
|
|
5004
|
+
function RelatedUI({ executeButton, onChange, simpleState }) {
|
|
5005
|
+
const [compare, setCompare] = useState(simpleState?.compare ?? "variant");
|
|
5006
|
+
const [limit, setLimit] = useState(simpleState?.limit ?? 4);
|
|
5007
|
+
useEffect(() => {
|
|
5008
|
+
const simpleState2 = {
|
|
5009
|
+
compare,
|
|
5010
|
+
limit
|
|
5011
|
+
};
|
|
5012
|
+
onChange(simpleState2);
|
|
5013
|
+
}, [compare, limit]);
|
|
5014
|
+
return /* @__PURE__ */ jsxs(Stack, { children: [
|
|
5015
|
+
/* @__PURE__ */ jsx(
|
|
5016
|
+
Radio.Group,
|
|
5017
|
+
{
|
|
5018
|
+
label: "Compare with members of",
|
|
5019
|
+
onChange: setCompare,
|
|
5020
|
+
value: compare,
|
|
5021
|
+
children: /* @__PURE__ */ jsxs(Group, { children: [
|
|
5022
|
+
/* @__PURE__ */ jsx(Radio, { label: "Same report", value: "report" }),
|
|
5023
|
+
/* @__PURE__ */ jsx(Radio, { label: "Same dimension", value: "dimension" }),
|
|
5024
|
+
/* @__PURE__ */ jsx(Radio, { label: "Same variant", value: "variant" })
|
|
5025
|
+
] })
|
|
5026
|
+
}
|
|
5027
|
+
),
|
|
5028
|
+
/* @__PURE__ */ jsx(
|
|
5029
|
+
NumberInput,
|
|
5030
|
+
{
|
|
5031
|
+
label: "Related reports limit",
|
|
5032
|
+
min: 1,
|
|
5033
|
+
onChange: (value) => setLimit(value),
|
|
5034
|
+
type: "number",
|
|
5035
|
+
value: limit
|
|
5036
|
+
}
|
|
5037
|
+
),
|
|
5038
|
+
executeButton
|
|
5039
|
+
] });
|
|
5040
|
+
}
|
|
5041
|
+
|
|
4873
5042
|
// components/blocks/types/simpleEditors/ResetButtonUI.tsx
|
|
4874
5043
|
init_esm_shims();
|
|
4875
5044
|
function ResetButtonUI({ id, locale, executeButton, onChange, simpleState }) {
|
|
@@ -4930,6 +5099,7 @@ function ResetButtonUI({ id, locale, executeButton, onChange, simpleState }) {
|
|
|
4930
5099
|
var simpleEditors_default = {
|
|
4931
5100
|
[BLOCK_TYPES.SELECTOR]: SelectorUI_default,
|
|
4932
5101
|
[BLOCK_TYPES.NAV]: NavUI,
|
|
5102
|
+
[BLOCK_TYPES.RELATED]: RelatedUI,
|
|
4933
5103
|
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonUI
|
|
4934
5104
|
};
|
|
4935
5105
|
|
|
@@ -5438,6 +5608,15 @@ function NavPreview({ headings, settings }) {
|
|
|
5438
5608
|
] });
|
|
5439
5609
|
}
|
|
5440
5610
|
|
|
5611
|
+
// components/blocks/types/renderers/Related.tsx
|
|
5612
|
+
init_esm_shims();
|
|
5613
|
+
function RelatedPreview(props) {
|
|
5614
|
+
const { related_reports } = props;
|
|
5615
|
+
if (!related_reports?.length)
|
|
5616
|
+
return /* @__PURE__ */ jsx(Text, { children: "There are no available members related to your current selection and report." });
|
|
5617
|
+
return /* @__PURE__ */ jsx(List, { children: related_reports.map((report) => /* @__PURE__ */ jsx(List.Item, { children: report.name }, report.content_id)) });
|
|
5618
|
+
}
|
|
5619
|
+
|
|
5441
5620
|
// components/blocks/types/renderers/ResetButton.tsx
|
|
5442
5621
|
init_esm_shims();
|
|
5443
5622
|
init_hooks();
|
|
@@ -5478,6 +5657,7 @@ var renderersMap = {
|
|
|
5478
5657
|
[BLOCK_TYPES.GENERATOR]: Generator_default,
|
|
5479
5658
|
[BLOCK_TYPES.IMAGE]: ImagePreview,
|
|
5480
5659
|
[BLOCK_TYPES.NAV]: NavPreview,
|
|
5660
|
+
[BLOCK_TYPES.RELATED]: RelatedPreview,
|
|
5481
5661
|
[BLOCK_TYPES.RESET_BUTTON]: ResetButtonPreview
|
|
5482
5662
|
};
|
|
5483
5663
|
var renderers_default = renderersMap;
|
|
@@ -5506,6 +5686,12 @@ var allBlocks = {
|
|
|
5506
5686
|
renderPreviewOnEdit: true,
|
|
5507
5687
|
evalWhenNonActive: true
|
|
5508
5688
|
},
|
|
5689
|
+
[BLOCK_TYPES.RELATED]: {
|
|
5690
|
+
type: BLOCK_TYPES.RELATED,
|
|
5691
|
+
renderer: renderers_default[BLOCK_TYPES.RELATED],
|
|
5692
|
+
renderPreviewOnEdit: false,
|
|
5693
|
+
evalWhenNonActive: true
|
|
5694
|
+
},
|
|
5509
5695
|
[BLOCK_TYPES.SELECTOR]: {
|
|
5510
5696
|
type: BLOCK_TYPES.SELECTOR,
|
|
5511
5697
|
renderer: renderers_default[BLOCK_TYPES.SELECTOR],
|
|
@@ -5633,6 +5819,11 @@ function Block({ blockId, active = true }) {
|
|
|
5633
5819
|
});
|
|
5634
5820
|
return;
|
|
5635
5821
|
}
|
|
5822
|
+
if (block.type === BLOCK_TYPES.RELATED) {
|
|
5823
|
+
const { related_reports } = generatorVariables;
|
|
5824
|
+
setContent({ related_reports });
|
|
5825
|
+
return;
|
|
5826
|
+
}
|
|
5636
5827
|
if (block.type === BLOCK_TYPES.RESET_BUTTON) {
|
|
5637
5828
|
setContent({ id: block.id, ...blockContent.simple });
|
|
5638
5829
|
return;
|
|
@@ -7183,6 +7374,7 @@ function Section({ section }) {
|
|
|
7183
7374
|
};
|
|
7184
7375
|
const state = useAppSelector((state2) => state2);
|
|
7185
7376
|
const status = useAppSelector((state2) => state2.variables.status);
|
|
7377
|
+
const previews = useAppSelector((state2) => state2.status.previews);
|
|
7186
7378
|
const sectionStyles = useBespokeStyles()["Section"];
|
|
7187
7379
|
const blockRecords = selectBlockRecords(state);
|
|
7188
7380
|
const sectionBlocks = Object.values(blockRecords || {}).filter((d) => d.section_id === id);
|
|
@@ -7206,6 +7398,7 @@ function Section({ section }) {
|
|
|
7206
7398
|
const colsQty = Object.keys(columns).length;
|
|
7207
7399
|
if (!displaySection)
|
|
7208
7400
|
return null;
|
|
7401
|
+
const showCredits = sectionSettings2.memberImageBg && previews.some(({ image }) => image && (image.url || image.author));
|
|
7209
7402
|
return /* @__PURE__ */ jsxs(
|
|
7210
7403
|
PositionWrapper,
|
|
7211
7404
|
{
|
|
@@ -7227,53 +7420,82 @@ function Section({ section }) {
|
|
|
7227
7420
|
/* @__PURE__ */ jsx(SectionResetButton, { id: section.id }),
|
|
7228
7421
|
sectionSettings2.optionsMenu && /* @__PURE__ */ jsx(Options, { sectionId: section.id })
|
|
7229
7422
|
] }),
|
|
7230
|
-
/* @__PURE__ */
|
|
7423
|
+
/* @__PURE__ */ jsxs(
|
|
7231
7424
|
StyleWrapper,
|
|
7232
7425
|
{
|
|
7233
7426
|
className: `bespoke-Section-${id} bespoke-Section-container`,
|
|
7234
7427
|
settings: sectionSettings2,
|
|
7235
7428
|
styles: sectionStyles?.content,
|
|
7236
|
-
children:
|
|
7237
|
-
|
|
7238
|
-
|
|
7239
|
-
|
|
7240
|
-
|
|
7241
|
-
|
|
7242
|
-
|
|
7243
|
-
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7248
|
-
|
|
7249
|
-
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
|
|
7263
|
-
|
|
7264
|
-
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
|
|
7429
|
+
children: [
|
|
7430
|
+
/* @__PURE__ */ jsx(ColumnsWrapper, { children: Object.keys(columns).sort((a, b) => orderSort(a, b, "blockcol")).map((columnIndex) => {
|
|
7431
|
+
const column = columns[columnIndex];
|
|
7432
|
+
const columnSettings = settings.columnSettings ? settings.columnSettings[columnIndex] : {};
|
|
7433
|
+
const columnBlocks = Object.values(column).sort((a, b) => orderSort(a, b, "blockrow"));
|
|
7434
|
+
if (!columnBlocks.some(
|
|
7435
|
+
(block) => status[block.id].allowed || block.type === BLOCK_TYPES.NAV
|
|
7436
|
+
))
|
|
7437
|
+
return null;
|
|
7438
|
+
return /* @__PURE__ */ jsx(
|
|
7439
|
+
SectionColumn,
|
|
7440
|
+
{
|
|
7441
|
+
column,
|
|
7442
|
+
columnSettings,
|
|
7443
|
+
sx: { flexBasis: `${100 / colsQty}%` },
|
|
7444
|
+
children: columnBlocks.map((item) => {
|
|
7445
|
+
if (!item.id || !status[item.id]?.allowed && item.type !== BLOCK_TYPES.NAV)
|
|
7446
|
+
return null;
|
|
7447
|
+
const { settings: settings2, type } = blockRecords[item.id];
|
|
7448
|
+
const blockWidth = settings2.width && !settings2.width.stretch && settings2.width.unit ? formatters[settings2.width.unit](settings2.width.value) : settings2.display === "inline" ? "auto" : "100%";
|
|
7449
|
+
const blockStyles = {
|
|
7450
|
+
alignSelf: type === "visualization" ? "stretch" : "flex-start",
|
|
7451
|
+
flexGrow: 0,
|
|
7452
|
+
margin: "0",
|
|
7453
|
+
textAlign: settings2.align || blockSettings.align.defaultValue,
|
|
7454
|
+
width: blockWidth,
|
|
7455
|
+
minWidth: 300
|
|
7456
|
+
};
|
|
7457
|
+
return /* @__PURE__ */ jsx(
|
|
7458
|
+
Box,
|
|
7459
|
+
{
|
|
7460
|
+
className: "bespoke-Block-wrapper",
|
|
7461
|
+
id: `bespoke-Block-${item.id}`,
|
|
7462
|
+
sx: blockStyles,
|
|
7463
|
+
py: site_default.block.padding,
|
|
7464
|
+
children: /* @__PURE__ */ jsx(Block, { blockId: item.id }, item.id)
|
|
7465
|
+
},
|
|
7466
|
+
item.id
|
|
7467
|
+
);
|
|
7468
|
+
})
|
|
7469
|
+
},
|
|
7470
|
+
columnIndex
|
|
7471
|
+
);
|
|
7472
|
+
}) }),
|
|
7473
|
+
showCredits && /* @__PURE__ */ jsxs(Popover, { position: "right", children: [
|
|
7474
|
+
/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(ActionIcon, { variant: "light", radius: "xl", children: /* @__PURE__ */ jsx(IconPhoto, { size: 20 }) }) }),
|
|
7475
|
+
/* @__PURE__ */ jsx(Popover.Dropdown, { children: previews.map(
|
|
7476
|
+
({ image, name }, idx) => (image.author || image.url) && /* @__PURE__ */ jsxs("div", { children: [
|
|
7477
|
+
image.author && /* @__PURE__ */ jsxs(Text, { size: "xs", children: [
|
|
7478
|
+
name,
|
|
7479
|
+
" image by ",
|
|
7480
|
+
/* @__PURE__ */ jsx("strong", { children: image.author })
|
|
7481
|
+
] }),
|
|
7482
|
+
image.url && /* @__PURE__ */ jsxs(Text, { size: "xs", children: [
|
|
7483
|
+
"URL: ",
|
|
7484
|
+
" ",
|
|
7485
|
+
/* @__PURE__ */ jsx(
|
|
7486
|
+
Anchor,
|
|
7487
|
+
{
|
|
7488
|
+
href: image.url,
|
|
7489
|
+
target: "_blank",
|
|
7490
|
+
children: image.url
|
|
7491
|
+
}
|
|
7492
|
+
)
|
|
7493
|
+
] }),
|
|
7494
|
+
idx + 1 < previews.length && /* @__PURE__ */ jsx(Divider, {})
|
|
7495
|
+
] }, image.image_id)
|
|
7496
|
+
) })
|
|
7497
|
+
] })
|
|
7498
|
+
]
|
|
7277
7499
|
}
|
|
7278
7500
|
)
|
|
7279
7501
|
]
|
|
@@ -7542,6 +7764,7 @@ function parseReadMemberParams(query) {
|
|
|
7542
7764
|
const mode = normalizeList(query.mode)[0];
|
|
7543
7765
|
const outputParam = normalizeList(query.output)[0] || "full";
|
|
7544
7766
|
const output = outputParam === "lite" ? "lite" : "full";
|
|
7767
|
+
const relatedLimit = parseInt(normalizeList(query.related)[0], 10) || 5;
|
|
7545
7768
|
let variant = normalizeList(query.variant).map(parseFiniteNumber);
|
|
7546
7769
|
if (variant.length === 0) {
|
|
7547
7770
|
variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
|
|
@@ -7579,6 +7802,19 @@ function parseReadMemberParams(query) {
|
|
|
7579
7802
|
})
|
|
7580
7803
|
};
|
|
7581
7804
|
}
|
|
7805
|
+
if (mode === "related") {
|
|
7806
|
+
return {
|
|
7807
|
+
all,
|
|
7808
|
+
mode,
|
|
7809
|
+
locale: all ? localeDefault8 : stripHTML(locale),
|
|
7810
|
+
related: relatedLimit,
|
|
7811
|
+
current_ids: normalizeList(query.current_ids || query["current_ids[]"]).map(parseFiniteNumber),
|
|
7812
|
+
report_ids: normalizeList(query.report_ids || query["report_ids[]"]).map(parseFiniteNumber),
|
|
7813
|
+
dimension_ids: normalizeList(query.dimension_ids || query["dimension_ids[]"]).map(parseFiniteNumber),
|
|
7814
|
+
variant_ids: normalizeList(query.variant_ids || query["variant_ids[]"]).map(parseFiniteNumber),
|
|
7815
|
+
output
|
|
7816
|
+
};
|
|
7817
|
+
}
|
|
7582
7818
|
throw new BackendError(400, `Invalid mode: '${mode}'`);
|
|
7583
7819
|
}
|
|
7584
7820
|
function parseSearchMemberParams(query) {
|
|
@@ -9234,6 +9470,12 @@ function BlockPreview(props) {
|
|
|
9234
9470
|
setContent({ headings: block.inputs, settings: block.settings });
|
|
9235
9471
|
return;
|
|
9236
9472
|
}
|
|
9473
|
+
if (block.type === BLOCK_TYPES.RELATED) {
|
|
9474
|
+
const { outputVariables } = await runSingleBlock(block, formatterFunctions, blockContext, readMemberFn);
|
|
9475
|
+
const { related_reports } = outputVariables;
|
|
9476
|
+
setContent({ related_reports });
|
|
9477
|
+
return;
|
|
9478
|
+
}
|
|
9237
9479
|
if (block.type === BLOCK_TYPES.RESET_BUTTON) {
|
|
9238
9480
|
setContent(blockContent.simple);
|
|
9239
9481
|
return;
|
|
@@ -9459,6 +9701,16 @@ function BlockSettings({ id, setBlockSettings, setBlockContent }) {
|
|
|
9459
9701
|
[BLOCK_SETTINGS.ALLOWED_LOGIC]: allowedLogic
|
|
9460
9702
|
});
|
|
9461
9703
|
};
|
|
9704
|
+
const blocks = useAppSelector((state) => state.records.entities.block);
|
|
9705
|
+
const consumers = block.consumers.filter((cid) => blocks[cid].section_id !== block.section_id);
|
|
9706
|
+
const isShared = Boolean(consumers.length);
|
|
9707
|
+
const consumersP = consumers.slice(0, 3).map(
|
|
9708
|
+
(cid, i) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
9709
|
+
i === consumers.length - 1 && consumers.length > 1 ? "and " : "",
|
|
9710
|
+
/* @__PURE__ */ jsx("strong", { children: `${blocks[cid].type} ${cid} [Section ${blocks[cid].section_id}]` }, cid),
|
|
9711
|
+
i < consumers.length - 1 && consumers.length > 1 ? ", " : ""
|
|
9712
|
+
] })
|
|
9713
|
+
);
|
|
9462
9714
|
return /* @__PURE__ */ jsxs(Group, { grow: true, align: "flex-start", children: [
|
|
9463
9715
|
/* @__PURE__ */ jsxs(Stack, { justify: "flex-start", children: [
|
|
9464
9716
|
/* @__PURE__ */ jsx(Title, { order: 4, children: "Allowed" }),
|
|
@@ -9480,10 +9732,20 @@ function BlockSettings({ id, setBlockSettings, setBlockContent }) {
|
|
|
9480
9732
|
}
|
|
9481
9733
|
),
|
|
9482
9734
|
/* @__PURE__ */ jsx(Title, { order: 4, children: "Sharing" }),
|
|
9735
|
+
isShared && block.shared && /* @__PURE__ */ jsxs(Text, { size: "xs", color: "red.4", sx: { display: "flex", alignItems: "flex-start", gap: "0.4rem" }, children: [
|
|
9736
|
+
/* @__PURE__ */ jsx(IconAlertCircle, { size: "1.2rem" }),
|
|
9737
|
+
/* @__PURE__ */ jsxs(Text, { color: "black", span: true, inherit: true, children: [
|
|
9738
|
+
"This block is being consumed by ",
|
|
9739
|
+
consumersP,
|
|
9740
|
+
consumers.length > 3 && " and others",
|
|
9741
|
+
". Please, make sure you remove this block dependencies before changing this setting."
|
|
9742
|
+
] })
|
|
9743
|
+
] }),
|
|
9483
9744
|
/* @__PURE__ */ jsx(
|
|
9484
9745
|
SegmentedControl,
|
|
9485
9746
|
{
|
|
9486
9747
|
defaultValue: String(block.shared),
|
|
9748
|
+
disabled: isShared && block.shared,
|
|
9487
9749
|
onChange: (e) => handleChange("shared", e === "true"),
|
|
9488
9750
|
data: shared
|
|
9489
9751
|
}
|
|
@@ -9513,6 +9775,8 @@ var Icons = {
|
|
|
9513
9775
|
function InputMenu({ id }) {
|
|
9514
9776
|
const dispatch = useAppDispatch();
|
|
9515
9777
|
const resource = useContext(ResourceContext);
|
|
9778
|
+
const [searchTerm, setSearchTerm] = useState("");
|
|
9779
|
+
const [debouncedSearchTerm] = useDebouncedValue(searchTerm, 200);
|
|
9516
9780
|
const blocks = useAppSelector((state) => {
|
|
9517
9781
|
if (state.records.reports && state.records.reports[0]) {
|
|
9518
9782
|
const reportId = state.records.reports[0];
|
|
@@ -9541,8 +9805,11 @@ function InputMenu({ id }) {
|
|
|
9541
9805
|
() => blocks.filter((d) => d.id !== block.id && (d.section_id === block.section_id || d.shared)).sort(inputMenuSort),
|
|
9542
9806
|
[blocks]
|
|
9543
9807
|
);
|
|
9544
|
-
|
|
9545
|
-
|
|
9808
|
+
const filteredBlocks = useMemo(() => availableBlocks.filter((block2) => {
|
|
9809
|
+
const matchId = String(block2.id).includes(debouncedSearchTerm.trim());
|
|
9810
|
+
const matchVariables = Object.keys(variables[block2.id] || {}).some((varName) => varName.includes(debouncedSearchTerm.trim()));
|
|
9811
|
+
return matchId || matchVariables;
|
|
9812
|
+
}), [availableBlocks, debouncedSearchTerm, variables]);
|
|
9546
9813
|
const handleClick = (blockId) => {
|
|
9547
9814
|
const operation = inputBlocks[blockId] ? "delete" : "create";
|
|
9548
9815
|
dispatch(actions_exports.updateEntity("block", {
|
|
@@ -9558,6 +9825,8 @@ function InputMenu({ id }) {
|
|
|
9558
9825
|
dispatch(recalculateVariables(resource));
|
|
9559
9826
|
});
|
|
9560
9827
|
};
|
|
9828
|
+
if (!block)
|
|
9829
|
+
return null;
|
|
9561
9830
|
const determineIcon = (blockId) => {
|
|
9562
9831
|
if (block.consumers.includes(blockId))
|
|
9563
9832
|
return Icons.Consumer;
|
|
@@ -9579,23 +9848,41 @@ function InputMenu({ id }) {
|
|
|
9579
9848
|
children: "Add New Input"
|
|
9580
9849
|
}
|
|
9581
9850
|
) }),
|
|
9582
|
-
/* @__PURE__ */
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9851
|
+
/* @__PURE__ */ jsxs(Menu.Dropdown, { children: [
|
|
9852
|
+
/* @__PURE__ */ jsx(
|
|
9853
|
+
TextInput,
|
|
9854
|
+
{
|
|
9855
|
+
placeholder: "Search by variable name or block id.",
|
|
9856
|
+
size: "xs",
|
|
9857
|
+
value: searchTerm,
|
|
9858
|
+
onChange: (e) => setSearchTerm(e.target.value)
|
|
9859
|
+
}
|
|
9860
|
+
),
|
|
9861
|
+
filteredBlocks.map(({ id: id2, shared }) => /* @__PURE__ */ jsx(
|
|
9862
|
+
Menu.Item,
|
|
9863
|
+
{
|
|
9864
|
+
disabled: block.consumers.includes(id2),
|
|
9865
|
+
onClick: () => handleClick(id2),
|
|
9866
|
+
icon: determineIcon(id2),
|
|
9867
|
+
rightSection: /* @__PURE__ */ jsxs(Stack, { ml: "xs", spacing: "xs", align: "flex-end", children: [
|
|
9868
|
+
/* @__PURE__ */ jsxs(Text, { size: "xs", color: "gray.6", children: [
|
|
9869
|
+
"[",
|
|
9870
|
+
id2,
|
|
9871
|
+
"]"
|
|
9872
|
+
] }),
|
|
9873
|
+
shared ? /* @__PURE__ */ jsx(ThemeIcon, { size: "xs", radius: "xl", children: /* @__PURE__ */ jsx(IconGlobe, {}) }) : null
|
|
9874
|
+
] }),
|
|
9875
|
+
children: /* @__PURE__ */ jsx(Box, { style: { maxWidth: "400px" }, children: /* @__PURE__ */ jsx(
|
|
9876
|
+
InputMenuItem_default,
|
|
9877
|
+
{
|
|
9878
|
+
id: id2,
|
|
9879
|
+
variables: variables[id2]
|
|
9880
|
+
}
|
|
9881
|
+
) })
|
|
9882
|
+
},
|
|
9883
|
+
id2
|
|
9884
|
+
))
|
|
9885
|
+
] })
|
|
9599
9886
|
]
|
|
9600
9887
|
}
|
|
9601
9888
|
);
|
|
@@ -9899,7 +10186,11 @@ function BlockEditor({
|
|
|
9899
10186
|
setBlockContent({ api: [...apiList, ""].join(apiSeparator) });
|
|
9900
10187
|
};
|
|
9901
10188
|
const onDeleteAPI = (deletedIx) => {
|
|
9902
|
-
setBlockContent(
|
|
10189
|
+
setBlockContent(
|
|
10190
|
+
{
|
|
10191
|
+
api: apiList.length === 1 && apiList[0] === "" ? null : apiList.filter((ai, ix) => ix !== deletedIx).join(apiSeparator)
|
|
10192
|
+
}
|
|
10193
|
+
);
|
|
9903
10194
|
};
|
|
9904
10195
|
const codeEditor = /* @__PURE__ */ jsx(
|
|
9905
10196
|
MonacoWrapper_default,
|
|
@@ -9953,7 +10244,7 @@ function BlockEditor({
|
|
|
9953
10244
|
onEnterPress: () => onSave(true),
|
|
9954
10245
|
onDelete: () => onDeleteAPI(ix)
|
|
9955
10246
|
},
|
|
9956
|
-
`${id}-${ix}`
|
|
10247
|
+
`${id}-${ix}-${apiList.length}`
|
|
9957
10248
|
)),
|
|
9958
10249
|
/* @__PURE__ */ jsx(
|
|
9959
10250
|
Button,
|
|
@@ -10927,7 +11218,7 @@ function BuilderEditor(props) {
|
|
|
10927
11218
|
{
|
|
10928
11219
|
report: reportRef.data,
|
|
10929
11220
|
locale: props.locale,
|
|
10930
|
-
isLoading:
|
|
11221
|
+
isLoading: false
|
|
10931
11222
|
}
|
|
10932
11223
|
);
|
|
10933
11224
|
}, [reportRef.status, reportRef.data?.sections]);
|
|
@@ -11312,6 +11603,7 @@ function FormatterForm({ formatterId, onEditEnd }) {
|
|
|
11312
11603
|
{
|
|
11313
11604
|
monacoOptions: {
|
|
11314
11605
|
onChange: (newLogic) => onContentValueChange("logic", newLogic),
|
|
11606
|
+
height: "30vh",
|
|
11315
11607
|
value: formatter.content.logic
|
|
11316
11608
|
}
|
|
11317
11609
|
},
|
|
@@ -12541,6 +12833,7 @@ function MetadataEditor() {
|
|
|
12541
12833
|
init_esm_shims();
|
|
12542
12834
|
function NotFoundView() {
|
|
12543
12835
|
const { user } = useUser();
|
|
12836
|
+
const textStyle = { color: "#000" };
|
|
12544
12837
|
return /* @__PURE__ */ jsxs(
|
|
12545
12838
|
Flex,
|
|
12546
12839
|
{
|
|
@@ -12550,14 +12843,15 @@ function NotFoundView() {
|
|
|
12550
12843
|
align: "center",
|
|
12551
12844
|
direction: "column",
|
|
12552
12845
|
wrap: "wrap",
|
|
12846
|
+
style: { background: "white" },
|
|
12553
12847
|
children: [
|
|
12554
|
-
/* @__PURE__ */ jsx(Title, { children: "Not found." }),
|
|
12555
|
-
/* @__PURE__ */ jsxs(Title, { order: 2, children: [
|
|
12848
|
+
/* @__PURE__ */ jsx(Title, { style: textStyle, children: "Not found." }),
|
|
12849
|
+
/* @__PURE__ */ jsxs(Title, { order: 2, style: textStyle, children: [
|
|
12556
12850
|
"Sorry, ",
|
|
12557
12851
|
user?.name,
|
|
12558
12852
|
"!"
|
|
12559
12853
|
] }),
|
|
12560
|
-
/* @__PURE__ */ jsx(Text, { children: "The page you are looking for is not here." }),
|
|
12854
|
+
/* @__PURE__ */ jsx(Text, { style: textStyle, children: "The page you are looking for is not here." }),
|
|
12561
12855
|
/* @__PURE__ */ jsx(Button, { component: "a", href: "/", children: "Back to homepage" })
|
|
12562
12856
|
]
|
|
12563
12857
|
}
|
|
@@ -12671,6 +12965,7 @@ function ReportPicker() {
|
|
|
12671
12965
|
init_esm_shims();
|
|
12672
12966
|
function UnauthorizeView() {
|
|
12673
12967
|
const { user } = useUser();
|
|
12968
|
+
const textStyle = { color: "#000" };
|
|
12674
12969
|
return /* @__PURE__ */ jsxs(
|
|
12675
12970
|
Flex,
|
|
12676
12971
|
{
|
|
@@ -12680,15 +12975,39 @@ function UnauthorizeView() {
|
|
|
12680
12975
|
align: "center",
|
|
12681
12976
|
direction: "column",
|
|
12682
12977
|
wrap: "wrap",
|
|
12978
|
+
style: { background: "white" },
|
|
12683
12979
|
children: [
|
|
12684
|
-
/* @__PURE__ */ jsx(Title, { children: "Unauthorize or forbidden access." }),
|
|
12685
|
-
/* @__PURE__ */ jsxs(Title, { order: 2, children: [
|
|
12980
|
+
/* @__PURE__ */ jsx(Title, { style: textStyle, children: "Unauthorize or forbidden access." }),
|
|
12981
|
+
/* @__PURE__ */ jsxs(Title, { style: textStyle, order: 2, children: [
|
|
12686
12982
|
"Sorry, ",
|
|
12687
12983
|
user?.name,
|
|
12688
12984
|
"!"
|
|
12689
12985
|
] }),
|
|
12690
|
-
/* @__PURE__ */ jsx(Text, { children: "Your session or your user's roles doesn't satisfy the needs of the requested view. Please, ask your administrator to allow you." }),
|
|
12691
|
-
/* @__PURE__ */
|
|
12986
|
+
/* @__PURE__ */ jsx(Text, { style: textStyle, children: "Your session or your user's roles doesn't satisfy the needs of the requested view. Please, ask your administrator to allow you." }),
|
|
12987
|
+
/* @__PURE__ */ jsxs(Group, { children: [
|
|
12988
|
+
/* @__PURE__ */ jsx(
|
|
12989
|
+
Button,
|
|
12990
|
+
{
|
|
12991
|
+
component: "a",
|
|
12992
|
+
href: "/",
|
|
12993
|
+
leftIcon: /* @__PURE__ */ jsx(IconHome, { size: 14 }),
|
|
12994
|
+
variant: "outline",
|
|
12995
|
+
color: "dark",
|
|
12996
|
+
children: "Back to homepage"
|
|
12997
|
+
}
|
|
12998
|
+
),
|
|
12999
|
+
/* @__PURE__ */ jsx(
|
|
13000
|
+
Button,
|
|
13001
|
+
{
|
|
13002
|
+
component: "a",
|
|
13003
|
+
href: "/api/auth/logout",
|
|
13004
|
+
leftIcon: /* @__PURE__ */ jsx(IconLogout, { size: 14 }),
|
|
13005
|
+
variant: "outline",
|
|
13006
|
+
color: "dark",
|
|
13007
|
+
children: "Disconnect"
|
|
13008
|
+
}
|
|
13009
|
+
)
|
|
13010
|
+
] })
|
|
12692
13011
|
]
|
|
12693
13012
|
}
|
|
12694
13013
|
);
|
package/dist/server.js
CHANGED
|
@@ -506,6 +506,7 @@ var BLOCK_CONTENT_TYPES = {
|
|
|
506
506
|
};
|
|
507
507
|
var BLOCK_LOGIC_TYPES = {
|
|
508
508
|
GENERATOR: "generator",
|
|
509
|
+
RELATED: "related",
|
|
509
510
|
VIZ: "visualization"
|
|
510
511
|
};
|
|
511
512
|
var BLOCK_LOGIC_LOCALE = "logic";
|
|
@@ -1974,6 +1975,26 @@ function readMemberFactory(db) {
|
|
|
1974
1975
|
}
|
|
1975
1976
|
});
|
|
1976
1977
|
whereClause.content_id = entities.map((item) => item.content_id);
|
|
1978
|
+
} else if (mode === "related") {
|
|
1979
|
+
const levelWhereClause = () => {
|
|
1980
|
+
if (params.variant_ids?.length)
|
|
1981
|
+
return { variant_id: params.variant_ids.map((item) => item) };
|
|
1982
|
+
if (params.dimension_ids?.length)
|
|
1983
|
+
return { dimension_id: params.dimension_ids.map((item) => item) };
|
|
1984
|
+
if (params.report_ids?.length)
|
|
1985
|
+
return { report_id: params.report_ids.map((item) => item) };
|
|
1986
|
+
};
|
|
1987
|
+
const entities = await Search.findAll({
|
|
1988
|
+
attributes: ["content_id"],
|
|
1989
|
+
where: {
|
|
1990
|
+
...levelWhereClause(),
|
|
1991
|
+
content_id: { [Op.notIn]: params.current_ids },
|
|
1992
|
+
visible: true
|
|
1993
|
+
},
|
|
1994
|
+
order: [Sequelize.fn("RANDOM")],
|
|
1995
|
+
limit: params.related || 4
|
|
1996
|
+
});
|
|
1997
|
+
whereClause.content_id = entities.map((item) => item.content_id);
|
|
1977
1998
|
}
|
|
1978
1999
|
const contentWhereClause = {
|
|
1979
2000
|
locale: all ? { [Op.ne]: null } : locale
|
|
@@ -2001,7 +2022,7 @@ function readMemberFactory(db) {
|
|
|
2001
2022
|
where: contentWhereClause
|
|
2002
2023
|
}]
|
|
2003
2024
|
});
|
|
2004
|
-
if (memberSearchResults.length !== params[mode].length) {
|
|
2025
|
+
if (mode !== "related" && memberSearchResults.length !== params[mode].length) {
|
|
2005
2026
|
throw new BackendError(404, "One or more members were not found.");
|
|
2006
2027
|
}
|
|
2007
2028
|
memberSearchResults.sort(
|
|
@@ -2703,7 +2724,7 @@ function dbSectionFactory(db) {
|
|
|
2703
2724
|
const { id, blocks, ...sectionData } = data;
|
|
2704
2725
|
const entity = await Section.findByPk(id, {
|
|
2705
2726
|
include: sectionQuery.include,
|
|
2706
|
-
rejectOnEmpty:
|
|
2727
|
+
rejectOnEmpty: false
|
|
2707
2728
|
});
|
|
2708
2729
|
entity.set(sectionData);
|
|
2709
2730
|
await entity.save();
|
|
@@ -3112,6 +3133,7 @@ function parseReadMemberParams(query) {
|
|
|
3112
3133
|
const mode = normalizeList(query.mode)[0];
|
|
3113
3134
|
const outputParam = normalizeList(query.output)[0] || "full";
|
|
3114
3135
|
const output = outputParam === "lite" ? "lite" : "full";
|
|
3136
|
+
const relatedLimit = parseInt(normalizeList(query.related)[0], 10) || 5;
|
|
3115
3137
|
let variant = normalizeList(query.variant).map(parseFiniteNumber);
|
|
3116
3138
|
if (variant.length === 0) {
|
|
3117
3139
|
variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
|
|
@@ -3149,6 +3171,19 @@ function parseReadMemberParams(query) {
|
|
|
3149
3171
|
})
|
|
3150
3172
|
};
|
|
3151
3173
|
}
|
|
3174
|
+
if (mode === "related") {
|
|
3175
|
+
return {
|
|
3176
|
+
all,
|
|
3177
|
+
mode,
|
|
3178
|
+
locale: all ? localeDefault3 : stripHTML(locale),
|
|
3179
|
+
related: relatedLimit,
|
|
3180
|
+
current_ids: normalizeList(query.current_ids || query["current_ids[]"]).map(parseFiniteNumber),
|
|
3181
|
+
report_ids: normalizeList(query.report_ids || query["report_ids[]"]).map(parseFiniteNumber),
|
|
3182
|
+
dimension_ids: normalizeList(query.dimension_ids || query["dimension_ids[]"]).map(parseFiniteNumber),
|
|
3183
|
+
variant_ids: normalizeList(query.variant_ids || query["variant_ids[]"]).map(parseFiniteNumber),
|
|
3184
|
+
output
|
|
3185
|
+
};
|
|
3186
|
+
}
|
|
3152
3187
|
throw new BackendError(400, `Invalid mode: '${mode}'`);
|
|
3153
3188
|
}
|
|
3154
3189
|
function parseSearchMemberParams(query) {
|
|
@@ -4360,6 +4395,9 @@ var transformReadMembers = (params) => {
|
|
|
4360
4395
|
).join(",");
|
|
4361
4396
|
return { ...params, slugs };
|
|
4362
4397
|
}
|
|
4398
|
+
if (params.mode === "related") {
|
|
4399
|
+
return { ...params };
|
|
4400
|
+
}
|
|
4363
4401
|
return { ...params, [params.mode]: params[params.mode].join(",") };
|
|
4364
4402
|
};
|
|
4365
4403
|
function apiFactory2(baseURL) {
|
|
@@ -4809,6 +4847,80 @@ async function runSingleBlock(block, formatterFunctions, blockContext, readMembe
|
|
|
4809
4847
|
}
|
|
4810
4848
|
};
|
|
4811
4849
|
}
|
|
4850
|
+
if (block.type === BLOCK_TYPES.RELATED) {
|
|
4851
|
+
const relatedCompare = block.contentByLocale?.logic?.content?.simple?.compare || "variant";
|
|
4852
|
+
const relatedLimit = block.contentByLocale?.logic?.content?.simple?.limit || 4;
|
|
4853
|
+
const reportIds = Object.keys(variables).filter((key) => key.startsWith("report_id")).map((key) => variables[key]);
|
|
4854
|
+
const dimensionIds = Object.keys(variables).filter((key) => key.startsWith("dimension_id")).map((key) => variables[key]);
|
|
4855
|
+
const variantIds = Object.keys(variables).filter((key) => key.startsWith("variant_id")).map((key) => variables[key]);
|
|
4856
|
+
const memberIds = Object.keys(variables).filter((key) => key.startsWith("id")).map((key) => variables[key]);
|
|
4857
|
+
if (!memberIds.length)
|
|
4858
|
+
return {
|
|
4859
|
+
outputVariables: { related_reports: [] },
|
|
4860
|
+
renderVariables: {},
|
|
4861
|
+
status: {
|
|
4862
|
+
log: [],
|
|
4863
|
+
allowed: false
|
|
4864
|
+
}
|
|
4865
|
+
};
|
|
4866
|
+
const membersContentIds = await readMemberFn({
|
|
4867
|
+
mode: "ids",
|
|
4868
|
+
locale,
|
|
4869
|
+
ids: memberIds,
|
|
4870
|
+
output: "lite"
|
|
4871
|
+
}).then((response) => {
|
|
4872
|
+
let data = [];
|
|
4873
|
+
if (isResult(response)) {
|
|
4874
|
+
if (response.ok) {
|
|
4875
|
+
data = response.data.results;
|
|
4876
|
+
}
|
|
4877
|
+
} else {
|
|
4878
|
+
data = response.results;
|
|
4879
|
+
}
|
|
4880
|
+
return data && Array.isArray(data) ? data : [];
|
|
4881
|
+
}).catch((err) => {
|
|
4882
|
+
console.log("Error getting related members", err);
|
|
4883
|
+
return [];
|
|
4884
|
+
});
|
|
4885
|
+
const current_ids = membersContentIds.map((member) => member.content_id);
|
|
4886
|
+
const memberParams = {
|
|
4887
|
+
mode: "related",
|
|
4888
|
+
locale,
|
|
4889
|
+
related: relatedLimit ?? 4,
|
|
4890
|
+
current_ids,
|
|
4891
|
+
output: "full"
|
|
4892
|
+
};
|
|
4893
|
+
if (relatedCompare) {
|
|
4894
|
+
if (relatedCompare === "report")
|
|
4895
|
+
memberParams.report_ids = reportIds;
|
|
4896
|
+
else if (relatedCompare === "dimension")
|
|
4897
|
+
memberParams.dimension_ids = dimensionIds;
|
|
4898
|
+
else
|
|
4899
|
+
memberParams.variant_ids = variantIds;
|
|
4900
|
+
}
|
|
4901
|
+
const bespokeMembers = await readMemberFn(memberParams).then((response) => {
|
|
4902
|
+
let data = [];
|
|
4903
|
+
if (isResult(response)) {
|
|
4904
|
+
if (response.ok) {
|
|
4905
|
+
data = response.data.results;
|
|
4906
|
+
}
|
|
4907
|
+
} else {
|
|
4908
|
+
data = response.results;
|
|
4909
|
+
}
|
|
4910
|
+
return data && Array.isArray(data) ? data : [];
|
|
4911
|
+
}).catch((err) => {
|
|
4912
|
+
console.log("Error getting related members", err);
|
|
4913
|
+
return [];
|
|
4914
|
+
});
|
|
4915
|
+
return {
|
|
4916
|
+
outputVariables: { related_reports: bespokeMembers },
|
|
4917
|
+
renderVariables: {},
|
|
4918
|
+
status: {
|
|
4919
|
+
log: [],
|
|
4920
|
+
allowed: bespokeMembers.length > 0
|
|
4921
|
+
}
|
|
4922
|
+
};
|
|
4923
|
+
}
|
|
4812
4924
|
const { logic } = getBlockContent(block, locale);
|
|
4813
4925
|
const swappedLogic = varSwap_default(logic, formatterFunctions, blockContext);
|
|
4814
4926
|
const evalResults = mortarEval_default("resp", resp || {}, swappedLogic, formatterFunctions, variables, blockContext);
|
|
@@ -4952,7 +5064,7 @@ var runConsumersV2 = async (blocks, sections, bid, formatterFunctions, blockCont
|
|
|
4952
5064
|
).then(({ outputVariables, status }) => {
|
|
4953
5065
|
if (
|
|
4954
5066
|
// store output variables for block that:
|
|
4955
|
-
(block.consumers.length > 0 ||
|
|
5067
|
+
(block.consumers.length > 0 || [BLOCK_TYPES.GENERATOR, BLOCK_TYPES.RELATED].includes(block.type)) && status.allowed && Object.keys(outputVariables).length > 0
|
|
4956
5068
|
)
|
|
4957
5069
|
variablesById[bid2] = outputVariables;
|
|
4958
5070
|
if (mode === "report") {
|
|
@@ -5957,7 +6069,7 @@ function BespokeRendererStaticPaths(options) {
|
|
|
5957
6069
|
limit,
|
|
5958
6070
|
format: "plain",
|
|
5959
6071
|
locale: locale || localeDefault9,
|
|
5960
|
-
noImage:
|
|
6072
|
+
noImage: false,
|
|
5961
6073
|
visible: true,
|
|
5962
6074
|
report: [],
|
|
5963
6075
|
dimension: [],
|
|
@@ -5965,7 +6077,7 @@ function BespokeRendererStaticPaths(options) {
|
|
|
5965
6077
|
includes: true
|
|
5966
6078
|
});
|
|
5967
6079
|
if (req.ok === true) {
|
|
5968
|
-
paths = req.data.results.
|
|
6080
|
+
paths = req.data.results.map((item) => ({
|
|
5969
6081
|
locale: locales9.find((token) => token === item.locale),
|
|
5970
6082
|
params: {
|
|
5971
6083
|
bespoke: [item.variant.slug, item.slug]
|