@evergis/react 3.1.74 → 3.1.76

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.
@@ -0,0 +1,9 @@
1
+ import { FC, CSSProperties } from 'react';
2
+ import { ITerminalInitOnlyOptions, ITerminalOptions } from '@xterm/xterm';
3
+ export interface TaskLogTerminalProps {
4
+ log?: string | Record<string, any>;
5
+ className?: string;
6
+ styles?: CSSProperties;
7
+ terminalOptions?: ITerminalOptions & ITerminalInitOnlyOptions;
8
+ }
9
+ export declare const LogTerminal: FC<TaskLogTerminalProps>;
@@ -13,6 +13,7 @@ export * from './FeatureCardHeader';
13
13
  export * from './FeatureCardTitle';
14
14
  export * from './HiddenTitleItems';
15
15
  export * from './Loading';
16
+ export * from './LogTerminal';
16
17
  export * from './Pagination';
17
18
  export * from './Pagination/styled';
18
19
  export * from './StackBar';
@@ -1,4 +1,5 @@
1
- import { FC } from 'react';
1
+ import { CSSProperties, FC } from 'react';
2
2
  export declare const LocalLink: FC<{
3
3
  link: string;
4
+ style?: CSSProperties;
4
5
  }>;
@@ -1,4 +1,5 @@
1
1
  export declare const ExternalLink: import('styled-components').StyledComponent<any, any, any, any>;
2
+ export declare const Link: import('styled-components').StyledComponent<"a", any, {}, never>;
2
3
  export declare const LocalLinkBlank: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').IBlankProps, never>;
3
4
  export declare const LocalLinkButton: import('styled-components').StyledComponent<any, any, any, any>;
4
5
  export declare const LocalLinkCopy: import('styled-components').StyledComponent<"div", any, import('@evergis/uilib-gl').FlexProps, never>;
package/dist/index.js CHANGED
@@ -24,9 +24,9 @@ require('mapbox-gl/dist/mapbox-gl.css');
24
24
  var react = require('swiper/react');
25
25
  var ReactMarkdown = require('react-markdown');
26
26
  var remarkGfm = require('remark-gfm');
27
- require('@xterm/xterm/css/xterm.css');
28
27
  var xterm = require('@xterm/xterm');
29
28
  var addonFit = require('@xterm/addon-fit');
29
+ require('@xterm/xterm/css/xterm.css');
30
30
 
