@datawheel/bespoke 0.3.21 → 0.4.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 CHANGED
@@ -1,4 +1,4 @@
1
- import { useMantineTheme, List, Text, Group, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Stack, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, TextInput, Code, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Loader, Container, Grid, Tooltip, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, Autocomplete, Image, NumberInput, Header, px, Notification, Accordion, Tabs, FileInput, SimpleGrid, Burger, Collapse, HoverCard, CopyButton, Col } from '@mantine/core';
1
+ import { useMantineTheme, List, Text, Group, Modal, Button, Input, MantineProvider, Box, Navbar, ScrollArea, Stack, Avatar, AppShell, UnstyledButton, ThemeIcon, LoadingOverlay, Skeleton, Flex, packSx, Menu, Card, Center, Space, Badge, Title, Tabs, TextInput, Code, Loader, Divider, SegmentedControl, Select, ActionIcon, Textarea, Paper, Alert, Container, Grid, Tooltip, MultiSelect, Anchor, Checkbox, MediaQuery, Affix, rem, Popover, Radio, Switch, Drawer, Overlay, NumberInput, Autocomplete, Image, Header, px, Notification, Accordion, FileInput, SimpleGrid, Burger, Collapse, HoverCard, CopyButton, Col } from '@mantine/core';
2
2
  import React, { forwardRef, useState, useCallback, useRef, useEffect, createContext, useContext, useMemo, Fragment as Fragment$1, memo, createElement } from 'react';
3
3
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
4
4
  import axios from 'axios';
@@ -21,8 +21,8 @@ import { HYDRATE, createWrapper } from 'next-redux-wrapper';
21
21
  import { Notifications, notifications } from '@mantine/notifications';
22
22
  import { useDispatch, useSelector } from 'react-redux';
23
23
  import Router, { useRouter } from 'next/router';
24
- import { useClickOutside, useDisclosure, useDebouncedValue, useSetState, useHotkeys, useMediaQuery, useFullscreen, getHotkeyHandler } from '@mantine/hooks';
25
- import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconUserCircle, IconEdit, IconCircleDashed, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconFlag, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconAlignCenter, IconAlignRight, IconDownload, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconPolaroid, IconCircleMinus, IconTable, IconCamera, IconShare, IconCirclePlus, IconLogin, IconWorld, IconLock, IconBinaryTree, IconVariable, IconArrowRightCircle, IconInfoCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconCode, IconPalette, IconSettings, IconMinimize, IconMaximize, IconRss, IconGlobe, IconLinkOff } from '@tabler/icons-react';
24
+ import { useClickOutside, useDisclosure, useDebouncedValue, useSetState, useHotkeys, getHotkeyHandler, useMediaQuery, useFullscreen } from '@mantine/hooks';
25
+ import { IconDice, IconBoxMultiple, IconEyeOff, IconChevronDown, IconBallpen, IconDatabase, IconMathFunction, IconUsers, IconLogout, IconHeading, IconApi, IconPercentage, IconChartBar, IconAlignLeft, IconSelector, IconPhoto, IconUserCircle, IconEdit, IconCircleDashed, IconServer, IconPencil, IconAlertCircle, IconCircleCheck, IconPlayerPlay, IconTrash, IconCircleX, IconFlag, IconPlus, IconFileAnalytics, IconHome, IconSearch, IconX, IconRefresh, IconAlignCenter, IconAlignRight, IconDownload, IconSettingsFilled, IconEye, IconWorldUpload, IconBraces, IconClockHour2, IconAugmentedReality, IconGitMerge, IconGripHorizontal, IconChevronLeft, IconChevronRight, IconListCheck, IconPolaroid, IconCircleMinus, IconTable, IconCamera, IconShare, IconQuestionMark, IconCirclePlus, IconLogin, IconWorld, IconLock, IconBinaryTree, IconVariable, IconArrowRightCircle, IconInfoCircle, IconPhotoFilled, IconFileUpload, IconIndentIncrease, IconCodeDots, IconUpload, IconCodePlus, IconLink, IconSparkles, IconClipboardCheck, IconClipboardCopy, IconExternalLink, IconFileTypeCsv, IconFileTypeJs, IconFileTypeXls, IconTemplate, IconCode, IconPalette, IconSettings, IconMinimize, IconMaximize, IconRss, IconGlobe, IconLinkOff } from '@tabler/icons-react';
26
26
  import Link from 'next/link';
27
27
  import parse2, { Element, domToReact, Text as Text$1 } from 'html-react-parser';
28
28
  import { UserProvider, withPageAuthRequired, useUser } from '@auth0/nextjs-auth0/client';
@@ -30,7 +30,7 @@ import { dataConcat, dataLoad } from 'd3plus-viz';
30
30
  import * as d3plus from 'd3plus-react';
31
31
  import dynamic from 'next/dynamic';
32
32
  import { Prism } from '@mantine/prism';
33
- import { DataTable } from 'mantine-datatable';
33
+ import { MantineReactTable } from 'mantine-react-table';
34
34
  import slugifyFn from 'slugify';
35
35
  import JSZip from 'jszip';
36
36
  import { saveAs } from 'file-saver';
