@evergis/react 4.0.54 → 4.0.56

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
@@ -3406,7 +3406,6 @@ exports.HeaderTemplate = void 0;
3406
3406
  HeaderTemplate["Default"] = "Default";
3407
3407
  HeaderTemplate["Slideshow"] = "Slideshow";
3408
3408
  HeaderTemplate["Gradient"] = "Gradient";
3409
- HeaderTemplate["Icon"] = "Icon";
3410
3409
  })(exports.HeaderTemplate || (exports.HeaderTemplate = {}));
3411
3410
  exports.WidgetType = void 0;
3412
3411
  (function (WidgetType) {
@@ -6034,8 +6033,7 @@ const SvgContainer$1 = styled.div `
6034
6033
  }
6035
6034
  }
6036
6035
  `;
6037
- const TwoColumnContainerWrapper = styled(uilibGl.Flex) `
6038
- width: 100%;
6036
+ const TwoColumnContainerWrapper = styled(Container) `
6039
6037
  flex-direction: row;
6040
6038
  flex-wrap: nowrap;
6041
6039
  align-items: center;
@@ -6109,7 +6107,6 @@ const useRenderContainer = ({ elementConfig, type, renderElement, renderBody, })
6109
6107
  if (OverrideContainer) {
6110
6108
  const itemConfig = {
6111
6109
  ...elementConfig,
6112
- style: { ...BASE_CONTAINER_STYLE, ...elementConfig.style },
6113
6110
  children: (elementConfig?.children ?? []).map(child => ({
6114
6111
  ...child,
6115
6112
  attributeName: attribute,
@@ -6138,7 +6135,7 @@ const OneColumnContainer = React.memo(({ type, elementConfig, renderElement }) =
6138
6135
  });
6139
6136
 
6140
6137
  const TwoColumnContainer = React.memo(({ elementConfig, type, renderElement }) => {
6141
- const renderBody = React.useCallback(({ id, value, style, hasIcon, hasUnits, render }, attribute) => (jsxRuntime.jsxs(TwoColumnContainerWrapper, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsxs(ContainerAlias, { children: [hasIcon && (jsxRuntime.jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] }, attribute)), []);
6138
+ const renderBody = React.useCallback(({ id, value, style, hasIcon, hasUnits, render }) => (jsxRuntime.jsxs(TwoColumnContainerWrapper, { id: id, style: style, children: [jsxRuntime.jsxs(ContainerAlias, { children: [hasIcon && (jsxRuntime.jsx(ContainerAliasIcon, { children: render({ id: "icon" }) })), render({ id: "alias" }), render({ id: "tooltip" }), render({ id: "modal" })] }), jsxRuntime.jsxs(ContainerValue, { big: true, children: [value, hasUnits && (jsxRuntime.jsx(ContainerUnits, { children: render({ id: "units" }) }))] })] })), []);
6142
6139
  const { renderContainer, attributesToRender } = useRenderContainer({
6143
6140
  type,
6144
6141
  elementConfig,
@@ -8042,10 +8039,31 @@ const useGlobalContext = () => {
8042
8039
  }), [language, translate, api, ewktGeometry, themeName]);
8043
8040
  };
8044
8041
 
8042
+ const ImagePreviewError = styled.div `
8043
+ display: flex;
8044
+ align-items: center;
8045
+ justify-content: center;
8046
+ width: 100%;
8047
+ height: 100%;
8048
+ background-color: ${({ theme }) => theme.palette.elementDark};
8049
+ border-radius: ${({ theme: { borderRadius: themeBorder }, borderRadius }) => borderRadius || themeBorder.smallest};
8050
+
8051
+ ${uilibGl.Icon} {
8052
+ width: 37.5%;
8053
+ height: 37.5%;
8054
+ }
8055
+
8056
+ ${uilibGl.Icon}:after {
8057
+ font-size: 1.5rem;
8058
+ color: ${({ theme }) => theme.palette.textSecondary};
8059
+ }
8060
+ `;
8045
8061
  const FileImagePreview = ({ link, isExternal, size, borderRadius, }) => {
8046
8062
  const { api } = useGlobalContext();
8047
8063
  const [imageSrc, setImageSrc] = React.useState();
8064
+ const [hasError, setHasError] = React.useState(false);
8048
8065
  React.useEffect(() => {
8066
+ setHasError(false);
8049
8067
  if (isExternal) {
8050
8068
  setImageSrc(link);
8051
8069
  return;
@@ -8063,14 +8081,18 @@ const FileImagePreview = ({ link, isExternal, size, borderRadius, }) => {
8063
8081
  objectUrl = URL.createObjectURL(blob);
8064
8082
  setImageSrc(objectUrl);
8065
8083
  })
8066
- .catch(() => { });
8084
+ .catch(() => {
8085
+ if (cancelled)
8086
+ return;
8087
+ setHasError(true);
8088
+ });
8067
8089
  return () => {
8068
8090
  cancelled = true;
8069
8091
  if (objectUrl)
8070
8092
  URL.revokeObjectURL(objectUrl);
8071
8093
  };
8072
8094
  }, [api, link, isExternal]);
8073
- return (jsxRuntime.jsxs(ImagePreviewContainer, { size: size, children: [!imageSrc && (jsxRuntime.jsx(ImagePreviewLoaderContainer, { children: jsxRuntime.jsx(uilibGl.LinearProgress, {}) })), imageSrc && (jsxRuntime.jsx(GridImagePreview, { borderRadius: borderRadius, size: size, src: imageSrc, alt: "" }))] }));
8095
+ return (jsxRuntime.jsxs(ImagePreviewContainer, { size: size, children: [hasError && (jsxRuntime.jsx(ImagePreviewError, { borderRadius: borderRadius, children: jsxRuntime.jsx(uilibGl.Icon, { kind: "alert" }) })), !hasError && !imageSrc && (jsxRuntime.jsx(ImagePreviewLoaderContainer, { children: jsxRuntime.jsx(uilibGl.LinearProgress, {}) })), !hasError && imageSrc && (jsxRuntime.jsx(GridImagePreview, { borderRadius: borderRadius, size: size, src: imageSrc, alt: "", onError: () => setHasError(true) }))] }));
8074
8096
  };
8075
8097
 
8076
8098
  const getFileType = (mimeType = "", name = "") => {
@@ -8223,6 +8245,60 @@ const useAttachmentContainer = ({ type, elementConfig, valueOverride, }) => {
8223
8245
  };
8224
8246
  };
8225
8247
 
8248
+ const usePreviewImages = ({ items, active }) => {
8249
+ const { api } = useGlobalContext();
8250
+ const [blobUrls, setBlobUrls] = React.useState({});
8251
+ const [failedLinks, setFailedLinks] = React.useState({});
8252
+ const inFlightRef = React.useRef(new Set());
8253
+ const blobUrlsRef = React.useRef(blobUrls);
8254
+ blobUrlsRef.current = blobUrls;
8255
+ React.useEffect(() => {
8256
+ if (!active || !api?.catalog?.getFile)
8257
+ return;
8258
+ items.forEach(item => {
8259
+ const fileType = getFileType(item.mimeType, item.name);
8260
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
8261
+ if (!isImage || item.isExternal)
8262
+ return;
8263
+ if (blobUrlsRef.current[item.link] || inFlightRef.current.has(item.link))
8264
+ return;
8265
+ inFlightRef.current.add(item.link);
8266
+ api.catalog
8267
+ .getFile(item.link)
8268
+ .then(blob => {
8269
+ const objectUrl = URL.createObjectURL(blob);
8270
+ setBlobUrls(prev => ({ ...prev, [item.link]: objectUrl }));
8271
+ })
8272
+ .catch(() => {
8273
+ setFailedLinks(prev => (prev[item.link] ? prev : { ...prev, [item.link]: true }));
8274
+ })
8275
+ .finally(() => {
8276
+ inFlightRef.current.delete(item.link);
8277
+ });
8278
+ });
8279
+ }, [active, api, items]);
8280
+ React.useEffect(() => () => {
8281
+ Object.values(blobUrlsRef.current).forEach(URL.revokeObjectURL);
8282
+ }, []);
8283
+ return React.useMemo(() => items.map(item => {
8284
+ const fileType = getFileType(item.mimeType, item.name);
8285
+ const isImage = IMAGE_FILE_TYPES.includes(fileType);
8286
+ const fileName = item.name;
8287
+ if (!isImage)
8288
+ return { src: getFileTypeIcon(fileType), fileName };
8289
+ if (item.isExternal)
8290
+ return { src: item.link, fileName };
8291
+ const hasError = !!failedLinks[item.link];
8292
+ const blobUrl = blobUrls[item.link];
8293
+ return {
8294
+ src: blobUrl ?? "",
8295
+ fileName,
8296
+ hasError,
8297
+ isLoading: !hasError && !blobUrl,
8298
+ };
8299
+ }), [items, blobUrls, failedLinks]);
8300
+ };
8301
+
8226
8302
  const EXTENSION_TO_MIME = {
8227
8303
  apng: "image/apng",
8228
8304
  avif: "image/avif",
@@ -8269,20 +8345,6 @@ const getFileNameFromUrl = (url) => {
8269
8345
  }
8270
8346
  };
8271
8347
 
8272
- const getResourceUrl = (url) => {
8273
- return url ? (url.startsWith("http") ? url : `/sp/resources/file/${url}`) : "";
8274
- };
8275
-
8276
- const buildPreviewImage$1 = (item) => {
8277
- const fileType = getFileType(item.mimeType, item.name);
8278
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
8279
- const src = isImage
8280
- ? item.isExternal
8281
- ? item.link
8282
- : getResourceUrl(item.link)
8283
- : getFileTypeIcon(fileType);
8284
- return { src, fileName: item.name };
8285
- };
8286
8348
  const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement }) => {
8287
8349
  const { api } = useGlobalContext();
8288
8350
  const { selectAttachmentsFromCatalog } = useWidgetContext(type);
@@ -8293,7 +8355,7 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
8293
8355
  const [previewIndex, setPreviewIndex] = React.useState(null);
8294
8356
  const [uploading, setUploading] = React.useState(false);
8295
8357
  const [isLinkDialogOpen, , setLinkDialogOpen] = useToggle(false);
8296
- const previewImages = React.useMemo(() => items.map(buildPreviewImage$1), [items]);
8358
+ const previewImages = usePreviewImages({ items, active: previewIndex !== null });
8297
8359
  const orderedPreviewImages = React.useMemo(() => {
8298
8360
  if (previewIndex === null)
8299
8361
  return previewImages;
@@ -8302,7 +8364,7 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
8302
8364
  ...previewImages.filter((_, idx) => idx !== previewIndex),
8303
8365
  ];
8304
8366
  }, [previewImages, previewIndex]);
8305
- const persist = React.useCallback((next) => onChange(JSON.stringify(next)), [onChange]);
8367
+ const persist = React.useCallback((next) => onChange(next), [onChange]);
8306
8368
  const handlePreview = React.useCallback((link) => {
8307
8369
  const idx = items.findIndex(item => item.link === link);
8308
8370
  if (idx >= 0)
@@ -8362,23 +8424,14 @@ const EditAttachmentContainer = React.memo(({ type, elementConfig, renderElement
8362
8424
  return (jsxRuntime.jsxs(AttachmentsContainer, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: true, onPreview: handlePreview, onDelete: handleDelete })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), jsxRuntime.jsx(AddButton, { accept: fileExtensions, onSelectFiles: uploading ? () => undefined : handleUpload, onSelectFromCatalog: handleSelectFromCatalog, onSelectFromLink: handleOpenLinkDialog }), jsxRuntime.jsx(AttachmentLinkDialog, { isOpen: isLinkDialogOpen, onClose: handleCloseLinkDialog, onSubmit: handleAddByLink }), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: orderedPreviewImages, isOpen: previewIndex !== null, onClose: handleClosePreview }))] }));
8363
8425
  });
8364
8426
 
8365
- const buildPreviewImage = (item) => {
8366
- const fileType = getFileType(item.mimeType, item.name);
8367
- const isImage = IMAGE_FILE_TYPES.includes(fileType);
8368
- const src = isImage
8369
- ? item.isExternal
8370
- ? item.link
8371
- : getResourceUrl(item.link)
8372
- : getFileTypeIcon(fileType);
8373
- return { src, fileName: item.name };
8374
- };
8375
8427
  const AttachmentContainer = React.memo(({ type, elementConfig, renderElement }) => {
8428
+ const { t } = useGlobalContext();
8376
8429
  const { expandedContainers } = useWidgetContext(type);
8377
8430
  const { items, visibleItems, viewMode, setViewMode, showMore, setShowMore, hasMore, hiddenCount } = useAttachmentContainer({ type, elementConfig });
8378
8431
  const { id, style, options } = elementConfig || {};
8379
8432
  const { expandable, expanded } = options || {};
8380
8433
  const [previewIndex, setPreviewIndex] = React.useState(null);
8381
- const previewImages = React.useMemo(() => items.map(buildPreviewImage), [items]);
8434
+ const previewImages = usePreviewImages({ items, active: previewIndex !== null });
8382
8435
  const orderedPreviewImages = React.useMemo(() => {
8383
8436
  if (previewIndex === null)
8384
8437
  return previewImages;
@@ -8395,7 +8448,10 @@ const AttachmentContainer = React.memo(({ type, elementConfig, renderElement })
8395
8448
  const handleClosePreview = React.useCallback(() => setPreviewIndex(null), []);
8396
8449
  const handleShowMore = React.useCallback(() => setShowMore(true), [setShowMore]);
8397
8450
  const isVisible = isVisibleContainer(id, expandable, expanded, expandedContainers);
8398
- return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsxs(Container, { id: id, isColumn: true, style: style, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: orderedPreviewImages, isOpen: previewIndex !== null, onClose: handleClosePreview }))] }))] }));
8451
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ExpandableTitle, { elementConfig: elementConfig, type: type, renderElement: renderElement }), isVisible && (jsxRuntime.jsx(Container, { id: id, style: { ...BASE_CONTAINER_STYLE, ...style }, children: jsxRuntime.jsxs(uilibGl.Flex, { column: true, children: [jsxRuntime.jsx(AttachmentsHeader, { alias: renderElement?.({ id: "alias" }), count: items.length, viewMode: viewMode, onChangeViewMode: setViewMode }), jsxRuntime.jsx(AttachmentsContent, { children: viewMode === "grid" ? (jsxRuntime.jsx(AttachmentsGrid, { items: visibleItems, isEdit: false, onPreview: handlePreview })) : (jsxRuntime.jsx(AttachmentsList, { items: visibleItems, isEdit: false, onPreview: handlePreview })) }), hasMore && !showMore && (jsxRuntime.jsx(ShowMoreButton, { hiddenCount: hiddenCount, onClick: handleShowMore })), previewIndex !== null && (jsxRuntime.jsx(uilibGl.Preview, { images: orderedPreviewImages, isOpen: previewIndex !== null, onClose: handleClosePreview, errorTitleText: t("attachments.resourceUnavailable", {
8452
+ ns: "common",
8453
+ defaultValue: "Ресурс недоступен",
8454
+ }) }))] }) }))] }));
8399
8455
  });
