@evergis/react 3.1.42 → 3.1.46

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/react.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
2
- import { IconButton, Flex, transition, Chip, Icon, Description, FlexSpan, IconToggle, Popup, Menu, DraggableTree, shadows, Divider, LegendToggler, Tooltip as Tooltip$1, DropdownField, MultiSelectContainer, IconButtonButton, FlatButton, DraggableTreeContainer, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, darkTheme, NumberRangeSlider, useAsyncAutocomplete, AutoComplete, Dropdown, Checkbox, CircularProgress, RangeNumberInput, dateFormat } from '@evergis/uilib-gl';
2
+ import { IconButton, Flex, transition, Chip, Icon, Description, FlexSpan, IconToggle, Popup, Menu, DraggableTree, shadows, Divider, LegendToggler, Tooltip as Tooltip$1, DropdownField, MultiSelectContainer, IconButtonButton, FlatButton, DraggableTreeContainer, LinearProgress, H2, ThemeProvider, defaultTheme, Preview, Blank, Popover, Expander, darkTheme, NumberRangeSlider, useAsyncAutocomplete, AutoComplete, Dropdown, Checkbox, CircularProgress, RangeNumberInput, dateFormat } from '@evergis/uilib-gl';
3
3
  import { createContext, memo, useRef, useState, useEffect, useCallback, useContext, useMemo, Fragment } from 'react';
4
4
  import styled, { createGlobalStyle, css, useTheme } from 'styled-components';
5
5
  import { lineChartClassNames, BarChart as BarChart$1, barChartClassNames, LineChart, PieChart } from '@evergis/charts';
@@ -20,6 +20,8 @@ import MapGL, { Source, Layer as Layer$1 } from 'react-map-gl/mapbox';
20
20
  import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
21
21
  import 'mapbox-gl/dist/mapbox-gl.css';
22
22
  import { Swiper, SwiperSlide } from 'swiper/react';
23
+ import ReactMarkdown from 'react-markdown';
24
+ import remarkGfm from 'remark-gfm';
23
25
 