@@ -297,8 +297,8 @@ var init_lib = __esm({
297
297
  // api/http/image/imageSave.ts
298
298
  function httpImageSaveFactory(axios9, provider) {
299
299
  return (params) => http(axios9, {
300
- method: "GET",
301
- url: `search/images/${provider}`,
300
+ method: "POST",
301
+ url: `images/save/${provider}`,
302
302
  params: { prompt: params.prompt, provider }
303
303
  });
304
304
  }
@@ -313,8 +313,8 @@ var init_imageSave = __esm({
313
313
  function httpImageSearchFactory(axios9, provider) {
314
314
  return (params) => http(axios9, {
315
315
  method: "GET",
316
- url: `search/images/${provider}`,
317
- params: { prompt: params.prompt, provider }
316
+ url: `images/search/${provider}`,
317
+ params: { prompt: params.prompt, page: params.page, provider }
318
318
  });
319
319
  }
320
320
  var init_imageSearch = __esm({
@@ -384,7 +384,7 @@ function apiFactory(baseURL) {
384
384
  validateVariantSlug: httpGET(axios9, "validate/variant"),
385
385
  readMember: httpGET(axios9, "read/members", transformReadMembers),
386
386
  readMemberImage: httpGET(axios9, {
387
- url: "member/image.png",
387
+ url: "member/image",
388
388
  responseType: "blob"
389
389
  }),
390
390
  searchMember: httpGET(axios9, "search/members"),
@@ -396,6 +396,8 @@ function apiFactory(baseURL) {
396
396
  imageUnsplashSearch: httpImageSearchFactory(axios9, "unsplash"),
397
397
  imageUnsplashSave: httpImageSaveFactory(axios9, "unsplash"),
398
398
  imageUploadSave: httpImageSaveFactory(axios9, "upload"),
399
+ imageAdobeSearch: httpImageSearchFactory(axios9, "adobe"),
400
+ imageAdobeSave: httpImageSaveFactory(axios9, "adobe"),
399
401
  readMetadata: httpGET(axios9, "read/metadata"),
400
402
  regenerateSearch: httpPOST(axios9, "search/regenerate"),
401
403
  urlProxy: httpGET(axios9, "url/proxy"),
@@ -3300,7 +3302,7 @@ function ExploreTile({ profile, profilePrefix, onSelect, reportTile }) {
3300
3302
  id: m.id,
3301
3303
  variant: m.metadata.variant.name,
3302
3304
  image: {
3303
- src: `/api/cms/member/image.png?member=${m.id}&size=thumb`,
3305
+ src: `/api/cms/member/image?member=${m.id}&size=thumb`,
3304
3306
  alt: m.name
3305
3307
  }
3306
3308
  }));
@@ -3647,7 +3649,7 @@ function BespokeSearch({
3647
3649
  id: m.id,
3648
3650
  variant: m.metadata.variant.name,
3649
3651
  image: {
3650
- src: `/api/cms/member/image.png?member=${m.id}&size=thumb`,
3652
+ src: `/api/cms/member/image?member=${m.id}&size=thumb`,
3651
3653
  alt: m.name
3652
3654
  }
3653
3655
  }))
@@ -4866,7 +4868,7 @@ function RelatedView(props) {
4866
4868
  id: report.content_id,
4867
4869
  variant: report.variant_name,
4868
4870
  image: {
4869
- src: `/api/cms/member/image.png?member=${report.content_id}&size=thumb`,
4871
+ src: `/api/cms/member/image?member=${report.content_id}&size=thumb`,
4870
4872
  alt: report.name
4871
4873
  }
4872
4874
  }];
@@ -7450,7 +7452,7 @@ var init_section2 = __esm({
7450
7452
  function SectionBackground({ previews }) {
7451
7453
  const images = previews.map((member, ix) => ({
7452
7454
  key: member ? `bg-${member.content_id}` : `bg-${ix}`,
7453
- src: member ? `/api/cms/member/image.png?member=${member.content_id}&size=splash` : ""
7455
+ src: member ? `/api/cms/member/image?member=${member.content_id}&size=splash` : ""
7454
7456
  }));
7455
7457
  return /* @__PURE__ */ jsxs(Fragment, { children: [
7456
7458
  /* @__PURE__ */ jsx(
@@ -7500,71 +7502,45 @@ var init_SectionBackground = __esm({
7500
7502
  init_esm_shims();
7501
7503
  }
7502
7504
  });
7503
- function SortableTable({ data, customIdAccessor = "id" }) {
7504
- const [records, setRecords] = useState();
7505
- const [sortStatus, setSortStatus] = useState();
7505
+ function SortableTable({ data }) {
7506
7506
  const keys = data && Array.isArray(data) && data[0] ? Object.keys(data[0]) : [];
7507
- const idAccessor = keys.includes(customIdAccessor) ? customIdAccessor : defaultIdAccessor;
7508
7507
  const fields = keys.filter((k) => !k.startsWith("_"));
7509
7508
  const columns = fields.map((field) => ({
7510
- accessor: field,
7511
- title: field,
7512
- sortable: true,
7513
- render: (r) => `${r[field]}`
7514
- }));
7515
- const getSortedData = (sortField) => {
7516
- let dataTemp = [...data];
7517
- dataTemp = dataTemp.map((item, ix) => {
7518
- const newItem = { ...item };
7519
- fields.forEach((f) => {
7520
- if (typeof newItem[f] === "object") {
7521
- newItem[f] = JSON.stringify(item[f]);
7522
- }
7523
- });
7524
- if (idAccessor === defaultIdAccessor) {
7525
- newItem._key = `i-${ix}`;
7509
+ accessorKey: field,
7510
+ header: field,
7511
+ enableSorting: true,
7512
+ mantineTableBodyCellProps: {
7513
+ sx: {
7514
+ textWrap: "wrap"
7526
7515
  }
7527
- return newItem;
7528
- });
7529
- if (sortField) {
7530
- dataTemp = dataTemp.sort((a, b) => {
7531
- if (isNaN(a[sortField.columnAccessor])) {
7532
- return a[sortField.columnAccessor].localeCompare(b[sortField.columnAccessor]);
7533
- } else {
7534
- return a[sortField.columnAccessor] > b[sortField.columnAccessor] ? 1 : -1;
7535
- }
7536
- });
7537
- }
7538
- return sortField && sortField.direction === "desc" ? dataTemp.reverse() : dataTemp;
7539
- };
7540
- useEffect(() => {
7541
- if (sortStatus) {
7542
- setRecords(getSortedData(sortStatus));
7543
7516
  }
7544
- }, [sortStatus]);
7545
- useEffect(() => {
7546
- setSortStatus(void 0);
7547
- setRecords(getSortedData(void 0));
7548
- }, [data]);
7517
+ }));
7549
7518
  return /* @__PURE__ */ jsx(
7550
- DataTable,
7519
+ MantineReactTable,
7551
7520
  {
7552
- withBorder: true,
7553
- withColumnBorders: true,
7554
- records,
7555
7521
  columns,
7556
- sortStatus,
7557
- onSortStatusChange: setSortStatus,
7558
- idAccessor,
7559
- minHeight: 100
7522
+ data,
7523
+ enableBottomToolbar: false,
7524
+ enableColumnActions: false,
7525
+ enablePagination: false,
7526
+ enableSorting: true,
7527
+ enableTopToolbar: false,
7528
+ initialState: {
7529
+ density: "xs"
7530
+ },
7531
+ layoutMode: "grid",
7532
+ mantineTableContainerProps: {
7533
+ sx: {
7534
+ minHeight: 100,
7535
+ maxHeight: 350
7536
+ }
7537
+ }
7560
7538
  }
7561
7539
  );
7562
7540
  }
7563
- var defaultIdAccessor;
7564
7541
  var init_SortableTable = __esm({
7565
7542
  "components/SortableTable.tsx"() {
7566
7543
  init_esm_shims();
7567
- defaultIdAccessor = "_key";
7568
7544
  }
7569
7545
  });
7570
7546
 
@@ -8044,28 +8020,29 @@ function ImageTab(props) {
8044
8020
  const translations = { ...DEFAULT_TRANSLATIONS3, ...optionsTranslations["image_tab"] };
8045
8021
  const { siteProps } = useBespoke();
8046
8022
  const includeLogo = siteProps?.logoSrc && typeof siteProps.logoSrc === "string";
8047
- const sectionHash = section.settings?.name ? `#${section.settings.name}` : `#section-${section.id}`;
8023
+ const sectionId = section?.settings?.name || `section-${section.id}`;
8024
+ const sectionHash = `#${sectionId}`;
8048
8025
  const theme = useMantineTheme();
8049
8026
  const vizSelectedHasSVG = () => {
8050
- const vizNode = getVizNode(section.id, vizSelected);
8027
+ const vizNode = getVizNode(vizSelected);
8051
8028
  const svgCount = select(vizNode).select("svg").size();
8052
8029
  return svgCount === 1;
8053
8030
  };
8054
- const getFileName = () => `${slugify_default(section?.settings?.name || `section-${section.id}`)}`;
8055
- const getSectionNode = (sectionId) => {
8056
- const sectionNode = document.getElementById(`section-${sectionId}`);
8031
+ const getFileName = () => `${slugify_default(sectionId)}`;
8032
+ const getSectionNode = () => {
8033
+ const sectionNode = document.getElementById(sectionId);
8057
8034
  return select(sectionNode).select(".bespoke-section-content").node();
8058
8035
  };
8059
- const getVizNode = (sectionId, vizId) => {
8060
- const sectionNode = getSectionNode(sectionId);
8036
+ const getVizNode = (vizId) => {
8037
+ const sectionNode = getSectionNode();
8061
8038
  return select(sectionNode).select(`#bespoke-visualization-${vizId}.bespoke-block-area`).node();
8062
8039
  };
8063
8040
  const getSelectedNode = () => new Promise((resolve) => {
8064
8041
  let node;
8065
8042
  if (imageContext === contextOptions.section) {
8066
- node = getSectionNode(section.id);
8043
+ node = getSectionNode();
8067
8044
  } else if (imageContext === contextOptions.viz) {
8068
- node = getVizNode(section.id, vizSelected);
8045
+ node = getVizNode(vizSelected);
8069
8046
  }
8070
8047
  const sourceContainer = document.createElement("div");
8071
8048
  sourceContainer.style.display = "flex";
@@ -8157,7 +8134,7 @@ function ImageTab(props) {
8157
8134
  const generatePreviews = async () => {
8158
8135
  const { toCanvas } = await import('html-to-image');
8159
8136
  Promise.all(
8160
- vizAvailable.map((viz) => toCanvas(getVizNode(section.id, viz.id)))
8137
+ vizAvailable.map((viz) => toCanvas(getVizNode(viz.id)))
8161
8138
  ).then((canvases) => {
8162
8139
  setVizPreviews(canvases.map((canvas) => canvas.toDataURL()));
8163
8140
  setLoadingPreviews(false);
@@ -9926,7 +9903,7 @@ init_store2();
9926
9903
  function VariantCard({ for: variant, onEdit }) {
9927
9904
  const theme = useMantineTheme();
9928
9905
  const { newConfirmation } = useDialog();
9929
- const secondaryColor = theme.colorScheme === "dark" ? theme.colors.dark[1] : theme.colors.gray[7];
9906
+ theme.colorScheme === "dark" ? theme.colors.dark[1] : theme.colors.gray[7];
9930
9907
  const maybeEdit = useCallback(async () => {
9931
9908
  try {
9932
9909
  await newConfirmation({
@@ -9952,8 +9929,7 @@ function VariantCard({ for: variant, onEdit }) {
9952
9929
  slug
9953
9930
  ] })
9954
9931
  ] }),
9955
- /* @__PURE__ */ jsx(Text, { size: "sm", style: { color: secondaryColor, lineHeight: 2 }, children: "Description of variant will go here" }),
9956
- /* @__PURE__ */ jsx(Space, { w: "xs" }),
9932
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
9957
9933
  /* @__PURE__ */ jsxs(Group, { position: "apart", children: [
9958
9934
  /* @__PURE__ */ jsx(Button, { onClick: () => maybeEdit(), leftIcon: /* @__PURE__ */ jsx(IconPencil, {}), compact: true, children: "Edit" }),
9959
9935
  /* @__PURE__ */ jsx(
@@ -9996,138 +9972,608 @@ function DrawerContentWithScroll({ content, buttons, size }) {
9996
9972
  /* @__PURE__ */ jsx(Group, { mt: "xs", grow: true, style: { height: 45 }, children: buttons })
9997
9973
  ] });
9998
9974
  }
9999
- function VariantEditor({ for: variant, onClose: closeHandler }) {
10000
- const dispatch = useAppDispatch();
10001
- const localeDefault10 = useAppSelector((state) => state.status.localeDefault);
10002
- const locales4 = useAppSelector((state) => state.status.locales);
10003
- const localesItems = locales4.map((locale) => ({ value: locale, label: locale.toUpperCase() }));
10004
- const [sample, setSample] = useState();
10005
- const [selectedLocale, setSelectedLocale] = useState(localeDefault10);
10006
- const [variantConfig, setVariantConfig] = useState(variant);
10007
- const [loading, setLoading] = useState(false);
10008
- const [loadingFetch, setLoadingFetch] = useState(false);
10009
- const [loadingValidSlug, setLoadingValidSlug] = useState(false);
10010
- const [validSlug, setValidSlug] = useState({ valid: false, suggestion: "" });
10011
- const [payload, setPayload] = useState();
10012
- const [accessors, setAccessors] = useState([]);
10013
- const getMembers = (path) => {
10014
- setLoadingFetch(true);
10015
- dispatch(actions_exports.urlProxy(path)).then((resp) => {
10016
- setPayload(resp);
10017
- setLoadingFetch(false);
10018
- }).catch((e) => {
10019
- console.error(e);
10020
- setLoadingFetch(false);
10021
- });
10022
- };
10023
- const setConfigFromSample = (sample2, accessor = "") => {
10024
- if (sample2) {
10025
- const sampleKeys = Object.keys(sample2);
10026
- const guessId = sampleKeys.find((d) => d.toLowerCase().includes("id")) || sampleKeys[0];
10027
- const guessName = sampleKeys.find((d) => !d.toLowerCase().includes("id")) || sampleKeys[0];
10028
- setVariantConfig({
10029
- ...variantConfig,
10030
- config: {
10031
- ...variantConfig.config,
10032
- [selectedLocale]: {
10033
- ...variantConfig.config[selectedLocale],
10034
- idKey: variantConfig.config[selectedLocale].idKey || guessId,
10035
- labelKey: variantConfig.config[selectedLocale].labelKey || guessName,
10036
- accessor
10037
- }
10038
- }
10039
- });
10040
- }
10041
- setSample(sample2);
9975
+
9976
+ // api/endpoints/member.ts
9977
+ init_esm_shims();
9978
+ init_getLocales();
9979
+ init_stripHTML();
9980
+ init_lib3();
9981
+
9982
+ // api/endpoints/lib.ts
9983
+ init_esm_shims();
9984
+ init_lib3();
9985
+ function parseFiniteNumber(value) {
9986
+ const num = Number.parseInt(`${value || ""}`, 10);
9987
+ if (Number.isNaN(num) || !Number.isFinite(num)) {
9988
+ throw new BackendError(400, `Invalid numeric parameter: ${value}`);
9989
+ }
9990
+ return num;
9991
+ }
9992
+ function normalizeList(value) {
9993
+ if (value == null || value === "") {
9994
+ return [];
9995
+ }
9996
+ if (Array.isArray(value)) {
9997
+ return value;
9998
+ }
9999
+ return value.toString().split(",");
10000
+ }
10001
+
10002
+ // api/endpoints/member.ts
10003
+ var { localeDefault: localeDefault9 } = getLocales_default();
10004
+ function parseReadMemberParams(query) {
10005
+ const locale = normalizeList(query.locale)[0] || localeDefault9 || "en";
10006
+ const all = locale === "all" || yn4(query.all);
10007
+ const mode = normalizeList(query.mode)[0];
10008
+ const outputParam = normalizeList(query.output)[0] || "full";
10009
+ const output = outputParam === "lite" ? "lite" : "full";
10010
+ const relatedLimit = parseInt(normalizeList(query.related)[0], 10) || 5;
10011
+ let variant = normalizeList(query.variant).map(parseFiniteNumber);
10012
+ if (variant.length === 0) {
10013
+ variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
10014
+ }
10015
+ if (mode === "ids") {
10016
+ return {
10017
+ all,
10018
+ mode,
10019
+ variant,
10020
+ output,
10021
+ locale: all ? localeDefault9 : stripHTML(locale),
10022
+ ids: normalizeList(query.ids || query["ids[]"])
10023
+ };
10024
+ }
10025
+ if (mode === "content_ids") {
10026
+ return {
10027
+ all,
10028
+ mode,
10029
+ variant,
10030
+ output,
10031
+ locale: all ? localeDefault9 : stripHTML(locale),
10032
+ content_ids: normalizeList(query.content_ids || query["content_ids[]"]).map(parseFiniteNumber)
10033
+ };
10034
+ }
10035
+ if (mode === "slugs") {
10036
+ return {
10037
+ all,
10038
+ mode,
10039
+ variant,
10040
+ output,
10041
+ locale: all ? localeDefault9 : stripHTML(locale),
10042
+ slugs: normalizeList(query.slugs || query["slugs[]"]).map((token) => {
10043
+ const [variantSlug, memberSlug] = token.split("/");
10044
+ return { variantSlug, memberSlug };
10045
+ })
10046
+ };
10047
+ }
10048
+ if (mode === "related") {
10049
+ return {
10050
+ all,
10051
+ mode,
10052
+ locale: all ? localeDefault9 : stripHTML(locale),
10053
+ related: relatedLimit,
10054
+ current_ids: normalizeList(query.current_ids || query["current_ids[]"]).map(parseFiniteNumber),
10055
+ report_ids: normalizeList(query.report_ids || query["report_ids[]"]).map(parseFiniteNumber),
10056
+ dimension_ids: normalizeList(query.dimension_ids || query["dimension_ids[]"]).map(parseFiniteNumber),
10057
+ variant_ids: normalizeList(query.variant_ids || query["variant_ids[]"]).map(parseFiniteNumber),
10058
+ output
10059
+ };
10060
+ }
10061
+ throw new BackendError(400, `Invalid mode: '${mode}'`);
10062
+ }
10063
+ function parseSearchMemberParams(query) {
10064
+ const locale = normalizeList(query.locale)[0] || localeDefault9 || "en";
10065
+ const localeIsAll = locale === "all";
10066
+ const format2 = normalizeList(query.format)[0];
10067
+ const formatIsNested = format2 ? format2 === "nested" : localeIsAll;
10068
+ let variant = normalizeList(query.variant).map(parseFiniteNumber);
10069
+ if (variant.length === 0) {
10070
+ variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
10071
+ }
10072
+ let dimension = normalizeList(query.dimension).map(parseFiniteNumber);
10073
+ if (dimension.length === 0) {
10074
+ dimension = normalizeList(query["dimension[]"]).map(parseFiniteNumber);
10075
+ }
10076
+ let report = normalizeList(query.report).map(parseFiniteNumber);
10077
+ if (report.length === 0) {
10078
+ report = normalizeList(query["report[]"]).map(parseFiniteNumber);
10079
+ }
10080
+ return {
10081
+ query: normalizeList(query.query || query.q)[0] || "",
10082
+ locale: localeIsAll ? localeDefault9 : locale,
10083
+ limit: normalizeList(query.limit).map(parseFiniteNumber)[0] ?? 5,
10084
+ format: formatIsNested ? "nested" : "plain",
10085
+ includes: yn4(query.includes, { default: true }),
10086
+ visible: yn4(query.visible, { default: true }),
10087
+ noImage: yn4(query.noImage, { default: false }),
10088
+ variant,
10089
+ dimension,
10090
+ report,
10091
+ all: localeIsAll,
10092
+ sort: normalizeList(query.sort)[0],
10093
+ direction: normalizeList(query.direction)[0]
10042
10094
  };
10095
+ }
10096
+
10097
+ // components/metadata/MembersTable.tsx
10098
+ init_esm_shims();
10099
+
10100
+ // views/ImagePreview.tsx
10101
+ init_esm_shims();
10102
+ function ImagePreview3({
10103
+ member,
10104
+ height = "auto",
10105
+ width = "100%",
10106
+ size = "thumb",
10107
+ forceRefreshTimestamp = false
10108
+ }) {
10109
+ let extraParam = "";
10110
+ if (forceRefreshTimestamp) {
10111
+ extraParam = `&t=${( new Date()).getTime()}`;
10112
+ }
10113
+ const imageUrl = member && member.image_id ? `/api/cms/member/image?member=${member.content_id}&size=${size}${extraParam}` : "https://placehold.jp/cccccc/ffffff/900x600.png?text=None";
10114
+ return /* @__PURE__ */ jsx(Image, { alt: `Image for ${member.id}`, height, width, radius: "md", src: imageUrl });
10115
+ }
10116
+ var ImagePreview_default = ImagePreview3;
10117
+
10118
+ // components/metadata/MembersTable.tsx
10119
+ init_store2();
10120
+ function MembersTable({ members, onClickEdit, onSort, colsToRender = [], dataTableProps = {} }) {
10121
+ const [sortStatus, setSortStatus] = useState([]);
10122
+ const [records, setRecords] = useState([]);
10123
+ const { state, ...tableProps } = dataTableProps;
10043
10124
  useEffect(() => {
10044
- if (!variantConfig.config[selectedLocale]) {
10045
- setVariantConfig({
10046
- ...variantConfig,
10047
- config: {
10048
- ...variantConfig.config,
10049
- [selectedLocale]: { attributes: [] }
10050
- }
10051
- });
10052
- }
10053
- if (variantConfig.config[selectedLocale] && variantConfig.config[selectedLocale].path) {
10054
- getMembers(variantConfig.config[selectedLocale].path);
10125
+ if (typeof onSort !== "undefined" && sortStatus && sortStatus.length) {
10126
+ onSort(sortStatus);
10055
10127
  }
10056
- }, []);
10128
+ }, [sortStatus]);
10057
10129
  useEffect(() => {
10058
- setPayload(void 0);
10059
- let attributesList = [];
10060
- if (selectedLocale !== localeDefault10) {
10061
- const defaultAttributes = variantConfig.config[localeDefault10] ? [...variantConfig.config[localeDefault10].attributes].map((item) => {
10062
- const newItem = { ...item };
10063
- newItem.value = "";
10064
- return newItem;
10065
- }) : [];
10066
- if (variantConfig.config[selectedLocale] && variantConfig.config[selectedLocale].attributes) {
10067
- attributesList = defaultAttributes.map((da) => {
10068
- const item = variantConfig.config[selectedLocale].attributes.find((sa) => da.name === sa.name);
10069
- if (item) {
10070
- da.value = item.value;
10071
- }
10072
- return da;
10073
- });
10074
- } else {
10075
- attributesList = defaultAttributes;
10076
- }
10077
- setVariantConfig({
10078
- ...variantConfig,
10079
- config: {
10080
- ...variantConfig.config,
10081
- [selectedLocale]: {
10082
- ...variantConfig.config[selectedLocale],
10083
- attributes: attributesList
10130
+ setRecords(members);
10131
+ }, [members]);
10132
+ useEffect(() => {
10133
+ setRecords(members);
10134
+ }, []);
10135
+ const localeDefault10 = useAppSelector((state2) => state2.status.localeDefault);
10136
+ const none = /* @__PURE__ */ jsx(Badge, { color: "gray", children: "None" });
10137
+ const cols = [
10138
+ {
10139
+ header: "",
10140
+ accessorKey: "visible",
10141
+ enableResizing: false,
10142
+ enableSorting: false,
10143
+ size: 10,
10144
+ Cell: ({ row }) => /* @__PURE__ */ jsx(Fragment, { children: !row.original.visible ? /* @__PURE__ */ jsx(Tooltip, { label: "Visible: false", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconEyeOff, { size: 20 }) }) }) : /* @__PURE__ */ jsx("span", {}) })
10145
+ },
10146
+ {
10147
+ header: "ID",
10148
+ accessorKey: "id",
10149
+ enableSorting: typeof onSort !== "undefined" ? true : false,
10150
+ mantineTableHeadCellProps: {
10151
+ align: "right",
10152
+ sx: {
10153
+ "& .mantine-TableHeadCell-Content-Labels": {
10154
+ flexDirection: "row"
10084
10155
  }
10085
10156
  }
10086
- });
10087
- }
10088
- if (variantConfig.config[selectedLocale] && variantConfig.config[selectedLocale].path) {
10089
- getMembers(variantConfig.config[selectedLocale].path);
10090
- }
10091
- }, [selectedLocale]);
10092
- useEffect(() => {
10093
- if (payload) {
10094
- const keys2 = arrayFinder(payload);
10095
- setAccessors(keys2);
10096
- if (variantConfig.config[selectedLocale].accessor && payload[variantConfig.config[selectedLocale].accessor]) {
10097
- setConfigFromSample(
10098
- payload[variantConfig.config[selectedLocale].accessor][0],
10099
- variantConfig.config[selectedLocale].accessor
10100
- );
10101
- } else if (keys2.length === 0) {
10102
- if (payload && payload[0])
10103
- setConfigFromSample(payload[0]);
10104
- }
10105
- }
10106
- }, [payload]);
10107
- useEffect(() => {
10108
- if (variantConfig.slug) {
10109
- setLoadingValidSlug(true);
10110
- dispatch(actions_exports.variantValidateSlug(variantConfig.dimension_id, variantConfig.slug)).then(setValidSlug).then(() => {
10111
- setLoadingValidSlug(false);
10112
- }, (err) => {
10113
- console.error(err);
10114
- });
10115
- }
10116
- }, [variantConfig.slug]);
10117
- const onChangeAccessor = (accessor) => {
10118
- const dataArray = keyDiver(payload, accessor);
10119
- if (dataArray[0]) {
10120
- setConfigFromSample(dataArray[0], accessor);
10121
- }
10122
- };
10123
- const onChange = (field, value) => {
10157
+ },
10158
+ mantineTableBodyCellProps: {
10159
+ align: "right"
10160
+ },
10161
+ size: 100
10162
+ },
10163
+ {
10164
+ header: "Report",
10165
+ accessorKey: "report.name",
10166
+ enableSorting: false,
10167
+ size: 100
10168
+ },
10169
+ {
10170
+ header: "Dimension",
10171
+ accessorKey: "dimension.name",
10172
+ enableSorting: false,
10173
+ size: 100
10174
+ },
10175
+ {
10176
+ header: "Variant",
10177
+ accessorKey: "variant.name",
10178
+ enableSorting: false,
10179
+ size: 100
10180
+ },
10181
+ {
10182
+ header: "Relevance",
10183
+ accessorKey: "zvalue",
10184
+ enableSorting: typeof onSort !== "undefined" ? true : false,
10185
+ size: 100
10186
+ },
10187
+ {
10188
+ header: "Slug",
10189
+ accessorKey: "slug",
10190
+ Cell: ({ row }) => /* @__PURE__ */ jsxs("span", { children: [
10191
+ "/",
10192
+ row.original.variant.slug,
10193
+ "/",
10194
+ row.original.slug
10195
+ ] }),
10196
+ enableSorting: false
10197
+ },
10198
+ {
10199
+ header: `Name ${localeDefault10.toUpperCase()}`,
10200
+ accessorKey: "name",
10201
+ enableSorting: typeof onSort !== "undefined" ? true : false,
10202
+ Cell: ({ row }) => {
10203
+ const defaultLocalized = row.original.contentByLocale.find((item) => item.locale === localeDefault10);
10204
+ const othersLocalized = row.original.contentByLocale.filter((item) => item.locale !== localeDefault10);
10205
+ const nameTooltipContent = othersLocalized.reduce((acc, item) => {
10206
+ const extraName = `${item.locale.toUpperCase()}: ${item.name}`;
10207
+ const newLine2 = acc !== "" ? "\n" : "";
10208
+ return `${acc}${newLine2}${extraName}`;
10209
+ }, "");
10210
+ return /* @__PURE__ */ jsxs(Group, { children: [
10211
+ /* @__PURE__ */ jsx("span", { children: defaultLocalized?.name || none }),
10212
+ othersLocalized.length > 0 && /* @__PURE__ */ jsx(Tooltip, { label: nameTooltipContent, children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", color: "pink", radius: "xl", children: [
10213
+ "+",
10214
+ othersLocalized.length
10215
+ ] }) })
10216
+ ] });
10217
+ }
10218
+ },
10219
+ {
10220
+ header: `Keywords ${localeDefault10.toUpperCase()}`,
10221
+ accessorKey: "keywords",
10222
+ Cell: ({ row }) => {
10223
+ const defaultLocalized = row.original.contentByLocale.find((item) => item.locale === localeDefault10);
10224
+ const othersLocalized = row.original.contentByLocale.filter((item) => item.locale !== localeDefault10);
10225
+ const keywords = (defaultLocalized.keywords ? defaultLocalized.keywords : []).map((k) => /* @__PURE__ */ jsx(Badge, { children: k }, k));
10226
+ const keywordsTooltipContent = othersLocalized.reduce((acc, item) => {
10227
+ const otherKeywords = item.keywords || [];
10228
+ const extraKeywords = `${item.locale.toUpperCase()}: ${otherKeywords.length > 0 ? otherKeywords.join(",") : "None"}`;
10229
+ const newLine2 = acc !== "" ? "\n" : "";
10230
+ return `${acc}${newLine2}${extraKeywords}`;
10231
+ }, "");
10232
+ return /* @__PURE__ */ jsxs(Group, { children: [
10233
+ /* @__PURE__ */ jsx("span", { children: keywords.length > 0 ? keywords : none }),
10234
+ othersLocalized.length > 0 && /* @__PURE__ */ jsx(Tooltip, { label: keywordsTooltipContent, children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", color: "pink", radius: "xl", children: [
10235
+ "+",
10236
+ othersLocalized.length
10237
+ ] }) })
10238
+ ] });
10239
+ },
10240
+ enableSorting: false,
10241
+ size: 100
10242
+ },
10243
+ {
10244
+ header: "Image",
10245
+ accessorKey: "image",
10246
+ Cell: ({ row }) => /* @__PURE__ */ jsx(ImagePreview_default, { member: row.original, height: "50px", forceRefreshTimestamp: true }),
10247
+ enableSorting: false,
10248
+ size: 80
10249
+ },
10250
+ {
10251
+ header: "",
10252
+ accessorKey: "actions",
10253
+ Cell: ({ row }) => /* @__PURE__ */ jsx(
10254
+ ActionIcon,
10255
+ {
10256
+ onClick: () => onClickEdit ? onClickEdit(row.original) : false,
10257
+ children: /* @__PURE__ */ jsx(IconPencil, { size: 20 })
10258
+ },
10259
+ "edit"
10260
+ ),
10261
+ enableResizing: false,
10262
+ enableSorting: false,
10263
+ size: 50,
10264
+ mantineTableHeadCellProps: {
10265
+ align: "center"
10266
+ },
10267
+ mantineTableBodyCellProps: {
10268
+ align: "center"
10269
+ }
10270
+ }
10271
+ ];
10272
+ return /* @__PURE__ */ jsx(
10273
+ MantineReactTable,
10274
+ {
10275
+ columns: cols.filter((col) => colsToRender && colsToRender.length === 0 || colsToRender.includes(col.accessorKey)),
10276
+ data: records,
10277
+ enableBottomToolbar: false,
10278
+ enableColumnActions: false,
10279
+ enableColumnResizing: true,
10280
+ enablePagination: false,
10281
+ enableStickyHeader: true,
10282
+ enableTopToolbar: false,
10283
+ initialState: {
10284
+ density: "xs"
10285
+ },
10286
+ layoutMode: "grid",
10287
+ mantineTableContainerProps: {
10288
+ sx: {
10289
+ minHeight: 150,
10290
+ maxHeight: "95vh"
10291
+ }
10292
+ },
10293
+ mantineTableProps: {
10294
+ striped: true
10295
+ },
10296
+ manualSorting: true,
10297
+ onSortingChange: setSortStatus,
10298
+ state: {
10299
+ sorting: sortStatus,
10300
+ ...state
10301
+ },
10302
+ ...tableProps
10303
+ }
10304
+ );
10305
+ }
10306
+
10307
+ // libs/settings/variant.tsx
10308
+ init_esm_shims();
10309
+ var getVariantSettingsDefaults = (settings) => ({
10310
+ overrideNames: settings && typeof settings.overrideNames !== "undefined" ? settings.overrideNames : false,
10311
+ overrideRelevance: settings && typeof settings.overrideRelevance !== "undefined" ? settings.overrideRelevance : false,
10312
+ regenerateSlugs: settings && typeof settings.regenerateSlugs !== "undefined" ? settings.regenerateSlugs : false,
10313
+ keepOldMembers: settings && typeof settings.keepOldMembers !== "undefined" ? settings.keepOldMembers : true,
10314
+ doIngest: settings && typeof settings.doIngest !== "undefined" ? settings.doIngest : false,
10315
+ overrideAttributes: settings && typeof settings.overrideAttributes !== "undefined" ? settings.overrideAttributes : false
10316
+ });
10317
+
10318
+ // components/builder/components/SwitchWithTooltip.tsx
10319
+ init_esm_shims();
10320
+ function SwitchWithTooltip({ switchProps, yesText, noText }) {
10321
+ const finalSwitchProps = {
10322
+ size: "md",
10323
+ onLabel: "YES",
10324
+ offLabel: "NO",
10325
+ label: "Switch Label",
10326
+ my: "xs",
10327
+ checked: false,
10328
+ onChange: (event) => console.log(event.currentTarget.checked),
10329
+ ...switchProps
10330
+ };
10331
+ return /* @__PURE__ */ jsxs(Group, { children: [
10332
+ /* @__PURE__ */ jsx(Switch, { ...finalSwitchProps }),
10333
+ /* @__PURE__ */ jsx(
10334
+ Tooltip,
10335
+ {
10336
+ label: finalSwitchProps.checked ? yesText : noText,
10337
+ withArrow: true,
10338
+ multiline: true,
10339
+ width: 200,
10340
+ children: /* @__PURE__ */ jsx(ActionIcon, { variant: "filled", radius: "50%", size: "xs", children: /* @__PURE__ */ jsx(IconQuestionMark, { size: "xs" }) })
10341
+ }
10342
+ )
10343
+ ] });
10344
+ }
10345
+ var SwitchWithTooltip_default = SwitchWithTooltip;
10346
+
10347
+ // libs/js/isURL.ts
10348
+ init_esm_shims();
10349
+ function isURL(url) {
10350
+ try {
10351
+ new URL(url);
10352
+ return true;
10353
+ } catch (error) {
10354
+ return false;
10355
+ }
10356
+ }
10357
+ function VariantEditor({ for: variant, onClose: closeHandler }) {
10358
+ const dispatch = useAppDispatch();
10359
+ const localeDefault10 = useAppSelector((state) => state.status.localeDefault);
10360
+ const locales4 = useAppSelector((state) => state.status.locales);
10361
+ const localesItems = locales4.map((locale) => ({ value: locale, label: locale.toUpperCase() }));
10362
+ const [sample, setSample] = useState();
10363
+ const [selectedLocale, setSelectedLocale] = useState(localeDefault10);
10364
+ const [variantConfig, setVariantConfig] = useState(() => {
10365
+ const hydratedVariant = { ...variant };
10366
+ locales4.forEach((l) => {
10367
+ hydratedVariant.config = {
10368
+ ...hydratedVariant.config,
10369
+ [l]: {
10370
+ ...{
10371
+ attributes: [],
10372
+ idKey: "",
10373
+ labelKey: "",
10374
+ accessor: "",
10375
+ path: ""
10376
+ },
10377
+ ...hydratedVariant.config[l] || {}
10378
+ }
10379
+ };
10380
+ });
10381
+ return hydratedVariant;
10382
+ });
10383
+ const [loading, setLoading] = useState(false);
10384
+ const [loadingFetch, setLoadingFetch] = useState(false);
10385
+ const [fetchError, setFetchError] = useState(false);
10386
+ const [loadingValidSlug, setLoadingValidSlug] = useState(false);
10387
+ const [validSlug, setValidSlug] = useState({ valid: false, suggestion: "" });
10388
+ const [payload, setPayload] = useState();
10389
+ const [accessors, setAccessors] = useState([]);
10390
+ const [loadingSearch, setLoadingSearch] = useState(false);
10391
+ const [membersSearch, setMembersSearch] = useState([]);
10392
+ const getMembers = (path) => {
10393
+ if (isURL(path)) {
10394
+ setLoadingFetch(true);
10395
+ dispatch(actions_exports.urlProxy(path)).then((resp) => {
10396
+ setPayload(resp);
10397
+ if (resp) {
10398
+ const keys2 = arrayFinder(resp);
10399
+ setAccessors(keys2);
10400
+ if (variantConfig.config[selectedLocale].accessor && resp[variantConfig.config[selectedLocale].accessor]) {
10401
+ setConfigFromSample(
10402
+ resp[variantConfig.config[selectedLocale].accessor][0],
10403
+ variantConfig.config[selectedLocale].accessor
10404
+ );
10405
+ } else if (keys2.length === 0) {
10406
+ if (resp && resp[0])
10407
+ setConfigFromSample(resp[0]);
10408
+ }
10409
+ }
10410
+ setFetchError(false);
10411
+ setLoadingFetch(false);
10412
+ }).catch((e) => {
10413
+ console.error(e);
10414
+ setFetchError(`Fetch error: ${e.message}`);
10415
+ setPayload(void 0);
10416
+ setLoadingFetch(false);
10417
+ });
10418
+ }
10419
+ };
10420
+ const searchIngestedMembers = (variantId) => {
10421
+ setLoadingSearch(true);
10422
+ const searchParams = parseSearchMemberParams({
10423
+ variant: variantId,
10424
+ limit: "5",
10425
+ locale: "all",
10426
+ visible: "true",
10427
+ includes: "true",
10428
+ noImage: "false",
10429
+ format: "plain",
10430
+ all: "true"
10431
+ });
10432
+ dispatch(actions_exports.searchMember(searchParams)).then((resp) => {
10433
+ if (resp && resp.results) {
10434
+ const members = resp.results;
10435
+ setMembersSearch(members);
10436
+ if (members.length === 0) {
10437
+ onChangeSettings("doIngest", true);
10438
+ }
10439
+ }
10440
+ setLoadingSearch(false);
10441
+ }).catch((e) => {
10442
+ console.error(e);
10443
+ setLoadingSearch(false);
10444
+ });
10445
+ };
10446
+ const setConfigFromSample = (sample2, accessor = "") => {
10447
+ if (sample2) {
10448
+ const sampleKeys = Object.keys(sample2);
10449
+ const guessId = sampleKeys.find((d) => d.toLowerCase().includes("id")) || sampleKeys[0];
10450
+ const guessName = sampleKeys.find((d) => !d.toLowerCase().includes("id")) || sampleKeys[0];
10451
+ if (!variantConfig.config[selectedLocale].idKey || variantConfig.config[selectedLocale].idKey === "" || !variantConfig.config[selectedLocale].labelKey || variantConfig.config[selectedLocale].labelKey === "") {
10452
+ setVariantConfig({
10453
+ ...variantConfig,
10454
+ config: {
10455
+ ...variantConfig.config,
10456
+ [selectedLocale]: {
10457
+ ...variantConfig.config[selectedLocale],
10458
+ idKey: guessId,
10459
+ labelKey: guessName,
10460
+ accessor
10461
+ }
10462
+ }
10463
+ });
10464
+ }
10465
+ }
10466
+ setSample(sample2);
10467
+ };
10468
+ useEffect(() => {
10469
+ if (variantConfig.id) {
10470
+ searchIngestedMembers(variantConfig.id);
10471
+ }
10472
+ validateSlug(variantConfig.slug);
10473
+ if (variantConfig.config[selectedLocale] && variantConfig.config[selectedLocale].path) {
10474
+ getMembers(variantConfig.config[selectedLocale].path);
10475
+ }
10476
+ }, []);
10477
+ const onLocaleChange = (newLocale) => {
10478
+ setPayload(void 0);
10479
+ setFetchError(false);
10480
+ let attributesList = [];
10481
+ if (newLocale !== localeDefault10) {
10482
+ const defaultAttributes = variantConfig.config[localeDefault10] ? [...variantConfig.config[localeDefault10].attributes].map((item) => {
10483
+ const newItem = { ...item };
10484
+ newItem.value = "";
10485
+ return newItem;
10486
+ }) : [];
10487
+ if (variantConfig.config[newLocale] && variantConfig.config[newLocale].attributes) {
10488
+ attributesList = defaultAttributes.map((da) => {
10489
+ const item = variantConfig.config[newLocale].attributes.find((sa) => da.name === sa.name);
10490
+ if (item) {
10491
+ da.value = item.value;
10492
+ }
10493
+ return da;
10494
+ });
10495
+ } else {
10496
+ attributesList = defaultAttributes;
10497
+ }
10498
+ const newConfig = {
10499
+ ...variantConfig.config,
10500
+ [newLocale]: {
10501
+ ...variantConfig.config[newLocale],
10502
+ attributes: attributesList
10503
+ }
10504
+ };
10505
+ setVariantConfig({
10506
+ ...variantConfig,
10507
+ config: newConfig
10508
+ });
10509
+ }
10510
+ if (variantConfig.config[newLocale] && variantConfig.config[newLocale].path) {
10511
+ getMembers(variantConfig.config[newLocale].path);
10512
+ }
10513
+ setSelectedLocale(newLocale);
10514
+ };
10515
+ const variantSettings = useMemo(() => getVariantSettingsDefaults(variantConfig.settings), [variantConfig.settings]);
10516
+ const variantSettingsSwitches = useMemo(() => [
10517
+ {
10518
+ label: "Replace names",
10519
+ key: "overrideNames",
10520
+ yesText: "Names from new source will update the previously ingested members.",
10521
+ noText: "Original names will be keep."
10522
+ },
10523
+ {
10524
+ label: "Replace slugs",
10525
+ key: "regenerateSlugs",
10526
+ yesText: "Slugs will be regenerated based on new member's names and updated on previously ingested members.",
10527
+ noText: "Original slugs will be keep.",
10528
+ disabled: !variantSettings.overrideNames
10529
+ },
10530
+ {
10531
+ label: "Replace relevance value",
10532
+ key: "overrideRelevance",
10533
+ yesText: "Relevance index will be recalculated and updated on previously ingested members.",
10534
+ noText: "Original numbers will be keep."
10535
+ },
10536
+ {
10537
+ label: "Replace attributes",
10538
+ key: "overrideAttributes",
10539
+ yesText: "Attributes will be regenerated and override the current ones. Different ones will be kept.",
10540
+ noText: "Original attributes will be keep, ignoring the changes"
10541
+ },
10542
+ {
10543
+ label: "Keep all existing members",
10544
+ key: "keepOldMembers",
10545
+ yesText: "All the the existing members will be keep even if they are not in the new API members list",
10546
+ noText: "Members that are not in the API members list will be deleted, keeping both lists on sync."
10547
+ }
10548
+ ], [variantSettings.overrideNames]);
10549
+ const onChangeAccessor = (accessor) => {
10550
+ const dataArray = keyDiver(payload, accessor);
10551
+ if (dataArray[0]) {
10552
+ setConfigFromSample(dataArray[0], accessor);
10553
+ }
10554
+ };
10555
+ const validateSlug = (slug) => {
10556
+ dispatch(actions_exports.variantValidateSlug(variantConfig.dimension_id, slug)).then(setValidSlug).then(() => {
10557
+ setLoadingValidSlug(false);
10558
+ }, (err) => {
10559
+ console.error(err);
10560
+ });
10561
+ };
10562
+ const onChange = (field, value) => {
10124
10563
  let newValue = value;
10125
10564
  if (field === "slug") {
10126
10565
  newValue = slugifyInput_default(value);
10566
+ if (newValue) {
10567
+ setLoadingValidSlug(true);
10568
+ validateSlug(value);
10569
+ }
10127
10570
  }
10128
10571
  setVariantConfig({ ...variantConfig, [field]: newValue });
10129
10572
  };
10130
10573
  const onChangeConfig = (field, value) => {
10574
+ if (field === "path") {
10575
+ setFetchError(false);
10576
+ }
10131
10577
  setVariantConfig({
10132
10578
  ...variantConfig,
10133
10579
  config: {
@@ -10139,6 +10585,18 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
10139
10585
  }
10140
10586
  });
10141
10587
  };
10588
+ const onChangeSettings = (field, value) => {
10589
+ const extraUpdate = field === "overrideNames" && !value ? { regenerateSlugs: false } : {};
10590
+ setVariantConfig({
10591
+ ...variantConfig,
10592
+ //config: configUpdate,
10593
+ settings: {
10594
+ ...variantConfig.settings,
10595
+ ...extraUpdate,
10596
+ [field]: value
10597
+ }
10598
+ });
10599
+ };
10142
10600
  const onSubmit = () => {
10143
10601
  setLoading(true);
10144
10602
  dispatch(actions_exports.updateEntity("variant", variantConfig)).then(() => {
@@ -10162,15 +10620,17 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
10162
10620
  });
10163
10621
  };
10164
10622
  const addAttributes = () => {
10165
- const sampleKeys = Object.keys(sample);
10166
- const sampleKey = sampleKeys[0];
10167
- if (sampleKey) {
10168
- const existingAttributes = variantConfig.config[selectedLocale]?.attributes || [];
10169
- const attrCount = existingAttributes.length || 0;
10170
- updateAttributes([
10171
- ...existingAttributes,
10172
- { type: "constant", name: `attr${attrCount + 1}`, value: "" }
10173
- ]);
10623
+ if (sample) {
10624
+ const sampleKeys = Object.keys(sample);
10625
+ const sampleKey = sampleKeys[0];
10626
+ if (sampleKey) {
10627
+ const existingAttributes = variantConfig.config[selectedLocale]?.attributes || [];
10628
+ const attrCount = existingAttributes.length || 0;
10629
+ updateAttributes([
10630
+ ...existingAttributes,
10631
+ { type: "constant", name: `attr${attrCount + 1}`, value: "" }
10632
+ ]);
10633
+ }
10174
10634
  }
10175
10635
  };
10176
10636
  const onChangeAttribute = (key, targetIx, value) => {
@@ -10191,200 +10651,276 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
10191
10651
  };
10192
10652
  const keys = sample ? Object.keys(sample).map((d) => ({ value: d, label: `${d}: ${sample[d]}` })) : [];
10193
10653
  const accessorSelectData = accessors.map((d) => ({ value: d, label: d }));
10654
+ const invalidPath = !isURL(variantConfig.config[selectedLocale].path);
10655
+ const fetchErrorMsg = useMemo(() => {
10656
+ if (fetchError)
10657
+ return fetchError;
10658
+ if (invalidPath && variantConfig.config[selectedLocale].path !== "")
10659
+ return "Format error: Invalid URL.";
10660
+ return false;
10661
+ }, [fetchError, invalidPath, variantConfig.config, selectedLocale]);
10194
10662
  return /* @__PURE__ */ jsx(
10195
10663
  DrawerContentWithScroll,
10196
10664
  {
10197
10665
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
10198
10666
  /* @__PURE__ */ jsx(Title, { order: 2, children: `Editing Variant: ${variantConfig.name}` }),
10199
10667
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
10200
- /* @__PURE__ */ jsx(TextInput, { value: variantConfig.name, label: "Name", onChange: (e) => onChange("name", e.target.value) }),
10201
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
10202
- /* @__PURE__ */ jsx(
10203
- TextInput,
10204
- {
10205
- value: variantConfig.slug,
10206
- icon: !loadingValidSlug && !validSlug.valid ? /* @__PURE__ */ jsx(IconAlertCircle, {}) : /* @__PURE__ */ jsx(IconCircleCheck, {}),
10207
- label: "Slug",
10208
- description: loadingValidSlug ? "Validating slug..." : validSlug.valid ? "Valid slug." : "Invalid slug.",
10209
- error: !loadingValidSlug && !validSlug.valid ? /* @__PURE__ */ jsxs(Text, { children: [
10210
- "Duplicated slug. Suggestion:",
10211
- /* @__PURE__ */ jsx(
10212
- Code,
10213
- {
10214
- onClick: () => onChange("slug", validSlug.suggestion),
10215
- style: { cursor: "pointer" },
10216
- children: validSlug.suggestion
10217
- }
10218
- )
10219
- ] }) : false,
10220
- onChange: (e) => onChange("slug", e.target.value)
10221
- }
10222
- ),
10223
- /* @__PURE__ */ jsx(Divider, { my: "lg" }),
10224
- /* @__PURE__ */ jsx(Title, { order: 2, size: "h4", children: "Members data" }),
10225
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
10226
- /* @__PURE__ */ jsx(
10227
- SegmentedControl,
10228
- {
10229
- value: selectedLocale,
10230
- fullWidth: true,
10231
- onChange: setSelectedLocale,
10232
- data: localesItems
10233
- }
10234
- ),
10235
- variantConfig.config[selectedLocale] && /* @__PURE__ */ jsxs(Fragment, { children: [
10236
- /* @__PURE__ */ jsx(Space, { h: "lg" }),
10237
- /* @__PURE__ */ jsxs(Group, { grow: true, align: "flex-end", children: [
10668
+ /* @__PURE__ */ jsxs(Tabs, { defaultValue: "variant", children: [
10669
+ /* @__PURE__ */ jsxs(Tabs.List, { grow: true, children: [
10670
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "variant", children: "Variant" }),
10671
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "members", children: "Members" })
10672
+ ] }),
10673
+ /* @__PURE__ */ jsxs(Tabs.Panel, { value: "variant", py: "md", children: [
10674
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "Variant Settings" }),
10675
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
10238
10676
  /* @__PURE__ */ jsx(
10239
10677
  TextInput,
10240
10678
  {
10241
- onChange: (e) => onChangeConfig("path", e.target.value),
10242
- title: "Api endpoint",
10243
- description: "Enter the url to retrieve a member list to ingest. (JSON) and click Fetch.",
10244
- value: variantConfig.config[selectedLocale].path
10679
+ value: variantConfig.name,
10680
+ label: "Name",
10681
+ onChange: (e) => onChange("name", e.target.value)
10245
10682
  }
10246
10683
  ),
10684
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
10247
10685
  /* @__PURE__ */ jsx(
10248
- Button,
10686
+ TextInput,
10249
10687
  {
10250
- disabled: loadingFetch,
10251
- onClick: () => getMembers(variantConfig.config[selectedLocale].path),
10252
- loading: loadingFetch,
10253
- leftIcon: /* @__PURE__ */ jsx(IconPlayerPlay, {}),
10254
- children: loadingFetch ? "Fetching" : "Fetch"
10688
+ value: variantConfig.slug,
10689
+ icon: !loadingValidSlug && !validSlug.valid ? /* @__PURE__ */ jsx(IconAlertCircle, {}) : /* @__PURE__ */ jsx(IconCircleCheck, {}),
10690
+ label: "Slug",
10691
+ description: loadingValidSlug ? "Validating slug..." : validSlug.valid ? "Valid slug." : "Invalid slug.",
10692
+ error: !loadingValidSlug && !validSlug.valid ? /* @__PURE__ */ jsxs(Text, { children: [
10693
+ "Duplicated slug. Suggestion:",
10694
+ /* @__PURE__ */ jsx(
10695
+ Code,
10696
+ {
10697
+ onClick: () => onChange("slug", validSlug.suggestion),
10698
+ style: { cursor: "pointer" },
10699
+ children: validSlug.suggestion
10700
+ }
10701
+ )
10702
+ ] }) : false,
10703
+ onChange: (e) => onChange("slug", e.target.value)
10255
10704
  }
10256
10705
  )
10257
10706
  ] }),
10258
- payload && /* @__PURE__ */ jsxs("div", { children: [
10259
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10260
- /* @__PURE__ */ jsx(
10261
- Select,
10262
- {
10263
- value: variantConfig.config[selectedLocale].accessor,
10264
- label: "Elements",
10265
- description: "Choose the key that returns the array of elements that \n are going to be ingested as members.",
10266
- data: accessorSelectData,
10267
- disabled: accessorSelectData.length === 0,
10268
- placeholder: accessorSelectData.length === 0 ? "Root is an array" : "",
10269
- onChange: (e) => onChangeAccessor(e)
10270
- }
10271
- ),
10272
- /* @__PURE__ */ jsx(Divider, { label: "First element preview", labelPosition: "center" }),
10273
- payload[variantConfig.config[selectedLocale].accessor] && !Array.isArray(payload) && /* @__PURE__ */ jsx(InputMenuItem_default, { variables: payload[variantConfig.config[selectedLocale].accessor][0] }),
10274
- Array.isArray(payload) && payload[0] && /* @__PURE__ */ jsx(InputMenuItem_default, { variables: payload[0] }),
10275
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10276
- /* @__PURE__ */ jsx(
10277
- Select,
10278
- {
10279
- value: variantConfig.config[selectedLocale].idKey,
10280
- label: "Unique identificator",
10281
- description: "Choose the field that is a unique identification for a single member.",
10282
- data: keys,
10283
- onChange: (e) => onChangeConfig("idKey", e)
10284
- }
10285
- ),
10286
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10287
- /* @__PURE__ */ jsx(
10288
- Select,
10289
- {
10290
- value: variantConfig.config[selectedLocale].labelKey,
10291
- label: "Members' name",
10292
- description: "Choose the field that contains the members name.",
10293
- data: keys,
10294
- onChange: (e) => onChangeConfig("labelKey", e)
10295
- }
10296
- ),
10297
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10707
+ /* @__PURE__ */ jsxs(Tabs.Panel, { value: "members", py: "md", children: [
10708
+ /* @__PURE__ */ jsx(Title, { order: 3, children: "Members Settings" }),
10709
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: "Members, once ingested, become pages for this variant." }),
10298
10710
  /* @__PURE__ */ jsx(
10299
- Select,
10711
+ SwitchWithTooltip_default,
10300
10712
  {
10301
- value: variantConfig.config[selectedLocale].zValueKey || "",
10302
- label: "Member's relevance (optional)",
10303
- description: "Choose a field that will be converted to a number and \n normalized from 0 to 1 to determine the member's relevance.",
10304
- data: [
10305
- { value: "null", label: "None" },
10306
- ...keys
10307
- ],
10308
- onChange: (e) => onChangeConfig("zValueKey", e)
10713
+ switchProps: {
10714
+ label: `${!loadingSearch && membersSearch.length > 0 ? "Re-" : ""}Ingest members`,
10715
+ checked: variantSettings.doIngest,
10716
+ onChange: (event) => onChangeSettings("doIngest", event.currentTarget.checked)
10717
+ },
10718
+ yesText: `Run the ingestion process and save the variant details.
10719
+ Remember include the ingestion information for all the locales.`,
10720
+ noText: "Ingestion is not going to run and the current members are not going to suffer any change."
10309
10721
  }
10310
10722
  ),
10311
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10312
- /* @__PURE__ */ jsx(Title, { order: 3, size: "h5", children: "Attributes" }),
10313
- /* @__PURE__ */ jsx(Text, { size: "sm", children: "Attributes are properties to be ingested as metadata with the member element. Could be constants (same value for every member) or dynamic (based on a property of the data)" }),
10314
- /* @__PURE__ */ jsx(Space, { h: "xs" }),
10315
- variantConfig.config[selectedLocale].attributes && variantConfig.config[selectedLocale].attributes.map((attr, ix) => /* @__PURE__ */ jsxs(Group, { align: "end", grow: true, children: [
10316
- /* @__PURE__ */ jsx(
10317
- Select,
10723
+ variantSettings.doIngest && !loadingSearch && membersSearch.length > 0 && /* @__PURE__ */ jsxs(Box, { ml: "lg", children: [
10724
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: "Settings that are going to be applied for members reingestions and for all available languages, matching by unique identificator. All new members are going to be ingested. Images and tags for existing members will be safe." }),
10725
+ variantSettingsSwitches.map((vs) => /* @__PURE__ */ jsx(
10726
+ SwitchWithTooltip_default,
10318
10727
  {
10319
- value: variantConfig.config[selectedLocale].attributes[ix].type,
10320
- label: "Type",
10321
- data: [{ value: "variable", label: "Data based" }, { value: "constant", label: "Constant" }],
10322
- readOnly: selectedLocale !== localeDefault10,
10323
- disabled: selectedLocale !== localeDefault10,
10324
- onChange: (e) => onChangeAttribute("type", ix, e)
10325
- }
10326
- ),
10728
+ switchProps: {
10729
+ disabled: vs.disabled,
10730
+ label: vs.label,
10731
+ checked: variantSettings[vs.key],
10732
+ onChange: (event) => onChangeSettings(vs.key, event.currentTarget.checked)
10733
+ },
10734
+ yesText: vs.yesText,
10735
+ noText: vs.noText
10736
+ },
10737
+ vs.key
10738
+ ))
10739
+ ] }),
10740
+ !variantSettings.doIngest && /* @__PURE__ */ jsxs(Fragment, { children: [
10741
+ /* @__PURE__ */ jsx(Title, { order: 2, size: "h4", children: "Ingested members preview" }),
10742
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
10743
+ /* @__PURE__ */ jsxs(Stack, { spacing: 0, justify: "center", children: [
10744
+ loadingSearch && /* @__PURE__ */ jsx(Loader, { m: "0 auto" }),
10745
+ !loadingSearch && membersSearch.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
10746
+ /* @__PURE__ */ jsx(
10747
+ MembersTable,
10748
+ {
10749
+ members: membersSearch,
10750
+ colsToRender: ["id", "name", "slug"]
10751
+ }
10752
+ ),
10753
+ /* @__PURE__ */ jsx(Link, { href: "metadata", passHref: true, children: /* @__PURE__ */ jsx(Text, { c: "dimmed", align: "center", td: "underline", size: "xs", children: "See the full list in Metadata View" }) })
10754
+ ] })
10755
+ ] }),
10756
+ !loadingSearch && membersSearch.length === 0 && /* @__PURE__ */ jsx(Text, { c: "dimmed", align: "center", children: "No members ingested yet." }),
10757
+ /* @__PURE__ */ jsx(Space, { h: "xs" })
10758
+ ] }),
10759
+ variantSettings.doIngest && /* @__PURE__ */ jsxs(Fragment, { children: [
10760
+ /* @__PURE__ */ jsx(Divider, { my: "sm" }),
10761
+ /* @__PURE__ */ jsx(Title, { order: 2, size: "h4", children: "Members ingestion" }),
10762
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
10327
10763
  /* @__PURE__ */ jsx(
10328
- TextInput,
10329
- {
10330
- value: variantConfig.config[selectedLocale].attributes[ix].name,
10331
- label: "Name",
10332
- readOnly: selectedLocale !== localeDefault10,
10333
- disabled: selectedLocale !== localeDefault10,
10334
- onChange: (e) => onChangeAttribute("name", ix, e.target.value)
10335
- }
10336
- ),
10337
- attr.type === "variable" && /* @__PURE__ */ jsx(
10338
- Select,
10339
- {
10340
- value: variantConfig.config[selectedLocale].attributes[ix].value,
10341
- label: "Value",
10342
- data: keys,
10343
- onChange: (e) => onChangeAttribute("value", ix, e)
10344
- }
10345
- ),
10346
- attr.type === "constant" && /* @__PURE__ */ jsx(
10347
- TextInput,
10764
+ SegmentedControl,
10348
10765
  {
10349
- value: variantConfig.config[selectedLocale].attributes[ix].value,
10350
- label: "Value",
10351
- onChange: (e) => onChangeAttribute("value", ix, e.target.value)
10766
+ value: selectedLocale,
10767
+ fullWidth: true,
10768
+ onChange: onLocaleChange,
10769
+ data: localesItems,
10770
+ disabled: loadingFetch
10352
10771
  }
10353
10772
  ),
10354
- /* @__PURE__ */ jsx(
10355
- ActionIcon,
10356
- {
10357
- color: "red",
10358
- onClick: () => deleteAttribute(ix),
10359
- disabled: selectedLocale !== localeDefault10,
10360
- children: /* @__PURE__ */ jsx(IconTrash, { size: 20 })
10361
- }
10362
- )
10363
- ] }, ix)),
10364
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10365
- /* @__PURE__ */ jsx(
10366
- Button,
10367
- {
10368
- onClick: addAttributes,
10369
- leftIcon: "+",
10370
- disabled: loading || selectedLocale !== localeDefault10,
10371
- children: "Add Attribute"
10372
- }
10373
- )
10773
+ variantConfig.config[selectedLocale] && /* @__PURE__ */ jsxs(Fragment, { children: [
10774
+ /* @__PURE__ */ jsx(Space, { h: "lg" }),
10775
+ /* @__PURE__ */ jsx(Group, { children: /* @__PURE__ */ jsx(
10776
+ TextInput,
10777
+ {
10778
+ onChange: (e) => onChangeConfig("path", e.target.value),
10779
+ title: "Api endpoint",
10780
+ description: "Enter the url to retrieve a member list to ingest. (JSON) and click Fetch.",
10781
+ value: variantConfig.config[selectedLocale].path,
10782
+ error: fetchErrorMsg,
10783
+ rightSectionWidth: "105px",
10784
+ w: "100%",
10785
+ rightSection: loadingFetch ? /* @__PURE__ */ jsxs(Group, { align: "center", children: [
10786
+ /* @__PURE__ */ jsx(Loader, { size: "xs" }),
10787
+ /* @__PURE__ */ jsx(Text, { span: true, variant: "subtle", size: "xs", children: "Fetching..." })
10788
+ ] }) : /* @__PURE__ */ jsx(
10789
+ Button,
10790
+ {
10791
+ disabled: loadingFetch || invalidPath,
10792
+ onClick: () => getMembers(variantConfig.config[selectedLocale].path),
10793
+ leftIcon: /* @__PURE__ */ jsx(IconPlayerPlay, {}),
10794
+ children: "Fetch"
10795
+ }
10796
+ ),
10797
+ readOnly: loadingFetch
10798
+ }
10799
+ ) }),
10800
+ payload && /* @__PURE__ */ jsxs("div", { children: [
10801
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10802
+ /* @__PURE__ */ jsx(
10803
+ Select,
10804
+ {
10805
+ value: variantConfig.config[selectedLocale].accessor,
10806
+ label: "Elements",
10807
+ description: "Choose the key that returns the array of elements that \n are going to be ingested as members.",
10808
+ data: accessorSelectData,
10809
+ disabled: accessorSelectData.length === 0,
10810
+ placeholder: accessorSelectData.length === 0 ? "Root is an array" : "",
10811
+ onChange: (e) => onChangeAccessor(e)
10812
+ }
10813
+ ),
10814
+ /* @__PURE__ */ jsx(Divider, { label: "First element preview", labelPosition: "center" }),
10815
+ payload[variantConfig.config[selectedLocale].accessor] && !Array.isArray(payload) && /* @__PURE__ */ jsx(InputMenuItem_default, { variables: payload[variantConfig.config[selectedLocale].accessor][0] }),
10816
+ Array.isArray(payload) && payload[0] && /* @__PURE__ */ jsx(InputMenuItem_default, { variables: payload[0] }),
10817
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10818
+ /* @__PURE__ */ jsx(
10819
+ Select,
10820
+ {
10821
+ value: variantConfig.config[selectedLocale].idKey,
10822
+ label: "Unique identificator",
10823
+ description: "Choose the field that is a unique identification for a single member.",
10824
+ data: keys,
10825
+ onChange: (e) => onChangeConfig("idKey", e)
10826
+ }
10827
+ ),
10828
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10829
+ /* @__PURE__ */ jsx(
10830
+ Select,
10831
+ {
10832
+ value: variantConfig.config[selectedLocale].labelKey,
10833
+ label: "Members' name",
10834
+ description: "Choose the field that contains the members name.",
10835
+ data: keys,
10836
+ onChange: (e) => onChangeConfig("labelKey", e)
10837
+ }
10838
+ ),
10839
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10840
+ /* @__PURE__ */ jsx(
10841
+ Select,
10842
+ {
10843
+ value: variantConfig.config[selectedLocale].zValueKey || "",
10844
+ label: "Member's relevance (optional)",
10845
+ description: "Choose a field that will be converted to a number and \n normalized from 0 to 1 to determine the member's relevance.",
10846
+ data: [
10847
+ { value: "null", label: "None" },
10848
+ ...keys
10849
+ ],
10850
+ onChange: (e) => onChangeConfig("zValueKey", e)
10851
+ }
10852
+ ),
10853
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10854
+ /* @__PURE__ */ jsx(Title, { order: 3, size: "h5", children: "Attributes" }),
10855
+ /* @__PURE__ */ jsx(Text, { size: "sm", children: "Attributes are properties to be ingested as metadata with the member element. Could be constants (same value for every member) or dynamic (based on a property of the data)" }),
10856
+ /* @__PURE__ */ jsx(Space, { h: "xs" }),
10857
+ variantConfig.config[selectedLocale].attributes && variantConfig.config[selectedLocale].attributes.map((attr, ix) => /* @__PURE__ */ jsxs(Group, { align: "end", grow: true, children: [
10858
+ /* @__PURE__ */ jsx(
10859
+ Select,
10860
+ {
10861
+ value: variantConfig.config[selectedLocale].attributes[ix].type,
10862
+ label: "Type",
10863
+ data: [
10864
+ { value: "variable", label: "Data based" },
10865
+ { value: "constant", label: "Constant" }
10866
+ ],
10867
+ readOnly: selectedLocale !== localeDefault10,
10868
+ disabled: selectedLocale !== localeDefault10,
10869
+ onChange: (e) => onChangeAttribute("type", ix, e)
10870
+ }
10871
+ ),
10872
+ /* @__PURE__ */ jsx(
10873
+ TextInput,
10874
+ {
10875
+ value: variantConfig.config[selectedLocale].attributes[ix].name,
10876
+ label: "Name",
10877
+ readOnly: selectedLocale !== localeDefault10,
10878
+ disabled: selectedLocale !== localeDefault10,
10879
+ onChange: (e) => onChangeAttribute("name", ix, e.target.value)
10880
+ }
10881
+ ),
10882
+ attr.type === "variable" && /* @__PURE__ */ jsx(
10883
+ Select,
10884
+ {
10885
+ value: variantConfig.config[selectedLocale].attributes[ix].value,
10886
+ label: "Value",
10887
+ data: keys,
10888
+ onChange: (e) => onChangeAttribute("value", ix, e)
10889
+ }
10890
+ ),
10891
+ attr.type === "constant" && /* @__PURE__ */ jsx(
10892
+ TextInput,
10893
+ {
10894
+ value: variantConfig.config[selectedLocale].attributes[ix].value,
10895
+ label: "Value",
10896
+ onChange: (e) => onChangeAttribute("value", ix, e.target.value)
10897
+ }
10898
+ ),
10899
+ /* @__PURE__ */ jsx(
10900
+ ActionIcon,
10901
+ {
10902
+ color: "red",
10903
+ onClick: () => deleteAttribute(ix),
10904
+ disabled: selectedLocale !== localeDefault10,
10905
+ children: /* @__PURE__ */ jsx(IconTrash, { size: 20 })
10906
+ }
10907
+ )
10908
+ ] }, ix)),
10909
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
10910
+ /* @__PURE__ */ jsx(
10911
+ Button,
10912
+ {
10913
+ onClick: addAttributes,
10914
+ leftIcon: "+",
10915
+ disabled: loading || selectedLocale !== localeDefault10,
10916
+ children: "Add Attribute"
10917
+ }
10918
+ )
10919
+ ] })
10920
+ ] }),
10921
+ /* @__PURE__ */ jsx(Space, { h: "md" })
10922
+ ] })
10374
10923
  ] })
10375
- ] }),
10376
- /* @__PURE__ */ jsx(Space, { h: "md" }),
10377
- /* @__PURE__ */ jsxs(Code, { block: true, children: [
10378
- "TO-DO Settings for member ingestion (all languages), checkboxes.",
10379
- /* @__PURE__ */ jsx("br", {}),
10380
- "(x) override names?",
10381
- /* @__PURE__ */ jsx("br", {}),
10382
- "(x) regenerate slugs based on names changes?",
10383
- /* @__PURE__ */ jsx("br", {}),
10384
- "(x) keep old members that doesn't exists?",
10385
- /* @__PURE__ */ jsx("br", {}),
10386
- "(x) keep metadata: tags, images?",
10387
- /* @__PURE__ */ jsx("br", {})
10388
10924
  ] })
10389
10925
  ] }),
10390
10926
  buttons: /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -10403,7 +10939,7 @@ function VariantEditor({ for: variant, onClose: closeHandler }) {
10403
10939
  disabled: loading || loadingFetch || !loadingValidSlug && !validSlug.valid,
10404
10940
  loading: loading || loadingFetch,
10405
10941
  onClick: onSubmit,
10406
- children: "Ingest & Save"
10942
+ children: `${variantSettings.doIngest ? `${!loadingSearch && membersSearch.length > 0 ? "Re-" : ""}Ingest & ` : ""}Save`
10407
10943
  }
10408
10944
  )
10409
10945
  ] }),
@@ -10458,12 +10994,12 @@ function DimensionEditor({ id, onClose: closeHandler }) {
10458
10994
  ),
10459
10995
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
10460
10996
  /* @__PURE__ */ jsx(
10461
- TextInput,
10997
+ NumberInput,
10462
10998
  {
10463
- value: config.ordering,
10999
+ value: config.ordering ? parseInt(config.ordering, 10) : 0,
10464
11000
  type: "number",
10465
11001
  label: "Order",
10466
- onChange: (e) => onChange("ordering", e.target.value)
11002
+ onChange: (value) => onChange("ordering", value)
10467
11003
  }
10468
11004
  ),
10469
11005
  /* @__PURE__ */ jsx(Divider, { my: "xl" }),
@@ -10570,129 +11106,6 @@ init_store2();
10570
11106
 
10571
11107
  // components/builder/DimensionAutocomplete.tsx
10572
11108
  init_esm_shims();
10573
-
10574
- // api/endpoints/member.ts
10575
- init_esm_shims();
10576
- init_getLocales();
10577
- init_stripHTML();
10578
- init_lib3();
10579
-
10580
- // api/endpoints/lib.ts
10581
- init_esm_shims();
10582
- init_lib3();
10583
- function parseFiniteNumber(value) {
10584
- const num = Number.parseInt(`${value || ""}`, 10);
10585
- if (Number.isNaN(num) || !Number.isFinite(num)) {
10586
- throw new BackendError(400, `Invalid numeric parameter: ${value}`);
10587
- }
10588
- return num;
10589
- }
10590
- function normalizeList(value) {
10591
- if (value == null || value === "") {
10592
- return [];
10593
- }
10594
- if (Array.isArray(value)) {
10595
- return value;
10596
- }
10597
- return value.toString().split(",");
10598
- }
10599
-
10600
- // api/endpoints/member.ts
10601
- var { localeDefault: localeDefault9 } = getLocales_default();
10602
- function parseReadMemberParams(query) {
10603
- const locale = normalizeList(query.locale)[0] || localeDefault9 || "en";
10604
- const all = locale === "all" || yn4(query.all);
10605
- const mode = normalizeList(query.mode)[0];
10606
- const outputParam = normalizeList(query.output)[0] || "full";
10607
- const output = outputParam === "lite" ? "lite" : "full";
10608
- const relatedLimit = parseInt(normalizeList(query.related)[0], 10) || 5;
10609
- let variant = normalizeList(query.variant).map(parseFiniteNumber);
10610
- if (variant.length === 0) {
10611
- variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
10612
- }
10613
- if (mode === "ids") {
10614
- return {
10615
- all,
10616
- mode,
10617
- variant,
10618
- output,
10619
- locale: all ? localeDefault9 : stripHTML(locale),
10620
- ids: normalizeList(query.ids || query["ids[]"])
10621
- };
10622
- }
10623
- if (mode === "content_ids") {
10624
- return {
10625
- all,
10626
- mode,
10627
- variant,
10628
- output,
10629
- locale: all ? localeDefault9 : stripHTML(locale),
10630
- content_ids: normalizeList(query.content_ids || query["content_ids[]"]).map(parseFiniteNumber)
10631
- };
10632
- }
10633
- if (mode === "slugs") {
10634
- return {
10635
- all,
10636
- mode,
10637
- variant,
10638
- output,
10639
- locale: all ? localeDefault9 : stripHTML(locale),
10640
- slugs: normalizeList(query.slugs || query["slugs[]"]).map((token) => {
10641
- const [variantSlug, memberSlug] = token.split("/");
10642
- return { variantSlug, memberSlug };
10643
- })
10644
- };
10645
- }
10646
- if (mode === "related") {
10647
- return {
10648
- all,
10649
- mode,
10650
- locale: all ? localeDefault9 : stripHTML(locale),
10651
- related: relatedLimit,
10652
- current_ids: normalizeList(query.current_ids || query["current_ids[]"]).map(parseFiniteNumber),
10653
- report_ids: normalizeList(query.report_ids || query["report_ids[]"]).map(parseFiniteNumber),
10654
- dimension_ids: normalizeList(query.dimension_ids || query["dimension_ids[]"]).map(parseFiniteNumber),
10655
- variant_ids: normalizeList(query.variant_ids || query["variant_ids[]"]).map(parseFiniteNumber),
10656
- output
10657
- };
10658
- }
10659
- throw new BackendError(400, `Invalid mode: '${mode}'`);
10660
- }
10661
- function parseSearchMemberParams(query) {
10662
- const locale = normalizeList(query.locale)[0] || localeDefault9 || "en";
10663
- const localeIsAll = locale === "all";
10664
- const format2 = normalizeList(query.format)[0];
10665
- const formatIsNested = format2 ? format2 === "nested" : localeIsAll;
10666
- let variant = normalizeList(query.variant).map(parseFiniteNumber);
10667
- if (variant.length === 0) {
10668
- variant = normalizeList(query["variant[]"]).map(parseFiniteNumber);
10669
- }
10670
- let dimension = normalizeList(query.dimension).map(parseFiniteNumber);
10671
- if (dimension.length === 0) {
10672
- dimension = normalizeList(query["dimension[]"]).map(parseFiniteNumber);
10673
- }
10674
- let report = normalizeList(query.report).map(parseFiniteNumber);
10675
- if (report.length === 0) {
10676
- report = normalizeList(query["report[]"]).map(parseFiniteNumber);
10677
- }
10678
- return {
10679
- query: normalizeList(query.query || query.q)[0] || "",
10680
- locale: localeIsAll ? localeDefault9 : locale,
10681
- limit: normalizeList(query.limit).map(parseFiniteNumber)[0] ?? 5,
10682
- format: formatIsNested ? "nested" : "plain",
10683
- includes: yn4(query.includes, { default: true }),
10684
- visible: yn4(query.visible, { default: true }),
10685
- noImage: yn4(query.noImage, { default: false }),
10686
- variant,
10687
- dimension,
10688
- report,
10689
- all: localeIsAll,
10690
- sort: normalizeList(query.sort)[0],
10691
- direction: normalizeList(query.direction)[0]
10692
- };
10693
- }
10694
-
10695
- // components/builder/DimensionAutocomplete.tsx
10696
11109
  init_store2();
10697
11110
  function DimensionAutocomplete({ id, locale, onSelect, initialSelection = void 0 }) {
10698
11111
  const dispatch = useAppDispatch();
@@ -14402,7 +14815,7 @@ function FormatterForm({ formatterId, onEditEnd }) {
14402
14815
  DrawerContentWithScroll,
14403
14816
  {
14404
14817
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
14405
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: initialLoading, overlayBlur: 2, overlayOpacity: 50 }),
14818
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: initialLoading, overlayBlur: 2, overlayOpacity: 0.5 }),
14406
14819
  error && /* @__PURE__ */ jsx(Alert, { title: "Formatter Form", color: "red", children: "Error, please try again." }),
14407
14820
  formatter && !error && /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
14408
14821
  /* @__PURE__ */ jsxs(Group, { grow: true, align: "flex-start", children: [
@@ -14531,7 +14944,6 @@ var getCastedValue2 = (type, value) => {
14531
14944
  }
14532
14945
  };
14533
14946
  function FormattersTable({ filters, onClickEdit }) {
14534
- const [sortStatus, setSortStatus] = useState();
14535
14947
  const [records, setRecords] = useState([]);
14536
14948
  const formattersList = useFormatterList();
14537
14949
  const formatters2 = !formattersList.isSuccess ? [] : formattersList.data;
@@ -14555,7 +14967,7 @@ function FormattersTable({ filters, onClickEdit }) {
14555
14967
  };
14556
14968
  }), [formatters2]);
14557
14969
  const doSearch = () => {
14558
- let filteredResults = formattersFull.filter(
14970
+ const filteredResults = formattersFull.filter(
14559
14971
  (formatter) => {
14560
14972
  let findQuery = true;
14561
14973
  let findType = true;
@@ -14568,91 +14980,132 @@ function FormattersTable({ filters, onClickEdit }) {
14568
14980
  return findQuery && findType;
14569
14981
  }
14570
14982
  );
14571
- if (sortStatus) {
14572
- const sortIndex = sortStatus.direction === "asc" ? -1 : 1;
14573
- filteredResults = filteredResults.sort((a, b) => a[sortStatus.columnAccessor] > b[sortStatus.columnAccessor] ? 1 * sortIndex : -1 * sortIndex);
14574
- }
14575
14983
  setRecords(filteredResults);
14576
14984
  };
14577
14985
  useEffect(() => {
14578
14986
  doSearch();
14579
- }, [sortStatus, filters, formattersFull]);
14987
+ }, [filters, formattersFull]);
14580
14988
  const cols = [
14581
14989
  {
14582
- title: "ID",
14583
- accessor: "id",
14584
- sortable: true,
14585
- textAlignment: "right"
14990
+ header: "ID",
14991
+ accessorKey: "id",
14992
+ minSize: 55,
14993
+ size: 55,
14994
+ maxSize: 55
14586
14995
  },
14587
14996
  {
14588
- title: "Name",
14589
- accessor: "name",
14590
- sortable: true,
14591
- render: (member) => {
14592
- const icon = member.content.type === FORMATTER_TYPES.FORMATTER ? /* @__PURE__ */ jsx(IconVariable, { size: "1.3em" }) : /* @__PURE__ */ jsx(IconMathFunction, { size: "1.3em" });
14997
+ header: "Name",
14998
+ accessorKey: "name",
14999
+ Cell: ({ row }) => {
15000
+ const icon = row.original.content.type === FORMATTER_TYPES.FORMATTER ? /* @__PURE__ */ jsx(IconVariable, { size: "1.3em" }) : /* @__PURE__ */ jsx(IconMathFunction, { size: "1.3em" });
14593
15001
  return /* @__PURE__ */ jsxs(Group, { noWrap: true, align: "center", spacing: 2, children: [
14594
- /* @__PURE__ */ jsx("span", { children: member.name }),
14595
- /* @__PURE__ */ jsx(Tooltip, { label: FORMATTER_TYPES_NAMES[member.content.type], children: /* @__PURE__ */ jsx("span", { children: icon }) })
15002
+ /* @__PURE__ */ jsx("span", { children: row.original.name }),
15003
+ /* @__PURE__ */ jsx(Tooltip, { label: FORMATTER_TYPES_NAMES[row.original.content.type], children: /* @__PURE__ */ jsx("span", { children: icon }) })
14596
15004
  ] });
14597
- }
15005
+ },
15006
+ minSize: 80,
15007
+ size: 80
14598
15008
  },
14599
15009
  {
14600
- title: "Description",
14601
- accessor: "content.description"
15010
+ header: "Description",
15011
+ accessorKey: "content.description",
15012
+ enableSorting: false,
15013
+ mantineTableBodyCellProps: {
15014
+ sx: {
15015
+ textWrap: "wrap"
15016
+ }
15017
+ },
15018
+ minSize: 100
14602
15019
  },
14603
15020
  {
14604
- title: "Demo",
14605
- accessor: "content.testValue",
14606
- render: (member) => {
14607
- let input = member.content.testValue;
14608
- if (member.content.inputType === FORMATTER_INPUT_TYPES.STRING) {
15021
+ header: "Demo",
15022
+ accessorKey: "content.testValue",
15023
+ Cell: ({ row }) => {
15024
+ let input = row.original.content.testValue;
15025
+ if (row.original.content.inputType === FORMATTER_INPUT_TYPES.STRING) {
14609
15026
  input = `"${input}"`;
14610
15027
  }
14611
- let output = member.result;
14612
- if (typeof member.result === "string") {
15028
+ let output = row.original.result;
15029
+ if (typeof row.original.result === "string") {
14613
15030
  output = `"${output}"`;
14614
15031
  }
14615
15032
  return /* @__PURE__ */ jsxs(Group, { spacing: 2, children: [
14616
- /* @__PURE__ */ jsx(Tooltip, { label: `Input Type: ${FORMATTER_INPUT_TYPES_NAMES[member.content.inputType]}`, children: /* @__PURE__ */ jsx(Code, { color: "blue", children: input }) }),
15033
+ /* @__PURE__ */ jsx(Tooltip, { label: `Input Type: ${FORMATTER_INPUT_TYPES_NAMES[row.original.content.inputType]}`, children: /* @__PURE__ */ jsx(Code, { color: "blue", children: input }) }),
14617
15034
  /* @__PURE__ */ jsx(IconArrowRightCircle, {}),
14618
- /* @__PURE__ */ jsx(Code, { color: member.result && `${member.result}`.includes("ERROR") ? "red" : "teal", children: output })
15035
+ /* @__PURE__ */ jsx(Code, { color: row.original.result && `${row.original.result}`.includes("ERROR") ? "red" : "teal", children: output })
14619
15036
  ] });
14620
- }
15037
+ },
15038
+ enableSorting: false,
15039
+ minSize: 100,
15040
+ size: 100
14621
15041
  },
14622
15042
  {
14623
- title: "Usage",
14624
- accessor: "usageCount",
14625
- textAlignment: "right",
14626
- sortable: true
15043
+ header: "Usage",
15044
+ accessorKey: "usageCount",
15045
+ mantineTableHeadCellProps: {
15046
+ align: "right",
15047
+ sx: {
15048
+ "& .mantine-TableHeadCell-Content-Labels": {
15049
+ flexDirection: "row"
15050
+ }
15051
+ }
15052
+ },
15053
+ mantineTableBodyCellProps: {
15054
+ align: "right"
15055
+ },
15056
+ minSize: 85,
15057
+ size: 85,
15058
+ maxSize: 85
14627
15059
  },
14628
15060
  {
14629
- title: "",
14630
- accessor: "actions",
14631
- render: (member) => /* @__PURE__ */ jsxs(Group, { position: "center", spacing: "xs", noWrap: true, children: [
14632
- /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(member), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit"),
15061
+ header: "Actions",
15062
+ accessorKey: "actions",
15063
+ Cell: ({ row }) => /* @__PURE__ */ jsxs(Group, { position: "center", spacing: "xs", noWrap: true, children: [
15064
+ /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(row.original), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit"),
14633
15065
  /* @__PURE__ */ jsx(
14634
15066
  EntityDeleteButton,
14635
15067
  {
14636
- id: member.id,
15068
+ id: row.original.id,
14637
15069
  type: "formatter",
14638
- disabled: member.usageCount > 0,
14639
- warning: `Delete formatter called "${member.name}" (id:${member.id}) ? It is not used in any block.`
15070
+ disabled: row.original.usageCount > 0,
15071
+ warning: `Delete formatter called "${row.original.name}" (id:${row.original.id}) ? It is not used in any block.`
14640
15072
  }
14641
15073
  )
14642
- ] })
15074
+ ] }),
15075
+ enableSorting: false,
15076
+ minSize: 80,
15077
+ size: 80,
15078
+ maxSize: 80,
15079
+ mantineTableHeadCellProps: {
15080
+ align: "center"
15081
+ },
15082
+ mantineTableBodyCellProps: {
15083
+ align: "center"
15084
+ }
14643
15085
  }
14644
15086
  ];
14645
15087
  return /* @__PURE__ */ jsx(
14646
- DataTable,
15088
+ MantineReactTable,
14647
15089
  {
14648
- striped: true,
14649
- minHeight: 150,
14650
- records,
14651
15090
  columns: cols,
14652
- sortStatus,
14653
- onSortStatusChange: (s) => setSortStatus(s),
14654
- idAccessor: "id",
14655
- withBorder: true
15091
+ data: records,
15092
+ enableBottomToolbar: false,
15093
+ enableColumnActions: false,
15094
+ enableColumnResizing: true,
15095
+ enablePagination: false,
15096
+ enableTopToolbar: false,
15097
+ initialState: {
15098
+ density: "xs"
15099
+ },
15100
+ layoutMode: "grid",
15101
+ mantineTableContainerProps: {
15102
+ sx: {
15103
+ minHeight: 150
15104
+ }
15105
+ },
15106
+ mantineTableProps: {
15107
+ striped: true
15108
+ }
14656
15109
  }
14657
15110
  );
14658
15111
  }
@@ -14912,51 +15365,77 @@ init_store2();
14912
15365
 
14913
15366
  // components/metadata/ImageSelector.tsx
14914
15367
  init_esm_shims();
15368
+ var isProviderAllowed = (ipk) => {
15369
+ const allowedProviderOptions = process.env.NEXT_PUBLIC_IMAGE_PROVIDERS ? process.env.NEXT_PUBLIC_IMAGE_PROVIDERS.split(",") : [];
15370
+ return typeof process.env.NEXT_PUBLIC_IMAGE_PROVIDERS === "undefined" || allowedProviderOptions.indexOf(ipk) > -1 ? true : false;
15371
+ };
14915
15372
  function ImageSelector({ member, onEditEnd }) {
14916
15373
  const initialPrompt = member.contentByLocale && member.contentByLocale[0] ? member.contentByLocale[0].name : "";
14917
- const imageProviders = {
14918
- local: {
14919
- title: "Bespoke",
14920
- key: "local",
14921
- input: "text",
14922
- forceSearch: true,
14923
- getAxiosSearchConfig: (prompt2, image) => ({
14924
- url: "/api/cms/images/search/local",
14925
- method: "get",
14926
- params: { prompt: prompt2 }
14927
- })
14928
- },
14929
- flickr: {
14930
- title: "Flickr",
14931
- key: "flickr",
14932
- input: "text",
14933
- forceSearch: true,
14934
- getAxiosSearchConfig: (prompt2, image) => ({
14935
- url: "/api/cms/images/search/flickr",
14936
- method: "get",
14937
- params: { prompt: prompt2 }
14938
- })
14939
- },
14940
- unsplash: {
14941
- title: "Unsplash",
14942
- key: "unsplash",
14943
- input: "text",
14944
- forceSearch: true,
14945
- getAxiosSearchConfig: (prompt2, image) => ({
14946
- url: "/api/cms/images/search/unsplash",
14947
- method: "get",
14948
- params: { prompt: prompt2 }
14949
- })
14950
- },
14951
- upload: {
14952
- title: "Upload",
14953
- key: "upload",
14954
- input: "file",
14955
- forceSearch: false,
14956
- getAxiosSearchConfig: (prompt2, image) => ({})
14957
- }
14958
- };
14959
- const imageProvidersOptions = Object.keys(imageProviders).map((key) => ({ value: key, label: imageProviders[key].title }));
15374
+ const imageProviders = useMemo(
15375
+ () => ({
15376
+ upload: {
15377
+ title: "Upload",
15378
+ key: "upload",
15379
+ input: "file",
15380
+ forceSearch: false,
15381
+ pagination: false,
15382
+ getAxiosSearchConfig: (_prompt, _image, _page) => ({})
15383
+ },
15384
+ local: {
15385
+ title: "Gallery",
15386
+ key: "local",
15387
+ input: "text",
15388
+ forceSearch: true,
15389
+ pagination: false,
15390
+ getAxiosSearchConfig: (prompt2, _image, page) => ({
15391
+ url: "/api/cms/images/search/local",
15392
+ method: "get",
15393
+ params: { prompt: prompt2, page }
15394
+ })
15395
+ },
15396
+ flickr: {
15397
+ title: "Flickr",
15398
+ key: "flickr",
15399
+ input: "text",
15400
+ forceSearch: true,
15401
+ pagination: true,
15402
+ getAxiosSearchConfig: (prompt2, _image, page) => ({
15403
+ url: "/api/cms/images/search/flickr",
15404
+ method: "get",
15405
+ params: { prompt: prompt2, page }
15406
+ })
15407
+ },
15408
+ unsplash: {
15409
+ title: "Unsplash",
15410
+ key: "unsplash",
15411
+ input: "text",
15412
+ forceSearch: true,
15413
+ pagination: true,
15414
+ getAxiosSearchConfig: (prompt2, _image, page) => ({
15415
+ url: "/api/cms/images/search/unsplash",
15416
+ method: "get",
15417
+ params: { prompt: prompt2, page }
15418
+ })
15419
+ }
15420
+ /* adobe: {
15421
+ title: "Adobe",
15422
+ key: "adobe",
15423
+ input: "text",
15424
+ forceSearch: true,
15425
+ pagination: true,
15426
+ getAxiosSearchConfig: (prompt, _image, page): AxiosRequestConfig => ({
15427
+ url: "/api/cms/images/search/adobe",
15428
+ method: "get",
15429
+ params: {prompt, page},
15430
+ })
15431
+ }*/
15432
+ }),
15433
+ []
15434
+ );
15435
+ const imageProvidersOptions = useMemo(
15436
+ () => Object.values(imageProviders).filter((im) => isProviderAllowed(im.key)).map((im) => ({ value: im.key, label: im.title })),
15437
+ []
15438
+ );
14960
15439
  const [loading, setLoading] = useState(false);
14961
15440
  const [selectedProvider, setSelectedProvider] = useState(Object.values(imageProviders)[0]);
14962
15441
  const [scrollSize, setScrollSize] = useState(500);
@@ -14965,17 +15444,25 @@ function ImageSelector({ member, onEditEnd }) {
14965
15444
  const [results, setResults] = useState([]);
14966
15445
  const [selectedImage, setSelectedImage] = useState();
14967
15446
  const [error, setError] = useState(false);
14968
- const onSearch = async () => {
14969
- setError(false);
14970
- setLoading(true);
14971
- setResults([]);
14972
- const providerAxiosConfig = selectedProvider.getAxiosSearchConfig(prompt, imageToUpload);
14973
- const imageRecords = await axios(providerAxiosConfig).then((response) => response.data.data && response.data.data.results ? response.data.data.results : []).catch((e) => {
14974
- console.error(e);
14975
- setError(true);
14976
- });
14977
- setResults(imageRecords);
14978
- setLoading(false);
15447
+ const [selectedPage, setSelectedPage] = useState(1);
15448
+ const onSearch = async (page = void 0) => {
15449
+ if (page && page !== selectedPage) {
15450
+ setSelectedPage(1);
15451
+ } else {
15452
+ setError(false);
15453
+ setLoading(true);
15454
+ const providerAxiosConfig = selectedProvider.getAxiosSearchConfig(
15455
+ prompt,
15456
+ imageToUpload,
15457
+ page || selectedPage
15458
+ );
15459
+ const imageRecords = await axios(providerAxiosConfig).then((response) => response.data.data && response.data.data.results ? response.data.data.results : []).catch((e) => {
15460
+ console.error(e);
15461
+ setError(true);
15462
+ });
15463
+ setResults(imageRecords);
15464
+ setLoading(false);
15465
+ }
14979
15466
  };
14980
15467
  const onSelect = (img) => {
14981
15468
  setSelectedImage(img);
@@ -15008,25 +15495,26 @@ function ImageSelector({ member, onEditEnd }) {
15008
15495
  setError(false);
15009
15496
  setSelectedProvider(imageProviders[providerKey]);
15010
15497
  setSelectedImage(void 0);
15498
+ setResults([]);
15499
+ setSelectedPage(1);
15011
15500
  };
15012
15501
  useEffect(() => {
15013
15502
  const { innerHeight } = window;
15014
15503
  setScrollSize(innerHeight - 280);
15015
- onSearch();
15016
15504
  }, []);
15017
15505
  useEffect(() => {
15018
- setResults([]);
15019
15506
  if (!loading && selectedProvider.forceSearch) {
15020
15507
  onSearch();
15021
15508
  }
15022
- }, [selectedProvider]);
15509
+ }, [selectedPage, selectedProvider]);
15023
15510
  const noResults = results && results.length === 0 && !loading && selectedProvider.key !== "upload";
15511
+ const callToAction = results && results.length === 0 && !loading && selectedProvider.key === "upload";
15024
15512
  return /* @__PURE__ */ jsx(
15025
15513
  Drawer,
15026
15514
  {
15027
15515
  opened: true,
15028
15516
  onClose: onEditEnd,
15029
- title: `Edit image for ${initialPrompt} (${member.id}) `,
15517
+ title: `Image selection for ${initialPrompt} (${member.id}) `,
15030
15518
  padding: "lg",
15031
15519
  closeOnClickOutside: false,
15032
15520
  closeOnEscape: false,
@@ -15034,7 +15522,7 @@ function ImageSelector({ member, onEditEnd }) {
15034
15522
  size: "50%",
15035
15523
  lockScroll: true,
15036
15524
  withCloseButton: false,
15037
- children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: /* @__PURE__ */ jsxs(Stack, { children: [
15525
+ children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: /* @__PURE__ */ jsxs(Stack, { spacing: "sm", children: [
15038
15526
  /* @__PURE__ */ jsxs(Stack, { spacing: "xs", children: [
15039
15527
  /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, align: "flex-end", children: [
15040
15528
  selectedProvider.input === "text" && /* @__PURE__ */ jsx(
@@ -15043,15 +15531,18 @@ function ImageSelector({ member, onEditEnd }) {
15043
15531
  placeholder: "Search term",
15044
15532
  label: "Search term",
15045
15533
  value: prompt,
15046
- onChange: (e) => setPrompt(e.target.value)
15534
+ onChange: (e) => setPrompt(e.target.value),
15535
+ onKeyDown: getHotkeyHandler([
15536
+ ["Enter", () => onSearch(1)]
15537
+ ])
15047
15538
  }
15048
15539
  ),
15049
15540
  selectedProvider.input === "file" && /* @__PURE__ */ jsx(
15050
15541
  FileInput,
15051
15542
  {
15052
15543
  label: "Upload image",
15053
- placeholder: "Choose a PNG image from your computer",
15054
- accept: "image/png",
15544
+ placeholder: "Choose an image from your computer (png, jpg, jpeg, webp)",
15545
+ accept: "image/png,image/jpeg,image/jpg,image/webp",
15055
15546
  value: imageToUpload,
15056
15547
  onChange: (image) => {
15057
15548
  setSelectedImage(void 0);
@@ -15074,7 +15565,7 @@ function ImageSelector({ member, onEditEnd }) {
15074
15565
  {
15075
15566
  fullWidth: true,
15076
15567
  disabled: loading || !prompt || prompt === "",
15077
- onClick: onSearch,
15568
+ onClick: () => onSearch(1),
15078
15569
  leftIcon: /* @__PURE__ */ jsx(IconPlayerPlay, {}),
15079
15570
  children: "Search"
15080
15571
  }
@@ -15092,23 +15583,37 @@ function ImageSelector({ member, onEditEnd }) {
15092
15583
  )
15093
15584
  ] }),
15094
15585
  /* @__PURE__ */ jsx(Group, { mt: "xs", grow: true, children: /* @__PURE__ */ jsxs(ScrollArea, { offsetScrollbars: true, type: "always", style: { height: scrollSize }, children: [
15095
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
15586
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 0.5, overlayColor: "#fff" }),
15096
15587
  error && /* @__PURE__ */ jsx(Alert, { title: `${selectedProvider.title}`, color: "red", children: "Error, please try again." }),
15097
15588
  noResults && /* @__PURE__ */ jsx(Alert, { title: `${selectedProvider.title}`, color: "blue", children: "No results, for try another prompt or provider." }),
15098
- results && results.length > 0 && !loading && /* @__PURE__ */ jsx(SimpleGrid, { cols: 3, children: results.map((img) => /* @__PURE__ */ jsx(
15099
- Image,
15100
- {
15101
- radius: "md",
15102
- src: img.source,
15103
- style: {
15104
- cursor: "pointer",
15105
- borderRadius: 15,
15106
- border: selectedImage && selectedImage.id === img.id ? "5px solid black" : ""
15589
+ callToAction && /* @__PURE__ */ jsx(Alert, { icon: /* @__PURE__ */ jsx(IconPhoto, { size: "1rem" }), title: "Welcome to image selector!", color: "blue", children: "Upload an image or select a provider." }),
15590
+ results && results.length > 0 && !loading && /* @__PURE__ */ jsxs(Fragment, { children: [
15591
+ /* @__PURE__ */ jsx(SimpleGrid, { cols: 3, children: results.map((img) => /* @__PURE__ */ jsx(
15592
+ Image,
15593
+ {
15594
+ alt: `${selectedProvider.title}-image-${img.id}`,
15595
+ radius: "md",
15596
+ src: img.source,
15597
+ style: {
15598
+ cursor: "pointer",
15599
+ borderRadius: 15,
15600
+ border: selectedImage && selectedImage.id === img.id ? "5px solid black" : ""
15601
+ },
15602
+ onClick: () => onSelect(img)
15107
15603
  },
15108
- onClick: () => onSelect(img)
15109
- },
15110
- img.id
15111
- )) })
15604
+ img.id
15605
+ )) }),
15606
+ /* @__PURE__ */ jsx(Space, { h: "md" }),
15607
+ selectedProvider.pagination && /* @__PURE__ */ jsx(
15608
+ Button,
15609
+ {
15610
+ variant: "outline",
15611
+ fullWidth: true,
15612
+ onClick: () => setSelectedPage(selectedPage + 1),
15613
+ children: "Load more images"
15614
+ }
15615
+ )
15616
+ ] })
15112
15617
  ] }) }),
15113
15618
  /* @__PURE__ */ jsxs(Group, { mt: "xs", grow: true, style: { height: 45 }, children: [
15114
15619
  /* @__PURE__ */ jsx(
@@ -15136,24 +15641,6 @@ function ImageSelector({ member, onEditEnd }) {
15136
15641
  }
15137
15642
  var ImageSelector_default = ImageSelector;
15138
15643
 
15139
- // views/ImagePreview.tsx
15140
- init_esm_shims();
15141
- function ImagePreview3({
15142
- member,
15143
- height = "auto",
15144
- width = "100%",
15145
- size = "thumb",
15146
- forceRefreshTimestamp = false
15147
- }) {
15148
- let extraParam = "";
15149
- if (forceRefreshTimestamp) {
15150
- extraParam = `&t=${( new Date()).getTime()}`;
15151
- }
15152
- const imageUrl = member && member.image_id ? `/api/cms/member/image.png?member=${member.content_id}&size=${size}${extraParam}` : "https://placehold.jp/cccccc/ffffff/900x600.png?text=None";
15153
- return /* @__PURE__ */ jsx(Image, { height, width, radius: "md", src: imageUrl });
15154
- }
15155
- var ImagePreview_default = ImagePreview3;
15156
-
15157
15644
  // components/metadata/MemberForm.tsx
15158
15645
  init_SortableTable();
15159
15646
  function MemberForm({ memberId, onEditEnd }) {
@@ -15166,6 +15653,10 @@ function MemberForm({ memberId, onEditEnd }) {
15166
15653
  const [loading, setLoading] = useState(true);
15167
15654
  const [showImageSelector, setShowImageSelector] = useState(false);
15168
15655
  const [error, setError] = useState(false);
15656
+ const [activeTab, setActiveTab] = useState("member");
15657
+ const [loadingSearch, setLoadingSearch] = useState(false);
15658
+ const [membersSearch, setMembersSearch] = useState([]);
15659
+ const [selectedRecords, setSelectedRecords] = useState({});
15169
15660
  const mainForm = useForm();
15170
15661
  const localizedForms = locales4.reduce((acc, item) => {
15171
15662
  acc[item] = useForm({});
@@ -15222,6 +15713,34 @@ function MemberForm({ memberId, onEditEnd }) {
15222
15713
  }
15223
15714
  setLoading(false);
15224
15715
  };
15716
+ const fetchSearchMembers = async () => {
15717
+ if (member && member.contentByLocale) {
15718
+ const localizedName = member.contentByLocale.find((cl) => cl.locale === selectedLocale);
15719
+ if (localizedName) {
15720
+ setLoadingSearch(true);
15721
+ const searchParams = parseSearchMemberParams({
15722
+ q: localizedName.name,
15723
+ limit: "10",
15724
+ locale: selectedLocale,
15725
+ visible: "true",
15726
+ includes: "true",
15727
+ noImage: "false",
15728
+ format: "plain",
15729
+ all: "true"
15730
+ });
15731
+ dispatch(actions_exports.searchMember(searchParams)).then((resp) => {
15732
+ if (resp && resp.results) {
15733
+ const members = resp.results.filter((r) => r.content_id !== memberId);
15734
+ setMembersSearch(members);
15735
+ }
15736
+ setLoadingSearch(false);
15737
+ }).catch((e) => {
15738
+ console.error(e);
15739
+ setLoadingSearch(false);
15740
+ });
15741
+ }
15742
+ }
15743
+ };
15225
15744
  useEffect(() => {
15226
15745
  if (memberId) {
15227
15746
  fetchMemberData();
@@ -15229,6 +15748,11 @@ function MemberForm({ memberId, onEditEnd }) {
15229
15748
  setMember(null);
15230
15749
  }
15231
15750
  }, [memberId]);
15751
+ useEffect(() => {
15752
+ if (member) {
15753
+ fetchSearchMembers();
15754
+ }
15755
+ }, [member, selectedLocale]);
15232
15756
  const onImageSelectorClose = async (edited) => {
15233
15757
  if (edited) {
15234
15758
  fetchMemberData();
@@ -15267,12 +15791,30 @@ function MemberForm({ memberId, onEditEnd }) {
15267
15791
  } : null,
15268
15792
  image_id: member.image_id
15269
15793
  };
15270
- await axios.post("/api/cms/update/member", payload).then((resp) => {
15794
+ const updateMembersPromises = [
15795
+ axios.post("/api/cms/update/member", payload)
15796
+ ];
15797
+ const selectedRecordKeys = Object.keys(selectedRecords);
15798
+ if (selectedRecordKeys.length > 0) {
15799
+ selectedRecordKeys.forEach((sr) => {
15800
+ updateMembersPromises.push(
15801
+ axios.post("/api/cms/update/member", { content_id: membersSearch[sr].content_id, image_id: member.image_id })
15802
+ );
15803
+ });
15804
+ }
15805
+ Promise.all(updateMembersPromises).then(() => {
15271
15806
  onEditEnd();
15272
- return resp.data.data;
15807
+ }).catch((e) => {
15808
+ console.error(e);
15809
+ setError(true);
15273
15810
  });
15274
15811
  };
15275
15812
  const isValidLocalizedForm = Object.keys(localizedForms[selectedLocale].values).length > 0;
15813
+ const membersTableProps = {
15814
+ state: { rowSelection: selectedRecords },
15815
+ onRowSelectionChange: setSelectedRecords,
15816
+ enableRowSelection: (row) => member.image_id && row.original.image_id !== member.image_id
15817
+ };
15276
15818
  return /* @__PURE__ */ jsxs(Fragment, { children: [
15277
15819
  /* @__PURE__ */ jsx(
15278
15820
  Drawer,
@@ -15291,169 +15833,218 @@ function MemberForm({ memberId, onEditEnd }) {
15291
15833
  DrawerContentWithScroll,
15292
15834
  {
15293
15835
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
15294
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
15836
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 0.5 }),
15295
15837
  error && /* @__PURE__ */ jsx(Alert, { title: "Member Form", color: "red", children: "Error, please try again." }),
15296
- member && !error && /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
15297
- /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15298
- /* @__PURE__ */ jsxs(Stack, { children: [
15299
- /* @__PURE__ */ jsx(ImagePreview_default, { member, forceRefreshTimestamp: true }),
15300
- /* @__PURE__ */ jsx(
15301
- Button,
15302
- {
15303
- variant: "outline",
15304
- disabled: loading,
15305
- leftIcon: /* @__PURE__ */ jsx(IconPolaroid, {}),
15306
- onClick: () => setShowImageSelector(true),
15307
- children: "Change image"
15308
- }
15309
- ),
15310
- member && member.image && /* @__PURE__ */ jsx(
15311
- Button,
15312
- {
15313
- variant: "outline",
15314
- disabled: loading,
15315
- leftIcon: /* @__PURE__ */ jsx(IconCircleMinus, {}),
15316
- onClick: () => clearImage(),
15317
- children: "Remove image"
15318
- }
15319
- ),
15320
- /* @__PURE__ */ jsx(Space, { h: "md" })
15838
+ member && !error && /* @__PURE__ */ jsxs(Tabs, { defaultValue: "member", value: activeTab, onTabChange: setActiveTab, children: [
15839
+ /* @__PURE__ */ jsxs(Tabs.List, { grow: true, children: [
15840
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "member", icon: /* @__PURE__ */ jsx(IconListCheck, {}), children: "Member" }),
15841
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "image", icon: /* @__PURE__ */ jsx(IconPhoto, {}), children: "Image" })
15842
+ ] }),
15843
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "member", py: "md", children: /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
15844
+ /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15845
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Original ID", ...mainForm.getInputProps("id") }),
15846
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Content ID", ...mainForm.getInputProps("content_id") })
15321
15847
  ] }),
15322
- /* @__PURE__ */ jsxs(Stack, { justify: "flex-start", children: [
15848
+ /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15323
15849
  /* @__PURE__ */ jsx(
15324
15850
  TextInput,
15325
15851
  {
15326
- disabled: !member || !member.image,
15327
- label: "Source",
15328
- ...imageForm.getInputProps("url")
15329
- }
15330
- ),
15331
- /* @__PURE__ */ jsx(
15332
- TextInput,
15333
- {
15334
- disabled: !member || !member.image,
15335
- label: "Author",
15336
- ...imageForm.getInputProps("author")
15337
- }
15338
- ),
15339
- /* @__PURE__ */ jsx(
15340
- TextInput,
15341
- {
15342
- disabled: !member || !member.image,
15343
- label: "License",
15344
- ...imageForm.getInputProps("license")
15852
+ mt: "xs",
15853
+ icon: "/",
15854
+ disabled: true,
15855
+ label: "Variant Slug",
15856
+ ...mainForm.getInputProps("variant_slug")
15345
15857
  }
15346
15858
  ),
15859
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", icon: "/", disabled: true, label: "Member Slug", ...mainForm.getInputProps("slug") })
15860
+ ] }),
15861
+ /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15862
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Report", ...mainForm.getInputProps("report_name") }),
15863
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Dimension", ...mainForm.getInputProps("dimension_name") }),
15864
+ /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Variant", ...mainForm.getInputProps("variant_name") })
15865
+ ] }),
15866
+ /* @__PURE__ */ jsxs(Group, { grow: true, children: [
15867
+ /* @__PURE__ */ jsxs(Box, { onClick: () => setActiveTab("image"), style: { cursor: "pointer" }, pos: "relative", children: [
15868
+ /* @__PURE__ */ jsx(Overlay, { opacity: 0, center: true, sx: {
15869
+ backdropFilter: "none",
15870
+ "& button": {
15871
+ display: "none"
15872
+ },
15873
+ "&:hover": {
15874
+ backdropFilter: "blur(0.2375rem)",
15875
+ "button": {
15876
+ display: "flex"
15877
+ }
15878
+ }
15879
+ }, children: /* @__PURE__ */ jsx(Button, { size: "xs", radius: "sm", variant: "filled", leftIcon: /* @__PURE__ */ jsx(IconPhoto, { size: "0.9rem" }), children: "Edit" }) }),
15880
+ /* @__PURE__ */ jsx(ImagePreview_default, { member, forceRefreshTimestamp: true })
15881
+ ] }),
15347
15882
  /* @__PURE__ */ jsx(
15348
- SegmentedControl,
15883
+ Input.Wrapper,
15349
15884
  {
15350
- disabled: !member || !member.image,
15351
- value: selectedLocale,
15352
- onChange: setSelectedLocale,
15353
- data: localesItems
15885
+ label: "Search relevance",
15886
+ description: "\n Relevance index to be used with search. Values from 0 (less relevant) to 1 (more relevant)\n ",
15887
+ children: /* @__PURE__ */ jsx(
15888
+ NumberInput,
15889
+ {
15890
+ disabled: !mainForm.values.visible,
15891
+ type: "number",
15892
+ precision: 4,
15893
+ step: 1e-4,
15894
+ removeTrailingZeros: true,
15895
+ min: 0,
15896
+ max: 1,
15897
+ decimalSeparator: ".",
15898
+ ...mainForm.getInputProps("zvalue")
15899
+ }
15900
+ )
15354
15901
  }
15355
15902
  ),
15356
15903
  /* @__PURE__ */ jsx(
15357
- TextInput,
15904
+ Checkbox,
15358
15905
  {
15359
- disabled: !member || !member.image,
15360
- label: "Alternative image text",
15361
- ...localizedImageForms[selectedLocale].getInputProps("meta")
15906
+ mt: "2.3rem",
15907
+ label: "Visible in search",
15908
+ ...mainForm.getInputProps("visible", { type: "checkbox" })
15362
15909
  }
15363
15910
  )
15364
- ] })
15365
- ] }),
15366
- /* @__PURE__ */ jsxs(Code, { block: true, children: [
15367
- "TO-DO apply same image also to some of these members? List of checkboxes",
15368
- /* @__PURE__ */ jsx("br", {}),
15369
- "(x) another member, similar name",
15370
- /* @__PURE__ */ jsx("br", {}),
15371
- "(x) another member, similar name",
15372
- /* @__PURE__ */ jsx("br", {})
15373
- ] }),
15374
- /* @__PURE__ */ jsx(Divider, { my: "sm" }),
15375
- /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15376
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Original ID", ...mainForm.getInputProps("id") }),
15377
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Content ID", ...mainForm.getInputProps("content_id") })
15378
- ] }),
15379
- /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15380
- /* @__PURE__ */ jsx(
15381
- TextInput,
15911
+ ] }),
15912
+ /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", grow: true, children: /* @__PURE__ */ jsx(
15913
+ SegmentedControl,
15382
15914
  {
15383
- mt: "xs",
15384
- icon: "/",
15385
- disabled: true,
15386
- label: "Variant Slug",
15387
- ...mainForm.getInputProps("variant_slug")
15915
+ value: selectedLocale,
15916
+ onChange: setSelectedLocale,
15917
+ data: localesItems
15388
15918
  }
15389
- ),
15390
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", icon: "/", disabled: true, label: "Member Slug", ...mainForm.getInputProps("slug") })
15391
- ] }),
15392
- /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15393
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Report", ...mainForm.getInputProps("report_name") }),
15394
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Dimension", ...mainForm.getInputProps("dimension_name") }),
15395
- /* @__PURE__ */ jsx(TextInput, { mt: "xs", disabled: true, label: "Variant", ...mainForm.getInputProps("variant_name") })
15396
- ] }),
15397
- /* @__PURE__ */ jsx(Group, { position: "apart", grow: true, children: /* @__PURE__ */ jsx(
15398
- Checkbox,
15399
- {
15400
- mt: "xs",
15401
- label: "Visible",
15402
- ...mainForm.getInputProps("visible", { type: "checkbox" })
15403
- }
15404
- ) }),
15405
- /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", grow: true, children: /* @__PURE__ */ jsx(
15406
- SegmentedControl,
15407
- {
15408
- value: selectedLocale,
15409
- onChange: setSelectedLocale,
15410
- data: localesItems
15411
- }
15412
- ) }),
15413
- !isValidLocalizedForm && /* @__PURE__ */ jsx(Alert, { title: "Unavailable locale", color: "blue", children: "This language was not ingested for the current member. Go to variant editor and provide the members there." }),
15414
- isValidLocalizedForm && /* @__PURE__ */ jsxs(Fragment, { children: [
15415
- /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", grow: true, children: /* @__PURE__ */ jsx(TextInput, { label: "Name", ...localizedForms[selectedLocale].getInputProps("name") }) }),
15416
- /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", align: "top", grow: true, children: /* @__PURE__ */ jsx(
15417
- MultiSelect,
15418
- {
15419
- label: "Keywords",
15420
- data: localizedForms[selectedLocale].values.keywords,
15421
- placeholder: "Enter keywords",
15422
- searchable: true,
15423
- creatable: true,
15424
- valueComponent: ({
15425
- value,
15426
- label,
15427
- image,
15428
- name
15429
- }) => /* @__PURE__ */ jsxs(
15430
- Badge,
15919
+ ) }),
15920
+ !isValidLocalizedForm && /* @__PURE__ */ jsx(Alert, { title: "Unavailable locale", color: "blue", children: "This language was not ingested for the current member. Go to variant editor and provide the members there." }),
15921
+ isValidLocalizedForm && /* @__PURE__ */ jsxs(Fragment, { children: [
15922
+ /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", grow: true, children: /* @__PURE__ */ jsx(TextInput, { label: "Name", ...localizedForms[selectedLocale].getInputProps("name") }) }),
15923
+ /* @__PURE__ */ jsx(Group, { mt: "xs", position: "apart", align: "top", grow: true, children: /* @__PURE__ */ jsx(
15924
+ MultiSelect,
15925
+ {
15926
+ label: "Keywords",
15927
+ data: localizedForms[selectedLocale].values.keywords,
15928
+ placeholder: "Enter keywords",
15929
+ searchable: true,
15930
+ creatable: true,
15931
+ valueComponent: ({
15932
+ value,
15933
+ label,
15934
+ image,
15935
+ name
15936
+ }) => /* @__PURE__ */ jsxs(
15937
+ Badge,
15938
+ {
15939
+ onClick: () => {
15940
+ const current = localizedForms[selectedLocale].values.keywords;
15941
+ localizedForms[selectedLocale].setFieldValue(
15942
+ "keywords",
15943
+ current.filter((k) => k !== label)
15944
+ );
15945
+ },
15946
+ children: [
15947
+ label,
15948
+ " ",
15949
+ "x"
15950
+ ]
15951
+ }
15952
+ ),
15953
+ getCreateLabel: (query) => `+ Create ${query}`,
15954
+ value: localizedForms[selectedLocale].values.keywords,
15955
+ onCreate: (query) => {
15956
+ const current = localizedForms[selectedLocale].values.keywords;
15957
+ localizedForms[selectedLocale].setFieldValue("keywords", [...current, query]);
15958
+ return query;
15959
+ }
15960
+ }
15961
+ ) }),
15962
+ /* @__PURE__ */ jsx(Input.Wrapper, { label: "Attributes", children: /* @__PURE__ */ jsx(SortableTable, { data: localizedForms[selectedLocale].values.attributes }) })
15963
+ ] })
15964
+ ] }) }),
15965
+ /* @__PURE__ */ jsx(Tabs.Panel, { value: "image", py: "md", children: /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
15966
+ /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
15967
+ /* @__PURE__ */ jsxs(Stack, { children: [
15968
+ /* @__PURE__ */ jsx(ImagePreview_default, { member, forceRefreshTimestamp: true }),
15969
+ /* @__PURE__ */ jsx(
15970
+ Button,
15431
15971
  {
15432
- onClick: () => {
15433
- const current = localizedForms[selectedLocale].values.keywords;
15434
- localizedForms[selectedLocale].setFieldValue(
15435
- "keywords",
15436
- current.filter((k) => k !== label)
15437
- );
15438
- },
15439
- children: [
15440
- label,
15441
- " ",
15442
- "x"
15443
- ]
15972
+ variant: "outline",
15973
+ disabled: loading,
15974
+ leftIcon: /* @__PURE__ */ jsx(IconPolaroid, {}),
15975
+ onClick: () => setShowImageSelector(true),
15976
+ children: "Change image"
15977
+ }
15978
+ ),
15979
+ member && member.image && /* @__PURE__ */ jsx(
15980
+ Button,
15981
+ {
15982
+ variant: "outline",
15983
+ disabled: loading,
15984
+ leftIcon: /* @__PURE__ */ jsx(IconCircleMinus, {}),
15985
+ onClick: () => clearImage(),
15986
+ children: "Remove image"
15987
+ }
15988
+ ),
15989
+ /* @__PURE__ */ jsx(Space, { h: "md" })
15990
+ ] }),
15991
+ /* @__PURE__ */ jsxs(Stack, { justify: "flex-start", children: [
15992
+ /* @__PURE__ */ jsx(
15993
+ TextInput,
15994
+ {
15995
+ disabled: !member || !member.image,
15996
+ label: "Source",
15997
+ ...imageForm.getInputProps("url")
15998
+ }
15999
+ ),
16000
+ /* @__PURE__ */ jsx(
16001
+ TextInput,
16002
+ {
16003
+ disabled: !member || !member.image,
16004
+ label: "Author",
16005
+ ...imageForm.getInputProps("author")
16006
+ }
16007
+ ),
16008
+ /* @__PURE__ */ jsx(
16009
+ TextInput,
16010
+ {
16011
+ disabled: !member || !member.image,
16012
+ label: "License",
16013
+ ...imageForm.getInputProps("license")
16014
+ }
16015
+ ),
16016
+ /* @__PURE__ */ jsx(
16017
+ SegmentedControl,
16018
+ {
16019
+ disabled: !member || !member.image,
16020
+ value: selectedLocale,
16021
+ onChange: setSelectedLocale,
16022
+ data: localesItems
15444
16023
  }
15445
16024
  ),
15446
- getCreateLabel: (query) => `+ Create ${query}`,
15447
- value: localizedForms[selectedLocale].values.keywords,
15448
- onCreate: (query) => {
15449
- const current = localizedForms[selectedLocale].values.keywords;
15450
- localizedForms[selectedLocale].setFieldValue("keywords", [...current, query]);
15451
- return query;
16025
+ /* @__PURE__ */ jsx(
16026
+ TextInput,
16027
+ {
16028
+ disabled: !member || !member.image,
16029
+ label: "Alternative image text",
16030
+ ...localizedImageForms[selectedLocale].getInputProps("meta")
16031
+ }
16032
+ )
16033
+ ] })
16034
+ ] }),
16035
+ loadingSearch && /* @__PURE__ */ jsx(Loader, {}),
16036
+ !loadingSearch && membersSearch.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
16037
+ /* @__PURE__ */ jsx(Text, { children: "Select the members you want to update with the same image." }),
16038
+ /* @__PURE__ */ jsx(
16039
+ MembersTable,
16040
+ {
16041
+ members: membersSearch,
16042
+ colsToRender: ["id", "report", "name", "slug", "image"],
16043
+ dataTableProps: membersTableProps
15452
16044
  }
15453
- }
15454
- ) }),
15455
- /* @__PURE__ */ jsx(Input.Wrapper, { label: "Attributes", children: /* @__PURE__ */ jsx(SortableTable, { data: localizedForms[selectedLocale].values.attributes }) })
15456
- ] })
16045
+ )
16046
+ ] })
16047
+ ] }) })
15457
16048
  ] })