8400
8456
 
8401
8457
  const ContainerDivider = styled(uilibGl.Divider) `
@@ -8616,17 +8672,17 @@ const HeaderFrontView = styled(uilibGl.Flex) `
8616
8672
  width: 100%;
8617
8673
  font: ${({ theme: { fonts } }) => fonts.subtitle};
8618
8674
  `;
8619
- const HeaderContainer = styled(uilibGl.FlexSpan) `
8675
+ const HeaderContainer = styled(uilibGl.Flex) `
8620
8676
  display: flex;
8621
8677
  flex-grow: 1;
8622
8678
  flex-wrap: nowrap;
8623
- width: calc(100% - 48px);
8679
+ width: calc(100% - 3rem);
8624
8680
  `;
8625
8681
  const FeatureTitleContainer = styled.div `
8626
8682
  display: -webkit-box;
8627
8683
  max-width: 100%;
8628
8684
  width: 100%;
8629
- margin: 0.5rem 0;
8685
+ margin-top: 0.5rem;
8630
8686
  -webkit-line-clamp: 2;
8631
8687
  -webkit-box-orient: vertical;
8632
8688
  overflow: hidden;
@@ -8682,6 +8738,10 @@ const Header = styled(uilibGl.Flex) `
8682
8738
  ${({ $isRow }) => $isRow && RowHeaderMixin};