24
26
  const AddFeatureButton = ({ title, icon = "feature_add" /* , layerName, geometryType*/ }) => {
25
27
  // const [, handleAddFeature] = useFeatureCreator(layerName, geometryType);
@@ -4446,24 +4448,48 @@ const formatDataSourceCondition = ({ condition, configFilters, filters, attribut
4446
4448
  const DashboardChipsContainer = styled(Flex) `
4447
4449
  flex-wrap: wrap;
4448
4450
  `;
4451
+ const DefaultChipColorMixin = css `
4452
+ && {
4453
+ color: ${({ theme: { palette } }) => palette.textPrimary};
4454
+ }
4455
+
4456
+ && > * {
4457
+ color: ${({ theme: { palette } }) => palette.textPrimary};
4458
+ }
4459
+
4460
+ && span[kind]:after {
4461
+ color: ${({ theme: { palette } }) => palette.icon};
4462
+ }
4463
+ `;
4464
+ const CustomChipColorMixin = css `
4465
+ && {
4466
+ color: ${({ $fontColor }) => $fontColor};
4467
+ }
4468
+
4469
+ && > * {
4470
+ color: ${({ $fontColor }) => $fontColor};
4471
+ }
4472
+
4473
+ && span[kind]:after {
4474
+ color: ${({ $fontColor }) => $fontColor};
4475
+ }
4476
+ `;
4449
4477
  const DashboardChip$1 = styled(Chip) `
4450
4478
  margin: 0 0.25rem 0.25rem 0;
4451
4479
  background: ${({ $isDefault, $bgColor, theme: { palette } }) => $isDefault ? palette.element : $bgColor || palette.primary};
4452
4480
  border-radius: ${({ $radius, theme: { borderRadius } }) => $radius || borderRadius.medium};
4453
4481
  white-space: nowrap;
4454
4482
  font-size: ${({ $fontSize }) => $fontSize || "0.875rem"};
4455
- color: ${({ $isDefault, $fontColor, theme: { palette } }) => $isDefault ? palette.textPrimary : $fontColor || "#fff"};
4483
+ color: ${({ theme: { palette } }) => palette.iconContrast};
4456
4484
 
4457
4485
  > * {
4458
4486
  font-size: ${({ $fontSize }) => $fontSize || "0.875rem"};
4459
- color: ${({ $isDefault, $fontColor, theme: { palette } }) => $isDefault ? palette.textPrimary : $fontColor || "#fff"};
4460
4487
  }
4461
4488
 
4462
4489
  span[kind] {
4463
4490
  height: 0.875rem;
4464
4491
 
4465
4492
  :after {
4466
- color: ${({ $isDefault, $fontColor, theme: { palette } }) => ($isDefault ? palette.icon : $fontColor || "#fff")};
4467
4493
  font-size: 0.875rem;
4468
4494
  }
4469
4495
  }
@@ -4472,6 +4498,9 @@ const DashboardChip$1 = styled(Chip) `
4472
4498
  width: auto;
4473
4499
  padding: 0 0.5rem;
4474
4500
  }
4501
+
4502
+ ${({ $isDefault }) => $isDefault && DefaultChipColorMixin}
4503
+ ${({ $fontColor, $isDefault }) => !!$fontColor && !$isDefault && CustomChipColorMixin}
4475
4504
  `;
4476
4505
 
4477
4506
  const ChartLegendContainer = styled(Flex) `
@@ -5038,7 +5067,7 @@ const LayerGroup = ({ group, onlyMainTools }) => {
5038
5067
  if (!group) {
5039
5068
  return null;
5040
5069
  }
5041
- return (jsx(LayerGroupContainer, { visible: group.isVisible, children: jsxs(LayerGroupMain, { children: [jsx(Icon, { kind: group.isExpanded ? "tree_folder_open" : "tree_folder_closed", style: { color: group.clientData.color } }), jsxs(Description, { children: [jsx("div", { style: { wordBreak: "break-word" }, children: group?.alias || group?.name }), jsx(IconButton, { kind: group.isExpanded ? "reduce" : "expand", onClick: () => onToggleExpand(group.name, !group.isExpanded) })] }), jsx(FlexSpan, { children: jsxs(Flex, { flexWrap: "nowrap", p: "0 0.5rem", children: [jsx(FlexSpan, { children: jsx(IconToggle, { kind: group.isVisible ? "password_show" : "password_hide", className: "feature-visible", isSelected: group.isVisible, onClick: () => onToggleVisibility(group.name, !group.isVisible) }) }), !onlyMainTools && (jsx(Popup, { distance: -14, isVisible: isMenuOpen, onRequestClose: toggleMenu, anchor: ref => (jsx(FlexSpan, { children: jsx(IconButton, { innerRef: ref, kind: "menu_vertical", onClick: toggleMenu }) })), children: jsx(Menu, { options: options, selectOption: selectOption }) }))] }) })] }) }));
5070
+ return (jsx(LayerGroupContainer, { visible: group.isVisible, children: jsxs(LayerGroupMain, { children: [jsx(Icon, { kind: group.isExpanded ? "tree_folder_opened" : "tree_folder_closed", style: { color: group.clientData.color } }), jsxs(Description, { children: [jsx("div", { style: { wordBreak: "break-word" }, children: group?.alias || group?.name }), jsx(IconButton, { kind: group.isExpanded ? "reduce" : "expand", onClick: () => onToggleExpand(group.name, !group.isExpanded) })] }), jsx(FlexSpan, { children: jsxs(Flex, { flexWrap: "nowrap", p: "0 0.5rem", children: [jsx(FlexSpan, { children: jsx(IconToggle, { kind: group.isVisible ? "password_show" : "password_hide", className: "feature-visible", isSelected: group.isVisible, onClick: () => onToggleVisibility(group.name, !group.isVisible) }) }), !onlyMainTools && (jsx(Popup, { distance: -14, isVisible: isMenuOpen, onRequestClose: toggleMenu, anchor: ref => (jsx(FlexSpan, { children: jsx(IconButton, { innerRef: ref, kind: "menu_vertical", onClick: toggleMenu }) })), children: jsx(Menu, { options: options, selectOption: selectOption }) }))] }) })] }) }));
5042
5071
  };
5043
5072
 
5044
5073
  const createTreeNode = (layer, Component, onlyMainTools) => {
@@ -6172,12 +6201,29 @@ const SvgContainer = styled.div `
6172
6201
  const ContainerIconTitle = styled(Flex) `
6173
6202
  align-items: center;
6174
6203
  flex-wrap: nowrap;
6204
+ flex-shrink: 1;
6205
+ flex-grow: 0;
6175
6206
  color: ${({ fontColor, theme: { palette } }) => fontColor || palette.textSecondary};
6176
6207
 
6208
+ > div {
6209
+ flex-shrink: 1;
6210
+ flex-grow: 0;
6211
+ width: auto;
6212
+ }
6213
+
6214
+ ${SvgContainer} {
6215
+ flex-shrink: 0;
6216
+ flex-grow: 0;
6217
+ margin-right: 0.5rem;
6218
+ }
6219
+
6220
+ > * {
6221
+ width: auto;
6222
+ }
6223
+
6177
6224
  svg,
6178
6225
  img,
6179
- span[kind],
6180
- ${SvgContainer} {
6226
+ span[kind] {
6181
6227
  margin-right: 0.5rem;
6182
6228
  }
6183
6229
 
@@ -7548,6 +7594,169 @@ const ElementLink = memo(({ type, elementConfig }) => {
7548
7594
  return link.startsWith("http") ? jsx(ExternalLink, { onClick: () => window.open(link) }) : jsx(LocalLink, { link: link });
7549
7595
  });
7550
7596
 
7597
+ const MarkdownWrapper = styled.div `
7598
+ padding: 0;
7599
+ background: transparent;
7600
+ border-radius: 0.5rem;
7601
+ font-family: 'Nunito Sans', sans-serif;
7602
+ color: ${({ theme: { palette } }) => palette.textPrimary};
7603
+
7604
+ /* Paragraphs */
7605
+ p {
7606
+ font-size: 0.875rem;
7607
+ line-height: 1rem;
7608
+ letter-spacing: 0.0052rem;
7609
+ margin: 0 0 1rem 0;
7610
+ font-weight: 400;
7611
+
7612
+ &:last-child {
7613
+ margin-bottom: 0;
7614
+ }
7615
+ }
7616
+
7617
+ /* Headings */
7618
+ h1, h2, h3, h4, h5, h6 {
7619
+ margin: 0 0 0.75rem 0;
7620
+ font-weight: 300;
7621
+ }
7622
+
7623
+ h1 {
7624
+ font-size: 1.5rem;
7625
+ line-height: 1.75rem;
7626
+ }
7627
+
7628
+ h2 {
7629
+ font-size: 1.25rem;
7630
+ line-height: 1.5rem;
7631
+ }
7632
+
7633
+ h3 {
7634
+ font-size: 1rem;
7635
+ line-height: 1.25rem;
7636
+ }
7637
+
7638
+ /* Images */
7639
+ img {
7640
+ max-width: 100%;
7641
+ height: auto;
7642
+ border-radius: 0.5rem;
7643
+ object-fit: cover;
7644
+ margin: 0.75rem 0;
7645
+ }
7646
+
7647
+ /* Links */
7648
+ a {
7649
+ color: ${({ theme: { palette } }) => palette.primary};
7650
+ text-decoration: none;
7651
+
7652
+ &:hover {
7653
+ text-decoration: underline;
7654
+ }
7655
+ }
7656
+
7657
+ /* Lists */
7658
+ ul, ol {
7659
+ margin: 0 0 1rem 0;
7660
+ padding-left: 1.25rem;
7661
+
7662
+ li {
7663
+ font-size: 0.875rem;
7664
+ line-height: 1rem;
7665
+ margin-bottom: 0.5rem;
7666
+ }
7667
+ }
7668
+
7669
+ /* Code */
7670
+ code {
7671
+ background: ${({ theme: { palette } }) => palette.element};
7672
+ padding: 0.125rem 0.375rem;
7673
+ border-radius: 0.25rem;
7674
+ font-family: monospace;
7675
+ font-size: 0.8125rem;
7676
+ }
7677
+
7678
+ pre {
7679
+ background: ${({ theme: { palette } }) => palette.element};
7680
+ padding: 0.75rem;
7681
+ border-radius: 0.25rem;
7682
+ overflow-x: auto;
7683
+ margin: 0.75rem 0;
7684
+
7685
+ code {
7686
+ background: transparent;
7687
+ padding: 0;
7688
+ }
7689
+ }
7690
+
7691
+ /* Hide horizontal rules */
7692
+ hr {
7693
+ display: none;
7694
+ }
7695
+ `;
7696
+ styled(Flex) `
7697
+ align-items: center;
7698
+ gap: 1rem;
7699
+ margin-top: 1rem;
7700
+ `;
7701
+ styled.span `
7702
+ display: block;
7703
+ font-size: 0.75rem;
7704
+ line-height: 0.875rem;
7705
+ opacity: 0.36;
7706
+ margin: 0 0 0.5rem 0;
7707
+ `;
7708
+ styled.div `
7709
+ width: 1.25rem;
7710
+ height: 1.25rem;
7711
+ cursor: pointer;
7712
+ transition: opacity 0.2s;
7713
+
7714
+ &:hover {
7715
+ opacity: 0.7;
7716
+ }
7717
+
7718
+ img, svg {
7719
+ width: 100%;
7720
+ height: 100%;
7721
+ display: block;
7722
+ }
7723
+ `;
7724
+ const ExpandButton = styled(IconButton) `
7725
+ margin-bottom: 1rem;
7726
+ `;
7727
+
7728
+ const ElementMarkdown = memo(({ elementConfig, type }) => {
7729
+ const { attributes } = useWidgetContext(type);
7730
+ const { t } = useGlobalContext();
7731
+ const [expanded, setExpanded] = useState(false);
7732
+ const { attributeName, value, options } = elementConfig || {};
7733
+ const expandLength = options?.expandLength || 0;
7734
+ // Get markdown content from:
7735
+ // 1. value (static content)
7736
+ // 2. attribute by attributeName (dynamic content from data)
7737
+ let content = value;
7738
+ if (!content && attributeName && attributes) {
7739
+ const attribute = attributes.find(attr => attr.name === attributeName);
7740
+ content = attribute?.value;
7741
+ }
7742
+ if (!content)
7743
+ return null;
7744
+ const markdownString = String(content);
7745
+ const shouldShowExpand = expandLength > 0 && markdownString.length > expandLength;
7746
+ // If expand is not needed, show full content
7747
+ if (!shouldShowExpand) {
7748
+ return (jsx(MarkdownWrapper, { children: jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: markdownString }) }));
7749
+ }
7750
+ // Truncated content for collapsed state
7751
+ const truncatedContent = markdownString.substring(0, expandLength);
7752
+ // Collapsed state
7753
+ if (!expanded) {
7754
+ return (jsxs(MarkdownWrapper, { children: [jsx(ExpandButton, { primary: true, icon: jsx(Expander, { isSelected: false }), onClick: () => setExpanded(true), children: t("more", { ns: "dashboard", defaultValue: "Подробнее" }) }), jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: truncatedContent })] }));
7755
+ }
7756
+ // Expanded state
7757
+ return (jsxs(MarkdownWrapper, { children: [jsx(ExpandButton, { primary: true, icon: jsx(Expander, { isSelected: true }), onClick: () => setExpanded(false), children: t("hide", { ns: "dashboard", defaultValue: "Свернуть" }) }), jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], children: markdownString })] }));
7758
+ });
7759
+
7551
7760
  const SmallPreviewContainer = styled.div `
7552
7761
  width: 100%;
7553
7762
  height: 100%;
@@ -7827,6 +8036,7 @@ const elementComponents = {
7827
8036
  camera: ElementCamera,
7828
8037
  chart: ElementChart,
7829
8038
  legend: ElementLegend,
8039
+ markdown: ElementMarkdown,
7830
8040
  };
7831
8041
 
7832
8042
  const getElementValue = ({ getDefaultContainer, ...props }) => {
@@ -8418,6 +8628,268 @@ const RangeDateFilter = ({ type, filter }) => {
8418
8628
  return (jsx(RangeNumberInput, { label: label || t("interval", { ns: "dashboard", defaultValue: "Интервал" }), selectedOption: { range: true }, minDate: getDate(minDate), maxDate: getDate(maxDate), value: [getDate(value[0]), getDate(value[1])], zIndex: 100, prefix: jsx(Icon, { kind: "date", disabled: true }), suffix: !isEmpty && !isDefault && jsx(StyledIconButton, { kind: "error", onClick: reset }), withTime: withTime, isDate: true, onChange: onChange }));
8419
8629
  };
8420
8630
 
8631
+ const getJustifyContent = (align) => {
8632
+ switch (align) {
8633
+ case "center":
8634
+ return "center";
8635
+ case "right":
8636
+ return "flex-end";
8637
+ case "left":
8638
+ default:
8639
+ return "flex-start";
8640
+ }
8641
+ };
8642
+ const ChipsContainer = styled(Flex) `
8643
+ flex-wrap: wrap;
8644
+ gap: 0.25rem;
8645
+ background: transparent;
8646
+ justify-content: ${({ $align }) => getJustifyContent($align)};
8647
+ `;
8648
+
8649
+ const FilterChip = styled.div `
8650
+ display: inline-flex;
8651
+ align-items: center;
8652
+ gap: 0.25rem;
8653
+ padding: 0.3125rem 0.5rem;
8654
+ height: 1.5rem;
8655
+ border-radius: 0.25rem;
8656
+ background-color: ${({ $isActive, $bgColor, theme }) => $bgColor
8657
+ ? $bgColor
8658
+ : $isActive
8659
+ ? theme.palette?.primary
8660
+ : theme.palette?.elementLight};
8661
+ color: ${({ $isActive, $textColor, theme }) => $textColor
8662
+ ? $textColor
8663
+ : $isActive
8664
+ ? theme.palette?.textContrast
8665
+ : theme.palette?.textSecondary};
8666
+ cursor: pointer;
8667
+ font-size: 0.75rem;
8668
+ line-height: 0.875rem;
8669
+ white-space: nowrap;
8670
+ flex-shrink: 0;
8671
+ transition: all 0.2s ease-in-out;
8672
+ margin: 0 0.25rem 0 0;
8673
+ box-sizing: border-box;
8674
+
8675
+ &:hover {
8676
+ background-color: ${({ $isActive, $bgColor, theme }) => $isActive
8677
+ ? $bgColor || 'inherit'
8678
+ : $bgColor || theme.palette?.elementDark};
8679
+ }
8680
+ `;
8681
+ const ChipIconWrapper = styled.span `
8682
+ display: inline-flex;
8683
+ align-items: center;
8684
+ justify-content: center;
8685
+ width: 0.875rem;
8686
+ height: 0.875rem;
8687
+ flex-shrink: 0;
8688
+
8689
+ svg, img {
8690
+ width: 100%;
8691
+ height: 100%;
8692
+ display: block;
8693
+ }
8694
+ `;
8695
+ const ChipText = styled.span `
8696
+ overflow: hidden;
8697
+ text-overflow: ellipsis;
8698
+ white-space: nowrap;
8699
+ ${({ $maxTextWidth }) => $maxTextWidth && `max-width: ${$maxTextWidth / 16}rem;`}
8700
+ `;
8701
+
8702
+ const CustomChip = ({ text, icon, color, primary, secondary, error, disabled, isActive, maxTextWidth, fontColor: customFontColor, backgroundColor: customBackgroundColor, ...props }) => {
8703
+ const theme = useTheme();
8704
+ const { palette } = theme;
8705
+ // Helper to add transparency to hex color
8706
+ const addTransparency = (hex, transparency = '1f') => {
8707
+ // Ensure hex starts with #
8708
+ const cleanHex = hex.startsWith('#') ? hex : `#${hex}`;
8709
+ return `${cleanHex}${transparency}`;
8710
+ };
8711
+ // Calculate colors based on priority:
8712
+ // 1. customFontColor / customBackgroundColor (highest, from options)
8713
+ // 2. color (from attribute)
8714
+ // 3. primary/secondary/error
8715
+ // 4. default theme colors
8716
+ let bgColor;
8717
+ let textColor;
8718
+ if (isActive) {
8719
+ // Priority 1: Custom colors from options
8720
+ if (customFontColor) {
8721
+ textColor = customFontColor;
8722
+ bgColor = customBackgroundColor || addTransparency(customFontColor); // 12% opacity
8723
+ }
8724
+ // Priority 2: Color from attribute
8725
+ else if (color) {
8726
+ textColor = palette.textPrimary; // White text for active chip
8727
+ bgColor = color; // Full color without transparency
8728
+ }
8729
+ // Priority 3: Variant colors
8730
+ else if (primary) {
8731
+ bgColor = theme.message.color.success; // Green
8732
+ textColor = palette.textContrast;
8733
+ }
8734
+ else if (secondary) {
8735
+ bgColor = palette.primary;
8736
+ textColor = palette.textContrast;
8737
+ }
8738
+ else if (error) {
8739
+ bgColor = theme.message.color.warning; // Yellow
8740
+ textColor = palette.textPrimary;
8741
+ }
8742
+ // Priority 4: Default - no colors specified
8743
+ else {
8744
+ textColor = palette.primary;
8745
+ bgColor = addTransparency(palette.primary); // palette.primary + 12%
8746
+ }
8747
+ }
8748
+ else {
8749
+ // Inactive state
8750
+ if (color) {
8751
+ textColor = color; // Use color for text
8752
+ bgColor = addTransparency(color); // Uses default 1f (12%) transparency
8753
+ }
8754
+ // else: No color attribute - leave bgColor and textColor undefined
8755
+ // Styled component will use fallback for inactive: bg = rgba(0,0,0,0.06), text = palette.textSecondary
8756
+ }
8757
+ const renderIcon = useCallback((iconValue) => {
8758
+ if (!iconValue) {
8759
+ return null;
8760
+ }
8761
+ // If icon doesn't contain a dot and doesn't start with /sp/, it's a built-in icon from uilib-gl
8762
+ if (!iconValue.includes(".") && !iconValue.startsWith("/sp/")) {
8763
+ return jsx(Icon, { kind: iconValue });
8764
+ }
8765
+ // If it's an SVG file or resourceId path, use SvgImage component
8766
+ const isSvg = iconValue.endsWith(".svg") || iconValue.startsWith("/sp/resources/file/");
8767
+ if (isSvg) {
8768
+ const iconColor = textColor
8769
+ ? textColor
8770
+ : isActive
8771
+ ? palette.textContrast
8772
+ : palette.textSecondary;
8773
+ return (jsx(SvgImage, { url: iconValue, width: 14, height: 14, fontColor: iconColor }));
8774
+ }
8775
+ // Otherwise, it's a regular image
8776
+ return jsx("img", { src: iconValue, alt: "" });
8777
+ }, [isActive, textColor, palette.textContrast, palette.textSecondary]);
8778
+ return (jsxs(FilterChip, { "$isActive": isActive, "$bgColor": bgColor, "$textColor": textColor, ...props, children: [icon && jsx(ChipIconWrapper, { children: renderIcon(icon) }), jsx(ChipText, { "$maxTextWidth": maxTextWidth, children: text })] }));
8779
+ };
8780
+
8781
+ const ChipsFilter = ({ type, filter, elementConfig, }) => {
8782
+ const { filters, dataSources, changeFilters } = useWidgetContext(type);
8783
+ const { currentPage } = useWidgetPage(type);
8784
+ const theme = useTheme();
8785
+ const { filters: configFilters } = currentPage;
8786
+ const { options } = elementConfig || {};
8787
+ const { align } = options || {};
8788
+ const { filterName, colorAttribute, iconAttribute, maxTextWidth, icon, fontColor, backgroundColor, } = filter.options;
8789
+ const configFilter = getConfigFilter(filterName, configFilters);
8790
+ const multiSelect = configFilter?.valueType === "array";
8791
+ // Process icon URL (resourceId or direct URL)
8792
+ const processedIcon = icon ? getResourceUrl(icon) : undefined;
8793
+ const chipOptions = useMemo(() => {
8794
+ if (!configFilter)
8795
+ return [];
8796
+ const dataSource = getDataSource(configFilter.relatedDataSource, dataSources);
8797
+ if (!dataSource?.features)
8798
+ return [];
8799
+ const features = dataSource.features;
8800
+ return features.map(feature => {
8801
+ const attrs = feature.attributes;
8802
+ const text = attrs[configFilter.attributeAlias || DEFAULT_ATTRIBUTE_NAME];
8803
+ const value = attrs[configFilter.attributeValue || DEFAULT_ATTRIBUTE_NAME];
8804
+ const chipIcon = iconAttribute
8805
+ ? getIconFromAttribute(attrs, iconAttribute)
8806
+ : undefined;
8807
+ const chipColor = colorAttribute
8808
+ ? getColorFromAttribute(attrs, colorAttribute, theme)
8809
+ : undefined;
8810
+ return {
8811
+ text,
8812
+ value,
8813
+ color: chipColor,
8814
+ icon: chipIcon,
8815
+ };
8816
+ });
8817
+ }, [configFilter, dataSources, colorAttribute, iconAttribute, theme]);
8818
+ const isChipActive = useCallback((chipValue) => {
8819
+ const currentValue = filters?.[filterName]?.value;
8820
+ if (currentValue === undefined) {
8821
+ return checkEqualOrIncludes(configFilter?.defaultValue, chipValue);
8822
+ }
8823
+ return checkEqualOrIncludes(currentValue, chipValue);
8824
+ }, [filters, filterName, configFilter]);
8825
+ const handleChipClick = useCallback((chipValue) => {
8826
+ const currentValue = filters?.[filterName]?.value;
8827
+ let newValue;
8828
+ if (multiSelect) {
8829
+ const currentArray = Array.isArray(currentValue)
8830
+ ? currentValue
8831
+ : currentValue
8832
+ ? [currentValue]
8833
+ : [];
8834
+ const valueIndex = currentArray.indexOf(chipValue);
8835
+ if (valueIndex >= 0) {
8836
+ const filtered = currentArray.filter(v => v !== chipValue);
8837
+ if (filtered.length === 0) {
8838
+ newValue = configFilter?.defaultValue || null;
8839
+ }
8840
+ else {
8841
+ newValue = filtered;
8842
+ }
8843
+ }
8844
+ else {
8845
+ newValue = [...currentArray, chipValue];
8846
+ }
8847
+ }
8848
+ else {
8849
+ if (currentValue === chipValue) {
8850
+ newValue = configFilter?.defaultValue || null;
8851
+ }
8852
+ else {
8853
+ newValue = chipValue;
8854
+ }
8855
+ }
8856
+ changeFilters({
8857
+ [filterName]: { value: newValue },
8858
+ });
8859
+ }, [filters, filterName, multiSelect, changeFilters, configFilter]);
8860
+ if (!configFilter)
8861
+ return null;
8862
+ return (jsx(ChipsContainer, { "$align": align, children: chipOptions.map((chip, index) => {
8863
+ const isActive = isChipActive(chip.value);
8864
+ // Use chip.icon from attribute or fallback to static icon
8865
+ const chipIcon = chip.icon || processedIcon;
8866
+ return (jsx(CustomChip, { text: chip.text, icon: chipIcon, color: chip.color, isActive: isActive, maxTextWidth: maxTextWidth, fontColor: fontColor, backgroundColor: backgroundColor, onClick: () => handleChipClick(chip.value), title: chip.text }, index));
8867
+ }) }));
8868
+ };
8869
+ function getColorFromAttribute(option, colorAttribute, theme) {
8870
+ const value = option[colorAttribute];
8871
+ // If value is already a hex color (starts with #), return it directly
8872
+ if (value && typeof value === 'string' && value.startsWith('#')) {
8873
+ return value;
8874
+ }
8875
+ // Otherwise, map string values to theme colors
8876
+ const colorMap = {
8877
+ active: theme?.message?.color?.success,
8878
+ warning: theme?.message?.color?.warning,
8879
+ info: theme?.message?.color?.info,
8880
+ inactive: theme?.palette?.textDisabled,
8881
+ };
8882
+ return value && typeof value === 'string' ? colorMap[value.toLowerCase()] : undefined;
8883
+ }
8884
+ function getIconFromAttribute(option, iconAttribute) {
8885
+ const iconValue = option[iconAttribute];
8886
+ if (!iconValue || typeof iconValue !== 'string') {
8887
+ return undefined;
8888
+ }
8889
+ // Process through getResourceUrl to handle both URLs and resourceIds
8890
+ return getResourceUrl(iconValue);
8891
+ }
8892
+
8421
8893
  const getFilterComponent = (filterType) => {
8422
8894
  switch (filterType) {
8423
8895
  case "checkbox":
@@ -8430,6 +8902,8 @@ const getFilterComponent = (filterType) => {
8430
8902
  return RangeDateFilter;
8431
8903
  case "text":
8432
8904
  return TextFilter;
8905
+ case "chips":
8906
+ return ChipsFilter;
8433
8907
  case "dropdown":
8434
8908
  default:
8435
8909
  return DropdownFilter;
@@ -8615,7 +9089,9 @@ const getRenderElement = ({ t, config, elementConfig, attributes = [], layerInfo
8615
9089
  return formatElementValue({ t, value, elementConfig: element, attributes, wrap });
8616
9090
  };
8617
9091
 
8618
- const getResourceUrl = (url) => url ? (url.startsWith("http") ? url : `/sp/resources/file/${url}`) : "";
9092
+ const getResourceUrl = (url) => {
9093
+ return url ? (url.startsWith("http") ? url : `/sp/resources/file/${url}`) : "";
9094
+ };
8619
9095
 
8620
9096
  const getSlideshowImages = ({ element, attribute, }) => {
8621
9097
  const { defaultValue, options } = element;
@@ -10105,5 +10581,5 @@ const Map$1 = ({ zIndex, lowerSiblings, upperSiblings, onError, children, ...res
10105
10581
  }, children: children }), upperSiblings] }));