31
31
  const AddFeatureButton = ({ title, icon = "feature_add" /* , layerName, geometryType*/ }) => {
32
32
  // const [, handleAddFeature] = useFeatureCreator(layerName, geometryType);
@@ -5695,8 +5695,8 @@ const TwoColumnContainer = React.memo(({ config, elementConfig, type, renderElem
5695
5695
  const icon = children?.[iconIndex];
5696
5696
  const hasIcon = !!icon;
5697
5697
  const elementChildren = elementConfig?.children?.map(child => ({
5698
- ...child,
5699
5698
  type: "attributeValue",
5699
+ ...child,
5700
5700
  attributeName: attribute,
5701
5701
  options: { noUnits: hasUnits, ...child.options },
5702
5702
  }));
@@ -6848,121 +6848,6 @@ const StatusBadge = styled(uilibGl.Chip) `
6848
6848
  color: ${({ theme }) => theme.palette.iconContrast};
6849
6849
  `;
6850
6850
 
6851
- const TerminalWrapper = styled.div `
6852
- flex: 1;
6853
- overflow: hidden;
6854
- padding: 0;
6855
- margin: 0;
6856
- box-sizing: border-box;
6857
- min-height: 0;
6858
-
6859
- .xterm-viewport {
6860
- overflow-y: auto;
6861
- }
6862
-
6863
- .xterm-screen .xterm-rows span {
6864
- letter-spacing: 0 !important;
6865
- }
6866
- `;
6867
-
6868
- const LogTerminal = ({ log }) => {
6869
- const terminalRef = React.useRef(null);
6870
- const xtermRef = React.useRef(null);
6871
- const fitAddonRef = React.useRef(null);
6872
- const previousLogRef = React.useRef("");
6873
- const theme = styled.useTheme();
6874
- React.useEffect(() => {
6875
- if (!terminalRef.current)
6876
- return;
6877
- // Create terminal instance
6878
- const terminal = new xterm.Terminal({
6879
- cursorBlink: false,
6880
- fontSize: 12,
6881
- fontFamily: '"Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace',
6882
- scrollback: 10000,
6883
- convertEol: true,
6884
- lineHeight: 1.5,
6885
- theme: {
6886
- background: theme.palette.background,
6887
- foreground: theme.palette.textPrimary,
6888
- cursor: theme.palette.primary,
6889
- },
6890
- });
6891
- // Create fit addon
6892
- const fitAddon = new addonFit.FitAddon();
6893
- terminal.loadAddon(fitAddon);
6894
- // Open terminal
6895
- terminal.open(terminalRef.current);
6896
- fitAddon.fit();
6897
- // Store refs
6898
- xtermRef.current = terminal;
6899
- fitAddonRef.current = fitAddon;
6900
- // Handle window resize
6901
- const handleResize = () => {
6902
- fitAddon.fit();
6903
- };
6904
- window.addEventListener("resize", handleResize);
6905
- // Cleanup
6906
- return () => {
6907
- window.removeEventListener("resize", handleResize);
6908
- terminal.dispose();
6909
- xtermRef.current = null;
6910
- fitAddonRef.current = null;
6911
- };
6912
- }, [theme]);
6913
- // Update log content
6914
- React.useEffect(() => {
6915
- if (!xtermRef.current)
6916
- return;
6917
- // Handle different log types
6918
- if (typeof log === "string") {
6919
- // For string logs, only write the new content (append mode)
6920
- const previousLog = previousLogRef.current;
6921
- if (log !== previousLog) {
6922
- if (log.startsWith(previousLog)) {
6923
- // Log is accumulated - write only the new part
6924
- const newContent = log.substring(previousLog.length);
6925
- xtermRef.current.write(newContent);
6926
- }
6927
- else {
6928
- // Log was replaced completely - clear and write all
6929
- xtermRef.current.clear();
6930
- xtermRef.current.write(log);
6931
- }
6932
- previousLogRef.current = log;
6933
- }
6934
- }
6935
- else if (typeof log === "object") {
6936
- // JSON object (results) - always replace
6937
- xtermRef.current.clear();
6938
- const formatted = JSON.stringify(log, null, 2);
6939
- xtermRef.current.write(formatted);
6940
- previousLogRef.current = "";
6941
- }
6942
- else if (!log) {
6943
- // No log - clear terminal
6944
- xtermRef.current.clear();
6945
- previousLogRef.current = "";
6946
- }
6947
- // Scroll to bottom
6948
- xtermRef.current.scrollToBottom();
6949
- }, [log]);
6950
- React.useEffect(() => {
6951
- if (!fitAddonRef.current)
6952
- return;
6953
- const resizeObserver = new ResizeObserver(() => {
6954
- fitAddonRef.current?.fit();
6955
- });
6956
- if (terminalRef.current) {
6957
- resizeObserver.observe(terminalRef.current);
6958
- }
6959
- return () => {
6960
- resizeObserver.disconnect();
6961
- };
6962
- }, []);
6963
- return jsxRuntime.jsx(TerminalWrapper, { ref: terminalRef });
6964
- };
6965
-
6966
6851
  const STATUS_TRANSLATION_KEYS = {
6967
6852
  [api.RemoteTaskStatus.Process]: "taskProcess",
6968
6853
  [api.RemoteTaskStatus.Completed]: "taskCompleted",
@@ -7432,7 +7317,7 @@ const FeatureCardGradientHeader = ({ isRow }) => {
7432
7317
  };
7433
7318
 
7434
7319
  const HeaderFontColorMixin = styled.css `
7435
- ${HeaderTitleContainer}, ${LayerDescription} {
7320
+ ${HeaderTitleContainer}, ${HeaderTitleContainer} *, ${LayerDescription} {
7436
7321
  color: ${({ $fontColor }) => $fontColor};
7437
7322
  }
7438
7323
  `;
@@ -7961,15 +7846,14 @@ const ExternalLink = styled(uilibGl.IconButton).attrs(() => ({
7961
7846
  color: ${({ theme: { palette } }) => palette.primaryDeep};
7962
7847
  }
7963
7848
  `;
7964
- const LocalLinkBlank = styled(uilibGl.Blank) `
7965
- min-width: 13.5rem;
7966
- padding: 0.5rem 0.75rem 0;
7967
-
7968
- a {
7849
+ const Link = styled.a `
7969
7850
  text-decoration: none;
7970
7851
  font-size: 0.75rem;
7971
7852
  color: ${({ theme: { palette } }) => palette.primary};
7972
- }
7853
+ `;
7854
+ const LocalLinkBlank = styled(uilibGl.Blank) `
7855
+ min-width: 13.5rem;
7856
+ padding: 0.5rem 0.75rem 0;
7973
7857
 
7974
7858
  ${uilibGl.IconButtonButton} {
7975
7859
  font-size: 0.75rem;
@@ -7981,8 +7865,13 @@ const LocalLinkButton = styled(uilibGl.IconButton).attrs(() => ({
7981
7865
  width: 1rem;
7982
7866
  height: 1rem;
7983
7867
  background-color: ${({ theme: { palette } }) => palette.primary};
7868
+ padding: 0;
7984
7869
  border-radius: 50%;
7985
7870
 
7871
+ :hover {
7872
+ background-color: ${({ theme: { palette } }) => palette.primary};
7873
+ }
7874
+
7986
7875
  span[kind] {
7987
7876
  display: flex;
7988
7877
  justify-content: center;
@@ -7999,23 +7888,30 @@ const LocalLinkCopy = styled(uilibGl.Flex) `
7999
7888
  justify-content: center;
8000
7889
  `;
8001
7890
 
8002
- const LocalLink = React.memo(({ link }) => {
7891
+ const LocalLink = React.memo(({ link, style }) => {
8003
7892
  const { t } = useGlobalContext();
8004
7893
  const [isOpen, toggleOpen] = useToggle();
8005
7894
  const onCopy = React.useCallback(() => {
8006
7895
  navigator.clipboard.writeText(link);
8007
7896
  toggleOpen();
8008
7897
  }, [link, toggleOpen]);
8009
- return (jsxRuntime.jsx(uilibGl.Popover, { open: isOpen, zIndex: 10, onRequestClose: toggleOpen, anchorOrigin: "bottom-right", targetOrigin: "top-right", anchor: jsxRuntime.jsx(LocalLinkButton, { onClick: toggleOpen }), children: jsxRuntime.jsxs(LocalLinkBlank, { children: [jsxRuntime.jsx("a", { href: link, target: "_blank", rel: "noreferrer", children: link }), jsxRuntime.jsx(LocalLinkCopy, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "copy", onClick: onCopy, children: t("copy", { ns: "dashboard", defaultValue: "Копировать" }) }) })] }) }));
7898
+ return (jsxRuntime.jsx(uilibGl.Popover, { open: isOpen, zIndex: 10, onRequestClose: toggleOpen, anchorOrigin: "bottom-right", targetOrigin: "top-right", anchor: jsxRuntime.jsx(LocalLinkButton, { onClick: toggleOpen }), children: jsxRuntime.jsxs(LocalLinkBlank, { children: [jsxRuntime.jsx(Link, { href: link, target: "_blank", rel: "noreferrer", style: style, children: link }), jsxRuntime.jsx(LocalLinkCopy, { children: jsxRuntime.jsx(uilibGl.IconButton, { kind: "copy", onClick: onCopy, children: t("copy", { ns: "dashboard", defaultValue: "Копировать" }) }) })] }) }));
8010
7899
  });
8011
7900
 
8012
7901
  const ElementLink = React.memo(({ type, elementConfig }) => {
8013
7902
  const { attributes } = useWidgetContext(type);
8014
- const attribute = getAttributeByName(elementConfig?.attributeName, attributes);
8015
- const link = attribute?.value;
8016
- if (!link || typeof link !== "string")
7903
+ const { options, style } = elementConfig || {};
7904
+ const { simple, title } = options || {};
7905
+ const attribute = React.useMemo(() => getAttributeByName(elementConfig?.attributeName, attributes), [attributes, elementConfig?.attributeName]);
7906
+ const link = React.useMemo(() => getResourceUrl(attribute?.value?.toString()), [attribute?.value]);
7907
+ if (!link)
8017
7908
  return null;
8018
- return link.startsWith("http") ? jsxRuntime.jsx(ExternalLink, { onClick: () => window.open(link) }) : jsxRuntime.jsx(LocalLink, { link: link });
7909
+ if (simple) {
7910
+ return (jsxRuntime.jsx(Link, { href: link, target: "_blank", rel: "noreferrer", style: style, children: title ?? link }));
7911
+ }
7912
+ return link.startsWith("http")
7913
+ ? jsxRuntime.jsx(ExternalLink, { style: style, onClick: () => window.open(link) })
7914
+ : jsxRuntime.jsx(LocalLink, { style: style, link: link });
8019
7915
  });
8020
7916
 
8021
7917
  const MarkdownWrapper = styled.div `
@@ -10794,6 +10690,122 @@ const HiddenTitleItems = React.memo(({ elementConfig, config, type, filter }) =>
10794
10690
  getConfigFilter(filterName, configFilters)?.defaultValue, index)) }));
10795
10691
  });
10796
10692
 
10693
+ const TerminalWrapper = styled.div `
10694
+ flex: 1;
10695
+ overflow: hidden;
10696
+ padding: 0;
10697
+ margin: 0;
10698
+ box-sizing: border-box;
10699
+ min-height: 0;
10700
+
10701
+ .xterm-viewport {
10702
+ overflow-y: auto;
10703
+ }
10704
+
10705
+ .xterm-screen .xterm-rows span {
10706
+ letter-spacing: 0 !important;
10707
+ }
10708
+ `;
10709
+
10710
+ const LogTerminal = ({ log, terminalOptions, className, styles }) => {
10711
+ const terminalRef = React.useRef(null);
10712
+ const xtermRef = React.useRef(null);
10713
+ const fitAddonRef = React.useRef(null);
10714
+ const previousLogRef = React.useRef("");
10715
+ const theme = styled.useTheme();
10716
+ React.useEffect(() => {
10717
+ if (!terminalRef.current)
10718
+ return;
10719
+ // Create terminal instance
10720
+ const terminal = new xterm.Terminal({
10721
+ cursorBlink: false,
10722
+ fontSize: 12,
10723
+ fontFamily: '"Monaco", "Menlo", "Ubuntu Mono", "Consolas", "source-code-pro", monospace',
10724
+ scrollback: 10000,
10725
+ convertEol: true,
10726
+ lineHeight: 1.5,
10727
+ theme: {
10728
+ background: theme.palette.background,
10729
+ foreground: theme.palette.textPrimary,
10730
+ cursor: theme.palette.primary,
10731
+ },
10732
+ ...terminalOptions,
10733
+ });
10734
+ // Create fit addon
10735
+ const fitAddon = new addonFit.FitAddon();
10736
+ terminal.loadAddon(fitAddon);
10737
+ // Open terminal
10738
+ terminal.open(terminalRef.current);
10739
+ fitAddon.fit();
10740
+ // Store refs
10741
+ xtermRef.current = terminal;
10742
+ fitAddonRef.current = fitAddon;
10743
+ // Handle window resize
10744
+ const handleResize = () => {
10745
+ fitAddon.fit();
10746
+ };
10747
+ window.addEventListener("resize", handleResize);
10748
+ // Cleanup
10749
+ return () => {
10750
+ window.removeEventListener("resize", handleResize);
10751
+ terminal.dispose();
10752
+ xtermRef.current = null;
10753
+ fitAddonRef.current = null;
10754
+ };
10755
+ }, [theme, terminalOptions]);
10756
+ // Update log content
10757
+ React.useEffect(() => {
10758
+ if (!xtermRef.current)
10759
+ return;
10760
+ // Handle different log types
10761
+ if (typeof log === "string") {
10762
+ // For string logs, only write the new content (append mode)
10763
+ const previousLog = previousLogRef.current;
10764
+ if (log !== previousLog) {
10765
+ if (log.startsWith(previousLog)) {
10766
+ // Log is accumulated - write only the new part
10767
+ const newContent = log.substring(previousLog.length);
10768
+ xtermRef.current.write(newContent);
10769
+ }
10770
+ else {
10771
+ // Log was replaced completely - clear and write all
10772
+ xtermRef.current.clear();
10773
+ xtermRef.current.write(log);
10774
+ }
10775
+ previousLogRef.current = log;
10776
+ }
10777
+ }
10778
+ else if (typeof log === "object") {
10779
+ // JSON object (results) - always replace
10780
+ xtermRef.current.clear();
10781
+ const formatted = JSON.stringify(log, null, 2);
10782
+ xtermRef.current.write(formatted);
10783
+ previousLogRef.current = "";
10784
+ }
10785
+ else if (!log) {
10786
+ // No log - clear terminal
10787
+ xtermRef.current.clear();
10788
+ previousLogRef.current = "";
10789
+ }
10790
+ // Scroll to bottom
10791
+ xtermRef.current.scrollToBottom();
10792
+ }, [log]);
10793
+ React.useEffect(() => {
10794
+ if (!fitAddonRef.current)
10795
+ return;
10796
+ const resizeObserver = new ResizeObserver(() => {
10797
+ fitAddonRef.current?.fit();
10798
+ });
10799
+ if (terminalRef.current) {
10800
+ resizeObserver.observe(terminalRef.current);
10801
+ }
10802
+ return () => {
10803
+ resizeObserver.disconnect();
10804
+ };
10805
+ }, []);
10806
+ return jsxRuntime.jsx(TerminalWrapper, { ref: terminalRef, className: className, style: styles });
10807
+ };
10808
+
10797
10809
  const PageNavigator = styled(uilibGl.Flex) `
10798
10810
  margin-right: -0.5rem;
10799
10811
  align-items: center;
@@ -11217,6 +11229,7 @@ exports.LayerTree = LayerTree;
11217
11229
  exports.LayersContainer = LayersContainer;
11218
11230
  exports.LayersListWrapper = LayersListWrapper;
11219
11231
  exports.LinearProgressContainer = LinearProgressContainer;
11232
+ exports.LogTerminal = LogTerminal;
11220
11233
  exports.LogoContainer = LogoContainer;
11221
11234
  exports.MAX_CHART_WIDTH = MAX_CHART_WIDTH;
11222
11235
  exports.Map = Map$1;