8683
8739
  `;
8684
8740
  const DefaultHeaderWrapper = styled.div `
8741
+ padding: 1rem 0 0 1rem;
8742
+ margin: -1rem 0 0 -1rem;
8743
+ background: url(${img$4}) 50% -2rem no-repeat;
8744
+
8685
8745
  ${Header} {
8686
8746
  padding: 0 1.5rem 1.5rem 0;
8687
8747
  }
@@ -8708,7 +8768,7 @@ const HeaderTitle = ({ noFeature }) => {
8708
8768
  stringFormat: layerDefinitionAttribute.stringFormat,
8709
8769
  })) ||
8710
8770
  feature?.id);
8711
- }, [attributes, feature, configuration]);
8771
+ }, [configuration, attributes, t, feature?.id]);
8712
8772
  return (jsxRuntime.jsxs(HeaderTitleContainer, { children: [noFeature ? (jsxRuntime.jsx(FeatureTitleContainer, { children: t("noObjectFound", { ns: "dashboard", defaultValue: "Объектов не найдено" }) })) : (jsxRuntime.jsx(FeatureTitleContainer, { clickable: true, children: jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(uilibGl.FlexSpan, { ref: ref, onClick: () => zoomToFeatures([feature]), children: resultTitle })) }) })), jsxRuntime.jsx(LayerDescription, { title: resultDescription, children: resultDescription })] }));