15458
16049
  ] }),
15459
16050
  buttons: /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -15484,133 +16075,6 @@ function MemberForm({ memberId, onEditEnd }) {
15484
16075
  showImageSelector && /* @__PURE__ */ jsx(ImageSelector_default, { member, onEditEnd: onImageSelectorClose })
15485
16076
  ] });
15486
16077
  }
15487
-
15488
- // components/metadata/MembersTable.tsx
15489
- init_esm_shims();
15490
- init_store2();
15491
- function MembersTable({ members, onClickEdit, onSort }) {
15492
- const [sortStatus, setSortStatus] = useState();
15493
- const [records, setRecords] = useState([]);
15494
- useEffect(() => {
15495
- if (sortStatus) {
15496
- onSort(sortStatus);
15497
- }
15498
- }, [sortStatus]);
15499
- useEffect(() => {
15500
- setRecords(members);
15501
- }, [members]);
15502
- useEffect(() => {
15503
- setRecords(members);
15504
- }, []);
15505
- const localeDefault10 = useAppSelector((state) => state.status.localeDefault);
15506
- const cols = [
15507
- {
15508
- title: "",
15509
- accessor: "visible",
15510
- width: "10px",
15511
- render: ({ visible }) => /* @__PURE__ */ jsx(Fragment, { children: !visible ? /* @__PURE__ */ jsx(Tooltip, { label: "Visible: false", children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(IconEyeOff, { size: 20 }) }) }) : /* @__PURE__ */ jsx("span", {}) })
15512
- },
15513
- {
15514
- title: "ID",
15515
- accessor: "id",
15516
- sortable: true,
15517
- textAlignment: "right"
15518
- },
15519
- {
15520
- title: "Report",
15521
- accessor: "report.name"
15522
- },
15523
- {
15524
- title: "Dimension",
15525
- accessor: "dimension.name"
15526
- },
15527
- {
15528
- title: "Variant",
15529
- accessor: "variant.name"
15530
- },
15531
- {
15532
- title: "Relevance",
15533
- sortable: true,
15534
- accessor: "zvalue"
15535
- },
15536
- {
15537
- title: "Slug",
15538
- accessor: "slug",
15539
- render: ({ slug, variant }) => /* @__PURE__ */ jsxs("span", { children: [
15540
- "/",
15541
- variant.slug,
15542
- "/",
15543
- slug
15544
- ] })
15545
- },
15546
- {
15547
- title: `Name ${localeDefault10.toUpperCase()}`,
15548
- sortable: true,
15549
- accessor: "name",
15550
- render: ({ contentByLocale }) => {
15551
- const defaultLocalized = contentByLocale.find((item) => item.locale === localeDefault10);
15552
- const othersLocalized = contentByLocale.filter((item) => item.locale !== localeDefault10);
15553
- const nameTooltipContent = othersLocalized.reduce((acc, item) => {
15554
- const extraName = `${item.locale.toUpperCase()}: ${item.name}`;
15555
- const newLine2 = acc !== "" ? "\n" : "";
15556
- return `${acc}${newLine2}${extraName}`;
15557
- }, "");
15558
- return /* @__PURE__ */ jsxs(Group, { children: [
15559
- /* @__PURE__ */ jsx("span", { children: defaultLocalized.name }),
15560
- othersLocalized.length > 0 && /* @__PURE__ */ jsx(Tooltip, { label: nameTooltipContent, children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", color: "pink", radius: "xl", children: [
15561
- "+",
15562
- othersLocalized.length
15563
- ] }) })
15564
- ] });
15565
- }
15566
- },
15567
- {
15568
- title: `Keywords ${localeDefault10.toUpperCase()}`,
15569
- accessor: "keywords",
15570
- render: ({ contentByLocale }) => {
15571
- const defaultLocalized = contentByLocale.find((item) => item.locale === localeDefault10);
15572
- const othersLocalized = contentByLocale.filter((item) => item.locale !== localeDefault10);
15573
- const keywords = (defaultLocalized.keywords ? defaultLocalized.keywords : []).map((k) => /* @__PURE__ */ jsx(Badge, { children: k }, k));
15574
- const keywordsTooltipContent = othersLocalized.reduce((acc, item) => {
15575
- const otherKeywords = item.keywords || [];
15576
- const extraKeywords = `${item.locale.toUpperCase()}: ${otherKeywords.length > 0 ? otherKeywords.join(",") : "None"}`;
15577
- const newLine2 = acc !== "" ? "\n" : "";
15578
- return `${acc}${newLine2}${extraKeywords}`;
15579
- }, "");
15580
- return /* @__PURE__ */ jsxs(Group, { children: [
15581
- /* @__PURE__ */ jsx("span", { children: keywords.length > 0 ? keywords : /* @__PURE__ */ jsx(Badge, { color: "gray", children: "None" }) }),
15582
- othersLocalized.length > 0 && /* @__PURE__ */ jsx(Tooltip, { label: keywordsTooltipContent, children: /* @__PURE__ */ jsxs(Avatar, { size: "sm", color: "pink", radius: "xl", children: [
15583
- "+",
15584
- othersLocalized.length
15585
- ] }) })
15586
- ] });
15587
- }
15588
- },
15589
- {
15590
- title: "Image",
15591
- accessor: "image",
15592
- render: (member) => /* @__PURE__ */ jsx(ImagePreview_default, { member, height: "50px" })
15593
- },
15594
- {
15595
- title: "",
15596
- accessor: "actions",
15597
- render: (member) => /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(member), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit")
15598
- }
15599
- ];
15600
- return /* @__PURE__ */ jsx(
15601
- DataTable,
15602
- {
15603
- striped: true,
15604
- minHeight: 150,
15605
- records,
15606
- columns: cols,
15607
- sortStatus,
15608
- onSortStatusChange: (s) => setSortStatus(s),
15609
- idAccessor: "content_id",
15610
- withBorder: true
15611
- }
15612
- );
15613
- }
15614
16078
  function MetadataEditor() {
15615
16079
  const [editingId, setEditingId] = useState(null);
15616
16080
  const [results, setResults] = useState([]);
@@ -15621,7 +16085,9 @@ function MetadataEditor() {
15621
16085
  setInternalFilters(filters);
15622
16086
  };
15623
16087
  const onChangeSort = (sort) => {
15624
- setInternalSort(sort);
16088
+ if (sort && sort.length) {
16089
+ setInternalSort(sort[0]);
16090
+ }
15625
16091
  };
15626
16092
  const setEditMember = (member) => {
15627
16093
  setEditingId(member.content_id);
@@ -15644,8 +16110,8 @@ function MetadataEditor() {
15644
16110
  ...getParams,
15645
16111
  locale: "all",
15646
16112
  includes: true,
15647
- sort: internalSort ? internalSort.columnAccessor : "zvalue",
15648
- direction: internalSort ? internalSort.direction : "desc"
16113
+ sort: internalSort ? internalSort.id : "zvalue",
16114
+ direction: internalSort ? internalSort.desc ? "desc" : "asc" : "desc"
15649
16115
  }
15650
16116
  }
15651
16117
  ).then((response) => response.data && response.data.data && response.data.data.results ? response.data.data.results : []);