10106
10582
  };
10107
10583
 
10108
- export { AddFeatureButton, AddFeatureContainer, AttributeGalleryContainer, AttributeLabel, BaseMapTheme, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, ContainerChildren, ContainerLoading, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_PAINT, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_FILL_EXTRUSION_PAINT, DEFAULT_FILL_PAINT, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_PAINT, DEFAULT_LNG, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_ZOOM, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementSlideshow, ElementSvg, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardGradientHeader, FeatureCardHeader, FeatureCardIconHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GlobalContext, GlobalProvider, Header, HeaderContainer, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, InnerContainerWrapper$1 as InnerContainerWrapper, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroup, LayerGroupList, LayerIcon, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogoContainer, MAX_CHART_WIDTH, Map$1 as Map, MapContext, MapProvider, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OneColumnContainer, PageNavigator, PageTitle, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, RoundedBackgroundContainer, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, SvgImage, TIME_ZONE_FORMAT, TabsContainer, TextTrim, ThemeName, TitleContainer, TmsType, TopContainer, TopContainerButtons, TwoColumnContainer, TwoColumnsInnerContainer, WidgetType, addDataSource, addDataSources, applyFiltersToCondition, applyQueryFilters, applyVarsToCondition, checkEqualOrIncludes, checkIsLoading, convertSpToTurfFeature, createConfigLayer, createConfigPage, createNewPageId, createTreeNode, dateOptions, debounce, decimalOpacityToHex, eqlParametersToPayload, findAttributeInExpression, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, getActualExtrusionHeight, getAttributeByName, getAttributeValue, getAttributesConfiguration, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDate, getDefaultConfig, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getLayerDefinition, getLayerInfo, getLayerInfoFromDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getSvgUrl, getTotalFromAttributes, getTotalFromRelatedFeatures, hexToRgba, isCompositeLayerConfiguration, isEmptyElementValue, isEmptyValue, isHiddenEmptyValue, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isVisibleContainer, numberOptions, parseClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, rgbToHex, roundTotalSum, sliceShownOtherItems, timeOptions, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, treeNodesToProjectItems, useAppHeight, useChartChange, useChartData, useDashboardHeader, useDataSources, useDebouncedCallback, useDiffPage, useExpandableContainers, useExportPdf, useGetConfigLayer, useGlobalContext, useHeaderRender, useLayerParams, useMapContext, useMapDraw, useProjectDashboardInit, useRedrawLayer, useRelatedDataSourceAttributes, useRenderElement, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useZoomToFeatures, useZoomToPoint };
10584
+ export { AddFeatureButton, AddFeatureContainer, AttributeGalleryContainer, AttributeLabel, BaseMapTheme, CONFIG_PAGES_ID, CONFIG_PAGE_ID, CameraContainer, Chart, ChartContainer, ChartLegend, ChartLoading, ContainerChildren, ContainerLoading, ContainerTemplate, ContainerWrapper, ContainersGroupContainer, DEFAULT_ATTRIBUTE_NAME, DEFAULT_BARCHART_RADIUS, DEFAULT_BASE_MAP, DEFAULT_CHART_ANGLE, DEFAULT_CHART_HEIGHT, DEFAULT_CHART_WIDTH, DEFAULT_CIRCLE_PAINT, DEFAULT_DASHBOARD_CONFIG, DEFAULT_DATA_SOURCE_LIMIT, DEFAULT_FILL_EXTRUSION_PAINT, DEFAULT_FILL_PAINT, DEFAULT_ID_ATTRIBUTE_NAME, DEFAULT_LAT, DEFAULT_LINE_PAINT, DEFAULT_LNG, DEFAULT_PAGES_CONFIG, DEFAULT_PIECHART_RADIUS, DEFAULT_ZOOM, Dashboard, DashboardCheckbox, DashboardChip, DashboardContent, DashboardContext, DashboardDefaultHeader, DashboardHeader, DashboardLoading, DashboardPlaceholder, DashboardPlaceholderWrap, DashboardProvider, DashboardWrapper, DataSourceContainer, DataSourceError, DataSourceErrorContainer, DataSourceInnerContainer, DataSourceProgressContainer, DateFormat, DefaultAttributesContainer, DefaultHeaderContainer, DefaultHeaderWrapper, DividerContainer, EditGeometryType, ElementButton, ElementCamera, ElementChart, ElementChips, ElementIcon, ElementImage, ElementLegend, ElementLink, ElementMarkdown, ElementSlideshow, ElementSvg, ElementTooltip, ElementValueWrapper, ExpandableTitle, FEATURE_CARD_DEFAULT_COLORS, FEATURE_CARD_OTHER_COLOR, FILTERED_VALUE_OPACITY, FILTER_PREFIX, FeatureCardButtons, FeatureCardContext, FeatureCardDefaultHeader, FeatureCardGradientHeader, FeatureCardHeader, FeatureCardIconHeader, FeatureCardProvider, FeatureCardSlideshowHeader, FeatureCardTitle, FeatureControls, FeatureTitleContainer, FiltersContainer, GEOMETRY_ATTRIBUTE, GlobalContext, GlobalProvider, Header, HeaderContainer, HeaderFrontView, HeaderTemplate, HeaderTitleContainer, HiddenTitleItems, IconContainer, ImageContainer, InnerContainerWrapper$1 as InnerContainerWrapper, LEFT_PANEL_HEADER_HEIGHT, Layer, LayerDescription, LayerGroup, LayerGroupList, LayerIcon, LayerListContainer, LayerTree, LayersContainer, LayersListWrapper, LinearProgressContainer, LogoContainer, MAX_CHART_WIDTH, Map$1 as Map, MapContext, MapProvider, NO_CONTENT_VALUE, NUMERIC_ATTRIBUTE_TYPES, NoLiveSnapshotContainer, OneColumnContainer, PageNavigator, PageTitle, PagesContainer, Pagination, PresentationHeader, PresentationHeaderButtons, PresentationHeaderTools, PresentationPanelContainer, PresentationPanelWrapper, PresentationWrapper, ProgressContainer, RoundedBackgroundContainer, ScalingFactor, ServerNotificationsContext, ServerNotificationsProvider, SlideshowContainer, SmallPreviewContainer$1 as SmallPreviewContainer, SmallPreviewControl, SmallPreviewCounter, SmallPreviewImages, SmallPreviewLeft, SmallPreviewRight, StackBar, SvgImage, TIME_ZONE_FORMAT, TabsContainer, TextTrim, ThemeName, TitleContainer, TmsType, TopContainer, TopContainerButtons, TwoColumnContainer, TwoColumnsInnerContainer, WidgetType, addDataSource, addDataSources, applyFiltersToCondition, applyQueryFilters, applyVarsToCondition, checkEqualOrIncludes, checkIsLoading, convertSpToTurfFeature, createConfigLayer, createConfigPage, createNewPageId, createTreeNode, dateOptions, debounce, decimalOpacityToHex, eqlParametersToPayload, findAttributeInExpression, formatArea, formatAttributeValue, formatChartRelatedValue, formatConditionValue, formatDataSourceCondition, formatDate$1 as formatDate, formatElementValue, formatLength, formatNumber, formatPolygonMeasure, getActualExtrusionHeight, getAttributeByName, getAttributeValue, getAttributesConfiguration, getChartAxes, getChartFilterName, getChartMarkers, getConfigFilter, getContainerComponent, getDashboardHeader, getDataFromAttributes, getDataFromRelatedFeatures, getDataSource, getDataSourceFilterValue, getDate, getDefaultConfig, getElementValue, getFeatureAttributes, getFeatureCardHeader, getFilterComponent, getFilterSelectedItems, getFilterValue, getFormattedAttributes, getGradientColors, getLayerDefinition, getLayerInfo, getLayerInfoFromDataSources, getPagesFromConfig, getPagesFromProjectInfo, getProxyService, getRelatedAttribute, getRenderElement, getResourceUrl, getRootElementId, getSelectedFilterValue, getSlideshowImages, getSvgUrl, getTotalFromAttributes, getTotalFromRelatedFeatures, hexToRgba, isCompositeLayerConfiguration, isEmptyElementValue, isEmptyValue, isHiddenEmptyValue, isLayerService, isNotValidSelectedTab, isNumeric, isObject, isProxyService, isVisibleContainer, numberOptions, parseClientStyle, pieChartTooltipFromAttributes, pieChartTooltipFromRelatedFeatures, pointOptions, removeDataSource, rgbToHex, roundTotalSum, sliceShownOtherItems, timeOptions, tooltipNameFromAttributes, tooltipValueFromAttributes, tooltipValueFromRelatedFeatures, transparentizeColor, treeNodesToProjectItems, useAppHeight, useChartChange, useChartData, useDashboardHeader, useDataSources, useDebouncedCallback, useDiffPage, useExpandableContainers, useExportPdf, useGetConfigLayer, useGlobalContext, useHeaderRender, useLayerParams, useMapContext, useMapDraw, useProjectDashboardInit, useRedrawLayer, useRelatedDataSourceAttributes, useRenderElement, useServerNotificationsContext, useShownOtherItems, useToggle, useUpdateDataSource, useWidgetConfig, useWidgetContext, useWidgetFilters, useWidgetPage, useWindowResize, useZoomToFeatures, useZoomToPoint };
10109
10585
  //# sourceMappingURL=react.esm.js.map