8713
8773
  };
8714
8774
 
@@ -8767,81 +8827,14 @@ const LayerIcon = ({ layerInfo, error }) => {
8767
8827
  };
8768
8828
 
8769
8829
  const FeatureCardDefaultHeader = ({ noFeature }) => {
8770
- const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
8771
- return (jsxRuntime.jsx(DefaultHeaderWrapper, { children: jsxRuntime.jsx(Header, { "$isRow": true, children: jsxRuntime.jsxs(HeaderFrontView, { isDefault: true, children: [jsxRuntime.jsxs(HeaderContainer, { children: [!!layerInfo?.name && jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(HeaderTitle, { noFeature: noFeature })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }));
8772
- };
8773
-
8774
- const HeaderFontColorMixin$1 = styled.css `
8775
- ${HeaderTitleContainer}, ${LayerDescription} {
8776
- color: ${({ $fontColor }) => $fontColor};
8777
- }
8778
- `;
8779
- const HeaderWrapperMixin$1 = styled.css `
8780
- ${Header} {
8781
- min-height: 5.25rem;
8782
- }
8783
-
8784
- ${HeaderContainer} {
8785
- max-width: 100%;
8786
- width: 100%;
8787
- }
8788
-
8789
- ${FeatureControls} {
8790
- max-width: calc(100% - 2rem);
8791
- width: calc(100% - 2rem);
8792
- margin-top: -0.5rem;
8793
- padding-top: 1rem;
8794
- border-radius: ${({ theme: { borderRadius } }) => borderRadius.medium};
8795
- }
8796
-
8797
- ${({ $fontColor }) => !!$fontColor && HeaderFontColorMixin$1};
8798
- `;
8799
- const GradientHeaderWrapper = styled.div `
8800
- ${Header} {
8801
- background: ${({ $bgColor }) => $bgColor || "radial-gradient(129.21% 133.22% at 51.94% 0%, #e8fffe 9.48%, #5fcaff 100%)"};
8802
- }
8803
-
8804
- ${HeaderContainer} {
8805
- align-items: center;
8806
- }
8807
-
8808
- ${HeaderTitleContainer} {
8809
- margin-left: 0;
8810
- text-align: center;
8811
- }
8812
-
8813
- ${FeatureTitleContainer} {
8814
- text-align: center;
8815
- }
8816
-
8817
- ${LayerDescription} {
8818
- text-align: center;
8819
- }
8820
-
8821
- ${HeaderWrapperMixin$1};
8822
- `;
8823
-
8824
- const FeatureCardGradientHeader = ({ isRow }) => {
8825
8830
  const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
8826
8831
  const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
8827
8832
  const { header } = config || {};
8828
8833
  const { options } = header || {};
8829
- const { fontColor, bgColor } = options || {};
8830
- const renderElement = useHeaderRender(header);
8831
- return (jsxRuntime.jsx(GradientHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.defaultTheme, children: jsxRuntime.jsx(Header, { "$isRow": isRow, children: jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
8832
- id: "title",
8833
- wrap: false,
8834
- }), description: renderElement({
8835
- id: "description",
8836
- wrap: false,
8837
- }) })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }) }));
8834
+ const { themeName } = options || {};
8835
+ return (jsxRuntime.jsx(DefaultHeaderWrapper, { children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName), children: jsxRuntime.jsx(Header, { "$isRow": true, children: jsxRuntime.jsxs(HeaderFrontView, { isDefault: true, children: [jsxRuntime.jsxs(HeaderContainer, { children: [!!layerInfo?.name && jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(HeaderTitle, { noFeature: noFeature })] }), jsxRuntime.jsx(FeatureCardButtons, {})] }) }) }) }));
8838
8836
  };