@@ -15662,7 +16128,7 @@ function MetadataEditor() {
15662
16128
  /* @__PURE__ */ jsx(FilterSidebar2, { onChange: onChangeFilters, loading })
15663
16129
  ] }),
15664
16130
  /* @__PURE__ */ jsxs(Grid.Col, { span: 10, style: { height: "100vh", position: "relative" }, children: [
15665
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
16131
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 0.5 }),
15666
16132
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
15667
16133
  /* @__PURE__ */ jsx(MembersTable, { members: results, onClickEdit: setEditMember, onSort: onChangeSort })
15668
16134
  ] })
@@ -15783,7 +16249,7 @@ function ReportPicker() {
15783
16249
  }, [ref.data, ref.error, ref.status, reportAccess]);
15784
16250
  return /* @__PURE__ */ jsxs(Container, { size: "xl", children: [
15785
16251
  /* @__PURE__ */ jsx("h1", { children: "Reports" }),
15786
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: createLoading, overlayBlur: 2, overlayOpacity: 50 }),
16252
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: createLoading, overlayBlur: 2, overlayOpacity: 0.5 }),
15787
16253
  content,
15788
16254
  /* @__PURE__ */ jsx(Space, { h: "xl", w: "xl" }),
15789
16255
  /* @__PURE__ */ jsx(
@@ -16174,7 +16640,7 @@ function UserForm({ userId, onEditEnd, roles }) {
16174
16640
  DrawerContentWithScroll,
16175
16641
  {
16176
16642
  content: /* @__PURE__ */ jsxs(Fragment, { children: [
16177
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
16643
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 0.5 }),
16178
16644
  error && /* @__PURE__ */ jsx(Alert, { title: "Member Form", color: "red", children: "Error, please try again." }),
16179
16645
  user && !error && /* @__PURE__ */ jsxs(Stack, { justify: "space-between", children: [
16180
16646
  /* @__PURE__ */ jsxs(Group, { position: "apart", grow: true, children: [
@@ -16269,50 +16735,44 @@ function UserForm({ userId, onEditEnd, roles }) {
16269
16735
 
16270
16736
  // components/users/UsersTable.tsx
16271
16737
  init_esm_shims();
16272
- init_store2();
16273
- function UsersTable({ response, onClickEdit, onSort, onPageChange }) {
16274
- const [sortStatus, setSortStatus] = useState();
16738
+ function UsersTable({ response, onClickEdit, onPageChange }) {
16275
16739
  const [records, setRecords] = useState([]);
16276
16740
  const [paginationStatus, setPaginationStatus] = useState({
16277
- start: 0,
16278
- limit: 1,
16279
- total: 0,
16280
- page: 0
16741
+ pageIndex: 0,
16742
+ pageSize: 10
16281
16743
  });
16744
+ const [totalResults, setTotalResults] = useState(0);
16282
16745
  useEffect(() => {
16283
- if (sortStatus) {
16284
- onSort(sortStatus);
16285
- }
16286
- }, [sortStatus]);
16746
+ onPageChange(paginationStatus.pageIndex + 1);
16747
+ }, [paginationStatus.pageIndex]);
16287
16748
  useEffect(() => {
16288
16749
  if (response) {
16289
16750
  setRecords(response.users);
16290
- setPaginationStatus({
16291
- start: response.start,
16292
- limit: response.limit,
16293
- total: response.total,
16294
- page: response.start / response.limit + 1
16295
- });
16751
+ setTotalResults(response.total);
16296
16752
  }
16297
16753
  }, [response]);
16298
16754
  useEffect(() => {
16299
16755
  setRecords(response);
16300
16756
  }, []);
16301
- useAppSelector((state) => state.status.localeDefault);
16302
16757
  const cols = [
16303
16758
  {
16304
- title: "",
16305
- accessor: "image",
16306
- width: 50,
16307
- render: (member) => /* @__PURE__ */ jsx(Avatar, { src: member.picture, alt: "it's me", radius: 20 })
16759
+ header: "",
16760
+ accessorKey: "image",
16761
+ Cell: ({ row }) => {
16762
+ return /* @__PURE__ */ jsx(Avatar, { src: row.original.picture, alt: `${row.original.name}`, radius: 20 });
16763
+ },
16764
+ size: 50,
16765
+ mantineTableBodyCellProps: {
16766
+ align: "center"
16767
+ }
16308
16768
  },
16309
16769
  {
16310
- title: "Name",
16311
- accessor: "name"
16770
+ header: "Name",
16771
+ accessorKey: "name"
16312
16772
  },
16313
16773
  {
16314
- title: "Email",
16315
- accessor: "email"
16774
+ header: "Email",
16775
+ accessorKey: "email"
16316
16776
  },
16317
16777
  /*{
16318
16778
  title: `Keywords ${localeDefault.toUpperCase()}`,
@@ -16347,26 +16807,52 @@ function UsersTable({ response, onClickEdit, onSort, onPageChange }) {
16347
16807
  },
16348
16808
  },*/
16349
16809
  {
16350
- title: "",
16351
- accessor: "actions",
16352
- render: (member) => /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(member), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit")
16810
+ header: "Actions",
16811
+ accessorKey: "actions",
16812
+ Cell: ({ row }) => /* @__PURE__ */ jsx(ActionIcon, { onClick: () => onClickEdit(row.original), children: /* @__PURE__ */ jsx(IconPencil, { size: 20 }) }, "edit"),
16813
+ size: 100,
16814
+ mantineTableHeadCellProps: {
16815
+ align: "center"
16816
+ },
16817
+ mantineTableBodyCellProps: {
16818
+ align: "center"
16819
+ }
16353
16820
  }
16354
16821
  ];
16355
16822
  return /* @__PURE__ */ jsx(
16356
- DataTable,
16823
+ MantineReactTable,
16357
16824
  {
16358
- striped: true,
16359
- minHeight: 150,
16360
- records,
16361
16825
  columns: cols,
16362
- sortStatus,
16363
- onSortStatusChange: (s) => setSortStatus(s),
16364
- idAccessor: "email",
16365
- withBorder: true,
16366
- totalRecords: paginationStatus.total,
16367
- recordsPerPage: paginationStatus.limit,
16368
- page: paginationStatus.page,
16369
- onPageChange
16826
+ data: records,
16827
+ enableColumnActions: false,
16828
+ enablePagination: true,
16829
+ enableSorting: false,
16830
+ enableTopToolbar: false,
16831
+ initialState: {
16832
+ density: "xs"
16833
+ },
16834
+ layoutMode: "grid",
16835
+ mantinePaginationProps: {
16836
+ showRowsPerPage: false
16837
+ },
16838
+ mantineTableContainerProps: {
16839
+ sx: {
16840
+ minHeight: 150
16841
+ }
16842
+ },
16843
+ mantineTableProps: {
16844
+ striped: true
16845
+ },
16846
+ manualPagination: true,
16847
+ onPaginationChange: setPaginationStatus,
16848
+ paginationDisplayMode: "pages",
16849
+ rowCount: totalResults,
16850
+ state: {
16851
+ pagination: {
16852
+ pageIndex: paginationStatus.pageIndex,
16853
+ pageSize: paginationStatus.pageSize
16854
+ }
16855
+ }
16370
16856
  }
16371
16857
  );
16372
16858
  }
@@ -16376,14 +16862,10 @@ function UsersEditor() {
16376
16862
  const [roles, setRoles] = useState([]);
16377
16863
  const [loading, setLoading] = useState(true);
16378
16864
  const [internalFilters, setInternalFilters] = useState({ query: "" });
16379
- const [internalSort, setInternalSort] = useState();
16380
16865
  const dispatch = useAppDispatch();
16381
16866
  const onChangeFilters = (filters) => {
16382
16867
  setInternalFilters(filters);
16383
16868
  };
16384
- const onChangeSort = (sort) => {
16385
- setInternalSort(sort);
16386
- };
16387
16869
  const onPageChange = (page) => {
16388
16870
  setInternalFilters({
16389
16871
  ...internalFilters,
@@ -16420,7 +16902,7 @@ function UsersEditor() {
16420
16902
  }, [dispatch]);
16421
16903
  useEffect(() => {
16422
16904
  doSearch();
16423
- }, [internalFilters, internalSort]);
16905
+ }, [internalFilters]);
16424
16906
  return /* @__PURE__ */ jsxs(Container, { fluid: true, children: [
16425
16907
  /* @__PURE__ */ jsxs(Grid, { children: [
16426
16908
  /* @__PURE__ */ jsxs(Grid.Col, { span: 2, children: [
@@ -16428,14 +16910,13 @@ function UsersEditor() {
16428
16910
  /* @__PURE__ */ jsx(FilterSidebar3, { onChange: onChangeFilters, loading, roles })
16429
16911
  ] }),
16430
16912
  /* @__PURE__ */ jsxs(Grid.Col, { span: 10, style: { height: "100vh", position: "relative" }, children: [
16431
- /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 50 }),
16913
+ /* @__PURE__ */ jsx(LoadingOverlay, { visible: loading, overlayBlur: 2, overlayOpacity: 0.5 }),
16432
16914
  /* @__PURE__ */ jsx(Space, { h: "xs" }),
16433
16915
  /* @__PURE__ */ jsx(
16434
16916
  UsersTable,
16435
16917
  {
16436
16918
  response: results,
16437
16919
  onClickEdit: setEditUser,
16438
- onSort: onChangeSort,
16439
16920
  onPageChange
16440
16921
  }
16441
16922
  )