8839
8837
 
8840
- const LayerIconClickable = styled.div `
8841
- display: flex;
8842
- align-items: center;
8843
- cursor: pointer;
8844
- `;
8845
8838
  const HeaderFontColorMixin = styled.css `
8846
8839
  ${HeaderTitleContainer}, ${HeaderTitleContainer} *, ${LayerDescription} {
8847
8840
  color: ${({ $fontColor }) => $fontColor};
@@ -8871,13 +8864,18 @@ const HeaderIcon = styled(uilibGl.Flex) `
8871
8864
  position: absolute;
8872
8865
  top: 0;
8873
8866
  right: 0;
8874
- justify-content: flex-end;
8875
8867
  align-items: center;
8876
- min-width: 7.5rem;
8868
+ justify-content: center;
8869
+ width: 7.625rem;
8877
8870
  height: 100%;
8878
8871
 
8879
- span[kind]:after {
8880
- font-size: 7.5rem;
8872
+ span[kind] {
8873
+ width: 4rem;
8874
+
8875
+ :after {
8876
+ font-size: 4rem;
8877
+ color: rgba(255, 255, 255, 0.36);
8878
+ }
8881
8879
  }
8882
8880
 
8883
8881
  span[kind]:after,
@@ -8903,34 +8901,77 @@ const BigIconHeaderMixin = styled.css `
8903
8901
  }
8904
8902
  }
8905
8903
  `;
8906
- const IconHeaderWrapper = styled.div `
8904
+ const WithPaddingHeaderMixin = styled.css `
8907
8905
  ${Header} {
8908
- width: calc(100% + 0.5rem);
8909
- margin: -1rem -1rem 0.5rem -1rem;
8910
- padding: 1.5rem;
8911
- border-top-left-radius: 0.5rem;
8912
- border-top-right-radius: 0.5rem;
8906
+ width: calc(100% - 1rem);
8907
+ margin: -0.5rem -0.5rem 0.5rem -0.5rem;
8908
+ }
8909
+ `;
8910
+ const BottomBlurHeaderMixin = styled.css `
8911
+ ${Header} {
8912
+ margin-bottom: 0;
8913
+
8914
+ &::after {
8915
+ content: "";
8916
+ position: absolute;
8917
+ left: 0;
8918
+ right: 0;
8919
+ bottom: 0;
8920
+ height: 1.5rem;
8921
+ z-index: 11;
8922
+ pointer-events: none;
8923
+ background: ${({ theme: { palette } }) => palette.background};
8924
+ mask-image: linear-gradient(to top, #000 0%, transparent 100%);
8925
+ -webkit-mask-image: linear-gradient(to top, #000 0%, transparent 100%);
8926
+ border-radius: 0 0 0.5rem 0.5rem;
8927
+ }
8928
+ }
8929
+
8930
+ ${HeaderFrontView} {
8931
+ z-index: 12;
8932
+ }
8933
+ `;
8934
+ const GradientHeaderWrapper = styled.div `
8935
+ ${Header} {
8936
+ margin: -1rem -1rem 1rem -1rem;
8937
+ padding: 1rem 1.5rem;
8938
+ border-radius: 0.5rem;
8913
8939
  background: ${({ $bgColor }) => $bgColor || "linear-gradient(96.55deg, #FFFCD3 0%, #B4DC47 100%)"};
8940
+ overflow: hidden;
8914
8941
  }
8915
8942
 
8916
8943
  ${HeaderWrapperMixin};
8917
8944
 
8918
8945
  ${({ $bigIcon }) => $bigIcon && BigIconHeaderMixin};
8946
+
8947
+ ${({ $withPadding }) => $withPadding && WithPaddingHeaderMixin};
8948
+
8949
+ ${({ $bottomBlur }) => $bottomBlur && BottomBlurHeaderMixin};
8950
+ `;
8951
+
8952
+ const LayerIconClickable = styled.div `
8953
+ display: flex;
8954
+ align-items: center;
8955
+ cursor: pointer;
8919
8956
  `;
8920
8957
 
8921
- const FeatureCardIconHeader = ({ isRow }) => {
8958
+ const HeaderLayerIcon = () => {
8922
8959
  const { t } = useGlobalContext();
8923
8960
  const { layerInfo, feature } = useWidgetContext(exports.WidgetType.FeatureCard);
8924
- const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
8925
8961
  const zoomToFeatures = useZoomToFeatures();
8926
8962
  const getMaxZoomTo = useMaxZoomTo();
8927
8963
  const [optionsMaxZoomTo, layerMaxZoomTo] = React.useMemo(() => getMaxZoomTo(layerInfo?.name), [layerInfo?.name, getMaxZoomTo]);
8964
+ const handleIconClick = React.useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
8965
+ return (jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(LayerIconClickable, { ref: ref, onClick: handleIconClick, children: jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }) })) }));
8966
+ };
8967
+
8968
+ const FeatureCardGradientHeader = ({ isRow }) => {
8969
+ const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
8928
8970
  const { header } = config || {};
8929
8971
  const { options } = header || {};
8930
- const { fontColor, bgColor, bigIcon } = options || {};
8972
+ const { fontColor, bgColor, bigIcon, withPadding, bottomBlur, themeName } = options || {};
8931
8973
  const renderElement = useHeaderRender(header);
8932
- const handleIconClick = React.useCallback(() => zoomToFeatures([feature], { maxZoom: layerMaxZoomTo ?? optionsMaxZoomTo }), [zoomToFeatures, feature, layerMaxZoomTo, optionsMaxZoomTo]);
8933
- return (jsxRuntime.jsx(IconHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$bigIcon": bigIcon, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.defaultTheme, children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(uilibGl.Tooltip, { arrow: true, placement: "top", content: t("zoomToFeature", { ns: "dashboard", defaultValue: "Приблизить к объекту" }), delay: [600, 0], children: ref => (jsxRuntime.jsx(LayerIconClickable, { ref: ref, onClick: handleIconClick, children: jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }) })) }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
8974
+ return (jsxRuntime.jsx(GradientHeaderWrapper, { "$fontColor": fontColor, "$bgColor": bgColor, "$bigIcon": bigIcon, "$withPadding": withPadding, "$bottomBlur": bottomBlur, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName), children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: true, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
8934
8975
  id: "title",
8935
8976
  wrap: false,
8936
8977
  }), description: renderElement({
@@ -9801,13 +9842,12 @@ const HeaderSlideshow = styled.div `
9801
9842
  `;
9802
9843
 
9803
9844
  const FeatureCardSlideshowHeader = ({ isRow }) => {
9804
- const { layerInfo } = useWidgetContext(exports.WidgetType.FeatureCard);
9805
9845
  const { config } = useWidgetConfig(exports.WidgetType.FeatureCard);
9806
9846
  const { header } = config || {};
9807
9847
  const { options } = header || {};
9808
- const { height, withPadding } = options || {};
9848
+ const { height, withPadding, themeName } = options || {};
9809
9849
  const renderElement = useHeaderRender(header);
9810
- return (jsxRuntime.jsx(SlideshowHeaderWrapper, { big: true, withPadding: withPadding, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: uilibGl.darkTheme, children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { children: [jsxRuntime.jsx(LayerIcon, { layerInfo: layerInfo }), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
9850
+ return (jsxRuntime.jsx(SlideshowHeaderWrapper, { big: true, withPadding: withPadding, children: jsxRuntime.jsx(uilibGl.ThemeProvider, { theme: getThemeByName(themeName), children: jsxRuntime.jsxs(Header, { "$isRow": isRow, children: [jsxRuntime.jsxs(HeaderFrontView, { children: [jsxRuntime.jsxs(HeaderContainer, { column: true, children: [jsxRuntime.jsx(HeaderLayerIcon, {}), jsxRuntime.jsx(FeatureCardTitle, { title: renderElement({
9811
9851
  id: "title",
9812
9852
  wrap: false,
9813
9853
  }), description: renderElement({
@@ -10143,13 +10183,6 @@ const ElementModal = React.memo(({ type = exports.WidgetType.Dashboard, elementC
10143
10183
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(ModalIcon, { kind: icon || "new_window", onClick: handleOpen, children: title }), jsxRuntime.jsxs(uilibGl.Dialog, { maxWidth: maxWidth, minWidth: minWidth, minHeight: minHeight, isOpen: isOpen, modal: true, onCloseRequest: handleClose, style: { paddingBottom: "2rem" }, children: [jsxRuntime.jsx(uilibGl.DialogTitle, { children: jsxRuntime.jsxs(uilibGl.Flex, { justifyContent: "space-between", alignItems: "center", children: [!!title && jsxRuntime.jsx("span", { children: title }), jsxRuntime.jsx(uilibGl.IconButton, { kind: "close", onClick: handleClose })] }) }), jsxRuntime.jsx(uilibGl.DialogContent, { children: isLoading ? (jsxRuntime.jsx(DashboardLoading, {})) : (jsxRuntime.jsx(Container, { isColumn: true, noBorders: true, children: jsxRuntime.jsx(ContainerChildren, { type: type, items: modalContent, isMain: true, renderElement: renderElement }) })) })] })] }));
10144
10184
  });
10145
10185
 
10146
- const ElementLayerName = React.memo(({ type }) => {
10147
- const { layerInfo } = useWidgetContext(type);
10148
- if (!layerInfo?.name)
10149
- return null;
10150
- return jsxRuntime.jsx("span", { children: layerInfo.name });
10151
- });
10152
-
10153
10186
  const elementComponents = {
10154
10187
  control: ElementControl,
10155
10188
  image: ElementImage,
@@ -10166,7 +10199,6 @@ const elementComponents = {
10166
10199
  markdown: ElementMarkdown,
10167
10200
  uploader: ElementUploader,
10168
10201
  modal: ElementModal,
10169
- layerName: ElementLayerName,
10170
10202
  };
10171
10203
 
10172
10204
  const getElementValue = ({ getDefaultContainer, ...props }) => {
@@ -10200,6 +10232,9 @@ const getElementValue = ({ getDefaultContainer, ...props }) => {
10200
10232
  null
10201
10233
  : null;
10202
10234
  }
10235
+ if (type === "layerName") {
10236
+ return layerInfo?.name || "";
10237
+ }
10203
10238
  const ElementComponent = type ? elementComponents[type] : null;
10204
10239
  return ElementComponent ? (jsxRuntime.jsx(ElementComponent, { ...props })) : (getDefaultContainer?.());
10205
10240
  };
@@ -10256,8 +10291,6 @@ const getFeatureCardHeader = (templateName) => {
10256
10291
  return FeatureCardSlideshowHeader;
10257
10292
  case exports.HeaderTemplate.Gradient:
10258
10293
  return FeatureCardGradientHeader;
10259
- case exports.HeaderTemplate.Icon:
10260
- return FeatureCardIconHeader;
10261
10294
  case exports.HeaderTemplate.Default:
10262
10295
  default:
10263
10296
  return FeatureCardDefaultHeader;
@@ -11174,6 +11207,10 @@ const getRelatedAttribute = (layerInfo, sourceAttributeName, relatedLayerName) =
11174
11207
  return attributeConfig?.options?.relatedAttributes?.find(({ layerName }) => layerName === relatedLayerName);
11175
11208
  };
11176
11209
 
11210
+ const getResourceUrl = (url) => {
11211
+ return url ? (url.startsWith("http") ? url : `/sp/resources/file/${url}`) : "";
11212
+ };
11213
+
11177
11214
  const getSlideshowImages = ({ element, attribute, }) => {
11178
11215
  const { defaultValue, options } = element;
11179
11216
  const { separator } = options || {};
@@ -11223,6 +11260,10 @@ const getTemplateNameFromAttribute = (attribute) => {
11223
11260
  }
11224
11261
  };
11225
11262
 
11263
+ const getThemeByName = (themeName) => {
11264
+ return themeName === exports.ThemeName.Dark ? uilibGl.darkTheme : uilibGl.defaultTheme;
11265
+ };
11266
+
11226
11267
  const getDisplayTemplateNameFromAttribute = (attribute) => {
11227
11268
  if (attribute?.subType === api.StringSubType.Attachments) {
11228
11269
  return exports.ContainerTemplate.Attachment;
@@ -13401,7 +13442,6 @@ exports.FeatureCardContext = FeatureCardContext;
13401
13442
  exports.FeatureCardDefaultHeader = FeatureCardDefaultHeader;
13402
13443
  exports.FeatureCardGradientHeader = FeatureCardGradientHeader;
13403
13444
  exports.FeatureCardHeader = FeatureCardHeader;
13404
- exports.FeatureCardIconHeader = FeatureCardIconHeader;
13405
13445
  exports.FeatureCardProvider = FeatureCardProvider;
13406
13446
  exports.FeatureCardSlideshowHeader = FeatureCardSlideshowHeader;
13407
13447
  exports.FeatureCardTitle = FeatureCardTitle;
@@ -13542,6 +13582,7 @@ exports.getSelectedFilterValue = getSelectedFilterValue;
13542
13582
  exports.getSlideshowImages = getSlideshowImages;
13543
13583
  exports.getSvgUrl = getSvgUrl;
13544
13584
  exports.getTemplateNameFromAttribute = getTemplateNameFromAttribute;
13585
+ exports.getThemeByName = getThemeByName;
13545
13586
  exports.getTotalFromAttributes = getTotalFromAttributes;
13546
13587
  exports.getTotalFromRelatedFeatures = getTotalFromRelatedFeatures;
13547
13588
  exports.hexToRgba = hexToRgba;